| /* Copyright(c) 2000, Compaq Computer Corporation |
| * Fibre Channel Host Bus Adapter 64-bit, 66MHz PCI |
| * Originally developed and tested on: |
| * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ... |
| * SP# P225CXCBFIEL6T, Rev XC |
| * SP# 161290-001, Rev XD |
| * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License as published by the |
| * Free Software Foundation; either version 2, or (at your option) any |
| * later version. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License for more details. |
| * Written by Don Zimmerman |
| */ |
| #ifndef CPQFCTSSTRUCTS_H |
| #define CPQFCTSSTRUCTS_H |
| |
| #include <linux/timer.h> // timer declaration in our host data |
| #include <linux/interrupt.h> |
| #include <asm/atomic.h> |
| #include "cpqfcTSioctl.h" |
| |
| #define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \ |
| for( wait_time=jiffies + (secs*HZ); \ |
| time_before(jiffies, wait_time) ;) ; } |
| |
| #define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
| // don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c |
| #define VER_MAJOR 2 |
| #define VER_MINOR 5 |
| #define VER_SUBMINOR 4 |
| |
| // Macros for kernel (esp. SMP) tracing using a PCI analyzer |
| // (e.g. x86). |
| //#define PCI_KERNEL_TRACE |
| #ifdef PCI_KERNEL_TRACE |
| #define PCI_TRACE(x) inl( fcChip->Registers.IOBaseL +x); |
| #define PCI_TRACEO(x,y) outl( x, (fcChip->Registers.IOBaseL +y)); |
| #else |
| |
| #define PCI_TRACE(x) |
| #define PCI_TRACEO(x,y) |
| #endif |
| |
| |
| //#define DEBUG_CMND 1 // debug output for Linux Scsi CDBs |
| //#define DUMMYCMND_DBG 1 |
| |
| //#define DEBUG_CPQFCTS 1 |
| //#undef DEBUG_CPQFCTS |
| #ifdef DEBUG_CPQFCTS |
| #define ENTER(x) printk("cpqfcts : entering %s()\n", x); |
| #define LEAVE(x) printk("cpqfcts : leaving %s()\n", x); |
| #define DEBUG(x) x |
| #else |
| #define ENTER(x) |
| #define LEAVE(x) |
| #define DEBUG(x) |
| #endif /* DEBUG_CPQFCTS */ |
| |
| //#define DEBUG_CPQFCTS_PCI 1 |
| //#undef DEBUG_CPQFCTS_PCI |
| #if DEBUG_CPQFCTS_PCI |
| #define DEBUG_PCI(x) x |
| #else |
| #define DEBUG_PCI(x) |
| #endif /* DEBUG_CPQFCTS_PCI */ |
| |
| #define STACHLITE66_TS12 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2" |
| #define STACHLITE66_TS13 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.3" |
| #define STACHLITE_UNKNOWN "Compaq FibreChannel HBA Tachyon Chip/Board Ver??" |
| #define SAGILENT_XL2_21 "Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.1" |
| |
| // PDA is Peripheral Device Address, VSA is Volume Set Addressing |
| // Linux SCSI parameters |
| #define CPQFCTS_MAX_TARGET_ID 64 |
| |
| // Note, changing CPQFCTS_MAX_LUN to less than 32 (e.g, 8) will result in |
| // strange behavior if a box with more than, e.g. 8, is on the loop. |
| #define CPQFCTS_MAX_LUN 32 // The RA-4x00 supports 32 (Linux SCSI supports 8) |
| #define CPQFCTS_MAX_CHANNEL 0 // One FC port on cpqfcTS HBA |
| |
| #define CPQFCTS_CMD_PER_LUN 15 // power of 2 -1, must be >0 |
| #define CPQFCTS_REQ_QUEUE_LEN (TACH_SEST_LEN/2) // must be < TACH_SEST_LEN |
| |
| #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) |
| #ifndef DECLARE_MUTEX_LOCKED |
| #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED |
| #endif |
| |
| #define DEV_NAME "cpqfcTS" |
| |
| struct SupportedPCIcards |
| { |
| __u16 vendor_id; |
| __u16 device_id; |
| }; |
| |
| // nn:nn denotes bit field |
| // TachyonHeader struct def. |
| // the fields shared with ODB |
| // need to have same value |
| |
| |
| |
| |
| #ifndef BYTE |
| //typedef UCHAR BYTE; |
| typedef __u8 BYTE; |
| #endif |
| #ifndef UCHAR |
| typedef __u8 UCHAR; |
| #endif |
| #ifndef LONG |
| typedef __s32 LONG; |
| #endif |
| #ifndef ULONG |
| typedef __u32 ULONG; |
| #endif |
| #ifndef PVOID |
| typedef void * PVOID; |
| #endif |
| #ifndef USHORT |
| typedef __u16 USHORT; |
| #endif |
| #ifndef BOOLEAN |
| typedef __u8 BOOLEAN; |
| #endif |
| |
| |
| // macro for FC-PH reject codes |
| // payload format for LS_RJT (FC payloads are big endian): |
| // byte 0 1 2 3 (MSB) |
| // DWORD 0 01 00 00 00 |
| // DWORD 1 resvd code expl. vendor |
| |
| #define LS_RJT_REASON( code, expl) (( code<<8) | (expl <<16)) |
| |
| |
| #define TachLiteSTATUS 0x12 |
| |
| // Fibre Channel EXCHANGE status codes for Tachyon chips/ driver software |
| // 32-bit ERROR word defines |
| #define INVALID_ARGS 0x1 |
| #define LNKDWN_OSLS 0x2 |
| #define LNKDWN_LASER 0x4 |
| #define OUTQUE_FULL 0x8 |
| #define DRIVERQ_FULL 0x10 |
| #define SEST_FULL 0x20 |
| #define BAD_ALPA 0x40 |
| #define OVERFLOW 0x80 // inbound CM |
| #define COUNT_ERROR 0x100 // inbound CM |
| #define LINKFAIL_RX 0x200 // inbound CM |
| #define ABORTSEQ_NOTIFY 0x400 // outbound CM |
| #define LINKFAIL_TX 0x800 // outbound CM |
| #define HOSTPROG_ERR 0x1000 // outbound CM |
| #define FRAME_TO 0x2000 // outbound CM |
| #define INV_ENTRY 0x4000 // outbound CM |
| #define SESTPROG_ERR 0x8000 // outbound CM |
| #define OUTBOUND_TIMEOUT 0x10000L // timeout waiting for Tachyon outbound CM |
| #define INITIATOR_ABORT 0x20000L // initiator exchange timeout or O/S ABORT |
| #define MEMPOOL_FAIL 0x40000L // O/S memory pool allocation failed |
| #define FC2_TIMEOUT 0x80000L // driver timeout for lost frames |
| #define TARGET_ABORT 0x100000L // ABTS received from FC port |
| #define EXCHANGE_QUEUED 0x200000L // e.g. Link State was LDn on fcStart |
| #define PORTID_CHANGED 0x400000L // fc Port address changed |
| #define DEVICE_REMOVED 0x800000L // fc Port address changed |
| // Several error scenarios result in SEST Exchange frames |
| // unexpectedly arriving in the SFQ |
| #define SFQ_FRAME 0x1000000L // SFQ frames from open Exchange |
| |
| // Maximum number of Host Bus Adapters (HBA) / controllers supported |
| // only important for mem allocation dimensions - increase as necessary |
| |
| #define MAX_ADAPTERS 8 |
| #define MAX_RX_PAYLOAD 1024 // hardware dependent max frame payload |
| // Tach header struc defines |
| #define SOFi3 0x7 |
| #define SOFf 0x8 |
| #define SOFn3 0xB |
| #define EOFn 0x5 |
| #define EOFt 0x6 |
| |
| // FCP R_CTL defines |
| #define FCP_CMND 0x6 |
| #define FCP_XFER_RDY 0x5 |
| #define FCP_RSP 0x7 |
| #define FCP_RESPONSE 0x777 // (arbitrary #) |
| #define NEED_FCP_RSP 0x77 // (arbitrary #) |
| #define FCP_DATA 0x1 |
| |
| #define RESET_TACH 0x100 // Reset Tachyon/TachLite |
| #define SCSI_IWE 0x2000 // initiator write entry (for SEST) |
| #define SCSI_IRE 0x3000 // initiator read entry (for SEST) |
| #define SCSI_TRE 0x400 // target read entry (for SEST) |
| #define SCSI_TWE 0x500 // target write entry (for SEST) |
| #define TOGGLE_LASER 0x800 |
| #define LIP 0x900 |
| #define CLEAR_FCPORTS 99 // (arbitrary #) free mem for Logged in ports |
| #define FMINIT 0x707 // (arbitrary) for Frame Manager Init command |
| |
| // BLS == Basic Link Service |
| // ELS == Extended Link Service |
| #define BLS_NOP 4 |
| #define BLS_ABTS 0x10 // FC-PH Basic Link Service Abort Sequence |
| #define BLS_ABTS_ACC 0x100 // FC-PH Basic Link Service Abort Sequence Accept |
| #define BLS_ABTS_RJT 0x101 // FC-PH Basic Link Service Abort Sequence Reject |
| #define ELS_PLOGI 0x03 // FC-PH Port Login (arbitrary assign) |
| #define ELS_SCR 0x70 // (arb assign) State Change Registration (Fabric) |
| #define FCS_NSR 0x72 // (arb assign) Name Service Request (Fabric) |
| #define ELS_FLOGI 0x44 // (arb assign) Fabric Login |
| #define ELS_FDISC 0x41 // (arb assign) Fabric Discovery (Login) |
| #define ELS_PDISC 0x50 // FC-PH2 Port Discovery |
| #define ELS_ABTX 0x06 // FC-PH Abort Exchange |
| #define ELS_LOGO 0x05 // FC-PH Port Logout |
| #define ELS_PRLI 0x20 // FCP-SCSI Process Login |
| #define ELS_PRLO 0x21 // FCP-SCSI Process Logout |
| #define ELS_LOGO_ACC 0x07 // {FC-PH} Port Logout Accept |
| #define ELS_PLOGI_ACC 0x08 // {FC-PH} Port Login Accept |
| #define ELS_ACC 0x18 // {FC-PH} (generic) ACCept |
| #define ELS_PRLI_ACC 0x22 // {FCP-SCSI} Process Login Accept |
| #define ELS_RJT 0x1000000 |
| #define SCSI_REPORT_LUNS 0x0A0 |
| #define FCP_TARGET_RESET 0x200 |
| |
| #define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame |
| |
| #define SFQ_UNASSISTED_FCP 1 // ICM, DWord3, "Type" unassisted FCP |
| #define SFQ_UNKNOWN 0x31 // (arbitrary) ICM, DWord3, "Type" unknown |
| |
| // these "LINK" bits refer to loop or non-loop |
| #define LINKACTIVE 0x2 // fcLinkQ type - LINK UP Tachyon FM 'Lup' bit set |
| #define LINKDOWN 0xf2 // fcLinkQ type - LINK DOWN Tachyon FM 'Ldn' bit set |
| |
| //#define VOLUME_SET_ADDRESSING 1 // "channel" or "bus" 1 |
| |
| typedef struct // 32 bytes hdr ONLY (e.g. FCP_DATA buffer for SEST) |
| { |
| ULONG reserved; // dword 0 (don't use) |
| ULONG sof_eof; |
| ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID |
| ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID |
| ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL |
| ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT |
| ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID |
| ULONG ro; // dword 7 - relative offset |
| } TachFCHDR; |
| |
| // NOTE!! the following struct MUST be 64 bytes. |
| typedef struct // 32 bytes hdr + 32 bytes payload |
| { |
| ULONG reserved; // dword 0 (don't use - must clear to 0) |
| ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp |
| ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID |
| ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID |
| ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL |
| ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT |
| ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID |
| ULONG ro; // dword 7 - relative offset |
| //--------- |
| __u32 pl[8]; // dwords 8-15 frame data payload |
| } TachFCHDR_CMND; |
| |
| |
| typedef struct // 32 bytes hdr + 120 bytes payload |
| { |
| ULONG reserved; // dword 0 (don't use - must clear to 0) |
| ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp |
| ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID |
| ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID |
| ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL |
| ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT |
| ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID |
| ULONG ro; // dword 7 - relative offset |
| //--------- |
| __u32 pl[30]; // largest necessary payload (for LOGIN cmnds) |
| } TachFCHDR_GCMND; |
| |
| typedef struct // 32 bytes hdr + 64 bytes payload |
| { |
| ULONG reserved; // dword 0 (don't use) |
| ULONG sof_eof; |
| ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID |
| ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID |
| ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL |
| ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT |
| ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID |
| ULONG ro; // dword 7 - relative offset |
| //--------- |
| __u32 pl[18]; // payload for FCP-RSP (response buffer) RA-4x00 is 72bytes |
| } TachFCHDR_RSP; |
| |
| |
| |
| |
| |
| |
| // Inbound Message Queue structures... |
| typedef struct // each entry 8 words (32 bytes) |
| { |
| ULONG type; // IMQ completion message types |
| ULONG word[7]; // remainder of structure |
| // interpreted by IMQ type |
| } TachyonIMQE; |
| |
| |
| // Queues for TachLite not in original Tachyon |
| // ERQ - Exchange Request Queue (for outbound commands) |
| // SFQ - Single Frame Queue (for incoming frames) |
| |
| // Define Tachyon Outbound Command Que |
| // (Since many Tachyon registers are Read |
| // only, maintain copies for debugging) |
| // most Tach ques need power-of-2 sizes, |
| // where registers are loaded with po2 -1 |
| #define TACH_SEST_LEN 512 // TachLite SEST |
| |
| #define ELS_EXCHANGES 64 // e.g. PLOGI, RSCN, ... |
| // define the total number of outstanding (simultaneous) exchanges |
| #define TACH_MAX_XID (TACH_SEST_LEN + ELS_EXCHANGES) // ELS exchanges |
| |
| #define ERQ_LEN 128 // power of 2, max 4096 |
| |
| // Inbound Message Queue structures... |
| #define IMQ_LEN 512 // minimum 4 entries [(power of 2) - 1] |
| typedef struct // 8 words - 32 bytes |
| { |
| TachyonIMQE QEntry[IMQ_LEN]; |
| ULONG producerIndex; // IMQ Producer Index register |
| // @32 byte align |
| ULONG consumerIndex; // Consumer Index register (in Tachyon) |
| ULONG length; // Length register |
| ULONG base; |
| } TachyonIMQ; // @ 32 * IMQ_LEN align |
| |
| |
| |
| typedef struct // inbound completion message |
| { |
| ULONG Type; |
| ULONG Index; |
| ULONG TransferLength; |
| } TachyonInbCM; |
| |
| |
| |
| // arbitrary numeric tags for TL structures |
| #define TL_FCHS 1 // TachLite Fibre Channel Header Structure |
| #define TL_IWE 2 // initiator write entry (for SEST) |
| #define TL_TWE 3 // target write entry (for SEST) |
| #define TL_IRE 4 // initiator read entry (for SEST) |
| #define TL_TRE 5 // target read entry (for SEST) |
| #define TL_IRB 6 // I/O request block |
| |
| // for INCOMING frames |
| #define SFQ_LEN 32 // minimum 32 entries, max 4096 |
| |
| typedef struct // Single Frame Que |
| { |
| TachFCHDR_CMND QEntry[SFQ_LEN]; // must be 64 bytes!! |
| ULONG producerIndex; // IMQ Producer Index register |
| // @32 byte align |
| ULONG consumerIndex; // Consumer Index register (in Tachyon) |
| ULONG length; // Length register |
| ULONG base; |
| } TachLiteSFQ; |
| |
| |
| typedef struct // I/O Request Block flags |
| { |
| UCHAR BRD : 1; |
| UCHAR : 1; // reserved |
| UCHAR SFA : 1; |
| UCHAR DNC : 1; |
| UCHAR DIN : 1; |
| UCHAR DCM : 1; |
| UCHAR CTS : 1; |
| UCHAR SBV : 1; // IRB entry valid - IRB'B' only |
| } IRBflags; |
| |
| typedef struct // I/O Request Block |
| { // Request 'A' |
| ULONG Req_A_SFS_Len; // total frame len (hdr + payload), min 32 |
| ULONG Req_A_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent) |
| ULONG Req_A_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa) |
| ULONG Req_A_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST |
| // Request 'B' |
| ULONG Req_B_SFS_Len; // total frame len (hdr + payload), min 32 |
| ULONG Req_B_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent) |
| ULONG Req_B_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa) |
| ULONG Req_B_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST |
| } TachLiteIRB; |
| |
| |
| typedef struct // TachLite placeholder for IRBs |
| { // aligned @sizeof(ERQ) for TachLite |
| // MAX commands is sum of SEST len and ERQ |
| // we know that each SEST entry requires an |
| // IRB (ERQ) entry; in addition, we provide |
| // ERQ_LEN |
| TachLiteIRB QEntry[ERQ_LEN]; // Base register; entries 32 bytes ea. |
| ULONG consumerIndex; // Consumer Index register |
| ULONG producerIndex; // ERQ Producer Index register |
| ULONG length; // Length register |
| ULONG base; // copy of base ptr for debug |
| // struct is sized for largest expected cmnd (LOGIN) |
| } TachLiteERQ; |
| |
| // for now, just 32 bit DMA, eventually 40something, with code changes |
| #define CPQFCTS_DMA_MASK ((unsigned long) (0x00000000FFFFFFFF)) |
| |
| #define TL_MAX_SG_ELEM_LEN 0x7ffff // Max buffer length a single S/G entry |
| // may represent (a hardware limitation). The |
| // only reason to ever change this is if you |
| // want to exercise very-hard-to-reach code in |
| // cpqfcTSworker.c:build_SEST_sglist(). |
| |
| #define TL_DANGER_SGPAGES 7 // arbitrary high water mark for # of S/G pages |
| // we must exceed to elicit a warning indicative |
| // of EXTREMELY large data transfers or |
| // EXTREME memory fragmentation. |
| // (means we just used up 2048 S/G elements, |
| // Never seen this is real life, only in |
| // testing with tricked up driver.) |
| |
| #define TL_EXT_SG_PAGE_COUNT 256 // Number of Extended Scatter/Gather a/l PAIRS |
| // Tachyon register (IOBaseU 0x68) |
| // power-of-2 value ONLY! 4 min, 256 max |
| |
| // byte len is #Pairs * 2 ULONG/Pair * 4 bytes/ULONG |
| #define TL_EXT_SG_PAGE_BYTELEN (TL_EXT_SG_PAGE_COUNT *2 *4) |
| |
| |
| |
| // SEST entry types: IWE, IRE, TWE, TRE |
| typedef struct |
| { |
| ULONG Hdr_Len; |
| ULONG Hdr_Addr; |
| ULONG RSP_Len; |
| ULONG RSP_Addr; |
| ULONG Buff_Off; |
| #define USES_EXTENDED_SGLIST(this_sest, x_ID) \ |
| (!((this_sest)->u[ x_ID ].IWE.Buff_Off & 0x80000000)) |
| ULONG Link; |
| ULONG RX_ID; |
| ULONG Data_Len; |
| ULONG Exp_RO; |
| ULONG Exp_Byte_Cnt; |
| // --- extended/local Gather Len/Address pairs |
| ULONG GLen1; |
| ULONG GAddr1; |
| ULONG GLen2; |
| ULONG GAddr2; |
| ULONG GLen3; |
| ULONG GAddr3; |
| } TachLiteIWE; |
| |
| |
| typedef struct |
| { |
| ULONG Seq_Accum; |
| ULONG reserved; // must clear to 0 |
| ULONG RSP_Len; |
| ULONG RSP_Addr; |
| ULONG Buff_Off; |
| ULONG Buff_Index; // ULONG 5 |
| ULONG Exp_RO; |
| ULONG Byte_Count; |
| ULONG reserved_; // ULONG 8 |
| ULONG Exp_Byte_Cnt; |
| // --- extended/local Scatter Len/Address pairs |
| ULONG SLen1; |
| ULONG SAddr1; |
| ULONG SLen2; |
| ULONG SAddr2; |
| ULONG SLen3; |
| ULONG SAddr3; |
| } TachLiteIRE; |
| |
| |
| typedef struct // Target Write Entry |
| { |
| ULONG Seq_Accum; // dword 0 |
| ULONG reserved; // dword 1 must clear to 0 |
| ULONG Remote_Node_ID; |
| ULONG reserved1; // dword 3 must clear to 0 |
| ULONG Buff_Off; |
| ULONG Buff_Index; // ULONG 5 |
| ULONG Exp_RO; |
| ULONG Byte_Count; |
| ULONG reserved_; // ULONG 8 |
| ULONG Exp_Byte_Cnt; |
| // --- extended/local Scatter Len/Address pairs |
| ULONG SLen1; |
| ULONG SAddr1; |
| ULONG SLen2; |
| ULONG SAddr2; |
| ULONG SLen3; |
| ULONG SAddr3; |
| } TachLiteTWE; |
| |
| typedef struct |
| { |
| ULONG Hdr_Len; |
| ULONG Hdr_Addr; |
| ULONG RSP_Len; // DWord 2 |
| ULONG RSP_Addr; |
| ULONG Buff_Off; |
| ULONG Buff_Index; // DWord 5 |
| 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 ext_sg_page_ptr_t *PSGPAGES; |
| typedef struct ext_sg_page_ptr_t |
| { |
| unsigned char page[TL_EXT_SG_PAGE_BYTELEN * 2]; // 2x for alignment |
| dma_addr_t busaddr; // need the bus addresses and |
| unsigned int maplen; // lengths for later pci unmapping. |
| PSGPAGES next; |
| } SGPAGES; // linked list of S/G pairs, by Exchange |
| |
| typedef 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 |
| PSGPAGES sgPages[TACH_SEST_LEN]; // head of linked list 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) |
| dma_addr_t dma_handle; |
| size_t size; |
| } 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 2 |
| |
| typedef 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) |
| |
| #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 ABORTs |
| typedef 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 |
| |
| dma_addr_t exch_dma_handle; |
| |
| // 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( struct pci_dev *pdev, |
| ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab, |
| ULONG ulAlignedAddress, dma_addr_t *dma_handle); |
| |
| void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt); |
| |
| //ULONG virt_to_phys( PVOID virtaddr ); |
| |
| |
| // Linux interrupt handler |
| irqreturn_t 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_XID |
| typedef 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 32 |
| |
| typedef 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; |
| |
| typedef struct { |
| /* This is tacked on to a Scsi_Request in upper_private_data |
| for pasthrough ioctls, as a place to hold data that can't |
| be stashed anywhere else in the Scsi_Request. We differentiate |
| this from _real_ upper_private_data by checking if the virt addr |
| is within our special pool. */ |
| ushort bus; |
| ushort pdrive; |
| } cpqfc_passthru_private_t; |
| |
| #define CPQFC_MAX_PASSTHRU_CMDS 100 |
| |
| #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; |
| dma_addr_t fcLQ_dma_handle; |
| |
| 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 |
| cpqfc_passthru_private_t *private_data_pool; |
| unsigned long *private_data_bits; |
| |
| } 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 ID |
| |
| ULONG cpqfcTSStartExchange( |
| CPQFCHBA *cpqfcHBAdata, |
| LONG ExchangeID ); |
| |
| void cpqfcTSCompleteExchange( |
| struct pci_dev *pcidev, |
| 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 |
| ); |
| |
| void cpqfcTSPutLinkQue( |
| CPQFCHBA *cpqfcHBAdata, |
| int Type, |
| void *QueContent); |
| |
| void fcPutScsiQue( |
| CPQFCHBA *cpqfcHBAdata, |
| int Type, |
| void *QueContent); |
| |
| void fcLinkQReset( |
| CPQFCHBA *); |
| void fcScsiQReset( |
| CPQFCHBA *); |
| void fcSestReset( |
| CPQFCHBA *); |
| |
| void cpqfc_pci_unmap(struct pci_dev *pcidev, |
| Scsi_Cmnd *cmd, |
| PTACHYON fcChip, |
| ULONG x_ID); |
| |
| extern const UCHAR valid_al_pa[]; |
| extern const int number_of_al_pa; |
| |
| #define FCP_RESID_UNDER 0x80000 |
| #define FCP_RESID_OVER 0x40000 |
| #define FCP_SNS_LEN_VALID 0x20000 |
| #define FCP_RSP_LEN_VALID 0x10000 |
| |
| // RSP_CODE definitions (dpANS Fibre Channel Protocol for SCSI, pg 34) |
| #define FCP_DATA_LEN_NOT_BURST_LEN 0x1000000 |
| #define FCP_CMND_FIELD_INVALID 0x2000000 |
| #define FCP_DATA_RO_NOT_XRDY_RO 0x3000000 |
| #define FCP_TASKFUNCTION_NS 0x4000000 |
| #define FCP_TASKFUNCTION_FAIL 0x5000000 |
| |
| // FCP-SCSI response status struct |
| typedef struct // see "TachFCHDR_RSP" definition - 64 bytes |
| { |
| __u32 reserved; |
| __u32 reserved1; |
| __u32 fcp_status; // field validity and SCSI status |
| __u32 fcp_resid; |
| __u32 fcp_sns_len; // length of FCP_SNS_INFO field |
| __u32 fcp_rsp_len; // length of FCP_RSP_INFO field (expect 8) |
| __u32 fcp_rsp_info; // 4 bytes of FCP protocol response information |
| __u32 fcp_rsp_info2; // (4 more bytes, since most implementations use 8) |
| __u8 fcp_sns_info[36]; // bytes for SCSI sense (ASC, ASCQ) |
| |
| } FCP_STATUS_RESPONSE, *PFCP_STATUS_RESPONSE; |
| |
| |
| // Fabric State Change Registration |
| typedef struct scrpl |
| { |
| __u32 command; |
| __u32 function; |
| } SCR_PL; |
| |
| // Fabric Name Service Request |
| typedef struct nsrpl |
| { |
| __u32 CT_Rev; // (& IN_ID) WORD 0 |
| __u32 FCS_Type; // WORD 1 |
| __u32 Command_code; // WORD 2 |
| __u32 reason_code; // WORD 3 |
| __u32 FCP; // WORD 4 (lower byte) |
| |
| } NSR_PL; |
| |
| |
| |
| // "FC.H" |
| #define MAX_RX_SIZE 0x800 // Max Receive Buffer Size is 2048 |
| #define MIN_RX_SIZE 0x100 // Min Size is 256, per FC-PLDA Spec |
| #define MAX_TARGET_RXIDS SEST_DEPTH |
| #define TARGET_RX_SIZE SEST_BUFFER_LENGTH |
| |
| #define CLASS_1 0x01 |
| #define CLASS_2 0x02 |
| #define CLASS_3 0x03 |
| |
| #define FC_PH42 0x08 |
| #define FC_PH43 0x09 |
| #define FC_PH3 0x20 |
| |
| #define RR_TOV 2 // Minimum Time for target to wait for |
| // PDISC after a LIP. |
| #define E_D_TOV 2 // Minimum Time to wait for Sequence |
| // Completion. |
| #define R_A_TOV 0 // Minimum Time for Target to wait |
| // before reclaiming resources. |
| // |
| // R_CTL Field |
| // |
| // Routing Bits (31-28) |
| // |
| #define FC4_DEVICE_DATA 0x00000000 |
| #define EXT_LINK_DATA 0x20000000 |
| #define FC4_LINK_DATA 0x30000000 |
| #define VIDEO_DATA 0x40000000 |
| #define BASIC_LINK_DATA 0x80000000 |
| #define LINK_CONTROL 0xC0000000 |
| #define ROUTING_MASK 0xF0000000 |
| |
| // |
| // Information Bits (27-24) |
| // |
| #define UNCAT_INFORMATION 0x00000000 |
| #define SOLICITED_DATA 0x01000000 |
| #define UNSOLICITED_CONTROL 0x02000000 |
| #define SOLICITED_CONTROL 0x03000000 |
| #define UNSOLICITED_DATA 0x04000000 |
| #define DATA_DESCRIPTOR 0x05000000 |
| #define UNSOLICITED_COMMAND 0x06000000 |
| #define COMMAND_STATUS 0x07000000 |
| #define INFO_MASK 0x0F000000 |
| // |
| // (Link Control Codes) |
| // |
| #define ACK_1 0x00000000 |
| #define ACK_0_OR_N 0x01000000 |
| #define P_RJT 0x02000000 |
| #define F_RJT 0x03000000 |
| #define P_BSY 0x04000000 |
| #define FABRIC_BUSY_TO_DF 0x05000000 // Fabric Busy to Data Frame |
| #define FABRIC_BUSY_TO_LC 0x06000000 // Fabric Busy to Link Ctl Frame |
| #define LINK_CREDIT_RESET 0x07000000 |
| // |
| // (Link Service Command Codes) |
| // |
| //#define LS_RJT 0x01000000 // LS Reject |
| |
| #define LS_ACC 0x02000000 // LS Accept |
| #define LS_PLOGI 0x03000000 // N_PORT Login |
| #define LS_FLOGI 0x04000000 // F_PORT Login |
| #define LS_LOGO 0x05000000 // Logout |
| #define LS_ABTX 0x06000000 // Abort Exchange |
| #define LS_RCS 0x07000000 // Read Connection Status |
| #define LS_RES 0x08000000 // Read Exchange Status |
| #define LS_RSS 0x09000000 // Read Sequence Status |
| #define LS_RSI 0x0A000000 // Request Seq Initiative |
| #define LS_ESTS 0x0B000000 // Establish Steaming |
| #define LS_ESTC 0x0C000000 // Estimate Credit |
| #define LS_ADVC 0x0D000000 // Advice Credit |
| #define LS_RTV 0x0E000000 // Read Timeout Value |
| #define LS_RLS 0x0F000000 // Read Link Status |
| #define LS_ECHO 0x10000000 // Echo |
| #define LS_TEST 0x11000000 // Test |
| #define LS_RRQ 0x12000000 // Reinstate Rec. Qual. |
| #define LS_PRLI 0x20000000 // Process Login |
| #define LS_PRLO 0x21000000 // Process Logout |
| #define LS_TPRLO 0x24000000 // 3rd Party Process Logout |
| #define LS_PDISC 0x50000000 // Process Discovery |
| #define LS_FDISC 0x51000000 // Fabric Discovery |
| #define LS_ADISC 0x52000000 // Discover Address |
| #define LS_RNC 0x53000000 // Report Node Capability |
| #define LS_SCR 0x62000000 // State Change Registration |
| #define LS_MASK 0xFF000000 |
| |
| // |
| // TYPE Bit Masks |
| // |
| #define BASIC_LINK_SERVICE 0x00000000 |
| #define EXT_LINK_SERVICE 0x01000000 |
| |
| #define LLC 0x04000000 |
| #define LLC_SNAP 0x05000000 |
| #define SCSI_FCP 0x08000000 |
| #define SCSI_GPP 0x09000000 |
| #define IPI3_MASTER 0x11000000 |
| #define IPI3_SLAVE 0x12000000 |
| #define IPI3_PEER 0x13000000 |
| #define CP_IPI3_MASTER 0x15000000 |
| #define CP_IPI3_SLAVE 0x16000000 |
| #define CP_IPI3_PEER 0x17000000 |
| #define SBCCS_CHANNEL 0x19000000 |
| #define SBCCS_CONTROL 0x1A000000 |
| #define FIBRE_SERVICES 0x20000000 |
| #define FC_FG 0x21000000 |
| #define FC_XS 0x22000000 |
| #define FC_AL 0x23000000 |
| #define SNMP 0x24000000 |
| #define HIPPI_FP 0x40000000 |
| #define TYPE_MASK 0xFF000000 |
| |
| typedef struct { |
| UCHAR seq_id_valid; |
| UCHAR seq_id; |
| USHORT reserved; // 2 bytes reserved |
| ULONG ox_rx_id; |
| USHORT low_seq_cnt; |
| USHORT high_seq_cnt; |
| } BA_ACC_PAYLOAD; |
| |
| typedef struct { |
| UCHAR reserved; |
| UCHAR reason_code; |
| UCHAR reason_explain; |
| UCHAR vendor_unique; |
| } BA_RJT_PAYLOAD; |
| |
| |
| typedef struct { |
| ULONG command_code; |
| ULONG sid; |
| USHORT ox_id; |
| USHORT rx_id; |
| } RRQ_MESSAGE; |
| |
| typedef struct { |
| ULONG command_code; |
| UCHAR vendor; |
| UCHAR explain; |
| UCHAR reason; |
| UCHAR reserved; |
| } REJECT_MESSAGE; |
| |
| |
| #define N_OR_F_PORT 0x1000 |
| #define RANDOM_RELATIVE_OFFSET 0x4000 |
| #define CONTINUOSLY_INCREASING 0x8000 |
| |
| #define CLASS_VALID 0x8000 |
| #define INTERMIX_MODE 0x4000 |
| #define TRANSPARENT_STACKED 0x2000 |
| #define LOCKDOWN_STACKED 0x1000 |
| #define SEQ_DELIVERY 0x800 |
| |
| #define XID_NOT_SUPPORTED 0x00 |
| #define XID_SUPPORTED 0x4000 |
| #define XID_REQUIRED 0xC000 |
| |
| #define ASSOCIATOR_NOT_SUPPORTED 0x00 |
| #define ASSOCIATOR_SUPPORTED 0x1000 |
| #define ASSOCIATOR_REQUIRED 0x3000 |
| |
| #define INIT_ACK0_SUPPORT 0x800 |
| #define INIT_ACKN_SUPPORT 0x400 |
| |
| #define RECIP_ACK0_SUPPORT 0x8000 |
| #define RECIP_ACKN_SUPPORT 0x4000 |
| |
| #define X_ID_INTERLOCK 0x2000 |
| |
| #define ERROR_POLICY 0x1800 // Error Policy Supported |
| #define ERROR_DISCARD 0x00 // Only Discard Supported |
| #define ERROR_DISC_PROCESS 0x02 // Discard and process supported |
| |
| #define NODE_ID 0x01 |
| #define IEEE_EXT 0x20 |
| |
| // |
| // Categories Supported Per Sequence |
| // |
| #define CATEGORIES_PER_SEQUENCE 0x300 |
| #define ONE_CATEGORY_SEQUENCE 0x00 // 1 Category per Sequence |
| #define TWO_CATEGORY_SEQUENCE 0x01 // 2 Categories per Sequence |
| #define MANY_CATEGORY_SEQUENCE 0x03 // > 2 Categories/Sequence |
| |
| typedef struct { |
| |
| USHORT initiator_control; |
| USHORT service_options; |
| |
| USHORT rx_data_size; |
| USHORT recipient_control; |
| |
| USHORT ee_credit; |
| USHORT concurrent_sequences; |
| |
| USHORT reserved; |
| USHORT open_sequences; |
| |
| } CLASS_PARAMETERS; |
| |
| typedef struct { |
| ULONG login_cmd; |
| // |
| // Common Service Parameters |
| // |
| struct { |
| |
| USHORT bb_credit; |
| UCHAR lowest_ver; |
| UCHAR highest_ver; |
| |
| USHORT bb_rx_size; |
| USHORT common_features; |
| |
| USHORT rel_offset; |
| USHORT concurrent_seq; |
| |
| |
| ULONG e_d_tov; |
| } cmn_services; |
| |
| // |
| // Port Name |
| // |
| UCHAR port_name[8]; |
| |
| // |
| // Node/Fabric Name |
| // |
| UCHAR node_name[8]; |
| |
| // |
| // Class 1, 2 and 3 Service Parameters |
| // |
| CLASS_PARAMETERS class1; |
| CLASS_PARAMETERS class2; |
| CLASS_PARAMETERS class3; |
| |
| ULONG reserved[4]; |
| |
| // |
| // Vendor Version Level |
| // |
| UCHAR vendor_id[2]; |
| UCHAR vendor_version[6]; |
| ULONG buffer_size; |
| USHORT rxid_start; |
| USHORT total_rxids; |
| } LOGIN_PAYLOAD; |
| |
| |
| typedef struct |
| { |
| ULONG cmd; // 4 bytes |
| UCHAR n_port_identifier[3]; |
| UCHAR reserved; |
| UCHAR port_name[8]; |
| } LOGOUT_PAYLOAD; |
| |
| |
| // |
| // PRLI Request Service Parameter Defines |
| // |
| #define PRLI_ACC 0x01 |
| #define PRLI_REQ 0x02 |
| #define ORIG_PROCESS_ASSOC_VALID 0x8000 |
| #define RESP_PROCESS_ASSOC_VALID 0x4000 |
| #define ESTABLISH_PAIR 0x2000 |
| #define DATA_OVERLAY_ALLOWED 0x40 |
| #define INITIATOR_FUNCTION 0x20 |
| #define TARGET_FUNCTION 0x10 |
| #define CMD_DATA_MIXED 0x08 |
| #define DATA_RESP_MIXED 0x04 |
| #define READ_XFER_RDY 0x02 |
| #define WRITE_XFER_RDY 0x01 |
| |
| #define RESPONSE_CODE_MASK 0xF00 |
| #define REQUEST_EXECUTED 0x100 |
| #define NO_RESOURCES 0x200 |
| #define INIT_NOT_COMPLETE 0x300 |
| #define IMAGE_DOES_NOT_EXIST 0x400 |
| #define BAD_PREDEFINED_COND 0x500 |
| #define REQ_EXEC_COND 0x600 |
| #define NO_MULTI_PAGE 0x700 |
| |
| typedef struct { |
| USHORT payload_length; |
| UCHAR page_length; |
| UCHAR cmd; |
| |
| |
| ULONG valid; |
| |
| ULONG orig_process_associator; |
| |
| ULONG resp_process_associator; |
| |
| ULONG fcp_info; |
| } PRLI_REQUEST; |
| |
| typedef struct { |
| |
| USHORT payload_length; |
| UCHAR page_length; |
| UCHAR cmd; |
| |
| ULONG valid; |
| ULONG orig_process_associator; |
| |
| ULONG resp_process_associator; |
| ULONG reserved; |
| } PRLO_REQUEST; |
| |
| typedef struct { |
| ULONG cmd; |
| |
| ULONG hard_address; |
| |
| UCHAR port_name[8]; |
| |
| UCHAR node_name[8]; |
| |
| ULONG s_id; |
| } ADISC_PAYLOAD; |
| |
| struct ext_sg_entry_t { |
| __u32 len:18; /* buffer length, bits 0-17 */ |
| __u32 uba:13; /* upper bus address bits 18-31 */ |
| __u32 lba; /* lower bus address bits 0-31 */ |
| }; |
| |
| |
| // J. McCarty's LINK.H |
| // |
| // LS_RJT Reason Codes |
| // |
| |
| #define INVALID_COMMAND_CODE 0x01 |
| #define LOGICAL_ERROR 0x03 |
| #define LOGICAL_BUSY 0x05 |
| #define PROTOCOL_ERROR 0x07 |
| #define UNABLE_TO_PERFORM 0x09 |
| #define COMMAND_NOT_SUPPORTED 0x0B |
| #define LS_VENDOR_UNIQUE 0xFF |
| |
| // |
| // LS_RJT Reason Codes Explanations |
| // |
| #define NO_REASON 0x00 |
| #define OPTIONS_ERROR 0x01 |
| #define INITIATOR_CTL_ERROR 0x03 |
| #define RECIPIENT_CTL_ERROR 0x05 |
| #define DATA_FIELD_SIZE_ERROR 0x07 |
| #define CONCURRENT_SEQ_ERROR 0x09 |
| #define CREDIT_ERROR 0x0B |
| #define INVALID_PORT_NAME 0x0D |
| #define INVALID_NODE_NAME 0x0E |
| #define INVALID_CSP 0x0F // Invalid Service Parameters |
| #define INVALID_ASSOC_HDR 0x11 // Invalid Association Header |
| #define ASSOC_HDR_REQUIRED 0x13 // Association Header Required |
| #define LS_INVALID_S_ID 0x15 |
| #define INVALID_OX_RX_ID 0x17 // Invalid OX_ID RX_ID Combination |
| #define CMD_IN_PROCESS 0x19 |
| #define INVALID_IDENTIFIER 0x1F // Invalid N_PORT Identifier |
| #define INVALID_SEQ_ID 0x21 |
| #define ABT_INVALID_XCHNG 0x23 // Attempt to Abort an invalid Exchange |
| #define ABT_INACTIVE_XCHNG 0x25 // Attempt to Abort an inactive Exchange |
| #define NEED_REC_QUAL 0x27 // Recovery Qualifier required |
| #define NO_LOGIN_RESOURCES 0x29 // No resources to support login |
| #define NO_DATA 0x2A // Unable to supply requested data |
| #define REQUEST_NOT_SUPPORTED 0x2C // Request Not Supported |
| |
| // |
| // Link Control Codes |
| // |
| |
| // |
| // P_BSY Action Codes |
| // |
| #define SEQUENCE_TERMINATED 0x01000000 |
| #define SEQUENCE_ACTIVE 0x02000000 |
| |
| // |
| // P_BSY Reason Codes |
| // |
| #define PHYS_NPORT_BUSY 0x010000 |
| #define NPORT_RESOURCE_BUSY 0x020000 |
| |
| // |
| // P_RJT, F_RJT Action Codes |
| // |
| |
| #define RETRYABLE_ERROR 0x01000000 |
| #define NON_RETRYABLE_ERROR 0x02000000 |
| |
| // |
| // P_RJT, F_RJT Reason Codes |
| // |
| #define INVALID_D_ID 0x010000 |
| #define INVALID_S_ID 0x020000 |
| #define NPORT_NOT_AVAIL_TMP 0x030000 |
| #define NPORT_NOT_AVAIL_PERM 0x040000 |
| #define CLASS_NOT_SUPPORTED 0x050000 |
| #define USAGE_ERROR 0x060000 |
| #define TYPE_NOT_SUPPORTED 0x070000 |
| #define INVAL_LINK_CONTROL 0x080000 |
| #define INVAL_R_CTL 0x090000 |
| #define INVAL_F_CTL 0x0A0000 |
| #define INVAL_OX_ID 0x0B0000 |
| #define INVAL_RX_ID 0x0C0000 |
| #define INVAL_SEQ_ID 0x0D0000 |
| #define INVAL_DF_CTL 0x0E0000 |
| #define INVAL_SEQ_CNT 0x0F0000 |
| #define INVAL_PARAMS 0x100000 |
| #define EXCHANGE_ERROR 0x110000 |
| #define LS_PROTOCOL_ERROR 0x120000 |
| #define INCORRECT_LENGTH 0x130000 |
| #define UNEXPECTED_ACK 0x140000 |
| #define LOGIN_REQ 0x160000 |
| #define EXCESSIVE_SEQ 0x170000 |
| #define NO_EXCHANGE 0x180000 |
| #define SEC_HDR_NOT_SUPPORTED 0x190000 |
| #define NO_FABRIC 0x1A0000 |
| #define P_VENDOR_UNIQUE 0xFF0000 |
| |
| // |
| // BA_RJT Reason Codes |
| // |
| #define BA_INVALID_COMMAND 0x00010000 |
| #define BA_LOGICAL_ERROR 0x00030000 |
| #define BA_LOGICAL_BUSY 0x00050000 |
| #define BA_PROTOCOL_ERROR 0x00070000 |
| #define BA_UNABLE_TO_PERFORM 0x00090000 |
| |
| // |
| // BA_RJT Reason Explanation Codes |
| // |
| #define BA_NO_REASON 0x00000000 |
| #define BA_INVALID_OX_RX 0x00000300 |
| #define BA_SEQUENCE_ABORTED 0x00000500 |
| |
| |
| |
| #endif /* CPQFCTSSTRUCTS_H */ |
| |