[SCSI] drivers/scsi/FlashPoint.c: remove UINT
[deliverable/linux.git] / drivers / scsi / FlashPoint.c
CommitLineData
1da177e4
LT
1/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
1da177e4
LT
25#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
1da177e4
LT
29
30
1da177e4 31
1da177e4
LT
32
33
1da177e4 34
1da177e4
LT
35
36#define CRCMASK 0xA001
37
1da177e4
LT
38
39
1da177e4
LT
40#define FAILURE 0xFFFFFFFFL
41
42
1da177e4 43typedef unsigned long ULONG;
1da177e4
LT
44
45
1da177e4 46typedef unsigned short * ushort_ptr;
1da177e4 47
1da177e4
LT
48
49#define s08bits char
50#define s16bits short
51#define s32bits long
52
53#define u08bits unsigned s08bits
54#define u16bits unsigned s16bits
55#define u32bits unsigned s32bits
56
1da177e4 57
1da177e4 58
db038cf8 59#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
c823feeb 60#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
1da177e4
LT
61
62
63
1da177e4 64
47b5d69c
JB
65typedef struct _SCCB *PSCCB;
66typedef void (*CALL_BK_FN)(PSCCB);
1da177e4
LT
67
68
69typedef struct SCCBMgr_info {
70 ULONG si_baseaddr;
db038cf8
AD
71 unsigned char si_present;
72 unsigned char si_intvect;
73 unsigned char si_id;
74 unsigned char si_lun;
c823feeb
AD
75 unsigned short si_fw_revision;
76 unsigned short si_per_targ_init_sync;
77 unsigned short si_per_targ_fast_nego;
78 unsigned short si_per_targ_ultra_nego;
79 unsigned short si_per_targ_no_disc;
80 unsigned short si_per_targ_wide_nego;
81 unsigned short si_flags;
db038cf8
AD
82 unsigned char si_card_family;
83 unsigned char si_bustype;
84 unsigned char si_card_model[3];
85 unsigned char si_relative_cardnum;
86 unsigned char si_reserved[4];
1da177e4 87 ULONG si_OS_reserved;
db038cf8 88 unsigned char si_XlatInfo[4];
1da177e4
LT
89 ULONG si_reserved2[5];
90 ULONG si_secondary_range;
91} SCCBMGR_INFO;
92
47b5d69c 93typedef SCCBMGR_INFO * PSCCBMGR_INFO;
1da177e4
LT
94
95
47b5d69c
JB
96#define SCSI_PARITY_ENA 0x0001
97#define LOW_BYTE_TERM 0x0010
98#define HIGH_BYTE_TERM 0x0020
99#define BUSTYPE_PCI 0x3
1da177e4
LT
100
101#define SUPPORT_16TAR_32LUN 0x0002
102#define SOFT_RESET 0x0004
103#define EXTENDED_TRANSLATION 0x0008
104#define POST_ALL_UNDERRRUNS 0x0040
105#define FLAG_SCAM_ENABLED 0x0080
106#define FLAG_SCAM_LEVEL2 0x0100
107
108
109
110
111#define HARPOON_FAMILY 0x02
112
113
1da177e4 114
32357988 115/* SCCB struct used for both SCCB and UCB manager compiles!
1da177e4
LT
116 * The UCB Manager treats the SCCB as it's 'native hardware structure'
117 */
118
119
120#pragma pack(1)
121typedef struct _SCCB {
db038cf8
AD
122 unsigned char OperationCode;
123 unsigned char ControlByte;
124 unsigned char CdbLength;
125 unsigned char RequestSenseLength;
1da177e4
LT
126 ULONG DataLength;
127 ULONG DataPointer;
db038cf8
AD
128 unsigned char CcbRes[2];
129 unsigned char HostStatus;
130 unsigned char TargetStatus;
131 unsigned char TargID;
132 unsigned char Lun;
133 unsigned char Cdb[12];
134 unsigned char CcbRes1;
135 unsigned char Reserved1;
1da177e4
LT
136 ULONG Reserved2;
137 ULONG SensePointer;
138
139
140 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
141 ULONG SccbIOPort; /* Identifies board base port */
db038cf8
AD
142 unsigned char SccbStatus;
143 unsigned char SCCBRes2;
c823feeb 144 unsigned short SccbOSFlags;
1da177e4
LT
145
146
147 ULONG Sccb_XferCnt; /* actual transfer count */
148 ULONG Sccb_ATC;
149 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
150 ULONG Sccb_res1;
c823feeb
AD
151 unsigned short Sccb_MGRFlags;
152 unsigned short Sccb_sgseg;
db038cf8
AD
153 unsigned char Sccb_scsimsg; /* identify msg for selection */
154 unsigned char Sccb_tag;
155 unsigned char Sccb_scsistat;
156 unsigned char Sccb_idmsg; /* image of last msg in */
1da177e4
LT
157 PSCCB Sccb_forwardlink;
158 PSCCB Sccb_backlink;
159 ULONG Sccb_savedATC;
db038cf8
AD
160 unsigned char Save_Cdb[6];
161 unsigned char Save_CdbLen;
162 unsigned char Sccb_XferState;
1da177e4 163 ULONG Sccb_SGoffset;
1da177e4
LT
164 } SCCB;
165
1da177e4
LT
166
167#pragma pack()
168
169
170
1da177e4
LT
171#define SCATTER_GATHER_COMMAND 0x02
172#define RESIDUAL_COMMAND 0x03
173#define RESIDUAL_SG_COMMAND 0x04
174#define RESET_COMMAND 0x81
175
176
177#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
178#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
1da177e4
LT
179#define SCCB_DATA_XFER_OUT 0x10 /* Write */
180#define SCCB_DATA_XFER_IN 0x08 /* Read */
181
182
1da177e4
LT
183#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
184
185
186#define BUS_FREE_ST 0
187#define SELECT_ST 1
188#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
189#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
190#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
191#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
192#define COMMAND_ST 6
193#define DATA_OUT_ST 7
194#define DATA_IN_ST 8
195#define DISCONNECT_ST 9
1da177e4 196#define ABORT_ST 11
1da177e4
LT
197
198
199#define F_HOST_XFER_DIR 0x01
200#define F_ALL_XFERRED 0x02
201#define F_SG_XFER 0x04
202#define F_AUTO_SENSE 0x08
203#define F_ODD_BALL_CNT 0x10
204#define F_NO_DATA_YET 0x80
205
206
207#define F_STATUSLOADED 0x01
1da177e4
LT
208#define F_DEV_SELECTED 0x04
209
210
211#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
212#define SCCB_DATA_UNDER_RUN 0x0C
213#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
214#define SCCB_DATA_OVER_RUN 0x12
1da177e4
LT
215#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
216
1da177e4
LT
217#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
218#define SCCB_BM_ERR 0x30 /* BusMaster error. */
219#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
220
221
222
1da177e4
LT
223
224
225#define SCCB_IN_PROCESS 0x00
226#define SCCB_SUCCESS 0x01
227#define SCCB_ABORT 0x02
1da177e4 228#define SCCB_ERROR 0x04
1da177e4 229
1da177e4
LT
230
231
1da177e4
LT
232#define ORION_FW_REV 3110
233
1da177e4
LT
234
235
1da177e4 236#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
1da177e4
LT
237
238#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
239
1da177e4 240
47b5d69c
JB
241#define MAX_SCSI_TAR 16
242#define MAX_LUN 32
243#define LUN_MASK 0x1f
1da177e4 244
1da177e4 245#define SG_BUF_CNT 16 /*Number of prefetched elements. */
1da177e4
LT
246
247#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
1da177e4
LT
248
249
d8b6b8bd
AD
250#define RD_HARPOON(ioport) inb((u32bits)ioport)
251#define RDW_HARPOON(ioport) inw((u32bits)ioport)
252#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
253#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
254#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
255#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
1da177e4
LT
256
257
258#define TAR_SYNC_MASK (BIT(7)+BIT(6))
1da177e4
LT
259#define SYNC_TRYING BIT(6)
260#define SYNC_SUPPORTED (BIT(7)+BIT(6))
261
262#define TAR_WIDE_MASK (BIT(5)+BIT(4))
1da177e4
LT
263#define WIDE_ENABLED BIT(4)
264#define WIDE_NEGOCIATED BIT(5)
265
266#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
1da177e4
LT
267#define TAG_Q_TRYING BIT(2)
268#define TAG_Q_REJECT BIT(3)
1da177e4
LT
269
270#define TAR_ALLOW_DISC BIT(0)
271
272
273#define EE_SYNC_MASK (BIT(0)+BIT(1))
1da177e4
LT
274#define EE_SYNC_5MB BIT(0)
275#define EE_SYNC_10MB BIT(1)
276#define EE_SYNC_20MB (BIT(0)+BIT(1))
277
1da177e4
LT
278#define EE_WIDE_SCSI BIT(7)
279
280
47b5d69c 281typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
1da177e4
LT
282
283
284typedef struct SCCBMgr_tar_info {
285
286 PSCCB TarSelQ_Head;
287 PSCCB TarSelQ_Tail;
db038cf8
AD
288 unsigned char TarLUN_CA; /*Contingent Allgiance */
289 unsigned char TarTagQ_Cnt;
290 unsigned char TarSelQ_Cnt;
291 unsigned char TarStatus;
292 unsigned char TarEEValue;
293 unsigned char TarSyncCtrl;
294 unsigned char TarReserved[2]; /* for alignment */
295 unsigned char LunDiscQ_Idx[MAX_LUN];
296 unsigned char TarLUNBusy[MAX_LUN];
1da177e4
LT
297} SCCBMGR_TAR_INFO;
298
299typedef struct NVRAMInfo {
db038cf8
AD
300 unsigned char niModel; /* Model No. of card */
301 unsigned char niCardNo; /* Card no. */
1da177e4 302 ULONG niBaseAddr; /* Port Address of card */
db038cf8
AD
303 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
304 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
305 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
306 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
307 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
308 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
1da177e4
LT
309}NVRAMINFO;
310
1da177e4 311typedef NVRAMINFO *PNVRamInfo;
1da177e4
LT
312
313#define MODEL_LT 1
314#define MODEL_DL 2
315#define MODEL_LW 3
316#define MODEL_DW 4
317
318
319typedef struct SCCBcard {
320 PSCCB currentSCCB;
1da177e4 321 PSCCBMGR_INFO cardInfo;
1da177e4 322
1da177e4 323 ULONG ioPort;
1da177e4 324
c823feeb 325 unsigned short cmdCounter;
db038cf8
AD
326 unsigned char discQCount;
327 unsigned char tagQ_Lst;
328 unsigned char cardIndex;
329 unsigned char scanIndex;
330 unsigned char globalFlags;
331 unsigned char ourId;
1da177e4
LT
332 PNVRamInfo pNvRamInfo;
333 PSCCB discQ_Tbl[QUEUE_DEPTH];
334
335}SCCBCARD;
336
1da177e4 337typedef struct SCCBcard *PSCCBcard;
1da177e4
LT
338
339
340#define F_TAG_STARTED 0x01
341#define F_CONLUN_IO 0x02
342#define F_DO_RENEGO 0x04
343#define F_NO_FILTER 0x08
344#define F_GREEN_PC 0x10
345#define F_HOST_XFER_ACT 0x20
346#define F_NEW_SCCB_CMD 0x40
347#define F_UPDATE_EEPROM 0x80
348
349
350#define ID_STRING_LENGTH 32
351#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
352
1da177e4
LT
353
354#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
355
356#define ASSIGN_ID 0x00
357#define SET_P_FLAG 0x01
358#define CFG_CMPLT 0x03
359#define DOM_MSTR 0x0F
360#define SYNC_PTRN 0x1F
361
362#define ID_0_7 0x18
363#define ID_8_F 0x11
1da177e4
LT
364#define MISC_CODE 0x14
365#define CLR_P_FLAG 0x18
1da177e4 366
1da177e4
LT
367
368
369#define INIT_SELTD 0x01
370#define LEVEL2_TAR 0x02
371
372
373enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
374 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
375 CLR_PRIORITY,NO_ID_AVAIL };
376
377typedef struct SCCBscam_info {
378
db038cf8 379 unsigned char id_string[ID_STRING_LENGTH];
1da177e4
LT
380 enum scam_id_st state;
381
85ae97d8 382} SCCBSCAM_INFO;
1da177e4 383
1da177e4 384
1da177e4 385#define SCSI_REQUEST_SENSE 0x03
1da177e4
LT
386#define SCSI_READ 0x08
387#define SCSI_WRITE 0x0A
1da177e4 388#define SCSI_START_STOP_UNIT 0x1B
1da177e4
LT
389#define SCSI_READ_EXTENDED 0x28
390#define SCSI_WRITE_EXTENDED 0x2A
1da177e4 391#define SCSI_WRITE_AND_VERIFY 0x2E
1da177e4
LT
392
393
394
395#define SSGOOD 0x00
396#define SSCHECK 0x02
1da177e4
LT
397#define SSQ_FULL 0x28
398
399
1da177e4
LT
400
401
402#define SMCMD_COMP 0x00
403#define SMEXT 0x01
404#define SMSAVE_DATA_PTR 0x02
405#define SMREST_DATA_PTR 0x03
406#define SMDISC 0x04
1da177e4
LT
407#define SMABORT 0x06
408#define SMREJECT 0x07
409#define SMNO_OP 0x08
410#define SMPARITY 0x09
411#define SMDEV_RESET 0x0C
412#define SMABORT_TAG 0x0D
413#define SMINIT_RECOVERY 0x0F
414#define SMREL_RECOVERY 0x10
415
416#define SMIDENT 0x80
417#define DISC_PRIV 0x40
418
419
420#define SMSYNC 0x01
1da177e4
LT
421#define SMWDTR 0x03
422#define SM8BIT 0x00
423#define SM16BIT 0x01
1da177e4
LT
424#define SMIGNORWR 0x23 /* Ignore Wide Residue */
425
426
1da177e4
LT
427
428
429
1da177e4
LT
430
431
432
433#define SIX_BYTE_CMD 0x06
1da177e4
LT
434#define TWELVE_BYTE_CMD 0x0C
435
436#define ASYNC 0x00
1da177e4
LT
437#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
438
1da177e4
LT
439
440#define EEPROM_WD_CNT 256
441
442#define EEPROM_CHECK_SUM 0
443#define FW_SIGNATURE 2
444#define MODEL_NUMB_0 4
1da177e4 445#define MODEL_NUMB_2 6
1da177e4 446#define MODEL_NUMB_4 8
1da177e4
LT
447#define SYSTEM_CONFIG 16
448#define SCSI_CONFIG 17
449#define BIOS_CONFIG 18
1da177e4
LT
450#define SCAM_CONFIG 20
451#define ADAPTER_SCSI_ID 24
452
453
454#define IGNORE_B_SCAN 32
455#define SEND_START_ENA 34
456#define DEVICE_ENABLE 36
457
458#define SYNC_RATE_TBL 38
459#define SYNC_RATE_TBL01 38
460#define SYNC_RATE_TBL23 40
461#define SYNC_RATE_TBL45 42
462#define SYNC_RATE_TBL67 44
463#define SYNC_RATE_TBL89 46
464#define SYNC_RATE_TBLab 48
465#define SYNC_RATE_TBLcd 50
466#define SYNC_RATE_TBLef 52
467
468
469
470#define EE_SCAMBASE 256
471
472
473
1da177e4
LT
474 #define SCAM_ENABLED BIT(2)
475 #define SCAM_LEVEL2 BIT(3)
476
477
478 #define RENEGO_ENA BITW(10)
479 #define CONNIO_ENA BITW(11)
480 #define GREEN_PC_ENA BITW(12)
481
482
483 #define AUTO_RATE_00 00
484 #define AUTO_RATE_05 01
485 #define AUTO_RATE_10 02
486 #define AUTO_RATE_20 03
487
488 #define WIDE_NEGO_BIT BIT(7)
489 #define DISC_ENABLE_BIT BIT(6)
490
491
1da177e4
LT
492
493 #define hp_vendor_id_0 0x00 /* LSB */
494 #define ORION_VEND_0 0x4B
495
496 #define hp_vendor_id_1 0x01 /* MSB */
497 #define ORION_VEND_1 0x10
498
499 #define hp_device_id_0 0x02 /* LSB */
500 #define ORION_DEV_0 0x30
501
502 #define hp_device_id_1 0x03 /* MSB */
503 #define ORION_DEV_1 0x81
504
505 /* Sub Vendor ID and Sub Device ID only available in
506 Harpoon Version 2 and higher */
507
1da177e4 508 #define hp_sub_device_id_0 0x06 /* LSB */
1da177e4
LT
509
510
1da177e4
LT
511
512 #define hp_semaphore 0x0C
513 #define SCCB_MGR_ACTIVE BIT(0)
514 #define TICKLE_ME BIT(1)
515 #define SCCB_MGR_PRESENT BIT(3)
516 #define BIOS_IN_USE BIT(4)
517
1da177e4 518
1da177e4
LT
519
520 #define hp_sys_ctrl 0x0F
521
522 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
523 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
524 #define HALT_MACH BIT(3) /*Halt State Machine */
525 #define HARD_ABORT BIT(4) /*Hard Abort */
1da177e4 526
1da177e4 527
1da177e4 528
1da177e4
LT
529
530
1da177e4 531
1da177e4 532
1da177e4 533
1da177e4
LT
534
535 #define hp_host_blk_cnt 0x13
536
1da177e4
LT
537 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
538
539 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
540
541
1da177e4
LT
542
543 #define hp_int_mask 0x17
544
545 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
546 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
1da177e4
LT
547
548
549 #define hp_xfer_cnt_lo 0x18
1da177e4
LT
550 #define hp_xfer_cnt_hi 0x1A
551 #define hp_xfer_cmd 0x1B
552
553 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
554 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
1da177e4
LT
555
556
557 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
1da177e4
LT
558
559 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
1da177e4
LT
560
561 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
562
563 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
564 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
1da177e4
LT
565
566 #define hp_host_addr_lo 0x1C
1da177e4 567 #define hp_host_addr_hmi 0x1E
1da177e4 568
1da177e4
LT
569 #define hp_ee_ctrl 0x22
570
571 #define EXT_ARB_ACK BIT(7)
572 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
573 #define SEE_MS BIT(5)
574 #define SEE_CS BIT(3)
575 #define SEE_CLK BIT(2)
576 #define SEE_DO BIT(1)
577 #define SEE_DI BIT(0)
578
579 #define EE_READ 0x06
580 #define EE_WRITE 0x05
581 #define EWEN 0x04
582 #define EWEN_ADDR 0x03C0
583 #define EWDS 0x04
584 #define EWDS_ADDR 0x0000
585
1da177e4 586
1da177e4 587
1da177e4
LT
588
589
590
591
592 #define hp_bm_ctrl 0x26
593
594 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
595 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
1da177e4
LT
596 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
597 #define FAST_SINGLE BIT(6) /*?? */
598
599 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
600
1da177e4
LT
601
602 #define hp_sg_addr 0x28
603 #define hp_page_ctrl 0x29
604
605 #define SCATTER_EN BIT(0)
606 #define SGRAM_ARAM BIT(1)
1da177e4
LT
607 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
608 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
609
1da177e4 610
1da177e4 611
1da177e4
LT
612
613 #define hp_pci_stat_cfg 0x2D
614
1da177e4 615 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
1da177e4 616
1da177e4 617
1da177e4 618
1da177e4 619
1da177e4 620
1da177e4 621
1da177e4 622
1da177e4
LT
623
624 #define hp_rev_num 0x33
625
1da177e4
LT
626
627 #define hp_stack_data 0x34
628 #define hp_stack_addr 0x35
629
630 #define hp_ext_status 0x36
631
632 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
633 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
634 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
1da177e4
LT
635 #define CMD_ABORTED BIT(4) /*Command aborted */
636 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
637 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
638 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
639 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
640 BM_PARITY_ERR | PIO_OVERRUN)
641
642 #define hp_int_status 0x37
643
1da177e4
LT
644 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
645 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
1da177e4 646 #define INT_ASSERTED BIT(5) /* */
1da177e4
LT
647
648
649 #define hp_fifo_cnt 0x38
1da177e4 650
1da177e4
LT
651
652
653
1da177e4
LT
654 #define hp_intena 0x40
655
656 #define RESET BITW(7)
657 #define PROG_HLT BITW(6)
658 #define PARITY BITW(5)
659 #define FIFO BITW(4)
660 #define SEL BITW(3)
661 #define SCAM_SEL BITW(2)
662 #define RSEL BITW(1)
663 #define TIMEOUT BITW(0)
664 #define BUS_FREE BITW(15)
665 #define XFER_CNT_0 BITW(14)
666 #define PHASE BITW(13)
667 #define IUNKWN BITW(12)
668 #define ICMD_COMP BITW(11)
669 #define ITICKLE BITW(10)
670 #define IDO_STRT BITW(9)
671 #define ITAR_DISC BITW(8)
672 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
673 #define CLR_ALL_INT 0xFFFF
674 #define CLR_ALL_INT_1 0xFF00
675
676 #define hp_intstat 0x42
677
678 #define hp_scsisig 0x44
679
680 #define SCSI_SEL BIT(7)
681 #define SCSI_BSY BIT(6)
682 #define SCSI_REQ BIT(5)
683 #define SCSI_ACK BIT(4)
684 #define SCSI_ATN BIT(3)
685 #define SCSI_CD BIT(2)
686 #define SCSI_MSG BIT(1)
687 #define SCSI_IOBIT BIT(0)
688
689 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
1da177e4 690 #define S_MSGO_PH (BIT(2)+BIT(1) )
1da177e4
LT
691 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
692 #define S_DATAI_PH ( BIT(0))
693 #define S_DATAO_PH 0x00
694 #define S_ILL_PH ( BIT(1) )
695
696 #define hp_scsictrl_0 0x45
697
1da177e4
LT
698 #define SEL_TAR BIT(6)
699 #define ENA_ATN BIT(4)
700 #define ENA_RESEL BIT(2)
701 #define SCSI_RST BIT(1)
702 #define ENA_SCAM_SEL BIT(0)
703
704
705
706 #define hp_portctrl_0 0x46
707
708 #define SCSI_PORT BIT(7)
709 #define SCSI_INBIT BIT(6)
710 #define DMA_PORT BIT(5)
711 #define DMA_RD BIT(4)
712 #define HOST_PORT BIT(3)
713 #define HOST_WRT BIT(2)
714 #define SCSI_BUS_EN BIT(1)
715 #define START_TO BIT(0)
716
717 #define hp_scsireset 0x47
718
1da177e4
LT
719 #define SCSI_INI BIT(6)
720 #define SCAM_EN BIT(5)
1da177e4
LT
721 #define DMA_RESET BIT(3)
722 #define HPSCSI_RESET BIT(2)
723 #define PROG_RESET BIT(1)
724 #define FIFO_CLR BIT(0)
725
726 #define hp_xfercnt_0 0x48
1da177e4 727 #define hp_xfercnt_2 0x4A
1da177e4
LT
728
729 #define hp_fifodata_0 0x4C
1da177e4
LT
730 #define hp_addstat 0x4E
731
732 #define SCAM_TIMER BIT(7)
1da177e4
LT
733 #define SCSI_MODE8 BIT(3)
734 #define SCSI_PAR_ERR BIT(0)
735
736 #define hp_prgmcnt_0 0x4F
737
1da177e4
LT
738
739 #define hp_selfid_0 0x50
740 #define hp_selfid_1 0x51
741 #define hp_arb_id 0x52
742
1da177e4
LT
743
744 #define hp_select_id 0x53
745
1da177e4
LT
746
747 #define hp_synctarg_base 0x54
748 #define hp_synctarg_12 0x54
749 #define hp_synctarg_13 0x55
750 #define hp_synctarg_14 0x56
751 #define hp_synctarg_15 0x57
752
753 #define hp_synctarg_8 0x58
754 #define hp_synctarg_9 0x59
755 #define hp_synctarg_10 0x5A
756 #define hp_synctarg_11 0x5B
757
758 #define hp_synctarg_4 0x5C
759 #define hp_synctarg_5 0x5D
760 #define hp_synctarg_6 0x5E
761 #define hp_synctarg_7 0x5F
762
763 #define hp_synctarg_0 0x60
764 #define hp_synctarg_1 0x61
765 #define hp_synctarg_2 0x62
766 #define hp_synctarg_3 0x63
767
1da177e4 768 #define NARROW_SCSI BIT(4)
1da177e4
LT
769 #define DEFAULT_OFFSET 0x0F
770
771 #define hp_autostart_0 0x64
772 #define hp_autostart_1 0x65
1da177e4
LT
773 #define hp_autostart_3 0x67
774
775
776
1da177e4
LT
777 #define AUTO_IMMED BIT(5)
778 #define SELECT BIT(6)
1da177e4 779 #define END_DATA (BIT(7)+BIT(6))
1da177e4
LT
780
781 #define hp_gp_reg_0 0x68
782 #define hp_gp_reg_1 0x69
1da177e4
LT
783 #define hp_gp_reg_3 0x6B
784
785 #define hp_seltimeout 0x6C
786
787
1da177e4
LT
788 #define TO_4ms 0x67 /* 3.9959ms */
789
790 #define TO_5ms 0x03 /* 4.9152ms */
791 #define TO_10ms 0x07 /* 11.xxxms */
792 #define TO_250ms 0x99 /* 250.68ms */
793 #define TO_290ms 0xB1 /* 289.99ms */
1da177e4
LT
794
795 #define hp_clkctrl_0 0x6D
796
797 #define PWR_DWN BIT(6)
798 #define ACTdeassert BIT(4)
1da177e4 799 #define CLK_40MHZ (BIT(1) + BIT(0))
1da177e4
LT
800
801 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
802
803 #define hp_fiforead 0x6E
804 #define hp_fifowrite 0x6F
805
806 #define hp_offsetctr 0x70
807 #define hp_xferstat 0x71
808
1da177e4 809 #define FIFO_EMPTY BIT(6)
1da177e4
LT
810
811 #define hp_portctrl_1 0x72
812
1da177e4
LT
813 #define CHK_SCSI_P BIT(3)
814 #define HOST_MODE8 BIT(0)
1da177e4
LT
815
816 #define hp_xfer_pad 0x73
817
818 #define ID_UNLOCK BIT(3)
1da177e4
LT
819
820 #define hp_scsidata_0 0x74
821 #define hp_scsidata_1 0x75
1da177e4 822
1da177e4 823
1da177e4
LT
824
825 #define hp_aramBase 0x80
826 #define BIOS_DATA_OFFSET 0x60
827 #define BIOS_RELATIVE_CARD 0x64
828
829
830
831
1da177e4
LT
832 #define AR3 (BITW(9) + BITW(8))
833 #define SDATA BITW(10)
834
1da177e4
LT
835
836 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
837
838 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
839
1da177e4 840
1da177e4
LT
841
842 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
843
844 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
845
846
847 #define ADATA_OUT 0x00
848 #define ADATA_IN BITW(8)
849 #define ACOMMAND BITW(10)
850 #define ASTATUS (BITW(10)+BITW(8))
851 #define AMSG_OUT (BITW(10)+BITW(9))
852 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
1da177e4
LT
853
854
855 #define BRH_OP BITW(13) /* Branch */
856
857
858 #define ALWAYS 0x00
859 #define EQUAL BITW(8)
860 #define NOT_EQ BITW(9)
861
862 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
863
864
1da177e4 865 #define FIFO_0 BITW(10)
1da177e4
LT
866
867
868 #define MPM_OP BITW(15) /* Match phase and move data */
869
1da177e4
LT
870
871 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
872
873
874 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
875
876
877 #define D_AR0 0x00
878 #define D_AR1 BIT(0)
1da177e4
LT
879 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
880
881
1da177e4 882
1da177e4 883
1da177e4 884
1da177e4 885
1da177e4 886
1da177e4
LT
887
888
889 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
890
891 #define SSI_OP (BITW(15)+BITW(11))
892
893
894 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
895 #define SSI_IDO_STRT (IDO_STRT >> 8)
1da177e4
LT
896
897 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
898 #define SSI_ITICKLE (ITICKLE >> 8)
899
900 #define SSI_IUNKWN (IUNKWN >> 8)
901 #define SSI_INO_CC (IUNKWN >> 8)
902 #define SSI_IRFAIL (IUNKWN >> 8)
903
904
905 #define NP 0x10 /*Next Phase */
906 #define NTCMD 0x02 /*Non- Tagged Command start */
907 #define CMDPZ 0x04 /*Command phase */
908 #define DINT 0x12 /*Data Out/In interrupt */
909 #define DI 0x13 /*Data Out */
1da177e4
LT
910 #define DC 0x19 /*Disconnect Message */
911 #define ST 0x1D /*Status Phase */
912 #define UNKNWN 0x24 /*Unknown bus action */
913 #define CC 0x25 /*Command Completion failure */
914 #define TICK 0x26 /*New target reselected us. */
1da177e4
LT
915 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
916
917
918 #define ID_MSG_STRT hp_aramBase + 0x00
919 #define NON_TAG_ID_MSG hp_aramBase + 0x06
920 #define CMD_STRT hp_aramBase + 0x08
921 #define SYNC_MSGS hp_aramBase + 0x08
922
923
924
925
926
927 #define TAG_STRT 0x00
1da177e4
LT
928 #define DISCONNECT_START 0x10/2
929 #define END_DATA_START 0x14/2
1da177e4 930 #define CMD_ONLY_STRT CMDPZ/2
1da177e4
LT
931 #define SELCHK_STRT SELCHK/2
932
933
934
935
1da177e4 936
1da177e4
LT
937
938
1da177e4 939
1da177e4
LT
940
941#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
942/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
943 xfercnt <<= 16,\
c823feeb 944 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
1da177e4 945 */
c823feeb 946#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
1da177e4 947 addr >>= 16,\
c823feeb 948 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
1da177e4 949 WR_HARP32(port,hp_xfercnt_0,count),\
c823feeb 950 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
1da177e4
LT
951 count >>= 16,\
952 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
1da177e4
LT
953
954#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
955 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
956
957
958#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
959 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
960
1da177e4 961
1da177e4
LT
962
963#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
964 WR_HARPOON(port+hp_scsireset, 0x00))
965
966#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
967 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
968
969#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
970 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
971
972#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
973 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
974
975#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
976 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
977
978
979
1da177e4 980
db038cf8
AD
981static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
982static void FPT_ssel(ULONG port, unsigned char p_card);
983static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
984static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
985static void FPT_stsyncn(ULONG port, unsigned char p_card);
986static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
987static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
47b5d69c 988 PSCCBMgr_tar_info currTar_Info);
db038cf8
AD
989static void FPT_sresb(ULONG port, unsigned char p_card);
990static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
991static void FPT_schkdd(ULONG port, unsigned char p_card);
992static unsigned char FPT_RdStack(ULONG port, unsigned char index);
993static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
994static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
995
996static void FPT_SendMsg(ULONG port, unsigned char message);
997static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
998 unsigned char error_code);
999
1000static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
47b5d69c 1001static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1da177e4 1002
db038cf8
AD
1003static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1004static void FPT_stwidn(ULONG port, unsigned char p_card);
1005static void FPT_siwidr(ULONG port, unsigned char width);
1da177e4
LT
1006
1007
db038cf8
AD
1008static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1009static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
47b5d69c 1010static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
db038cf8
AD
1011 unsigned char p_card);
1012static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1013static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1014static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1015static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
47b5d69c 1016static void FPT_utilUpdateResidual(PSCCB p_SCCB);
c823feeb 1017static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
db038cf8 1018static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1da177e4 1019
1da177e4 1020
47b5d69c 1021static void FPT_Wait1Second(ULONG p_port);
db038cf8
AD
1022static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1023static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
c823feeb
AD
1024static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr);
1025static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr);
1026static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr);
1027static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr);
1da177e4
LT
1028
1029
1da177e4 1030
db038cf8
AD
1031static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1032static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1033static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1034static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1035static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1036static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1037static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
1da177e4 1038
db038cf8
AD
1039static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1040static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1041static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
1da177e4 1042
1da177e4 1043
1da177e4 1044
1da177e4 1045
db038cf8 1046static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
47b5d69c
JB
1047static void FPT_BusMasterInit(ULONG p_port);
1048static void FPT_DiagEEPROM(ULONG p_port);
1da177e4 1049
1da177e4 1050
1da177e4
LT
1051
1052
47b5d69c
JB
1053static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1054static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1055static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
db038cf8 1056static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
47b5d69c 1057static void FPT_hostDataXferRestart(PSCCB currSCCB);
1da177e4 1058
1da177e4 1059
db038cf8 1060static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
c823feeb 1061 PSCCBcard pCurrCard, unsigned short p_int);
1da177e4 1062
47b5d69c 1063static void FPT_SccbMgrTableInitAll(void);
db038cf8
AD
1064static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1065static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1da177e4 1066
1da177e4
LT
1067
1068
db038cf8 1069static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1da177e4 1070
db038cf8 1071static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
47b5d69c
JB
1072static void FPT_scbusf(ULONG p_port);
1073static void FPT_scsel(ULONG p_port);
db038cf8
AD
1074static void FPT_scasid(unsigned char p_card, ULONG p_port);
1075static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1076static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1077static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1078static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1079static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1080static unsigned char FPT_scvalq(unsigned char p_quintet);
1081static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
47b5d69c 1082static void FPT_scwtsel(ULONG p_port);
db038cf8
AD
1083static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1084static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1085static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1da177e4 1086
1da177e4 1087
db038cf8 1088static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
47b5d69c 1089static void FPT_autoLoadDefaultMap(ULONG p_port);
1da177e4
LT
1090
1091
1092
1da177e4 1093
47b5d69c
JB
1094static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1095static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1096static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1097static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1da177e4 1098
1da177e4 1099
db038cf8
AD
1100static unsigned char FPT_mbCards = 0;
1101static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
47b5d69c
JB
1102 ' ', 'B', 'T', '-', '9', '3', '0', \
1103 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1104 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1da177e4 1105
c823feeb 1106static unsigned short FPT_default_intena = 0;
1da177e4
LT
1107
1108
db038cf8 1109static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
1da177e4 1110
1da177e4
LT
1111
1112/*---------------------------------------------------------------------
1113 *
d8b6b8bd 1114 * Function: FlashPoint_ProbeHostAdapter
1da177e4
LT
1115 *
1116 * Description: Setup and/or Search for cards and return info to caller.
1117 *
1118 *---------------------------------------------------------------------*/
1119
d8b6b8bd 1120static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1da177e4 1121{
db038cf8 1122 static unsigned char first_time = 1;
1da177e4 1123
db038cf8 1124 unsigned char i,j,id,ScamFlg;
c823feeb 1125 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1da177e4 1126 ULONG ioport;
1da177e4
LT
1127 PNVRamInfo pCurrNvRam;
1128
1da177e4 1129 ioport = pCardInfo->si_baseaddr;
1da177e4
LT
1130
1131
1132 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1133 return((int)FAILURE);
1134
1135 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1136 return((int)FAILURE);
1137
1138 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1139 return((int)FAILURE);
1140
1141 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1142 return((int)FAILURE);
1143
1144
1145 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1146
1147/* For new Harpoon then check for sub_device ID LSB
1148 the bits(0-3) must be all ZERO for compatible with
1149 current version of SCCBMgr, else skip this Harpoon
1150 device. */
1151
1152 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1153 return((int)FAILURE);
1154 }
1155
1156 if (first_time)
1157 {
47b5d69c 1158 FPT_SccbMgrTableInitAll();
1da177e4 1159 first_time = 0;
47b5d69c 1160 FPT_mbCards = 0;
1da177e4
LT
1161 }
1162
47b5d69c
JB
1163 if(FPT_RdStack(ioport, 0) != 0x00) {
1164 if(FPT_ChkIfChipInitialized(ioport) == 0)
1da177e4
LT
1165 {
1166 pCurrNvRam = NULL;
1167 WR_HARPOON(ioport+hp_semaphore, 0x00);
47b5d69c
JB
1168 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1169 FPT_DiagEEPROM(ioport);
1da177e4
LT
1170 }
1171 else
1172 {
47b5d69c
JB
1173 if(FPT_mbCards < MAX_MB_CARDS) {
1174 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1175 FPT_mbCards++;
1da177e4 1176 pCurrNvRam->niBaseAddr = ioport;
47b5d69c 1177 FPT_RNVRamData(pCurrNvRam);
1da177e4
LT
1178 }else
1179 return((int) FAILURE);
1180 }
1181 }else
1182 pCurrNvRam = NULL;
1da177e4
LT
1183
1184 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1185 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1186
1187 if(pCurrNvRam)
1188 pCardInfo->si_id = pCurrNvRam->niAdapId;
1189 else
db038cf8
AD
1190 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1191 (unsigned char)0x0FF);
1da177e4
LT
1192
1193 pCardInfo->si_lun = 0x00;
1194 pCardInfo->si_fw_revision = ORION_FW_REV;
1195 temp2 = 0x0000;
1196 temp3 = 0x0000;
1197 temp4 = 0x0000;
1198 temp5 = 0x0000;
1199 temp6 = 0x0000;
1200
1201 for (id = 0; id < (16/2); id++) {
1202
1203 if(pCurrNvRam){
c823feeb 1204 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1da177e4
LT
1205 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1206 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1207 }else
c823feeb 1208 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1da177e4
LT
1209
1210 for (i = 0; i < 2; temp >>=8,i++) {
1211
1212 temp2 >>= 1;
1213 temp3 >>= 1;
1214 temp4 >>= 1;
1215 temp5 >>= 1;
1216 temp6 >>= 1;
1217 switch (temp & 0x3)
1218 {
1219 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1220 temp6 |= 0x8000; /* Fall through */
1221 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1222 temp5 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1224 temp2 |= 0x8000; /* Fall through */
1225 case AUTO_RATE_00: /* Asynchronous */
1226 break;
1227 }
1228
1229 if (temp & DISC_ENABLE_BIT)
1230 temp3 |= 0x8000;
1231
1232 if (temp & WIDE_NEGO_BIT)
1233 temp4 |= 0x8000;
1234
1235 }
1236 }
1237
1238 pCardInfo->si_per_targ_init_sync = temp2;
1239 pCardInfo->si_per_targ_no_disc = temp3;
1240 pCardInfo->si_per_targ_wide_nego = temp4;
1241 pCardInfo->si_per_targ_fast_nego = temp5;
1242 pCardInfo->si_per_targ_ultra_nego = temp6;
1243
1244 if(pCurrNvRam)
1245 i = pCurrNvRam->niSysConf;
1246 else
db038cf8 1247 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1da177e4
LT
1248
1249 if(pCurrNvRam)
1250 ScamFlg = pCurrNvRam->niScamConf;
1251 else
db038cf8 1252 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1da177e4
LT
1253
1254 pCardInfo->si_flags = 0x0000;
1255
1256 if (i & 0x01)
1257 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1258
1259 if (!(i & 0x02))
1260 pCardInfo->si_flags |= SOFT_RESET;
1261
1262 if (i & 0x10)
1263 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1264
1265 if (ScamFlg & SCAM_ENABLED)
1266 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1267
1268 if (ScamFlg & SCAM_LEVEL2)
1269 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1270
1271 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1272 if (i & 0x04) {
1273 j |= SCSI_TERM_ENA_L;
1274 }
1275 WR_HARPOON(ioport+hp_bm_ctrl, j );
1276
1277 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1278 if (i & 0x08) {
1279 j |= SCSI_TERM_ENA_H;
1280 }
1281 WR_HARPOON(ioport+hp_ee_ctrl, j );
1282
1283 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1284
1285 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1286
1287 pCardInfo->si_card_family = HARPOON_FAMILY;
1288 pCardInfo->si_bustype = BUSTYPE_PCI;
1289
1290 if(pCurrNvRam){
1291 pCardInfo->si_card_model[0] = '9';
1292 switch(pCurrNvRam->niModel & 0x0f){
1293 case MODEL_LT:
1294 pCardInfo->si_card_model[1] = '3';
1295 pCardInfo->si_card_model[2] = '0';
1296 break;
1297 case MODEL_LW:
1298 pCardInfo->si_card_model[1] = '5';
1299 pCardInfo->si_card_model[2] = '0';
1300 break;
1301 case MODEL_DL:
1302 pCardInfo->si_card_model[1] = '3';
1303 pCardInfo->si_card_model[2] = '2';
1304 break;
1305 case MODEL_DW:
1306 pCardInfo->si_card_model[1] = '5';
1307 pCardInfo->si_card_model[2] = '2';
1308 break;
1309 }
1310 }else{
47b5d69c 1311 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
db038cf8 1312 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
47b5d69c 1313 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1da177e4 1314
db038cf8
AD
1315 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1316 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1da177e4
LT
1317 }
1318
1319 if (pCardInfo->si_card_model[1] == '3')
1320 {
1321 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1322 pCardInfo->si_flags |= LOW_BYTE_TERM;
1323 }
1324 else if (pCardInfo->si_card_model[2] == '0')
1325 {
1326 temp = RD_HARPOON(ioport+hp_xfer_pad);
1327 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1328 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1329 pCardInfo->si_flags |= LOW_BYTE_TERM;
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1331 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1332 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1333 WR_HARPOON(ioport+hp_xfer_pad, temp);
1334 }
1335 else
1336 {
1337 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1338 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1339 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1340 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1341 temp3 = 0;
1342 for (i = 0; i < 8; i++)
1343 {
1344 temp3 <<= 1;
1345 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1346 temp3 |= 1;
1347 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1348 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1349 }
1350 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1351 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1352 if (!(temp3 & BIT(7)))
1353 pCardInfo->si_flags |= LOW_BYTE_TERM;
1354 if (!(temp3 & BIT(6)))
1355 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1356 }
1357
1358
1359 ARAM_ACCESS(ioport);
1360
1361 for ( i = 0; i < 4; i++ ) {
1362
1363 pCardInfo->si_XlatInfo[i] =
1364 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1365 }
1366
1367 /* return with -1 if no sort, else return with
1368 logical card number sorted by BIOS (zero-based) */
1369
1370 pCardInfo->si_relative_cardnum =
db038cf8 1371 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1da177e4
LT
1372
1373 SGRAM_ACCESS(ioport);
1374
47b5d69c
JB
1375 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1376 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1377 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1378 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1379 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1380 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1381 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1382 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1da177e4
LT
1383
1384 pCardInfo->si_present = 0x01;
1385
1da177e4
LT
1386 return(0);
1387}
1388
1389
1390/*---------------------------------------------------------------------
1391 *
d8b6b8bd 1392 * Function: FlashPoint_HardwareResetHostAdapter
1da177e4
LT
1393 *
1394 * Description: Setup adapter for normal operation (hard reset).
1395 *
1396 *---------------------------------------------------------------------*/
1397
d8b6b8bd 1398static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1da177e4
LT
1399{
1400 PSCCBcard CurrCard = NULL;
1401 PNVRamInfo pCurrNvRam;
db038cf8 1402 unsigned char i,j,thisCard, ScamFlg;
c823feeb 1403 unsigned short temp,sync_bit_map,id;
1da177e4 1404 ULONG ioport;
1da177e4 1405
1da177e4 1406 ioport = pCardInfo->si_baseaddr;
1da177e4
LT
1407
1408 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1409
1410 if (thisCard == MAX_CARDS) {
1411
1412 return(FAILURE);
1413 }
1414
47b5d69c 1415 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1da177e4 1416
47b5d69c
JB
1417 CurrCard = &FPT_BL_Card[thisCard];
1418 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1da177e4
LT
1419 break;
1420 }
1421
47b5d69c 1422 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1da177e4 1423
47b5d69c
JB
1424 FPT_BL_Card[thisCard].ioPort = ioport;
1425 CurrCard = &FPT_BL_Card[thisCard];
1da177e4 1426
47b5d69c
JB
1427 if(FPT_mbCards)
1428 for(i = 0; i < FPT_mbCards; i++){
1429 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1430 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1da177e4 1431 }
47b5d69c 1432 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1da177e4
LT
1433 CurrCard->cardIndex = thisCard;
1434 CurrCard->cardInfo = pCardInfo;
1435
1436 break;
1437 }
1438 }
1439
1440 pCurrNvRam = CurrCard->pNvRamInfo;
1441
1442 if(pCurrNvRam){
1443 ScamFlg = pCurrNvRam->niScamConf;
1444 }
1445 else{
db038cf8 1446 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1da177e4
LT
1447 }
1448
1449
47b5d69c
JB
1450 FPT_BusMasterInit(ioport);
1451 FPT_XbowInit(ioport, ScamFlg);
1da177e4 1452
47b5d69c 1453 FPT_autoLoadDefaultMap(ioport);
1da177e4
LT
1454
1455
1456 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1457
1458 WR_HARPOON(ioport+hp_selfid_0, id);
1459 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1460 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1461 CurrCard->ourId = pCardInfo->si_id;
1462
db038cf8 1463 i = (unsigned char) pCardInfo->si_flags;
1da177e4
LT
1464 if (i & SCSI_PARITY_ENA)
1465 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1466
1467 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1468 if (i & LOW_BYTE_TERM)
1469 j |= SCSI_TERM_ENA_L;
1470 WR_HARPOON(ioport+hp_bm_ctrl, j);
1471
1472 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1473 if (i & HIGH_BYTE_TERM)
1474 j |= SCSI_TERM_ENA_H;
1475 WR_HARPOON(ioport+hp_ee_ctrl, j );
1476
1477
1478 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1479
47b5d69c 1480 FPT_sresb(ioport,thisCard);
1da177e4 1481
47b5d69c 1482 FPT_scini(thisCard, pCardInfo->si_id, 0);
1da177e4 1483 }
1da177e4 1484
1da177e4 1485
1da177e4 1486
47b5d69c
JB
1487 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1488 CurrCard->globalFlags |= F_NO_FILTER;
1da177e4 1489
47b5d69c
JB
1490 if(pCurrNvRam){
1491 if(pCurrNvRam->niSysConf & 0x10)
1492 CurrCard->globalFlags |= F_GREEN_PC;
1493 }
1494 else{
1495 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1496 CurrCard->globalFlags |= F_GREEN_PC;
1497 }
1da177e4 1498
47b5d69c
JB
1499 /* Set global flag to indicate Re-Negotiation to be done on all
1500 ckeck condition */
1501 if(pCurrNvRam){
1502 if(pCurrNvRam->niScsiConf & 0x04)
1503 CurrCard->globalFlags |= F_DO_RENEGO;
1504 }
1505 else{
1506 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1507 CurrCard->globalFlags |= F_DO_RENEGO;
1508 }
1da177e4 1509
47b5d69c
JB
1510 if(pCurrNvRam){
1511 if(pCurrNvRam->niScsiConf & 0x08)
1512 CurrCard->globalFlags |= F_CONLUN_IO;
1513 }
1514 else{
1515 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1516 CurrCard->globalFlags |= F_CONLUN_IO;
1da177e4
LT
1517 }
1518
1da177e4 1519
47b5d69c 1520 temp = pCardInfo->si_per_targ_no_disc;
1da177e4 1521
47b5d69c 1522 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1da177e4 1523
47b5d69c
JB
1524 if (temp & id)
1525 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1526 }
1da177e4 1527
47b5d69c 1528 sync_bit_map = 0x0001;
1da177e4 1529
47b5d69c 1530 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1da177e4 1531
47b5d69c 1532 if(pCurrNvRam){
c823feeb 1533 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
47b5d69c
JB
1534 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1535 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1536 }else
c823feeb 1537 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1da177e4 1538
47b5d69c 1539 for (i = 0; i < 2; temp >>=8,i++) {
1da177e4 1540
47b5d69c 1541 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1da177e4 1542
db038cf8 1543 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
47b5d69c 1544 }
1da177e4 1545
47b5d69c
JB
1546 else {
1547 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1548 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
db038cf8 1549 (unsigned char)(temp & ~EE_SYNC_MASK);
47b5d69c 1550 }
1da177e4 1551
47b5d69c
JB
1552/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1553 (id*2+i >= 8)){
1554*/
1555 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1da177e4 1556
47b5d69c 1557 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1da177e4 1558
47b5d69c 1559 }
1da177e4 1560
47b5d69c
JB
1561 else { /* NARROW SCSI */
1562 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1563 }
1da177e4 1564
1da177e4 1565
47b5d69c 1566 sync_bit_map <<= 1;
1da177e4 1567
1da177e4 1568
1da177e4 1569
47b5d69c
JB
1570 }
1571 }
1da177e4 1572
47b5d69c 1573 WR_HARPOON((ioport+hp_semaphore),
db038cf8 1574 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1da177e4 1575
47b5d69c
JB
1576 return((ULONG)CurrCard);
1577}
1578
d8b6b8bd 1579static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
1da177e4 1580{
db038cf8 1581 unsigned char i;
1da177e4
LT
1582 ULONG portBase;
1583 ULONG regOffset;
1da177e4 1584 ULONG scamData;
1da177e4 1585 ULONG *pScamTbl;
1da177e4
LT
1586 PNVRamInfo pCurrNvRam;
1587
1588 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1589
1590 if(pCurrNvRam){
47b5d69c
JB
1591 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1da177e4
LT
1596
1597 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
db038cf8 1598 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1da177e4
LT
1599
1600 portBase = pCurrNvRam->niBaseAddr;
1601
1602 for(i = 0; i < MAX_SCSI_TAR; i++){
1603 regOffset = hp_aramBase + 64 + i*4;
1da177e4 1604 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1da177e4
LT
1605 scamData = *pScamTbl;
1606 WR_HARP32(portBase, regOffset, scamData);
1607 }
1608
1609 }else{
47b5d69c 1610 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1da177e4
LT
1611 }
1612}
1da177e4
LT
1613
1614
47b5d69c 1615static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1da177e4 1616{
db038cf8 1617 unsigned char i;
1da177e4
LT
1618 ULONG portBase;
1619 ULONG regOffset;
1da177e4 1620 ULONG scamData;
1da177e4 1621 ULONG *pScamTbl;
1da177e4 1622
47b5d69c
JB
1623 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1624 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1625 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1626 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1627 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1da177e4
LT
1628
1629 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
db038cf8 1630 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1da177e4
LT
1631
1632 portBase = pNvRamInfo->niBaseAddr;
1633
1634 for(i = 0; i < MAX_SCSI_TAR; i++){
1635 regOffset = hp_aramBase + 64 + i*4;
1636 RD_HARP32(portBase, regOffset, scamData);
1da177e4 1637 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1da177e4
LT
1638 *pScamTbl = scamData;
1639 }
1640
1641}
1642
db038cf8 1643static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
1da177e4
LT
1644{
1645 WR_HARPOON(portBase + hp_stack_addr, index);
1646 return(RD_HARPOON(portBase + hp_stack_data));
1647}
1648
db038cf8 1649static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
1da177e4
LT
1650{
1651 WR_HARPOON(portBase + hp_stack_addr, index);
1652 WR_HARPOON(portBase + hp_stack_data, data);
1653}
1654
1655
db038cf8 1656static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
1da177e4 1657{
47b5d69c
JB
1658 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1659 return(0);
1da177e4
LT
1660 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1661 != CLKCTRL_DEFAULT)
47b5d69c 1662 return(0);
1da177e4
LT
1663 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1664 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
47b5d69c
JB
1665 return(1);
1666 return(0);
1da177e4
LT
1667
1668}
1669/*---------------------------------------------------------------------
1670 *
d8b6b8bd 1671 * Function: FlashPoint_StartCCB
1da177e4
LT
1672 *
1673 * Description: Start a command pointed to by p_Sccb. When the
1674 * command is completed it will be returned via the
1675 * callback function.
1676 *
1677 *---------------------------------------------------------------------*/
d8b6b8bd 1678static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
1da177e4 1679{
1da177e4 1680 ULONG ioport;
db038cf8 1681 unsigned char thisCard, lun;
1da177e4
LT
1682 PSCCB pSaveSccb;
1683 CALL_BK_FN callback;
1684
1da177e4
LT
1685 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1686 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1687
1da177e4
LT
1688 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1689 {
1690
1da177e4
LT
1691 p_Sccb->HostStatus = SCCB_COMPLETE;
1692 p_Sccb->SccbStatus = SCCB_ERROR;
1693 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1694 if (callback)
1695 callback(p_Sccb);
1da177e4 1696
1da177e4
LT
1697 return;
1698 }
1699
47b5d69c 1700 FPT_sinits(p_Sccb,thisCard);
1da177e4
LT
1701
1702
1703 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1704 {
1705 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1706 | SCCB_MGR_ACTIVE));
1707
1708 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1709 {
1710 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1711 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1712 }
1713 }
1714
1715 ((PSCCBcard)pCurrCard)->cmdCounter++;
1716
1717 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1718
1719 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1720 | TICKLE_ME));
1721 if(p_Sccb->OperationCode == RESET_COMMAND)
1722 {
1723 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1724 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1725 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1726 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1727 }
1728 else
1729 {
47b5d69c 1730 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1731 }
1732 }
1733
1734 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1735
1736 if(p_Sccb->OperationCode == RESET_COMMAND)
1737 {
1738 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1739 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1740 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1741 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1742 }
1743 else
1744 {
47b5d69c 1745 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1746 }
1747 }
1748
1749 else {
1750
1751 MDISABLE_INT(ioport);
1752
1753 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
47b5d69c 1754 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1da177e4
LT
1755 lun = p_Sccb->Lun;
1756 else
1757 lun = 0;
1758 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
47b5d69c
JB
1759 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1760 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1761 == 0)) {
1da177e4
LT
1762
1763 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1764 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1da177e4
LT
1765 }
1766
1767 else {
1768
1769 if(p_Sccb->OperationCode == RESET_COMMAND)
1770 {
1771 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1772 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1773 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1774 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1775 }
1776 else
1777 {
47b5d69c 1778 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1779 }
1780 }
1781
1782
1783 MENABLE_INT(ioport);
1784 }
1785
1da177e4
LT
1786}
1787
1788
1789/*---------------------------------------------------------------------
1790 *
d8b6b8bd 1791 * Function: FlashPoint_AbortCCB
1da177e4
LT
1792 *
1793 * Description: Abort the command pointed to by p_Sccb. When the
1794 * command is completed it will be returned via the
1795 * callback function.
1796 *
1797 *---------------------------------------------------------------------*/
d8b6b8bd 1798static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
1da177e4 1799{
1da177e4 1800 ULONG ioport;
1da177e4 1801
db038cf8 1802 unsigned char thisCard;
1da177e4 1803 CALL_BK_FN callback;
db038cf8 1804 unsigned char TID;
1da177e4
LT
1805 PSCCB pSaveSCCB;
1806 PSCCBMgr_tar_info currTar_Info;
1807
1808
1da177e4
LT
1809 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1810
1811 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1812
47b5d69c 1813 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1da177e4
LT
1814 {
1815
47b5d69c 1816 if (FPT_queueFindSccb(p_Sccb,thisCard))
1da177e4
LT
1817 {
1818
1da177e4
LT
1819 ((PSCCBcard)pCurrCard)->cmdCounter--;
1820
1821 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1822 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
db038cf8 1823 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1da177e4 1824
1da177e4
LT
1825 p_Sccb->SccbStatus = SCCB_ABORT;
1826 callback = p_Sccb->SccbCallback;
1827 callback(p_Sccb);
1da177e4
LT
1828
1829 return(0);
1830 }
1831
1832 else
1833 {
1da177e4
LT
1834 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1835 {
1836 p_Sccb->SccbStatus = SCCB_ABORT;
1837 return(0);
1838
1839 }
1840
1841 else
1842 {
1843
1844 TID = p_Sccb->TargID;
1845
1846
1847 if(p_Sccb->Sccb_tag)
1848 {
1849 MDISABLE_INT(ioport);
1850 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1851 {
1852 p_Sccb->SccbStatus = SCCB_ABORT;
1853 p_Sccb->Sccb_scsistat = ABORT_ST;
1da177e4
LT
1854 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1855
1856 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1857 {
1858 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1859 FPT_ssel(ioport, thisCard);
1da177e4
LT
1860 }
1861 else
1862 {
1863 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1864 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1865 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1da177e4
LT
1866 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1867 }
1868 }
1869 MENABLE_INT(ioport);
1870 return(0);
1871 }
1872 else
1873 {
47b5d69c 1874 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1da177e4 1875
47b5d69c 1876 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1da177e4
LT
1877 == p_Sccb)
1878 {
1879 p_Sccb->SccbStatus = SCCB_ABORT;
1880 return(0);
1881 }
1882 }
1883 }
1884 }
1885 }
1886 return(-1);
1887}
1888
1889
1890/*---------------------------------------------------------------------
1891 *
d8b6b8bd 1892 * Function: FlashPoint_InterruptPending
1da177e4
LT
1893 *
1894 * Description: Do a quick check to determine if there is a pending
1895 * interrupt for this card and disable the IRQ Pin if so.
1896 *
1897 *---------------------------------------------------------------------*/
db038cf8 1898static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
1da177e4 1899{
1da177e4 1900 ULONG ioport;
1da177e4
LT
1901
1902 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1903
1904 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1905 {
47b5d69c 1906 return(1);
1da177e4
LT
1907 }
1908
1909 else
1910
47b5d69c 1911 return(0);
1da177e4
LT
1912}
1913
1914
1915
1916/*---------------------------------------------------------------------
1917 *
d8b6b8bd 1918 * Function: FlashPoint_HandleInterrupt
1da177e4
LT
1919 *
1920 * Description: This is our entry point when an interrupt is generated
1921 * by the card and the upper level driver passes it on to
1922 * us.
1923 *
1924 *---------------------------------------------------------------------*/
d8b6b8bd 1925static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
1da177e4
LT
1926{
1927 PSCCB currSCCB;
db038cf8 1928 unsigned char thisCard,result,bm_status, bm_int_st;
c823feeb 1929 unsigned short hp_int;
db038cf8 1930 unsigned char i, target;
1da177e4 1931 ULONG ioport;
1da177e4
LT
1932
1933 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1934 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1935
1936 MDISABLE_INT(ioport);
1937
1da177e4 1938 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
db038cf8 1939 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1da177e4
LT
1940 else
1941 bm_status = 0;
1942
1943 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1944
47b5d69c 1945 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1da177e4
LT
1946 bm_status)
1947 {
1948
1949 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1950
1da177e4 1951 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
47b5d69c 1952 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1da177e4
LT
1953 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1954 bm_status = 0;
1955
1956 if (result) {
1957
1da177e4 1958 MENABLE_INT(ioport);
1da177e4
LT
1959 return(result);
1960 }
1961 }
1962
1963
1964 else if (hp_int & ICMD_COMP) {
1965
1966 if ( !(hp_int & BUS_FREE) ) {
1967 /* Wait for the BusFree before starting a new command. We
1968 must also check for being reselected since the BusFree
1969 may not show up if another device reselects us in 1.5us or
1970 less. SRR Wednesday, 3/8/1995.
1971 */
1972 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1973 }
1974
1975 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1976
47b5d69c 1977 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
1978
1979/* WRW_HARPOON((ioport+hp_intstat),
1980 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1981 */
1982
1983 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1984
47b5d69c 1985 FPT_autoCmdCmplt(ioport,thisCard);
1da177e4
LT
1986
1987 }
1988
1989
1990 else if (hp_int & ITAR_DISC)
1991 {
1992
1993 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1994
47b5d69c 1995 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
1996
1997 }
1998
1999 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2000
2001 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2002 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2003
2004 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2005 }
2006
2007 currSCCB->Sccb_scsistat = DISCONNECT_ST;
47b5d69c 2008 FPT_queueDisconnect(currSCCB,thisCard);
1da177e4
LT
2009
2010 /* Wait for the BusFree before starting a new command. We
2011 must also check for being reselected since the BusFree
2012 may not show up if another device reselects us in 1.5us or
2013 less. SRR Wednesday, 3/8/1995.
2014 */
2015 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2016 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2017 RD_HARPOON((ioport+hp_scsisig)) ==
2018 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2019
2020 /*
2021 The additional loop exit condition above detects a timing problem
2022 with the revision D/E harpoon chips. The caller should reset the
2023 host adapter to recover when 0xFE is returned.
2024 */
2025 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2026 {
1da177e4 2027 MENABLE_INT(ioport);
1da177e4
LT
2028 return 0xFE;
2029 }
2030
2031 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2032
2033
2034 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2035
2036 }
2037
2038
2039 else if (hp_int & RSEL) {
2040
2041 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2042
2043 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2044 {
2045 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2046 {
47b5d69c 2047 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
2048 }
2049
2050 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2051 {
2052 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2053 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2054 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2055 }
2056
2057 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2058 currSCCB->Sccb_scsistat = DISCONNECT_ST;
47b5d69c 2059 FPT_queueDisconnect(currSCCB,thisCard);
1da177e4
LT
2060 }
2061
47b5d69c
JB
2062 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2063 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2064
2065 }
2066
2067
2068 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2069 {
2070
2071 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
47b5d69c 2072 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2073
2074 }
2075
2076
2077 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2078 {
2079 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
db038cf8 2080 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
1da177e4 2081 {
47b5d69c 2082 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2083 }
2084 else
2085 {
2086 /* Harpoon problem some SCSI target device respond to selection
2087 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2088 to latch the correct Target ID into reg. x53.
2089 The work around require to correct this reg. But when write to this
2090 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2091 need to read this reg first then restore it later. After update to 0x53 */
2092
db038cf8
AD
2093 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2094 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2095 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2096 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2097 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
1da177e4
LT
2098 WR_HARPOON(ioport+hp_fifowrite, i);
2099 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2100 }
2101 }
2102
2103 else if (hp_int & XFER_CNT_0) {
2104
2105 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2106
47b5d69c 2107 FPT_schkdd(ioport,thisCard);
1da177e4
LT
2108
2109 }
2110
2111
2112 else if (hp_int & BUS_FREE) {
2113
2114 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2115
2116 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2117
47b5d69c 2118 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
1da177e4
LT
2119 }
2120
47b5d69c 2121 FPT_phaseBusFree(ioport,thisCard);
1da177e4
LT
2122 }
2123
2124
2125 else if (hp_int & ITICKLE) {
2126
2127 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2128 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2129 }
2130
2131
2132
2133 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2134
2135
2136 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2137
2138
2139 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2140
47b5d69c 2141 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
1da177e4
LT
2142 }
2143
2144 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2145 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
47b5d69c 2146 FPT_ssel(ioport,thisCard);
1da177e4
LT
2147 }
2148
2149 break;
2150
2151 }
2152
2153 } /*end while */
2154
1da177e4 2155 MENABLE_INT(ioport);
1da177e4
LT
2156
2157 return(0);
2158}
2159
2160/*---------------------------------------------------------------------
2161 *
2162 * Function: Sccb_bad_isr
2163 *
2164 * Description: Some type of interrupt has occurred which is slightly
2165 * out of the ordinary. We will now decode it fully, in
2166 * this routine. This is broken up in an attempt to save
2167 * processing time.
2168 *
2169 *---------------------------------------------------------------------*/
db038cf8 2170static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
c823feeb 2171 PSCCBcard pCurrCard, unsigned short p_int)
1da177e4 2172{
db038cf8 2173 unsigned char temp, ScamFlg;
47b5d69c
JB
2174 PSCCBMgr_tar_info currTar_Info;
2175 PNVRamInfo pCurrNvRam;
1da177e4
LT
2176
2177
2178 if (RD_HARPOON(p_port+hp_ext_status) &
2179 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2180 {
2181
2182 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2183 {
2184
47b5d69c 2185 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
1da177e4
LT
2186 }
2187
2188 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2189
2190 {
2191 WR_HARPOON(p_port+hp_pci_stat_cfg,
2192 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2193
2194 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2195
2196 }
2197
2198 if (pCurrCard->currentSCCB != NULL)
2199 {
2200
2201 if (!pCurrCard->currentSCCB->HostStatus)
2202 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2203
47b5d69c 2204 FPT_sxfrp(p_port,p_card);
1da177e4 2205
db038cf8 2206 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
1da177e4 2207 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
db038cf8 2208 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
1da177e4
LT
2209 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2210
2211 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2212 {
47b5d69c 2213 FPT_phaseDecode(p_port,p_card);
1da177e4
LT
2214 }
2215 }
2216 }
2217
2218
2219 else if (p_int & RESET)
2220 {
2221
2222 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2223 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2224 if (pCurrCard->currentSCCB != NULL) {
2225
2226 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2227
47b5d69c 2228 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
1da177e4
LT
2229 }
2230
2231
2232 DISABLE_AUTO(p_port);
2233
47b5d69c 2234 FPT_sresb(p_port,p_card);
1da177e4
LT
2235
2236 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2237
2238 pCurrNvRam = pCurrCard->pNvRamInfo;
2239 if(pCurrNvRam){
2240 ScamFlg = pCurrNvRam->niScamConf;
2241 }
2242 else{
db038cf8 2243 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
1da177e4
LT
2244 }
2245
47b5d69c 2246 FPT_XbowInit(p_port, ScamFlg);
1da177e4 2247
47b5d69c 2248 FPT_scini(p_card, pCurrCard->ourId, 0);
1da177e4
LT
2249
2250 return(0xFF);
2251 }
2252
2253
2254 else if (p_int & FIFO) {
2255
2256 WRW_HARPOON((p_port+hp_intstat), FIFO);
2257
1da177e4 2258 if (pCurrCard->currentSCCB != NULL)
47b5d69c 2259 FPT_sxfrp(p_port,p_card);
1da177e4
LT
2260 }
2261
2262 else if (p_int & TIMEOUT)
2263 {
2264
2265 DISABLE_AUTO(p_port);
2266
2267 WRW_HARPOON((p_port+hp_intstat),
2268 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2269
2270 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2271
2272
47b5d69c 2273 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2274 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2275 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
47b5d69c 2276 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
1da177e4 2277 else
47b5d69c 2278 currTar_Info->TarLUNBusy[0] = 0;
1da177e4
LT
2279
2280
2281 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2282 {
2283 currTar_Info->TarSyncCtrl = 0;
2284 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2285 }
2286
2287 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2288 {
2289 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2290 }
2291
47b5d69c 2292 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
1da177e4 2293
47b5d69c 2294 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
1da177e4 2295
1da177e4
LT
2296 }
2297
47b5d69c 2298 else if (p_int & SCAM_SEL)
1da177e4 2299 {
1da177e4 2300
47b5d69c
JB
2301 FPT_scarb(p_port,LEVEL2_TAR);
2302 FPT_scsel(p_port);
2303 FPT_scasid(p_card, p_port);
1da177e4 2304
47b5d69c 2305 FPT_scbusf(p_port);
1da177e4 2306
47b5d69c 2307 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
1da177e4
LT
2308 }
2309
47b5d69c 2310 return(0x00);
1da177e4
LT
2311}
2312
1da177e4
LT
2313
2314/*---------------------------------------------------------------------
2315 *
2316 * Function: SccbMgrTableInit
2317 *
2318 * Description: Initialize all Sccb manager data structures.
2319 *
2320 *---------------------------------------------------------------------*/
2321
47b5d69c 2322static void FPT_SccbMgrTableInitAll()
1da177e4 2323{
db038cf8 2324 unsigned char thisCard;
1da177e4
LT
2325
2326 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2327 {
47b5d69c 2328 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
1da177e4 2329
47b5d69c
JB
2330 FPT_BL_Card[thisCard].ioPort = 0x00;
2331 FPT_BL_Card[thisCard].cardInfo = NULL;
2332 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2333 FPT_BL_Card[thisCard].ourId = 0x00;
2334 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
1da177e4
LT
2335 }
2336}
2337
2338
2339/*---------------------------------------------------------------------
2340 *
2341 * Function: SccbMgrTableInit
2342 *
2343 * Description: Initialize all Sccb manager data structures.
2344 *
2345 *---------------------------------------------------------------------*/
2346
db038cf8 2347static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
1da177e4 2348{
db038cf8 2349 unsigned char scsiID, qtag;
1da177e4
LT
2350
2351 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2352 {
47b5d69c 2353 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
2354 }
2355
2356 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2357 {
47b5d69c
JB
2358 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2359 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2360 FPT_SccbMgrTableInitTarget(p_card, scsiID);
1da177e4
LT
2361 }
2362
2363 pCurrCard->scanIndex = 0x00;
2364 pCurrCard->currentSCCB = NULL;
2365 pCurrCard->globalFlags = 0x00;
2366 pCurrCard->cmdCounter = 0x00;
2367 pCurrCard->tagQ_Lst = 0x01;
2368 pCurrCard->discQCount = 0;
2369
2370
2371}
2372
2373
2374/*---------------------------------------------------------------------
2375 *
2376 * Function: SccbMgrTableInit
2377 *
2378 * Description: Initialize all Sccb manager data structures.
2379 *
2380 *---------------------------------------------------------------------*/
2381
db038cf8 2382static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
1da177e4
LT
2383{
2384
db038cf8 2385 unsigned char lun, qtag;
1da177e4
LT
2386 PSCCBMgr_tar_info currTar_Info;
2387
47b5d69c 2388 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2389
2390 currTar_Info->TarSelQ_Cnt = 0;
2391 currTar_Info->TarSyncCtrl = 0;
2392
2393 currTar_Info->TarSelQ_Head = NULL;
2394 currTar_Info->TarSelQ_Tail = NULL;
2395 currTar_Info->TarTagQ_Cnt = 0;
47b5d69c 2396 currTar_Info->TarLUN_CA = 0;
1da177e4
LT
2397
2398
2399 for (lun = 0; lun < MAX_LUN; lun++)
2400 {
47b5d69c 2401 currTar_Info->TarLUNBusy[lun] = 0;
1da177e4
LT
2402 currTar_Info->LunDiscQ_Idx[lun] = 0;
2403 }
2404
2405 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2406 {
47b5d69c 2407 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
1da177e4 2408 {
47b5d69c 2409 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
1da177e4 2410 {
47b5d69c
JB
2411 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2412 FPT_BL_Card[p_card].discQCount--;
1da177e4
LT
2413 }
2414 }
2415 }
2416}
2417
1da177e4
LT
2418
2419/*---------------------------------------------------------------------
2420 *
2421 * Function: sfetm
2422 *
2423 * Description: Read in a message byte from the SCSI bus, and check
2424 * for a parity error.
2425 *
2426 *---------------------------------------------------------------------*/
2427
db038cf8 2428static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
1da177e4 2429{
db038cf8 2430 unsigned char message;
c823feeb 2431 unsigned short TimeOutLoop;
1da177e4
LT
2432
2433 TimeOutLoop = 0;
2434 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2435 (TimeOutLoop++ < 20000) ){}
2436
2437
2438 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2439
2440 message = RD_HARPOON(port+hp_scsidata_0);
2441
2442 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2443
2444
2445 if (TimeOutLoop > 20000)
2446 message = 0x00; /* force message byte = 0 if Time Out on Req */
2447
2448 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2449 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2450 {
2451 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2452 WR_HARPOON(port+hp_xferstat, 0);
2453 WR_HARPOON(port+hp_fiforead, 0);
2454 WR_HARPOON(port+hp_fifowrite, 0);
2455 if (pCurrSCCB != NULL)
2456 {
2457 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2458 }
2459 message = 0x00;
2460 do
2461 {
2462 ACCEPT_MSG_ATN(port);
2463 TimeOutLoop = 0;
2464 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2465 (TimeOutLoop++ < 20000) ){}
2466 if (TimeOutLoop > 20000)
2467 {
2468 WRW_HARPOON((port+hp_intstat), PARITY);
2469 return(message);
2470 }
2471 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2472 {
2473 WRW_HARPOON((port+hp_intstat), PARITY);
2474 return(message);
2475 }
2476 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2477
2478 RD_HARPOON(port+hp_scsidata_0);
2479
2480 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2481
2482 }while(1);
2483
2484 }
2485 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2486 WR_HARPOON(port+hp_xferstat, 0);
2487 WR_HARPOON(port+hp_fiforead, 0);
2488 WR_HARPOON(port+hp_fifowrite, 0);
2489 return(message);
2490}
2491
2492
2493/*---------------------------------------------------------------------
2494 *
47b5d69c 2495 * Function: FPT_ssel
1da177e4
LT
2496 *
2497 * Description: Load up automation and select target device.
2498 *
2499 *---------------------------------------------------------------------*/
2500
db038cf8 2501static void FPT_ssel(ULONG port, unsigned char p_card)
1da177e4
LT
2502{
2503
db038cf8 2504 unsigned char auto_loaded, i, target, *theCCB;
1da177e4 2505
1da177e4 2506 ULONG cdb_reg;
1da177e4
LT
2507 PSCCBcard CurrCard;
2508 PSCCB currSCCB;
2509 PSCCBMgr_tar_info currTar_Info;
db038cf8 2510 unsigned char lastTag, lun;
1da177e4 2511
47b5d69c 2512 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
2513 currSCCB = CurrCard->currentSCCB;
2514 target = currSCCB->TargID;
47b5d69c 2515 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2516 lastTag = CurrCard->tagQ_Lst;
2517
2518 ARAM_ACCESS(port);
2519
2520
2521 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2522 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2523
2524 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2525 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2526
2527 lun = currSCCB->Lun;
2528 else
2529 lun = 0;
2530
2531
1da177e4
LT
2532 if (CurrCard->globalFlags & F_TAG_STARTED)
2533 {
2534 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2535 {
47b5d69c 2536 if ((currTar_Info->TarLUN_CA == 0)
1da177e4
LT
2537 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2538 == TAG_Q_TRYING))
2539 {
2540
2541 if (currTar_Info->TarTagQ_Cnt !=0)
2542 {
47b5d69c
JB
2543 currTar_Info->TarLUNBusy[lun] = 1;
2544 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2545 SGRAM_ACCESS(port);
2546 return;
2547 }
2548
2549 else {
47b5d69c 2550 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2551 }
2552
2553 } /*End non-tagged */
2554
2555 else {
47b5d69c 2556 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2557 }
2558
2559 } /*!Use cmd Q Tagged */
2560
2561 else {
47b5d69c 2562 if (currTar_Info->TarLUN_CA == 1)
1da177e4 2563 {
47b5d69c 2564 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2565 SGRAM_ACCESS(port);
2566 return;
2567 }
2568
47b5d69c 2569 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2570
2571 } /*else use cmd Q tagged */
2572
2573 } /*if glob tagged started */
2574
2575 else {
47b5d69c 2576 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2577 }
2578
1da177e4
LT
2579
2580
2581 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2582 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2583 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2584 {
2585 if(CurrCard->discQCount >= QUEUE_DEPTH)
2586 {
47b5d69c
JB
2587 currTar_Info->TarLUNBusy[lun] = 1;
2588 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2589 SGRAM_ACCESS(port);
2590 return;
2591 }
2592 for (i = 1; i < QUEUE_DEPTH; i++)
2593 {
2594 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2595 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2596 {
2597 CurrCard->tagQ_Lst = lastTag;
2598 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2599 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2600 CurrCard->discQCount++;
2601 break;
2602 }
2603 }
2604 if(i == QUEUE_DEPTH)
2605 {
47b5d69c
JB
2606 currTar_Info->TarLUNBusy[lun] = 1;
2607 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2608 SGRAM_ACCESS(port);
2609 return;
2610 }
2611 }
2612
2613
2614
47b5d69c 2615 auto_loaded = 0;
1da177e4
LT
2616
2617 WR_HARPOON(port+hp_select_id, target);
2618 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2619
2620 if (currSCCB->OperationCode == RESET_COMMAND) {
2621 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2622 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2623
2624 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2625
2626 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2627
2628 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
47b5d69c 2629 auto_loaded = 1;
1da177e4
LT
2630 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2631
2632 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2633 {
2634 currTar_Info->TarSyncCtrl = 0;
2635 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2636 }
2637
1da177e4
LT
2638 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2639 {
2640 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2641 }
1da177e4 2642
47b5d69c
JB
2643 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2644 FPT_SccbMgrTableInitTarget(p_card, target);
1da177e4
LT
2645
2646 }
2647
2648 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2649 {
2650 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2651 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2652
2653 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2654
2655 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
db038cf8
AD
2656 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2657 >> 6) | (unsigned char)0x20)));
1da177e4
LT
2658 WRW_HARPOON((port+SYNC_MSGS+2),
2659 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2660 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2661
2662 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
47b5d69c 2663 auto_loaded = 1;
1da177e4
LT
2664
2665 }
2666
1da177e4 2667 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
47b5d69c 2668 auto_loaded = FPT_siwidn(port,p_card);
1da177e4
LT
2669 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2670 }
2671
1da177e4
LT
2672 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2673 == SYNC_SUPPORTED)) {
47b5d69c 2674 auto_loaded = FPT_sisyncn(port,p_card, 0);
1da177e4
LT
2675 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2676 }
2677
2678
2679 if (!auto_loaded)
2680 {
2681
1da177e4
LT
2682 if (currSCCB->ControlByte & F_USE_CMD_Q)
2683 {
2684
2685 CurrCard->globalFlags |= F_TAG_STARTED;
2686
2687 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2688 == TAG_Q_REJECT)
2689 {
2690 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2691
2692 /* Fix up the start instruction with a jump to
2693 Non-Tag-CMD handling */
2694 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2695
2696 WRW_HARPOON((port+NON_TAG_ID_MSG),
2697 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2698
2699 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2700
2701 /* Setup our STATE so we know what happend when
2702 the wheels fall off. */
2703 currSCCB->Sccb_scsistat = SELECT_ST;
2704
47b5d69c 2705 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2706 }
2707
2708 else
2709 {
2710 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2711
2712 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
db038cf8
AD
2713 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2714 >> 6) | (unsigned char)0x20)));
1da177e4
LT
2715
2716 for (i = 1; i < QUEUE_DEPTH; i++)
2717 {
2718 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2719 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2720 {
2721 WRW_HARPOON((port+ID_MSG_STRT+6),
2722 (MPM_OP+AMSG_OUT+lastTag));
2723 CurrCard->tagQ_Lst = lastTag;
2724 currSCCB->Sccb_tag = lastTag;
2725 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2726 CurrCard->discQCount++;
2727 break;
2728 }
2729 }
2730
2731
2732 if ( i == QUEUE_DEPTH )
2733 {
47b5d69c
JB
2734 currTar_Info->TarLUNBusy[lun] = 1;
2735 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2736 SGRAM_ACCESS(port);
2737 return;
2738 }
2739
2740 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2741
2742 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2743 }
2744 }
2745
2746 else
2747 {
1da177e4
LT
2748
2749 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2750
2751 WRW_HARPOON((port+NON_TAG_ID_MSG),
2752 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2753
2754 currSCCB->Sccb_scsistat = SELECT_ST;
2755
2756 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
1da177e4 2757 }
1da177e4
LT
2758
2759
db038cf8 2760 theCCB = (unsigned char *)&currSCCB->Cdb[0];
1da177e4
LT
2761
2762 cdb_reg = port + CMD_STRT;
2763
2764 for (i=0; i < currSCCB->CdbLength; i++)
2765 {
2766 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2767 cdb_reg +=2;
2768 theCCB++;
2769 }
2770
2771 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2772 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2773
2774 } /* auto_loaded */
2775
c823feeb 2776 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
1da177e4 2777 WR_HARPOON(port+hp_xferstat, 0x00);
1da177e4
LT
2778
2779 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2780
2781 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2782
2783
2784 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2785 {
2786 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2787 }
2788 else
2789 {
2790
db038cf8 2791/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
1da177e4
LT
2792 auto_loaded |= AUTO_IMMED; */
2793 auto_loaded = AUTO_IMMED;
2794
2795 DISABLE_AUTO(port);
2796
2797 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2798 }
2799
2800 SGRAM_ACCESS(port);
2801}
2802
2803
2804/*---------------------------------------------------------------------
2805 *
47b5d69c 2806 * Function: FPT_sres
1da177e4
LT
2807 *
2808 * Description: Hookup the correct CCB and handle the incoming messages.
2809 *
2810 *---------------------------------------------------------------------*/
2811
db038cf8 2812static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
1da177e4
LT
2813{
2814
db038cf8 2815 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
1da177e4
LT
2816
2817
2818 PSCCBMgr_tar_info currTar_Info;
2819 PSCCB currSCCB;
2820
2821
2822
2823
2824 if(pCurrCard->currentSCCB != NULL)
2825 {
47b5d69c 2826 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2827 DISABLE_AUTO(port);
2828
2829
2830 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2831
2832
2833 currSCCB = pCurrCard->currentSCCB;
2834 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2835 {
2836 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2837 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2838 }
2839 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2840 {
2841 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2842 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2843 }
2844 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2845 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2846 {
47b5d69c 2847 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
1da177e4
LT
2848 if(currSCCB->Sccb_scsistat != ABORT_ST)
2849 {
2850 pCurrCard->discQCount--;
2851 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2852 = NULL;
2853 }
2854 }
2855 else
2856 {
47b5d69c 2857 currTar_Info->TarLUNBusy[0] = 0;
1da177e4
LT
2858 if(currSCCB->Sccb_tag)
2859 {
2860 if(currSCCB->Sccb_scsistat != ABORT_ST)
2861 {
2862 pCurrCard->discQCount--;
2863 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2864 }
2865 }else
2866 {
2867 if(currSCCB->Sccb_scsistat != ABORT_ST)
2868 {
2869 pCurrCard->discQCount--;
2870 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2871 }
2872 }
2873 }
2874
47b5d69c 2875 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
2876 }
2877
c823feeb 2878 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
1da177e4
LT
2879
2880
db038cf8 2881 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
47b5d69c 2882 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2883
2884
2885 msgRetryCount = 0;
2886 do
2887 {
2888
47b5d69c 2889 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2890 tag = 0;
2891
2892
2893 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2894 {
2895 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2896 {
2897
2898 WRW_HARPOON((port+hp_intstat), PHASE);
2899 return;
2900 }
2901 }
2902
2903 WRW_HARPOON((port+hp_intstat), PHASE);
2904 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2905 {
2906
47b5d69c 2907 message = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2908 if (message)
2909 {
2910
2911 if (message <= (0x80 | LUN_MASK))
2912 {
db038cf8 2913 lun = message & (unsigned char)LUN_MASK;
1da177e4 2914
1da177e4
LT
2915 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2916 {
2917 if (currTar_Info->TarTagQ_Cnt != 0)
2918 {
2919
2920 if (!(currTar_Info->TarLUN_CA))
2921 {
2922 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2923
2924
47b5d69c 2925 message = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2926 if (message)
2927 {
2928 ACCEPT_MSG(port);
2929 }
2930
2931 else
47b5d69c 2932 message = 0;
1da177e4 2933
47b5d69c 2934 if(message != 0)
1da177e4 2935 {
47b5d69c 2936 tag = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2937
2938 if (!(tag))
47b5d69c 2939 message = 0;
1da177e4
LT
2940 }
2941
2942 } /*C.A. exists! */
2943
2944 } /*End Q cnt != 0 */
2945
2946 } /*End Tag cmds supported! */
1da177e4
LT
2947
2948 } /*End valid ID message. */
2949
2950 else
2951 {
2952
2953 ACCEPT_MSG_ATN(port);
2954 }
2955
2956 } /* End good id message. */
2957
2958 else
2959 {
2960
47b5d69c 2961 message = 0;
1da177e4
LT
2962 }
2963 }
2964 else
2965 {
2966 ACCEPT_MSG_ATN(port);
2967
2968 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2969 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2970 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2971
2972 return;
2973 }
1da177e4 2974
47b5d69c 2975 if(message == 0)
1da177e4
LT
2976 {
2977 msgRetryCount++;
2978 if(msgRetryCount == 1)
2979 {
47b5d69c 2980 FPT_SendMsg(port, SMPARITY);
1da177e4
LT
2981 }
2982 else
2983 {
47b5d69c 2984 FPT_SendMsg(port, SMDEV_RESET);
1da177e4 2985
47b5d69c 2986 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
1da177e4 2987
47b5d69c 2988 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
1da177e4
LT
2989 {
2990
47b5d69c 2991 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
2992
2993 }
2994
47b5d69c 2995 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
1da177e4
LT
2996 {
2997
47b5d69c 2998 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
2999 }
3000
3001
47b5d69c
JB
3002 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3003 FPT_SccbMgrTableInitTarget(p_card,our_target);
1da177e4
LT
3004 return;
3005 }
3006 }
47b5d69c 3007 }while(message == 0);
1da177e4
LT
3008
3009
3010
3011 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3012 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3013 {
47b5d69c 3014 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
3015 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3016 if(pCurrCard->currentSCCB != NULL)
3017 {
3018 ACCEPT_MSG(port);
3019 }
3020 else
3021 {
3022 ACCEPT_MSG_ATN(port);
3023 }
3024 }
3025 else
3026 {
47b5d69c 3027 currTar_Info->TarLUNBusy[0] = 1;
1da177e4
LT
3028
3029
3030 if (tag)
3031 {
3032 if (pCurrCard->discQ_Tbl[tag] != NULL)
3033 {
3034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3035 currTar_Info->TarTagQ_Cnt--;
3036 ACCEPT_MSG(port);
3037 }
3038 else
3039 {
3040 ACCEPT_MSG_ATN(port);
3041 }
3042 }else
3043 {
3044 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3045 if(pCurrCard->currentSCCB != NULL)
3046 {
3047 ACCEPT_MSG(port);
3048 }
3049 else
3050 {
3051 ACCEPT_MSG_ATN(port);
3052 }
3053 }
3054 }
3055
3056 if(pCurrCard->currentSCCB != NULL)
3057 {
3058 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3059 {
3060 /* During Abort Tag command, the target could have got re-selected
3061 and completed the command. Check the select Q and remove the CCB
3062 if it is in the Select Q */
47b5d69c 3063 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
1da177e4
LT
3064 }
3065 }
3066
3067
3068 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3069 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3070 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3071}
3072
db038cf8 3073static void FPT_SendMsg(ULONG port, unsigned char message)
1da177e4
LT
3074{
3075 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3076 {
3077 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3078 {
3079
3080 WRW_HARPOON((port+hp_intstat), PHASE);
3081 return;
3082 }
3083 }
3084
3085 WRW_HARPOON((port+hp_intstat), PHASE);
3086 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3087 {
3088 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3089
3090
3091 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3092
3093 WR_HARPOON(port+hp_scsidata_0,message);
3094
3095 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3096
3097 ACCEPT_MSG(port);
3098
3099 WR_HARPOON(port+hp_portctrl_0, 0x00);
3100
3101 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3102 (message == SMABORT_TAG) )
3103 {
3104 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3105
3106 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3107 {
3108 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3109 }
3110 }
3111 }
3112}
3113
3114/*---------------------------------------------------------------------
3115 *
47b5d69c 3116 * Function: FPT_sdecm
1da177e4
LT
3117 *
3118 * Description: Determine the proper responce to the message from the
3119 * target device.
3120 *
3121 *---------------------------------------------------------------------*/
db038cf8 3122static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
1da177e4
LT
3123{
3124 PSCCB currSCCB;
3125 PSCCBcard CurrCard;
3126 PSCCBMgr_tar_info currTar_Info;
3127
47b5d69c 3128 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
3129 currSCCB = CurrCard->currentSCCB;
3130
47b5d69c 3131 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3132
3133 if (message == SMREST_DATA_PTR)
3134 {
3135 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3136 {
3137 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3138
47b5d69c 3139 FPT_hostDataXferRestart(currSCCB);
1da177e4
LT
3140 }
3141
3142 ACCEPT_MSG(port);
3143 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3144 }
3145
3146 else if (message == SMCMD_COMP)
3147 {
3148
3149
3150 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3151 {
db038cf8
AD
3152 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3153 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
1da177e4
LT
3154 }
3155
3156 ACCEPT_MSG(port);
3157
3158 }
3159
3160 else if ((message == SMNO_OP) || (message >= SMIDENT)
3161 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3162 {
3163
3164 ACCEPT_MSG(port);
3165 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3166 }
3167
3168 else if (message == SMREJECT)
3169 {
3170
3171 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3172 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3173 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3174 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3175
3176 {
3177 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3178
3179 ACCEPT_MSG(port);
3180
3181
3182 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3183 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3184
3185 if(currSCCB->Lun == 0x00)
3186 {
3187 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3188 {
3189
db038cf8 3190 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
1da177e4
LT
3191
3192 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3193 }
3194
1da177e4
LT
3195 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3196 {
3197
3198
3199 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3200 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3201
3202 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3203
3204 }
1da177e4
LT
3205
3206 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3207 {
3208 currTar_Info->TarStatus = (currTar_Info->TarStatus &
db038cf8 3209 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
1da177e4
LT
3210
3211
3212 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3213 CurrCard->discQCount--;
3214 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3215 currSCCB->Sccb_tag = 0x00;
3216
3217 }
3218 }
3219
3220 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3221 {
3222
3223
3224 if(currSCCB->Lun == 0x00)
3225 {
3226 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3227 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3228 }
3229 }
3230
3231 else
3232 {
3233
3234 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3235 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
47b5d69c 3236 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
1da177e4 3237 else
47b5d69c 3238 currTar_Info->TarLUNBusy[0] = 1;
1da177e4
LT
3239
3240
db038cf8 3241 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
1da177e4
LT
3242
3243 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3244
3245 }
3246 }
3247
3248 else
3249 {
3250 ACCEPT_MSG(port);
3251
3252 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3253 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3254
3255 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3256 {
3257 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3258 }
3259 }
3260 }
3261
3262 else if (message == SMEXT)
3263 {
3264
3265 ACCEPT_MSG(port);
47b5d69c 3266 FPT_shandem(port,p_card,currSCCB);
1da177e4
LT
3267 }
3268
3269 else if (message == SMIGNORWR)
3270 {
3271
3272 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3273
47b5d69c 3274 message = FPT_sfm(port,currSCCB);
1da177e4
LT
3275
3276 if(currSCCB->Sccb_scsimsg != SMPARITY)
3277 ACCEPT_MSG(port);
3278 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3279 }
3280
3281
3282 else
3283 {
3284
3285 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3286 currSCCB->Sccb_scsimsg = SMREJECT;
3287
3288 ACCEPT_MSG_ATN(port);
3289 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3290 }
3291}
3292
3293
3294/*---------------------------------------------------------------------
3295 *
47b5d69c 3296 * Function: FPT_shandem
1da177e4
LT
3297 *
3298 * Description: Decide what to do with the extended message.
3299 *
3300 *---------------------------------------------------------------------*/
db038cf8 3301static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
1da177e4 3302{
db038cf8 3303 unsigned char length,message;
1da177e4 3304
47b5d69c 3305 length = FPT_sfm(port,pCurrSCCB);
1da177e4
LT
3306 if (length)
3307 {
3308
3309 ACCEPT_MSG(port);
47b5d69c 3310 message = FPT_sfm(port,pCurrSCCB);
1da177e4
LT
3311 if (message)
3312 {
3313
3314 if (message == SMSYNC)
3315 {
3316
3317 if (length == 0x03)
3318 {
3319
3320 ACCEPT_MSG(port);
47b5d69c 3321 FPT_stsyncn(port,p_card);
1da177e4
LT
3322 }
3323 else
3324 {
3325
3326 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3327 ACCEPT_MSG_ATN(port);
3328 }
3329 }
1da177e4
LT
3330 else if (message == SMWDTR)
3331 {
3332
3333 if (length == 0x02)
3334 {
3335
3336 ACCEPT_MSG(port);
47b5d69c 3337 FPT_stwidn(port,p_card);
1da177e4
LT
3338 }
3339 else
3340 {
3341
3342 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3343 ACCEPT_MSG_ATN(port);
3344
3345 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3346 }
3347 }
1da177e4
LT
3348 else
3349 {
3350
3351 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3352 ACCEPT_MSG_ATN(port);
3353
3354 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3355 }
3356 }
3357 else
3358 {
3359 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3360 ACCEPT_MSG(port);
3361 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3362 }
3363 }else
3364 {
3365 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3366 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3367 }
3368}
3369
3370
3371/*---------------------------------------------------------------------
3372 *
47b5d69c 3373 * Function: FPT_sisyncn
1da177e4
LT
3374 *
3375 * Description: Read in a message byte from the SCSI bus, and check
3376 * for a parity error.
3377 *
3378 *---------------------------------------------------------------------*/
3379
db038cf8 3380static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
1da177e4
LT
3381{
3382 PSCCB currSCCB;
3383 PSCCBMgr_tar_info currTar_Info;
3384
47b5d69c
JB
3385 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3386 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3387
3388 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3389
3390
3391 WRW_HARPOON((port+ID_MSG_STRT),
db038cf8 3392 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
1da177e4
LT
3393
3394 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3395
3396 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3397 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3398 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3399
3400
3401 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3402
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3404
3405 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3406
3407 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3408
3409 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3410
3411 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3412
3413 else
3414 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3415
3416
3417 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3418 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3419 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3420
3421
47b5d69c 3422 if(syncFlag == 0)
1da177e4
LT
3423 {
3424 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3425 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
db038cf8 3426 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
1da177e4
LT
3427 }
3428 else
3429 {
3430 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3431 }
3432
3433
47b5d69c 3434 return(1);
1da177e4
LT
3435 }
3436
3437 else {
3438
db038cf8 3439 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
1da177e4 3440 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
47b5d69c 3441 return(0);
1da177e4
LT
3442 }
3443}
3444
3445
3446
3447/*---------------------------------------------------------------------
3448 *
47b5d69c 3449 * Function: FPT_stsyncn
1da177e4
LT
3450 *
3451 * Description: The has sent us a Sync Nego message so handle it as
3452 * necessary.
3453 *
3454 *---------------------------------------------------------------------*/
db038cf8 3455static void FPT_stsyncn(ULONG port, unsigned char p_card)
1da177e4 3456{
db038cf8 3457 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
1da177e4
LT
3458 PSCCB currSCCB;
3459 PSCCBMgr_tar_info currTar_Info;
3460
47b5d69c
JB
3461 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3462 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3463
47b5d69c 3464 sync_msg = FPT_sfm(port,currSCCB);
1da177e4
LT
3465
3466 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3467 {
3468 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3469 return;
3470 }
3471
3472 ACCEPT_MSG(port);
3473
3474
47b5d69c 3475 offset = FPT_sfm(port,currSCCB);
1da177e4
LT
3476
3477 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3478 {
3479 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3480 return;
3481 }
3482
3483 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3484
3485 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3486
3487 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3488
3489 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3490
3491 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3492
3493 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3494 else
3495
3496 our_sync_msg = 0; /* Message = Async */
3497
3498 if (sync_msg < our_sync_msg) {
3499 sync_msg = our_sync_msg; /*if faster, then set to max. */
3500 }
3501
3502 if (offset == ASYNC)
3503 sync_msg = ASYNC;
3504
3505 if (offset > MAX_OFFSET)
3506 offset = MAX_OFFSET;
3507
3508 sync_reg = 0x00;
3509
3510 if (sync_msg > 12)
3511
3512 sync_reg = 0x20; /* Use 10MB/s */
3513
3514 if (sync_msg > 25)
3515
3516 sync_reg = 0x40; /* Use 6.6MB/s */
3517
3518 if (sync_msg > 38)
3519
3520 sync_reg = 0x60; /* Use 5MB/s */
3521
3522 if (sync_msg > 50)
3523
3524 sync_reg = 0x80; /* Use 4MB/s */
3525
3526 if (sync_msg > 62)
3527
3528 sync_reg = 0xA0; /* Use 3.33MB/s */
3529
3530 if (sync_msg > 75)
3531
3532 sync_reg = 0xC0; /* Use 2.85MB/s */
3533
3534 if (sync_msg > 87)
3535
3536 sync_reg = 0xE0; /* Use 2.5MB/s */
3537
3538 if (sync_msg > 100) {
3539
3540 sync_reg = 0x00; /* Use ASYNC */
3541 offset = 0x00;
3542 }
3543
3544
1da177e4
LT
3545 if (currTar_Info->TarStatus & WIDE_ENABLED)
3546
3547 sync_reg |= offset;
3548
3549 else
3550
3551 sync_reg |= (offset | NARROW_SCSI);
3552
47b5d69c 3553 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
1da177e4
LT
3554
3555
3556 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3557
3558
3559 ACCEPT_MSG(port);
3560
3561 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
db038cf8 3562 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
1da177e4
LT
3563
3564 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3565 }
3566
3567 else {
3568
3569
3570 ACCEPT_MSG_ATN(port);
3571
47b5d69c 3572 FPT_sisyncr(port,sync_msg,offset);
1da177e4
LT
3573
3574 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
db038cf8 3575 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
1da177e4
LT
3576 }
3577}
3578
3579
3580/*---------------------------------------------------------------------
3581 *
47b5d69c 3582 * Function: FPT_sisyncr
1da177e4
LT
3583 *
3584 * Description: Answer the targets sync message.
3585 *
3586 *---------------------------------------------------------------------*/
db038cf8 3587static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
1da177e4
LT
3588{
3589 ARAM_ACCESS(port);
3590 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3591 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3592 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3593 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3594 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3595 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3596 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3597 SGRAM_ACCESS(port);
3598
3599 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3600 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3601
3602 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3603
3604 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3605}
3606
3607
3608
1da177e4
LT
3609/*---------------------------------------------------------------------
3610 *
47b5d69c 3611 * Function: FPT_siwidn
1da177e4
LT
3612 *
3613 * Description: Read in a message byte from the SCSI bus, and check
3614 * for a parity error.
3615 *
3616 *---------------------------------------------------------------------*/
3617
db038cf8 3618static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
1da177e4
LT
3619{
3620 PSCCB currSCCB;
3621 PSCCBMgr_tar_info currTar_Info;
3622
47b5d69c
JB
3623 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3624 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3625
3626 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3627
3628
3629 WRW_HARPOON((port+ID_MSG_STRT),
db038cf8 3630 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
1da177e4
LT
3631
3632 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3633
3634 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3635 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3636 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3637 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3638 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3639 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3640
3641 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3642
3643
3644 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
db038cf8 3645 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
1da177e4 3646
47b5d69c 3647 return(1);
1da177e4
LT
3648 }
3649
3650 else {
3651
3652 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
db038cf8 3653 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
1da177e4
LT
3654
3655 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
47b5d69c 3656 return(0);
1da177e4
LT
3657 }
3658}
3659
3660
3661
3662/*---------------------------------------------------------------------
3663 *
47b5d69c 3664 * Function: FPT_stwidn
1da177e4
LT
3665 *
3666 * Description: The has sent us a Wide Nego message so handle it as
3667 * necessary.
3668 *
3669 *---------------------------------------------------------------------*/
db038cf8 3670static void FPT_stwidn(ULONG port, unsigned char p_card)
1da177e4 3671{
db038cf8 3672 unsigned char width;
1da177e4
LT
3673 PSCCB currSCCB;
3674 PSCCBMgr_tar_info currTar_Info;
3675
47b5d69c
JB
3676 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3677 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3678
47b5d69c 3679 width = FPT_sfm(port,currSCCB);
1da177e4
LT
3680
3681 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3682 {
3683 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3684 return;
3685 }
3686
3687
3688 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3689 width = 0;
3690
3691 if (width) {
3692 currTar_Info->TarStatus |= WIDE_ENABLED;
3693 width = 0;
3694 }
3695 else {
3696 width = NARROW_SCSI;
3697 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3698 }
3699
3700
47b5d69c 3701 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
1da177e4
LT
3702
3703
3704 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3705 {
3706
3707
3708
3709 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3710
3711 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3712 {
3713 ACCEPT_MSG_ATN(port);
3714 ARAM_ACCESS(port);
47b5d69c 3715 FPT_sisyncn(port,p_card, 1);
1da177e4
LT
3716 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3717 SGRAM_ACCESS(port);
3718 }
3719 else
3720 {
3721 ACCEPT_MSG(port);
3722 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3723 }
3724 }
3725
3726 else {
3727
3728
3729 ACCEPT_MSG_ATN(port);
3730
3731 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3732 width = SM16BIT;
3733 else
3734 width = SM8BIT;
3735
47b5d69c 3736 FPT_siwidr(port,width);
1da177e4
LT
3737
3738 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3739 }
3740}
3741
3742
3743/*---------------------------------------------------------------------
3744 *
47b5d69c 3745 * Function: FPT_siwidr
1da177e4
LT
3746 *
3747 * Description: Answer the targets Wide nego message.
3748 *
3749 *---------------------------------------------------------------------*/
db038cf8 3750static void FPT_siwidr(ULONG port, unsigned char width)
1da177e4
LT
3751{
3752 ARAM_ACCESS(port);
3753 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3754 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3755 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3756 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3757 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3758 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3759 SGRAM_ACCESS(port);
3760
3761 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3762 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3763
3764 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3765
3766 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3767}
3768
1da177e4
LT
3769
3770
3771/*---------------------------------------------------------------------
3772 *
47b5d69c 3773 * Function: FPT_sssyncv
1da177e4
LT
3774 *
3775 * Description: Write the desired value to the Sync Register for the
3776 * ID specified.
3777 *
3778 *---------------------------------------------------------------------*/
db038cf8 3779static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
47b5d69c 3780 PSCCBMgr_tar_info currTar_Info)
1da177e4 3781{
db038cf8 3782 unsigned char index;
1da177e4
LT
3783
3784 index = p_id;
3785
3786 switch (index) {
3787
3788 case 0:
3789 index = 12; /* hp_synctarg_0 */
3790 break;
3791 case 1:
3792 index = 13; /* hp_synctarg_1 */
3793 break;
3794 case 2:
3795 index = 14; /* hp_synctarg_2 */
3796 break;
3797 case 3:
3798 index = 15; /* hp_synctarg_3 */
3799 break;
3800 case 4:
3801 index = 8; /* hp_synctarg_4 */
3802 break;
3803 case 5:
3804 index = 9; /* hp_synctarg_5 */
3805 break;
3806 case 6:
3807 index = 10; /* hp_synctarg_6 */
3808 break;
3809 case 7:
3810 index = 11; /* hp_synctarg_7 */
3811 break;
3812 case 8:
3813 index = 4; /* hp_synctarg_8 */
3814 break;
3815 case 9:
3816 index = 5; /* hp_synctarg_9 */
3817 break;
3818 case 10:
3819 index = 6; /* hp_synctarg_10 */
3820 break;
3821 case 11:
3822 index = 7; /* hp_synctarg_11 */
3823 break;
3824 case 12:
3825 index = 0; /* hp_synctarg_12 */
3826 break;
3827 case 13:
3828 index = 1; /* hp_synctarg_13 */
3829 break;
3830 case 14:
3831 index = 2; /* hp_synctarg_14 */
3832 break;
3833 case 15:
3834 index = 3; /* hp_synctarg_15 */
3835
3836 }
3837
3838 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3839
3840 currTar_Info->TarSyncCtrl = p_sync_value;
3841}
3842
3843
3844/*---------------------------------------------------------------------
3845 *
47b5d69c 3846 * Function: FPT_sresb
1da177e4
LT
3847 *
3848 * Description: Reset the desired card's SCSI bus.
3849 *
3850 *---------------------------------------------------------------------*/
db038cf8 3851static void FPT_sresb(ULONG port, unsigned char p_card)
1da177e4 3852{
db038cf8 3853 unsigned char scsiID, i;
1da177e4
LT
3854
3855 PSCCBMgr_tar_info currTar_Info;
3856
3857 WR_HARPOON(port+hp_page_ctrl,
3858 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3859 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3860
3861 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3862
3863 scsiID = RD_HARPOON(port+hp_seltimeout);
3864 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3865 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3866
3867 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3868
3869 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3870
3871 WR_HARPOON(port+hp_seltimeout,scsiID);
3872
3873 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3874
47b5d69c 3875 FPT_Wait(port, TO_5ms);
1da177e4
LT
3876
3877 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3878
3879 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3880
3881 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3882 {
47b5d69c 3883 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4
LT
3884
3885 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3886 {
3887 currTar_Info->TarSyncCtrl = 0;
3888 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3889 }
3890
3891 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3892 {
3893 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3894 }
3895
47b5d69c 3896 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
1da177e4 3897
47b5d69c 3898 FPT_SccbMgrTableInitTarget(p_card, scsiID);
1da177e4
LT
3899 }
3900
47b5d69c
JB
3901 FPT_BL_Card[p_card].scanIndex = 0x00;
3902 FPT_BL_Card[p_card].currentSCCB = NULL;
3903 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
1da177e4 3904 | F_NEW_SCCB_CMD);
47b5d69c
JB
3905 FPT_BL_Card[p_card].cmdCounter = 0x00;
3906 FPT_BL_Card[p_card].discQCount = 0x00;
3907 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
1da177e4
LT
3908
3909 for(i = 0; i < QUEUE_DEPTH; i++)
47b5d69c 3910 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
1da177e4
LT
3911
3912 WR_HARPOON(port+hp_page_ctrl,
3913 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3914
3915}
3916
3917/*---------------------------------------------------------------------
3918 *
47b5d69c 3919 * Function: FPT_ssenss
1da177e4
LT
3920 *
3921 * Description: Setup for the Auto Sense command.
3922 *
3923 *---------------------------------------------------------------------*/
47b5d69c 3924static void FPT_ssenss(PSCCBcard pCurrCard)
1da177e4 3925{
db038cf8 3926 unsigned char i;
1da177e4
LT
3927 PSCCB currSCCB;
3928
3929 currSCCB = pCurrCard->currentSCCB;
3930
3931
3932 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3933
3934 for (i = 0; i < 6; i++) {
3935
3936 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3937 }
3938
3939 currSCCB->CdbLength = SIX_BYTE_CMD;
3940 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
db038cf8 3941 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
1da177e4
LT
3942 currSCCB->Cdb[2] = 0x00;
3943 currSCCB->Cdb[3] = 0x00;
3944 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3945 currSCCB->Cdb[5] = 0x00;
3946
3947 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3948
3949 currSCCB->Sccb_ATC = 0x00;
3950
3951 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3952
3953 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3954
db038cf8 3955 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
1da177e4
LT
3956
3957 currSCCB->ControlByte = 0x00;
3958
3959 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3960}
3961
3962
3963
3964/*---------------------------------------------------------------------
3965 *
47b5d69c 3966 * Function: FPT_sxfrp
1da177e4
LT
3967 *
3968 * Description: Transfer data into the bit bucket until the device
3969 * decides to switch phase.
3970 *
3971 *---------------------------------------------------------------------*/
3972
db038cf8 3973static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
1da177e4 3974{
db038cf8 3975 unsigned char curr_phz;
1da177e4
LT
3976
3977
3978 DISABLE_AUTO(p_port);
3979
47b5d69c 3980 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
1da177e4 3981
47b5d69c 3982 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
1da177e4
LT
3983
3984 }
3985
3986 /* If the Automation handled the end of the transfer then do not
3987 match the phase or we will get out of sync with the ISR. */
3988
3989 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3990 return;
3991
3992 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3993
db038cf8 3994 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
1da177e4
LT
3995
3996 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3997
3998
3999 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4000
4001 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
db038cf8 4002 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
1da177e4 4003 {
db038cf8 4004 if (curr_phz & (unsigned char)SCSI_IOBIT)
1da177e4
LT
4005 {
4006 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4007
4008 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4009 {
4010 RD_HARPOON(p_port+hp_fifodata_0);
4011 }
4012 }
4013 else
4014 {
4015 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4016 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4017 {
4018 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4019 }
4020 }
4021 } /* End of While loop for padding data I/O phase */
4022
4023 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4024 {
4025 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4026 break;
4027 }
4028
4029 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4030 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4031 {
4032 RD_HARPOON(p_port+hp_fifodata_0);
4033 }
4034
4035 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4036 {
4037 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4038 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4039
4040 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4041 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4042 }
4043}
4044
4045
4046/*---------------------------------------------------------------------
4047 *
47b5d69c 4048 * Function: FPT_schkdd
1da177e4
LT
4049 *
4050 * Description: Make sure data has been flushed from both FIFOs and abort
4051 * the operations if necessary.
4052 *
4053 *---------------------------------------------------------------------*/
4054
db038cf8 4055static void FPT_schkdd(ULONG port, unsigned char p_card)
1da177e4 4056{
c823feeb 4057 unsigned short TimeOutLoop;
db038cf8 4058 unsigned char sPhase;
1da177e4
LT
4059
4060 PSCCB currSCCB;
4061
47b5d69c 4062 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4063
4064
4065 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4066 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4067 return;
4068 }
4069
4070
4071
4072 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4073 {
4074
4075 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4076
4077 currSCCB->Sccb_XferCnt = 1;
4078
4079 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
c823feeb 4080 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
1da177e4
LT
4081 WR_HARPOON(port+hp_xferstat, 0x00);
4082 }
4083
4084 else
4085 {
4086
4087 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4088
4089 currSCCB->Sccb_XferCnt = 0;
4090 }
4091
4092 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4093 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4094
4095 currSCCB->HostStatus = SCCB_PARITY_ERR;
4096 WRW_HARPOON((port+hp_intstat), PARITY);
4097 }
4098
4099
47b5d69c 4100 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4
LT
4101
4102
4103 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4104
4105 TimeOutLoop = 0;
4106
4107 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4108 {
4109 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4110 return;
4111 }
db038cf8 4112 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
1da177e4
LT
4113 break;
4114 }
4115 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4116 return;
4117 }
4118 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4119 break;
4120 }
4121
4122 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4123 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
db038cf8 4124 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
1da177e4
LT
4125 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4126 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4127 {
4128
4129 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4130
4131 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4132 {
4133 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
47b5d69c 4134 FPT_phaseDataIn(port,p_card);
1da177e4
LT
4135 }
4136
4137 else {
47b5d69c 4138 FPT_phaseDataOut(port,p_card);
1da177e4
LT
4139 }
4140 }
4141 else
4142 {
47b5d69c 4143 FPT_sxfrp(port,p_card);
1da177e4
LT
4144 if (!(RDW_HARPOON((port+hp_intstat)) &
4145 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4146 {
4147 WRW_HARPOON((port+hp_intstat), AUTO_INT);
47b5d69c 4148 FPT_phaseDecode(port,p_card);
1da177e4
LT
4149 }
4150 }
4151
4152 }
4153
4154 else {
4155 WR_HARPOON(port+hp_portctrl_0, 0x00);
4156 }
4157}
4158
4159
4160/*---------------------------------------------------------------------
4161 *
47b5d69c 4162 * Function: FPT_sinits
1da177e4
LT
4163 *
4164 * Description: Setup SCCB manager fields in this SCCB.
4165 *
4166 *---------------------------------------------------------------------*/
4167
db038cf8 4168static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
1da177e4
LT
4169{
4170 PSCCBMgr_tar_info currTar_Info;
4171
4172 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4173 {
4174 return;
4175 }
47b5d69c 4176 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4
LT
4177
4178 p_sccb->Sccb_XferState = 0x00;
4179 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4180
4181 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4182 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4183
4184 p_sccb->Sccb_SGoffset = 0;
4185 p_sccb->Sccb_XferState = F_SG_XFER;
4186 p_sccb->Sccb_XferCnt = 0x00;
4187 }
4188
4189 if (p_sccb->DataLength == 0x00)
4190
4191 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4192
4193 if (p_sccb->ControlByte & F_USE_CMD_Q)
4194 {
4195 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4196 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4197
4198 else
4199 currTar_Info->TarStatus |= TAG_Q_TRYING;
4200 }
4201
4202/* For !single SCSI device in system & device allow Disconnect
4203 or command is tag_q type then send Cmd with Disconnect Enable
4204 else send Cmd with Disconnect Disable */
4205
4206/*
47b5d69c 4207 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
1da177e4
LT
4208 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4209 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4210*/
4211 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4212 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
db038cf8 4213 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
1da177e4
LT
4214 }
4215
4216 else {
4217
db038cf8 4218 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
1da177e4
LT
4219 }
4220
4221 p_sccb->HostStatus = 0x00;
4222 p_sccb->TargetStatus = 0x00;
4223 p_sccb->Sccb_tag = 0x00;
4224 p_sccb->Sccb_MGRFlags = 0x00;
4225 p_sccb->Sccb_sgseg = 0x00;
4226 p_sccb->Sccb_ATC = 0x00;
4227 p_sccb->Sccb_savedATC = 0x00;
4228/*
4229 p_sccb->SccbVirtDataPtr = 0x00;
4230 p_sccb->Sccb_forwardlink = NULL;
4231 p_sccb->Sccb_backlink = NULL;
4232 */
4233 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4234 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4235 p_sccb->Sccb_scsimsg = SMNO_OP;
4236
4237}
4238
4239
1da177e4
LT
4240/*---------------------------------------------------------------------
4241 *
4242 * Function: Phase Decode
4243 *
4244 * Description: Determine the phase and call the appropriate function.
4245 *
4246 *---------------------------------------------------------------------*/
4247
db038cf8 4248static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
1da177e4
LT
4249{
4250 unsigned char phase_ref;
db038cf8 4251 void (*phase) (ULONG, unsigned char);
1da177e4
LT
4252
4253
4254 DISABLE_AUTO(p_port);
4255
db038cf8 4256 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
1da177e4 4257
47b5d69c 4258 phase = FPT_s_PhaseTbl[phase_ref];
1da177e4
LT
4259
4260 (*phase)(p_port, p_card); /* Call the correct phase func */
4261}
4262
4263
4264
4265/*---------------------------------------------------------------------
4266 *
4267 * Function: Data Out Phase
4268 *
4269 * Description: Start up both the BusMaster and Xbow.
4270 *
4271 *---------------------------------------------------------------------*/
4272
db038cf8 4273static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
1da177e4
LT
4274{
4275
4276 PSCCB currSCCB;
4277
47b5d69c 4278 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4279 if (currSCCB == NULL)
4280 {
4281 return; /* Exit if No SCCB record */
4282 }
4283
4284 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4285 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4286
4287 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4288
4289 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4290
4291 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4292
47b5d69c 4293 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4294
4295 if (currSCCB->Sccb_XferCnt == 0) {
4296
4297
4298 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4299 (currSCCB->HostStatus == SCCB_COMPLETE))
4300 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4301
47b5d69c 4302 FPT_sxfrp(port,p_card);
1da177e4 4303 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
47b5d69c 4304 FPT_phaseDecode(port,p_card);
1da177e4
LT
4305 }
4306}
4307
4308
4309/*---------------------------------------------------------------------
4310 *
4311 * Function: Data In Phase
4312 *
4313 * Description: Startup the BusMaster and the XBOW.
4314 *
4315 *---------------------------------------------------------------------*/
4316
db038cf8 4317static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
1da177e4
LT
4318{
4319
4320 PSCCB currSCCB;
4321
47b5d69c 4322 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4323
4324 if (currSCCB == NULL)
4325 {
4326 return; /* Exit if No SCCB record */
4327 }
4328
4329
4330 currSCCB->Sccb_scsistat = DATA_IN_ST;
4331 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4332 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4333
4334 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4335
4336 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4337
4338 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4339
47b5d69c 4340 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4341
4342 if (currSCCB->Sccb_XferCnt == 0) {
4343
4344
4345 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4346 (currSCCB->HostStatus == SCCB_COMPLETE))
4347 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4348
47b5d69c 4349 FPT_sxfrp(port,p_card);
1da177e4 4350 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
47b5d69c 4351 FPT_phaseDecode(port,p_card);
1da177e4
LT
4352
4353 }
4354}
4355
4356/*---------------------------------------------------------------------
4357 *
4358 * Function: Command Phase
4359 *
4360 * Description: Load the CDB into the automation and start it up.
4361 *
4362 *---------------------------------------------------------------------*/
4363
db038cf8 4364static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
1da177e4
LT
4365{
4366 PSCCB currSCCB;
1da177e4 4367 ULONG cdb_reg;
db038cf8 4368 unsigned char i;
1da177e4 4369
47b5d69c 4370 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4371
4372 if (currSCCB->OperationCode == RESET_COMMAND) {
4373
4374 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4375 currSCCB->CdbLength = SIX_BYTE_CMD;
4376 }
4377
4378 WR_HARPOON(p_port+hp_scsisig, 0x00);
4379
4380 ARAM_ACCESS(p_port);
4381
4382
4383 cdb_reg = p_port + CMD_STRT;
4384
4385 for (i=0; i < currSCCB->CdbLength; i++) {
4386
4387 if (currSCCB->OperationCode == RESET_COMMAND)
4388
4389 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4390
4391 else
4392 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4393 cdb_reg +=2;
4394 }
4395
4396 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4397 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4398
4399 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4400
4401 currSCCB->Sccb_scsistat = COMMAND_ST;
4402
4403 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4404 SGRAM_ACCESS(p_port);
4405}
4406
4407
4408/*---------------------------------------------------------------------
4409 *
4410 * Function: Status phase
4411 *
4412 * Description: Bring in the status and command complete message bytes
4413 *
4414 *---------------------------------------------------------------------*/
4415
db038cf8 4416static void FPT_phaseStatus(ULONG port, unsigned char p_card)
1da177e4
LT
4417{
4418 /* Start-up the automation to finish off this command and let the
4419 isr handle the interrupt for command complete when it comes in.
4420 We could wait here for the interrupt to be generated?
4421 */
4422
4423 WR_HARPOON(port+hp_scsisig, 0x00);
4424
4425 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4426}
4427
4428
4429/*---------------------------------------------------------------------
4430 *
4431 * Function: Phase Message Out
4432 *
4433 * Description: Send out our message (if we have one) and handle whatever
4434 * else is involed.
4435 *
4436 *---------------------------------------------------------------------*/
4437
db038cf8 4438static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
1da177e4 4439{
db038cf8 4440 unsigned char message,scsiID;
1da177e4
LT
4441 PSCCB currSCCB;
4442 PSCCBMgr_tar_info currTar_Info;
4443
47b5d69c 4444 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4445
4446 if (currSCCB != NULL) {
4447
4448 message = currSCCB->Sccb_scsimsg;
4449 scsiID = currSCCB->TargID;
4450
4451 if (message == SMDEV_RESET)
4452 {
4453
4454
47b5d69c 4455 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4 4456 currTar_Info->TarSyncCtrl = 0;
47b5d69c 4457 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
1da177e4 4458
47b5d69c 4459 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
1da177e4
LT
4460 {
4461
47b5d69c 4462 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
4463
4464 }
4465
47b5d69c 4466 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
1da177e4
LT
4467 {
4468
47b5d69c 4469 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
4470 }
4471
4472
47b5d69c
JB
4473 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4474 FPT_SccbMgrTableInitTarget(p_card,scsiID);
1da177e4
LT
4475 }
4476 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4477 {
4478 currSCCB->HostStatus = SCCB_COMPLETE;
47b5d69c 4479 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
1da177e4 4480 {
47b5d69c
JB
4481 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4482 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
1da177e4
LT
4483 }
4484
4485 }
4486
4487 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4488 {
4489
4490
4491 if(message == SMNO_OP)
4492 {
4493 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4494
47b5d69c 4495 FPT_ssel(port,p_card);
1da177e4
LT
4496 return;
4497 }
4498 }
4499 else
4500 {
4501
4502
4503 if (message == SMABORT)
4504
47b5d69c 4505 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
1da177e4
LT
4506 }
4507
4508 }
4509 else
4510 {
4511 message = SMABORT;
4512 }
4513
4514 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4515
4516
4517 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4518
4519 WR_HARPOON(port+hp_scsidata_0,message);
4520
4521 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4522
4523 ACCEPT_MSG(port);
4524
4525 WR_HARPOON(port+hp_portctrl_0, 0x00);
4526
4527 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4528 (message == SMABORT_TAG) )
4529 {
4530
4531 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4532
4533 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4534 {
4535 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4536
4537 if (currSCCB != NULL)
4538 {
4539
47b5d69c
JB
4540 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4541 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4542 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4543 else
47b5d69c 4544 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4545
47b5d69c 4546 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
1da177e4
LT
4547 }
4548
4549 else
4550 {
47b5d69c 4551 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4
LT
4552 }
4553 }
4554
4555 else
4556 {
4557
47b5d69c 4558 FPT_sxfrp(port,p_card);
1da177e4
LT
4559 }
4560 }
4561
4562 else
4563 {
4564
4565 if(message == SMPARITY)
4566 {
4567 currSCCB->Sccb_scsimsg = SMNO_OP;
4568 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4569 }
4570 else
4571 {
47b5d69c 4572 FPT_sxfrp(port,p_card);
1da177e4
LT
4573 }
4574 }
4575}
4576
4577
4578/*---------------------------------------------------------------------
4579 *
4580 * Function: Message In phase
4581 *
4582 * Description: Bring in the message and determine what to do with it.
4583 *
4584 *---------------------------------------------------------------------*/
4585
db038cf8 4586static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
1da177e4 4587{
db038cf8 4588 unsigned char message;
1da177e4
LT
4589 PSCCB currSCCB;
4590
47b5d69c 4591 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4592
47b5d69c 4593 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
1da177e4
LT
4594 {
4595
47b5d69c 4596 FPT_phaseChkFifo(port, p_card);
1da177e4
LT
4597 }
4598
4599 message = RD_HARPOON(port+hp_scsidata_0);
4600 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4601 {
4602
4603 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4604
4605 }
4606
4607 else
4608 {
4609
47b5d69c 4610 message = FPT_sfm(port,currSCCB);
1da177e4
LT
4611 if (message)
4612 {
4613
4614
47b5d69c 4615 FPT_sdecm(message,port,p_card);
1da177e4
LT
4616
4617 }
4618 else
4619 {
4620 if(currSCCB->Sccb_scsimsg != SMPARITY)
4621 ACCEPT_MSG(port);
4622 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4623 }
4624 }
4625
4626}
4627
4628
4629/*---------------------------------------------------------------------
4630 *
4631 * Function: Illegal phase
4632 *
4633 * Description: Target switched to some illegal phase, so all we can do
4634 * is report an error back to the host (if that is possible)
4635 * and send an ABORT message to the misbehaving target.
4636 *
4637 *---------------------------------------------------------------------*/
4638
db038cf8 4639static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
1da177e4
LT
4640{
4641 PSCCB currSCCB;
4642
47b5d69c 4643 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4644
4645 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4646 if (currSCCB != NULL) {
4647
4648 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4649 currSCCB->Sccb_scsistat = ABORT_ST;
4650 currSCCB->Sccb_scsimsg = SMABORT;
4651 }
4652
4653 ACCEPT_MSG_ATN(port);
4654}
4655
4656
4657
4658/*---------------------------------------------------------------------
4659 *
4660 * Function: Phase Check FIFO
4661 *
4662 * Description: Make sure data has been flushed from both FIFOs and abort
4663 * the operations if necessary.
4664 *
4665 *---------------------------------------------------------------------*/
4666
db038cf8 4667static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
1da177e4
LT
4668{
4669 ULONG xfercnt;
4670 PSCCB currSCCB;
4671
47b5d69c 4672 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4673
4674 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4675 {
4676
4677 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4678 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4679
4680
4681 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4682 {
4683 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4684
4685 currSCCB->Sccb_XferCnt = 0;
4686
4687 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4688 (currSCCB->HostStatus == SCCB_COMPLETE))
4689 {
4690 currSCCB->HostStatus = SCCB_PARITY_ERR;
4691 WRW_HARPOON((port+hp_intstat), PARITY);
4692 }
4693
47b5d69c 4694 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4 4695
47b5d69c 4696 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4697
4698 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4699 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4700
4701 }
4702 } /*End Data In specific code. */
4703
4704
4705
1da177e4 4706 GET_XFER_CNT(port,xfercnt);
1da177e4
LT
4707
4708
4709 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4710
4711
4712 WR_HARPOON(port+hp_portctrl_0, 0x00);
4713
4714 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4715
4716 currSCCB->Sccb_XferCnt = xfercnt;
4717
4718 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4719 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4720
4721 currSCCB->HostStatus = SCCB_PARITY_ERR;
4722 WRW_HARPOON((port+hp_intstat), PARITY);
4723 }
4724
4725
47b5d69c 4726 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4
LT
4727
4728
4729 WR_HARPOON(port+hp_fifowrite, 0x00);
4730 WR_HARPOON(port+hp_fiforead, 0x00);
4731 WR_HARPOON(port+hp_xferstat, 0x00);
4732
4733 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4734}
4735
4736
4737/*---------------------------------------------------------------------
4738 *
4739 * Function: Phase Bus Free
4740 *
4741 * Description: We just went bus free so figure out if it was
4742 * because of command complete or from a disconnect.
4743 *
4744 *---------------------------------------------------------------------*/
db038cf8 4745static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
1da177e4
LT
4746{
4747 PSCCB currSCCB;
4748
47b5d69c 4749 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4750
4751 if (currSCCB != NULL)
4752 {
4753
4754 DISABLE_AUTO(port);
4755
4756
4757 if (currSCCB->OperationCode == RESET_COMMAND)
4758 {
4759
47b5d69c
JB
4760 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4761 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4763 else
47b5d69c 4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4765
47b5d69c 4766 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 4767
47b5d69c 4768 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
4769
4770 }
4771
4772 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4773 {
47b5d69c 4774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
db038cf8 4775 (unsigned char)SYNC_SUPPORTED;
47b5d69c 4776 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
1da177e4
LT
4777 }
4778
4779 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4780 {
47b5d69c
JB
4781 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4782 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
1da177e4
LT
4783 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4784
47b5d69c 4785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
1da177e4
LT
4786 }
4787
1da177e4
LT
4788 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4789 {
4790 /* Make sure this is not a phony BUS_FREE. If we were
4791 reselected or if BUSY is NOT on then this is a
4792 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4793
4794 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4795 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4796 {
47b5d69c
JB
4797 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4798 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
1da177e4
LT
4799 }
4800
4801 else
4802 {
4803 return;
4804 }
4805 }
1da177e4
LT
4806
4807 else
4808 {
4809
4810 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4811
4812 if (!currSCCB->HostStatus)
4813 {
4814 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4815 }
4816
47b5d69c
JB
4817 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4818 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4819 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4820 else
47b5d69c 4821 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4822
47b5d69c 4823 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4
LT
4824 return;
4825 }
4826
4827
47b5d69c 4828 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4
LT
4829
4830 } /*end if !=null */
4831}
4832
4833
4834
4835
1da177e4
LT
4836/*---------------------------------------------------------------------
4837 *
4838 * Function: Auto Load Default Map
4839 *
4840 * Description: Load the Automation RAM with the defualt map values.
4841 *
4842 *---------------------------------------------------------------------*/
47b5d69c 4843static void FPT_autoLoadDefaultMap(ULONG p_port)
1da177e4 4844{
1da177e4 4845 ULONG map_addr;
1da177e4
LT
4846
4847 ARAM_ACCESS(p_port);
4848 map_addr = p_port + hp_aramBase;
4849
4850 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4851 map_addr +=2;
4852 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4873 map_addr +=2;
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4875 map_addr +=2;
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4877 map_addr +=2;
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4883 map_addr +=2;
4884 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4885 map_addr +=2; /*This means AYNC DATA IN */
4886 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4887 map_addr +=2;
4888 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4909 map_addr +=2;
4910 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4911 map_addr +=2;
4912 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4913 map_addr +=2;
4914 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4917 map_addr +=2;
4918 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4919 map_addr +=2;
4920 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4921 map_addr +=2;
4922
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4924 map_addr +=2;
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4926 map_addr +=2;
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4928 map_addr +=2;
4929 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4930 map_addr +=2; /* DIDN'T GET ONE */
4931 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4932 map_addr +=2;
4933 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4934 map_addr +=2;
4935 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4936
4937
4938
4939 SGRAM_ACCESS(p_port);
4940}
4941
4942/*---------------------------------------------------------------------
4943 *
4944 * Function: Auto Command Complete
4945 *
4946 * Description: Post command back to host and find another command
4947 * to execute.
4948 *
4949 *---------------------------------------------------------------------*/
4950
db038cf8 4951static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
1da177e4
LT
4952{
4953 PSCCB currSCCB;
db038cf8 4954 unsigned char status_byte;
1da177e4 4955
47b5d69c 4956 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4957
4958 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4959
47b5d69c 4960 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
1da177e4
LT
4961
4962 if (status_byte != SSGOOD) {
4963
4964 if (status_byte == SSQ_FULL) {
4965
4966
47b5d69c
JB
4967 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4968 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 4969 {
47b5d69c
JB
4970 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4971 if(FPT_BL_Card[p_card].discQCount != 0)
4972 FPT_BL_Card[p_card].discQCount--;
4973 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
4974 }
4975 else
4976 {
47b5d69c 4977 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
4978 if(currSCCB->Sccb_tag)
4979 {
47b5d69c
JB
4980 if(FPT_BL_Card[p_card].discQCount != 0)
4981 FPT_BL_Card[p_card].discQCount--;
4982 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
4983 }else
4984 {
47b5d69c
JB
4985 if(FPT_BL_Card[p_card].discQCount != 0)
4986 FPT_BL_Card[p_card].discQCount--;
4987 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
4988 }
4989 }
4990
4991 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4992
47b5d69c 4993 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
4994
4995 return;
4996 }
4997
4998 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4999 {
47b5d69c 5000 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
db038cf8 5001 (unsigned char)SYNC_SUPPORTED;
1da177e4 5002
47b5d69c
JB
5003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5004 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5005
47b5d69c
JB
5006 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5007 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 5008 {
47b5d69c
JB
5009 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5010 if(FPT_BL_Card[p_card].discQCount != 0)
5011 FPT_BL_Card[p_card].discQCount--;
5012 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
5013 }
5014 else
5015 {
47b5d69c 5016 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5017 if(currSCCB->Sccb_tag)
5018 {
47b5d69c
JB
5019 if(FPT_BL_Card[p_card].discQCount != 0)
5020 FPT_BL_Card[p_card].discQCount--;
5021 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
5022 }else
5023 {
47b5d69c
JB
5024 if(FPT_BL_Card[p_card].discQCount != 0)
5025 FPT_BL_Card[p_card].discQCount--;
5026 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
5027 }
5028 }
5029 return;
5030
5031 }
5032
5033 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5034 {
5035
47b5d69c
JB
5036 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5037 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
1da177e4
LT
5038 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5039
47b5d69c
JB
5040 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5041 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5042
47b5d69c
JB
5043 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5044 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 5045 {
47b5d69c
JB
5046 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5047 if(FPT_BL_Card[p_card].discQCount != 0)
5048 FPT_BL_Card[p_card].discQCount--;
5049 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
5050 }
5051 else
5052 {
47b5d69c 5053 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5054 if(currSCCB->Sccb_tag)
5055 {
47b5d69c
JB
5056 if(FPT_BL_Card[p_card].discQCount != 0)
5057 FPT_BL_Card[p_card].discQCount--;
5058 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
5059 }else
5060 {
47b5d69c
JB
5061 if(FPT_BL_Card[p_card].discQCount != 0)
5062 FPT_BL_Card[p_card].discQCount--;
5063 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
5064 }
5065 }
5066 return;
5067
5068 }
5069
5070 if (status_byte == SSCHECK)
5071 {
47b5d69c 5072 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
1da177e4 5073 {
47b5d69c 5074 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
1da177e4 5075 {
47b5d69c 5076 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
1da177e4 5077 }
47b5d69c 5078 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
1da177e4 5079 {
47b5d69c 5080 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
5081 }
5082 }
5083 }
5084
5085 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5086
5087 currSCCB->SccbStatus = SCCB_ERROR;
5088 currSCCB->TargetStatus = status_byte;
5089
5090 if (status_byte == SSCHECK) {
5091
47b5d69c
JB
5092 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5093 = 1;
1da177e4
LT
5094
5095
1da177e4
LT
5096 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5097
5098 if (currSCCB->RequestSenseLength == 0)
5099 currSCCB->RequestSenseLength = 14;
5100
47b5d69c
JB
5101 FPT_ssenss(&FPT_BL_Card[p_card]);
5102 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5103
47b5d69c
JB
5104 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5105 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 5106 {
47b5d69c
JB
5107 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5108 if(FPT_BL_Card[p_card].discQCount != 0)
5109 FPT_BL_Card[p_card].discQCount--;
5110 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
5111 }
5112 else
5113 {
47b5d69c 5114 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5115 if(currSCCB->Sccb_tag)
5116 {
47b5d69c
JB
5117 if(FPT_BL_Card[p_card].discQCount != 0)
5118 FPT_BL_Card[p_card].discQCount--;
5119 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
5120 }else
5121 {
47b5d69c
JB
5122 if(FPT_BL_Card[p_card].discQCount != 0)
5123 FPT_BL_Card[p_card].discQCount--;
5124 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
5125 }
5126 }
5127 return;
5128 }
1da177e4
LT
5129 }
5130 }
5131 }
5132
5133
47b5d69c
JB
5134 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5135 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5136 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 5137 else
47b5d69c 5138 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4
LT
5139
5140
47b5d69c 5141 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 5142}
1da177e4
LT
5143
5144#define SHORT_WAIT 0x0000000F
5145#define LONG_WAIT 0x0000FFFFL
5146
1da177e4
LT
5147
5148/*---------------------------------------------------------------------
5149 *
5150 * Function: Data Transfer Processor
5151 *
5152 * Description: This routine performs two tasks.
5153 * (1) Start data transfer by calling HOST_DATA_XFER_START
5154 * function. Once data transfer is started, (2) Depends
5155 * on the type of data transfer mode Scatter/Gather mode
5156 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5157 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5158 * data transfer done. In Scatter/Gather mode, this routine
5159 * checks bus master command complete and dual rank busy
5160 * bit to keep chaining SC transfer command. Similarly,
5161 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5162 * (F_HOST_XFER_ACT bit) for data transfer done.
5163 *
5164 *---------------------------------------------------------------------*/
5165
47b5d69c 5166static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
1da177e4
LT
5167{
5168 PSCCB currSCCB;
5169
5170 currSCCB = pCurrCard->currentSCCB;
5171
5172 if (currSCCB->Sccb_XferState & F_SG_XFER)
5173 {
5174 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5175
5176 {
db038cf8 5177 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
1da177e4
LT
5178 currSCCB->Sccb_SGoffset = 0x00;
5179 }
5180 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5181
47b5d69c 5182 FPT_busMstrSGDataXferStart(port, currSCCB);
1da177e4
LT
5183 }
5184
5185 else
5186 {
5187 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5188 {
5189 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5190
47b5d69c 5191 FPT_busMstrDataXferStart(port, currSCCB);
1da177e4
LT
5192 }
5193 }
5194}
5195
5196
5197/*---------------------------------------------------------------------
5198 *
5199 * Function: BusMaster Scatter Gather Data Transfer Start
5200 *
5201 * Description:
5202 *
5203 *---------------------------------------------------------------------*/
47b5d69c 5204static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
1da177e4
LT
5205{
5206 ULONG count,addr,tmpSGCnt;
ce793215 5207 unsigned int sg_index;
db038cf8 5208 unsigned char sg_count, i;
1da177e4 5209 ULONG reg_offset;
1da177e4
LT
5210
5211
5212 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5213
5214 count = ((ULONG) HOST_RD_CMD)<<24;
5215 }
5216
5217 else {
5218 count = ((ULONG) HOST_WRT_CMD)<<24;
5219 }
5220
5221 sg_count = 0;
5222 tmpSGCnt = 0;
5223 sg_index = pcurrSCCB->Sccb_sgseg;
5224 reg_offset = hp_aramBase;
5225
5226
db038cf8 5227 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
1da177e4
LT
5228
5229
5230 WR_HARPOON(p_port+hp_page_ctrl, i);
5231
db038cf8 5232 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
ce793215 5233 ((ULONG)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
1da177e4 5234
1da177e4
LT
5235 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5236 (sg_index * 2));
5237
5238 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5239 (sg_index * 2));
5240
5241 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5242 ((sg_index * 2) + 1));
1da177e4
LT
5243
5244
5245 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5246
5247 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5248 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5249
5250 tmpSGCnt = count & 0x00FFFFFFL;
5251 }
5252
5253 WR_HARP32(p_port,reg_offset,addr);
5254 reg_offset +=4;
5255
5256 WR_HARP32(p_port,reg_offset,count);
5257 reg_offset +=4;
5258
5259 count &= 0xFF000000L;
5260 sg_index++;
5261 sg_count++;
5262
5263 } /*End While */
5264
5265 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5266
5267 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5268
5269 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5270
5271 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5272
5273
5274 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5275 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5276 }
5277
5278 else {
5279
5280
5281 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5282 (tmpSGCnt & 0x000000001))
5283 {
5284
5285 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5286 tmpSGCnt--;
5287 }
5288
5289
5290 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5291
5292 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5293 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5294 }
5295
5296
db038cf8 5297 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
1da177e4
LT
5298
5299}
5300
5301
5302/*---------------------------------------------------------------------
5303 *
5304 * Function: BusMaster Data Transfer Start
5305 *
5306 * Description:
5307 *
5308 *---------------------------------------------------------------------*/
47b5d69c 5309static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
1da177e4
LT
5310{
5311 ULONG addr,count;
5312
5313 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5314
5315 count = pcurrSCCB->Sccb_XferCnt;
5316
5317 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5318 }
5319
5320 else {
5321 addr = pcurrSCCB->SensePointer;
5322 count = pcurrSCCB->RequestSenseLength;
5323
5324 }
5325
1da177e4 5326 HP_SETUP_ADDR_CNT(p_port,addr,count);
1da177e4
LT
5327
5328
5329 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5330
5331 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5332 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5333
5334 WR_HARPOON(p_port+hp_xfer_cmd,
5335 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5336 }
5337
5338 else {
5339
5340 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5341 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5342
5343 WR_HARPOON(p_port+hp_xfer_cmd,
5344 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5345
5346 }
5347}
5348
5349
5350/*---------------------------------------------------------------------
5351 *
5352 * Function: BusMaster Timeout Handler
5353 *
5354 * Description: This function is called after a bus master command busy time
5355 * out is detected. This routines issue halt state machine
5356 * with a software time out for command busy. If command busy
5357 * is still asserted at the end of the time out, it issues
5358 * hard abort with another software time out. It hard abort
5359 * command busy is also time out, it'll just give up.
5360 *
5361 *---------------------------------------------------------------------*/
db038cf8 5362static unsigned char FPT_busMstrTimeOut(ULONG p_port)
1da177e4
LT
5363{
5364 ULONG timeout;
5365
5366 timeout = LONG_WAIT;
5367
5368 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5369
5370 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5371
5372
5373
5374 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5375 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5376
5377 timeout = LONG_WAIT;
5378 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5379 }
5380
5381 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5382
5383 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
47b5d69c 5384 return(1);
1da177e4
LT
5385 }
5386
5387 else {
47b5d69c 5388 return(0);
1da177e4
LT
5389 }
5390}
5391
5392
5393/*---------------------------------------------------------------------
5394 *
5395 * Function: Host Data Transfer Abort
5396 *
5397 * Description: Abort any in progress transfer.
5398 *
5399 *---------------------------------------------------------------------*/
db038cf8 5400static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
1da177e4
LT
5401{
5402
5403 ULONG timeout;
5404 ULONG remain_cnt;
ce793215 5405 unsigned int sg_ptr;
1da177e4 5406
47b5d69c 5407 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
1da177e4
LT
5408
5409 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5410
5411
5412 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5413
5414 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5415 timeout = LONG_WAIT;
5416
5417 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5418
5419 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5420
5421 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5422
47b5d69c 5423 if (FPT_busMstrTimeOut(port)) {
1da177e4
LT
5424
5425 if (pCurrSCCB->HostStatus == 0x00)
5426
5427 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5428
5429 }
5430
5431 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5432
5433 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5434
5435 if (pCurrSCCB->HostStatus == 0x00)
5436
5437 {
5438 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5439 }
5440 }
5441 }
5442 }
5443
5444 else if (pCurrSCCB->Sccb_XferCnt) {
5445
5446 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5447
5448
5449 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5450 ~SCATTER_EN));
5451
5452 WR_HARPOON(port+hp_sg_addr,0x00);
5453
5454 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5455
ce793215 5456 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
1da177e4 5457
ce793215 5458 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
1da177e4
LT
5459 }
5460
5461 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5462
5463 while (remain_cnt < 0x01000000L) {
5464
5465 sg_ptr--;
5466
1da177e4
LT
5467 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5468 DataPointer) + (sg_ptr * 2)))) {
5469
5470 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5471 DataPointer) + (sg_ptr * 2)));
5472 }
1da177e4
LT
5473
5474 else {
5475
5476 break;
5477 }
5478 }
5479
5480
5481
5482 if (remain_cnt < 0x01000000L) {
5483
5484
5485 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5486
c823feeb 5487 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
1da177e4
LT
5488
5489
5490 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5491 && (remain_cnt == 0))
5492
5493 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5494 }
5495
5496 else {
5497
5498
5499 if (pCurrSCCB->HostStatus == 0x00) {
5500
5501 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5502 }
5503 }
5504 }
5505
5506
5507 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5508
5509
5510 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5511
47b5d69c 5512 FPT_busMstrTimeOut(port);
1da177e4
LT
5513 }
5514
5515 else {
5516
5517 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5518
5519 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5520
5521 if (pCurrSCCB->HostStatus == 0x00) {
5522
5523 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5524 }
5525 }
5526 }
5527
5528 }
5529 }
5530
5531 else {
5532
5533
5534 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5535
5536 timeout = SHORT_WAIT;
5537
5538 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5539 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5540 timeout--) {}
5541 }
5542
5543 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5544
5545 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5546 FLUSH_XFER_CNTR));
5547
5548 timeout = LONG_WAIT;
5549
5550 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5551 timeout--) {}
5552
5553 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5554 ~FLUSH_XFER_CNTR));
5555
5556
5557 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5558
5559 if (pCurrSCCB->HostStatus == 0x00) {
5560
5561 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5562 }
5563
47b5d69c 5564 FPT_busMstrTimeOut(port);
1da177e4
LT
5565 }
5566 }
5567
5568 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5569
5570 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5571
5572 if (pCurrSCCB->HostStatus == 0x00) {
5573
5574 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5575 }
5576 }
5577 }
5578 }
5579
5580 }
5581
5582 else {
5583
5584
5585 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5586
5587 timeout = LONG_WAIT;
5588
5589 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5590
5591 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5592
5593 if (pCurrSCCB->HostStatus == 0x00) {
5594
5595 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5596 }
5597
47b5d69c 5598 FPT_busMstrTimeOut(port);
1da177e4
LT
5599 }
5600 }
5601
5602
5603 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5604
5605 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5606
5607 if (pCurrSCCB->HostStatus == 0x00) {
5608
5609 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5610 }
5611 }
5612
5613 }
5614
5615 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5616
5617 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5618 ~SCATTER_EN));
5619
5620 WR_HARPOON(port+hp_sg_addr,0x00);
5621
5622 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5623
5624 pCurrSCCB->Sccb_SGoffset = 0x00;
5625
5626
5627 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5628 pCurrSCCB->DataLength) {
5629
5630 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5631
c823feeb 5632 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
1da177e4
LT
5633
5634 }
5635 }
5636
5637 else {
5638
5639 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5640
5641 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5642 }
5643 }
5644
5645 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5646}
5647
5648
5649
5650/*---------------------------------------------------------------------
5651 *
5652 * Function: Host Data Transfer Restart
5653 *
5654 * Description: Reset the available count due to a restore data
5655 * pointers message.
5656 *
5657 *---------------------------------------------------------------------*/
47b5d69c 5658static void FPT_hostDataXferRestart(PSCCB currSCCB)
1da177e4
LT
5659{
5660 ULONG data_count;
ce793215 5661 unsigned int sg_index;
1da177e4 5662 ULONG *sg_ptr;
1da177e4
LT
5663
5664 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5665
5666 currSCCB->Sccb_XferCnt = 0;
5667
5668 sg_index = 0xffff; /*Index by long words into sg list. */
5669 data_count = 0; /*Running count of SG xfer counts. */
5670
1da177e4 5671 sg_ptr = (ULONG *)currSCCB->DataPointer;
1da177e4
LT
5672
5673 while (data_count < currSCCB->Sccb_ATC) {
5674
5675 sg_index++;
5676 data_count += *(sg_ptr+(sg_index * 2));
5677 }
5678
5679 if (data_count == currSCCB->Sccb_ATC) {
5680
5681 currSCCB->Sccb_SGoffset = 0;
5682 sg_index++;
5683 }
5684
5685 else {
5686 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5687 }
5688
c823feeb 5689 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
1da177e4
LT
5690 }
5691
5692 else {
5693 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5694 }
5695}
1da177e4
LT
5696
5697
5698
1da177e4
LT
5699/*---------------------------------------------------------------------
5700 *
47b5d69c 5701 * Function: FPT_scini
1da177e4
LT
5702 *
5703 * Description: Setup all data structures necessary for SCAM selection.
5704 *
5705 *---------------------------------------------------------------------*/
5706
db038cf8 5707static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
1da177e4
LT
5708{
5709
db038cf8 5710 unsigned char loser,assigned_id;
1da177e4 5711 ULONG p_port;
1da177e4 5712
db038cf8 5713 unsigned char i,k,ScamFlg ;
1da177e4
LT
5714 PSCCBcard currCard;
5715 PNVRamInfo pCurrNvRam;
5716
47b5d69c 5717 currCard = &FPT_BL_Card[p_card];
1da177e4
LT
5718 p_port = currCard->ioPort;
5719 pCurrNvRam = currCard->pNvRamInfo;
5720
5721
5722 if(pCurrNvRam){
5723 ScamFlg = pCurrNvRam->niScamConf;
5724 i = pCurrNvRam->niSysConf;
5725 }
5726 else{
db038cf8
AD
5727 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5728 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
1da177e4
LT
5729 }
5730 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5731 return;
5732
47b5d69c 5733 FPT_inisci(p_card,p_port, p_our_id);
1da177e4
LT
5734
5735 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5736 too slow to return to SCAM selection */
5737
5738 /* if (p_power_up)
47b5d69c 5739 FPT_Wait1Second(p_port);
1da177e4 5740 else
47b5d69c 5741 FPT_Wait(p_port, TO_250ms); */
1da177e4 5742
47b5d69c 5743 FPT_Wait1Second(p_port);
1da177e4
LT
5744
5745 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5746 {
47b5d69c 5747 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
1da177e4 5748
47b5d69c 5749 FPT_scsel(p_port);
1da177e4
LT
5750
5751 do {
47b5d69c
JB
5752 FPT_scxferc(p_port,SYNC_PTRN);
5753 FPT_scxferc(p_port,DOM_MSTR);
5754 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
1da177e4
LT
5755 } while ( loser == 0xFF );
5756
47b5d69c 5757 FPT_scbusf(p_port);
1da177e4
LT
5758
5759 if ((p_power_up) && (!loser))
5760 {
47b5d69c
JB
5761 FPT_sresb(p_port,p_card);
5762 FPT_Wait(p_port, TO_250ms);
1da177e4 5763
47b5d69c 5764 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
1da177e4 5765
47b5d69c 5766 FPT_scsel(p_port);
1da177e4
LT
5767
5768 do {
47b5d69c
JB
5769 FPT_scxferc(p_port, SYNC_PTRN);
5770 FPT_scxferc(p_port, DOM_MSTR);
5771 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
1da177e4
LT
5772 id_string[0]);
5773 } while ( loser == 0xFF );
5774
47b5d69c 5775 FPT_scbusf(p_port);
1da177e4
LT
5776 }
5777 }
5778
5779 else
5780 {
47b5d69c 5781 loser = 0;
1da177e4
LT
5782 }
5783
5784
5785 if (!loser)
5786 {
5787
47b5d69c 5788 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
1da177e4
LT
5789
5790
5791 if (ScamFlg & SCAM_ENABLED)
5792 {
5793
5794 for (i=0; i < MAX_SCSI_TAR; i++)
5795 {
47b5d69c
JB
5796 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5797 (FPT_scamInfo[i].state == ID_UNUSED))
1da177e4 5798 {
47b5d69c 5799 if (FPT_scsell(p_port,i))
1da177e4 5800 {
47b5d69c
JB
5801 FPT_scamInfo[i].state = LEGACY;
5802 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5803 (FPT_scamInfo[i].id_string[1] != 0xFA))
1da177e4
LT
5804 {
5805
47b5d69c
JB
5806 FPT_scamInfo[i].id_string[0] = 0xFF;
5807 FPT_scamInfo[i].id_string[1] = 0xFA;
1da177e4
LT
5808 if(pCurrNvRam == NULL)
5809 currCard->globalFlags |= F_UPDATE_EEPROM;
5810 }
5811 }
5812 }
5813 }
5814
47b5d69c
JB
5815 FPT_sresb(p_port,p_card);
5816 FPT_Wait1Second(p_port);
5817 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5818 FPT_scsel(p_port);
5819 FPT_scasid(p_card, p_port);
1da177e4
LT
5820 }
5821
1da177e4
LT
5822 }
5823
5824 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5825 {
47b5d69c
JB
5826 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5827 assigned_id = 0;
5828 FPT_scwtsel(p_port);
1da177e4
LT
5829
5830 do {
47b5d69c 5831 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
1da177e4 5832
47b5d69c 5833 i = FPT_scxferc(p_port,0x00);
1da177e4
LT
5834 if (i == ASSIGN_ID)
5835 {
47b5d69c 5836 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
1da177e4 5837 {
47b5d69c
JB
5838 i = FPT_scxferc(p_port,0x00);
5839 if (FPT_scvalq(i))
1da177e4 5840 {
47b5d69c 5841 k = FPT_scxferc(p_port,0x00);
1da177e4 5842
47b5d69c 5843 if (FPT_scvalq(k))
1da177e4
LT
5844 {
5845 currCard->ourId =
db038cf8 5846 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
47b5d69c
JB
5847 FPT_inisci(p_card, p_port, p_our_id);
5848 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5849 FPT_scamInfo[currCard->ourId].id_string[0]
1da177e4 5850 = SLV_TYPE_CODE0;
47b5d69c 5851 assigned_id = 1;
1da177e4
LT
5852 }
5853 }
5854 }
5855 }
5856
5857 else if (i == SET_P_FLAG)
5858 {
47b5d69c
JB
5859 if (!(FPT_scsendi(p_port,
5860 &FPT_scamInfo[p_our_id].id_string[0])))
5861 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
1da177e4
LT
5862 }
5863 }while (!assigned_id);
5864
47b5d69c 5865 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
1da177e4
LT
5866 }
5867
1da177e4
LT
5868 if (ScamFlg & SCAM_ENABLED)
5869 {
47b5d69c 5870 FPT_scbusf(p_port);
1da177e4
LT
5871 if (currCard->globalFlags & F_UPDATE_EEPROM)
5872 {
47b5d69c 5873 FPT_scsavdi(p_card, p_port);
1da177e4
LT
5874 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5875 }
5876 }
5877
5878
1da177e4
LT
5879/*
5880 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5881 {
47b5d69c
JB
5882 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5883 (FPT_scamInfo[i].state == LEGACY))
1da177e4
LT
5884 k++;
5885 }
5886
5887 if (k==2)
5888 currCard->globalFlags |= F_SINGLE_DEVICE;
5889 else
5890 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5891*/
5892}
5893
5894
5895/*---------------------------------------------------------------------
5896 *
47b5d69c 5897 * Function: FPT_scarb
1da177e4
LT
5898 *
5899 * Description: Gain control of the bus and wait SCAM select time (250ms)
5900 *
5901 *---------------------------------------------------------------------*/
5902
db038cf8 5903static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
1da177e4
LT
5904{
5905 if (p_sel_type == INIT_SELTD)
5906 {
5907
5908 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5909
5910
5911 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
47b5d69c 5912 return(0);
1da177e4
LT
5913
5914 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
47b5d69c 5915 return(0);
1da177e4
LT
5916
5917 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5918
5919 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5920
5921 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5922 ~SCSI_BSY));
47b5d69c 5923 return(0);
1da177e4
LT
5924 }
5925
5926
5927 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5928
5929 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5930
5931 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5932 ~(SCSI_BSY | SCSI_SEL)));
47b5d69c 5933 return(0);
1da177e4
LT
5934 }
5935 }
5936
5937
5938 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5939 & ~ACTdeassert));
5940 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5941 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
1da177e4 5942 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
1da177e4
LT
5943 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5944
5945 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5946
5947 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5948 & ~SCSI_BSY));
5949
47b5d69c 5950 FPT_Wait(p_port,TO_250ms);
1da177e4 5951
47b5d69c 5952 return(1);
1da177e4
LT
5953}
5954
5955
5956/*---------------------------------------------------------------------
5957 *
47b5d69c 5958 * Function: FPT_scbusf
1da177e4
LT
5959 *
5960 * Description: Release the SCSI bus and disable SCAM selection.
5961 *
5962 *---------------------------------------------------------------------*/
5963
47b5d69c 5964static void FPT_scbusf(ULONG p_port)
1da177e4
LT
5965{
5966 WR_HARPOON(p_port+hp_page_ctrl,
5967 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5968
5969
5970 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5971
5972 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5973 & ~SCSI_BUS_EN));
5974
5975 WR_HARPOON(p_port+hp_scsisig, 0x00);
5976
5977
5978 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5979 & ~SCAM_EN));
5980
5981 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5982 | ACTdeassert));
5983
1da177e4 5984 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
1da177e4
LT
5985
5986 WR_HARPOON(p_port+hp_page_ctrl,
5987 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5988}
5989
5990
5991
5992/*---------------------------------------------------------------------
5993 *
47b5d69c 5994 * Function: FPT_scasid
1da177e4
LT
5995 *
5996 * Description: Assign an ID to all the SCAM devices.
5997 *
5998 *---------------------------------------------------------------------*/
5999
db038cf8 6000static void FPT_scasid(unsigned char p_card, ULONG p_port)
1da177e4 6001{
db038cf8 6002 unsigned char temp_id_string[ID_STRING_LENGTH];
1da177e4 6003
db038cf8
AD
6004 unsigned char i,k,scam_id;
6005 unsigned char crcBytes[3];
1da177e4
LT
6006 PNVRamInfo pCurrNvRam;
6007 ushort_ptr pCrcBytes;
6008
47b5d69c 6009 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4 6010
47b5d69c 6011 i=0;
1da177e4
LT
6012
6013 while (!i)
6014 {
6015
6016 for (k=0; k < ID_STRING_LENGTH; k++)
6017 {
db038cf8 6018 temp_id_string[k] = (unsigned char) 0x00;
1da177e4
LT
6019 }
6020
47b5d69c
JB
6021 FPT_scxferc(p_port,SYNC_PTRN);
6022 FPT_scxferc(p_port,ASSIGN_ID);
1da177e4 6023
47b5d69c 6024 if (!(FPT_sciso(p_port,&temp_id_string[0])))
1da177e4
LT
6025 {
6026 if(pCurrNvRam){
6027 pCrcBytes = (ushort_ptr)&crcBytes[0];
47b5d69c
JB
6028 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6029 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
1da177e4
LT
6030 temp_id_string[1] = crcBytes[2];
6031 temp_id_string[2] = crcBytes[0];
6032 temp_id_string[3] = crcBytes[1];
6033 for(k = 4; k < ID_STRING_LENGTH; k++)
db038cf8 6034 temp_id_string[k] = (unsigned char) 0x00;
1da177e4 6035 }
47b5d69c 6036 i = FPT_scmachid(p_card,temp_id_string);
1da177e4
LT
6037
6038 if (i == CLR_PRIORITY)
6039 {
47b5d69c
JB
6040 FPT_scxferc(p_port,MISC_CODE);
6041 FPT_scxferc(p_port,CLR_P_FLAG);
6042 i = 0; /*Not the last ID yet. */
1da177e4
LT
6043 }
6044
6045 else if (i != NO_ID_AVAIL)
6046 {
6047 if (i < 8 )
47b5d69c 6048 FPT_scxferc(p_port,ID_0_7);
1da177e4 6049 else
47b5d69c 6050 FPT_scxferc(p_port,ID_8_F);
1da177e4 6051
db038cf8 6052 scam_id = (i & (unsigned char) 0x07);
1da177e4
LT
6053
6054
6055 for (k=1; k < 0x08; k <<= 1)
6056 if (!( k & i ))
6057 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6058
47b5d69c 6059 FPT_scxferc(p_port,scam_id);
1da177e4 6060
47b5d69c 6061 i = 0; /*Not the last ID yet. */
1da177e4
LT
6062 }
6063 }
6064
6065 else
6066 {
47b5d69c 6067 i = 1;
1da177e4
LT
6068 }
6069
6070 } /*End while */
6071
47b5d69c
JB
6072 FPT_scxferc(p_port,SYNC_PTRN);
6073 FPT_scxferc(p_port,CFG_CMPLT);
1da177e4
LT
6074}
6075
6076
6077
6078
6079
6080/*---------------------------------------------------------------------
6081 *
47b5d69c 6082 * Function: FPT_scsel
1da177e4
LT
6083 *
6084 * Description: Select all the SCAM devices.
6085 *
6086 *---------------------------------------------------------------------*/
6087
47b5d69c 6088static void FPT_scsel(ULONG p_port)
1da177e4
LT
6089{
6090
6091 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
47b5d69c 6092 FPT_scwiros(p_port, SCSI_MSG);
1da177e4
LT
6093
6094 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6095
6096
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
db038cf8
AD
6098 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6099 (unsigned char)(BIT(7)+BIT(6))));
1da177e4
LT
6100
6101
6102 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
47b5d69c 6103 FPT_scwiros(p_port, SCSI_SEL);
1da177e4 6104
db038cf8
AD
6105 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6106 ~(unsigned char)BIT(6)));
47b5d69c 6107 FPT_scwirod(p_port, BIT(6));
1da177e4
LT
6108
6109 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6110}
6111
6112
6113
6114/*---------------------------------------------------------------------
6115 *
47b5d69c 6116 * Function: FPT_scxferc
1da177e4
LT
6117 *
6118 * Description: Handshake the p_data (DB4-0) across the bus.
6119 *
6120 *---------------------------------------------------------------------*/
6121
db038cf8 6122static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
1da177e4 6123{
db038cf8 6124 unsigned char curr_data, ret_data;
1da177e4
LT
6125
6126 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6127
6128 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6129
6130 curr_data &= ~BIT(7);
6131
6132 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133
47b5d69c 6134 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
1da177e4
LT
6135 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6136
db038cf8 6137 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
1da177e4
LT
6138
6139 curr_data |= BIT(6);
6140
6141 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6142
6143 curr_data &= ~BIT(5);
6144
6145 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146
47b5d69c 6147 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
1da177e4
LT
6148
6149 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6150 curr_data |= BIT(7);
6151
6152 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6153
6154 curr_data &= ~BIT(6);
6155
6156 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6157
47b5d69c 6158 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
1da177e4
LT
6159
6160 return(ret_data);
6161}
6162
6163
6164/*---------------------------------------------------------------------
6165 *
47b5d69c 6166 * Function: FPT_scsendi
1da177e4
LT
6167 *
6168 * Description: Transfer our Identification string to determine if we
6169 * will be the dominant master.
6170 *
6171 *---------------------------------------------------------------------*/
6172
db038cf8 6173static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
1da177e4 6174{
db038cf8 6175 unsigned char ret_data,byte_cnt,bit_cnt,defer;
1da177e4 6176
47b5d69c 6177 defer = 0;
1da177e4
LT
6178
6179 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6180
6181 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6182
6183 if (defer)
47b5d69c 6184 ret_data = FPT_scxferc(p_port,00);
1da177e4
LT
6185
6186 else if (p_id_string[byte_cnt] & bit_cnt)
6187
47b5d69c 6188 ret_data = FPT_scxferc(p_port,02);
1da177e4
LT
6189
6190 else {
6191
47b5d69c 6192 ret_data = FPT_scxferc(p_port,01);
1da177e4 6193 if (ret_data & 02)
47b5d69c 6194 defer = 1;
1da177e4
LT
6195 }
6196
6197 if ((ret_data & 0x1C) == 0x10)
6198 return(0x00); /*End of isolation stage, we won! */
6199
6200 if (ret_data & 0x1C)
6201 return(0xFF);
6202
6203 if ((defer) && (!(ret_data & 0x1F)))
6204 return(0x01); /*End of isolation stage, we lost. */
6205
6206 } /*bit loop */
6207
6208 } /*byte loop */
6209
6210 if (defer)
6211 return(0x01); /*We lost */
6212 else
6213 return(0); /*We WON! Yeeessss! */
6214}
6215
6216
6217
6218/*---------------------------------------------------------------------
6219 *
47b5d69c 6220 * Function: FPT_sciso
1da177e4
LT
6221 *
6222 * Description: Transfer the Identification string.
6223 *
6224 *---------------------------------------------------------------------*/
6225
db038cf8 6226static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
1da177e4 6227{
db038cf8 6228 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
1da177e4
LT
6229
6230 the_data = 0;
6231
6232 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6233
6234 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6235
47b5d69c 6236 ret_data = FPT_scxferc(p_port,0);
1da177e4
LT
6237
6238 if (ret_data & 0xFC)
6239 return(0xFF);
6240
6241 else {
6242
6243 the_data <<= 1;
6244 if (ret_data & BIT(1)) {
6245 the_data |= 1;
6246 }
6247 }
6248
6249 if ((ret_data & 0x1F) == 0)
6250 {
6251/*
6252 if(bit_cnt != 0 || bit_cnt != 8)
6253 {
6254 byte_cnt = 0;
6255 bit_cnt = 0;
47b5d69c
JB
6256 FPT_scxferc(p_port, SYNC_PTRN);
6257 FPT_scxferc(p_port, ASSIGN_ID);
1da177e4
LT
6258 continue;
6259 }
6260*/
6261 if (byte_cnt)
6262 return(0x00);
6263 else
6264 return(0xFF);
6265 }
6266
6267 } /*bit loop */
6268
6269 p_id_string[byte_cnt] = the_data;
6270
6271 } /*byte loop */
6272
6273 return(0);
6274}
6275
6276
6277
6278/*---------------------------------------------------------------------
6279 *
47b5d69c 6280 * Function: FPT_scwirod
1da177e4
LT
6281 *
6282 * Description: Sample the SCSI data bus making sure the signal has been
6283 * deasserted for the correct number of consecutive samples.
6284 *
6285 *---------------------------------------------------------------------*/
6286
db038cf8 6287static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
1da177e4 6288{
db038cf8 6289 unsigned char i;
1da177e4
LT
6290
6291 i = 0;
6292 while ( i < MAX_SCSI_TAR ) {
6293
6294 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6295
6296 i = 0;
6297
6298 else
6299
6300 i++;
6301
6302 }
6303}
6304
6305
6306
6307/*---------------------------------------------------------------------
6308 *
47b5d69c 6309 * Function: FPT_scwiros
1da177e4
LT
6310 *
6311 * Description: Sample the SCSI Signal lines making sure the signal has been
6312 * deasserted for the correct number of consecutive samples.
6313 *
6314 *---------------------------------------------------------------------*/
6315
db038cf8 6316static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
1da177e4 6317{
db038cf8 6318 unsigned char i;
1da177e4 6319
47b5d69c
JB
6320 i = 0;
6321 while ( i < MAX_SCSI_TAR ) {
1da177e4 6322
47b5d69c 6323 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
1da177e4 6324
47b5d69c 6325 i = 0;
1da177e4 6326
47b5d69c 6327 else
1da177e4 6328
47b5d69c 6329 i++;
1da177e4 6330
1da177e4 6331 }
47b5d69c 6332}
1da177e4 6333
1da177e4 6334
47b5d69c
JB
6335/*---------------------------------------------------------------------
6336 *
6337 * Function: FPT_scvalq
6338 *
6339 * Description: Make sure we received a valid data byte.
6340 *
6341 *---------------------------------------------------------------------*/
1da177e4 6342
db038cf8 6343static unsigned char FPT_scvalq(unsigned char p_quintet)
47b5d69c 6344{
db038cf8 6345 unsigned char count;
1da177e4 6346
47b5d69c
JB
6347 for (count=1; count < 0x08; count<<=1) {
6348 if (!(p_quintet & count))
6349 p_quintet -= 0x80;
1da177e4 6350 }
47b5d69c
JB
6351
6352 if (p_quintet & 0x18)
6353 return(0);
6354
6355 else
6356 return(1);
1da177e4
LT
6357}
6358
47b5d69c 6359
1da177e4
LT
6360/*---------------------------------------------------------------------
6361 *
47b5d69c 6362 * Function: FPT_scsell
1da177e4
LT
6363 *
6364 * Description: Select the specified device ID using a selection timeout
47b5d69c
JB
6365 * less than 4ms. If somebody responds then it is a legacy
6366 * drive and this ID must be marked as such.
1da177e4
LT
6367 *
6368 *---------------------------------------------------------------------*/
6369
db038cf8 6370static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
1da177e4 6371{
47b5d69c 6372 ULONG i;
1da177e4
LT
6373
6374 WR_HARPOON(p_port+hp_page_ctrl,
6375 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6376
6377 ARAM_ACCESS(p_port);
6378
6379 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
47b5d69c 6380 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
1da177e4
LT
6381
6382
6383 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6384 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6385 }
6386 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6387
6388 WRW_HARPOON((p_port+hp_intstat),
6389 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6390
6391 WR_HARPOON(p_port+hp_select_id, targ_id);
6392
6393 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6394 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6395 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6396
6397
6398 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6399 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6400
6401 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
47b5d69c 6402 FPT_Wait(p_port, TO_250ms);
1da177e4
LT
6403
6404 DISABLE_AUTO(p_port);
6405
6406 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6407 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6408
6409 SGRAM_ACCESS(p_port);
6410
6411 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6412
6413 WRW_HARPOON((p_port+hp_intstat),
6414 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6415
6416 WR_HARPOON(p_port+hp_page_ctrl,
6417 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6418
47b5d69c 6419 return(0); /*No legacy device */
1da177e4
LT
6420 }
6421
6422 else {
6423
6424 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6425 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6426 {
6427 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6428 ACCEPT_MSG(p_port);
6429 }
6430 }
6431
6432 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6433
6434 WR_HARPOON(p_port+hp_page_ctrl,
6435 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6436
47b5d69c 6437 return(1); /*Found one of them oldies! */
1da177e4
LT
6438 }
6439}
1da177e4
LT
6440
6441/*---------------------------------------------------------------------
6442 *
47b5d69c 6443 * Function: FPT_scwtsel
1da177e4
LT
6444 *
6445 * Description: Wait to be selected by another SCAM initiator.
6446 *
6447 *---------------------------------------------------------------------*/
6448
47b5d69c 6449static void FPT_scwtsel(ULONG p_port)
1da177e4
LT
6450{
6451 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6452}
6453
6454
6455/*---------------------------------------------------------------------
6456 *
47b5d69c 6457 * Function: FPT_inisci
1da177e4
LT
6458 *
6459 * Description: Setup the data Structure with the info from the EEPROM.
6460 *
6461 *---------------------------------------------------------------------*/
6462
db038cf8 6463static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
1da177e4 6464{
db038cf8 6465 unsigned char i,k,max_id;
c823feeb 6466 unsigned short ee_data;
1da177e4
LT
6467 PNVRamInfo pCurrNvRam;
6468
47b5d69c 6469 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4
LT
6470
6471 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6472 max_id = 0x08;
6473
6474 else
6475 max_id = 0x10;
6476
6477 if(pCurrNvRam){
6478 for(i = 0; i < max_id; i++){
6479
6480 for(k = 0; k < 4; k++)
47b5d69c 6481 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
1da177e4 6482 for(k = 4; k < ID_STRING_LENGTH; k++)
db038cf8 6483 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
1da177e4 6484
47b5d69c
JB
6485 if(FPT_scamInfo[i].id_string[0] == 0x00)
6486 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4 6487 else
47b5d69c 6488 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6489
6490 }
6491 }else {
6492 for (i=0; i < max_id; i++)
6493 {
6494 for (k=0; k < ID_STRING_LENGTH; k+=2)
6495 {
c823feeb
AD
6496 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6497 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
db038cf8 6498 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
1da177e4 6499 ee_data >>= 8;
db038cf8 6500 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
1da177e4
LT
6501 }
6502
47b5d69c
JB
6503 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6504 (FPT_scamInfo[i].id_string[0] == 0xFF))
1da177e4 6505
47b5d69c 6506 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4
LT
6507
6508 else
47b5d69c 6509 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6510
6511 }
6512 }
6513 for(k = 0; k < ID_STRING_LENGTH; k++)
47b5d69c 6514 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
1da177e4
LT
6515
6516}
6517
6518/*---------------------------------------------------------------------
6519 *
47b5d69c 6520 * Function: FPT_scmachid
1da177e4
LT
6521 *
6522 * Description: Match the Device ID string with our values stored in
6523 * the EEPROM.
6524 *
6525 *---------------------------------------------------------------------*/
6526
db038cf8 6527static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
1da177e4
LT
6528{
6529
db038cf8 6530 unsigned char i,k,match;
1da177e4
LT
6531
6532
6533 for (i=0; i < MAX_SCSI_TAR; i++) {
6534
47b5d69c 6535 match = 1;
1da177e4
LT
6536
6537 for (k=0; k < ID_STRING_LENGTH; k++)
6538 {
47b5d69c
JB
6539 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6540 match = 0;
1da177e4
LT
6541 }
6542
6543 if (match)
6544 {
47b5d69c 6545 FPT_scamInfo[i].state = ID_ASSIGNED;
1da177e4
LT
6546 return(i);
6547 }
6548
1da177e4
LT
6549 }
6550
6551
6552
6553 if (p_id_string[0] & BIT(5))
6554 i = 8;
6555 else
6556 i = MAX_SCSI_TAR;
6557
6558 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
db038cf8 6559 match = p_id_string[1] & (unsigned char) 0x1F;
1da177e4
LT
6560 else
6561 match = 7;
6562
6563 while (i > 0)
6564 {
6565 i--;
6566
47b5d69c 6567 if (FPT_scamInfo[match].state == ID_UNUSED)
1da177e4
LT
6568 {
6569 for (k=0; k < ID_STRING_LENGTH; k++)
6570 {
47b5d69c 6571 FPT_scamInfo[match].id_string[k] = p_id_string[k];
1da177e4
LT
6572 }
6573
47b5d69c 6574 FPT_scamInfo[match].state = ID_ASSIGNED;
1da177e4 6575
47b5d69c
JB
6576 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6577 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
1da177e4
LT
6578 return(match);
6579
6580 }
6581
6582
6583 match--;
6584
6585 if (match == 0xFF)
6586 {
6587 if (p_id_string[0] & BIT(5))
6588 match = 7;
6589 else
6590 match = MAX_SCSI_TAR-1;
6591 }
6592 }
6593
6594
6595
6596 if (p_id_string[0] & BIT(7))
6597 {
6598 return(CLR_PRIORITY);
6599 }
6600
6601
6602 if (p_id_string[0] & BIT(5))
6603 i = 8;
6604 else
6605 i = MAX_SCSI_TAR;
6606
6607 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
db038cf8 6608 match = p_id_string[1] & (unsigned char) 0x1F;
1da177e4
LT
6609 else
6610 match = 7;
6611
6612 while (i > 0)
6613 {
6614
6615 i--;
6616
47b5d69c 6617 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
1da177e4
LT
6618 {
6619 for (k=0; k < ID_STRING_LENGTH; k++)
6620 {
47b5d69c 6621 FPT_scamInfo[match].id_string[k] = p_id_string[k];
1da177e4
LT
6622 }
6623
47b5d69c
JB
6624 FPT_scamInfo[match].id_string[0] |= BIT(7);
6625 FPT_scamInfo[match].state = ID_ASSIGNED;
6626 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6627 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
1da177e4
LT
6628 return(match);
6629
6630 }
6631
6632
6633 match--;
6634
6635 if (match == 0xFF)
6636 {
6637 if (p_id_string[0] & BIT(5))
6638 match = 7;
6639 else
6640 match = MAX_SCSI_TAR-1;
6641 }
6642 }
6643
6644 return(NO_ID_AVAIL);
6645}
6646
6647
6648/*---------------------------------------------------------------------
6649 *
47b5d69c 6650 * Function: FPT_scsavdi
1da177e4
LT
6651 *
6652 * Description: Save off the device SCAM ID strings.
6653 *
6654 *---------------------------------------------------------------------*/
6655
db038cf8 6656static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
1da177e4 6657{
db038cf8 6658 unsigned char i,k,max_id;
c823feeb 6659 unsigned short ee_data,sum_data;
1da177e4
LT
6660
6661
6662 sum_data = 0x0000;
6663
6664 for (i = 1; i < EE_SCAMBASE/2; i++)
6665 {
47b5d69c 6666 sum_data += FPT_utilEERead(p_port, i);
1da177e4
LT
6667 }
6668
6669
47b5d69c 6670 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
1da177e4
LT
6671
6672 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6673 max_id = 0x08;
6674
6675 else
6676 max_id = 0x10;
6677
6678 for (i=0; i < max_id; i++)
6679 {
6680
6681 for (k=0; k < ID_STRING_LENGTH; k+=2)
6682 {
47b5d69c 6683 ee_data = FPT_scamInfo[i].id_string[k+1];
1da177e4 6684 ee_data <<= 8;
47b5d69c 6685 ee_data |= FPT_scamInfo[i].id_string[k];
1da177e4 6686 sum_data += ee_data;
c823feeb
AD
6687 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6688 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
1da177e4
LT
6689 }
6690 }
6691
6692
47b5d69c
JB
6693 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6694 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
1da177e4 6695}
1da177e4
LT
6696
6697/*---------------------------------------------------------------------
6698 *
47b5d69c 6699 * Function: FPT_XbowInit
1da177e4
LT
6700 *
6701 * Description: Setup the Xbow for normal operation.
6702 *
6703 *---------------------------------------------------------------------*/
6704
db038cf8 6705static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
1da177e4 6706{
db038cf8 6707unsigned char i;
1da177e4
LT
6708
6709 i = RD_HARPOON(port+hp_page_ctrl);
db038cf8 6710 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
1da177e4
LT
6711
6712 WR_HARPOON(port+hp_scsireset,0x00);
6713 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6714
6715 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6716 FIFO_CLR));
6717
6718 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6719
6720 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6721
6722 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6723 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6724
6725 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6726
47b5d69c 6727 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
1da177e4
LT
6728 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6729
6730 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
47b5d69c 6731 FPT_default_intena |= SCAM_SEL;
1da177e4 6732
47b5d69c 6733 WRW_HARPOON((port+hp_intena), FPT_default_intena);
1da177e4
LT
6734
6735 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6736
6737 /* Turn on SCSI_MODE8 for narrow cards to fix the
6738 strapping issue with the DUAL CHANNEL card */
6739 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6740 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6741
1da177e4
LT
6742 WR_HARPOON(port+hp_page_ctrl, i);
6743
6744}
6745
6746
6747/*---------------------------------------------------------------------
6748 *
47b5d69c 6749 * Function: FPT_BusMasterInit
1da177e4
LT
6750 *
6751 * Description: Initialize the BusMaster for normal operations.
6752 *
6753 *---------------------------------------------------------------------*/
6754
47b5d69c 6755static void FPT_BusMasterInit(ULONG p_port)
1da177e4
LT
6756{
6757
6758
6759 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6760 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6761
6762 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6763
6764
6765 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6766
6767 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6768
6769
1da177e4
LT
6770 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6771 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6772 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6773 ~SCATTER_EN));
6774}
6775
6776
6777/*---------------------------------------------------------------------
6778 *
47b5d69c 6779 * Function: FPT_DiagEEPROM
1da177e4
LT
6780 *
6781 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6782 * necessary.
6783 *
6784 *---------------------------------------------------------------------*/
6785
47b5d69c 6786static void FPT_DiagEEPROM(ULONG p_port)
1da177e4 6787{
c823feeb 6788 unsigned short index,temp,max_wd_cnt;
1da177e4
LT
6789
6790 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6791 max_wd_cnt = EEPROM_WD_CNT;
6792 else
6793 max_wd_cnt = EEPROM_WD_CNT * 2;
6794
47b5d69c 6795 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
1da177e4
LT
6796
6797 if (temp == 0x4641) {
6798
6799 for (index = 2; index < max_wd_cnt; index++) {
6800
47b5d69c 6801 temp += FPT_utilEERead(p_port, index);
1da177e4
LT
6802
6803 }
6804
47b5d69c 6805 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
1da177e4
LT
6806
6807 return; /*EEPROM is Okay so return now! */
6808 }
6809 }
6810
6811
db038cf8 6812 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
1da177e4
LT
6813
6814 for (index = 0; index < max_wd_cnt; index++) {
6815
47b5d69c 6816 FPT_utilEEWrite(p_port, 0x0000, index);
1da177e4
LT
6817 }
6818
6819 temp = 0;
6820
47b5d69c 6821 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
1da177e4 6822 temp += 0x4641;
47b5d69c 6823 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
1da177e4 6824 temp += 0x3920;
47b5d69c 6825 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
1da177e4 6826 temp += 0x3033;
47b5d69c 6827 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
1da177e4 6828 temp += 0x2020;
47b5d69c 6829 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
1da177e4 6830 temp += 0x70D3;
47b5d69c 6831 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
1da177e4 6832 temp += 0x0010;
47b5d69c 6833 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
1da177e4 6834 temp += 0x0003;
47b5d69c 6835 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
1da177e4
LT
6836 temp += 0x0007;
6837
47b5d69c 6838 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
1da177e4 6839 temp += 0x0000;
47b5d69c 6840 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
1da177e4 6841 temp += 0x0000;
47b5d69c 6842 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
1da177e4
LT
6843 temp += 0x0000;
6844
47b5d69c 6845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
1da177e4 6846 temp += 0x4242;
47b5d69c 6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
1da177e4 6848 temp += 0x4242;
47b5d69c 6849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
1da177e4 6850 temp += 0x4242;
47b5d69c 6851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
1da177e4 6852 temp += 0x4242;
47b5d69c 6853 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
1da177e4 6854 temp += 0x4242;
47b5d69c 6855 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
1da177e4 6856 temp += 0x4242;
47b5d69c 6857 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
1da177e4 6858 temp += 0x4242;
47b5d69c 6859 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
1da177e4
LT
6860 temp += 0x4242;
6861
6862
47b5d69c 6863 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
1da177e4 6864 temp += 0x6C46;
47b5d69c 6865 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
1da177e4 6866 temp += 0x7361;
47b5d69c 6867 FPT_utilEEWrite(p_port, 0x5068, 68/2);
1da177e4 6868 temp += 0x5068;
47b5d69c 6869 FPT_utilEEWrite(p_port, 0x696F, 70/2);
1da177e4 6870 temp += 0x696F;
47b5d69c 6871 FPT_utilEEWrite(p_port, 0x746E, 72/2);
1da177e4 6872 temp += 0x746E;
47b5d69c 6873 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
1da177e4 6874 temp += 0x4C20;
47b5d69c 6875 FPT_utilEEWrite(p_port, 0x2054, 76/2);
1da177e4 6876 temp += 0x2054;
47b5d69c 6877 FPT_utilEEWrite(p_port, 0x2020, 78/2);
1da177e4
LT
6878 temp += 0x2020;
6879
6880 index = ((EE_SCAMBASE/2)+(7*16));
47b5d69c 6881 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
1da177e4
LT
6882 temp += (0x0700+TYPE_CODE0);
6883 index++;
47b5d69c 6884 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
1da177e4
LT
6885 temp += 0x5542; /* BUSLOGIC */
6886 index++;
47b5d69c 6887 FPT_utilEEWrite(p_port, 0x4C53, index);
1da177e4
LT
6888 temp += 0x4C53;
6889 index++;
47b5d69c 6890 FPT_utilEEWrite(p_port, 0x474F, index);
1da177e4
LT
6891 temp += 0x474F;
6892 index++;
47b5d69c 6893 FPT_utilEEWrite(p_port, 0x4349, index);
1da177e4
LT
6894 temp += 0x4349;
6895 index++;
47b5d69c 6896 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
1da177e4
LT
6897 temp += 0x5442; /* BT- 930 */
6898 index++;
47b5d69c 6899 FPT_utilEEWrite(p_port, 0x202D, index);
1da177e4
LT
6900 temp += 0x202D;
6901 index++;
47b5d69c 6902 FPT_utilEEWrite(p_port, 0x3339, index);
1da177e4
LT
6903 temp += 0x3339;
6904 index++; /*Serial # */
47b5d69c 6905 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
1da177e4
LT
6906 temp += 0x2030;
6907 index++;
47b5d69c 6908 FPT_utilEEWrite(p_port, 0x5453, index);
1da177e4
LT
6909 temp += 0x5453;
6910 index++;
47b5d69c 6911 FPT_utilEEWrite(p_port, 0x5645, index);
1da177e4
LT
6912 temp += 0x5645;
6913 index++;
47b5d69c 6914 FPT_utilEEWrite(p_port, 0x2045, index);
1da177e4
LT
6915 temp += 0x2045;
6916 index++;
47b5d69c 6917 FPT_utilEEWrite(p_port, 0x202F, index);
1da177e4
LT
6918 temp += 0x202F;
6919 index++;
47b5d69c 6920 FPT_utilEEWrite(p_port, 0x4F4A, index);
1da177e4
LT
6921 temp += 0x4F4A;
6922 index++;
47b5d69c 6923 FPT_utilEEWrite(p_port, 0x204E, index);
1da177e4
LT
6924 temp += 0x204E;
6925 index++;
47b5d69c 6926 FPT_utilEEWrite(p_port, 0x3539, index);
1da177e4
LT
6927 temp += 0x3539;
6928
6929
6930
47b5d69c 6931 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
1da177e4 6932
db038cf8 6933 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
1da177e4
LT
6934
6935}
6936
1da177e4
LT
6937
6938/*---------------------------------------------------------------------
6939 *
6940 * Function: Queue Search Select
6941 *
6942 * Description: Try to find a new command to execute.
6943 *
6944 *---------------------------------------------------------------------*/
6945
db038cf8 6946static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
1da177e4 6947{
db038cf8 6948 unsigned char scan_ptr, lun;
1da177e4
LT
6949 PSCCBMgr_tar_info currTar_Info;
6950 PSCCB pOldSccb;
6951
6952 scan_ptr = pCurrCard->scanIndex;
6953 do
6954 {
47b5d69c 6955 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
1da177e4
LT
6956 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6957 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6958 {
6959 if (currTar_Info->TarSelQ_Cnt != 0)
6960 {
6961
6962 scan_ptr++;
6963 if (scan_ptr == MAX_SCSI_TAR)
6964 scan_ptr = 0;
6965
6966 for(lun=0; lun < MAX_LUN; lun++)
6967 {
47b5d69c 6968 if(currTar_Info->TarLUNBusy[lun] == 0)
1da177e4
LT
6969 {
6970
6971 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6972 pOldSccb = NULL;
6973
6974 while((pCurrCard->currentSCCB != NULL) &&
6975 (lun != pCurrCard->currentSCCB->Lun))
6976 {
6977 pOldSccb = pCurrCard->currentSCCB;
6978 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6979 Sccb_forwardlink;
6980 }
6981 if(pCurrCard->currentSCCB == NULL)
6982 continue;
6983 if(pOldSccb != NULL)
6984 {
6985 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6986 Sccb_forwardlink;
6987 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6988 Sccb_backlink;
6989 currTar_Info->TarSelQ_Cnt--;
6990 }
6991 else
6992 {
6993 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6994
6995 if (currTar_Info->TarSelQ_Head == NULL)
6996 {
6997 currTar_Info->TarSelQ_Tail = NULL;
6998 currTar_Info->TarSelQ_Cnt = 0;
6999 }
7000 else
7001 {
7002 currTar_Info->TarSelQ_Cnt--;
7003 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7004 }
7005 }
7006 pCurrCard->scanIndex = scan_ptr;
7007
7008 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7009
7010 break;
7011 }
7012 }
7013 }
7014
7015 else
7016 {
7017 scan_ptr++;
7018 if (scan_ptr == MAX_SCSI_TAR) {
7019 scan_ptr = 0;
7020 }
7021 }
7022
7023 }
7024 else
7025 {
7026 if ((currTar_Info->TarSelQ_Cnt != 0) &&
47b5d69c 7027 (currTar_Info->TarLUNBusy[0] == 0))
1da177e4
LT
7028 {
7029
7030 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7031
7032 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7033
7034 if (currTar_Info->TarSelQ_Head == NULL)
7035 {
7036 currTar_Info->TarSelQ_Tail = NULL;
7037 currTar_Info->TarSelQ_Cnt = 0;
7038 }
7039 else
7040 {
7041 currTar_Info->TarSelQ_Cnt--;
7042 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7043 }
7044
7045 scan_ptr++;
7046 if (scan_ptr == MAX_SCSI_TAR)
7047 scan_ptr = 0;
7048
7049 pCurrCard->scanIndex = scan_ptr;
7050
7051 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7052
7053 break;
7054 }
7055
7056 else
7057 {
7058 scan_ptr++;
7059 if (scan_ptr == MAX_SCSI_TAR)
7060 {
7061 scan_ptr = 0;
7062 }
7063 }
7064 }
7065 } while (scan_ptr != pCurrCard->scanIndex);
7066}
7067
7068
7069/*---------------------------------------------------------------------
7070 *
7071 * Function: Queue Select Fail
7072 *
7073 * Description: Add the current SCCB to the head of the Queue.
7074 *
7075 *---------------------------------------------------------------------*/
7076
db038cf8 7077static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
1da177e4 7078{
db038cf8 7079 unsigned char thisTarg;
1da177e4
LT
7080 PSCCBMgr_tar_info currTar_Info;
7081
7082 if (pCurrCard->currentSCCB != NULL)
7083 {
db038cf8 7084 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
47b5d69c 7085 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7086
7087 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7088
7089 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7090
7091 if (currTar_Info->TarSelQ_Cnt == 0)
7092 {
7093 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7094 }
7095
7096 else
7097 {
7098 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7099 }
7100
7101
7102 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7103
7104 pCurrCard->currentSCCB = NULL;
7105 currTar_Info->TarSelQ_Cnt++;
7106 }
7107}
7108/*---------------------------------------------------------------------
7109 *
7110 * Function: Queue Command Complete
7111 *
7112 * Description: Call the callback function with the current SCCB.
7113 *
7114 *---------------------------------------------------------------------*/
7115
47b5d69c 7116static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
db038cf8 7117 unsigned char p_card)
1da177e4
LT
7118{
7119
db038cf8 7120 unsigned char i, SCSIcmd;
1da177e4
LT
7121 CALL_BK_FN callback;
7122 PSCCBMgr_tar_info currTar_Info;
7123
7124 SCSIcmd = p_sccb->Cdb[0];
7125
7126
7127 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7128
7129 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7130 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7131 (p_sccb->TargetStatus != SSCHECK))
7132
7133 if ((SCSIcmd == SCSI_READ) ||
7134 (SCSIcmd == SCSI_WRITE) ||
7135 (SCSIcmd == SCSI_READ_EXTENDED) ||
7136 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7137 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7138 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7139 (pCurrCard->globalFlags & F_NO_FILTER)
7140 )
7141 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7142 }
7143
7144
7145 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7146 {
7147 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7148 p_sccb->SccbStatus = SCCB_ERROR;
7149 else
7150 p_sccb->SccbStatus = SCCB_SUCCESS;
7151 }
7152
7153 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7154
7155 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7156 for (i=0; i < 6; i++) {
7157 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7158 }
7159 }
7160
7161 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7162 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7163
47b5d69c 7164 FPT_utilUpdateResidual(p_sccb);
1da177e4
LT
7165 }
7166
7167 pCurrCard->cmdCounter--;
7168 if (!pCurrCard->cmdCounter) {
7169
7170 if (pCurrCard->globalFlags & F_GREEN_PC) {
7171 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7172 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7173 }
7174
7175 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7176 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7177
7178 }
7179
7180 if(pCurrCard->discQCount != 0)
7181 {
47b5d69c 7182 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4
LT
7183 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7184 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7185 {
7186 pCurrCard->discQCount--;
7187 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7188 }
7189 else
7190 {
7191 if(p_sccb->Sccb_tag)
7192 {
7193 pCurrCard->discQCount--;
7194 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7195 }else
7196 {
7197 pCurrCard->discQCount--;
7198 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7199 }
7200 }
7201
7202 }
7203
7204 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7205 callback(p_sccb);
7206 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7207 pCurrCard->currentSCCB = NULL;
7208}
1da177e4
LT
7209
7210
7211/*---------------------------------------------------------------------
7212 *
7213 * Function: Queue Disconnect
7214 *
7215 * Description: Add SCCB to our disconnect array.
7216 *
7217 *---------------------------------------------------------------------*/
db038cf8 7218static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
1da177e4
LT
7219{
7220 PSCCBMgr_tar_info currTar_Info;
7221
47b5d69c 7222 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4 7223
47b5d69c 7224 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
1da177e4
LT
7225 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7226 {
47b5d69c 7227 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
1da177e4
LT
7228 }
7229 else
7230 {
7231 if (p_sccb->Sccb_tag)
7232 {
47b5d69c
JB
7233 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7234 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7235 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
1da177e4
LT
7236 }else
7237 {
47b5d69c 7238 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
1da177e4
LT
7239 }
7240 }
47b5d69c 7241 FPT_BL_Card[p_card].currentSCCB = NULL;
1da177e4
LT
7242}
7243
7244
7245/*---------------------------------------------------------------------
7246 *
7247 * Function: Queue Flush SCCB
7248 *
7249 * Description: Flush all SCCB's back to the host driver for this target.
7250 *
7251 *---------------------------------------------------------------------*/
7252
db038cf8 7253static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
1da177e4 7254{
db038cf8 7255 unsigned char qtag,thisTarg;
1da177e4
LT
7256 PSCCB currSCCB;
7257 PSCCBMgr_tar_info currTar_Info;
7258
47b5d69c 7259 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
7260 if(currSCCB != NULL)
7261 {
db038cf8 7262 thisTarg = (unsigned char)currSCCB->TargID;
47b5d69c 7263 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7264
7265 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7266
47b5d69c
JB
7267 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7268 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
1da177e4
LT
7269 {
7270
db038cf8 7271 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
1da177e4 7272
47b5d69c 7273 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
1da177e4 7274
47b5d69c 7275 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
7276 currTar_Info->TarTagQ_Cnt--;
7277
7278 }
7279 }
7280 }
7281
7282}
7283
7284/*---------------------------------------------------------------------
7285 *
7286 * Function: Queue Flush Target SCCB
7287 *
7288 * Description: Flush all SCCB's back to the host driver for this target.
7289 *
7290 *---------------------------------------------------------------------*/
7291
db038cf8
AD
7292static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7293 unsigned char error_code)
1da177e4 7294{
db038cf8 7295 unsigned char qtag;
1da177e4
LT
7296 PSCCBMgr_tar_info currTar_Info;
7297
47b5d69c 7298 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7299
7300 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7301
47b5d69c
JB
7302 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7303 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
1da177e4
LT
7304 {
7305
db038cf8 7306 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
1da177e4 7307
47b5d69c 7308 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
1da177e4 7309
47b5d69c 7310 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
7311 currTar_Info->TarTagQ_Cnt--;
7312
7313 }
7314 }
7315
7316}
7317
7318
7319
7320
7321
db038cf8 7322static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
1da177e4
LT
7323{
7324 PSCCBMgr_tar_info currTar_Info;
47b5d69c 7325 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4
LT
7326
7327 p_SCCB->Sccb_forwardlink = NULL;
7328
7329 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7330
7331 if (currTar_Info->TarSelQ_Cnt == 0) {
7332
7333 currTar_Info->TarSelQ_Head = p_SCCB;
7334 }
7335
7336 else {
7337
7338 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7339 }
7340
7341
7342 currTar_Info->TarSelQ_Tail = p_SCCB;
7343 currTar_Info->TarSelQ_Cnt++;
7344}
7345
7346
7347/*---------------------------------------------------------------------
7348 *
7349 * Function: Queue Find SCCB
7350 *
7351 * Description: Search the target select Queue for this SCCB, and
7352 * remove it if found.
7353 *
7354 *---------------------------------------------------------------------*/
7355
db038cf8 7356static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
1da177e4
LT
7357{
7358 PSCCB q_ptr;
7359 PSCCBMgr_tar_info currTar_Info;
7360
47b5d69c 7361 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4
LT
7362
7363 q_ptr = currTar_Info->TarSelQ_Head;
7364
7365 while(q_ptr != NULL) {
7366
7367 if (q_ptr == p_SCCB) {
7368
7369
7370 if (currTar_Info->TarSelQ_Head == q_ptr) {
7371
7372 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7373 }
7374
7375 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7376
7377 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7378 }
7379
7380 if (q_ptr->Sccb_forwardlink != NULL) {
7381 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7382 }
7383
7384 if (q_ptr->Sccb_backlink != NULL) {
7385 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7386 }
7387
7388 currTar_Info->TarSelQ_Cnt--;
7389
47b5d69c 7390 return(1);
1da177e4
LT
7391 }
7392
7393 else {
7394 q_ptr = q_ptr->Sccb_forwardlink;
7395 }
7396 }
7397
7398
47b5d69c 7399 return(0);
1da177e4
LT
7400
7401}
7402
7403
7404/*---------------------------------------------------------------------
7405 *
7406 * Function: Utility Update Residual Count
7407 *
7408 * Description: Update the XferCnt to the remaining byte count.
7409 * If we transferred all the data then just write zero.
7410 * If Non-SG transfer then report Total Cnt - Actual Transfer
7411 * Cnt. For SG transfers add the count fields of all
7412 * remaining SG elements, as well as any partial remaining
7413 * element.
7414 *
7415 *---------------------------------------------------------------------*/
7416
47b5d69c 7417static void FPT_utilUpdateResidual(PSCCB p_SCCB)
1da177e4
LT
7418{
7419 ULONG partial_cnt;
ce793215 7420 unsigned int sg_index;
1da177e4 7421 ULONG *sg_ptr;
1da177e4
LT
7422
7423 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7424
7425 p_SCCB->DataLength = 0x0000;
7426 }
7427
7428 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7429
7430 partial_cnt = 0x0000;
7431
7432 sg_index = p_SCCB->Sccb_sgseg;
7433
1da177e4 7434 sg_ptr = (ULONG *)p_SCCB->DataPointer;
1da177e4
LT
7435
7436 if (p_SCCB->Sccb_SGoffset) {
7437
7438 partial_cnt = p_SCCB->Sccb_SGoffset;
7439 sg_index++;
7440 }
7441
7442 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7443 p_SCCB->DataLength ) {
7444
7445 partial_cnt += *(sg_ptr+(sg_index * 2));
7446 sg_index++;
7447 }
7448
7449 p_SCCB->DataLength = partial_cnt;
7450 }
7451
7452 else {
7453
7454 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7455 }
7456}
7457
7458
7459/*---------------------------------------------------------------------
7460 *
7461 * Function: Wait 1 Second
7462 *
7463 * Description: Wait for 1 second.
7464 *
7465 *---------------------------------------------------------------------*/
7466
47b5d69c 7467static void FPT_Wait1Second(ULONG p_port)
1da177e4 7468{
db038cf8 7469 unsigned char i;
1da177e4
LT
7470
7471 for(i=0; i < 4; i++) {
7472
47b5d69c 7473 FPT_Wait(p_port, TO_250ms);
1da177e4
LT
7474
7475 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7476 break;
7477
7478 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7479 break;
7480 }
7481}
7482
7483
7484/*---------------------------------------------------------------------
7485 *
47b5d69c 7486 * Function: FPT_Wait
1da177e4
LT
7487 *
7488 * Description: Wait the desired delay.
7489 *
7490 *---------------------------------------------------------------------*/
7491
db038cf8 7492static void FPT_Wait(ULONG p_port, unsigned char p_delay)
1da177e4 7493{
db038cf8
AD
7494 unsigned char old_timer;
7495 unsigned char green_flag;
1da177e4
LT
7496
7497 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7498
7499 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7500 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7501
7502 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7503 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
47b5d69c 7504 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
1da177e4
LT
7505
7506
7507 WR_HARPOON(p_port+hp_portctrl_0,
7508 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7509
7510 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7511
7512 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7513 break;
7514
7515 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7516 break;
7517 }
7518
7519 WR_HARPOON(p_port+hp_portctrl_0,
7520 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7521
7522 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
47b5d69c 7523 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
1da177e4
LT
7524
7525 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7526
7527 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7528}
7529
7530
7531/*---------------------------------------------------------------------
7532 *
7533 * Function: Enable/Disable Write to EEPROM
7534 *
7535 * Description: The EEPROM must first be enabled for writes
7536 * A total of 9 clocks are needed.
7537 *
7538 *---------------------------------------------------------------------*/
7539
db038cf8 7540static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
1da177e4 7541{
db038cf8 7542 unsigned char ee_value;
1da177e4 7543
db038cf8 7544 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
1da177e4
LT
7545
7546 if (p_mode)
7547
47b5d69c 7548 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
1da177e4
LT
7549
7550 else
7551
7552
47b5d69c 7553 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
1da177e4
LT
7554
7555 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7556 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7557}
7558
7559
7560/*---------------------------------------------------------------------
7561 *
7562 * Function: Write EEPROM
7563 *
7564 * Description: Write a word to the EEPROM at the specified
7565 * address.
7566 *
7567 *---------------------------------------------------------------------*/
7568
c823feeb 7569static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr)
1da177e4
LT
7570{
7571
db038cf8 7572 unsigned char ee_value;
c823feeb 7573 unsigned short i;
1da177e4 7574
db038cf8 7575 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
1da177e4
LT
7576 (SEE_MS | SEE_CS));
7577
7578
7579
47b5d69c 7580 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
1da177e4
LT
7581
7582
7583 ee_value |= (SEE_MS + SEE_CS);
7584
7585 for(i = 0x8000; i != 0; i>>=1) {
7586
7587 if (i & ee_data)
7588 ee_value |= SEE_DO;
7589 else
7590 ee_value &= ~SEE_DO;
7591
7592 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 ee_value |= SEE_CLK; /* Clock data! */
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 ee_value &= ~SEE_CLK;
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 }
7601 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7602 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7603
47b5d69c 7604 FPT_Wait(p_port, TO_10ms);
1da177e4
LT
7605
7606 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7607 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7608 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7609}
7610
7611/*---------------------------------------------------------------------
7612 *
7613 * Function: Read EEPROM
7614 *
7615 * Description: Read a word from the EEPROM at the desired
7616 * address.
7617 *
7618 *---------------------------------------------------------------------*/
7619
c823feeb 7620static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr)
1da177e4 7621{
c823feeb 7622 unsigned short i, ee_data1, ee_data2;
1da177e4
LT
7623
7624 i = 0;
47b5d69c 7625 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4
LT
7626 do
7627 {
47b5d69c 7628 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4
LT
7629
7630 if(ee_data1 == ee_data2)
7631 return(ee_data1);
7632
7633 ee_data1 = ee_data2;
7634 i++;
7635
7636 }while(i < 4);
7637
7638 return(ee_data1);
7639}
7640
7641/*---------------------------------------------------------------------
7642 *
7643 * Function: Read EEPROM Original
7644 *
7645 * Description: Read a word from the EEPROM at the desired
7646 * address.
7647 *
7648 *---------------------------------------------------------------------*/
7649
c823feeb 7650static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr)
1da177e4
LT
7651{
7652
db038cf8 7653 unsigned char ee_value;
c823feeb 7654 unsigned short i, ee_data;
1da177e4 7655
db038cf8 7656 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
1da177e4
LT
7657 (SEE_MS | SEE_CS));
7658
7659
47b5d69c 7660 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
1da177e4
LT
7661
7662
7663 ee_value |= (SEE_MS + SEE_CS);
7664 ee_data = 0;
7665
7666 for(i = 1; i <= 16; i++) {
7667
7668 ee_value |= SEE_CLK; /* Clock data! */
7669 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 ee_value &= ~SEE_CLK;
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674
7675 ee_data <<= 1;
7676
7677 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7678 ee_data |= 1;
7679 }
7680
7681 ee_value &= ~(SEE_MS + SEE_CS);
7682 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7683 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7684
7685 return(ee_data);
7686}
7687
7688
7689/*---------------------------------------------------------------------
7690 *
7691 * Function: Send EE command and Address to the EEPROM
7692 *
7693 * Description: Transfers the correct command and sends the address
7694 * to the eeprom.
7695 *
7696 *---------------------------------------------------------------------*/
7697
c823feeb 7698static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr)
1da177e4 7699{
db038cf8
AD
7700 unsigned char ee_value;
7701 unsigned char narrow_flg;
1da177e4 7702
c823feeb 7703 unsigned short i;
1da177e4
LT
7704
7705
db038cf8 7706 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
1da177e4
LT
7707
7708
7709 ee_value = SEE_MS;
7710 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7711
7712 ee_value |= SEE_CS; /* Set CS to EEPROM */
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714
7715
7716 for(i = 0x04; i != 0; i>>=1) {
7717
7718 if (i & ee_cmd)
7719 ee_value |= SEE_DO;
7720 else
7721 ee_value &= ~SEE_DO;
7722
7723 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 ee_value |= SEE_CLK; /* Clock data! */
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 ee_value &= ~SEE_CLK;
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 }
7732
7733
7734 if (narrow_flg)
7735 i = 0x0080;
7736
7737 else
7738 i = 0x0200;
7739
7740
7741 while (i != 0) {
7742
7743 if (i & ee_addr)
7744 ee_value |= SEE_DO;
7745 else
7746 ee_value &= ~SEE_DO;
7747
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 ee_value |= SEE_CLK; /* Clock data! */
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 ee_value &= ~SEE_CLK;
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756
7757 i >>= 1;
7758 }
7759}
7760
c823feeb 7761static unsigned short FPT_CalcCrc16(unsigned char buffer[])
1da177e4 7762{
c823feeb 7763 unsigned short crc=0;
1da177e4 7764 int i,j;
c823feeb 7765 unsigned short ch;
1da177e4
LT
7766 for (i=0; i < ID_STRING_LENGTH; i++)
7767 {
c823feeb 7768 ch = (unsigned short) buffer[i];
1da177e4
LT
7769 for(j=0; j < 8; j++)
7770 {
7771 if ((crc ^ ch) & 1)
7772 crc = (crc >> 1) ^ CRCMASK;
7773 else
7774 crc >>= 1;
7775 ch >>= 1;
7776 }
7777 }
7778 return(crc);
7779}
7780
db038cf8 7781static unsigned char FPT_CalcLrc(unsigned char buffer[])
1da177e4
LT
7782{
7783 int i;
db038cf8 7784 unsigned char lrc;
1da177e4
LT
7785 lrc = 0;
7786 for(i = 0; i < ID_STRING_LENGTH; i++)
7787 lrc ^= buffer[i];
7788 return(lrc);
7789}
7790
7791
7792
7793/*
7794 The following inline definitions avoid type conflicts.
7795*/
7796
7797static inline unsigned char
7798FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7799{
7800 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7801}
7802
7803
7804static inline FlashPoint_CardHandle_T
7805FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7806{
7807 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7808}
7809
7810static inline void
7811FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7812{
7813 FlashPoint_ReleaseHostAdapter(CardHandle);
7814}
7815
7816
7817static inline void
7818FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7819{
7820 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7821}
7822
7823
7824static inline void
7825FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7826{
7827 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7828}
7829
7830
7831static inline boolean
7832FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7833{
7834 return FlashPoint_InterruptPending(CardHandle);
7835}
7836
7837
7838static inline int
7839FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7840{
7841 return FlashPoint_HandleInterrupt(CardHandle);
7842}
7843
7844
7845#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7846#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7847#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7848#define FlashPoint_StartCCB FlashPoint__StartCCB
7849#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7850#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7851#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7852
7853
1da177e4
LT
7854#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7855
7856
7857/*
7858 Define prototypes for the FlashPoint SCCB Manager Functions.
7859*/
7860
7861extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7862extern FlashPoint_CardHandle_T
7863 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7864extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7865extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7866extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7867extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7868extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
1da177e4
LT
7869
7870
7871#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */
This page took 0.538185 seconds and 5 git commands to generate.