📄 sym53c8xx.c
字号:
/*** Host flags*/#define HF_IN_PM0 1u#define HF_IN_PM1 (1u<<1)#define HF_ACT_PM (1u<<2)#define HF_DP_SAVED (1u<<3)#define HF_AUTO_SENSE (1u<<4)#define HF_DATA_IN (1u<<5)#define HF_PM_TO_C (1u<<6)#define HF_EXT_ERR (1u<<7)#ifdef SCSI_NCR_IARB_SUPPORT#define HF_HINT_IARB (1u<<7)#endif/*** This one is stolen from QU_REG.:)*/#define HF_DATA_ST (1u<<7)/*==========================================================**** 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 smsg_ext ; struct scr_tblmove cmd ; struct scr_tblmove sense ; struct scr_tblmove wresid; struct scr_tblmove data [MAX_SCATTER]; /* ** Phase mismatch contexts. ** We need two to handle correctly the ** SAVED DATA POINTER. */ struct pm_ctx pm0; struct pm_ctx pm1;};/*========================================================================**** 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. **---------------------------------------------------------------- */ struct dsb phys; /*---------------------------------------------------------------- ** The general SCSI driver provides a ** pointer to a control block. **---------------------------------------------------------------- */ Scsi_Cmnd *cmd; /* SCSI command */ u_char cdb_buf[16]; /* Copy of CDB */ u_char sense_buf[64]; int data_len; /* Total data length */ int segments; /* Number of SG segments */ /*---------------------------------------------------------------- ** Message areas. ** We prepare a message to be sent after selection. ** We may use a second one if the command is rescheduled ** due to CHECK_CONDITION or QUEUE FULL status. ** Contents are IDENTIFY and SIMPLE_TAG. ** While negotiating sync or wide transfer, ** a SDTR or WDTR message is appended. **---------------------------------------------------------------- */ u_char scsi_smsg [12]; u_char scsi_smsg2[12]; /*---------------------------------------------------------------- ** Miscellaneous status'. **---------------------------------------------------------------- */ u_char nego_status; /* Negotiation status */ u_char xerr_status; /* Extended error flags */ u_int32 extra_bytes; /* Extraneous bytes transferred */ /*---------------------------------------------------------------- ** Saved info for auto-sense **---------------------------------------------------------------- */ u_char sv_scsi_status; u_char sv_xerr_status; /*---------------------------------------------------------------- ** Other fields. **---------------------------------------------------------------- */ u_long p_ccb; /* BUS address of this CCB */ u_char sensecmd[6]; /* Sense command */ u_char to_abort; /* This CCB is to be aborted */ u_short tag; /* Tag for this transfer */ /* NO_TAG means no tag */ u_char tags_si; /* Lun tags sum index (0,1) */ u_char target; u_char lun; u_short queued; ccb_p link_ccb; /* Host adapter CCB chain */ ccb_p link_ccbh; /* Host adapter CCB hash chain */ XPT_QUEHEAD link_ccbq; /* Link to unit CCB queue */ u_int32 startp; /* Initial data pointer */ u_int32 lastp0; /* Initial 'lastp' */ int ext_sg; /* Extreme data pointer, used */ int ext_ofs; /* to calculate the residual. */ int resid;};#define CCB_PHYS(cp,lbl) (cp->p_ccb + offsetof(struct ccb, lbl))/*========================================================================**** Declaration of structs: NCR device descriptor****========================================================================*/struct ncb { /*---------------------------------------------------------------- ** Idle task and invalid task actions and their bus ** addresses. **---------------------------------------------------------------- */ struct action idletask; struct action notask; struct action bad_i_t_l; struct action bad_i_t_l_q; u_long p_idletask; u_long p_notask; u_long p_bad_i_t_l; u_long p_bad_i_t_l_q; /*---------------------------------------------------------------- ** Dummy lun table to protect us against target returning bad ** lun number on reselection. **---------------------------------------------------------------- */ u_int32 *badluntbl; /* Table physical address */ u_int32 resel_badlun; /* SCRIPT handler BUS address */ /*---------------------------------------------------------------- ** Bit 32-63 of the on-chip RAM bus address in LE format. ** The START_RAM64 script loads the MMRS and MMWS from this ** field. **---------------------------------------------------------------- */ u_int32 scr_ram_seg; /*---------------------------------------------------------------- ** 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, sv_stest1, sv_scntl4; /*---------------------------------------------------------------- ** 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, rv_ccntl0, rv_ccntl1, rv_scntl4; /*---------------------------------------------------------------- ** Target data. ** Target control block bus address array used by the SCRIPT ** on reselection. **---------------------------------------------------------------- */ struct tcb target[MAX_TARGET]; u_int32 *targtbl; /*---------------------------------------------------------------- ** Virtual and physical bus addresses of the chip. **---------------------------------------------------------------- */#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED u_long base_va; /* MMIO base virtual address */ u_long base2_va; /* On-chip RAM virtual address */#endif u_long base_ba; /* MMIO base bus address */ u_long base_io; /* IO space base address */ u_long base_ws; /* (MM)IO window size */ u_long base2_ba; /* On-chip RAM bus address */ u_long base2_ws; /* On-chip RAM window size */ u_int irq; /* IRQ number */ 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 for all chips except the ** 53C895A and 53C896 that provide 8K on-chip RAM. **---------------------------------------------------------------- */ struct script *script0; /* Copies of script and scripth */ struct scripth *scripth0; /* relocated for this ncb. */ u_long p_script; /* Actual script and scripth */ u_long p_scripth; /* bus addresses. */ u_long p_scripth0; /*---------------------------------------------------------------- ** General controller parameters and configuration. **---------------------------------------------------------------- */ pcidev_t pdev; u_short device_id; /* PCI device id */ u_char revision_id; /* PCI device revision id */ u_char bus; /* PCI BUS number */ u_char device_fn; /* PCI BUS device and function */ 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 maxoffs_st; /* Max scsi offset in ST mode */ 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 */ u_int features; /* Chip features map */ /*---------------------------------------------------------------- ** Range for the PCI clock frequency measurement result ** that ensures the algorithm used by the driver can be ** trusted for the SCSI clock frequency measurement. ** (Assuming a PCI clock frequency of 33 MHz). **---------------------------------------------------------------- */ u_int pciclock_min; u_int pciclock_max; /*---------------------------------------------------------------- ** Start queue management. ** It is filled up by the host processor and accessed by the ** SCRIPTS processor in order to start SCSI commands. **---------------------------------------------------------------- */ u_long p_squeue; /* Start queue BUS address */ u_int32 *squeue; /* Start queue virtual address */ u_short squeueput; /* Next free slot of the queue */ u_short actccbs; /* Number of allocated CCBs */ u_short queuedepth; /* Start queue depth */ /*---------------------------------------------------------------- ** Command completion queue. ** It is the same size as the start queue to avoid overflow. **---------------------------------------------------------------- */ u_short dqueueget; /* Next position to scan */ u_int32 *dqueue; /* Completion (done) queue */ /*---------------------------------------------------------------- ** 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 */ /*---------------------------------------------------------------- ** Miscellaneous buffers accessed by the scripts-processor. ** They shall be DWORD aligned, because they may be read or ** written with a script command. **---------------------------------------------------------------- */ u_char msgout[12]; /* Buffer for MESSAGE OUT */ u_char msgin [12]; /* Buffer for MESSAGE IN */ u_int32 lastmsg; /* Last SCSI message sent */ u_char scratch; /* Scratch for SCSI receive */ /*---------------------------------------------------------------- ** Miscellaneous configuration and status parameters. **---------------------------------------------------------------- */ u_char scsi_mode; /* Current SCSI BUS mode */ u_char order; /* Tag order to use */ u_char verbose; /* Verbosity for this controller*/ u_int32 ncr_cache; /* Used for cache test at init. */ u_long p_ncb; /* BUS address of this NCB */ /*---------------------------------------------------------------- ** CCB lists and queue. **---------------------------------------------------------------- */ ccb_p ccbh[CCB_HASH_SIZE]; /* CCB hashed by DSA value */ struct ccb *ccbc; /* CCB chain */ XPT_QUEHEAD free_ccbq; /* Queue of available CCBs */ /*---------------------------------------------------------------- ** IMMEDIATE ARBITRATION (IARB) control. ** We keep track in 'last_cp' of the last CCB that has been ** queued to the SCRIPTS processor and clear 'last_cp' when ** this CCB completes. If last_cp is not zero at the moment ** we queue a new CCB, we set a flag in 'last_cp' that is ** used by the SCRIPTS as a hint for setting IARB. ** We donnot set more than 'iarb_max' consecutive hints for ** IARB in order to leave devices a chance to reselect. ** By the way, any non zero value of 'iarb_max' is unfair. :) **---------------------------------------------------------------- */#ifdef SCSI_NCR_IARB_SUPPORT struct ccb *last_cp; /* Last queud CCB used for IARB */ u_short iarb_max; /* Max. # consecutive IARB hints*/ u_short iarb_count; /* Actual # of these hints */#endif /*---------------------------------------------------------------- ** We need the LCB in order to handle disconnections and ** to count active CCBs for task management. So, we use ** a unique CCB for LUNs we donnot have the LCB yet. ** This queue normally should have at most 1 element. **---------------------------------------------------------------- */ XPT_QUEHEAD b0_ccbq; /*---------------------------------------------------------------- ** We use a different scatter function for 896 rev 1. **---------------------------------------------------------------- */ int (*scatter) (ncb_p, ccb_p, Scsi_Cmnd *); /*---------------------------------------------------------------- ** Command abort handling. ** We need to synchronize tightly with the SCRIPTS ** processor in order to handle things correctly. **---------------------------------------------------------------- */ u_char abrt_msg[4]; /* Message to send buffer */ struct scr_tblmove abrt_tbl; /* Table for the MOV of it */ struct scr_tblsel abrt_sel; /* Sync params for selection */ u_char istat_sem; /* Tells the chip to stop (SEM) */ /*---------------------------------------------------------------- ** Fields that should be removed or changed. **---------------------------------------------------------------- */ struct usrcmd user; /* Command from user */ volatile u_char release_stage; /* Synchronisation stage on release */ /*---------------------------------------------------------------- ** Fields that are used (primarily) for integrity check **---------------------------------------------------------------- */ unsigned char check_integrity; /* Enable midlayer integ. check on * bus scan. */#ifdef SCSI_NCR_INTEGRITY_CHECKING unsigned char check_integ_par; /* Set if par or Init. Det. error * used only during integ check */#endif};#define NCB_PHYS(np, lbl) (np->p_ncb + offsetof(struct ncb, lbl))#define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl))#define NCB_SCRIPTH_PHYS(np,lbl) (np->p_scripth + offsetof (struct scripth,lbl))#define NCB_SCRIPTH0_PHYS(np,lbl) (np->p_scripth0+offsetof (struct scripth,lbl))/*==========================================================****** Script for NCR-Processor.**** Use ncr_script_fill() to create the variable parts.** Use ncr_script_copy_and_bind() to make a copy and** bind to physical addresses.******==========================================================**** We have to know the offsets of all labels before** we reach them (for forward jumps).** Therefore we declare a struct here.** If you make changes inside the script,** DONT FORGET TO CHANGE THE LENGTHS HERE!****----------------------------------------------------------*//*** Script fragments which are loaded into the on-chip RAM ** of 825A, 875, 876, 895, 895A and 896 chips.*/struct script { ncrcmd start [ 14]; ncrcmd getjob_begin [ 4]; ncrcmd getjob_end [ 4]; ncrcmd select [ 8]; ncrcmd wf_sel_done [ 2]; ncrcmd send_ident [ 2];#ifdef SCSI_NCR_IARB_SUPPORT ncrcmd select2 [ 8];#else ncrc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -