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 */