📄 sym53c8xx.c
字号:
/*** Structure used by sym53c8xx_detect/sym53c8xx_pci_init** to save data on each detected board for ncr_attach().*/typedef struct { pcidev_t pdev; ncr_slot slot; ncr_chip chip; ncr_nvram *nvram; u_char host_id;#ifdef SCSI_NCR_PQS_PDS_SUPPORT u_char pqs_pds;#endif int attach_done;} ncr_device;/*==========================================================**** assert ()****==========================================================**** modified copy from 386bsd:/usr/include/sys/assert.h****----------------------------------------------------------*/#define assert(expression) { \ if (!(expression)) { \ (void)panic( \ "assertion \"%s\" failed: file \"%s\", line %d\n", \ #expression, \ __FILE__, __LINE__); \ } \}/*==========================================================**** 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 */#define DSA_INVALID 0xffffffff/*==========================================================**** Software Interrupt Codes****==========================================================*/#define SIR_BAD_STATUS (1)#define SIR_SEL_ATN_NO_MSG_OUT (2)#define SIR_MSG_RECEIVED (3)#define SIR_MSG_WEIRD (4)#define SIR_NEGO_FAILED (5)#define SIR_NEGO_PROTO (6)#define SIR_SCRIPT_STOPPED (7)#define SIR_REJECT_TO_SEND (8)#define SIR_SWIDE_OVERRUN (9)#define SIR_SODL_UNDERRUN (10)#define SIR_RESEL_NO_MSG_IN (11)#define SIR_RESEL_NO_IDENTIFY (12)#define SIR_RESEL_BAD_LUN (13)#define SIR_TARGET_SELECTED (14)#define SIR_RESEL_BAD_I_T_L (15)#define SIR_RESEL_BAD_I_T_L_Q (16)#define SIR_ABORT_SENT (17)#define SIR_RESEL_ABORTED (18)#define SIR_MSG_OUT_DONE (19)#define SIR_AUTO_SENSE_DONE (20)#define SIR_DUMMY_INTERRUPT (21)#define SIR_DATA_OVERRUN (22)#define SIR_BAD_PHASE (23)#define SIR_MAX (23)/*==========================================================**** Extended error bits.** xerr_status field of struct ccb.****==========================================================*/#define XE_EXTRA_DATA (1) /* unexpected data phase */#define XE_BAD_PHASE (2) /* illegal phase (4/5) */#define XE_PARITY_ERR (4) /* unrecovered SCSI parity error */#define XE_SODL_UNRUN (1<<3)#define XE_SWIDE_OVRUN (1<<4)/*==========================================================**** Negotiation status.** nego_status field of struct ccb.****==========================================================*/#define NS_NOCHANGE (0)#define NS_SYNC (1)#define NS_WIDE (2)#define NS_PPR (4)/*==========================================================**** "Special features" of targets.** quirks field of struct tcb.** actualquirks field of struct ccb.****==========================================================*/#define QUIRK_AUTOSAVE (0x01)/*==========================================================**** Capability bits in Inquire response byte 7.****==========================================================*/#define INQ7_QUEUE (0x02)#define INQ7_SYNC (0x10)#define INQ7_WIDE16 (0x20)/*==========================================================**** A CCB hashed table is used to retrieve CCB address ** from DSA value.****==========================================================*/#define CCB_HASH_SHIFT 8#define CCB_HASH_SIZE (1UL << CCB_HASH_SHIFT)#define CCB_HASH_MASK (CCB_HASH_SIZE-1)#define CCB_HASH_CODE(dsa) (((dsa) >> 11) & CCB_HASH_MASK)/*==========================================================**** 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_SETVERBOSE 17#define UC_RESETDEV 18#define UC_CLEARDEV 19#define UF_TRACE (0x01)#define UF_NODISC (0x02)#define UF_NOSCAN (0x04)/*========================================================================**** Declaration of structs: target control block****========================================================================*/struct tcb { /*---------------------------------------------------------------- ** LUN tables. ** An array of bus addresses is used on reselection by ** the SCRIPT. **---------------------------------------------------------------- */ u_int32 *luntbl; /* lcbs bus address table */ u_int32 b_luntbl; /* bus address of this table */ u_int32 b_lun0; /* bus address of lun0 */ lcb_p l0p; /* lcb of LUN #0 (normal case) */#if MAX_LUN > 1 lcb_p *lmp; /* Other lcb's [1..MAX_LUN] */#endif /*---------------------------------------------------------------- ** Target capabilities. **---------------------------------------------------------------- */ u_char inq_done; /* Target capabilities received */ u_char inq_byte7; /* Contains these capabilities */ /*---------------------------------------------------------------- ** Some flags. **---------------------------------------------------------------- */ u_char to_reset; /* This target is to be reset */ /*---------------------------------------------------------------- ** 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; /*---------------------------------------------------------------- ** negotiation of wide and synch transfer and device quirks. ** sval, wval and uval are read from SCRIPTS and so have alignment ** constraints. **---------------------------------------------------------------- *//*0*/ u_char uval;/*1*/ u_char sval;/*2*/ u_char filler2;/*3*/ u_char wval; u_short period; u_char minsync; u_char maxoffs; u_char quirks; u_char widedone;#ifdef SCSI_NCR_INTEGRITY_CHECKING u_char ic_min_sync; u_char ic_max_width; u_char ic_done;#endif u_char ic_maximums_set; u_char ppr_negotiation; /*---------------------------------------------------------------- ** User settable limits and options. ** These limits are read from the NVRAM if present. **---------------------------------------------------------------- */ u_char usrsync; u_char usrwide; u_short usrtags; u_char usrflag;};/*========================================================================**** Declaration of structs: lun control block****========================================================================*/struct lcb { /*---------------------------------------------------------------- ** On reselection, SCRIPTS use this value as a JUMP address ** after the IDENTIFY has been successfully received. ** This field is set to 'resel_tag' if TCQ is enabled and ** to 'resel_notag' if TCQ is disabled. ** (Must be at zero due to bad lun handling on reselection) **---------------------------------------------------------------- *//*0*/ u_int32 resel_task; /*---------------------------------------------------------------- ** Task table used by the script processor to retrieve the ** task corresponding to a reselected nexus. The TAG is used ** as offset to determine the corresponding entry. ** Each entry contains the associated CCB bus address. **---------------------------------------------------------------- */ u_int32 tasktbl_0; /* Used if TCQ not enabled */ u_int32 *tasktbl; u_int32 b_tasktbl; /*---------------------------------------------------------------- ** CCB queue management. **---------------------------------------------------------------- */ XPT_QUEHEAD busy_ccbq; /* Queue of busy CCBs */ XPT_QUEHEAD wait_ccbq; /* Queue of waiting for IO CCBs */ u_short busyccbs; /* CCBs busy for this lun */ u_short queuedccbs; /* CCBs queued to the controller*/ u_short queuedepth; /* Queue depth for this lun */ u_short scdev_depth; /* SCSI device queue depth */ u_short maxnxs; /* Max possible nexuses */ /*---------------------------------------------------------------- ** Control of tagged command queuing. ** Tags allocation is performed using a circular buffer. ** This avoids using a loop for tag allocation. **---------------------------------------------------------------- */ u_short ia_tag; /* Tag allocation index */ u_short if_tag; /* Tag release index */ u_char *cb_tags; /* Circular tags buffer */ u_char inq_byte7; /* Store unit CmdQ capability */ u_char usetags; /* Command queuing is active */ u_char to_clear; /* User wants to clear all tasks*/ u_short maxtags; /* Max NR of tags asked by user */ u_short numtags; /* Current number of tags */ /*---------------------------------------------------------------- ** QUEUE FULL and ORDERED tag control. **---------------------------------------------------------------- */ u_short num_good; /* Nr of GOOD since QUEUE FULL */ u_short tags_sum[2]; /* Tags sum counters */ u_char tags_si; /* Current index to tags sum */ u_long tags_stime; /* Last time we switch tags_sum */};/*========================================================================**** Declaration of structs: actions for a task.****========================================================================**** It is part of the CCB and is called by the scripts processor to ** start or restart the data structure (nexus).****------------------------------------------------------------------------*/struct action { u_int32 start; u_int32 restart;};/*========================================================================**** Declaration of structs: Phase mismatch context.****========================================================================**** It is part of the CCB and is used as parameters for the DATA ** pointer. We need two contexts to handle correctly the SAVED ** DATA POINTER.****------------------------------------------------------------------------*/struct pm_ctx { struct scr_tblmove sg; /* Updated interrupted SG block */ u_int32 ret; /* SCRIPT return address */};/*========================================================================**** Declaration of structs: global HEADER.****========================================================================**** In earlier driver versions, this substructure was copied from the ** ccb to a global address after selection (or reselection) and copied ** back before disconnect. Since we are now using LOAD/STORE DSA ** RELATIVE instructions, the script is able to access directly these ** fields, and so, this header is no more copied.****------------------------------------------------------------------------*/struct head { /*---------------------------------------------------------------- ** Start and restart SCRIPTS addresses (must be at 0). **---------------------------------------------------------------- */ struct action go; /*---------------------------------------------------------------- ** Saved data pointer. ** Points to the position in the script responsible for the ** actual transfer of data. ** It's written after reception of a SAVE_DATA_POINTER message. ** The goalpointer points after the last transfer command. **---------------------------------------------------------------- */ u_int32 savep; u_int32 lastp; u_int32 goalp; /*---------------------------------------------------------------- ** Alternate data pointer. ** They are copied back to savep/lastp/goalp by the SCRIPTS ** when the direction is unknown and the device claims data out. **---------------------------------------------------------------- */ u_int32 wlastp; u_int32 wgoalp; /*---------------------------------------------------------------- ** Status fields. **---------------------------------------------------------------- */ u_char status[4]; /* host status */};/*** LUN control block lookup.** We use a direct pointer for LUN #0, and a table of pointers ** which is only allocated for devices that support LUN(s) > 0.*/#if MAX_LUN <= 1#define ncr_lp(np, tp, lun) (!lun) ? (tp)->l0p : 0#else#define ncr_lp(np, tp, lun) \ (!lun) ? (tp)->l0p : (tp)->lmp ? (tp)->lmp[(lun)] : 0#endif/*** The status bytes are used by the host and the script processor.**** The four bytes (status[4]) are copied to the scratchb register** (declared as scr0..scr3 in ncr_reg.h) just after the select/reselect,** and copied back just after disconnecting.** Inside the script the XX_REG are used.*//*** Last four bytes (script)*/#define QU_REG scr0#define HS_REG scr1#define HS_PRT nc_scr1#define SS_REG scr2#define SS_PRT nc_scr2#define HF_REG scr3#define HF_PRT nc_scr3/*** Last four bytes (host)*/#define actualquirks phys.header.status[0]#define host_status phys.header.status[1]#define scsi_status phys.header.status[2]#define host_flags phys.header.status[3]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -