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