📄 ncr53c8xx.c
字号:
** 64 possible tags. **---------------------------------------------------------------- */ u_int32 jump_ccb_0; /* Default table if no tags */ u_int32 *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[SCSI_NCR_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. **---------------------------------------------------------------- */ u_short 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 */ ccb_p 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. **---------------------------------------------------------------- */ 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; /*---------------------------------------------------------------- ** The virtual address of the ccb containing this header. **---------------------------------------------------------------- */ ccb_p cp;#ifdef SCSI_NCR_PROFILE_SUPPORT /*---------------------------------------------------------------- ** Space for some timestamps to gather profiling data. **---------------------------------------------------------------- */ struct tstamp stamp;#endif /*---------------------------------------------------------------- ** 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)*/#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]/*** 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. **---------------------------------------------------------------- */ Scsi_Cmnd *cmd; /* SCSI command */ u_long tlimit; /* Deadline for this job */ 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; ccb_p link_ccb; /* Host adapter CCB chain */ XPT_QUEHEAD link_ccbq; /* Link to unit CCB queue */ u_int32 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. **---------------------------------------------------------------- */ struct head header; /*---------------------------------------------------------------- ** CCBs management queues. **---------------------------------------------------------------- */ Scsi_Cmnd *waiting_list; /* Commands waiting for a CCB */ /* when lcb is not allocated. */ Scsi_Cmnd *done_list; /* Commands waiting for done() */ /* callback to be invoked. */ #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93) spinlock_t smp_lock; /* Lock for SMP threading */#endif /*---------------------------------------------------------------- ** Chip and controller indentification. **---------------------------------------------------------------- */ int unit; /* Unit number */ char chip_name[8]; /* Chip name */ char inst_name[16]; /* ncb instance name */ /*---------------------------------------------------------------- ** Initial value of some IO register bits. ** These values are assumed to have been set by BIOS, and may ** be used for probing adapter implementation differences. **---------------------------------------------------------------- */ u_char sv_scntl0, sv_scntl3, sv_dmode, sv_dcntl, sv_ctest3, sv_ctest4, sv_ctest5, sv_gpcntl, sv_stest2, sv_stest4; /*---------------------------------------------------------------- ** Actual initial value of IO register bits used by the ** driver. They are loaded at initialisation according to ** features that are to be enabled. **---------------------------------------------------------------- */ u_char rv_scntl0, rv_scntl3, rv_dmode, rv_dcntl, rv_ctest3, rv_ctest4, rv_ctest5, rv_stest2; /*---------------------------------------------------------------- ** Targets management. ** During reselection the ncr jumps to jump_tcb. ** The SFBR register is loaded with the encoded target id. ** For i = 0 to 3 ** SCR_JUMP ^ IFTRUE(MASK(i, 3)), @(next tcb mod. i) ** ** Recent chips will prefetch the 4 JUMPS using only 1 burst. ** It is kind of hashcoding. **---------------------------------------------------------------- */ struct link jump_tcb[4]; /* JUMPs for reselection */ struct tcb target[MAX_TARGET]; /* Target data */ /*---------------------------------------------------------------- ** Virtual and physical bus addresses of the chip. **---------------------------------------------------------------- */ vm_offset_t vaddr; /* Virtual and bus address of */ vm_offset_t paddr; /* chip's IO registers. */ vm_offset_t paddr2; /* On-chip RAM bus address. */ volatile /* Pointer to volatile for */ struct ncr_reg *reg; /* memory mapped IO. */ /*---------------------------------------------------------------- ** SCRIPTS virtual and physical bus addresses. ** 'script' is loaded in the on-chip RAM if present. ** 'scripth' stays in main memory. **---------------------------------------------------------------- */ struct script *script0; /* Copies of script and scripth */ struct scripth *scripth0; /* relocated for this ncb. */ struct scripth *scripth; /* Actual scripth virt. address */ u_long p_script; /* Actual script and scripth */ u_long p_scripth; /* bus addresses. */ /*---------------------------------------------------------------- ** General controller parameters and configuration. **---------------------------------------------------------------- */ u_short device_id; /* PCI device id */ u_char revision_id; /* PCI device revision id */ u_long port; /* IO space base address */ u_int irq; /* IRQ level */ u_int features; /* Chip features map */ u_char myaddr; /* SCSI id of the adapter */ u_char maxburst; /* log base 2 of dwords burst */ u_char maxwide; /* Maximum transfer width */ u_char minsync; /* Minimum sync period factor */ u_char maxsync; /* Maximum sync period factor */ u_char maxoffs; /* Max scsi offset */ u_char multiplier; /* Clock multiplier (1,2,4) */ u_char clock_divn; /* Number of clock divisors */ u_long clock_khz; /* SCSI clock frequency in KHz */ /*---------------------------------------------------------------- ** Start queue management. ** It is filled up by the host processor and accessed by the ** SCRIPTS processor in order to start SCSI commands. **---------------------------------------------------------------- */ u_short squeueput; /* Next free slot of the queue */ u_short actccbs; /* Number of allocated CCBs */ u_short queuedccbs; /* Number of CCBs in start queue*/ u_short queuedepth; /* Start queue depth */ /*---------------------------------------------------------------- ** Timeout handler. **---------------------------------------------------------------- */ struct timer_list timer; /* Timer handler link header */ u_long lasttime; u_long settle_time; /* Resetting the SCSI BUS */ /*---------------------------------------------------------------- ** Debugging and profiling. **---------------------------------------------------------------- */ struct ncr_reg regdump; /* Register dump */ u_long regtime; /* Time it has been done */#ifdef SCSI_NCR_PROFILE_SUPPORT struct profile profile; /* Profiling data */ u_int disc_phys; /* Disconnection counters */ u_int disc_ref;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -