📄 cpqfctsstructs.h
字号:
ULONG reserved; ULONG Data_Len; ULONG reserved_; ULONG reserved__; // --- extended/local Gather Len/Address pairs ULONG GLen1; // DWord A ULONG GAddr1; ULONG GLen2; ULONG GAddr2; ULONG GLen3; ULONG GAddr3;} TachLiteTRE;typedef struct{ void *PoolPage[TL_MAX_SGPAGES];} SGPAGES, *PSGPAGES; // linked list of S/G pairs, by Exchangetypedef struct // SCSI Exchange State Table{ union // Entry can be IWE, IRE, TWE, TRE { // 64 bytes per entry TachLiteIWE IWE; TachLiteIRE IRE; TachLiteTWE TWE; TachLiteTRE TRE; } u[TACH_SEST_LEN]; TachFCHDR DataHDR[TACH_SEST_LEN]; // for SEST FCP_DATA frame hdr (no pl) TachFCHDR_RSP RspHDR[TACH_SEST_LEN]; // space for SEST FCP_RSP frame SGPAGES sgPages[TACH_SEST_LEN]; // array of Pool-allocations ULONG length; // Length register ULONG base; // copy of base ptr for debug} TachSEST;typedef struct // each register has it's own address // and value (used for write-only regs){ void* address; volatile ULONG value;} FCREGISTER;typedef struct // Host copy - TachLite Registers{ ULONG IOBaseL, IOBaseU; // I/O port lower and upper TL register addresses ULONG MemBase; // memory mapped register addresses void* ReMapMemBase; // O/S VM reference for MemBase ULONG wwn_hi; // WWN is set once at startup ULONG wwn_lo; ULONG my_al_pa; // al_pa received after LIP() ULONG ROMCTR; // flags for on-board RAM/ROM ULONG RAMBase; // on-board RAM (i.e. some Tachlites) ULONG SROMBase; // on-board EEPROM (some Tachlites) ULONG PCIMCTR; // PCI Master Control Reg (has bus width) FCREGISTER INTEN; // copy of interrupt enable mask FCREGISTER INTPEND; // interrupt pending FCREGISTER INTSTAT; // interrupt status FCREGISTER SFQconsumerIndex; FCREGISTER ERQproducerIndex; FCREGISTER TYconfig; // TachYon (chip level) FCREGISTER TYcontrol; FCREGISTER TYstatus; FCREGISTER FMconfig; // Frame Manager (FC loop level) FCREGISTER FMcontrol; FCREGISTER FMstatus; FCREGISTER FMLinkStatus1; FCREGISTER FMLinkStatus2; FCREGISTER FMBB_CreditZero; FCREGISTER status; FCREGISTER ed_tov; // error detect time-out value FCREGISTER rcv_al_pa; // received arb. loop physical address FCREGISTER primitive; // e.g. LIP(), OPN(), ...} TL_REGISTERS;typedef struct { ULONG ok; ULONG invalidArgs; ULONG linkDown; ULONG linkUp; ULONG outQueFull; ULONG SESTFull; ULONG hpe; // host programming err (from Tach) ULONG FC4aborted; // aborts from Application or upper driver layer ULONG FC2aborted; // aborts from our driver's timeouts ULONG timeouts; // our driver timeout (on individual exchanges) ULONG logouts; // explicit - sent LOGO; implicit - device removed ULONG retries; ULONG linkFailTX; ULONG linkFailRX; ULONG CntErrors; // byte count expected != count received (typ. SEST) ULONG e_stores; // elastic store errs ULONG resets; // hard or soft controller resets ULONG FMinits; // TACH Frame Manager Init (e.g. LIPs) ULONG lnkQueFull; // too many LOGIN, loop commands ULONG ScsiQueFull; // too many FCP-SCSI inbound frames ULONG LossofSignal; // FM link status 1 regs ULONG BadRXChar; // FM link status 1 regs ULONG LossofSync; // FM link status 1 regs ULONG Rx_EOFa; // FM link status 2 regs (received EOFa) ULONG Dis_Frm; // FM link status 2 regs (discarded frames) ULONG Bad_CRC; // FM link status 2 regs ULONG BB0_Timer; // FM BB_Credit Zero Timer Reg ULONG loopBreaks; // infinite loop exits ULONG lastBB0timer; // static accum. buffer needed by Tachlite} FCSTATS;typedef struct // Config Options{ // LS Bit first USHORT : 1; // bit0: USHORT flogi : 1; // bit1: We sent FLOGI - wait for Fabric logins USHORT fabric: 1; // bit2: Tachyon detected Fabric (FM stat LG) USHORT LILPin: 1; // bit3: We can use an FC-AL LILP frame USHORT target: 1; // bit4: this Port has SCSI target capability USHORT initiator: 1; // bit5: this Port has SCSI initiator capability USHORT extLoopback: 1; // bit6: loopback at GBIC USHORT intLoopback: 1; // bit7: loopback in HP silicon USHORT : 1; // bit8: USHORT : 1; // bit9: USHORT : 1; // bit10: USHORT : 1; // bit11: USHORT : 1; // bit12: USHORT : 1; // bit13: USHORT : 1; // bit14: USHORT : 1; // bit15:} FC_OPTIONS;typedef struct dyn_mem_pair{ void *BaseAllocated; // address as allocated from O/S; unsigned long AlignedAddress; // aligned address (used by Tachyon DMA)} ALIGNED_MEM;// these structs contain only CRUCIAL (stuff we actually use) parameters// from FC-PH(n) logins. (Don't save entire LOGIN payload to save mem.)// Implicit logout happens when the loop goes down - we require PDISC// to restore. Explicit logout is when WE decide never to talk to someone,// or when a target refuses to talk to us, i.e. sends us a LOGO frame or// LS_RJT reject in response to our PLOGI request.#define IMPLICIT_LOGOUT 1#define EXPLICIT_LOGOUT 2typedef struct { UCHAR channel; // SCSI "bus" UCHAR target; UCHAR InqDeviceType; // byte 0 from SCSI Inquiry response UCHAR VolumeSetAddressing; // FCP-SCSI LUN coding (40h for VSA) UCHAR LunMasking; // True if selective presentation supported UCHAR lun[CPQFCTS_MAX_LUN];} SCSI_NEXUS;typedef struct { union { UCHAR ucWWN[8]; // a FC 64-bit World Wide Name/ PortID of target // addressing of single target on single loop... u64 liWWN; } u; ULONG port_id; // a FC 24-bit address of port (lower 8 bits = al_pa) Scsi_Cmnd ScsiCmnd; // command buffer for Report Luns#define REPORT_LUNS_PL 256 UCHAR ReportLunsPayload[REPORT_LUNS_PL]; SCSI_NEXUS ScsiNexus; // LUNs per FC device ULONG LOGO_counter; // might try several times before logging out for good ULONG LOGO_timer; // after LIP, ports expecting PDISC must time-out and // LOGOut if successful PDISC not completed in 2 secs ULONG concurrent_seq; // must be 1 or greater ULONG rx_data_size; // e.g. 128, 256, 1024, 2048 per FC-PH spec ULONG BB_credit; ULONG EE_credit; ULONG fcp_info; // from PRLI (i.e. INITIATOR/ TARGET flags) // flags for login process BOOLEAN Originator; // Login sequence Originated (if false, we // responded to another port's login sequence) BOOLEAN plogi; // PLOGI frame ACCepted (originated or responded) BOOLEAN pdisc; // PDISC frame was ORIGINATED (self-login logic) BOOLEAN prli; // PRLI frame ACCepted (originated or responded) BOOLEAN flogi; // FLOGI frame ACCepted (originated or responded) BOOLEAN logo; // port permanently logged out (invalid login param) BOOLEAN flogiReq; // Fabric login required (set in LIP process) UCHAR highest_ver; UCHAR lowest_ver; // when the "target" (actually FC Port) is waiting for login // (e.g. after Link reset), set the device_blocked bit; // after Port completes login, un-block target. UCHAR device_blocked; // see Scsi_Device struct // define singly-linked list of logged-in ports // once a port_id is identified, it is remembered, // even if the port is removed indefinitely PVOID pNextPort; // actually, type PFC_LOGGEDIN_PORT; void for Compiler} FC_LOGGEDIN_PORT, *PFC_LOGGEDIN_PORT;// This serves as the ESB (Exchange Status Block),// and has timeout counter; used for ABORTstypedef struct { // FC-1 X_IDs ULONG type; // ELS_PLOGI, SCSI_IWE, ... (0 if free) PFC_LOGGEDIN_PORT pLoggedInPort; // FC device on other end of Exchange Scsi_Cmnd *Cmnd; // Linux SCSI command packet includes S/G list ULONG timeOut; // units of ??, DEC by driver, Abort when 0 ULONG reTries; // need one or more retries? ULONG status; // flags indicating errors (0 if none) TachLiteIRB IRB; // I/O Request Block, gets copied to ERQ TachFCHDR_GCMND fchs; // location of IRB's Req_A_SFS_Addr} FC_EXCHANGE, *PFC_EXCHANGE;// Unfortunately, Linux limits our kmalloc() allocations to 128k.// Because of this and the fact that our ScsiRegister allocation// is also constrained, we move this large structure out for// allocation after Scsi Register.// (In other words, this cumbersome indirection is necessary// because of kernel memory allocation constraints!)typedef struct // we will allocate this dynamically{ FC_EXCHANGE fcExchange[ TACH_MAX_XID ];} FC_EXCHANGES;typedef struct{ char Name[64]; // name of controller ("HP Tachlite TL Rev2.0, 33MHz, 64bit bus") //PVOID pAdapterDevExt; // back pointer to device object/extension ULONG ChipType; // local numeric key for Tachyon Type / Rev. ULONG status; // our Driver - logical status TL_REGISTERS Registers; // reg addresses & host memory copies // FC-4 mapping of 'transaction' to X_IDs UCHAR LILPmap[32*4]; // Loop Position Map of ALPAs (late FC-AL only) FC_OPTIONS Options; // e.g. Target, Initiator, loopback... UCHAR highest_FCPH_ver; // FC-PH version limits UCHAR lowest_FCPH_ver; // FC-PH version limits FC_EXCHANGES *Exchanges; ULONG fcLsExchangeLRU; // Least Recently Used counter (Link Service) ULONG fcSestExchangeLRU; // Least Recently Used counter (FCP-SCSI) FC_LOGGEDIN_PORT fcPorts; // linked list of every FC port ever seen FCSTATS fcStats; // FC comm err counters // Host memory QUEUE pointers TachLiteERQ *ERQ; // Exchange Request Que TachyonIMQ *IMQ; // Inbound Message Que TachLiteSFQ *SFQ; // Single Frame Queue TachSEST *SEST; // SCSI Exchange State Table // these function pointers are for "generic" functions, which are // replaced with Host Bus Adapter types at // runtime. int (*CreateTachyonQues)( void* , int); int (*DestroyTachyonQues)( void* , int); int (*LaserControl)(void*, int ); // e.g. On/Off int (*ResetTachyon)(void*, int ); void (*FreezeTachyon)(void*, int ); void (*UnFreezeTachyon)(void*, int ); int (*InitializeTachyon)(void*, int, int ); int (*InitializeFrameManager)(void*, int ); int (*ProcessIMQEntry)(void*); int (*ReadWriteWWN)(void*, int ReadWrite); int (*ReadWriteNVRAM)(void*, void*, int ReadWrite);} TACHYON, *PTACHYON;void cpqfcTSClearLinkStatusCounters(TACHYON * fcChip);int CpqTsCreateTachLiteQues( void* pHBA, int opcode);int CpqTsDestroyTachLiteQues( void* , int);int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2);int CpqTsProcessIMQEntry(void* pHBA);int CpqTsResetTachLite(void *pHBA, int type);void CpqTsFreezeTachlite(void *pHBA, int type);void CpqTsUnFreezeTachlite(void *pHBA, int type);int CpqTsInitializeFrameManager(void *pHBA, int);int CpqTsLaserControl( void* addrBase, int opcode );int CpqTsReadWriteWWN(void*, int ReadWrite);int CpqTsReadWriteNVRAM(void*, void* data, int ReadWrite);void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter);void cpqfcTSWorkerThread( void *host);int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf );ULONG cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count, UCHAR *buf );BOOLEAN tl_write_i2c_nvram( void* GPIOin, void* GPIOout, USHORT startOffset, // e.g. 0x2f for WWN start USHORT count, UCHAR *buf );// define misc functions int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]);int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]);void* fcMemManager( ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab, ULONG ulAlignedAddress);void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt);//ULONG virt_to_phys( PVOID virtaddr ); // Linux interrupt handlervoid cpqfcTS_intr_handler( int irq,void *dev_id,struct pt_regs *regs);void cpqfcTSheartbeat( unsigned long ptr );// The biggest Q element we deal with is Aborts - we// need 4 bytes for x_ID, and a Scsi_Cmnd (~284 bytes)//#define LINKQ_ITEM_SIZE ((4+sizeof(Scsi_Cmnd)+3)/4)#define LINKQ_ITEM_SIZE (3*16)typedef struct{ ULONG Type; // e.g. LINKUP, SFQENTRY, PDISC, BLS_ABTS, ... ULONG ulBuff[ LINKQ_ITEM_SIZE ];} LINKQ_ITEM;#define FC_LINKQ_DEPTH TACH_MAX_XIDtypedef struct{ ULONG producer; ULONG consumer; // when producer equals consumer, Q empty LINKQ_ITEM Qitem[ FC_LINKQ_DEPTH ];} FC_LINK_QUE, *PFC_LINK_QUE; // DPC routines post to here on Inbound SCSI frames // User thread processes#define FC_SCSIQ_DEPTH 32typedef struct{ int Type; // e.g. SCSI ULONG ulBuff[ 3*16 ];} SCSIQ_ITEM;typedef struct{ ULONG producer; ULONG consumer; // when producer equals consumer, Q empty SCSIQ_ITEM Qitem[ FC_SCSIQ_DEPTH ];} FC_SCSI_QUE, *PFC_SCSI_QUE;#define DYNAMIC_ALLOCATIONS 4 // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST// Linux space allocated per HBA (chip state, etc.)typedef struct { struct Scsi_Host *HostAdapter; // back pointer to Linux Scsi struct TACHYON fcChip; // All Tachyon registers, Queues, functions ALIGNED_MEM dynamic_mem[DYNAMIC_ALLOCATIONS]; struct pci_dev *PciDev; Scsi_Cmnd *LinkDnCmnd[CPQFCTS_REQ_QUEUE_LEN]; // collects Cmnds during LDn // (for Acceptable targets) Scsi_Cmnd *BoardLockCmnd[CPQFCTS_REQ_QUEUE_LEN]; // SEST was full Scsi_Cmnd *BadTargetCmnd[CPQFCTS_MAX_TARGET_ID]; // missing targets u_char HBAnum; // 0-based host number struct timer_list cpqfcTStimer; // FC utility timer for implicit // logouts, FC protocol timeouts, etc. int fcStatsTime; // Statistics delta reporting time struct task_struct *worker_thread; // our kernel thread int PortDiscDone; // set by SendLogins(), cleared by LDn struct semaphore *TachFrozen; struct semaphore *TYOBcomplete; // handshake for Tach outbound frames struct semaphore *fcQueReady; // FibreChannel work for our kernel thread struct semaphore *notify_wt; // synchronizes kernel thread kill struct semaphore *BoardLock; PFC_LINK_QUE fcLQ; // the WorkerThread operates on this spinlock_t hba_spinlock; // held/released by WorkerThread} CPQFCHBA;#define CPQ_SPINLOCK_HBA( x ) spin_lock(&x->hba_spinlock);#define CPQ_SPINUNLOCK_HBA(x) spin_unlock(&x->hba_spinlock);void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata, PFC_LOGGEDIN_PORT pFcPort);void cpqfcTSTerminateExchange( CPQFCHBA*, SCSI_NEXUS *target, int );PFC_LOGGEDIN_PORT fcPortLoggedIn( CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs, BOOLEAN, BOOLEAN);void fcProcessLoggedIn( CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs);ULONG cpqfcTSBuildExchange( CPQFCHBA *cpqfcHBAdata, ULONG type, // e.g. PLOGI TachFCHDR_GCMND* InFCHS, // incoming FCHS void *Data, // the CDB, scatter/gather, etc. LONG *ExchangeID ); // allocated exchange IDULONG cpqfcTSStartExchange( CPQFCHBA *cpqfcHBAdata, LONG ExchangeID );void cpqfcTSCompleteExchange( PTACHYON fcChip, ULONG exchange_ID);PFC_LOGGEDIN_PORT fcFindLoggedInPort( PTACHYON fcChip, Scsi_Cmnd *Cmnd, // (We want the channel/target/lun Nexus from Cmnd) ULONG port_id, // search linked list for al_pa, or UCHAR wwn[8], // search linked list for WWN, or... PFC_LOGGEDIN_PORT *pLastLoggedInPort);// don't do this unless you have the right hardware!#define TRIGGERABLE_HBA 1#ifdef TRIGGERABLE_HBAvoid TriggerHBA( void*, int);#endifvoid cpqfcTSPutLinkQue( CPQFCHBA *cpqfcHBAdata, int Type, void *QueContent);void fcPutScsiQue( CPQFCHBA *cpqfcHBAdata, int Type, void *QueContent);void fcLinkQReset( CPQFCHBA *);void fcScsiQReset( CPQFCHBA *);void fcSestReset( CPQFCHBA *);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -