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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #ifndef _SYS_SDCARD_SDA_IMPL_H
27 #define _SYS_SDCARD_SDA_IMPL_H
30 #include <sys/ksynch.h>
33 #include <sys/sunddi.h>
34 #include <sys/sdcard/sda.h>
41 * Type and structure definitions.
43 typedef struct sda_slot sda_slot_t
;
50 void *s_prv
; /* bus private data */
51 dev_info_t
*s_dip
; /* devinfo node for child */
58 uint32_t s_cur_ocr
; /* current ocr */
61 uint32_t s_maxclk
; /* maximum freq for card */
63 sda_cmd_t
*s_xfrp
; /* pending transfer cmd */
64 hrtime_t s_xfrtmo
; /* transfer timeout */
68 boolean_t s_ready
; /* target node ready */
69 boolean_t s_init
; /* slot initializing */
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 */
77 boolean_t s_xfrdone
; /* transfer event occurred */
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)
92 #define SLOT_CAP_NOPIO 0x0002
93 #define SLOT_CAP_HISPEED 0x0004
94 #define SLOT_CAP_4BITS 0x0008
100 * Slot operations. Slot local copy for performance.
105 * Recursive locking of slot.
109 kt_did_t s_owner
; /* owner holding the slot */
110 uint32_t s_circular
; /* circular sda_slot_enter() calls */
113 * Event notification/thread wakeup.
121 ddi_taskq_t
*s_hp_tq
; /* insert taskq */
122 ddi_taskq_t
*s_main_tq
; /* main processing taskq */
125 * Timestamping for cfgadm benefit.
131 * Memory card-specific.
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 */
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 */
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? */
156 char s_uuid
[40]; /* fabricated universal unique id */
158 struct b2s_nexus
*s_nexus
;
159 struct b2s_leaf
*s_leaf
;
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
))
175 * Per host state. One per devinfo node. There could be multiple
176 * slots per devinfo node.
182 ddi_dma_attr_t
*h_dma
; /* dma attr, needed for mem */
184 list_node_t h_node
; /* nexus node linkage */
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 */
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
))
197 * Useful function-like macros.
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)
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
,
211 sda_cmd_t
*sda_cmd_alloc_acmd(sda_slot_t
*, sda_index_t
, uint32_t, sda_rtype_t
,
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 *);
224 sda_err_t
sda_init_card(sda_slot_t
*);
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);
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 *,
248 void sda_nexus_remove(sda_slot_t
*);
249 void sda_nexus_insert(sda_slot_t
*);
250 void sda_nexus_reap(void *);
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
);
275 void sda_slot_err(sda_slot_t
*, const char *, ...);
277 void sda_slot_log(sda_slot_t
*, const char *, ...);
280 #define sda_slot_debug(...) sda_slot_log(__VA_ARGS__)
282 #define sda_slot_debug(...)
289 #endif /* _SYS_SDCARD_SDA_IMPL_H */