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