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