📄 ncr53c8xx.c
字号:
#define cpu_to_scr(dw) cpu_to_le32(dw)#define scr_to_cpu(dw) le32_to_cpu(dw)#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define cpu_to_scr(dw) cpu_to_be32(dw)#define scr_to_cpu(dw) be32_to_cpu(dw)#else#define cpu_to_scr(dw) (dw)#define scr_to_cpu(dw) (dw)#endif/*==========================================================**** Access to the controller chip.**** If NCR_IOMAPPED is defined, the driver will use ** normal IOs instead of the MEMORY MAPPED IO method ** recommended by PCI specifications.** If all PCI bridges, host brigdes and architectures ** would have been correctly designed for PCI, this ** option would be useless.****==========================================================*//*** If the CPU and the NCR use same endian-ness addressing,** no byte reordering is needed for accessing chip io ** registers. Functions suffixed by '_raw' are assumed ** to access the chip over the PCI without doing byte ** reordering. Functions suffixed by '_l2b' are ** assumed to perform little-endian to big-endian byte ** reordering, those suffixed by '_b2l' blah, blah,** blah, ...*/#if defined(NCR_IOMAPPED)/*** IO mapped only input / ouput*/#define INB_OFF(o) inb (np->port + ncr_offb(o))#define OUTB_OFF(o, val) outb ((val), np->port + ncr_offb(o))#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) inw_l2b (np->port + ncr_offw(o))#define INL_OFF(o) inl_l2b (np->port + (o))#define OUTW_OFF(o, val) outw_b2l ((val), np->port + ncr_offw(o))#define OUTL_OFF(o, val) outl_b2l ((val), np->port + (o))#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) inw_b2l (np->port + ncr_offw(o))#define INL_OFF(o) inl_b2l (np->port + (o))#define OUTW_OFF(o, val) outw_l2b ((val), np->port + ncr_offw(o))#define OUTL_OFF(o, val) outl_l2b ((val), np->port + (o))#else#define INW_OFF(o) inw_raw (np->port + ncr_offw(o))#define INL_OFF(o) inl_raw (np->port + (o))#define OUTW_OFF(o, val) outw_raw ((val), np->port + ncr_offw(o))#define OUTL_OFF(o, val) outl_raw ((val), np->port + (o))#endif /* ENDIANs */#else /* defined NCR_IOMAPPED *//*** MEMORY mapped IO input / output*/#define INB_OFF(o) readb((char *)np->reg + ncr_offb(o))#define OUTB_OFF(o, val) writeb((val), (char *)np->reg + ncr_offb(o))#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) readw_l2b((char *)np->reg + ncr_offw(o))#define INL_OFF(o) readl_l2b((char *)np->reg + (o))#define OUTW_OFF(o, val) writew_b2l((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val) writel_b2l((val), (char *)np->reg + (o))#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) readw_b2l((char *)np->reg + ncr_offw(o))#define INL_OFF(o) readl_b2l((char *)np->reg + (o))#define OUTW_OFF(o, val) writew_l2b((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val) writel_l2b((val), (char *)np->reg + (o))#else#define INW_OFF(o) readw_raw((char *)np->reg + ncr_offw(o))#define INL_OFF(o) readl_raw((char *)np->reg + (o))#define OUTW_OFF(o, val) writew_raw((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val) writel_raw((val), (char *)np->reg + (o))#endif#endif /* defined NCR_IOMAPPED */#define INB(r) INB_OFF (offsetof(struct ncr_reg,r))#define INW(r) INW_OFF (offsetof(struct ncr_reg,r))#define INL(r) INL_OFF (offsetof(struct ncr_reg,r))#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val))#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val))#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val))/*** Set bit field ON, OFF */#define OUTONB(r, m) OUTB(r, INB(r) | (m))#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m))#define OUTONW(r, m) OUTW(r, INW(r) | (m))#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m))#define OUTONL(r, m) OUTL(r, INL(r) | (m))#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m))/*==========================================================**** Command control block states.****==========================================================*/#define HS_IDLE (0)#define HS_BUSY (1)#define HS_NEGOTIATE (2) /* sync/wide data transfer*/#define HS_DISCONNECT (3) /* Disconnected by target */#define HS_DONEMASK (0x80)#define HS_COMPLETE (4|HS_DONEMASK)#define HS_SEL_TIMEOUT (5|HS_DONEMASK) /* Selection timeout */#define HS_RESET (6|HS_DONEMASK) /* SCSI reset */#define HS_ABORTED (7|HS_DONEMASK) /* Transfer aborted */#define HS_TIMEOUT (8|HS_DONEMASK) /* Software timeout */#define HS_FAIL (9|HS_DONEMASK) /* SCSI or PCI bus errors */#define HS_UNEXPECTED (10|HS_DONEMASK)/* Unexpected disconnect *//*** Invalid host status values used by the SCRIPTS processor ** when the nexus is not fully identified.** Shall never appear in a CCB.*/#define HS_INVALMASK (0x40)#define HS_SELECTING (0|HS_INVALMASK)#define HS_IN_RESELECT (1|HS_INVALMASK)#define HS_STARTING (2|HS_INVALMASK)/*** Flags set by the SCRIPT processor for commands ** that have been skipped.*/#define HS_SKIPMASK (0x20)/*==========================================================**** Software Interrupt Codes****==========================================================*/#define SIR_BAD_STATUS (1)#define SIR_XXXXXXXXXX (2)#define SIR_NEGO_SYNC (3)#define SIR_NEGO_WIDE (4)#define SIR_NEGO_FAILED (5)#define SIR_NEGO_PROTO (6)#define SIR_REJECT_RECEIVED (7)#define SIR_REJECT_SENT (8)#define SIR_IGN_RESIDUE (9)#define SIR_MISSING_SAVE (10)#define SIR_RESEL_NO_MSG_IN (11)#define SIR_RESEL_NO_IDENTIFY (12)#define SIR_RESEL_BAD_LUN (13)#define SIR_RESEL_BAD_TARGET (14)#define SIR_RESEL_BAD_I_T_L (15)#define SIR_RESEL_BAD_I_T_L_Q (16)#define SIR_DONE_OVERFLOW (17)#define SIR_MAX (17)/*==========================================================**** Extended error codes.** xerr_status field of struct ccb.****==========================================================*/#define XE_OK (0)#define XE_EXTRA_DATA (1) /* unexpected data phase */#define XE_BAD_PHASE (2) /* illegal phase (4/5) *//*==========================================================**** Negotiation status.** nego_status field of struct ccb.****==========================================================*/#define NS_SYNC (1)#define NS_WIDE (2)/*==========================================================**** "Special features" of targets.** quirks field of struct tcb.** actualquirks field of struct ccb.****==========================================================*/#define QUIRK_AUTOSAVE (0x01)#define QUIRK_NOMSG (0x02)#define QUIRK_NOSYNC (0x10)#define QUIRK_NOWIDE16 (0x20)/*==========================================================**** Capability bits in Inquire response byte 7.****==========================================================*/#define INQ7_QUEUE (0x02)#define INQ7_SYNC (0x10)#define INQ7_WIDE16 (0x20)/*==========================================================**** Misc.****==========================================================*/#define CCB_MAGIC (0xf2691ad2)/*==========================================================**** Declaration of structs.****==========================================================*/struct tcb;struct lcb;struct ccb;struct ncb;struct script;typedef struct ncb * ncb_p;typedef struct tcb * tcb_p;typedef struct lcb * lcb_p;typedef struct ccb * ccb_p;struct link { ncrcmd l_cmd; ncrcmd l_paddr;};struct usrcmd { u_long target; u_long lun; u_long data; u_long cmd;};#define UC_SETSYNC 10#define UC_SETTAGS 11#define UC_SETDEBUG 12#define UC_SETORDER 13#define UC_SETWIDE 14#define UC_SETFLAG 15#define UC_CLEARPROF 16#define UC_SETVERBOSE 17#define UF_TRACE (0x01)#define UF_NODISC (0x02)#define UF_NOSCAN (0x04)/*---------------------------------------**** Timestamps for profiling****---------------------------------------*/#ifdef SCSI_NCR_PROFILE_SUPPORTstruct tstamp { u_long start; u_long end; u_long command; u_long status; u_long disconnect; u_long reselect;};/*** profiling data (per device)*/struct profile { u_long num_trans; u_long num_kbytes; u_long rest_bytes; u_long num_disc; u_long num_break; u_long num_int; u_long num_fly; u_long ms_setup; u_long ms_data; u_long ms_disc; u_long ms_post;};#endif/*========================================================================**** Declaration of structs: target control block****========================================================================*/struct tcb { /*---------------------------------------------------------------- ** During reselection the ncr jumps to this point with SFBR ** set to the encoded target number with bit 7 set. ** if it's not this target, jump to the next. ** ** JUMP IF (SFBR != #target#), @(next tcb) **---------------------------------------------------------------- */ struct link jump_tcb; /*---------------------------------------------------------------- ** Load the actual values for the sxfer and the scntl3 ** register (sync/wide mode). ** ** SCR_COPY (1), @(sval field of this tcb), @(sxfer register) ** SCR_COPY (1), @(wval field of this tcb), @(scntl3 register) **---------------------------------------------------------------- */ ncrcmd getscr[6]; /*---------------------------------------------------------------- ** Get the IDENTIFY message and load the LUN to SFBR. ** ** CALL, <RESEL_LUN> **---------------------------------------------------------------- */ struct link call_lun; /*---------------------------------------------------------------- ** Now look for the right lun. ** ** For i = 0 to 3 ** SCR_JUMP ^ IFTRUE(MASK(i, 3)), @(first lcb mod. i) ** ** Recent chips will prefetch the 4 JUMPS using only 1 burst. ** It is kind of hashcoding. **---------------------------------------------------------------- */ struct link jump_lcb[4]; /* JUMPs for reselection */ lcb_p lp[MAX_LUN]; /* The lcb's of this tcb */ u_char inq_done; /* Target capabilities received */ u_char inq_byte7; /* Contains these capabilities */ /*---------------------------------------------------------------- ** Pointer to the ccb used for negotiation. ** Prevent from starting a negotiation for all queued commands ** when tagged command queuing is enabled. **---------------------------------------------------------------- */ ccb_p nego_cp; /*---------------------------------------------------------------- ** statistical data **---------------------------------------------------------------- */ u_long transfers; u_long bytes; /*---------------------------------------------------------------- ** negotiation of wide and synch transfer and device quirks. **---------------------------------------------------------------- *//*0*/ u_char minsync;/*1*/ u_char sval;/*2*/ u_short period;/*0*/ u_char maxoffs;/*1*/ u_char quirks;/*2*/ u_char widedone;/*3*/ u_char wval; /*---------------------------------------------------------------- ** User settable limits and options. ** These limits are read from the NVRAM if present. **---------------------------------------------------------------- */ u_char usrsync; u_char usrwide; u_char usrtags; u_char usrflag;};/*========================================================================**** Declaration of structs: lun control block****========================================================================*/struct lcb { /*---------------------------------------------------------------- ** During reselection the ncr jumps to this point ** with SFBR set to the "Identify" message. ** if it's not this lun, jump to the next. ** ** JUMP IF (SFBR != #lun#), @(next lcb of this target) ** ** It is this lun. Load TEMP with the nexus jumps table ** address and jump to RESEL_TAG (or RESEL_NOTAG). ** ** SCR_COPY (4), p_jump_ccb, TEMP, ** SCR_JUMP, <RESEL_TAG> **---------------------------------------------------------------- */ struct link jump_lcb; ncrcmd load_jump_ccb[3]; struct link jump_tag; ncrcmd p_jump_ccb; /* Jump table bus address */ /*---------------------------------------------------------------- ** Jump table used by the script processor to directly jump ** to the CCB corresponding to the reselected nexus. ** Address is allocated on 256 bytes boundary in order to ** allow 8 bit calculation of the tag jump entry for up to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -