#ifndef _SYS_SDCARD_SDA_IMPL_H
#define _SYS_SDCARD_SDA_IMPL_H
#include <sys/list.h>
#include <sys/ksynch.h>
#include <sys/note.h>
#include <sys/blkdev.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sdcard/sda.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct sda_slot sda_slot_t;
struct sda_slot {
sda_host_t *s_hostp;
void *s_prv;
dev_info_t *s_dip;
int s_slot_num;
boolean_t s_inserted;
boolean_t s_failed;
uint8_t s_num_io;
uint32_t s_cur_ocr;
uint16_t s_rca;
uint32_t s_maxclk;
sda_cmd_t *s_xfrp;
hrtime_t s_xfrtmo;
boolean_t s_reap;
boolean_t s_warn;
boolean_t s_ready;
boolean_t s_init;
boolean_t s_wake;
boolean_t s_detach;
boolean_t s_suspend;
boolean_t s_detect;
sda_fault_t s_fault;
boolean_t s_xfrdone;
sda_err_t s_errno;
uint16_t s_flags;
#define SLOTF_WRITABLE 0x0004
#define SLOTF_4BITS 0x0008
#define SLOTF_IFCOND 0x0010
#define SLOTF_MMC 0x0020
#define SLOTF_SDMEM 0x0040
#define SLOTF_SDIO 0x0080
#define SLOTF_SDHC 0x0100
#define SLOTF_MEMORY (SLOTF_MMC | SLOTF_SDMEM)
#define SLOTF_SD (SLOTF_SDMEM | SLOTF_SDIO)
uint16_t s_caps;
#define SLOT_CAP_NOPIO 0x0002
#define SLOT_CAP_HISPEED 0x0004
#define SLOT_CAP_4BITS 0x0008
list_t s_cmdlist;
list_t s_abortlist;
sda_ops_t s_ops;
kmutex_t s_lock;
kcondvar_t s_cv;
kt_did_t s_owner;
uint32_t s_circular;
kmutex_t s_evlock;
kcondvar_t s_evcv;
ddi_taskq_t *s_hp_tq;
ddi_taskq_t *s_main_tq;
uint8_t s_intransit;
time_t s_stamp;
uint32_t s_rcsd[4];
uint32_t s_rcid[4];
uint32_t s_nblks;
uint16_t s_blksz;
uint16_t s_bshift;
uint32_t s_speed;
uint32_t s_mfg;
char s_prod[8];
char s_oem[2];
uint32_t s_serial;
uint8_t s_majver;
uint8_t s_minver;
uint16_t s_year;
uint8_t s_month;
uint16_t s_ccc;
uint8_t s_r2w;
uint8_t s_dsr;
uint8_t s_perm_wp;
uint8_t s_temp_wp;
bd_handle_t s_bdh;
};
struct sda_host {
dev_info_t *h_dip;
int h_nslot;
sda_slot_t *h_slots;
ddi_dma_attr_t *h_dma;
list_node_t h_node;
uint32_t h_flags;
#define HOST_ATTACH (1U << 0)
#define HOST_XOPEN (1U << 2)
#define HOST_SOPEN (1U << 3)
};
#define sda_setprop(s, p, v) s->s_ops.so_setprop(s->s_prv, p, v)
#define sda_getprop(s, p, v) s->s_ops.so_getprop(s->s_prv, p, v)
void sda_cmd_init(void);
void sda_cmd_fini(void);
void sda_cmd_list_init(list_t *);
void sda_cmd_list_fini(list_t *);
sda_cmd_t *sda_cmd_alloc(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t,
void *, int);
sda_cmd_t *sda_cmd_alloc_acmd(sda_slot_t *, sda_index_t, uint32_t, sda_rtype_t,
void *, int);
void sda_cmd_free(sda_cmd_t *);
sda_err_t sda_cmd_errno(sda_cmd_t *);
void *sda_cmd_data(sda_cmd_t *);
void sda_cmd_submit(sda_slot_t *, sda_cmd_t *, void (*)(sda_cmd_t *));
void sda_cmd_resubmit_acmd(sda_slot_t *, sda_cmd_t *);
void sda_cmd_notify(sda_cmd_t *, uint16_t, sda_err_t);
sda_err_t sda_cmd_exec(sda_slot_t *, sda_cmd_t *, uint32_t *);
sda_err_t sda_init_card(sda_slot_t *);
void sda_mem_init(struct modlinkage *);
void sda_mem_fini(struct modlinkage *);
uint32_t sda_mem_maxclk(sda_slot_t *);
uint32_t sda_mem_getbits(uint32_t *, int, int);
int sda_mem_parse_cid_csd(sda_slot_t *);
int sda_mem_bd_read(void *, bd_xfer_t *);
int sda_mem_bd_write(void *, bd_xfer_t *);
void sda_mem_bd_driveinfo(void *, bd_drive_t *);
int sda_mem_bd_mediainfo(void *, bd_media_t *);
void sda_nexus_init(void);
void sda_nexus_fini(void);
void sda_nexus_register(sda_host_t *);
void sda_nexus_unregister(sda_host_t *);
int sda_nexus_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
int sda_nexus_open(dev_t *, int, int, cred_t *);
int sda_nexus_close(dev_t, int, int, cred_t *);
int sda_nexus_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
int sda_nexus_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *,
void *);
void sda_nexus_remove(sda_slot_t *);
void sda_nexus_insert(sda_slot_t *);
void sda_nexus_reap(void *);
void sda_slot_init(sda_slot_t *);
void sda_slot_fini(sda_slot_t *);
void sda_slot_enter(sda_slot_t *);
void sda_slot_exit(sda_slot_t *);
boolean_t sda_slot_owned(sda_slot_t *);
void sda_slot_attach(sda_slot_t *);
void sda_slot_detach(sda_slot_t *);
void sda_slot_suspend(sda_slot_t *);
void sda_slot_resume(sda_slot_t *);
void sda_slot_reset(sda_slot_t *);
void sda_slot_wakeup(sda_slot_t *);
void sda_slot_detect(sda_slot_t *);
int sda_slot_power_on(sda_slot_t *);
void sda_slot_power_off(sda_slot_t *);
void sda_slot_reset(sda_slot_t *);
void sda_slot_shutdown(sda_slot_t *);
void sda_slot_transfer(sda_slot_t *, sda_err_t);
void sda_slot_fault(sda_slot_t *, sda_fault_t);
void sda_slot_err(sda_slot_t *, const char *, ...);
void sda_slot_log(sda_slot_t *, const char *, ...);
#ifdef DEBUG
#define sda_slot_debug(...) sda_slot_log(__VA_ARGS__)
#else
#define sda_slot_debug(...)
#endif
#ifdef __cplusplus
}
#endif
#endif