#ifndef _SYS_SCSI_ADAPTERS_FASVAR_H
#define _SYS_SCSI_ADAPTERS_FASVAR_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/note.h>
#if DEBUG
#define FASDEBUG
#define FASTEST
#endif
#define POLL_TIMEOUT (2 * SCSI_POLL_TIMEOUT * 1000000)
#define SHORT_POLL_TIMEOUT (1000000)
#define FAS_MUTEX(fas) (&(fas)->f_mutex)
#define FAS_CV(fas) (&(fas)->f_cv)
#define FAS_INITIAL_SOFT_SPACE 4
#define FAS_QUIESCE_TIMEOUT 1
struct f_slots {
ushort_t f_dups;
ushort_t f_tags;
int f_timeout;
int f_timebase;
ushort_t f_n_slots;
ushort_t f_size;
struct fas_cmd *f_slot[1];
};
#define FAS_F_SLOTS_SIZE_TQ (sizeof (struct f_slots) + \
(sizeof (struct fas_cmd *) * (NTAGS -1)))
#define FAS_F_SLOT_SIZE (sizeof (struct f_slots))
#define SDEV2TRAN(sd) ((sd)->sd_address.a_hba_tran)
#define SDEV2ADDR(sd) (&((sd)->sd_address))
#define PKT2TRAN(pkt) ((pkt)->pkt_address.a_hba_tran)
#define ADDR2TRAN(ap) ((ap)->a_hba_tran)
#define TRAN2FAS(tran) ((struct fas *)(tran)->tran_hba_private)
#define SDEV2FAS(sd) (TRAN2FAS(SDEV2TRAN(sd)))
#define PKT2FAS(pkt) (TRAN2FAS(PKT2TRAN(pkt)))
#define ADDR2FAS(ap) (TRAN2FAS(ADDR2TRAN(ap)))
#define N_SLOTS (NTARGETS_WIDE*NLUNS_PER_TARGET)
#define REG_TRACE_BUF_SIZE 1024
struct fas {
int f_instance;
scsi_hba_tran_t *f_tran;
dev_info_t *f_dev;
kmutex_t f_mutex;
ddi_iblock_cookie_t f_iblock;
struct fas *f_next;
uchar_t f_type;
uchar_t f_hm_rev;
uint8_t f_fasconf;
uint8_t f_fasconf2;
uint8_t f_fasconf3[NTARGETS_WIDE];
uint8_t f_fasconf3_reg_last;
uchar_t f_clock_conv;
ushort_t f_clock_cycle;
uint8_t f_stval;
uchar_t f_sdtr_sent;
uchar_t f_wdtr_sent;
uchar_t f_stat;
uchar_t f_stat2;
uchar_t f_intr;
uchar_t f_step;
uchar_t f_abort_msg_sent;
uchar_t f_reset_msg_sent;
uchar_t f_last_cmd;
ushort_t f_state;
ushort_t f_laststate;
uchar_t f_suspended;
uchar_t f_dslot;
uchar_t f_idcode;
uchar_t f_polled_intr;
#define OMSGSIZE 12
uchar_t f_cur_msgout[OMSGSIZE];
uchar_t f_last_msgout;
uchar_t f_omsglen;
#define IMSGSIZE 8
uchar_t f_imsgarea[IMSGSIZE];
uchar_t f_imsglen;
uchar_t f_imsgindex;
uchar_t f_last_msgin;
uchar_t f_next_slot;
uchar_t f_resel_slot;
uchar_t f_offset[NTARGETS_WIDE];
uchar_t f_sync_period[NTARGETS_WIDE];
uchar_t f_neg_period[NTARGETS_WIDE];
ushort_t f_backoff;
uchar_t f_req_ack_delay;
uchar_t f_offset_reg_last;
uchar_t f_period_reg_last;
uchar_t f_fifolen;
uchar_t f_fifo[2*FIFOSIZE];
ushort_t f_wide_known;
ushort_t f_nowide;
ushort_t f_wide_enabled;
ushort_t f_sync_known;
ushort_t f_nosync;
ushort_t f_sync_enabled;
ushort_t f_force_async;
ushort_t f_force_narrow;
ushort_t f_notag;
ushort_t f_props_update;
int f_target_scsi_options_defined;
int f_scsi_options;
int f_target_scsi_options[NTARGETS_WIDE];
int f_scsi_tag_age_limit;
uint_t f_scsi_reset_delay;
uchar_t *f_cmdarea;
uint32_t f_dma_csr;
ddi_dma_cookie_t f_dmacookie;
ddi_dma_handle_t f_dmahandle;
ddi_dma_attr_t *f_dma_attr;
short f_ncmds;
short f_ndisc;
volatile struct fasreg *f_reg;
volatile struct dma *f_dma;
uint32_t f_lastdma;
uint32_t f_lastcount;
struct fas_cmd *f_current_sp;
struct f_slots *f_active[N_SLOTS];
struct fas_cmd *f_readyf[N_SLOTS];
struct fas_cmd *f_readyb[N_SLOTS];
short f_throttle[N_SLOTS];
short f_tcmds[N_SLOTS];
int f_reset_delay[NTARGETS_WIDE];
struct fas_cmd *f_arq_pkt[N_SLOTS];
struct fas_cmd *f_c_qf;
struct fas_cmd *f_c_qb;
kmutex_t f_c_mutex;
int f_c_in_callback;
kmutex_t f_waitQ_mutex;
struct fas_cmd *f_waitf;
struct fas_cmd *f_waitb;
struct scsi_reset_notify_entry *f_reset_notify_listf;
uchar_t f_qfull_retries[NTARGETS_WIDE];
ushort_t f_qfull_retry_interval[NTARGETS_WIDE];
timeout_id_t f_restart_cmd_timeid;
struct kmem_cache *f_kmem_cache;
ddi_acc_handle_t f_regs_acc_handle;
ddi_acc_handle_t f_cmdarea_acc_handle;
ddi_acc_handle_t f_dmar_acc_handle;
uint_t f_flags;
kcondvar_t f_cv;
uint_t f_softstate;
timeout_id_t f_quiesce_timeid;
struct kstat *f_intr_kstat;
#ifdef FASDEBUG
uint_t f_reg_trace_index;
uint_t f_reg_trace[REG_TRACE_BUF_SIZE+1];
uint_t f_reserved[256];
uint_t f_reg_reads;
uint_t f_reg_dma_reads;
uint_t f_reg_writes;
uint_t f_reg_dma_writes;
uint_t f_reg_cmds;
uint_t f_total_cmds;
#endif
};
_NOTE(MUTEX_PROTECTS_DATA(fas::f_mutex, fas))
_NOTE(MUTEX_PROTECTS_DATA(fas::f_waitQ_mutex, fas::f_waitf fas::f_waitb))
_NOTE(MUTEX_PROTECTS_DATA(fas::f_c_mutex, fas::f_c_qf fas::f_c_qb
fas::f_c_in_callback))
_NOTE(DATA_READABLE_WITHOUT_LOCK(fas::f_flags))
_NOTE(SCHEME_PROTECTS_DATA("unique per packet or safe sharing",
scsi_cdb scsi_status scsi_pkt buf))
_NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
_NOTE(SCHEME_PROTECTS_DATA("safe sharing", fas::f_next fas::f_state))
_NOTE(SCHEME_PROTECTS_DATA("safe sharing",
fas::f_dma fas::f_dma_attr fas::f_hm_rev))
_NOTE(SCHEME_PROTECTS_DATA("stable data",
fas::f_target_scsi_options fas::f_scsi_options))
_NOTE(SCHEME_PROTECTS_DATA("stable data", fas::f_instance))
_NOTE(SCHEME_PROTECTS_DATA("only debugging",
fas::f_reg_trace_index fas::f_reg_trace))
_NOTE(SCHEME_PROTECTS_DATA("protected by kmem lock", fas::f_kmem_cache))
_NOTE(SCHEME_PROTECTS_DATA("safe sharing",
fas::f_notag fas::f_suspended fas::f_ndisc))
_NOTE(SCHEME_PROTECTS_DATA("stable data", fas::f_dev fas::f_tran))
_NOTE(SCHEME_PROTECTS_DATA("only debugging", fas::f_reg_dma_reads))
_NOTE(SCHEME_PROTECTS_DATA("safe sharing", fas::f_quiesce_timeid))
#define FAS_KSTAT_INTR(fas) KSTAT_INTR_PTR(fas->f_intr_kstat)->\
intrs[KSTAT_INTR_HARD]++
#define DEFAULT_SCSI_OPTIONS SCSI_OPTIONS_DR
#define DEFAULT_TAG_AGE_LIMIT 2
#define DEFAULT_WD_TICK 10
#define FAS_FLG_NOTIMEOUTS 0x0001
#define FAS_CAN_SCHED ((fas->f_flags & FAS_FLG_NOTIMEOUTS) == 0)
#define DEFAULT_REQ_ACK_DELAY 0x50
#define STATE_FREE 0x00
#define STATE_SELECT_NORMAL 0x0100
#define STATE_SELECT_N_STOP 0x0200
#define STATE_SELECT_N_SENDMSG 0x0400
#define STATE_SYNC_ASKING 0x0800
#define STATE_SELECT_N_TAG 0x1000
#define STATE_SELECTING 0xFF00
#define STATE_ITPHASES 0x00FF
#define ACTS_CMD_START 0x01
#define ACTS_CMD_DONE 0x02
#define ACTS_MSG_OUT 0x03
#define ACTS_MSG_OUT_DONE 0x04
#define ACTS_MSG_IN 0x05
#define ACTS_MSG_IN_MORE 0x06
#define ACTS_MSG_IN_DONE 0x07
#define ACTS_CLEARING 0x08
#define ACTS_DATA 0x09
#define ACTS_DATA_DONE 0x0A
#define ACTS_C_CMPLT 0x0B
#define ACTS_RESEL 0x0C
#define ACTS_UNKNOWN 0x0D
#define ACTS_RESET 0x0E
#define ACTS_ENDVEC 0x0E
#define ACTS_ABORTING 0x1D
#define ACTS_FROZEN 0x1F
#define ACTION_RETURN -1
#define ACTION_FINSEL 0x00
#define ACTION_RESEL 0x01
#define ACTION_PHASEMANAGE 0x02
#define ACTION_FINISH 0x03
#define ACTION_FINRST 0x04
#define ACTION_SEARCH 0x05
#define ACTION_ABORT_CURCMD 0x06
#define ACTION_ABORT_ALLCMDS 0x07
#define ACTION_RESET 0x08
#define ACTION_SELECT 0x09
#define FAS_PROXY_TYPE CDB_GROUP0
#define FAS_PROXY_RESULT FAS_PROXY_TYPE+1
#define FAS_PROXY_DATA FAS_PROXY_RESULT+1
#define FAS_PROXY_SNDMSG 1
#define FAS_RESET_FAS 0x1
#define FAS_RESET_DMA 0x2
#define FAS_RESET_BRESET 0x4
#define FAS_RESET_IGNORE_BRESET 0x8
#define FAS_RESET_SCSIBUS (FAS_RESET_BRESET|FAS_RESET_IGNORE_BRESET)
#define FAS_RESET_SOFTC 0x10
#define FAS_RESET_HW (FAS_RESET_FAS|FAS_RESET_DMA|FAS_RESET_SCSIBUS)
#define FAS_RESET_ALL (FAS_RESET_HW|FAS_RESET_SOFTC)
#define FAS_RESET_MSG 0x20
#define FAS_RESET_SPIN_DELAY_USEC 20
#define FAS_RESET_SPIN_MAX_LOOP 1000
#define FAS_SS_DRAINING 0x02
#define FAS_SS_QUIESCED 0x04
#ifdef FASDEBUG
extern void fas_dprintf(struct fas *fas, const char *fmt, ...)
__KPRINTFLIKE(2);
#define INFORMATIVE (fasdebug)
#define IDEBUGGING ((fasdebug) && \
((fas->f_instance == fasdebug_instance) || \
(fasdebug_instance == -1)))
#define DDEBUGGING ((fasdebug > 1) && \
((fas->f_instance == fasdebug_instance) || \
(fasdebug_instance == -1)))
#define EDEBUGGING ((fasdebug > 2) && \
((fas->f_instance == fasdebug_instance) || \
(fasdebug_instance == -1)))
#define EPRINTF(str) if (EDEBUGGING) fas_dprintf(fas, str)
#define EPRINTF1(str, a) if (EDEBUGGING) fas_dprintf(fas, str, a)
#define EPRINTF2(str, a, b) if (EDEBUGGING) fas_dprintf(fas, str, a, b)
#define EPRINTF3(str, a, b, c) if (EDEBUGGING) fas_dprintf(fas, str, a, b, c)
#define EPRINTF4(str, a, b, c, d) \
if (EDEBUGGING) fas_dprintf(fas, str, a, b, c, d)
#define EPRINTF5(str, a, b, c, d, e) \
if (EDEBUGGING) fas_dprintf(fas, str, a, b, c, d, e)
#define EPRINTF6(str, a, b, c, d, e, f) \
if (EDEBUGGING) fas_dprintf(fas, str, a, b, c, d, e, f)
#define DPRINTF(str) if (DDEBUGGING) fas_dprintf(fas, str)
#define DPRINTF1(str, a) if (DDEBUGGING) fas_dprintf(fas, str, a)
#define DPRINTF2(str, a, b) if (DDEBUGGING) fas_dprintf(fas, str, a, b)
#define DPRINTF3(str, a, b, c) if (DDEBUGGING) fas_dprintf(fas, str, a, b, c)
#define DPRINTF4(str, a, b, c, d) \
if (DDEBUGGING) fas_dprintf(fas, str, a, b, c, d)
#define DPRINTF5(str, a, b, c, d, e) \
if (DDEBUGGING) fas_dprintf(fas, str, a, b, c, d, e)
#define DPRINTF6(str, a, b, c, d, e, f) \
if (DDEBUGGING) fas_dprintf(fas, str, a, b, c, d, e, f)
#define IPRINTF(str) if (IDEBUGGING) fas_dprintf(fas, str)
#define IPRINTF1(str, a) if (IDEBUGGING) fas_dprintf(fas, str, a)
#define IPRINTF2(str, a, b) if (IDEBUGGING) fas_dprintf(fas, str, a, b)
#define IPRINTF3(str, a, b, c) if (IDEBUGGING) fas_dprintf(fas, str, a, b, c)
#define IPRINTF4(str, a, b, c, d) \
if (IDEBUGGING) fas_dprintf(fas, str, a, b, c, d)
#define IPRINTF5(str, a, b, c, d, e) \
if (IDEBUGGING) fas_dprintf(fas, str, a, b, c, d, e)
#define IPRINTF6(str, a, b, c, d, e, f) \
if (IDEBUGGING) fas_dprintf(fas, str, a, b, c, d, e, f)
#else
#define EPRINTF(str)
#define EPRINTF1(str, a)
#define EPRINTF2(str, a, b)
#define EPRINTF3(str, a, b, c)
#define EPRINTF4(str, a, b, c, d)
#define EPRINTF5(str, a, b, c, d, e)
#define EPRINTF6(str, a, b, c, d, e, f)
#define DPRINTF(str)
#define DPRINTF1(str, a)
#define DPRINTF2(str, a, b)
#define DPRINTF3(str, a, b, c)
#define DPRINTF4(str, a, b, c, d)
#define DPRINTF5(str, a, b, c, d, e)
#define DPRINTF6(str, a, b, c, d, e, f)
#define IPRINTF(str)
#define IPRINTF1(str, a)
#define IPRINTF2(str, a, b)
#define IPRINTF3(str, a, b, c)
#define IPRINTF4(str, a, b, c, d)
#define IPRINTF5(str, a, b, c, d, e)
#define IPRINTF6(str, a, b, c, d, e, f)
#endif
#define ALL_TARGETS 0xffff
#define MAX_THROTTLE 254
#define HOLD_THROTTLE 0
#define DRAIN_THROTTLE -1
#define QFULL_THROTTLE -2
#define NODISC(tgt) (fas->f_nodisc & (1<<(tgt)))
#define NOTAG(tgt) (fas->f_notag & (1<<(tgt)))
#define TAGGED(tgt) ((fas->f_notag & (1<<(tgt))) == 0)
#define SYNC_KNOWN(tgt) (fas->f_sync_known & (1<<(tgt)))
#define NEXTSLOT(slot, d) ((slot)+(d)) & ((N_SLOTS)-1)
#define MY_ID(fas) ((fas)->f_fasconf & FAS_CONF_BUSID)
#define INTPENDING(fas) (fas_dma_reg_read((fas), \
&((fas)->f_dma->dma_csr))&DMA_INT_MASK)
#define Tgt(sp) ((sp)->cmd_pkt->pkt_address.a_target)
#define Lun(sp) ((sp)->cmd_pkt->pkt_address.a_lun)
#define New_state(fas, state)\
(fas)->f_laststate = (fas)->f_state, (fas)->f_state = (state)
#define CNUM (fas->f_instance)
#define TRUE 1
#define FALSE 0
#define UNDEFINED -1
#define INVALID_MSG 0x7f
#define QFULL_RETRIES 10
#define QFULL_RETRY_INTERVAL 100
#define FAS_HM_REV(fas) (fas)->f_hm_rev
#define MEG (1000 * 1000)
#define FIVE_MEG (5 * MEG)
#define TEN_MEG (10 * MEG)
#define TWENTY_MEG (20 * MEG)
#define TWENTYFIVE_MEG (25 * MEG)
#define FORTY_MEG (40 * MEG)
#define FAS_FREQ_SLOP (25000)
#define FAS_XFER_WIDTH 1
#define FAS_EMPTY_CALLBACKQ(fas) fas_empty_callbackQ(fas)
#define FAS_CHECK_WAITQ_AND_FAS_MUTEX_EXIT(fas) \
mutex_enter(&fas->f_waitQ_mutex); \
if (fas->f_waitf) { \
fas_empty_waitQ(fas); \
} \
mutex_exit(FAS_MUTEX(fas)); \
mutex_exit(&fas->f_waitQ_mutex);
#define NO_TRAN_BUSY 0
#define TRAN_BUSY_OK 1
#define FAS_WATCH_RESET_DELAY_TICK 50
#define RECONNECT_TAG_RCV_TIMEOUT 2000
#define RQ_MAKECOM_COMMON(pktp, flag, cmd) \
(pktp)->pkt_flags = (flag), \
((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \
((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \
(pktp)->pkt_address.a_lun
#define RQ_MAKECOM_G0(pktp, flag, cmd, addr, cnt) \
RQ_MAKECOM_COMMON((pktp), (flag), (cmd)), \
FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \
FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt))
#define NEW_TIMEOUT 1
#ifdef __cplusplus
}
#endif
#endif