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