| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* Copyright(c) 2000, Compaq Computer Corporation | 
|  | 2 | * Fibre Channel Host Bus Adapter 64-bit, 66MHz PCI | 
|  | 3 | * Originally developed and tested on: | 
|  | 4 | * (front): [chip] Tachyon TS HPFC-5166A/1.2  L2C1090 ... | 
|  | 5 | *          SP# P225CXCBFIEL6T, Rev XC | 
|  | 6 | *          SP# 161290-001, Rev XD | 
|  | 7 | * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5 | 
|  | 8 | * | 
|  | 9 | * This program is free software; you can redistribute it and/or modify it | 
|  | 10 | * under the terms of the GNU General Public License as published by the | 
|  | 11 | * Free Software Foundation; either version 2, or (at your option) any | 
|  | 12 | * later version. | 
|  | 13 | * | 
|  | 14 | * This program is distributed in the hope that it will be useful, but | 
|  | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | 17 | * General Public License for more details. | 
|  | 18 | * Written by Don Zimmerman | 
|  | 19 | */ | 
|  | 20 | #ifndef CPQFCTSSTRUCTS_H | 
|  | 21 | #define CPQFCTSSTRUCTS_H | 
|  | 22 |  | 
|  | 23 | #include <linux/timer.h>  // timer declaration in our host data | 
|  | 24 | #include <linux/interrupt.h> | 
|  | 25 | #include <asm/atomic.h> | 
|  | 26 | #include "cpqfcTSioctl.h" | 
|  | 27 |  | 
|  | 28 | #define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \ | 
|  | 29 | for( wait_time=jiffies + (secs*HZ); \ | 
|  | 30 | time_before(jiffies, wait_time) ;) ; } | 
|  | 31 |  | 
|  | 32 | #define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 
|  | 33 | // don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c | 
|  | 34 | #define VER_MAJOR 2 | 
|  | 35 | #define VER_MINOR 5 | 
|  | 36 | #define VER_SUBMINOR 4 | 
|  | 37 |  | 
|  | 38 | // Macros for kernel (esp. SMP) tracing using a PCI analyzer | 
|  | 39 | // (e.g. x86). | 
|  | 40 | //#define PCI_KERNEL_TRACE | 
|  | 41 | #ifdef PCI_KERNEL_TRACE | 
|  | 42 | #define PCI_TRACE(x) inl( fcChip->Registers.IOBaseL +x); | 
|  | 43 | #define PCI_TRACEO(x,y) outl( x, (fcChip->Registers.IOBaseL +y)); | 
|  | 44 | #else | 
|  | 45 |  | 
|  | 46 | #define PCI_TRACE(x) | 
|  | 47 | #define PCI_TRACEO(x,y) | 
|  | 48 | #endif | 
|  | 49 |  | 
|  | 50 |  | 
|  | 51 | //#define DEBUG_CMND 1   // debug output for Linux Scsi CDBs | 
|  | 52 | //#define DUMMYCMND_DBG 1 | 
|  | 53 |  | 
|  | 54 | //#define DEBUG_CPQFCTS 1 | 
|  | 55 | //#undef DEBUG_CPQFCTS | 
|  | 56 | #ifdef DEBUG_CPQFCTS | 
|  | 57 | #define ENTER(x)	printk("cpqfcts : entering %s()\n", x); | 
|  | 58 | #define LEAVE(x)	printk("cpqfcts : leaving %s()\n", x); | 
|  | 59 | #define DEBUG(x)	x | 
|  | 60 | #else | 
|  | 61 | #define ENTER(x) | 
|  | 62 | #define LEAVE(x) | 
|  | 63 | #define DEBUG(x) | 
|  | 64 | #endif				/* DEBUG_CPQFCTS */ | 
|  | 65 |  | 
|  | 66 | //#define DEBUG_CPQFCTS_PCI 1 | 
|  | 67 | //#undef DEBUG_CPQFCTS_PCI | 
|  | 68 | #if DEBUG_CPQFCTS_PCI | 
|  | 69 | #define DEBUG_PCI(x)	x | 
|  | 70 | #else | 
|  | 71 | #define DEBUG_PCI(x) | 
|  | 72 | #endif				/* DEBUG_CPQFCTS_PCI */ | 
|  | 73 |  | 
|  | 74 | #define STACHLITE66_TS12  "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2" | 
|  | 75 | #define STACHLITE66_TS13  "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.3" | 
|  | 76 | #define STACHLITE_UNKNOWN "Compaq FibreChannel HBA Tachyon Chip/Board Ver??" | 
|  | 77 | #define SAGILENT_XL2_21   "Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.1" | 
|  | 78 |  | 
|  | 79 | // PDA is Peripheral Device Address, VSA is Volume Set Addressing | 
|  | 80 | // Linux SCSI parameters | 
|  | 81 | #define CPQFCTS_MAX_TARGET_ID 64 | 
|  | 82 |  | 
|  | 83 | // Note, changing CPQFCTS_MAX_LUN to less than 32 (e.g, 8) will result in | 
|  | 84 | // strange behavior if a box with more than, e.g. 8, is on the loop. | 
|  | 85 | #define CPQFCTS_MAX_LUN 32    // The RA-4x00 supports 32 (Linux SCSI supports 8) | 
|  | 86 | #define CPQFCTS_MAX_CHANNEL 0 // One FC port on cpqfcTS HBA | 
|  | 87 |  | 
|  | 88 | #define CPQFCTS_CMD_PER_LUN 15 // power of 2 -1, must be >0 | 
|  | 89 | #define CPQFCTS_REQ_QUEUE_LEN (TACH_SEST_LEN/2) // must be < TACH_SEST_LEN | 
|  | 90 |  | 
|  | 91 | #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) | 
|  | 92 | #ifndef DECLARE_MUTEX_LOCKED | 
|  | 93 | #define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED | 
|  | 94 | #endif | 
|  | 95 |  | 
|  | 96 | #define DEV_NAME "cpqfcTS" | 
|  | 97 |  | 
|  | 98 | struct SupportedPCIcards | 
|  | 99 | { | 
|  | 100 | __u16 vendor_id; | 
|  | 101 | __u16 device_id; | 
|  | 102 | }; | 
|  | 103 |  | 
|  | 104 | // nn:nn denotes bit field | 
|  | 105 | // TachyonHeader struct def. | 
|  | 106 | // the fields shared with ODB | 
|  | 107 | // need to have same value | 
|  | 108 |  | 
|  | 109 |  | 
|  | 110 |  | 
|  | 111 |  | 
|  | 112 | #ifndef BYTE | 
|  | 113 | //typedef UCHAR BYTE; | 
|  | 114 | typedef __u8 BYTE; | 
|  | 115 | #endif | 
|  | 116 | #ifndef UCHAR | 
|  | 117 | typedef __u8 UCHAR; | 
|  | 118 | #endif | 
|  | 119 | #ifndef LONG | 
|  | 120 | typedef __s32 LONG; | 
|  | 121 | #endif | 
|  | 122 | #ifndef ULONG | 
|  | 123 | typedef __u32 ULONG; | 
|  | 124 | #endif | 
|  | 125 | #ifndef PVOID | 
|  | 126 | typedef void * PVOID; | 
|  | 127 | #endif | 
|  | 128 | #ifndef USHORT | 
|  | 129 | typedef __u16 USHORT; | 
|  | 130 | #endif | 
|  | 131 | #ifndef BOOLEAN | 
|  | 132 | typedef __u8 BOOLEAN; | 
|  | 133 | #endif | 
|  | 134 |  | 
|  | 135 |  | 
|  | 136 | // macro for FC-PH reject codes | 
|  | 137 | // payload format for LS_RJT (FC payloads are big endian): | 
|  | 138 | //     byte  0         1         2         3  (MSB) | 
|  | 139 | // DWORD 0   01        00        00        00 | 
|  | 140 | // DWORD 1   resvd     code      expl.     vendor | 
|  | 141 |  | 
|  | 142 | #define LS_RJT_REASON( code, expl) (( code<<8) | (expl <<16)) | 
|  | 143 |  | 
|  | 144 |  | 
|  | 145 | #define TachLiteSTATUS 0x12 | 
|  | 146 |  | 
|  | 147 | // Fibre Channel EXCHANGE status codes for Tachyon chips/ driver software | 
|  | 148 | // 32-bit ERROR word defines | 
|  | 149 | #define INVALID_ARGS 0x1 | 
|  | 150 | #define LNKDWN_OSLS  0x2 | 
|  | 151 | #define LNKDWN_LASER 0x4 | 
|  | 152 | #define OUTQUE_FULL  0x8 | 
|  | 153 | #define DRIVERQ_FULL 0x10 | 
|  | 154 | #define SEST_FULL    0x20 | 
|  | 155 | #define BAD_ALPA     0x40 | 
|  | 156 | #define OVERFLOW     0x80  // inbound CM | 
|  | 157 | #define COUNT_ERROR     0x100  // inbound CM | 
|  | 158 | #define LINKFAIL_RX     0x200  // inbound CM | 
|  | 159 | #define ABORTSEQ_NOTIFY 0x400  // outbound CM | 
|  | 160 | #define LINKFAIL_TX     0x800  // outbound CM | 
|  | 161 | #define HOSTPROG_ERR     0x1000  // outbound CM | 
|  | 162 | #define FRAME_TO         0x2000  // outbound CM | 
|  | 163 | #define INV_ENTRY        0x4000  // outbound CM | 
|  | 164 | #define SESTPROG_ERR     0x8000  // outbound CM | 
|  | 165 | #define OUTBOUND_TIMEOUT 0x10000L // timeout waiting for Tachyon outbound CM | 
|  | 166 | #define INITIATOR_ABORT  0x20000L // initiator exchange timeout or O/S ABORT | 
|  | 167 | #define MEMPOOL_FAIL     0x40000L // O/S memory pool allocation failed | 
|  | 168 | #define FC2_TIMEOUT      0x80000L // driver timeout for lost frames | 
|  | 169 | #define TARGET_ABORT     0x100000L // ABTS received from FC port | 
|  | 170 | #define EXCHANGE_QUEUED  0x200000L // e.g. Link State was LDn on fcStart | 
|  | 171 | #define PORTID_CHANGED   0x400000L // fc Port address changed | 
|  | 172 | #define DEVICE_REMOVED   0x800000L // fc Port address changed | 
|  | 173 | // Several error scenarios result in SEST Exchange frames | 
|  | 174 | // unexpectedly arriving in the SFQ | 
|  | 175 | #define SFQ_FRAME        0x1000000L // SFQ frames from open Exchange | 
|  | 176 |  | 
|  | 177 | // Maximum number of Host Bus Adapters (HBA) / controllers supported | 
|  | 178 | // only important for mem allocation dimensions - increase as necessary | 
|  | 179 |  | 
|  | 180 | #define MAX_ADAPTERS 8 | 
|  | 181 | #define MAX_RX_PAYLOAD 1024  // hardware dependent max frame payload | 
|  | 182 | // Tach header struc defines | 
|  | 183 | #define SOFi3 0x7 | 
|  | 184 | #define SOFf  0x8 | 
|  | 185 | #define SOFn3 0xB | 
|  | 186 | #define EOFn  0x5 | 
|  | 187 | #define EOFt  0x6 | 
|  | 188 |  | 
|  | 189 | // FCP R_CTL defines | 
|  | 190 | #define FCP_CMND 0x6 | 
|  | 191 | #define FCP_XFER_RDY 0x5 | 
|  | 192 | #define FCP_RSP 0x7 | 
|  | 193 | #define FCP_RESPONSE 0x777 // (arbitrary #) | 
|  | 194 | #define NEED_FCP_RSP 0x77  // (arbitrary #) | 
|  | 195 | #define FCP_DATA 0x1 | 
|  | 196 |  | 
|  | 197 | #define RESET_TACH 0x100 // Reset Tachyon/TachLite | 
|  | 198 | #define SCSI_IWE 0x2000  // initiator write entry (for SEST) | 
|  | 199 | #define SCSI_IRE 0x3000  // initiator read entry (for SEST) | 
|  | 200 | #define SCSI_TRE 0x400  // target read entry (for SEST) | 
|  | 201 | #define SCSI_TWE 0x500  // target write entry (for SEST) | 
|  | 202 | #define TOGGLE_LASER 0x800 | 
|  | 203 | #define LIP 0x900 | 
|  | 204 | #define CLEAR_FCPORTS 99 // (arbitrary #) free mem for Logged in ports | 
|  | 205 | #define FMINIT 0x707     // (arbitrary) for Frame Manager Init command | 
|  | 206 |  | 
|  | 207 | // BLS == Basic Link Service | 
|  | 208 | // ELS == Extended Link Service | 
|  | 209 | #define BLS_NOP 4 | 
|  | 210 | #define BLS_ABTS 0x10   // FC-PH Basic Link Service Abort Sequence | 
|  | 211 | #define BLS_ABTS_ACC 0x100  // FC-PH Basic Link Service Abort Sequence Accept | 
|  | 212 | #define BLS_ABTS_RJT 0x101  // FC-PH Basic Link Service Abort Sequence Reject | 
|  | 213 | #define ELS_PLOGI 0x03  // FC-PH Port Login (arbitrary assign) | 
|  | 214 | #define ELS_SCR   0x70  // (arb assign) State Change Registration (Fabric) | 
|  | 215 | #define FCS_NSR   0x72  // (arb assign) Name Service Request (Fabric) | 
|  | 216 | #define ELS_FLOGI 0x44  // (arb assign) Fabric Login | 
|  | 217 | #define ELS_FDISC 0x41  // (arb assign) Fabric Discovery (Login) | 
|  | 218 | #define ELS_PDISC 0x50  // FC-PH2 Port Discovery | 
|  | 219 | #define ELS_ABTX  0x06  // FC-PH Abort Exchange | 
|  | 220 | #define ELS_LOGO 0x05   // FC-PH Port Logout | 
|  | 221 | #define ELS_PRLI 0x20   // FCP-SCSI Process Login | 
|  | 222 | #define ELS_PRLO 0x21   // FCP-SCSI Process Logout | 
|  | 223 | #define ELS_LOGO_ACC 0x07   // {FC-PH} Port Logout Accept | 
|  | 224 | #define ELS_PLOGI_ACC 0x08  // {FC-PH} Port Login Accept | 
|  | 225 | #define ELS_ACC 0x18        // {FC-PH} (generic) ACCept | 
|  | 226 | #define ELS_PRLI_ACC 0x22  // {FCP-SCSI} Process Login Accept | 
|  | 227 | #define ELS_RJT 0x1000000 | 
|  | 228 | #define SCSI_REPORT_LUNS 0x0A0 | 
|  | 229 | #define FCP_TARGET_RESET 0x200 | 
|  | 230 |  | 
|  | 231 | #define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame | 
|  | 232 |  | 
|  | 233 | #define SFQ_UNASSISTED_FCP  1  // ICM, DWord3, "Type" unassisted FCP | 
|  | 234 | #define SFQ_UNKNOWN         0x31 // (arbitrary) ICM, DWord3, "Type" unknown | 
|  | 235 |  | 
|  | 236 | // these "LINK" bits refer to loop or non-loop | 
|  | 237 | #define LINKACTIVE 0x2    // fcLinkQ type - LINK UP Tachyon FM 'Lup' bit set | 
|  | 238 | #define LINKDOWN 0xf2     // fcLinkQ type - LINK DOWN Tachyon FM 'Ldn' bit set | 
|  | 239 |  | 
|  | 240 | //#define VOLUME_SET_ADDRESSING 1 // "channel" or "bus" 1 | 
|  | 241 |  | 
|  | 242 | typedef struct      // 32 bytes hdr ONLY (e.g. FCP_DATA buffer for SEST) | 
|  | 243 | { | 
|  | 244 | ULONG reserved;   // dword 0 (don't use) | 
|  | 245 | ULONG sof_eof; | 
|  | 246 | ULONG d_id;       // dword 2 - 31:24 R_CTL, 23:0 D_ID | 
|  | 247 | ULONG s_id;       // dword 3 - 31:24 CS_CTL, 23:0 S_ID | 
|  | 248 | ULONG f_ctl;      // dword 4 - 31:24 Type,  23:0 F_CTL | 
|  | 249 | ULONG seq_cnt;    // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT | 
|  | 250 | ULONG ox_rx_id;   // dword 6 - 31:16 OX_ID,  15:0 RX_ID | 
|  | 251 | ULONG ro;         // dword 7 - relative offset | 
|  | 252 | } TachFCHDR; | 
|  | 253 |  | 
|  | 254 | // NOTE!! the following struct MUST be 64 bytes. | 
|  | 255 | typedef struct      // 32 bytes hdr + 32 bytes payload | 
|  | 256 | { | 
|  | 257 | ULONG reserved;   // dword 0 (don't use - must clear to 0) | 
|  | 258 | ULONG sof_eof;    // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp | 
|  | 259 | ULONG d_id;       // dword 2 - 31:24 R_CTL, 23:0 D_ID | 
|  | 260 | ULONG s_id;       // dword 3 - 31:24 CS_CTL, 23:0 S_ID | 
|  | 261 | ULONG f_ctl;      // dword 4 - 31:24 Type,  23:0 F_CTL | 
|  | 262 | ULONG seq_cnt;    // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT | 
|  | 263 | ULONG ox_rx_id;   // dword 6 - 31:16 OX_ID,  15:0 RX_ID | 
|  | 264 | ULONG ro;  // dword 7 - relative offset | 
|  | 265 | //--------- | 
|  | 266 | __u32 pl[8];              // dwords 8-15 frame data payload | 
|  | 267 | } TachFCHDR_CMND; | 
|  | 268 |  | 
|  | 269 |  | 
|  | 270 | typedef struct      // 32 bytes hdr + 120 bytes payload | 
|  | 271 | { | 
|  | 272 | ULONG reserved;   // dword 0 (don't use - must clear to 0) | 
|  | 273 | ULONG sof_eof;    // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp | 
|  | 274 | ULONG d_id;       // dword 2 - 31:24 R_CTL, 23:0 D_ID | 
|  | 275 | ULONG s_id;       // dword 3 - 31:24 CS_CTL, 23:0 S_ID | 
|  | 276 | ULONG f_ctl;      // dword 4 - 31:24 Type,  23:0 F_CTL | 
|  | 277 | ULONG seq_cnt;    // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT | 
|  | 278 | ULONG ox_rx_id;   // dword 6 - 31:16 OX_ID,  15:0 RX_ID | 
|  | 279 | ULONG ro;  // dword 7 - relative offset | 
|  | 280 | //--------- | 
|  | 281 | __u32 pl[30];              // largest necessary payload (for LOGIN cmnds) | 
|  | 282 | } TachFCHDR_GCMND; | 
|  | 283 |  | 
|  | 284 | typedef struct      // 32 bytes hdr + 64 bytes payload | 
|  | 285 | { | 
|  | 286 | ULONG reserved;   // dword 0 (don't use) | 
|  | 287 | ULONG sof_eof; | 
|  | 288 | ULONG d_id;       // dword 2 - 31:24 R_CTL, 23:0 D_ID | 
|  | 289 | ULONG s_id;       // dword 3 - 31:24 CS_CTL, 23:0 S_ID | 
|  | 290 | ULONG f_ctl;      // dword 4 - 31:24 Type,  23:0 F_CTL | 
|  | 291 | ULONG seq_cnt;    // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT | 
|  | 292 | ULONG ox_rx_id;   // dword 6 - 31:16 OX_ID,  15:0 RX_ID | 
|  | 293 | ULONG ro;  // dword 7 - relative offset | 
|  | 294 | //--------- | 
|  | 295 | __u32 pl[18]; // payload for FCP-RSP (response buffer) RA-4x00 is 72bytes | 
|  | 296 | } TachFCHDR_RSP; | 
|  | 297 |  | 
|  | 298 |  | 
|  | 299 |  | 
|  | 300 |  | 
|  | 301 |  | 
|  | 302 |  | 
|  | 303 | // Inbound Message Queue structures... | 
|  | 304 | typedef struct              // each entry 8 words (32 bytes) | 
|  | 305 | { | 
|  | 306 | ULONG type;               // IMQ completion message types | 
|  | 307 | ULONG word[7];            // remainder of structure | 
|  | 308 | // interpreted by IMQ type | 
|  | 309 | } TachyonIMQE; | 
|  | 310 |  | 
|  | 311 |  | 
|  | 312 | // Queues for TachLite not in original Tachyon | 
|  | 313 | // ERQ       - Exchange Request Queue (for outbound commands) | 
|  | 314 | // SFQ       - Single Frame Queue (for incoming frames) | 
|  | 315 |  | 
|  | 316 | // Define Tachyon Outbound Command Que | 
|  | 317 | // (Since many Tachyon registers are Read | 
|  | 318 | // only, maintain copies for debugging) | 
|  | 319 | // most Tach ques need power-of-2 sizes, | 
|  | 320 | // where registers are loaded with po2 -1 | 
|  | 321 | #define TACH_SEST_LEN 512   // TachLite SEST | 
|  | 322 |  | 
|  | 323 | #define ELS_EXCHANGES 64    // e.g. PLOGI, RSCN, ... | 
|  | 324 | // define the total number of outstanding (simultaneous) exchanges | 
|  | 325 | #define TACH_MAX_XID (TACH_SEST_LEN + ELS_EXCHANGES)  // ELS exchanges | 
|  | 326 |  | 
|  | 327 | #define ERQ_LEN 128         // power of 2, max 4096 | 
|  | 328 |  | 
|  | 329 | // Inbound Message Queue structures... | 
|  | 330 | #define IMQ_LEN 512              // minimum 4 entries [(power of 2) - 1] | 
|  | 331 | typedef struct                   // 8 words - 32 bytes | 
|  | 332 | { | 
|  | 333 | TachyonIMQE QEntry[IMQ_LEN]; | 
|  | 334 | ULONG producerIndex;   // IMQ Producer Index register | 
|  | 335 | // @32 byte align | 
|  | 336 | ULONG consumerIndex;   // Consumer Index register (in Tachyon) | 
|  | 337 | ULONG length;          // Length register | 
|  | 338 | ULONG base; | 
|  | 339 | } TachyonIMQ;                    // @ 32 * IMQ_LEN align | 
|  | 340 |  | 
|  | 341 |  | 
|  | 342 |  | 
|  | 343 | typedef struct           // inbound completion message | 
|  | 344 | { | 
|  | 345 | ULONG Type; | 
|  | 346 | ULONG Index; | 
|  | 347 | ULONG TransferLength; | 
|  | 348 | } TachyonInbCM; | 
|  | 349 |  | 
|  | 350 |  | 
|  | 351 |  | 
|  | 352 | // arbitrary numeric tags for TL structures | 
|  | 353 | #define TL_FCHS 1  // TachLite Fibre Channel Header Structure | 
|  | 354 | #define TL_IWE 2  // initiator write entry (for SEST) | 
|  | 355 | #define TL_TWE 3  // target write entry (for SEST) | 
|  | 356 | #define TL_IRE 4  // initiator read entry (for SEST) | 
|  | 357 | #define TL_TRE 5  // target read entry (for SEST) | 
|  | 358 | #define TL_IRB 6  // I/O request block | 
|  | 359 |  | 
|  | 360 | // for INCOMING frames | 
|  | 361 | #define SFQ_LEN 32              // minimum 32 entries, max 4096 | 
|  | 362 |  | 
|  | 363 | typedef struct                  // Single Frame Que | 
|  | 364 | { | 
|  | 365 | TachFCHDR_CMND QEntry[SFQ_LEN]; // must be 64 bytes!! | 
|  | 366 | ULONG producerIndex;   // IMQ Producer Index register | 
|  | 367 | // @32 byte align | 
|  | 368 | ULONG consumerIndex;   // Consumer Index register (in Tachyon) | 
|  | 369 | ULONG length;          // Length register | 
|  | 370 | ULONG base; | 
|  | 371 | } TachLiteSFQ; | 
|  | 372 |  | 
|  | 373 |  | 
|  | 374 | typedef struct                 // I/O Request Block flags | 
|  | 375 | { | 
|  | 376 | UCHAR  BRD : 1; | 
|  | 377 | UCHAR      : 1; // reserved | 
|  | 378 | UCHAR  SFA : 1; | 
|  | 379 | UCHAR  DNC : 1; | 
|  | 380 | UCHAR  DIN : 1; | 
|  | 381 | UCHAR  DCM : 1; | 
|  | 382 | UCHAR  CTS : 1; | 
|  | 383 | UCHAR  SBV : 1;  // IRB entry valid - IRB'B' only | 
|  | 384 | } IRBflags; | 
|  | 385 |  | 
|  | 386 | typedef struct                  // I/O Request Block | 
|  | 387 | {                          // Request 'A' | 
|  | 388 | ULONG Req_A_SFS_Len;     // total frame len (hdr + payload), min 32 | 
|  | 389 | ULONG Req_A_SFS_Addr;    // 32-bit pointer to FCHS struct (to be sent) | 
|  | 390 | ULONG Req_A_SFS_D_ID;    // 24-bit FC destination (i.e. 8 bit al_pa) | 
|  | 391 | ULONG Req_A_Trans_ID;    // X_ID (OX_ID or RX_ID) and/or Index in SEST | 
|  | 392 | // Request 'B' | 
|  | 393 | ULONG Req_B_SFS_Len;     // total frame len (hdr + payload), min 32 | 
|  | 394 | ULONG Req_B_SFS_Addr;    // 32-bit pointer to FCHS struct (to be sent) | 
|  | 395 | ULONG Req_B_SFS_D_ID;    // 24-bit FC destination (i.e. 8 bit al_pa) | 
|  | 396 | ULONG Req_B_Trans_ID;    // X_ID (OX_ID or RX_ID) and/or Index in SEST | 
|  | 397 | } TachLiteIRB; | 
|  | 398 |  | 
|  | 399 |  | 
|  | 400 | typedef struct           // TachLite placeholder for IRBs | 
|  | 401 | {                        // aligned @sizeof(ERQ) for TachLite | 
|  | 402 | // MAX commands is sum of SEST len and ERQ | 
|  | 403 | // we know that each SEST entry requires an | 
|  | 404 | // IRB (ERQ) entry; in addition, we provide | 
|  | 405 | // ERQ_LEN | 
|  | 406 | TachLiteIRB QEntry[ERQ_LEN]; // Base register; entries 32 bytes ea. | 
|  | 407 | ULONG consumerIndex;   // Consumer Index register | 
|  | 408 | ULONG producerIndex;   // ERQ Producer Index register | 
|  | 409 | ULONG length;          // Length register | 
|  | 410 | ULONG base;            // copy of base ptr for debug | 
|  | 411 | // struct is sized for largest expected cmnd (LOGIN) | 
|  | 412 | } TachLiteERQ; | 
|  | 413 |  | 
|  | 414 | // for now, just 32 bit DMA, eventually 40something, with code changes | 
|  | 415 | #define CPQFCTS_DMA_MASK ((unsigned long) (0x00000000FFFFFFFF)) | 
|  | 416 |  | 
|  | 417 | #define TL_MAX_SG_ELEM_LEN 0x7ffff  // Max buffer length a single S/G entry | 
|  | 418 | // may represent (a hardware limitation).  The | 
|  | 419 | // only reason to ever change this is if you | 
|  | 420 | // want to exercise very-hard-to-reach code in | 
|  | 421 | // cpqfcTSworker.c:build_SEST_sglist(). | 
|  | 422 |  | 
|  | 423 | #define TL_DANGER_SGPAGES 7  // arbitrary high water mark for # of S/G pages | 
|  | 424 | // we must exceed to elicit a warning indicative | 
|  | 425 | // of EXTREMELY large data transfers or | 
|  | 426 | // EXTREME memory fragmentation. | 
|  | 427 | // (means we just used up 2048 S/G elements, | 
|  | 428 | // Never seen this is real life, only in | 
|  | 429 | // testing with tricked up driver.) | 
|  | 430 |  | 
|  | 431 | #define TL_EXT_SG_PAGE_COUNT 256  // Number of Extended Scatter/Gather a/l PAIRS | 
|  | 432 | // Tachyon register (IOBaseU 0x68) | 
|  | 433 | // power-of-2 value ONLY!  4 min, 256 max | 
|  | 434 |  | 
|  | 435 | // byte len is #Pairs * 2 ULONG/Pair * 4 bytes/ULONG | 
|  | 436 | #define TL_EXT_SG_PAGE_BYTELEN (TL_EXT_SG_PAGE_COUNT *2 *4) | 
|  | 437 |  | 
|  | 438 |  | 
|  | 439 |  | 
|  | 440 | // SEST entry types: IWE, IRE, TWE, TRE | 
|  | 441 | typedef struct | 
|  | 442 | { | 
|  | 443 | ULONG Hdr_Len; | 
|  | 444 | ULONG Hdr_Addr; | 
|  | 445 | ULONG RSP_Len; | 
|  | 446 | ULONG RSP_Addr; | 
|  | 447 | ULONG Buff_Off; | 
|  | 448 | #define USES_EXTENDED_SGLIST(this_sest, x_ID) \ | 
|  | 449 | (!((this_sest)->u[ x_ID ].IWE.Buff_Off & 0x80000000)) | 
|  | 450 | ULONG Link; | 
|  | 451 | ULONG RX_ID; | 
|  | 452 | ULONG Data_Len; | 
|  | 453 | ULONG Exp_RO; | 
|  | 454 | ULONG Exp_Byte_Cnt; | 
|  | 455 | // --- extended/local Gather Len/Address pairs | 
|  | 456 | ULONG GLen1; | 
|  | 457 | ULONG GAddr1; | 
|  | 458 | ULONG GLen2; | 
|  | 459 | ULONG GAddr2; | 
|  | 460 | ULONG GLen3; | 
|  | 461 | ULONG GAddr3; | 
|  | 462 | } TachLiteIWE; | 
|  | 463 |  | 
|  | 464 |  | 
|  | 465 | typedef struct | 
|  | 466 | { | 
|  | 467 | ULONG Seq_Accum; | 
|  | 468 | ULONG reserved;       // must clear to 0 | 
|  | 469 | ULONG RSP_Len; | 
|  | 470 | ULONG RSP_Addr; | 
|  | 471 | ULONG Buff_Off; | 
|  | 472 | ULONG Buff_Index;           // ULONG 5 | 
|  | 473 | ULONG Exp_RO; | 
|  | 474 | ULONG Byte_Count; | 
|  | 475 | ULONG reserved_;      // ULONG 8 | 
|  | 476 | ULONG Exp_Byte_Cnt; | 
|  | 477 | // --- extended/local Scatter Len/Address pairs | 
|  | 478 | ULONG SLen1; | 
|  | 479 | ULONG SAddr1; | 
|  | 480 | ULONG SLen2; | 
|  | 481 | ULONG SAddr2; | 
|  | 482 | ULONG SLen3; | 
|  | 483 | ULONG SAddr3; | 
|  | 484 | } TachLiteIRE; | 
|  | 485 |  | 
|  | 486 |  | 
|  | 487 | typedef struct          // Target Write Entry | 
|  | 488 | { | 
|  | 489 | ULONG Seq_Accum;      // dword 0 | 
|  | 490 | ULONG reserved;       // dword 1  must clear to 0 | 
|  | 491 | ULONG Remote_Node_ID; | 
|  | 492 | ULONG reserved1;      // dword 3  must clear to 0 | 
|  | 493 | ULONG Buff_Off; | 
|  | 494 | ULONG Buff_Index;     // ULONG 5 | 
|  | 495 | ULONG Exp_RO; | 
|  | 496 | ULONG Byte_Count; | 
|  | 497 | ULONG reserved_;      // ULONG 8 | 
|  | 498 | ULONG Exp_Byte_Cnt; | 
|  | 499 | // --- extended/local Scatter Len/Address pairs | 
|  | 500 | ULONG SLen1; | 
|  | 501 | ULONG SAddr1; | 
|  | 502 | ULONG SLen2; | 
|  | 503 | ULONG SAddr2; | 
|  | 504 | ULONG SLen3; | 
|  | 505 | ULONG SAddr3; | 
|  | 506 | } TachLiteTWE; | 
|  | 507 |  | 
|  | 508 | typedef struct | 
|  | 509 | { | 
|  | 510 | ULONG Hdr_Len; | 
|  | 511 | ULONG Hdr_Addr; | 
|  | 512 | ULONG RSP_Len;        // DWord 2 | 
|  | 513 | ULONG RSP_Addr; | 
|  | 514 | ULONG Buff_Off; | 
|  | 515 | ULONG Buff_Index;     // DWord 5 | 
|  | 516 | ULONG reserved; | 
|  | 517 | ULONG Data_Len; | 
|  | 518 | ULONG reserved_; | 
|  | 519 | ULONG reserved__; | 
|  | 520 | // --- extended/local Gather Len/Address pairs | 
|  | 521 | ULONG GLen1;          // DWord A | 
|  | 522 | ULONG GAddr1; | 
|  | 523 | ULONG GLen2; | 
|  | 524 | ULONG GAddr2; | 
|  | 525 | ULONG GLen3; | 
|  | 526 | ULONG GAddr3; | 
|  | 527 | } TachLiteTRE; | 
|  | 528 |  | 
|  | 529 | typedef struct ext_sg_page_ptr_t *PSGPAGES; | 
|  | 530 | typedef struct ext_sg_page_ptr_t | 
|  | 531 | { | 
|  | 532 | unsigned char page[TL_EXT_SG_PAGE_BYTELEN * 2]; // 2x for alignment | 
|  | 533 | dma_addr_t busaddr; 	// need the bus addresses and | 
|  | 534 | unsigned int maplen;  // lengths for later pci unmapping. | 
|  | 535 | PSGPAGES next; | 
|  | 536 | } SGPAGES; // linked list of S/G pairs, by Exchange | 
|  | 537 |  | 
|  | 538 | typedef struct                  // SCSI Exchange State Table | 
|  | 539 | { | 
|  | 540 | union                         // Entry can be IWE, IRE, TWE, TRE | 
|  | 541 | {                             // 64 bytes per entry | 
|  | 542 | TachLiteIWE IWE; | 
|  | 543 | TachLiteIRE IRE; | 
|  | 544 | TachLiteTWE TWE; | 
|  | 545 | TachLiteTRE TRE; | 
|  | 546 | } u[TACH_SEST_LEN]; | 
|  | 547 |  | 
|  | 548 | TachFCHDR DataHDR[TACH_SEST_LEN]; // for SEST FCP_DATA frame hdr (no pl) | 
|  | 549 | TachFCHDR_RSP RspHDR[TACH_SEST_LEN]; // space for SEST FCP_RSP frame | 
|  | 550 | PSGPAGES sgPages[TACH_SEST_LEN]; // head of linked list of Pool-allocations | 
|  | 551 | ULONG length;          // Length register | 
|  | 552 | ULONG base;            // copy of base ptr for debug | 
|  | 553 | } TachSEST; | 
|  | 554 |  | 
|  | 555 |  | 
|  | 556 |  | 
|  | 557 | typedef struct                  // each register has it's own address | 
|  | 558 | // and value (used for write-only regs) | 
|  | 559 | { | 
|  | 560 | void* address; | 
|  | 561 | volatile ULONG value; | 
|  | 562 | } FCREGISTER; | 
|  | 563 |  | 
|  | 564 | typedef struct         // Host copy - TachLite Registers | 
|  | 565 | { | 
|  | 566 | ULONG IOBaseL, IOBaseU;  // I/O port lower and upper TL register addresses | 
|  | 567 | ULONG MemBase;           // memory mapped register addresses | 
|  | 568 | void* ReMapMemBase;      // O/S VM reference for MemBase | 
|  | 569 | ULONG wwn_hi;            // WWN is set once at startup | 
|  | 570 | ULONG wwn_lo; | 
|  | 571 | ULONG my_al_pa;          // al_pa received after LIP() | 
|  | 572 | ULONG ROMCTR;            // flags for on-board RAM/ROM | 
|  | 573 | ULONG RAMBase;           // on-board RAM (i.e. some Tachlites) | 
|  | 574 | ULONG SROMBase;          // on-board EEPROM (some Tachlites) | 
|  | 575 | ULONG PCIMCTR;           // PCI Master Control Reg (has bus width) | 
|  | 576 |  | 
|  | 577 | FCREGISTER INTEN;        // copy of interrupt enable mask | 
|  | 578 | FCREGISTER INTPEND;      // interrupt pending | 
|  | 579 | FCREGISTER INTSTAT;      // interrupt status | 
|  | 580 | FCREGISTER SFQconsumerIndex; | 
|  | 581 | FCREGISTER ERQproducerIndex; | 
|  | 582 | FCREGISTER TYconfig;   // TachYon (chip level) | 
|  | 583 | FCREGISTER TYcontrol; | 
|  | 584 | FCREGISTER TYstatus; | 
|  | 585 | FCREGISTER FMconfig;   // Frame Manager (FC loop level) | 
|  | 586 | FCREGISTER FMcontrol; | 
|  | 587 | FCREGISTER FMstatus; | 
|  | 588 | FCREGISTER FMLinkStatus1; | 
|  | 589 | FCREGISTER FMLinkStatus2; | 
|  | 590 | FCREGISTER FMBB_CreditZero; | 
|  | 591 | FCREGISTER status; | 
|  | 592 | FCREGISTER ed_tov;     // error detect time-out value | 
|  | 593 | FCREGISTER rcv_al_pa;  // received arb. loop physical address | 
|  | 594 | FCREGISTER primitive;  // e.g. LIP(), OPN(), ... | 
|  | 595 | } TL_REGISTERS; | 
|  | 596 |  | 
|  | 597 |  | 
|  | 598 |  | 
|  | 599 | typedef struct | 
|  | 600 | { | 
|  | 601 | ULONG ok; | 
|  | 602 | ULONG invalidArgs; | 
|  | 603 | ULONG linkDown; | 
|  | 604 | ULONG linkUp; | 
|  | 605 | ULONG outQueFull; | 
|  | 606 | ULONG SESTFull; | 
|  | 607 | ULONG hpe;    // host programming err (from Tach) | 
|  | 608 | ULONG FC4aborted; // aborts from Application or upper driver layer | 
|  | 609 | ULONG FC2aborted; // aborts from our driver's timeouts | 
|  | 610 | ULONG timeouts;   // our driver timeout (on individual exchanges) | 
|  | 611 | ULONG logouts;    // explicit - sent LOGO; implicit - device removed | 
|  | 612 | ULONG retries; | 
|  | 613 | ULONG linkFailTX; | 
|  | 614 | ULONG linkFailRX; | 
|  | 615 | ULONG CntErrors;  // byte count expected != count received (typ. SEST) | 
|  | 616 | ULONG e_stores;   // elastic store errs | 
|  | 617 | ULONG resets;     // hard or soft controller resets | 
|  | 618 | ULONG FMinits;    // TACH Frame Manager Init (e.g. LIPs) | 
|  | 619 | ULONG lnkQueFull;  // too many LOGIN, loop commands | 
|  | 620 | ULONG ScsiQueFull; // too many FCP-SCSI inbound frames | 
|  | 621 | ULONG LossofSignal;   // FM link status 1 regs | 
|  | 622 | ULONG BadRXChar;   // FM link status 1 regs | 
|  | 623 | ULONG LossofSync;   // FM link status 1 regs | 
|  | 624 | ULONG Rx_EOFa;   // FM link status 2 regs (received EOFa) | 
|  | 625 | ULONG Dis_Frm;   // FM link status 2 regs (discarded frames) | 
|  | 626 | ULONG Bad_CRC;   // FM link status 2 regs | 
|  | 627 | ULONG BB0_Timer; //  FM BB_Credit Zero Timer Reg | 
|  | 628 | ULONG loopBreaks; // infinite loop exits | 
|  | 629 | ULONG lastBB0timer;  // static accum. buffer needed by Tachlite | 
|  | 630 | } FCSTATS; | 
|  | 631 |  | 
|  | 632 |  | 
|  | 633 | typedef struct               // Config Options | 
|  | 634 | {                            // LS Bit first | 
|  | 635 | USHORT        : 1;           // bit0: | 
|  | 636 | USHORT  flogi : 1;           // bit1: We sent FLOGI - wait for Fabric logins | 
|  | 637 | USHORT  fabric: 1;           // bit2: Tachyon detected Fabric (FM stat LG) | 
|  | 638 | USHORT  LILPin: 1;           // bit3: We can use an FC-AL LILP frame | 
|  | 639 | USHORT  target: 1;           // bit4: this Port has SCSI target capability | 
|  | 640 | USHORT  initiator:    1;     // bit5: this Port has SCSI initiator capability | 
|  | 641 | USHORT  extLoopback:  1;     // bit6: loopback at GBIC | 
|  | 642 | USHORT  intLoopback:  1;     // bit7: loopback in HP silicon | 
|  | 643 | USHORT        : 1;           // bit8: | 
|  | 644 | USHORT        : 1;           // bit9: | 
|  | 645 | USHORT        : 1;           // bit10: | 
|  | 646 | USHORT        : 1;           // bit11: | 
|  | 647 | USHORT        : 1;           // bit12: | 
|  | 648 | USHORT        : 1;           // bit13: | 
|  | 649 | USHORT        : 1;           // bit14: | 
|  | 650 | USHORT        : 1;           // bit15: | 
|  | 651 | } FC_OPTIONS; | 
|  | 652 |  | 
|  | 653 |  | 
|  | 654 |  | 
|  | 655 | typedef struct dyn_mem_pair | 
|  | 656 | { | 
|  | 657 | void *BaseAllocated;  // address as allocated from O/S; | 
|  | 658 | unsigned long AlignedAddress; // aligned address (used by Tachyon DMA) | 
|  | 659 | dma_addr_t dma_handle; | 
|  | 660 | size_t size; | 
|  | 661 | } ALIGNED_MEM; | 
|  | 662 |  | 
|  | 663 |  | 
|  | 664 |  | 
|  | 665 |  | 
|  | 666 | // these structs contain only CRUCIAL (stuff we actually use) parameters | 
|  | 667 | // from FC-PH(n) logins.  (Don't save entire LOGIN payload to save mem.) | 
|  | 668 |  | 
|  | 669 | // Implicit logout happens when the loop goes down - we require PDISC | 
|  | 670 | // to restore.  Explicit logout is when WE decide never to talk to someone, | 
|  | 671 | // or when a target refuses to talk to us, i.e. sends us a LOGO frame or | 
|  | 672 | // LS_RJT reject in response to our PLOGI request. | 
|  | 673 |  | 
|  | 674 | #define IMPLICIT_LOGOUT 1 | 
|  | 675 | #define EXPLICIT_LOGOUT 2 | 
|  | 676 |  | 
|  | 677 | typedef struct | 
|  | 678 | { | 
|  | 679 | UCHAR channel; // SCSI "bus" | 
|  | 680 | UCHAR target; | 
|  | 681 | UCHAR InqDeviceType;  // byte 0 from SCSI Inquiry response | 
|  | 682 | UCHAR VolumeSetAddressing;  // FCP-SCSI LUN coding (40h for VSA) | 
|  | 683 | UCHAR LunMasking;     // True if selective presentation supported | 
|  | 684 | UCHAR lun[CPQFCTS_MAX_LUN]; | 
|  | 685 | } SCSI_NEXUS; | 
|  | 686 |  | 
|  | 687 |  | 
|  | 688 | typedef struct | 
|  | 689 | { | 
|  | 690 | union | 
|  | 691 | { | 
|  | 692 | UCHAR ucWWN[8];  // a FC 64-bit World Wide Name/ PortID of target | 
|  | 693 | // addressing of single target on single loop... | 
|  | 694 | u64 liWWN; | 
|  | 695 | } u; | 
|  | 696 |  | 
|  | 697 | ULONG port_id;     // a FC 24-bit address of port (lower 8 bits = al_pa) | 
|  | 698 |  | 
|  | 699 | #define REPORT_LUNS_PL 256 | 
|  | 700 | UCHAR ReportLunsPayload[REPORT_LUNS_PL]; | 
|  | 701 |  | 
|  | 702 | SCSI_NEXUS ScsiNexus; // LUNs per FC device | 
|  | 703 |  | 
|  | 704 | ULONG LOGO_counter; // might try several times before logging out for good | 
|  | 705 | ULONG LOGO_timer;   // after LIP, ports expecting PDISC must time-out and | 
|  | 706 | // LOGOut if successful PDISC not completed in 2 secs | 
|  | 707 |  | 
|  | 708 | ULONG concurrent_seq;  // must be 1 or greater | 
|  | 709 | ULONG rx_data_size;    // e.g. 128, 256, 1024, 2048 per FC-PH spec | 
|  | 710 | ULONG BB_credit; | 
|  | 711 | ULONG EE_credit; | 
|  | 712 |  | 
|  | 713 | ULONG fcp_info;        // from PRLI (i.e. INITIATOR/ TARGET flags) | 
|  | 714 | // flags for login process | 
|  | 715 | BOOLEAN Originator;    // Login sequence Originated (if false, we | 
|  | 716 | // responded to another port's login sequence) | 
|  | 717 | BOOLEAN plogi;         // PLOGI frame ACCepted (originated or responded) | 
|  | 718 | BOOLEAN pdisc;         // PDISC frame was ORIGINATED (self-login logic) | 
|  | 719 | BOOLEAN prli;          // PRLI frame ACCepted (originated or responded) | 
|  | 720 | BOOLEAN flogi;         // FLOGI frame ACCepted (originated or responded) | 
|  | 721 | BOOLEAN logo;          // port permanently logged out (invalid login param) | 
|  | 722 | BOOLEAN flogiReq;      // Fabric login required (set in LIP process) | 
|  | 723 | UCHAR highest_ver; | 
|  | 724 | UCHAR lowest_ver; | 
|  | 725 |  | 
|  | 726 |  | 
|  | 727 | // when the "target" (actually FC Port) is waiting for login | 
|  | 728 | // (e.g. after Link reset), set the device_blocked bit; | 
|  | 729 | // after Port completes login, un-block target. | 
|  | 730 | UCHAR device_blocked; // see Scsi_Device struct | 
|  | 731 |  | 
|  | 732 | // define singly-linked list of logged-in ports | 
|  | 733 | // once a port_id is identified, it is remembered, | 
|  | 734 | // even if the port is removed indefinitely | 
|  | 735 | PVOID pNextPort;  // actually, type PFC_LOGGEDIN_PORT; void for Compiler | 
|  | 736 |  | 
|  | 737 | } FC_LOGGEDIN_PORT, *PFC_LOGGEDIN_PORT; | 
|  | 738 |  | 
|  | 739 |  | 
|  | 740 |  | 
|  | 741 | // This serves as the ESB (Exchange Status Block), | 
|  | 742 | // and has timeout counter; used for ABORTs | 
|  | 743 | typedef struct | 
|  | 744 | {                                  // FC-1 X_IDs | 
|  | 745 | ULONG type;            // ELS_PLOGI, SCSI_IWE, ... (0 if free) | 
|  | 746 | PFC_LOGGEDIN_PORT pLoggedInPort; // FC device on other end of Exchange | 
|  | 747 | Scsi_Cmnd *Cmnd;       // Linux SCSI command packet includes S/G list | 
|  | 748 | ULONG timeOut;         // units of ??, DEC by driver, Abort when 0 | 
|  | 749 | ULONG reTries;         // need one or more retries? | 
|  | 750 | ULONG status;          // flags indicating errors (0 if none) | 
|  | 751 | TachLiteIRB IRB;       // I/O Request Block, gets copied to ERQ | 
|  | 752 | TachFCHDR_GCMND fchs;  // location of IRB's Req_A_SFS_Addr | 
|  | 753 | } FC_EXCHANGE, *PFC_EXCHANGE; | 
|  | 754 |  | 
|  | 755 | // Unfortunately, Linux limits our kmalloc() allocations to 128k. | 
|  | 756 | // Because of this and the fact that our ScsiRegister allocation | 
|  | 757 | // is also constrained, we move this large structure out for | 
|  | 758 | // allocation after Scsi Register. | 
|  | 759 | // (In other words, this cumbersome indirection is necessary | 
|  | 760 | // because of kernel memory allocation constraints!) | 
|  | 761 |  | 
|  | 762 | typedef struct // we will allocate this dynamically | 
|  | 763 | { | 
|  | 764 | FC_EXCHANGE fcExchange[ TACH_MAX_XID ]; | 
|  | 765 | } FC_EXCHANGES; | 
|  | 766 |  | 
|  | 767 |  | 
|  | 768 |  | 
|  | 769 |  | 
|  | 770 |  | 
|  | 771 |  | 
|  | 772 |  | 
|  | 773 |  | 
|  | 774 |  | 
|  | 775 |  | 
|  | 776 |  | 
|  | 777 | typedef struct | 
|  | 778 | { | 
|  | 779 | char Name[64]; // name of controller ("HP Tachlite TL Rev2.0, 33MHz, 64bit bus") | 
|  | 780 | //PVOID  pAdapterDevExt; // back pointer to device object/extension | 
|  | 781 | ULONG ChipType;        // local numeric key for Tachyon Type / Rev. | 
|  | 782 | ULONG status;              // our Driver - logical status | 
|  | 783 |  | 
|  | 784 | TL_REGISTERS Registers;    // reg addresses & host memory copies | 
|  | 785 | // FC-4 mapping of 'transaction' to X_IDs | 
|  | 786 | UCHAR LILPmap[32*4];       // Loop Position Map of ALPAs (late FC-AL only) | 
|  | 787 | FC_OPTIONS Options;        // e.g. Target, Initiator, loopback... | 
|  | 788 | UCHAR highest_FCPH_ver;    // FC-PH version limits | 
|  | 789 | UCHAR lowest_FCPH_ver;     // FC-PH version limits | 
|  | 790 |  | 
|  | 791 | FC_EXCHANGES *Exchanges; | 
|  | 792 | ULONG fcLsExchangeLRU;       // Least Recently Used counter (Link Service) | 
|  | 793 | ULONG fcSestExchangeLRU;       // Least Recently Used counter (FCP-SCSI) | 
|  | 794 | FC_LOGGEDIN_PORT fcPorts;  // linked list of every FC port ever seen | 
|  | 795 | FCSTATS fcStats;           // FC comm err counters | 
|  | 796 |  | 
|  | 797 | // Host memory QUEUE pointers | 
|  | 798 | TachLiteERQ *ERQ;          // Exchange Request Que | 
|  | 799 | TachyonIMQ *IMQ;           // Inbound Message Que | 
|  | 800 | TachLiteSFQ *SFQ;          // Single Frame Queue | 
|  | 801 | TachSEST *SEST;            // SCSI Exchange State Table | 
|  | 802 |  | 
|  | 803 | dma_addr_t exch_dma_handle; | 
|  | 804 |  | 
|  | 805 | // these function pointers are for "generic" functions, which are | 
|  | 806 | // replaced with Host Bus Adapter types at | 
|  | 807 | // runtime. | 
|  | 808 | int (*CreateTachyonQues)( void* , int); | 
|  | 809 | int (*DestroyTachyonQues)( void* , int); | 
|  | 810 | int (*LaserControl)(void*, int );   // e.g. On/Off | 
|  | 811 | int (*ResetTachyon)(void*, int ); | 
|  | 812 | void (*FreezeTachyon)(void*, int ); | 
|  | 813 | void (*UnFreezeTachyon)(void*, int ); | 
|  | 814 | int (*InitializeTachyon)(void*, int, int ); | 
|  | 815 | int (*InitializeFrameManager)(void*, int ); | 
|  | 816 | int (*ProcessIMQEntry)(void*); | 
|  | 817 | int (*ReadWriteWWN)(void*, int ReadWrite); | 
|  | 818 | int (*ReadWriteNVRAM)(void*, void*, int ReadWrite); | 
|  | 819 |  | 
|  | 820 | } TACHYON, *PTACHYON; | 
|  | 821 |  | 
|  | 822 |  | 
|  | 823 | void cpqfcTSClearLinkStatusCounters(TACHYON * fcChip); | 
|  | 824 |  | 
|  | 825 | int CpqTsCreateTachLiteQues( void* pHBA, int opcode); | 
|  | 826 | int CpqTsDestroyTachLiteQues( void* , int); | 
|  | 827 | int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2); | 
|  | 828 |  | 
|  | 829 | int CpqTsProcessIMQEntry(void* pHBA); | 
|  | 830 | int CpqTsResetTachLite(void *pHBA, int type); | 
|  | 831 | void CpqTsFreezeTachlite(void *pHBA, int type); | 
|  | 832 | void CpqTsUnFreezeTachlite(void *pHBA, int type); | 
|  | 833 | int CpqTsInitializeFrameManager(void *pHBA, int); | 
|  | 834 | int CpqTsLaserControl( void* addrBase, int opcode ); | 
|  | 835 | int CpqTsReadWriteWWN(void*, int ReadWrite); | 
|  | 836 | int CpqTsReadWriteNVRAM(void*, void* data, int ReadWrite); | 
|  | 837 |  | 
|  | 838 | void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter); | 
|  | 839 | void cpqfcTSWorkerThread( void *host); | 
|  | 840 |  | 
|  | 841 | int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf ); | 
|  | 842 | ULONG cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count, | 
|  | 843 | UCHAR *buf ); | 
|  | 844 |  | 
|  | 845 | BOOLEAN tl_write_i2c_nvram( void* GPIOin, void* GPIOout, | 
|  | 846 | USHORT startOffset,  // e.g. 0x2f for WWN start | 
|  | 847 | USHORT count, | 
|  | 848 | UCHAR *buf ); | 
|  | 849 |  | 
|  | 850 |  | 
|  | 851 | // define misc functions | 
|  | 852 | int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]); | 
|  | 853 | int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]); | 
|  | 854 | void* fcMemManager( struct pci_dev *pdev, | 
|  | 855 | ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab, | 
|  | 856 | ULONG ulAlignedAddress, dma_addr_t *dma_handle); | 
|  | 857 |  | 
|  | 858 | void BigEndianSwap(  UCHAR *source, UCHAR *dest,  USHORT cnt); | 
|  | 859 |  | 
|  | 860 | //ULONG virt_to_phys( PVOID virtaddr ); | 
|  | 861 |  | 
|  | 862 |  | 
|  | 863 | // Linux interrupt handler | 
|  | 864 | irqreturn_t cpqfcTS_intr_handler( int irq,void *dev_id,struct pt_regs *regs); | 
|  | 865 | void cpqfcTSheartbeat( unsigned long ptr ); | 
|  | 866 |  | 
|  | 867 |  | 
|  | 868 |  | 
|  | 869 | // The biggest Q element we deal with is Aborts - we | 
|  | 870 | // need 4 bytes for x_ID, and a Scsi_Cmnd (~284 bytes) | 
|  | 871 | //#define LINKQ_ITEM_SIZE ((4+sizeof(Scsi_Cmnd)+3)/4) | 
|  | 872 | #define LINKQ_ITEM_SIZE (3*16) | 
|  | 873 | typedef struct | 
|  | 874 | { | 
|  | 875 | ULONG Type;              // e.g. LINKUP, SFQENTRY, PDISC, BLS_ABTS, ... | 
|  | 876 | ULONG ulBuff[ LINKQ_ITEM_SIZE ]; | 
|  | 877 | } LINKQ_ITEM; | 
|  | 878 |  | 
|  | 879 | #define FC_LINKQ_DEPTH TACH_MAX_XID | 
|  | 880 | typedef struct | 
|  | 881 | { | 
|  | 882 | ULONG producer; | 
|  | 883 | ULONG consumer;  // when producer equals consumer, Q empty | 
|  | 884 |  | 
|  | 885 | LINKQ_ITEM Qitem[ FC_LINKQ_DEPTH ]; | 
|  | 886 |  | 
|  | 887 | } FC_LINK_QUE, *PFC_LINK_QUE; | 
|  | 888 |  | 
|  | 889 |  | 
|  | 890 | // DPC routines post to here on Inbound SCSI frames | 
|  | 891 | // User thread processes | 
|  | 892 | #define FC_SCSIQ_DEPTH 32 | 
|  | 893 |  | 
|  | 894 | typedef struct | 
|  | 895 | { | 
|  | 896 | int Type;              // e.g. SCSI | 
|  | 897 | ULONG ulBuff[ 3*16 ]; | 
|  | 898 | } SCSIQ_ITEM; | 
|  | 899 |  | 
|  | 900 | typedef struct | 
|  | 901 | { | 
|  | 902 | ULONG producer; | 
|  | 903 | ULONG consumer;  // when producer equals consumer, Q empty | 
|  | 904 |  | 
|  | 905 | SCSIQ_ITEM Qitem[ FC_SCSIQ_DEPTH ]; | 
|  | 906 |  | 
|  | 907 | } FC_SCSI_QUE, *PFC_SCSI_QUE; | 
|  | 908 |  | 
|  | 909 | typedef struct { | 
|  | 910 | /* This is tacked on to a Scsi_Request in upper_private_data | 
|  | 911 | for pasthrough ioctls, as a place to hold data that can't | 
|  | 912 | be stashed anywhere else in the Scsi_Request.  We differentiate | 
|  | 913 | this from _real_ upper_private_data by checking if the virt addr | 
|  | 914 | is within our special pool.  */ | 
|  | 915 | ushort bus; | 
|  | 916 | ushort pdrive; | 
|  | 917 | } cpqfc_passthru_private_t; | 
|  | 918 |  | 
|  | 919 | #define CPQFC_MAX_PASSTHRU_CMDS 100 | 
|  | 920 |  | 
|  | 921 | #define DYNAMIC_ALLOCATIONS 4  // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST | 
|  | 922 |  | 
|  | 923 | // Linux space allocated per HBA (chip state, etc.) | 
|  | 924 | typedef struct | 
|  | 925 | { | 
|  | 926 | struct Scsi_Host *HostAdapter; // back pointer to Linux Scsi struct | 
|  | 927 |  | 
|  | 928 | TACHYON fcChip;    // All Tachyon registers, Queues, functions | 
|  | 929 | ALIGNED_MEM dynamic_mem[DYNAMIC_ALLOCATIONS]; | 
|  | 930 |  | 
|  | 931 | struct pci_dev *PciDev; | 
|  | 932 | dma_addr_t fcLQ_dma_handle; | 
|  | 933 |  | 
|  | 934 | Scsi_Cmnd *LinkDnCmnd[CPQFCTS_REQ_QUEUE_LEN]; // collects Cmnds during LDn | 
|  | 935 | // (for Acceptable targets) | 
|  | 936 | Scsi_Cmnd *BoardLockCmnd[CPQFCTS_REQ_QUEUE_LEN]; // SEST was full | 
|  | 937 |  | 
|  | 938 | Scsi_Cmnd *BadTargetCmnd[CPQFCTS_MAX_TARGET_ID]; // missing targets | 
|  | 939 |  | 
|  | 940 | u_char HBAnum;     // 0-based host number | 
|  | 941 |  | 
|  | 942 |  | 
|  | 943 | struct timer_list cpqfcTStimer; // FC utility timer for implicit | 
|  | 944 | // logouts, FC protocol timeouts, etc. | 
|  | 945 | int fcStatsTime;  // Statistics delta reporting time | 
|  | 946 |  | 
|  | 947 | struct task_struct *worker_thread; // our kernel thread | 
|  | 948 | int PortDiscDone;    // set by SendLogins(), cleared by LDn | 
|  | 949 |  | 
|  | 950 | struct semaphore *TachFrozen; | 
|  | 951 | struct semaphore *TYOBcomplete;    // handshake for Tach outbound frames | 
|  | 952 | struct semaphore *fcQueReady;      // FibreChannel work for our kernel thread | 
|  | 953 | struct semaphore *notify_wt;       // synchronizes kernel thread kill | 
|  | 954 | struct semaphore *BoardLock; | 
|  | 955 |  | 
|  | 956 | PFC_LINK_QUE fcLQ;             // the WorkerThread operates on this | 
|  | 957 |  | 
|  | 958 | spinlock_t hba_spinlock;           // held/released by WorkerThread | 
|  | 959 | cpqfc_passthru_private_t *private_data_pool; | 
|  | 960 | unsigned long *private_data_bits; | 
|  | 961 |  | 
|  | 962 | } CPQFCHBA; | 
|  | 963 |  | 
|  | 964 | #define	CPQ_SPINLOCK_HBA( x )   spin_lock(&x->hba_spinlock); | 
|  | 965 | #define CPQ_SPINUNLOCK_HBA(x)   spin_unlock(&x->hba_spinlock); | 
|  | 966 |  | 
|  | 967 |  | 
|  | 968 |  | 
|  | 969 | void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata, | 
|  | 970 | PFC_LOGGEDIN_PORT pFcPort); | 
|  | 971 |  | 
|  | 972 |  | 
|  | 973 | void cpqfcTSTerminateExchange( CPQFCHBA*, SCSI_NEXUS *target, int ); | 
|  | 974 |  | 
|  | 975 | PFC_LOGGEDIN_PORT fcPortLoggedIn( | 
|  | 976 | CPQFCHBA *cpqfcHBAdata, | 
|  | 977 | TachFCHDR_GCMND* fchs, | 
|  | 978 | BOOLEAN, | 
|  | 979 | BOOLEAN); | 
|  | 980 | void fcProcessLoggedIn( | 
|  | 981 | CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs); | 
|  | 982 |  | 
|  | 983 |  | 
|  | 984 | ULONG cpqfcTSBuildExchange( | 
|  | 985 | CPQFCHBA *cpqfcHBAdata, | 
|  | 986 | ULONG type, // e.g. PLOGI | 
|  | 987 | TachFCHDR_GCMND* InFCHS,  // incoming FCHS | 
|  | 988 | void *Data,               // the CDB, scatter/gather, etc. | 
|  | 989 | LONG *ExchangeID );       // allocated exchange ID | 
|  | 990 |  | 
|  | 991 | ULONG cpqfcTSStartExchange( | 
|  | 992 | CPQFCHBA *cpqfcHBAdata, | 
|  | 993 | LONG ExchangeID ); | 
|  | 994 |  | 
|  | 995 | void cpqfcTSCompleteExchange( | 
|  | 996 | struct pci_dev *pcidev, | 
|  | 997 | PTACHYON fcChip, | 
|  | 998 | ULONG exchange_ID); | 
|  | 999 |  | 
|  | 1000 |  | 
|  | 1001 | PFC_LOGGEDIN_PORT  fcFindLoggedInPort( | 
|  | 1002 | PTACHYON fcChip, | 
|  | 1003 | Scsi_Cmnd *Cmnd,  // (We want the channel/target/lun Nexus from Cmnd) | 
|  | 1004 | ULONG port_id,  // search linked list for al_pa, or | 
|  | 1005 | UCHAR wwn[8],    // search linked list for WWN, or... | 
|  | 1006 | PFC_LOGGEDIN_PORT *pLastLoggedInPort | 
|  | 1007 | ); | 
|  | 1008 |  | 
|  | 1009 | void cpqfcTSPutLinkQue( | 
|  | 1010 | CPQFCHBA *cpqfcHBAdata, | 
|  | 1011 | int Type, | 
|  | 1012 | void *QueContent); | 
|  | 1013 |  | 
|  | 1014 | void fcPutScsiQue( | 
|  | 1015 | CPQFCHBA *cpqfcHBAdata, | 
|  | 1016 | int Type, | 
|  | 1017 | void *QueContent); | 
|  | 1018 |  | 
|  | 1019 | void fcLinkQReset( | 
|  | 1020 | CPQFCHBA *); | 
|  | 1021 | void fcScsiQReset( | 
|  | 1022 | CPQFCHBA *); | 
|  | 1023 | void fcSestReset( | 
|  | 1024 | CPQFCHBA *); | 
|  | 1025 |  | 
|  | 1026 | void cpqfc_pci_unmap(struct pci_dev *pcidev, | 
|  | 1027 | Scsi_Cmnd *cmd, | 
|  | 1028 | PTACHYON fcChip, | 
|  | 1029 | ULONG x_ID); | 
|  | 1030 |  | 
|  | 1031 | extern const UCHAR valid_al_pa[]; | 
|  | 1032 | extern const int number_of_al_pa; | 
|  | 1033 |  | 
|  | 1034 | #define FCP_RESID_UNDER   0x80000 | 
|  | 1035 | #define FCP_RESID_OVER    0x40000 | 
|  | 1036 | #define FCP_SNS_LEN_VALID 0x20000 | 
|  | 1037 | #define FCP_RSP_LEN_VALID 0x10000 | 
|  | 1038 |  | 
|  | 1039 | // RSP_CODE definitions (dpANS Fibre Channel Protocol for SCSI, pg 34) | 
|  | 1040 | #define FCP_DATA_LEN_NOT_BURST_LEN 0x1000000 | 
|  | 1041 | #define FCP_CMND_FIELD_INVALID     0x2000000 | 
|  | 1042 | #define FCP_DATA_RO_NOT_XRDY_RO    0x3000000 | 
|  | 1043 | #define FCP_TASKFUNCTION_NS        0x4000000 | 
|  | 1044 | #define FCP_TASKFUNCTION_FAIL      0x5000000 | 
|  | 1045 |  | 
|  | 1046 | // FCP-SCSI response status struct | 
|  | 1047 | typedef struct  // see "TachFCHDR_RSP" definition - 64 bytes | 
|  | 1048 | { | 
|  | 1049 | __u32 reserved; | 
|  | 1050 | __u32 reserved1; | 
|  | 1051 | __u32 fcp_status;    // field validity and SCSI status | 
|  | 1052 | __u32 fcp_resid; | 
|  | 1053 | __u32 fcp_sns_len;   // length of FCP_SNS_INFO field | 
|  | 1054 | __u32 fcp_rsp_len;   // length of FCP_RSP_INFO field (expect 8) | 
|  | 1055 | __u32 fcp_rsp_info;  // 4 bytes of FCP protocol response information | 
|  | 1056 | __u32 fcp_rsp_info2; // (4 more bytes, since most implementations use 8) | 
|  | 1057 | __u8  fcp_sns_info[36]; // bytes for SCSI sense (ASC, ASCQ) | 
|  | 1058 |  | 
|  | 1059 | } FCP_STATUS_RESPONSE, *PFCP_STATUS_RESPONSE; | 
|  | 1060 |  | 
|  | 1061 |  | 
|  | 1062 | // Fabric State Change Registration | 
|  | 1063 | typedef struct scrpl | 
|  | 1064 | { | 
|  | 1065 | __u32 command; | 
|  | 1066 | __u32 function; | 
|  | 1067 | } SCR_PL; | 
|  | 1068 |  | 
|  | 1069 | // Fabric Name Service Request | 
|  | 1070 | typedef struct nsrpl | 
|  | 1071 | { | 
|  | 1072 | __u32 CT_Rev;  // (& IN_ID)   WORD 0 | 
|  | 1073 | __u32 FCS_Type;            // WORD 1 | 
|  | 1074 | __u32 Command_code;        // WORD 2 | 
|  | 1075 | __u32 reason_code;         // WORD 3 | 
|  | 1076 | __u32 FCP;                 // WORD 4 (lower byte) | 
|  | 1077 |  | 
|  | 1078 | } NSR_PL; | 
|  | 1079 |  | 
|  | 1080 |  | 
|  | 1081 |  | 
|  | 1082 | // "FC.H" | 
|  | 1083 | #define MAX_RX_SIZE		0x800	// Max Receive Buffer Size is 2048 | 
|  | 1084 | #define MIN_RX_SIZE		0x100	// Min Size is 256, per FC-PLDA Spec | 
|  | 1085 | #define	MAX_TARGET_RXIDS	SEST_DEPTH | 
|  | 1086 | #define TARGET_RX_SIZE		SEST_BUFFER_LENGTH | 
|  | 1087 |  | 
|  | 1088 | #define CLASS_1			0x01 | 
|  | 1089 | #define CLASS_2			0x02 | 
|  | 1090 | #define CLASS_3			0x03 | 
|  | 1091 |  | 
|  | 1092 | #define FC_PH42			0x08 | 
|  | 1093 | #define FC_PH43			0x09 | 
|  | 1094 | #define FC_PH3			0x20 | 
|  | 1095 |  | 
|  | 1096 | #define RR_TOV			2	// Minimum Time for target to wait for | 
|  | 1097 | // PDISC after a LIP. | 
|  | 1098 | #define E_D_TOV			2	// Minimum Time to wait for Sequence | 
|  | 1099 | // Completion. | 
|  | 1100 | #define R_A_TOV			0	// Minimum Time for Target to wait | 
|  | 1101 | // before reclaiming resources. | 
|  | 1102 | // | 
|  | 1103 | //	R_CTL Field | 
|  | 1104 | // | 
|  | 1105 | //	Routing Bits (31-28) | 
|  | 1106 | // | 
|  | 1107 | #define FC4_DEVICE_DATA		0x00000000 | 
|  | 1108 | #define EXT_LINK_DATA		0x20000000 | 
|  | 1109 | #define FC4_LINK_DATA		0x30000000 | 
|  | 1110 | #define VIDEO_DATA		0x40000000 | 
|  | 1111 | #define BASIC_LINK_DATA		0x80000000 | 
|  | 1112 | #define LINK_CONTROL		0xC0000000 | 
|  | 1113 | #define ROUTING_MASK		0xF0000000 | 
|  | 1114 |  | 
|  | 1115 | // | 
|  | 1116 | //	Information Bits (27-24) | 
|  | 1117 | // | 
|  | 1118 | #define UNCAT_INFORMATION	0x00000000 | 
|  | 1119 | #define SOLICITED_DATA		0x01000000 | 
|  | 1120 | #define UNSOLICITED_CONTROL	0x02000000 | 
|  | 1121 | #define SOLICITED_CONTROL	0x03000000 | 
|  | 1122 | #define UNSOLICITED_DATA	0x04000000 | 
|  | 1123 | #define DATA_DESCRIPTOR		0x05000000 | 
|  | 1124 | #define UNSOLICITED_COMMAND	0x06000000 | 
|  | 1125 | #define COMMAND_STATUS		0x07000000 | 
|  | 1126 | #define INFO_MASK		0x0F000000 | 
|  | 1127 | // | 
|  | 1128 | //	(Link Control Codes) | 
|  | 1129 | // | 
|  | 1130 | #define ACK_1			0x00000000 | 
|  | 1131 | #define ACK_0_OR_N		0x01000000 | 
|  | 1132 | #define P_RJT			0x02000000 | 
|  | 1133 | #define F_RJT			0x03000000 | 
|  | 1134 | #define P_BSY			0x04000000 | 
|  | 1135 | #define FABRIC_BUSY_TO_DF	0x05000000	// Fabric Busy to Data Frame | 
|  | 1136 | #define FABRIC_BUSY_TO_LC	0x06000000	// Fabric Busy to Link Ctl Frame | 
|  | 1137 | #define LINK_CREDIT_RESET	0x07000000 | 
|  | 1138 | // | 
|  | 1139 | //	(Link Service Command Codes) | 
|  | 1140 | // | 
|  | 1141 | //#define LS_RJT			0x01000000	// LS Reject | 
|  | 1142 |  | 
|  | 1143 | #define LS_ACC			0x02000000	// LS Accept | 
|  | 1144 | #define LS_PLOGI		0x03000000	// N_PORT Login | 
|  | 1145 | #define LS_FLOGI		0x04000000	// F_PORT Login | 
|  | 1146 | #define LS_LOGO			0x05000000	// Logout | 
|  | 1147 | #define LS_ABTX			0x06000000	// Abort Exchange | 
|  | 1148 | #define LS_RCS			0x07000000	// Read Connection Status | 
|  | 1149 | #define LS_RES			0x08000000	// Read Exchange Status | 
|  | 1150 | #define LS_RSS			0x09000000	// Read Sequence Status | 
|  | 1151 | #define LS_RSI			0x0A000000	// Request Seq Initiative | 
|  | 1152 | #define LS_ESTS			0x0B000000	// Establish Steaming | 
|  | 1153 | #define LS_ESTC			0x0C000000	// Estimate Credit | 
|  | 1154 | #define LS_ADVC			0x0D000000	// Advice Credit | 
|  | 1155 | #define LS_RTV			0x0E000000	// Read Timeout Value | 
|  | 1156 | #define LS_RLS			0x0F000000	// Read Link Status | 
|  | 1157 | #define LS_ECHO			0x10000000	// Echo | 
|  | 1158 | #define LS_TEST			0x11000000	// Test | 
|  | 1159 | #define LS_RRQ			0x12000000	// Reinstate Rec. Qual. | 
|  | 1160 | #define LS_PRLI			0x20000000	// Process Login | 
|  | 1161 | #define LS_PRLO			0x21000000	// Process Logout | 
|  | 1162 | #define LS_TPRLO		0x24000000	// 3rd Party Process Logout | 
|  | 1163 | #define LS_PDISC		0x50000000	// Process Discovery | 
|  | 1164 | #define LS_FDISC		0x51000000	// Fabric Discovery | 
|  | 1165 | #define LS_ADISC		0x52000000	// Discover Address | 
|  | 1166 | #define LS_RNC			0x53000000	// Report Node Capability | 
|  | 1167 | #define LS_SCR                  0x62000000      // State Change Registration | 
|  | 1168 | #define LS_MASK			0xFF000000 | 
|  | 1169 |  | 
|  | 1170 | // | 
|  | 1171 | // 	TYPE Bit Masks | 
|  | 1172 | // | 
|  | 1173 | #define BASIC_LINK_SERVICE	0x00000000 | 
|  | 1174 | #define EXT_LINK_SERVICE	0x01000000 | 
|  | 1175 |  | 
|  | 1176 | #define LLC			0x04000000 | 
|  | 1177 | #define LLC_SNAP		0x05000000 | 
|  | 1178 | #define SCSI_FCP		0x08000000 | 
|  | 1179 | #define SCSI_GPP		0x09000000 | 
|  | 1180 | #define IPI3_MASTER		0x11000000 | 
|  | 1181 | #define IPI3_SLAVE		0x12000000 | 
|  | 1182 | #define IPI3_PEER		0x13000000 | 
|  | 1183 | #define CP_IPI3_MASTER		0x15000000 | 
|  | 1184 | #define CP_IPI3_SLAVE		0x16000000 | 
|  | 1185 | #define CP_IPI3_PEER		0x17000000 | 
|  | 1186 | #define SBCCS_CHANNEL		0x19000000 | 
|  | 1187 | #define SBCCS_CONTROL		0x1A000000 | 
|  | 1188 | #define FIBRE_SERVICES		0x20000000 | 
|  | 1189 | #define FC_FG			0x21000000 | 
|  | 1190 | #define FC_XS			0x22000000 | 
|  | 1191 | #define FC_AL			0x23000000 | 
|  | 1192 | #define SNMP			0x24000000 | 
|  | 1193 | #define HIPPI_FP		0x40000000 | 
|  | 1194 | #define TYPE_MASK		0xFF000000 | 
|  | 1195 |  | 
|  | 1196 | typedef struct { | 
|  | 1197 | UCHAR seq_id_valid; | 
|  | 1198 | UCHAR seq_id; | 
|  | 1199 | USHORT reserved;  // 2 bytes reserved | 
|  | 1200 | ULONG ox_rx_id; | 
|  | 1201 | USHORT low_seq_cnt; | 
|  | 1202 | USHORT high_seq_cnt; | 
|  | 1203 | } BA_ACC_PAYLOAD; | 
|  | 1204 |  | 
|  | 1205 | typedef struct { | 
|  | 1206 | UCHAR reserved; | 
|  | 1207 | UCHAR reason_code; | 
|  | 1208 | UCHAR reason_explain; | 
|  | 1209 | UCHAR vendor_unique; | 
|  | 1210 | } BA_RJT_PAYLOAD; | 
|  | 1211 |  | 
|  | 1212 |  | 
|  | 1213 | typedef struct { | 
|  | 1214 | ULONG 	command_code; | 
|  | 1215 | ULONG 	sid; | 
|  | 1216 | USHORT	ox_id; | 
|  | 1217 | USHORT	rx_id; | 
|  | 1218 | } RRQ_MESSAGE; | 
|  | 1219 |  | 
|  | 1220 | typedef struct { | 
|  | 1221 | ULONG command_code; | 
|  | 1222 | UCHAR vendor; | 
|  | 1223 | UCHAR explain; | 
|  | 1224 | UCHAR reason; | 
|  | 1225 | UCHAR reserved; | 
|  | 1226 | } REJECT_MESSAGE; | 
|  | 1227 |  | 
|  | 1228 |  | 
|  | 1229 | #define	N_OR_F_PORT		0x1000 | 
|  | 1230 | #define RANDOM_RELATIVE_OFFSET	0x4000 | 
|  | 1231 | #define CONTINUOSLY_INCREASING	0x8000 | 
|  | 1232 |  | 
|  | 1233 | #define CLASS_VALID		0x8000 | 
|  | 1234 | #define INTERMIX_MODE		0x4000 | 
|  | 1235 | #define TRANSPARENT_STACKED	0x2000 | 
|  | 1236 | #define LOCKDOWN_STACKED	0x1000 | 
|  | 1237 | #define SEQ_DELIVERY		0x800 | 
|  | 1238 |  | 
|  | 1239 | #define XID_NOT_SUPPORTED	0x00 | 
|  | 1240 | #define XID_SUPPORTED		0x4000 | 
|  | 1241 | #define XID_REQUIRED		0xC000 | 
|  | 1242 |  | 
|  | 1243 | #define ASSOCIATOR_NOT_SUPPORTED	0x00 | 
|  | 1244 | #define ASSOCIATOR_SUPPORTED	0x1000 | 
|  | 1245 | #define ASSOCIATOR_REQUIRED	0x3000 | 
|  | 1246 |  | 
|  | 1247 | #define	INIT_ACK0_SUPPORT	0x800 | 
|  | 1248 | #define INIT_ACKN_SUPPORT	0x400 | 
|  | 1249 |  | 
|  | 1250 | #define	RECIP_ACK0_SUPPORT	0x8000 | 
|  | 1251 | #define RECIP_ACKN_SUPPORT	0x4000 | 
|  | 1252 |  | 
|  | 1253 | #define X_ID_INTERLOCK		0x2000 | 
|  | 1254 |  | 
|  | 1255 | #define ERROR_POLICY		0x1800		// Error Policy Supported | 
|  | 1256 | #define ERROR_DISCARD		0x00		// Only Discard Supported | 
|  | 1257 | #define ERROR_DISC_PROCESS	0x02		// Discard and process supported | 
|  | 1258 |  | 
|  | 1259 | #define NODE_ID			0x01 | 
|  | 1260 | #define IEEE_EXT		0x20 | 
|  | 1261 |  | 
|  | 1262 | // | 
|  | 1263 | // Categories Supported Per Sequence | 
|  | 1264 | // | 
|  | 1265 | #define	CATEGORIES_PER_SEQUENCE	0x300 | 
|  | 1266 | #define ONE_CATEGORY_SEQUENCE	0x00		// 1 Category per Sequence | 
|  | 1267 | #define TWO_CATEGORY_SEQUENCE	0x01		// 2 Categories per Sequence | 
|  | 1268 | #define MANY_CATEGORY_SEQUENCE	0x03		// > 2 Categories/Sequence | 
|  | 1269 |  | 
|  | 1270 | typedef struct { | 
|  | 1271 |  | 
|  | 1272 | USHORT initiator_control; | 
|  | 1273 | USHORT service_options; | 
|  | 1274 |  | 
|  | 1275 | USHORT rx_data_size; | 
|  | 1276 | USHORT recipient_control; | 
|  | 1277 |  | 
|  | 1278 | USHORT ee_credit; | 
|  | 1279 | USHORT concurrent_sequences; | 
|  | 1280 |  | 
|  | 1281 | USHORT reserved; | 
|  | 1282 | USHORT open_sequences; | 
|  | 1283 |  | 
|  | 1284 | } CLASS_PARAMETERS; | 
|  | 1285 |  | 
|  | 1286 | typedef struct { | 
|  | 1287 | ULONG	login_cmd; | 
|  | 1288 | // | 
|  | 1289 | // Common Service Parameters | 
|  | 1290 | // | 
|  | 1291 | struct { | 
|  | 1292 |  | 
|  | 1293 | USHORT bb_credit; | 
|  | 1294 | UCHAR lowest_ver; | 
|  | 1295 | UCHAR highest_ver; | 
|  | 1296 |  | 
|  | 1297 | USHORT bb_rx_size; | 
|  | 1298 | USHORT common_features; | 
|  | 1299 |  | 
|  | 1300 | USHORT rel_offset; | 
|  | 1301 | USHORT concurrent_seq; | 
|  | 1302 |  | 
|  | 1303 |  | 
|  | 1304 | ULONG e_d_tov; | 
|  | 1305 | } cmn_services; | 
|  | 1306 |  | 
|  | 1307 | // | 
|  | 1308 | // Port Name | 
|  | 1309 | // | 
|  | 1310 | UCHAR port_name[8]; | 
|  | 1311 |  | 
|  | 1312 | // | 
|  | 1313 | // Node/Fabric Name | 
|  | 1314 | // | 
|  | 1315 | UCHAR node_name[8]; | 
|  | 1316 |  | 
|  | 1317 | // | 
|  | 1318 | // Class 1, 2 and 3 Service Parameters | 
|  | 1319 | // | 
|  | 1320 | CLASS_PARAMETERS	class1; | 
|  | 1321 | CLASS_PARAMETERS	class2; | 
|  | 1322 | CLASS_PARAMETERS	class3; | 
|  | 1323 |  | 
|  | 1324 | ULONG reserved[4]; | 
|  | 1325 |  | 
|  | 1326 | // | 
|  | 1327 | // Vendor Version Level | 
|  | 1328 | // | 
|  | 1329 | UCHAR		vendor_id[2]; | 
|  | 1330 | UCHAR		vendor_version[6]; | 
|  | 1331 | ULONG		buffer_size; | 
|  | 1332 | USHORT		rxid_start; | 
|  | 1333 | USHORT		total_rxids; | 
|  | 1334 | } LOGIN_PAYLOAD; | 
|  | 1335 |  | 
|  | 1336 |  | 
|  | 1337 | typedef struct | 
|  | 1338 | { | 
|  | 1339 | ULONG cmd;  // 4 bytes | 
|  | 1340 | UCHAR n_port_identifier[3]; | 
|  | 1341 | UCHAR reserved; | 
|  | 1342 | UCHAR port_name[8]; | 
|  | 1343 | } LOGOUT_PAYLOAD; | 
|  | 1344 |  | 
|  | 1345 |  | 
|  | 1346 | // | 
|  | 1347 | //	PRLI Request Service Parameter Defines | 
|  | 1348 | // | 
|  | 1349 | #define PRLI_ACC			0x01 | 
|  | 1350 | #define PRLI_REQ			0x02 | 
|  | 1351 | #define ORIG_PROCESS_ASSOC_VALID	0x8000 | 
|  | 1352 | #define RESP_PROCESS_ASSOC_VALID	0x4000 | 
|  | 1353 | #define ESTABLISH_PAIR			0x2000 | 
|  | 1354 | #define DATA_OVERLAY_ALLOWED		0x40 | 
|  | 1355 | #define	INITIATOR_FUNCTION		0x20 | 
|  | 1356 | #define	TARGET_FUNCTION			0x10 | 
|  | 1357 | #define CMD_DATA_MIXED			0x08 | 
|  | 1358 | #define DATA_RESP_MIXED			0x04 | 
|  | 1359 | #define READ_XFER_RDY			0x02 | 
|  | 1360 | #define WRITE_XFER_RDY			0x01 | 
|  | 1361 |  | 
|  | 1362 | #define RESPONSE_CODE_MASK	0xF00 | 
|  | 1363 | #define REQUEST_EXECUTED	0x100 | 
|  | 1364 | #define NO_RESOURCES		0x200 | 
|  | 1365 | #define INIT_NOT_COMPLETE	0x300 | 
|  | 1366 | #define IMAGE_DOES_NOT_EXIST	0x400 | 
|  | 1367 | #define BAD_PREDEFINED_COND	0x500 | 
|  | 1368 | #define REQ_EXEC_COND		0x600 | 
|  | 1369 | #define NO_MULTI_PAGE		0x700 | 
|  | 1370 |  | 
|  | 1371 | typedef struct { | 
|  | 1372 | USHORT	payload_length; | 
|  | 1373 | UCHAR	page_length; | 
|  | 1374 | UCHAR	cmd; | 
|  | 1375 |  | 
|  | 1376 |  | 
|  | 1377 | ULONG	valid; | 
|  | 1378 |  | 
|  | 1379 | ULONG	orig_process_associator; | 
|  | 1380 |  | 
|  | 1381 | ULONG	resp_process_associator; | 
|  | 1382 |  | 
|  | 1383 | ULONG	fcp_info; | 
|  | 1384 | } PRLI_REQUEST; | 
|  | 1385 |  | 
|  | 1386 | typedef struct { | 
|  | 1387 |  | 
|  | 1388 | USHORT	payload_length; | 
|  | 1389 | UCHAR	page_length; | 
|  | 1390 | UCHAR	cmd; | 
|  | 1391 |  | 
|  | 1392 | ULONG	valid; | 
|  | 1393 | ULONG	orig_process_associator; | 
|  | 1394 |  | 
|  | 1395 | ULONG	resp_process_associator; | 
|  | 1396 | ULONG	reserved; | 
|  | 1397 | } PRLO_REQUEST; | 
|  | 1398 |  | 
|  | 1399 | typedef struct { | 
|  | 1400 | ULONG	cmd; | 
|  | 1401 |  | 
|  | 1402 | ULONG	hard_address; | 
|  | 1403 |  | 
|  | 1404 | UCHAR	port_name[8]; | 
|  | 1405 |  | 
|  | 1406 | UCHAR	node_name[8]; | 
|  | 1407 |  | 
|  | 1408 | ULONG	s_id; | 
|  | 1409 | } ADISC_PAYLOAD; | 
|  | 1410 |  | 
|  | 1411 | struct ext_sg_entry_t { | 
|  | 1412 | __u32 len:18;		/* buffer length, bits 0-17 */ | 
|  | 1413 | __u32 uba:13;		/* upper bus address bits 18-31 */ | 
|  | 1414 | __u32 lba;		/* lower bus address bits 0-31 */ | 
|  | 1415 | }; | 
|  | 1416 |  | 
|  | 1417 |  | 
|  | 1418 | // J. McCarty's LINK.H | 
|  | 1419 | // | 
|  | 1420 | //	LS_RJT Reason Codes | 
|  | 1421 | // | 
|  | 1422 |  | 
|  | 1423 | #define INVALID_COMMAND_CODE	0x01 | 
|  | 1424 | #define LOGICAL_ERROR		0x03 | 
|  | 1425 | #define LOGICAL_BUSY		0x05 | 
|  | 1426 | #define PROTOCOL_ERROR		0x07 | 
|  | 1427 | #define UNABLE_TO_PERFORM	0x09 | 
|  | 1428 | #define COMMAND_NOT_SUPPORTED	0x0B | 
|  | 1429 | #define LS_VENDOR_UNIQUE	0xFF | 
|  | 1430 |  | 
|  | 1431 | // | 
|  | 1432 | // 	LS_RJT Reason Codes Explanations | 
|  | 1433 | // | 
|  | 1434 | #define NO_REASON		0x00 | 
|  | 1435 | #define OPTIONS_ERROR		0x01 | 
|  | 1436 | #define INITIATOR_CTL_ERROR	0x03 | 
|  | 1437 | #define RECIPIENT_CTL_ERROR	0x05 | 
|  | 1438 | #define DATA_FIELD_SIZE_ERROR	0x07 | 
|  | 1439 | #define CONCURRENT_SEQ_ERROR	0x09 | 
|  | 1440 | #define CREDIT_ERROR		0x0B | 
|  | 1441 | #define INVALID_PORT_NAME	0x0D | 
|  | 1442 | #define INVALID_NODE_NAME	0x0E | 
|  | 1443 | #define INVALID_CSP		0x0F	// Invalid Service Parameters | 
|  | 1444 | #define INVALID_ASSOC_HDR	0x11	// Invalid Association Header | 
|  | 1445 | #define ASSOC_HDR_REQUIRED	0x13	// Association Header Required | 
|  | 1446 | #define LS_INVALID_S_ID		0x15 | 
|  | 1447 | #define INVALID_OX_RX_ID	0x17	// Invalid OX_ID RX_ID Combination | 
|  | 1448 | #define CMD_IN_PROCESS		0x19 | 
|  | 1449 | #define INVALID_IDENTIFIER	0x1F	// Invalid N_PORT Identifier | 
|  | 1450 | #define INVALID_SEQ_ID		0x21 | 
|  | 1451 | #define ABT_INVALID_XCHNG	0x23 	// Attempt to Abort an invalid Exchange | 
|  | 1452 | #define ABT_INACTIVE_XCHNG	0x25 	// Attempt to Abort an inactive Exchange | 
|  | 1453 | #define NEED_REC_QUAL		0x27	// Recovery Qualifier required | 
|  | 1454 | #define NO_LOGIN_RESOURCES	0x29	// No resources to support login | 
|  | 1455 | #define NO_DATA			0x2A	// Unable to supply requested data | 
|  | 1456 | #define	REQUEST_NOT_SUPPORTED	0x2C	// Request Not Supported | 
|  | 1457 |  | 
|  | 1458 | // | 
|  | 1459 | //	Link Control Codes | 
|  | 1460 | // | 
|  | 1461 |  | 
|  | 1462 | // | 
|  | 1463 | //	P_BSY Action Codes | 
|  | 1464 | // | 
|  | 1465 | #define SEQUENCE_TERMINATED	0x01000000 | 
|  | 1466 | #define SEQUENCE_ACTIVE		0x02000000 | 
|  | 1467 |  | 
|  | 1468 | // | 
|  | 1469 | //	P_BSY Reason Codes | 
|  | 1470 | // | 
|  | 1471 | #define PHYS_NPORT_BUSY		0x010000 | 
|  | 1472 | #define NPORT_RESOURCE_BUSY	0x020000 | 
|  | 1473 |  | 
|  | 1474 | // | 
|  | 1475 | // 	P_RJT, F_RJT Action Codes | 
|  | 1476 | // | 
|  | 1477 |  | 
|  | 1478 | #define RETRYABLE_ERROR		0x01000000 | 
|  | 1479 | #define NON_RETRYABLE_ERROR	0x02000000 | 
|  | 1480 |  | 
|  | 1481 | // | 
|  | 1482 | // 	P_RJT, F_RJT Reason Codes | 
|  | 1483 | // | 
|  | 1484 | #define INVALID_D_ID		0x010000 | 
|  | 1485 | #define INVALID_S_ID		0x020000 | 
|  | 1486 | #define NPORT_NOT_AVAIL_TMP	0x030000 | 
|  | 1487 | #define NPORT_NOT_AVAIL_PERM	0x040000 | 
|  | 1488 | #define CLASS_NOT_SUPPORTED	0x050000 | 
|  | 1489 | #define USAGE_ERROR		0x060000 | 
|  | 1490 | #define TYPE_NOT_SUPPORTED	0x070000 | 
|  | 1491 | #define INVAL_LINK_CONTROL	0x080000 | 
|  | 1492 | #define INVAL_R_CTL		0x090000 | 
|  | 1493 | #define INVAL_F_CTL		0x0A0000 | 
|  | 1494 | #define INVAL_OX_ID		0x0B0000 | 
|  | 1495 | #define INVAL_RX_ID		0x0C0000 | 
|  | 1496 | #define INVAL_SEQ_ID		0x0D0000 | 
|  | 1497 | #define INVAL_DF_CTL		0x0E0000 | 
|  | 1498 | #define INVAL_SEQ_CNT		0x0F0000 | 
|  | 1499 | #define INVAL_PARAMS		0x100000 | 
|  | 1500 | #define EXCHANGE_ERROR		0x110000 | 
|  | 1501 | #define LS_PROTOCOL_ERROR	0x120000 | 
|  | 1502 | #define INCORRECT_LENGTH	0x130000 | 
|  | 1503 | #define UNEXPECTED_ACK		0x140000 | 
|  | 1504 | #define LOGIN_REQ		0x160000 | 
|  | 1505 | #define EXCESSIVE_SEQ		0x170000 | 
|  | 1506 | #define NO_EXCHANGE		0x180000 | 
|  | 1507 | #define SEC_HDR_NOT_SUPPORTED	0x190000 | 
|  | 1508 | #define NO_FABRIC		0x1A0000 | 
|  | 1509 | #define P_VENDOR_UNIQUE		0xFF0000 | 
|  | 1510 |  | 
|  | 1511 | // | 
|  | 1512 | // 	BA_RJT Reason Codes | 
|  | 1513 | // | 
|  | 1514 | #define BA_INVALID_COMMAND	0x00010000 | 
|  | 1515 | #define BA_LOGICAL_ERROR	0x00030000 | 
|  | 1516 | #define BA_LOGICAL_BUSY		0x00050000 | 
|  | 1517 | #define BA_PROTOCOL_ERROR	0x00070000 | 
|  | 1518 | #define BA_UNABLE_TO_PERFORM	0x00090000 | 
|  | 1519 |  | 
|  | 1520 | // | 
|  | 1521 | // 	BA_RJT Reason Explanation Codes | 
|  | 1522 | // | 
|  | 1523 | #define BA_NO_REASON		0x00000000 | 
|  | 1524 | #define BA_INVALID_OX_RX	0x00000300 | 
|  | 1525 | #define BA_SEQUENCE_ABORTED	0x00000500 | 
|  | 1526 |  | 
|  | 1527 |  | 
|  | 1528 |  | 
|  | 1529 | #endif /* CPQFCTSSTRUCTS_H	*/ | 
|  | 1530 |  |