14bb7efa7SGarrett D'Amore /* 24bb7efa7SGarrett D'Amore * CDDL HEADER START 34bb7efa7SGarrett D'Amore * 44bb7efa7SGarrett D'Amore * The contents of this file are subject to the terms of the 54bb7efa7SGarrett D'Amore * Common Development and Distribution License (the "License"). 64bb7efa7SGarrett D'Amore * You may not use this file except in compliance with the License. 74bb7efa7SGarrett D'Amore * 84bb7efa7SGarrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94bb7efa7SGarrett D'Amore * or http://www.opensolaris.org/os/licensing. 104bb7efa7SGarrett D'Amore * See the License for the specific language governing permissions 114bb7efa7SGarrett D'Amore * and limitations under the License. 124bb7efa7SGarrett D'Amore * 134bb7efa7SGarrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each 144bb7efa7SGarrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154bb7efa7SGarrett D'Amore * If applicable, add the following below this CDDL HEADER, with the 164bb7efa7SGarrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying 174bb7efa7SGarrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner] 184bb7efa7SGarrett D'Amore * 194bb7efa7SGarrett D'Amore * CDDL HEADER END 204bb7efa7SGarrett D'Amore */ 214bb7efa7SGarrett D'Amore /* 22*3f7d54a6SGarrett D'Amore * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 234bb7efa7SGarrett D'Amore */ 244bb7efa7SGarrett D'Amore 254bb7efa7SGarrett D'Amore #ifndef _SYS_SDCARD_SDA_IMPL_H 264bb7efa7SGarrett D'Amore #define _SYS_SDCARD_SDA_IMPL_H 274bb7efa7SGarrett D'Amore 284bb7efa7SGarrett D'Amore #include <sys/list.h> 294bb7efa7SGarrett D'Amore #include <sys/ksynch.h> 304bb7efa7SGarrett D'Amore #include <sys/note.h> 31*3f7d54a6SGarrett D'Amore #include <sys/blkdev.h> 324bb7efa7SGarrett D'Amore #include <sys/ddi.h> 334bb7efa7SGarrett D'Amore #include <sys/sunddi.h> 344bb7efa7SGarrett D'Amore #include <sys/sdcard/sda.h> 354bb7efa7SGarrett D'Amore 364bb7efa7SGarrett D'Amore #ifdef __cplusplus 374bb7efa7SGarrett D'Amore extern "C" { 384bb7efa7SGarrett D'Amore #endif 394bb7efa7SGarrett D'Amore 404bb7efa7SGarrett D'Amore /* 414bb7efa7SGarrett D'Amore * Type and structure definitions. 424bb7efa7SGarrett D'Amore */ 434bb7efa7SGarrett D'Amore typedef struct sda_slot sda_slot_t; 444bb7efa7SGarrett D'Amore 454bb7efa7SGarrett D'Amore /* 464bb7efa7SGarrett D'Amore * Per slot state. 474bb7efa7SGarrett D'Amore */ 484bb7efa7SGarrett D'Amore struct sda_slot { 491cb84fbfSGarrett D'Amore sda_host_t *s_hostp; 504bb7efa7SGarrett D'Amore void *s_prv; /* bus private data */ 511cb84fbfSGarrett D'Amore dev_info_t *s_dip; /* devinfo node for child */ 524bb7efa7SGarrett D'Amore 534bb7efa7SGarrett D'Amore int s_slot_num; 544bb7efa7SGarrett D'Amore boolean_t s_inserted; 554bb7efa7SGarrett D'Amore boolean_t s_failed; 56f2b90c3cSGarrett D'Amore 574bb7efa7SGarrett D'Amore uint8_t s_num_io; 584bb7efa7SGarrett D'Amore uint32_t s_cur_ocr; /* current ocr */ 594bb7efa7SGarrett D'Amore 604bb7efa7SGarrett D'Amore uint16_t s_rca; 614bb7efa7SGarrett D'Amore uint32_t s_maxclk; /* maximum freq for card */ 624bb7efa7SGarrett D'Amore 634bb7efa7SGarrett D'Amore sda_cmd_t *s_xfrp; /* pending transfer cmd */ 644bb7efa7SGarrett D'Amore hrtime_t s_xfrtmo; /* transfer timeout */ 654bb7efa7SGarrett D'Amore 664bb7efa7SGarrett D'Amore boolean_t s_reap; 674bb7efa7SGarrett D'Amore boolean_t s_warn; 684bb7efa7SGarrett D'Amore boolean_t s_ready; /* target node ready */ 694bb7efa7SGarrett D'Amore boolean_t s_init; /* slot initializing */ 704bb7efa7SGarrett D'Amore 714bb7efa7SGarrett D'Amore /* these are protected by the evlock */ 724bb7efa7SGarrett D'Amore boolean_t s_wake; /* wake up thread */ 734bb7efa7SGarrett D'Amore boolean_t s_detach; /* detach in progress */ 74f2b90c3cSGarrett D'Amore boolean_t s_suspend; /* host has DDI_SUSPENDed */ 754bb7efa7SGarrett D'Amore boolean_t s_detect; /* detect event occurred */ 764bb7efa7SGarrett D'Amore sda_fault_t s_fault; 774bb7efa7SGarrett D'Amore boolean_t s_xfrdone; /* transfer event occurred */ 784bb7efa7SGarrett D'Amore sda_err_t s_errno; 794bb7efa7SGarrett D'Amore 804bb7efa7SGarrett D'Amore uint16_t s_flags; 814bb7efa7SGarrett D'Amore #define SLOTF_WRITABLE 0x0004 824bb7efa7SGarrett D'Amore #define SLOTF_4BITS 0x0008 834bb7efa7SGarrett D'Amore #define SLOTF_IFCOND 0x0010 844bb7efa7SGarrett D'Amore #define SLOTF_MMC 0x0020 854bb7efa7SGarrett D'Amore #define SLOTF_SDMEM 0x0040 864bb7efa7SGarrett D'Amore #define SLOTF_SDIO 0x0080 874bb7efa7SGarrett D'Amore #define SLOTF_SDHC 0x0100 884bb7efa7SGarrett D'Amore #define SLOTF_MEMORY (SLOTF_MMC | SLOTF_SDMEM) 894bb7efa7SGarrett D'Amore #define SLOTF_SD (SLOTF_SDMEM | SLOTF_SDIO) 904bb7efa7SGarrett D'Amore 914bb7efa7SGarrett D'Amore uint16_t s_caps; 924bb7efa7SGarrett D'Amore #define SLOT_CAP_NOPIO 0x0002 934bb7efa7SGarrett D'Amore #define SLOT_CAP_HISPEED 0x0004 944bb7efa7SGarrett D'Amore #define SLOT_CAP_4BITS 0x0008 954bb7efa7SGarrett D'Amore 964bb7efa7SGarrett D'Amore list_t s_cmdlist; 974bb7efa7SGarrett D'Amore list_t s_abortlist; 984bb7efa7SGarrett D'Amore 994bb7efa7SGarrett D'Amore /* 1004bb7efa7SGarrett D'Amore * Slot operations. Slot local copy for performance. 1014bb7efa7SGarrett D'Amore */ 1024bb7efa7SGarrett D'Amore sda_ops_t s_ops; 1034bb7efa7SGarrett D'Amore 1044bb7efa7SGarrett D'Amore /* 1054bb7efa7SGarrett D'Amore * Recursive locking of slot. 1064bb7efa7SGarrett D'Amore */ 1074bb7efa7SGarrett D'Amore kmutex_t s_lock; 1084bb7efa7SGarrett D'Amore kcondvar_t s_cv; 1094bb7efa7SGarrett D'Amore kt_did_t s_owner; /* owner holding the slot */ 1104bb7efa7SGarrett D'Amore uint32_t s_circular; /* circular sda_slot_enter() calls */ 1114bb7efa7SGarrett D'Amore 1124bb7efa7SGarrett D'Amore /* 1134bb7efa7SGarrett D'Amore * Event notification/thread wakeup. 1144bb7efa7SGarrett D'Amore */ 1154bb7efa7SGarrett D'Amore kmutex_t s_evlock; 1164bb7efa7SGarrett D'Amore kcondvar_t s_evcv; 1174bb7efa7SGarrett D'Amore 1184bb7efa7SGarrett D'Amore /* 1194bb7efa7SGarrett D'Amore * Asynch. threads. 1204bb7efa7SGarrett D'Amore */ 121f2b90c3cSGarrett D'Amore ddi_taskq_t *s_hp_tq; /* insert taskq */ 122f2b90c3cSGarrett D'Amore ddi_taskq_t *s_main_tq; /* main processing taskq */ 1234bb7efa7SGarrett D'Amore 1244bb7efa7SGarrett D'Amore /* 1254bb7efa7SGarrett D'Amore * Timestamping for cfgadm benefit. 1264bb7efa7SGarrett D'Amore */ 1274bb7efa7SGarrett D'Amore uint8_t s_intransit; 1284bb7efa7SGarrett D'Amore time_t s_stamp; 1294bb7efa7SGarrett D'Amore 1304bb7efa7SGarrett D'Amore /* 1314bb7efa7SGarrett D'Amore * Memory card-specific. 1324bb7efa7SGarrett D'Amore */ 1334bb7efa7SGarrett D'Amore uint32_t s_rcsd[4]; /* raw csd */ 1344bb7efa7SGarrett D'Amore uint32_t s_rcid[4]; /* raw cid */ 1354bb7efa7SGarrett D'Amore uint32_t s_nblks; /* total blocks on device */ 1364bb7efa7SGarrett D'Amore uint16_t s_blksz; /* device block size (typ. 512) */ 1374bb7efa7SGarrett D'Amore uint16_t s_bshift; /* block address shift factor */ 1384bb7efa7SGarrett D'Amore uint32_t s_speed; /* max memory clock in hz */ 1394bb7efa7SGarrett D'Amore 1404bb7efa7SGarrett D'Amore /* Other CID and CSD values */ 1414bb7efa7SGarrett D'Amore uint32_t s_mfg; /* mfg id */ 1424bb7efa7SGarrett D'Amore char s_prod[8]; /* product id */ 1434bb7efa7SGarrett D'Amore char s_oem[2]; /* oem id */ 1444bb7efa7SGarrett D'Amore uint32_t s_serial; 1454bb7efa7SGarrett D'Amore uint8_t s_majver; 1464bb7efa7SGarrett D'Amore uint8_t s_minver; 1474bb7efa7SGarrett D'Amore uint16_t s_year; 1484bb7efa7SGarrett D'Amore uint8_t s_month; 1494bb7efa7SGarrett D'Amore 1504bb7efa7SGarrett D'Amore uint16_t s_ccc; /* card command classes */ 1514bb7efa7SGarrett D'Amore uint8_t s_r2w; /* read/write factor */ 1524bb7efa7SGarrett D'Amore uint8_t s_dsr; /* DSR implemented? */ 1534bb7efa7SGarrett D'Amore uint8_t s_perm_wp; /* permanent write protect set? */ 1544bb7efa7SGarrett D'Amore uint8_t s_temp_wp; /* temporary write protect set? */ 1554bb7efa7SGarrett D'Amore 156*3f7d54a6SGarrett D'Amore bd_handle_t s_bdh; /* block dev handle */ 1574bb7efa7SGarrett D'Amore }; 1584bb7efa7SGarrett D'Amore 1594bb7efa7SGarrett D'Amore /* 1604bb7efa7SGarrett D'Amore * Per host state. One per devinfo node. There could be multiple 1614bb7efa7SGarrett D'Amore * slots per devinfo node. 1624bb7efa7SGarrett D'Amore */ 1634bb7efa7SGarrett D'Amore struct sda_host { 1644bb7efa7SGarrett D'Amore dev_info_t *h_dip; 1654bb7efa7SGarrett D'Amore int h_nslot; 1664bb7efa7SGarrett D'Amore sda_slot_t *h_slots; 1674bb7efa7SGarrett D'Amore ddi_dma_attr_t *h_dma; /* dma attr, needed for mem */ 1684bb7efa7SGarrett D'Amore 1694bb7efa7SGarrett D'Amore list_node_t h_node; /* nexus node linkage */ 1704bb7efa7SGarrett D'Amore 1714bb7efa7SGarrett D'Amore uint32_t h_flags; 1724bb7efa7SGarrett D'Amore #define HOST_ATTACH (1U << 0) /* host attach completed */ 1734bb7efa7SGarrett D'Amore #define HOST_XOPEN (1U << 2) /* exclusive open */ 1744bb7efa7SGarrett D'Amore #define HOST_SOPEN (1U << 3) /* shared open */ 1754bb7efa7SGarrett D'Amore }; 1764bb7efa7SGarrett D'Amore 1774bb7efa7SGarrett D'Amore /* 1784bb7efa7SGarrett D'Amore * Useful function-like macros. 1794bb7efa7SGarrett D'Amore */ 1804bb7efa7SGarrett D'Amore #define sda_setprop(s, p, v) s->s_ops.so_setprop(s->s_prv, p, v) 1814bb7efa7SGarrett D'Amore #define sda_getprop(s, p, v) s->s_ops.so_getprop(s->s_prv, p, v) 1824bb7efa7SGarrett D'Amore 1834bb7efa7SGarrett D'Amore /* 1844bb7efa7SGarrett D'Amore * sda_cmd.c 1854bb7efa7SGarrett D'Amore */ 1864bb7efa7SGarrett D'Amore void sda_cmd_init(void); 1874bb7efa7SGarrett D'Amore void sda_cmd_fini(void); 1884bb7efa7SGarrett D'Amore void sda_cmd_list_init(list_t *); 1894bb7efa7SGarrett D'Amore void sda_cmd_list_fini(list_t *); 1904bb7efa7SGarrett D'Amore sda_cmd_t *sda_cmd_alloc(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t, 1914bb7efa7SGarrett D'Amore void *, int); 1924bb7efa7SGarrett D'Amore sda_cmd_t *sda_cmd_alloc_acmd(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t, 1934bb7efa7SGarrett D'Amore void *, int); 1944bb7efa7SGarrett D'Amore void sda_cmd_free(sda_cmd_t *); 1954bb7efa7SGarrett D'Amore sda_err_t sda_cmd_errno(sda_cmd_t *); 1964bb7efa7SGarrett D'Amore void *sda_cmd_data(sda_cmd_t *); 1974bb7efa7SGarrett D'Amore void sda_cmd_submit(sda_slot_t *, sda_cmd_t *, void (*)(sda_cmd_t *)); 1984bb7efa7SGarrett D'Amore void sda_cmd_resubmit_acmd(sda_slot_t *, sda_cmd_t *); 1994bb7efa7SGarrett D'Amore void sda_cmd_notify(sda_cmd_t *, uint16_t, sda_err_t); 2004bb7efa7SGarrett D'Amore sda_err_t sda_cmd_exec(sda_slot_t *, sda_cmd_t *, uint32_t *); 2014bb7efa7SGarrett D'Amore 2024bb7efa7SGarrett D'Amore /* 2034bb7efa7SGarrett D'Amore * sda_init.c 2044bb7efa7SGarrett D'Amore */ 2054bb7efa7SGarrett D'Amore sda_err_t sda_init_card(sda_slot_t *); 2064bb7efa7SGarrett D'Amore 2074bb7efa7SGarrett D'Amore /* 2084bb7efa7SGarrett D'Amore * sda_mem.c 2094bb7efa7SGarrett D'Amore */ 2104bb7efa7SGarrett D'Amore void sda_mem_init(struct modlinkage *); 2114bb7efa7SGarrett D'Amore void sda_mem_fini(struct modlinkage *); 2124bb7efa7SGarrett D'Amore uint32_t sda_mem_maxclk(sda_slot_t *); 2134bb7efa7SGarrett D'Amore uint32_t sda_mem_getbits(uint32_t *, int, int); 214*3f7d54a6SGarrett D'Amore int sda_mem_parse_cid_csd(sda_slot_t *); 215*3f7d54a6SGarrett D'Amore int sda_mem_bd_read(void *, bd_xfer_t *); 216*3f7d54a6SGarrett D'Amore int sda_mem_bd_write(void *, bd_xfer_t *); 217*3f7d54a6SGarrett D'Amore void sda_mem_bd_driveinfo(void *, bd_drive_t *); 218*3f7d54a6SGarrett D'Amore int sda_mem_bd_mediainfo(void *, bd_media_t *); 2194bb7efa7SGarrett D'Amore 2204bb7efa7SGarrett D'Amore 2214bb7efa7SGarrett D'Amore /* 2224bb7efa7SGarrett D'Amore * sda_nexus.c 2234bb7efa7SGarrett D'Amore */ 2244bb7efa7SGarrett D'Amore void sda_nexus_init(void); 2254bb7efa7SGarrett D'Amore void sda_nexus_fini(void); 2264bb7efa7SGarrett D'Amore void sda_nexus_register(sda_host_t *); 2274bb7efa7SGarrett D'Amore void sda_nexus_unregister(sda_host_t *); 2284bb7efa7SGarrett D'Amore int sda_nexus_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 2294bb7efa7SGarrett D'Amore int sda_nexus_open(dev_t *, int, int, cred_t *); 2304bb7efa7SGarrett D'Amore int sda_nexus_close(dev_t, int, int, cred_t *); 2314bb7efa7SGarrett D'Amore int sda_nexus_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 2324bb7efa7SGarrett D'Amore int sda_nexus_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *, 2334bb7efa7SGarrett D'Amore void *); 2344bb7efa7SGarrett D'Amore void sda_nexus_remove(sda_slot_t *); 2354bb7efa7SGarrett D'Amore void sda_nexus_insert(sda_slot_t *); 2364bb7efa7SGarrett D'Amore void sda_nexus_reap(void *); 2374bb7efa7SGarrett D'Amore 2384bb7efa7SGarrett D'Amore /* 2394bb7efa7SGarrett D'Amore * sda_slot.c 2404bb7efa7SGarrett D'Amore */ 2414bb7efa7SGarrett D'Amore void sda_slot_init(sda_slot_t *); 2424bb7efa7SGarrett D'Amore void sda_slot_fini(sda_slot_t *); 2434bb7efa7SGarrett D'Amore void sda_slot_enter(sda_slot_t *); 2444bb7efa7SGarrett D'Amore void sda_slot_exit(sda_slot_t *); 2454bb7efa7SGarrett D'Amore boolean_t sda_slot_owned(sda_slot_t *); 2464bb7efa7SGarrett D'Amore void sda_slot_attach(sda_slot_t *); 2474bb7efa7SGarrett D'Amore void sda_slot_detach(sda_slot_t *); 248f2b90c3cSGarrett D'Amore void sda_slot_suspend(sda_slot_t *); 249f2b90c3cSGarrett D'Amore void sda_slot_resume(sda_slot_t *); 2504bb7efa7SGarrett D'Amore void sda_slot_reset(sda_slot_t *); 2514bb7efa7SGarrett D'Amore void sda_slot_wakeup(sda_slot_t *); 2524bb7efa7SGarrett D'Amore void sda_slot_detect(sda_slot_t *); 2534bb7efa7SGarrett D'Amore int sda_slot_power_on(sda_slot_t *); 2544bb7efa7SGarrett D'Amore void sda_slot_power_off(sda_slot_t *); 2554bb7efa7SGarrett D'Amore void sda_slot_reset(sda_slot_t *); 2564bb7efa7SGarrett D'Amore void sda_slot_shutdown(sda_slot_t *); 2574bb7efa7SGarrett D'Amore void sda_slot_transfer(sda_slot_t *, sda_err_t); 2584bb7efa7SGarrett D'Amore void sda_slot_fault(sda_slot_t *, sda_fault_t); 2594bb7efa7SGarrett D'Amore /*PRINTFLIKE2*/ 2604bb7efa7SGarrett D'Amore void sda_slot_err(sda_slot_t *, const char *, ...); 2614bb7efa7SGarrett D'Amore /*PRINTFLIKE2*/ 2624bb7efa7SGarrett D'Amore void sda_slot_log(sda_slot_t *, const char *, ...); 2634bb7efa7SGarrett D'Amore 2644bb7efa7SGarrett D'Amore #ifdef DEBUG 2654bb7efa7SGarrett D'Amore #define sda_slot_debug(...) sda_slot_log(__VA_ARGS__) 2664bb7efa7SGarrett D'Amore #else 2674bb7efa7SGarrett D'Amore #define sda_slot_debug(...) 2684bb7efa7SGarrett D'Amore #endif 2694bb7efa7SGarrett D'Amore 2704bb7efa7SGarrett D'Amore #ifdef __cplusplus 2714bb7efa7SGarrett D'Amore } 2724bb7efa7SGarrett D'Amore #endif 2734bb7efa7SGarrett D'Amore 2744bb7efa7SGarrett D'Amore #endif /* _SYS_SDCARD_SDA_IMPL_H */ 275