Home | History | Annotate | Download | only in sdcard
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_SYS_SDCARD_SDA_IMPL_H
     27 #define	_SYS_SDCARD_SDA_IMPL_H
     28 
     29 #include <sys/list.h>
     30 #include <sys/ksynch.h>
     31 #include <sys/note.h>
     32 #include <sys/ddi.h>
     33 #include <sys/sunddi.h>
     34 #include <sys/sdcard/sda.h>
     35 
     36 #ifdef __cplusplus
     37 extern "C" {
     38 #endif
     39 
     40 /*
     41  * Type and structure definitions.
     42  */
     43 typedef struct sda_slot sda_slot_t;
     44 
     45 /*
     46  * Per slot state.
     47  */
     48 struct sda_slot {
     49 	sda_host_t	*s_hostp;
     50 	void		*s_prv;			/* bus private data */
     51 	dev_info_t	*s_dip;			/* devinfo node for child */
     52 
     53 	int		s_slot_num;
     54 	boolean_t	s_inserted;
     55 	boolean_t	s_failed;
     56 
     57 	uint8_t		s_num_io;
     58 	uint32_t	s_cur_ocr;		/* current ocr */
     59 
     60 	uint16_t	s_rca;
     61 	uint32_t	s_maxclk;		/* maximum freq for card */
     62 
     63 	sda_cmd_t	*s_xfrp;		/* pending transfer cmd */
     64 	hrtime_t	s_xfrtmo;		/* transfer timeout */
     65 
     66 	boolean_t	s_reap;
     67 	boolean_t	s_warn;
     68 	boolean_t	s_ready;		/* target node ready */
     69 	boolean_t	s_init;			/* slot initializing */
     70 
     71 	/* these are protected by the evlock */
     72 	boolean_t	s_wake;			/* wake up thread */
     73 	boolean_t	s_detach;		/* detach in progress */
     74 	boolean_t	s_suspend;		/* host has DDI_SUSPENDed */
     75 	boolean_t	s_detect;		/* detect event occurred */
     76 	sda_fault_t	s_fault;
     77 	boolean_t	s_xfrdone;		/* transfer event occurred */
     78 	sda_err_t	s_errno;
     79 
     80 	uint16_t	s_flags;
     81 #define	SLOTF_WRITABLE		0x0004
     82 #define	SLOTF_4BITS		0x0008
     83 #define	SLOTF_IFCOND		0x0010
     84 #define	SLOTF_MMC		0x0020
     85 #define	SLOTF_SDMEM		0x0040
     86 #define	SLOTF_SDIO		0x0080
     87 #define	SLOTF_SDHC		0x0100
     88 #define	SLOTF_MEMORY		(SLOTF_MMC | SLOTF_SDMEM)
     89 #define	SLOTF_SD		(SLOTF_SDMEM | SLOTF_SDIO)
     90 
     91 	uint16_t	s_caps;
     92 #define	SLOT_CAP_NOPIO		0x0002
     93 #define	SLOT_CAP_HISPEED	0x0004
     94 #define	SLOT_CAP_4BITS		0x0008
     95 
     96 	list_t		s_cmdlist;
     97 	list_t		s_abortlist;
     98 
     99 	/*
    100 	 * Slot operations.  Slot local copy for performance.
    101 	 */
    102 	sda_ops_t	s_ops;
    103 
    104 	/*
    105 	 * Recursive locking of slot.
    106 	 */
    107 	kmutex_t	s_lock;
    108 	kcondvar_t	s_cv;
    109 	kt_did_t	s_owner;	/* owner holding the slot */
    110 	uint32_t	s_circular;	/* circular sda_slot_enter() calls */
    111 
    112 	/*
    113 	 * Event notification/thread wakeup.
    114 	 */
    115 	kmutex_t	s_evlock;
    116 	kcondvar_t	s_evcv;
    117 
    118 	/*
    119 	 * Asynch. threads.
    120 	 */
    121 	ddi_taskq_t	*s_hp_tq;	/* insert taskq */
    122 	ddi_taskq_t	*s_main_tq;	/* main processing taskq */
    123 
    124 	/*
    125 	 * Timestamping for cfgadm benefit.
    126 	 */
    127 	uint8_t		s_intransit;
    128 	time_t		s_stamp;
    129 
    130 	/*
    131 	 * Memory card-specific.
    132 	 */
    133 	uint32_t	s_rcsd[4];	/* raw csd */
    134 	uint32_t	s_rcid[4];	/* raw cid */
    135 	uint32_t	s_nblks;	/* total blocks on device */
    136 	uint16_t	s_blksz;	/* device block size (typ. 512) */
    137 	uint16_t	s_bshift;	/* block address shift factor */
    138 	uint32_t	s_speed;	/* max memory clock in hz */
    139 
    140 	/* Other CID and CSD values */
    141 	uint32_t	s_mfg;		/* mfg id */
    142 	char		s_prod[8];	/* product id */
    143 	char		s_oem[2];	/* oem id */
    144 	uint32_t	s_serial;
    145 	uint8_t		s_majver;
    146 	uint8_t		s_minver;
    147 	uint16_t	s_year;
    148 	uint8_t		s_month;
    149 
    150 	uint16_t	s_ccc;		/* card command classes */
    151 	uint8_t		s_r2w;		/* read/write factor */
    152 	uint8_t		s_dsr;		/* DSR implemented? */
    153 	uint8_t		s_perm_wp;	/* permanent write protect set? */
    154 	uint8_t		s_temp_wp;	/* temporary write protect set? */
    155 
    156 	char		s_uuid[40];	/* fabricated universal unique id */
    157 
    158 	struct b2s_nexus	*s_nexus;
    159 	struct b2s_leaf		*s_leaf;
    160 };
    161 
    162 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_lock, sda_slot::s_circular))
    163 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_wake))
    164 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_detach))
    165 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_detect))
    166 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_suspend))
    167 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_fault))
    168 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_xfrdone))
    169 _NOTE(MUTEX_PROTECTS_DATA(sda_slot::s_evlock, sda_slot::s_errno))
    170 _NOTE(SCHEME_PROTECTS_DATA("slot_enter", sda_slot::s_warn))
    171 _NOTE(SCHEME_PROTECTS_DATA("slot_enter", sda_slot::s_xfrtmo))
    172 _NOTE(SCHEME_PROTECTS_DATA("slot_enter", sda_slot::s_xfrp))
    173 
    174 /*
    175  * Per host state.  One per devinfo node.  There could be multiple
    176  * slots per devinfo node.
    177  */
    178 struct sda_host {
    179 	dev_info_t	*h_dip;
    180 	int		h_nslot;
    181 	sda_slot_t	*h_slots;
    182 	ddi_dma_attr_t	*h_dma;		/* dma attr, needed for mem */
    183 
    184 	list_node_t	h_node;		/* nexus node linkage */
    185 
    186 	uint32_t	h_flags;
    187 #define	HOST_ATTACH	(1U << 0)	/* host attach completed */
    188 #define	HOST_XOPEN	(1U << 2)	/* exclusive open */
    189 #define	HOST_SOPEN	(1U << 3)	/* shared open */
    190 };
    191 
    192 _NOTE(SCHEME_PROTECTS_DATA("stable data", sda_host::h_dip))
    193 _NOTE(SCHEME_PROTECTS_DATA("stable data", sda_host::h_nslot))
    194 _NOTE(SCHEME_PROTECTS_DATA("stable data", sda_host::h_dma))
    195 
    196 /*
    197  * Useful function-like macros.
    198  */
    199 #define	sda_setprop(s, p, v)	s->s_ops.so_setprop(s->s_prv, p, v)
    200 #define	sda_getprop(s, p, v)	s->s_ops.so_getprop(s->s_prv, p, v)
    201 
    202 /*
    203  * sda_cmd.c
    204  */
    205 void sda_cmd_init(void);
    206 void sda_cmd_fini(void);
    207 void sda_cmd_list_init(list_t *);
    208 void sda_cmd_list_fini(list_t *);
    209 sda_cmd_t *sda_cmd_alloc(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t,
    210     void *, int);
    211 sda_cmd_t *sda_cmd_alloc_acmd(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t,
    212     void *, int);
    213 void sda_cmd_free(sda_cmd_t *);
    214 sda_err_t sda_cmd_errno(sda_cmd_t *);
    215 void *sda_cmd_data(sda_cmd_t *);
    216 void sda_cmd_submit(sda_slot_t *, sda_cmd_t *, void (*)(sda_cmd_t *));
    217 void sda_cmd_resubmit_acmd(sda_slot_t *, sda_cmd_t *);
    218 void sda_cmd_notify(sda_cmd_t *, uint16_t, sda_err_t);
    219 sda_err_t sda_cmd_exec(sda_slot_t *, sda_cmd_t *, uint32_t *);
    220 
    221 /*
    222  * sda_init.c
    223  */
    224 sda_err_t sda_init_card(sda_slot_t *);
    225 
    226 /*
    227  * sda_mem.c
    228  */
    229 void sda_mem_init(struct modlinkage *);
    230 void sda_mem_fini(struct modlinkage *);
    231 uint32_t sda_mem_maxclk(sda_slot_t *);
    232 uint32_t sda_mem_getbits(uint32_t *, int, int);
    233 
    234 
    235 /*
    236  * sda_nexus.c
    237  */
    238 void sda_nexus_init(void);
    239 void sda_nexus_fini(void);
    240 void sda_nexus_register(sda_host_t *);
    241 void sda_nexus_unregister(sda_host_t *);
    242 int sda_nexus_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
    243 int sda_nexus_open(dev_t *, int, int, cred_t *);
    244 int sda_nexus_close(dev_t, int, int, cred_t *);
    245 int sda_nexus_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
    246 int sda_nexus_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *,
    247     void *);
    248 void sda_nexus_remove(sda_slot_t *);
    249 void sda_nexus_insert(sda_slot_t *);
    250 void sda_nexus_reap(void *);
    251 
    252 /*
    253  * sda_slot.c
    254  */
    255 void sda_slot_init(sda_slot_t *);
    256 void sda_slot_fini(sda_slot_t *);
    257 void sda_slot_enter(sda_slot_t *);
    258 void sda_slot_exit(sda_slot_t *);
    259 boolean_t sda_slot_owned(sda_slot_t *);
    260 void sda_slot_attach(sda_slot_t *);
    261 void sda_slot_detach(sda_slot_t *);
    262 void sda_slot_suspend(sda_slot_t *);
    263 void sda_slot_resume(sda_slot_t *);
    264 void sda_slot_reset(sda_slot_t *);
    265 void sda_slot_wakeup(sda_slot_t *);
    266 void sda_slot_detect(sda_slot_t *);
    267 int sda_slot_power_on(sda_slot_t *);
    268 void sda_slot_power_off(sda_slot_t *);
    269 void sda_slot_reset(sda_slot_t *);
    270 void sda_slot_shutdown(sda_slot_t *);
    271 void sda_slot_transfer(sda_slot_t *, sda_err_t);
    272 void sda_slot_mem_reset(sda_slot_t *, sda_err_t);
    273 void sda_slot_fault(sda_slot_t *, sda_fault_t);
    274 /*PRINTFLIKE2*/
    275 void sda_slot_err(sda_slot_t *, const char *, ...);
    276 /*PRINTFLIKE2*/
    277 void sda_slot_log(sda_slot_t *, const char *, ...);
    278 
    279 #ifdef	DEBUG
    280 #define	sda_slot_debug(...)	sda_slot_log(__VA_ARGS__)
    281 #else
    282 #define	sda_slot_debug(...)
    283 #endif
    284 
    285 #ifdef __cplusplus
    286 }
    287 #endif
    288 
    289 #endif	/* _SYS_SDCARD_SDA_IMPL_H */
    290