ncr53c8xx.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,351 行 · 第 1/5 页
C
2,351 行
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 UF_TRACE (0x01)#define UF_NODISC (0x02)#define UF_NOSCAN (0x04)/*========================================================================**** 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 */ struct lcb * 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. **---------------------------------------------------------------- */ struct ccb * nego_cp; /*---------------------------------------------------------------- ** statistical data **---------------------------------------------------------------- */ u_long transfers; u_long bytes; /*---------------------------------------------------------------- ** negotiation of wide and synch transfer and device quirks. **---------------------------------------------------------------- */#ifdef SCSI_NCR_BIG_ENDIAN/*0*/ u16 period;/*2*/ u_char sval;/*3*/ u_char minsync;/*0*/ u_char wval;/*1*/ u_char widedone;/*2*/ u_char quirks;/*3*/ u_char maxoffs;#else/*0*/ u_char minsync;/*1*/ u_char sval;/*2*/ u16 period;/*0*/ u_char maxoffs;/*1*/ u_char quirks;/*2*/ u_char widedone;/*3*/ u_char wval;#endif#ifdef SCSI_NCR_INTEGRITY_CHECKING u_char ic_min_sync; u_char ic_max_width; u_char ic_maximums_set; u_char ic_done;#endif /* User settable limits and options. */ 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 ** 64 possible tags. **---------------------------------------------------------------- */ u32 jump_ccb_0; /* Default table if no tags */ u32 *jump_ccb; /* Virtual address */ /*---------------------------------------------------------------- ** CCB queue management. **---------------------------------------------------------------- */ XPT_QUEHEAD free_ccbq; /* Queue of available CCBs */ XPT_QUEHEAD busy_ccbq; /* Queue of busy CCBs */ XPT_QUEHEAD wait_ccbq; /* Queue of waiting for IO CCBs */ XPT_QUEHEAD skip_ccbq; /* Queue of skipped CCBs */ u_char actccbs; /* Number of allocated CCBs */ u_char busyccbs; /* CCBs busy for this lun */ u_char queuedccbs; /* CCBs queued to the controller*/ u_char queuedepth; /* Queue depth for this lun */ u_char scdev_depth; /* SCSI device queue depth */ u_char 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_char ia_tag; /* Allocation index */ u_char if_tag; /* Freeing index */ u_char cb_tags[MAX_TAGS]; /* Circular tags buffer */ u_char usetags; /* Command queuing is active */ u_char maxtags; /* Max nr of tags asked by user */ u_char numtags; /* Current number of tags */ u_char inq_byte7; /* Store unit CmdQ capabitility */ /*---------------------------------------------------------------- ** QUEUE FULL control and ORDERED tag control. **---------------------------------------------------------------- */ /*---------------------------------------------------------------- ** QUEUE FULL and ORDERED tag control. **---------------------------------------------------------------- */ u16 num_good; /* Nr of GOOD since QUEUE FULL */ tagmap_t tags_umap; /* Used tags bitmap */ tagmap_t tags_smap; /* Tags in use at 'tag_stime' */ u_long tags_stime; /* Last time we set smap=umap */ struct ccb * held_ccb; /* CCB held for QUEUE FULL */};/*========================================================================**** Declaration of structs: the launch script.****========================================================================**** It is part of the CCB and is called by the scripts processor to ** start or restart the data structure (nexus).** This 6 DWORDs mini script makes use of prefetching.****------------------------------------------------------------------------*/struct launch { /*---------------------------------------------------------------- ** SCR_COPY(4), @(p_phys), @(dsa register) ** SCR_JUMP, @(scheduler_point) **---------------------------------------------------------------- */ ncrcmd setup_dsa[3]; /* Copy 'phys' address to dsa */ struct link schedule; /* Jump to scheduler point */ ncrcmd p_phys; /* 'phys' header bus address */};/*========================================================================**** Declaration of structs: global HEADER.****========================================================================**** This substructure is copied from the ccb to a global address after ** selection (or reselection) and copied back before disconnect.**** These fields are accessible to the script processor.****------------------------------------------------------------------------*/struct head { /*---------------------------------------------------------------- ** Saved data pointer. ** Points to the position in the script responsible for the ** actual transfer transfer of data. ** It's written after reception of a SAVE_DATA_POINTER message. ** The goalpointer points after the last transfer command. **---------------------------------------------------------------- */ u32 savep; u32 lastp; u32 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. **---------------------------------------------------------------- */ u32 wlastp; u32 wgoalp; /*---------------------------------------------------------------- ** The virtual address of the ccb containing this header. **---------------------------------------------------------------- */ struct ccb * cp; /*---------------------------------------------------------------- ** Status fields. **---------------------------------------------------------------- */ u_char scr_st[4]; /* script status */ u_char status[4]; /* host status. must be the */ /* last DWORD of the header. */};/*** The status bytes are used by the host and the script processor.**** The byte corresponding to the host_status must be stored in the ** last DWORD of the CCB header since it is used for command ** completion (ncr_wakeup()). Doing so, we are sure that the header ** has been entirely copied back to the CCB when the host_status is ** seen complete by the CPU.**** The last 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.**** The first four bytes (scr_st[4]) are used inside the script by ** "COPY" commands.** Because source and destination must have the same alignment** in a DWORD, the fields HAVE to be at the choosen offsets.** xerr_st 0 (0x34) scratcha** sync_st 1 (0x05) sxfer** wide_st 3 (0x03) scntl3*//*** 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 PS_REG scr3/*** Last four bytes (host)*/#ifdef SCSI_NCR_BIG_ENDIAN#define actualquirks phys.header.status[3]#define host_status phys.header.status[2]#define scsi_status phys.header.status[1]#define parity_status phys.header.status[0]#else#define actualquirks phys.header.status[0]#define host_status phys.header.status[1]#define scsi_status phys.header.status[2]#define parity_status phys.header.status[3]#endif/*** First four bytes (script)*/#define xerr_st header.scr_st[0]#define sync_st header.scr_st[1]#define nego_st header.scr_st[2]#define wide_st header.scr_st[3]/*** First four bytes (host)*/#define xerr_status phys.xerr_st#define nego_status phys.nego_st#if 0#define sync_status phys.sync_st#define wide_status phys.wide_st#endif/*==========================================================**** Declaration of structs: Data structure block****==========================================================**** During execution of a ccb by the script processor,** the DSA (data structure address) register points** to this substructure of the ccb.** This substructure contains the header with** the script-processor-changable data and** data blocks for the indirect move commands.****----------------------------------------------------------*/struct dsb { /* ** Header. */ struct head header; /* ** Table data for Script */ struct scr_tblsel select; struct scr_tblmove smsg ; struct scr_tblmove cmd ; struct scr_tblmove sense ; struct scr_tblmove data[MAX_SCATTER];};/*========================================================================**** Declaration of structs: Command control block.****========================================================================*/struct ccb { /*---------------------------------------------------------------- ** This is the data structure which is pointed by the DSA ** register when it is executed by the script processor. ** It must be the first entry because it contains the header ** as first entry that must be cache line aligned. **---------------------------------------------------------------- */ struct dsb phys; /*---------------------------------------------------------------- ** Mini-script used at CCB execution start-up. ** Load the DSA with the data structure address (phys) and ** jump to SELECT. Jump to CANCEL if CCB is to be canceled. **---------------------------------------------------------------- */ struct launch start; /*---------------------------------------------------------------- ** Mini-script used at CCB relection to restart the nexus. ** Load the DSA with the data structure address (phys) and ** jump to RESEL_DSA. Jump to ABORT if CCB is to be aborted. **---------------------------------------------------------------- */ struct launch restart; /*---------------------------------------------------------------- ** If a data transfer phase is terminated too early ** (after reception of a message (i.e. DISCONNECT)), ** we have to prepare a mini script to transfer ** the rest of the data. **---------------------------------------------------------------- */ ncrcmd patch[8]; /*---------------------------------------------------------------- ** The general SCSI driver provides a ** pointer to a control block. **---------------------------------------------------------------- */ struct scsi_cmnd *cmd; /* SCSI command */ u_char cdb_buf[16]; /* Copy of CDB */ u_char sense_buf[64]; int data_len; /* Total data length */ /*---------------------------------------------------------------- ** Message areas. ** We prepare a message to be sent after selection. ** We may use a second one if the command is rescheduled ** due to GETCC or QFULL. ** Contents are IDENTIFY and SIMPLE_TAG. ** While negotiating sync or wide transfer, ** a SDTR or WDTR message is appended. **---------------------------------------------------------------- */ u_char scsi_smsg [8]; u_char scsi_smsg2[8]; /*---------------------------------------------------------------- ** Other fields. **---------------------------------------------------------------- */ u_long p_ccb; /* BUS address of this CCB */ u_char sensecmd[6]; /* Sense command */ u_char tag; /* Tag for this transfer */ /* 255 means no tag */ u_char target; u_char lun; u_char queued; u_char auto_sense; struct ccb * link_ccb; /* Host adapter CCB chain */ XPT_QUEHEAD link_ccbq; /* Link to unit CCB queue */ u32 startp; /* Initial data pointer */ u_long magic; /* Free / busy CCB flag */};#define CCB_PHYS(cp,lbl) (cp->p_ccb + offsetof(struct ccb, lbl))/*========================================================================**** Declaration of structs: NCR device descriptor****========================================================================*/struct ncb { /*---------------------------------------------------------------- ** The global header. ** It is accessible to both the host and the script processor. ** Must be cache line size aligned (32 for x86) in order to ** allow cache line bursting when it is copied to/from CCB.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?