|  | /* 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	*/ | 
|  |  |