#ifndef _AAC_H_
#define _AAC_H_
#ifdef __cplusplus
extern "C" {
#endif
#define AAC_ROUNDUP(x, y) (((x) + (y) - 1) / (y) * (y))
#define AAC_TYPE_DEVO 1
#define AAC_TYPE_ALPHA 2
#define AAC_TYPE_BETA 3
#define AAC_TYPE_RELEASE 4
#ifndef AAC_DRIVER_BUILD
#define AAC_DRIVER_BUILD 1
#endif
#define AAC_DRIVER_MAJOR_VERSION 2
#define AAC_DRIVER_MINOR_VERSION 2
#define AAC_DRIVER_BUGFIX_LEVEL 11
#define AAC_DRIVER_TYPE AAC_TYPE_RELEASE
#define STR(s) # s
#define AAC_VERSION(a, b, c) STR(a.b.c)
#define AAC_DRIVER_VERSION AAC_VERSION(AAC_DRIVER_MAJOR_VERSION, \
AAC_DRIVER_MINOR_VERSION, \
AAC_DRIVER_BUGFIX_LEVEL)
#define AACOK 0
#define AACERR -1
#define AAC_MAX_ADAPTERS 64
#ifndef SD_MODE_SENSE_PAGE3_CODE
#define SD_MODE_SENSE_PAGE3_CODE 0x03
#endif
#ifndef SD_MODE_SENSE_PAGE4_CODE
#define SD_MODE_SENSE_PAGE4_CODE 0x04
#endif
#ifndef SCMD_SYNCHRONIZE_CACHE
#define SCMD_SYNCHRONIZE_CACHE 0x35
#endif
#define AAC_AIFQ_LENGTH 64
#ifdef __x86
#define AAC_IMMEDIATE_TIMEOUT 30
#else
#define AAC_IMMEDIATE_TIMEOUT 60
#endif
#define AAC_FWUP_TIMEOUT 180
#define AAC_IOCTL_TIMEOUT 900
#define AAC_SYNC_TIMEOUT 900
#define AAC_HWIF_UNKNOWN 0
#define AAC_HWIF_I960RX 1
#define AAC_HWIF_RKT 2
#define AAC_TYPE_UNKNOWN 0
#define AAC_TYPE_SCSI 1
#define AAC_TYPE_SATA 2
#define AAC_TYPE_SAS 3
#define AAC_LS32(d) ((uint32_t)((d) & 0xffffffffull))
#define AAC_MS32(d) ((uint32_t)((d) >> 32))
#define AAC_LO32(p64) ((uint32_t *)(p64))
#define AAC_HI32(p64) ((uint32_t *)(p64) + 1)
#define AAC_EVENT_AIF (1 << 0)
#define AAC_EVENT_TIMEOUT (1 << 1)
#define AAC_EVENT_SYNCTICK (1 << 2)
enum aac_cmdq {
AAC_CMDQ_SYNC,
AAC_CMDQ_ASYNC,
AAC_CMDQ_NUM
};
#define AAC_IOCMD_SYNC (1 << AAC_CMDQ_SYNC)
#define AAC_IOCMD_ASYNC (1 << AAC_CMDQ_ASYNC)
#define AAC_IOCMD_OUTSTANDING (1 << AAC_CMDQ_NUM)
#define AAC_IOCMD_ALL (AAC_IOCMD_SYNC | AAC_IOCMD_ASYNC | \
AAC_IOCMD_OUTSTANDING)
struct aac_cmd_queue {
struct aac_cmd *q_head;
struct aac_cmd *q_tail;
};
struct aac_card_type {
uint16_t vendor;
uint16_t device;
uint16_t subvendor;
uint16_t subsys;
uint16_t hwif;
uint16_t quirks;
uint16_t type;
char *vid;
char *desc;
};
#define AAC_DEV_LD 0
#define AAC_DEV_PD 1
#define AAC_DFLAG_VALID (1 << 0)
#define AAC_DFLAG_CONFIGURING (1 << 1)
#define AAC_DEV_IS_VALID(dvp) ((dvp)->flags & AAC_DFLAG_VALID)
#define AAC_P2VTGT(softs, bus, tgt) \
((softs)->tgt_max * (bus) + (tgt) + AAC_MAX_LD)
enum aac_cfg_event {
AAC_CFG_NULL_NOEXIST = 0,
AAC_CFG_NULL_EXIST,
AAC_CFG_ADD,
AAC_CFG_DELETE,
AAC_CFG_CHANGE
};
struct aac_device {
int flags;
uint8_t type;
dev_info_t *dip;
int ncmds[AAC_CMDQ_NUM];
int throttle[AAC_CMDQ_NUM];
};
struct aac_container {
struct aac_device dev;
uint32_t cid;
uint32_t uid;
uint64_t size;
uint8_t locked;
uint8_t deleted;
uint8_t reset;
};
struct aac_nondasd {
struct aac_device dev;
uint32_t bus;
uint32_t tid;
};
struct aac_slot {
struct aac_slot *next;
int index;
ddi_acc_handle_t fib_acc_handle;
ddi_dma_handle_t fib_dma_handle;
uint64_t fib_phyaddr;
struct aac_cmd *acp;
struct aac_fib *fibp;
};
struct aac_sge {
uint32_t bcount;
union {
uint32_t ad32;
struct {
uint32_t lo;
uint32_t hi;
} ad64;
} addr;
};
#define AAC_CMD_CONSISTENT (1 << 0)
#define AAC_CMD_DMA_PARTIAL (1 << 1)
#define AAC_CMD_DMA_VALID (1 << 2)
#define AAC_CMD_BUF_READ (1 << 3)
#define AAC_CMD_BUF_WRITE (1 << 4)
#define AAC_CMD_SYNC (1 << 5)
#define AAC_CMD_NO_INTR (1 << 6)
#define AAC_CMD_NO_CB (1 << 7)
#define AAC_CMD_NTAG (1 << 8)
#define AAC_CMD_CMPLT (1 << 9)
#define AAC_CMD_ABORT (1 << 10)
#define AAC_CMD_TIMEOUT (1 << 11)
#define AAC_CMD_ERR (1 << 12)
#define AAC_CMD_IN_SYNC_SLOT (1 << 13)
struct aac_softstate;
typedef void (*aac_cmd_fib_t)(struct aac_softstate *, struct aac_cmd *);
struct aac_cmd {
struct aac_cmd *next;
struct aac_cmd *prev;
struct scsi_pkt *pkt;
int cmdlen;
int flags;
uint32_t timeout;
struct buf *bp;
ddi_dma_handle_t buf_dma_handle;
caddr_t abp;
ddi_acc_handle_t abh;
ddi_dma_cookie_t cookie;
uint_t left_cookien;
uint_t cur_win;
uint_t total_nwin;
size_t total_xfer;
uint64_t blkno;
uint32_t bcount;
struct aac_sge *sgt;
aac_cmd_fib_t aac_cmd_fib;
void (*ac_comp)(struct aac_softstate *, struct aac_cmd *);
struct aac_slot *slotp;
struct aac_device *dvp;
int fib_size;
struct aac_fib *fibp;
#ifdef DEBUG
uint32_t fib_flags;
#endif
};
#define AAC_ATTACH_SOFTSTATE_ALLOCED (1 << 0)
#define AAC_ATTACH_CARD_DETECTED (1 << 1)
#define AAC_ATTACH_PCI_MEM_MAPPED (1 << 2)
#define AAC_ATTACH_KMUTEX_INITED (1 << 3)
#define AAC_ATTACH_SCSI_TRAN_SETUP (1 << 4)
#define AAC_ATTACH_COMM_SPACE_SETUP (1 << 5)
#define AAC_ATTACH_CREATE_DEVCTL (1 << 6)
#define AAC_ATTACH_CREATE_SCSI (1 << 7)
#define AAC_STATE_STOPPED 0
#define AAC_STATE_RUN (1 << 0)
#define AAC_STATE_RESET (1 << 1)
#define AAC_STATE_QUIESCED (1 << 2)
#define AAC_STATE_DEAD (1 << 3)
#define AAC_STATE_INTR (1 << 4)
#define AAC_FLAGS_SG_64BIT (1 << 0)
#define AAC_FLAGS_4GB_WINDOW (1 << 1)
#define AAC_FLAGS_NO4GB (1 << 2)
#define AAC_FLAGS_256FIBS (1 << 3)
#define AAC_FLAGS_NEW_COMM (1 << 4)
#define AAC_FLAGS_RAW_IO (1 << 5)
#define AAC_FLAGS_ARRAY_64BIT (1 << 6)
#define AAC_FLAGS_LBA_64BIT (1 << 7)
#define AAC_FLAGS_17SG (1 << 8)
#define AAC_FLAGS_34SG (1 << 9)
#define AAC_FLAGS_NONDASD (1 << 10)
#define AAC_FLAGS_BRKUP (1 << 11)
#define AAC_FLAGS_JBOD (1 << 12)
struct aac_softstate;
struct aac_interface {
int (*aif_get_fwstatus)(struct aac_softstate *);
int (*aif_get_mailbox)(struct aac_softstate *, int);
void (*aif_set_mailbox)(struct aac_softstate *, uint32_t,
uint32_t, uint32_t, uint32_t, uint32_t);
};
#define AAC_CTXFLAG_FILLED 0x01
#define AAC_CTXFLAG_RESETED 0x02
struct aac_fib_context {
uint32_t unique;
int ctx_idx;
int ctx_filled;
int ctx_flags;
int ctx_overrun;
struct aac_fib_context *next, *prev;
};
#define AAC_VENDOR_LEN 8
#define AAC_PRODUCT_LEN 16
struct aac_softstate {
int card;
uint16_t hwif;
uint16_t vendid;
uint16_t subvendid;
uint16_t devid;
uint16_t subsysid;
char vendor_name[AAC_VENDOR_LEN + 1];
char product_name[AAC_PRODUCT_LEN + 1];
uint32_t support_opt;
uint32_t support_opt2;
uint32_t feature_bits;
uint32_t atu_size;
uint32_t map_size;
uint32_t map_size_min;
int flags;
int instance;
dev_info_t *devinfo_p;
scsi_hba_tran_t *hba_tran;
int slen;
int legacy;
uint32_t dma_max;
ddi_dma_attr_t buf_dma_attr;
ddi_dma_attr_t addr_dma_attr;
ddi_device_acc_attr_t acc_attr;
ddi_device_acc_attr_t reg_attr;
ddi_acc_handle_t pci_mem_handle;
uint8_t *pci_mem_base_vaddr;
uint32_t pci_mem_base_paddr;
struct aac_interface aac_if;
struct aac_cmd sync_ac;
struct aac_comm_space *comm_space;
ddi_acc_handle_t comm_space_acc_handle;
ddi_dma_handle_t comm_space_dma_handle;
uint32_t comm_space_phyaddr;
struct aac_queue_table *qtablep;
struct aac_queue_entry *qentries[AAC_QUEUE_COUNT];
uint32_t aac_max_fibs;
uint32_t aac_max_fib_size;
uint32_t aac_sg_tablesize;
uint32_t aac_max_sectors;
aac_cmd_fib_t aac_cmd_fib;
aac_cmd_fib_t aac_cmd_fib_scsi;
ddi_softintr_t softint_id;
kmutex_t io_lock;
int state;
struct aac_container containers[AAC_MAX_LD];
int container_count;
struct aac_nondasd *nondasds;
uint32_t bus_max;
uint32_t tgt_max;
struct aac_cmd_queue q_wait[AAC_CMDQ_NUM];
struct aac_cmd_queue q_busy;
kmutex_t q_comp_mutex;
struct aac_cmd_queue q_comp;
int total_slots;
int total_fibs;
struct aac_slot *io_slot;
struct aac_slot *free_io_slot_head;
kcondvar_t event;
kcondvar_t sync_fib_cv;
int bus_ncmds[AAC_CMDQ_NUM];
int bus_throttle[AAC_CMDQ_NUM];
int ndrains;
timeout_id_t drain_timeid;
kcondvar_t drain_cv;
kmutex_t time_mutex;
timeout_id_t timeout_id;
uint32_t timebase;
uint32_t time_sync;
uint32_t time_out;
uint32_t time_throttle;
kmutex_t ev_lock;
int events;
kthread_t *event_thread;
kcondvar_t event_wait_cv;
kcondvar_t event_disp_cv;
kmutex_t aifq_mutex;
kcondvar_t aifq_cv;
union aac_fib_align aifq[AAC_AIFQ_LENGTH];
int aifq_idx;
int aifq_wrap;
struct aac_fib_context aifctx;
struct aac_fib_context *fibctx_p;
int devcfg_wait_on;
int fm_capabilities;
ddi_intr_handle_t *htable;
int intr_type;
int intr_cnt;
int intr_size;
uint_t intr_pri;
int intr_cap;
#ifdef DEBUG
uint32_t debug_flags;
uint32_t debug_fib_flags;
uint32_t debug_fw_flags;
uint32_t debug_buf_offset;
uint32_t debug_buf_size;
uint32_t debug_header_size;
#endif
};
_NOTE(SCHEME_PROTECTS_DATA("stable data", aac_softstate::{flags slen \
buf_dma_attr pci_mem_handle pci_mem_base_vaddr \
comm_space_acc_handle comm_space_dma_handle aac_max_fib_size \
aac_sg_tablesize aac_cmd_fib aac_cmd_fib_scsi debug_flags bus_max tgt_max}))
#ifdef DEBUG
#define AACDB_FLAGS_MASK 0x0000ffff
#define AACDB_FLAGS_KERNEL_PRINT 0x00000001
#define AACDB_FLAGS_FW_PRINT 0x00000002
#define AACDB_FLAGS_NO_HEADERS 0x00000004
#define AACDB_FLAGS_MISC 0x00000010
#define AACDB_FLAGS_FUNC1 0x00000020
#define AACDB_FLAGS_FUNC2 0x00000040
#define AACDB_FLAGS_SCMD 0x00000080
#define AACDB_FLAGS_AIF 0x00000100
#define AACDB_FLAGS_FIB 0x00000200
#define AACDB_FLAGS_IOCTL 0x00000400
#define AACDB_FLAGS_FIB_SCMD 0x00000001
#define AACDB_FLAGS_FIB_IOCTL 0x00000002
#define AACDB_FLAGS_FIB_SRB 0x00000004
#define AACDB_FLAGS_FIB_SYNC 0x00000008
#define AACDB_FLAGS_FIB_HEADER 0x00000010
#define AACDB_FLAGS_FIB_TIMEOUT 0x00000100
extern uint32_t aac_debug_flags;
extern int aac_dbflag_on(struct aac_softstate *, int);
extern void aac_printf(struct aac_softstate *, uint_t, const char *, ...);
extern void aac_print_fib(struct aac_softstate *, struct aac_slot *);
#define AACDB_PRINT(s, lev, ...) { \
if (aac_dbflag_on((s), AACDB_FLAGS_MISC)) \
aac_printf((s), (lev), __VA_ARGS__); }
#define AACDB_PRINT_IOCTL(s, ...) { \
if (aac_dbflag_on((s), AACDB_FLAGS_IOCTL)) \
aac_printf((s), CE_NOTE, __VA_ARGS__); }
#define AACDB_PRINT_TRAN(s, ...) { \
if (aac_dbflag_on((s), AACDB_FLAGS_SCMD)) \
aac_printf((s), CE_NOTE, __VA_ARGS__); }
#define DBCALLED(s, n) { \
if (aac_dbflag_on((s), AACDB_FLAGS_FUNC ## n)) \
aac_printf((s), CE_NOTE, "--- %s() called ---", __func__); }
#define AACDB_PRINT_SCMD(s, x) { \
if (aac_dbflag_on((s), AACDB_FLAGS_SCMD)) aac_print_scmd((s), (x)); }
#define AACDB_PRINT_AIF(s, x) { \
if (aac_dbflag_on((s), AACDB_FLAGS_AIF)) aac_print_aif((s), (x)); }
#define AACDB_PRINT_FIB(s, x) { \
if (aac_dbflag_on((s), AACDB_FLAGS_FIB)) aac_print_fib((s), (x)); }
#else
#define AACDB_PRINT(s, lev, ...)
#define AACDB_PRINT_IOCTL(s, ...)
#define AACDB_PRINT_TRAN(s, ...)
#define AACDB_PRINT_FIB(s, x)
#define AACDB_PRINT_SCMD(s, x)
#define AACDB_PRINT_AIF(s, x)
#define DBCALLED(s, n)
#endif
#ifdef __cplusplus
}
#endif
#endif