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