patch-2.2.18 linux/drivers/scsi/cpqfcTSstructs.h

Next file: linux/drivers/scsi/cpqfcTStrigger.c
Previous file: linux/drivers/scsi/cpqfcTSioctl.h
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/drivers/scsi/cpqfcTSstructs.h linux/drivers/scsi/cpqfcTSstructs.h
@@ -0,0 +1,1497 @@
+/* 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/tqueue.h> // task queue sched
+#include <asm/atomic.h>
+#include "cpqfcTSioctl.h"
+
+#define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \
+                         for( wait_time=jiffies + (secs*HZ); \
+		         wait_time > jiffies ;) ; }
+#define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
+#define VER_MAJOR 1
+#define VER_MINOR 3
+#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
+#define CPQFCTS_MAX_LUN 8    // 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
+
+#ifndef LinuxVersionCode
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#endif
+#ifndef DECLARE_MUTEX_LOCKED
+#define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED
+#endif
+
+#define DEV_NAME "cpqfcTS"
+
+#define CPQ_DEVICE_ID     0xA0FC
+#define AGILENT_XL2_ID    0x1029
+
+typedef struct
+{
+  __u16 vendor_id;
+  __u16 device_id;
+} SupportedPCIcards;
+			 
+// nn:nn denotes bit field
+                            // TachyonHeader struct def.
+                            // the fields shared with ODB
+                            // need to have same value
+
+// 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
+
+
+#ifndef HOSTS_C
+
+#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 REPORT_LUNS 0xA0 // SCSI-3 command op-code
+
+#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;
+
+
+
+// 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;
+
+
+#define TL_MAX_SGPAGES 4  // arbitrary limit to # of TL Ext. S/G pages
+                          // stores array of allocated page blocks used
+                          // in extended S/G lists.  Affects amount of static
+                          // memory consumed by 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;
+  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
+{
+  void *PoolPage[TL_MAX_SGPAGES];
+} SGPAGES, *PSGPAGES; // 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
+  SGPAGES sgPages[TACH_SEST_LEN]; // array of Pool-allocations
+  ULONG length;          // Length register
+  ULONG base;            // copy of base ptr for debug
+} TachSEST;
+
+
+
+typedef struct                  // each register has it's own address
+                                // and value (used for write-only regs)
+{
+  void* address;
+  volatile ULONG value;
+} FCREGISTER;
+
+typedef struct         // Host copy - TachLite Registers
+{
+  ULONG IOBaseL, IOBaseU;  // I/O port lower and upper TL register addresses
+  ULONG MemBase;           // memory mapped register addresses
+  void* ReMapMemBase;      // O/S VM reference for MemBase
+  ULONG wwn_hi;            // WWN is set once at startup
+  ULONG wwn_lo;
+  ULONG my_al_pa;          // al_pa received after LIP()
+  ULONG ROMCTR;            // flags for on-board RAM/ROM
+  ULONG RAMBase;           // on-board RAM (i.e. some Tachlites)
+  ULONG SROMBase;          // on-board EEPROM (some Tachlites)
+  ULONG PCIMCTR;           // PCI Master Control Reg (has bus width)
+
+  FCREGISTER INTEN;        // copy of interrupt enable mask
+  FCREGISTER INTPEND;      // interrupt pending
+  FCREGISTER INTSTAT;      // interrupt status
+  FCREGISTER SFQconsumerIndex; 
+  FCREGISTER ERQproducerIndex; 
+  FCREGISTER TYconfig;   // TachYon (chip level)
+  FCREGISTER TYcontrol;
+  FCREGISTER TYstatus;
+  FCREGISTER FMconfig;   // Frame Manager (FC loop level)
+  FCREGISTER FMcontrol;
+  FCREGISTER FMstatus;
+  FCREGISTER FMLinkStatus1;
+  FCREGISTER FMLinkStatus2;
+  FCREGISTER FMBB_CreditZero;
+  FCREGISTER status;
+  FCREGISTER ed_tov;     // error detect time-out value
+  FCREGISTER rcv_al_pa;  // received arb. loop physical address
+  FCREGISTER primitive;  // e.g. LIP(), OPN(), ...
+} TL_REGISTERS;
+
+
+
+typedef struct 
+{
+  ULONG ok;
+  ULONG invalidArgs;
+  ULONG linkDown;
+  ULONG linkUp;
+  ULONG outQueFull;
+  ULONG SESTFull;
+  ULONG hpe;    // host programming err (from Tach)
+  ULONG FC4aborted; // aborts from Application or upper driver layer
+  ULONG FC2aborted; // aborts from our driver's timeouts
+  ULONG timeouts;   // our driver timeout (on individual exchanges)
+  ULONG logouts;    // explicit - sent LOGO; implicit - device removed
+  ULONG retries;
+  ULONG linkFailTX;
+  ULONG linkFailRX;
+  ULONG CntErrors;  // byte count expected != count received (typ. SEST)
+  ULONG e_stores;   // elastic store errs
+  ULONG resets;     // hard or soft controller resets
+  ULONG FMinits;    // TACH Frame Manager Init (e.g. LIPs)
+  ULONG lnkQueFull;  // too many LOGIN, loop commands
+  ULONG ScsiQueFull; // too many FCP-SCSI inbound frames
+  ULONG LossofSignal;   // FM link status 1 regs
+  ULONG BadRXChar;   // FM link status 1 regs
+  ULONG LossofSync;   // FM link status 1 regs
+  ULONG Rx_EOFa;   // FM link status 2 regs (received EOFa)
+  ULONG Dis_Frm;   // FM link status 2 regs (discarded frames)
+  ULONG Bad_CRC;   // FM link status 2 regs
+  ULONG BB0_Timer; //  FM BB_Credit Zero Timer Reg
+  ULONG loopBreaks; // infinite loop exits
+  ULONG lastBB0timer;  // static accum. buffer needed by Tachlite
+} FCSTATS;
+
+
+typedef struct               // Config Options
+{                            // LS Bit first
+  USHORT        : 1;           // bit0:
+  USHORT  flogi : 1;           // bit1: We sent FLOGI - wait for Fabric logins
+  USHORT  fabric: 1;           // bit2: Tachyon detected Fabric (FM stat LG)
+  USHORT  LILPin: 1;           // bit3: We can use an FC-AL LILP frame
+  USHORT  target: 1;           // bit4: this Port has SCSI target capability
+  USHORT  initiator:    1;     // bit5: this Port has SCSI initiator capability
+  USHORT  extLoopback:  1;     // bit6: loopback at GBIC
+  USHORT  intLoopback:  1;     // bit7: loopback in HP silicon
+  USHORT        : 1;           // bit8:
+  USHORT        : 1;           // bit9:
+  USHORT        : 1;           // bit10:
+  USHORT        : 1;           // bit11:
+  USHORT        : 1;           // bit12:
+  USHORT        : 1;           // bit13:
+  USHORT        : 1;           // bit14:
+  USHORT        : 1;           // bit15:
+} FC_OPTIONS;
+
+
+
+typedef struct dyn_mem_pair
+{
+  void *BaseAllocated;  // address as allocated from O/S;
+  unsigned long AlignedAddress; // aligned address (used by Tachyon DMA)
+} ALIGNED_MEM;
+
+
+
+
+// these structs contain only CRUCIAL (stuff we actually use) parameters
+// from FC-PH(n) logins.  (Don't save entire LOGIN payload to save mem.)
+
+// Implicit logout happens when the loop goes down - we require PDISC
+// to restore.  Explicit logout is when WE decide never to talk to someone,
+// or when a target refuses to talk to us, i.e. sends us a LOGO frame or
+// LS_RJT reject in response to our PLOGI request.
+
+#define IMPLICIT_LOGOUT 1
+#define EXPLICIT_LOGOUT 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)
+
+  Scsi_Cmnd ScsiCmnd;   // command buffer for Report Luns
+#define REPORT_LUNS_PL 256  
+  UCHAR ReportLunsPayload[REPORT_LUNS_PL];
+  
+  SCSI_NEXUS ScsiNexus; // LUNs per FC device
+
+  ULONG LOGO_counter; // might try several times before logging out for good
+  ULONG LOGO_timer;   // after LIP, ports expecting PDISC must time-out and
+                      // LOGOut if successful PDISC not completed in 2 secs
+
+  ULONG concurrent_seq;  // must be 1 or greater
+  ULONG rx_data_size;    // e.g. 128, 256, 1024, 2048 per FC-PH spec
+  ULONG BB_credit;
+  ULONG EE_credit;
+
+  ULONG fcp_info;        // from PRLI (i.e. INITIATOR/ TARGET flags)
+                         // flags for login process
+  BOOLEAN Originator;    // Login sequence Originated (if false, we
+                         // responded to another port's login sequence)
+  BOOLEAN plogi;         // PLOGI frame ACCepted (originated or responded)
+  BOOLEAN pdisc;         // PDISC frame was ORIGINATED (self-login logic)
+  BOOLEAN prli;          // PRLI frame ACCepted (originated or responded)
+  BOOLEAN flogi;         // FLOGI frame ACCepted (originated or responded)
+  BOOLEAN logo;          // port permanently logged out (invalid login param)
+  BOOLEAN flogiReq;      // Fabric login required (set in LIP process)
+  UCHAR highest_ver;
+  UCHAR lowest_ver;
+
+  
+  // when the "target" (actually FC Port) is waiting for login
+  // (e.g. after Link reset), set the device_blocked bit;
+  // after Port completes login, un-block target.
+  UCHAR device_blocked; // see Scsi_Device struct
+
+                    // define singly-linked list of logged-in ports
+                    // once a port_id is identified, it is remembered,
+                    // even if the port is removed indefinitely
+  PVOID pNextPort;  // actually, type PFC_LOGGEDIN_PORT; void for Compiler
+
+} FC_LOGGEDIN_PORT, *PFC_LOGGEDIN_PORT;
+
+
+
+// This serves as the ESB (Exchange Status Block),
+// and has timeout counter; used for 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
+
+  // these function pointers are for "generic" functions, which are
+  // replaced with Host Bus Adapter types at
+  // runtime.
+  int (*CreateTachyonQues)( void* , int);
+  int (*DestroyTachyonQues)( void* , int);
+  int (*LaserControl)(void*, int );   // e.g. On/Off
+  int (*ResetTachyon)(void*, int );
+  void (*FreezeTachyon)(void*, int );
+  void (*UnFreezeTachyon)(void*, int );
+  int (*InitializeTachyon)(void*, int, int );
+  int (*InitializeFrameManager)(void*, int );
+  int (*ProcessIMQEntry)(void*);
+  int (*ReadWriteWWN)(void*, int ReadWrite);
+  int (*ReadWriteNVRAM)(void*, void*, int ReadWrite);
+
+} TACHYON, *PTACHYON;
+
+
+void cpqfcTSClearLinkStatusCounters(TACHYON * fcChip);
+
+int CpqTsCreateTachLiteQues( void* pHBA, int opcode);
+int CpqTsDestroyTachLiteQues( void* , int);
+int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2);
+
+int CpqTsProcessIMQEntry(void* pHBA);
+int CpqTsResetTachLite(void *pHBA, int type);
+void CpqTsFreezeTachlite(void *pHBA, int type);
+void CpqTsUnFreezeTachlite(void *pHBA, int type);
+int CpqTsInitializeFrameManager(void *pHBA, int);
+int CpqTsLaserControl( void* addrBase, int opcode );
+int CpqTsReadWriteWWN(void*, int ReadWrite);
+int CpqTsReadWriteNVRAM(void*, void* data, int ReadWrite);
+
+void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter);
+void cpqfcTSWorkerThread( void *host);
+
+int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf );
+ULONG cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count,
+	UCHAR *buf );
+
+BOOLEAN tl_write_i2c_nvram( void* GPIOin, void* GPIOout,
+  USHORT startOffset,  // e.g. 0x2f for WWN start
+  USHORT count,
+  UCHAR *buf );
+
+
+// define misc functions 
+int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]);
+int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]);
+void* fcMemManager( ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab,
+                   ULONG ulAlignedAddress);
+
+void BigEndianSwap(  UCHAR *source, UCHAR *dest,  USHORT cnt);
+
+//ULONG virt_to_phys( PVOID virtaddr );
+                  
+
+// Linux interrupt handler
+void 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;
+
+
+
+
+
+#define DYNAMIC_ALLOCATIONS 4  // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST
+
+// Linux space allocated per HBA (chip state, etc.)
+typedef struct 
+{
+  struct Scsi_Host *HostAdapter; // back pointer to Linux Scsi struct
+
+  TACHYON fcChip;    // All Tachyon registers, Queues, functions
+  ALIGNED_MEM dynamic_mem[DYNAMIC_ALLOCATIONS];
+
+  struct pci_dev *PciDev;
+
+  Scsi_Cmnd *LinkDnCmnd[CPQFCTS_REQ_QUEUE_LEN]; // collects Cmnds during LDn
+                                                // (for Acceptable targets)
+  Scsi_Cmnd *BoardLockCmnd[CPQFCTS_REQ_QUEUE_LEN]; // SEST was full
+  
+  Scsi_Cmnd *BadTargetCmnd[CPQFCTS_MAX_TARGET_ID]; // missing targets
+
+  u_char HBAnum;     // 0-based host number
+
+
+  struct timer_list cpqfcTStimer; // FC utility timer for implicit
+                                  // logouts, FC protocol timeouts, etc.
+  int fcStatsTime;  // Statistics delta reporting time
+
+  struct task_struct *worker_thread; // our kernel thread
+  int PortDiscDone;    // set by SendLogins(), cleared by LDn
+  
+  struct semaphore *TachFrozen;
+  struct semaphore *TYOBcomplete;    // handshake for Tach outbound frames
+  struct semaphore *fcQueReady;      // FibreChannel work for our kernel thread
+  struct semaphore *notify_wt;       // synchronizes kernel thread kill
+  struct semaphore *BoardLock;
+  
+  PFC_LINK_QUE fcLQ;             // the WorkerThread operates on this
+
+  spinlock_t hba_spinlock;           // held/released by WorkerThread
+
+} CPQFCHBA;
+
+#define	CPQ_SPINLOCK_HBA( x )   spin_lock(&x->hba_spinlock);
+#define CPQ_SPINUNLOCK_HBA(x)   spin_unlock(&x->hba_spinlock);
+
+
+
+void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata,
+		PFC_LOGGEDIN_PORT pFcPort);
+
+
+void cpqfcTSTerminateExchange( CPQFCHBA*, SCSI_NEXUS *target, int );
+
+PFC_LOGGEDIN_PORT fcPortLoggedIn( 
+   CPQFCHBA *cpqfcHBAdata, 
+   TachFCHDR_GCMND* fchs, 
+   BOOLEAN, 
+   BOOLEAN);
+void fcProcessLoggedIn( 
+   CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs);
+
+
+ULONG cpqfcTSBuildExchange( 
+  CPQFCHBA *cpqfcHBAdata,
+  ULONG type, // e.g. PLOGI
+  TachFCHDR_GCMND* InFCHS,  // incoming FCHS
+  void *Data,               // the CDB, scatter/gather, etc.  
+  LONG *ExchangeID );       // allocated exchange ID
+
+ULONG cpqfcTSStartExchange( 
+  CPQFCHBA *cpqfcHBAdata,
+  LONG ExchangeID );
+
+void cpqfcTSCompleteExchange( 
+       PTACHYON fcChip, 
+       ULONG exchange_ID);
+
+
+PFC_LOGGEDIN_PORT  fcFindLoggedInPort( 
+  PTACHYON fcChip, 
+  Scsi_Cmnd *Cmnd,  // (We want the channel/target/lun Nexus from Cmnd)
+  ULONG port_id,  // search linked list for al_pa, or
+  UCHAR wwn[8],    // search linked list for WWN, or...
+  PFC_LOGGEDIN_PORT *pLastLoggedInPort
+);
+
+// don't do this unless you have the right hardware!
+#define TRIGGERABLE_HBA 1
+#ifdef TRIGGERABLE_HBA
+void TriggerHBA( void*, int);
+#endif
+
+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 *);
+
+
+
+
+
+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;
+
+// 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
+#endif /* CPQFCTSSTRUCTS_H	*/
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)