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