17302Sgdamore@opensolaris.org /* 27302Sgdamore@opensolaris.org * CDDL HEADER START 37302Sgdamore@opensolaris.org * 47302Sgdamore@opensolaris.org * The contents of this file are subject to the terms of the 57302Sgdamore@opensolaris.org * Common Development and Distribution License (the "License"). 67302Sgdamore@opensolaris.org * You may not use this file except in compliance with the License. 77302Sgdamore@opensolaris.org * 87302Sgdamore@opensolaris.org * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97302Sgdamore@opensolaris.org * or http://www.opensolaris.org/os/licensing. 107302Sgdamore@opensolaris.org * See the License for the specific language governing permissions 117302Sgdamore@opensolaris.org * and limitations under the License. 127302Sgdamore@opensolaris.org * 137302Sgdamore@opensolaris.org * When distributing Covered Code, include this CDDL HEADER in each 147302Sgdamore@opensolaris.org * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157302Sgdamore@opensolaris.org * If applicable, add the following below this CDDL HEADER, with the 167302Sgdamore@opensolaris.org * fields enclosed by brackets "[]" replaced with your own identifying 177302Sgdamore@opensolaris.org * information: Portions Copyright [yyyy] [name of copyright owner] 187302Sgdamore@opensolaris.org * 197302Sgdamore@opensolaris.org * CDDL HEADER END 207302Sgdamore@opensolaris.org */ 217302Sgdamore@opensolaris.org /* 22*12426Sgdamore@opensolaris.org * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 237302Sgdamore@opensolaris.org */ 247302Sgdamore@opensolaris.org 257302Sgdamore@opensolaris.org #ifndef _SYS_SDCARD_SDA_IMPL_H 267302Sgdamore@opensolaris.org #define _SYS_SDCARD_SDA_IMPL_H 277302Sgdamore@opensolaris.org 287302Sgdamore@opensolaris.org #include <sys/list.h> 297302Sgdamore@opensolaris.org #include <sys/ksynch.h> 307302Sgdamore@opensolaris.org #include <sys/note.h> 31*12426Sgdamore@opensolaris.org #include <sys/blkdev.h> 327302Sgdamore@opensolaris.org #include <sys/ddi.h> 337302Sgdamore@opensolaris.org #include <sys/sunddi.h> 347302Sgdamore@opensolaris.org #include <sys/sdcard/sda.h> 357302Sgdamore@opensolaris.org 367302Sgdamore@opensolaris.org #ifdef __cplusplus 377302Sgdamore@opensolaris.org extern "C" { 387302Sgdamore@opensolaris.org #endif 397302Sgdamore@opensolaris.org 407302Sgdamore@opensolaris.org /* 417302Sgdamore@opensolaris.org * Type and structure definitions. 427302Sgdamore@opensolaris.org */ 437302Sgdamore@opensolaris.org typedef struct sda_slot sda_slot_t; 447302Sgdamore@opensolaris.org 457302Sgdamore@opensolaris.org /* 467302Sgdamore@opensolaris.org * Per slot state. 477302Sgdamore@opensolaris.org */ 487302Sgdamore@opensolaris.org struct sda_slot { 497686Sgdamore@opensolaris.org sda_host_t *s_hostp; 507302Sgdamore@opensolaris.org void *s_prv; /* bus private data */ 517686Sgdamore@opensolaris.org dev_info_t *s_dip; /* devinfo node for child */ 527302Sgdamore@opensolaris.org 537302Sgdamore@opensolaris.org int s_slot_num; 547302Sgdamore@opensolaris.org boolean_t s_inserted; 557302Sgdamore@opensolaris.org boolean_t s_failed; 568289Sgdamore@opensolaris.org 577302Sgdamore@opensolaris.org uint8_t s_num_io; 587302Sgdamore@opensolaris.org uint32_t s_cur_ocr; /* current ocr */ 597302Sgdamore@opensolaris.org 607302Sgdamore@opensolaris.org uint16_t s_rca; 617302Sgdamore@opensolaris.org uint32_t s_maxclk; /* maximum freq for card */ 627302Sgdamore@opensolaris.org 637302Sgdamore@opensolaris.org sda_cmd_t *s_xfrp; /* pending transfer cmd */ 647302Sgdamore@opensolaris.org hrtime_t s_xfrtmo; /* transfer timeout */ 657302Sgdamore@opensolaris.org 667302Sgdamore@opensolaris.org boolean_t s_reap; 677302Sgdamore@opensolaris.org boolean_t s_warn; 687302Sgdamore@opensolaris.org boolean_t s_ready; /* target node ready */ 697302Sgdamore@opensolaris.org boolean_t s_init; /* slot initializing */ 707302Sgdamore@opensolaris.org 717302Sgdamore@opensolaris.org /* these are protected by the evlock */ 727302Sgdamore@opensolaris.org boolean_t s_wake; /* wake up thread */ 737302Sgdamore@opensolaris.org boolean_t s_detach; /* detach in progress */ 748289Sgdamore@opensolaris.org boolean_t s_suspend; /* host has DDI_SUSPENDed */ 757302Sgdamore@opensolaris.org boolean_t s_detect; /* detect event occurred */ 767302Sgdamore@opensolaris.org sda_fault_t s_fault; 777302Sgdamore@opensolaris.org boolean_t s_xfrdone; /* transfer event occurred */ 787302Sgdamore@opensolaris.org sda_err_t s_errno; 797302Sgdamore@opensolaris.org 807302Sgdamore@opensolaris.org uint16_t s_flags; 817302Sgdamore@opensolaris.org #define SLOTF_WRITABLE 0x0004 827302Sgdamore@opensolaris.org #define SLOTF_4BITS 0x0008 837302Sgdamore@opensolaris.org #define SLOTF_IFCOND 0x0010 847302Sgdamore@opensolaris.org #define SLOTF_MMC 0x0020 857302Sgdamore@opensolaris.org #define SLOTF_SDMEM 0x0040 867302Sgdamore@opensolaris.org #define SLOTF_SDIO 0x0080 877302Sgdamore@opensolaris.org #define SLOTF_SDHC 0x0100 887302Sgdamore@opensolaris.org #define SLOTF_MEMORY (SLOTF_MMC | SLOTF_SDMEM) 897302Sgdamore@opensolaris.org #define SLOTF_SD (SLOTF_SDMEM | SLOTF_SDIO) 907302Sgdamore@opensolaris.org 917302Sgdamore@opensolaris.org uint16_t s_caps; 927302Sgdamore@opensolaris.org #define SLOT_CAP_NOPIO 0x0002 937302Sgdamore@opensolaris.org #define SLOT_CAP_HISPEED 0x0004 947302Sgdamore@opensolaris.org #define SLOT_CAP_4BITS 0x0008 957302Sgdamore@opensolaris.org 967302Sgdamore@opensolaris.org list_t s_cmdlist; 977302Sgdamore@opensolaris.org list_t s_abortlist; 987302Sgdamore@opensolaris.org 997302Sgdamore@opensolaris.org /* 1007302Sgdamore@opensolaris.org * Slot operations. Slot local copy for performance. 1017302Sgdamore@opensolaris.org */ 1027302Sgdamore@opensolaris.org sda_ops_t s_ops; 1037302Sgdamore@opensolaris.org 1047302Sgdamore@opensolaris.org /* 1057302Sgdamore@opensolaris.org * Recursive locking of slot. 1067302Sgdamore@opensolaris.org */ 1077302Sgdamore@opensolaris.org kmutex_t s_lock; 1087302Sgdamore@opensolaris.org kcondvar_t s_cv; 1097302Sgdamore@opensolaris.org kt_did_t s_owner; /* owner holding the slot */ 1107302Sgdamore@opensolaris.org uint32_t s_circular; /* circular sda_slot_enter() calls */ 1117302Sgdamore@opensolaris.org 1127302Sgdamore@opensolaris.org /* 1137302Sgdamore@opensolaris.org * Event notification/thread wakeup. 1147302Sgdamore@opensolaris.org */ 1157302Sgdamore@opensolaris.org kmutex_t s_evlock; 1167302Sgdamore@opensolaris.org kcondvar_t s_evcv; 1177302Sgdamore@opensolaris.org 1187302Sgdamore@opensolaris.org /* 1197302Sgdamore@opensolaris.org * Asynch. threads. 1207302Sgdamore@opensolaris.org */ 1218289Sgdamore@opensolaris.org ddi_taskq_t *s_hp_tq; /* insert taskq */ 1228289Sgdamore@opensolaris.org ddi_taskq_t *s_main_tq; /* main processing taskq */ 1237302Sgdamore@opensolaris.org 1247302Sgdamore@opensolaris.org /* 1257302Sgdamore@opensolaris.org * Timestamping for cfgadm benefit. 1267302Sgdamore@opensolaris.org */ 1277302Sgdamore@opensolaris.org uint8_t s_intransit; 1287302Sgdamore@opensolaris.org time_t s_stamp; 1297302Sgdamore@opensolaris.org 1307302Sgdamore@opensolaris.org /* 1317302Sgdamore@opensolaris.org * Memory card-specific. 1327302Sgdamore@opensolaris.org */ 1337302Sgdamore@opensolaris.org uint32_t s_rcsd[4]; /* raw csd */ 1347302Sgdamore@opensolaris.org uint32_t s_rcid[4]; /* raw cid */ 1357302Sgdamore@opensolaris.org uint32_t s_nblks; /* total blocks on device */ 1367302Sgdamore@opensolaris.org uint16_t s_blksz; /* device block size (typ. 512) */ 1377302Sgdamore@opensolaris.org uint16_t s_bshift; /* block address shift factor */ 1387302Sgdamore@opensolaris.org uint32_t s_speed; /* max memory clock in hz */ 1397302Sgdamore@opensolaris.org 1407302Sgdamore@opensolaris.org /* Other CID and CSD values */ 1417302Sgdamore@opensolaris.org uint32_t s_mfg; /* mfg id */ 1427302Sgdamore@opensolaris.org char s_prod[8]; /* product id */ 1437302Sgdamore@opensolaris.org char s_oem[2]; /* oem id */ 1447302Sgdamore@opensolaris.org uint32_t s_serial; 1457302Sgdamore@opensolaris.org uint8_t s_majver; 1467302Sgdamore@opensolaris.org uint8_t s_minver; 1477302Sgdamore@opensolaris.org uint16_t s_year; 1487302Sgdamore@opensolaris.org uint8_t s_month; 1497302Sgdamore@opensolaris.org 1507302Sgdamore@opensolaris.org uint16_t s_ccc; /* card command classes */ 1517302Sgdamore@opensolaris.org uint8_t s_r2w; /* read/write factor */ 1527302Sgdamore@opensolaris.org uint8_t s_dsr; /* DSR implemented? */ 1537302Sgdamore@opensolaris.org uint8_t s_perm_wp; /* permanent write protect set? */ 1547302Sgdamore@opensolaris.org uint8_t s_temp_wp; /* temporary write protect set? */ 1557302Sgdamore@opensolaris.org 156*12426Sgdamore@opensolaris.org bd_handle_t s_bdh; /* block dev handle */ 1577302Sgdamore@opensolaris.org }; 1587302Sgdamore@opensolaris.org 1597302Sgdamore@opensolaris.org /* 1607302Sgdamore@opensolaris.org * Per host state. One per devinfo node. There could be multiple 1617302Sgdamore@opensolaris.org * slots per devinfo node. 1627302Sgdamore@opensolaris.org */ 1637302Sgdamore@opensolaris.org struct sda_host { 1647302Sgdamore@opensolaris.org dev_info_t *h_dip; 1657302Sgdamore@opensolaris.org int h_nslot; 1667302Sgdamore@opensolaris.org sda_slot_t *h_slots; 1677302Sgdamore@opensolaris.org ddi_dma_attr_t *h_dma; /* dma attr, needed for mem */ 1687302Sgdamore@opensolaris.org 1697302Sgdamore@opensolaris.org list_node_t h_node; /* nexus node linkage */ 1707302Sgdamore@opensolaris.org 1717302Sgdamore@opensolaris.org uint32_t h_flags; 1727302Sgdamore@opensolaris.org #define HOST_ATTACH (1U << 0) /* host attach completed */ 1737302Sgdamore@opensolaris.org #define HOST_XOPEN (1U << 2) /* exclusive open */ 1747302Sgdamore@opensolaris.org #define HOST_SOPEN (1U << 3) /* shared open */ 1757302Sgdamore@opensolaris.org }; 1767302Sgdamore@opensolaris.org 1777302Sgdamore@opensolaris.org /* 1787302Sgdamore@opensolaris.org * Useful function-like macros. 1797302Sgdamore@opensolaris.org */ 1807302Sgdamore@opensolaris.org #define sda_setprop(s, p, v) s->s_ops.so_setprop(s->s_prv, p, v) 1817302Sgdamore@opensolaris.org #define sda_getprop(s, p, v) s->s_ops.so_getprop(s->s_prv, p, v) 1827302Sgdamore@opensolaris.org 1837302Sgdamore@opensolaris.org /* 1847302Sgdamore@opensolaris.org * sda_cmd.c 1857302Sgdamore@opensolaris.org */ 1867302Sgdamore@opensolaris.org void sda_cmd_init(void); 1877302Sgdamore@opensolaris.org void sda_cmd_fini(void); 1887302Sgdamore@opensolaris.org void sda_cmd_list_init(list_t *); 1897302Sgdamore@opensolaris.org void sda_cmd_list_fini(list_t *); 1907302Sgdamore@opensolaris.org sda_cmd_t *sda_cmd_alloc(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t, 1917302Sgdamore@opensolaris.org void *, int); 1927302Sgdamore@opensolaris.org sda_cmd_t *sda_cmd_alloc_acmd(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t, 1937302Sgdamore@opensolaris.org void *, int); 1947302Sgdamore@opensolaris.org void sda_cmd_free(sda_cmd_t *); 1957302Sgdamore@opensolaris.org sda_err_t sda_cmd_errno(sda_cmd_t *); 1967302Sgdamore@opensolaris.org void *sda_cmd_data(sda_cmd_t *); 1977302Sgdamore@opensolaris.org void sda_cmd_submit(sda_slot_t *, sda_cmd_t *, void (*)(sda_cmd_t *)); 1987302Sgdamore@opensolaris.org void sda_cmd_resubmit_acmd(sda_slot_t *, sda_cmd_t *); 1997302Sgdamore@opensolaris.org void sda_cmd_notify(sda_cmd_t *, uint16_t, sda_err_t); 2007302Sgdamore@opensolaris.org sda_err_t sda_cmd_exec(sda_slot_t *, sda_cmd_t *, uint32_t *); 2017302Sgdamore@opensolaris.org 2027302Sgdamore@opensolaris.org /* 2037302Sgdamore@opensolaris.org * sda_init.c 2047302Sgdamore@opensolaris.org */ 2057302Sgdamore@opensolaris.org sda_err_t sda_init_card(sda_slot_t *); 2067302Sgdamore@opensolaris.org 2077302Sgdamore@opensolaris.org /* 2087302Sgdamore@opensolaris.org * sda_mem.c 2097302Sgdamore@opensolaris.org */ 2107302Sgdamore@opensolaris.org void sda_mem_init(struct modlinkage *); 2117302Sgdamore@opensolaris.org void sda_mem_fini(struct modlinkage *); 2127302Sgdamore@opensolaris.org uint32_t sda_mem_maxclk(sda_slot_t *); 2137302Sgdamore@opensolaris.org uint32_t sda_mem_getbits(uint32_t *, int, int); 214*12426Sgdamore@opensolaris.org int sda_mem_parse_cid_csd(sda_slot_t *); 215*12426Sgdamore@opensolaris.org int sda_mem_bd_read(void *, bd_xfer_t *); 216*12426Sgdamore@opensolaris.org int sda_mem_bd_write(void *, bd_xfer_t *); 217*12426Sgdamore@opensolaris.org void sda_mem_bd_driveinfo(void *, bd_drive_t *); 218*12426Sgdamore@opensolaris.org int sda_mem_bd_mediainfo(void *, bd_media_t *); 2197302Sgdamore@opensolaris.org 2207302Sgdamore@opensolaris.org 2217302Sgdamore@opensolaris.org /* 2227302Sgdamore@opensolaris.org * sda_nexus.c 2237302Sgdamore@opensolaris.org */ 2247302Sgdamore@opensolaris.org void sda_nexus_init(void); 2257302Sgdamore@opensolaris.org void sda_nexus_fini(void); 2267302Sgdamore@opensolaris.org void sda_nexus_register(sda_host_t *); 2277302Sgdamore@opensolaris.org void sda_nexus_unregister(sda_host_t *); 2287302Sgdamore@opensolaris.org int sda_nexus_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 2297302Sgdamore@opensolaris.org int sda_nexus_open(dev_t *, int, int, cred_t *); 2307302Sgdamore@opensolaris.org int sda_nexus_close(dev_t, int, int, cred_t *); 2317302Sgdamore@opensolaris.org int sda_nexus_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 2327302Sgdamore@opensolaris.org int sda_nexus_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *, 2337302Sgdamore@opensolaris.org void *); 2347302Sgdamore@opensolaris.org void sda_nexus_remove(sda_slot_t *); 2357302Sgdamore@opensolaris.org void sda_nexus_insert(sda_slot_t *); 2367302Sgdamore@opensolaris.org void sda_nexus_reap(void *); 2377302Sgdamore@opensolaris.org 2387302Sgdamore@opensolaris.org /* 2397302Sgdamore@opensolaris.org * sda_slot.c 2407302Sgdamore@opensolaris.org */ 2417302Sgdamore@opensolaris.org void sda_slot_init(sda_slot_t *); 2427302Sgdamore@opensolaris.org void sda_slot_fini(sda_slot_t *); 2437302Sgdamore@opensolaris.org void sda_slot_enter(sda_slot_t *); 2447302Sgdamore@opensolaris.org void sda_slot_exit(sda_slot_t *); 2457302Sgdamore@opensolaris.org boolean_t sda_slot_owned(sda_slot_t *); 2467302Sgdamore@opensolaris.org void sda_slot_attach(sda_slot_t *); 2477302Sgdamore@opensolaris.org void sda_slot_detach(sda_slot_t *); 2488289Sgdamore@opensolaris.org void sda_slot_suspend(sda_slot_t *); 2498289Sgdamore@opensolaris.org void sda_slot_resume(sda_slot_t *); 2507302Sgdamore@opensolaris.org void sda_slot_reset(sda_slot_t *); 2517302Sgdamore@opensolaris.org void sda_slot_wakeup(sda_slot_t *); 2527302Sgdamore@opensolaris.org void sda_slot_detect(sda_slot_t *); 2537302Sgdamore@opensolaris.org int sda_slot_power_on(sda_slot_t *); 2547302Sgdamore@opensolaris.org void sda_slot_power_off(sda_slot_t *); 2557302Sgdamore@opensolaris.org void sda_slot_reset(sda_slot_t *); 2567302Sgdamore@opensolaris.org void sda_slot_shutdown(sda_slot_t *); 2577302Sgdamore@opensolaris.org void sda_slot_transfer(sda_slot_t *, sda_err_t); 2587302Sgdamore@opensolaris.org void sda_slot_fault(sda_slot_t *, sda_fault_t); 2597302Sgdamore@opensolaris.org /*PRINTFLIKE2*/ 2607302Sgdamore@opensolaris.org void sda_slot_err(sda_slot_t *, const char *, ...); 2617302Sgdamore@opensolaris.org /*PRINTFLIKE2*/ 2627302Sgdamore@opensolaris.org void sda_slot_log(sda_slot_t *, const char *, ...); 2637302Sgdamore@opensolaris.org 2647302Sgdamore@opensolaris.org #ifdef DEBUG 2657302Sgdamore@opensolaris.org #define sda_slot_debug(...) sda_slot_log(__VA_ARGS__) 2667302Sgdamore@opensolaris.org #else 2677302Sgdamore@opensolaris.org #define sda_slot_debug(...) 2687302Sgdamore@opensolaris.org #endif 2697302Sgdamore@opensolaris.org 2707302Sgdamore@opensolaris.org #ifdef __cplusplus 2717302Sgdamore@opensolaris.org } 2727302Sgdamore@opensolaris.org #endif 2737302Sgdamore@opensolaris.org 2747302Sgdamore@opensolaris.org #endif /* _SYS_SDCARD_SDA_IMPL_H */ 275