xref: /onnv-gate/usr/src/uts/common/sys/sdcard/sda_impl.h (revision 12426:cdff5d2ea989)
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