treewide: Use fallthrough pseudo-keyword
[linux-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;
db038cf8 1618 unsigned char TID;
5c04a7b8
AD
1619 struct sccb *pSaveSCCB;
1620 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 1621
5c04a7b8 1622 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1da177e4 1623
13e6851a 1624 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1da177e4 1625
5c04a7b8 1626 if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1da177e4 1627
5c04a7b8 1628 if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1da177e4 1629
13e6851a 1630 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1da177e4 1631
13e6851a 1632 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
5c04a7b8
AD
1633 WR_HARPOON(ioport + hp_semaphore,
1634 (RD_HARPOON(ioport + hp_semaphore)
1635 & (unsigned
1636 char)(~(SCCB_MGR_ACTIVE |
1637 TICKLE_ME))));
1da177e4 1638
1da177e4
LT
1639 p_Sccb->SccbStatus = SCCB_ABORT;
1640 callback = p_Sccb->SccbCallback;
1641 callback(p_Sccb);
1da177e4 1642
5c1b85e2 1643 return 0;
1da177e4
LT
1644 }
1645
5c04a7b8
AD
1646 else {
1647 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1648 p_Sccb) {
1da177e4 1649 p_Sccb->SccbStatus = SCCB_ABORT;
5c1b85e2 1650 return 0;
1da177e4
LT
1651
1652 }
1653
5c04a7b8 1654 else {
1da177e4
LT
1655
1656 TID = p_Sccb->TargID;
1657
5c04a7b8 1658 if (p_Sccb->Sccb_tag) {
1da177e4 1659 MDISABLE_INT(ioport);
5c04a7b8
AD
1660 if (((struct sccb_card *)pCurrCard)->
1661 discQ_Tbl[p_Sccb->Sccb_tag] ==
1662 p_Sccb) {
1da177e4 1663 p_Sccb->SccbStatus = SCCB_ABORT;
5c04a7b8
AD
1664 p_Sccb->Sccb_scsistat =
1665 ABORT_ST;
1666 p_Sccb->Sccb_scsimsg =
1667 SMABORT_TAG;
1668
1669 if (((struct sccb_card *)
1670 pCurrCard)->currentSCCB ==
1671 NULL) {
1672 ((struct sccb_card *)
1673 pCurrCard)->
1674 currentSCCB = p_Sccb;
1675 FPT_ssel(ioport,
1676 thisCard);
1677 } else {
1678 pSaveSCCB =
1679 ((struct sccb_card
1680 *)pCurrCard)->
1681 currentSCCB;
1682 ((struct sccb_card *)
1683 pCurrCard)->
1684 currentSCCB = p_Sccb;
1685 FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1686 ((struct sccb_card *)
1687 pCurrCard)->
1688 currentSCCB = pSaveSCCB;
1da177e4
LT
1689 }
1690 }
1691 MENABLE_INT(ioport);
5c1b85e2 1692 return 0;
5c04a7b8
AD
1693 } else {
1694 currTar_Info =
1695 &FPT_sccbMgrTbl[thisCard][p_Sccb->
1696 TargID];
1697
1698 if (FPT_BL_Card[thisCard].
1699 discQ_Tbl[currTar_Info->
1700 LunDiscQ_Idx[p_Sccb->Lun]]
1701 == p_Sccb) {
1da177e4 1702 p_Sccb->SccbStatus = SCCB_ABORT;
5c1b85e2 1703 return 0;
1da177e4
LT
1704 }
1705 }
1706 }
1707 }
1708 }
5c1b85e2 1709 return -1;
1da177e4
LT
1710}
1711
1da177e4
LT
1712/*---------------------------------------------------------------------
1713 *
d8b6b8bd 1714 * Function: FlashPoint_InterruptPending
1da177e4
LT
1715 *
1716 * Description: Do a quick check to determine if there is a pending
1717 * interrupt for this card and disable the IRQ Pin if so.
1718 *
1719 *---------------------------------------------------------------------*/
391e2f25 1720static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1da177e4 1721{
391e2f25 1722 u32 ioport;
1da177e4 1723
5c04a7b8 1724 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1da177e4 1725
5c04a7b8 1726 if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
5c1b85e2 1727 return 1;
5c04a7b8 1728 }
1da177e4 1729
5c04a7b8 1730 else
1da177e4 1731
5c1b85e2 1732 return 0;
1da177e4
LT
1733}
1734
1da177e4
LT
1735/*---------------------------------------------------------------------
1736 *
d8b6b8bd 1737 * Function: FlashPoint_HandleInterrupt
1da177e4
LT
1738 *
1739 * Description: This is our entry point when an interrupt is generated
1740 * by the card and the upper level driver passes it on to
1741 * us.
1742 *
1743 *---------------------------------------------------------------------*/
391e2f25 1744static int FlashPoint_HandleInterrupt(void *pcard)
1da177e4 1745{
5c04a7b8
AD
1746 struct sccb *currSCCB;
1747 unsigned char thisCard, result, bm_status, bm_int_st;
1748 unsigned short hp_int;
1749 unsigned char i, target;
391e2f25
KA
1750 struct sccb_card *pCurrCard = pcard;
1751 u32 ioport;
1da177e4 1752
391e2f25
KA
1753 thisCard = pCurrCard->cardIndex;
1754 ioport = pCurrCard->ioPort;
1da177e4 1755
5c04a7b8 1756 MDISABLE_INT(ioport);
1da177e4 1757
5c04a7b8 1758 if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
391e2f25
KA
1759 bm_status = RD_HARPOON(ioport + hp_ext_status) &
1760 (unsigned char)BAD_EXT_STATUS;
5c04a7b8
AD
1761 else
1762 bm_status = 0;
1da177e4 1763
5c04a7b8 1764 WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1da177e4 1765
391e2f25
KA
1766 while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1767 FPT_default_intena) | bm_status) {
1da177e4 1768
391e2f25 1769 currSCCB = pCurrCard->currentSCCB;
1da177e4 1770
5c04a7b8
AD
1771 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1772 result =
391e2f25 1773 FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
5c04a7b8
AD
1774 hp_int);
1775 WRW_HARPOON((ioport + hp_intstat),
1776 (FIFO | TIMEOUT | RESET | SCAM_SEL));
1777 bm_status = 0;
1da177e4 1778
5c04a7b8 1779 if (result) {
1da177e4 1780
5c04a7b8 1781 MENABLE_INT(ioport);
5c1b85e2 1782 return result;
5c04a7b8
AD
1783 }
1784 }
1da177e4 1785
5c04a7b8
AD
1786 else if (hp_int & ICMD_COMP) {
1787
1788 if (!(hp_int & BUS_FREE)) {
1789 /* Wait for the BusFree before starting a new command. We
1790 must also check for being reselected since the BusFree
1791 may not show up if another device reselects us in 1.5us or
1792 less. SRR Wednesday, 3/8/1995.
1793 */
1794 while (!
1795 (RDW_HARPOON((ioport + hp_intstat)) &
1796 (BUS_FREE | RSEL))) ;
1797 }
1da177e4 1798
391e2f25 1799 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1da177e4 1800
5c04a7b8 1801 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
1802
1803/* WRW_HARPOON((ioport+hp_intstat),
1804 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1805 */
1806
5c04a7b8 1807 WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1da177e4 1808
5c04a7b8 1809 FPT_autoCmdCmplt(ioport, thisCard);
1da177e4 1810
5c04a7b8 1811 }
1da177e4 1812
5c04a7b8 1813 else if (hp_int & ITAR_DISC) {
1da177e4 1814
391e2f25 1815 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5c04a7b8 1816 FPT_phaseChkFifo(ioport, thisCard);
1da177e4 1817
391e2f25
KA
1818 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1819 SMSAVE_DATA_PTR) {
1da177e4 1820
5c04a7b8
AD
1821 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1822 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1da177e4 1823
5c04a7b8
AD
1824 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1825 }
1da177e4 1826
5c04a7b8
AD
1827 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1828 FPT_queueDisconnect(currSCCB, thisCard);
1829
1830 /* Wait for the BusFree before starting a new command. We
1831 must also check for being reselected since the BusFree
1832 may not show up if another device reselects us in 1.5us or
1833 less. SRR Wednesday, 3/8/1995.
1834 */
1835 while (!
1836 (RDW_HARPOON((ioport + hp_intstat)) &
1837 (BUS_FREE | RSEL))
1838 && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1839 && RD_HARPOON((ioport + hp_scsisig)) ==
1840 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1841 SCSI_IOBIT))) ;
1842
1843 /*
1844 The additional loop exit condition above detects a timing problem
1845 with the revision D/E harpoon chips. The caller should reset the
1846 host adapter to recover when 0xFE is returned.
1847 */
1848 if (!
1849 (RDW_HARPOON((ioport + hp_intstat)) &
1850 (BUS_FREE | RSEL))) {
1851 MENABLE_INT(ioport);
1852 return 0xFE;
1853 }
1da177e4 1854
5c04a7b8
AD
1855 WRW_HARPOON((ioport + hp_intstat),
1856 (BUS_FREE | ITAR_DISC));
1da177e4 1857
391e2f25 1858 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1da177e4 1859
5c04a7b8 1860 }
1da177e4 1861
5c04a7b8 1862 else if (hp_int & RSEL) {
1da177e4 1863
5c04a7b8
AD
1864 WRW_HARPOON((ioport + hp_intstat),
1865 (PROG_HLT | RSEL | PHASE | BUS_FREE));
1da177e4 1866
5c04a7b8 1867 if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
391e2f25 1868 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5c04a7b8 1869 FPT_phaseChkFifo(ioport, thisCard);
1da177e4 1870
5c04a7b8
AD
1871 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1872 SMSAVE_DATA_PTR) {
1873 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1874 currSCCB->Sccb_XferState |=
1875 F_NO_DATA_YET;
1876 currSCCB->Sccb_savedATC =
1877 currSCCB->Sccb_ATC;
1878 }
1da177e4 1879
5c04a7b8
AD
1880 WRW_HARPOON((ioport + hp_intstat),
1881 (BUS_FREE | ITAR_DISC));
1882 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1883 FPT_queueDisconnect(currSCCB, thisCard);
1884 }
1da177e4 1885
391e2f25 1886 FPT_sres(ioport, thisCard, pCurrCard);
5c04a7b8 1887 FPT_phaseDecode(ioport, thisCard);
1da177e4 1888
5c04a7b8 1889 }
1da177e4 1890
5c04a7b8 1891 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1da177e4 1892
5c04a7b8
AD
1893 WRW_HARPOON((ioport + hp_intstat),
1894 (IDO_STRT | XFER_CNT_0));
1895 FPT_phaseDecode(ioport, thisCard);
1da177e4 1896
5c04a7b8 1897 }
1da177e4 1898
5c04a7b8
AD
1899 else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1900 WRW_HARPOON((ioport + hp_intstat),
1901 (PHASE | IUNKWN | PROG_HLT));
1902 if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1903 0x3f) < (unsigned char)SELCHK) {
1904 FPT_phaseDecode(ioport, thisCard);
1905 } else {
1906 /* Harpoon problem some SCSI target device respond to selection
1907 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1908 to latch the correct Target ID into reg. x53.
1909 The work around require to correct this reg. But when write to this
1910 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1911 need to read this reg first then restore it later. After update to 0x53 */
1912
1913 i = (unsigned
1914 char)(RD_HARPOON(ioport + hp_fifowrite));
1915 target =
1916 (unsigned
1917 char)(RD_HARPOON(ioport + hp_gp_reg_3));
1918 WR_HARPOON(ioport + hp_xfer_pad,
1919 (unsigned char)ID_UNLOCK);
1920 WR_HARPOON(ioport + hp_select_id,
1921 (unsigned char)(target | target <<
1922 4));
1923 WR_HARPOON(ioport + hp_xfer_pad,
1924 (unsigned char)0x00);
1925 WR_HARPOON(ioport + hp_fifowrite, i);
1926 WR_HARPOON(ioport + hp_autostart_3,
1927 (AUTO_IMMED + TAG_STRT));
1928 }
1929 }
1da177e4 1930
5c04a7b8 1931 else if (hp_int & XFER_CNT_0) {
1da177e4 1932
5c04a7b8 1933 WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1da177e4 1934
5c04a7b8 1935 FPT_schkdd(ioport, thisCard);
1da177e4 1936
5c04a7b8 1937 }
1da177e4 1938
5c04a7b8 1939 else if (hp_int & BUS_FREE) {
1da177e4 1940
5c04a7b8 1941 WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1da177e4 1942
391e2f25 1943 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1da177e4 1944
5c04a7b8
AD
1945 FPT_hostDataXferAbort(ioport, thisCard,
1946 currSCCB);
1da177e4
LT
1947 }
1948
5c04a7b8
AD
1949 FPT_phaseBusFree(ioport, thisCard);
1950 }
1da177e4 1951
5c04a7b8 1952 else if (hp_int & ITICKLE) {
1da177e4 1953
5c04a7b8 1954 WRW_HARPOON((ioport + hp_intstat), ITICKLE);
391e2f25 1955 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
5c04a7b8 1956 }
1da177e4 1957
5c04a7b8
AD
1958 if (((struct sccb_card *)pCurrCard)->
1959 globalFlags & F_NEW_SCCB_CMD) {
1da177e4 1960
391e2f25 1961 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1da177e4 1962
391e2f25
KA
1963 if (pCurrCard->currentSCCB == NULL)
1964 FPT_queueSearchSelect(pCurrCard, thisCard);
1da177e4 1965
391e2f25
KA
1966 if (pCurrCard->currentSCCB != NULL) {
1967 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
5c04a7b8
AD
1968 FPT_ssel(ioport, thisCard);
1969 }
1da177e4 1970
5c04a7b8 1971 break;
1da177e4 1972
5c04a7b8 1973 }
1da177e4 1974
5c04a7b8 1975 } /*end while */
1da177e4 1976
5c04a7b8 1977 MENABLE_INT(ioport);
1da177e4 1978
5c1b85e2 1979 return 0;
1da177e4
LT
1980}
1981
1982/*---------------------------------------------------------------------
1983 *
1984 * Function: Sccb_bad_isr
1985 *
1986 * Description: Some type of interrupt has occurred which is slightly
1987 * out of the ordinary. We will now decode it fully, in
1988 * this routine. This is broken up in an attempt to save
1989 * processing time.
1990 *
1991 *---------------------------------------------------------------------*/
391e2f25 1992static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
5c04a7b8
AD
1993 struct sccb_card *pCurrCard,
1994 unsigned short p_int)
1da177e4 1995{
5c04a7b8
AD
1996 unsigned char temp, ScamFlg;
1997 struct sccb_mgr_tar_info *currTar_Info;
1998 struct nvram_info *pCurrNvRam;
1da177e4 1999
5c04a7b8
AD
2000 if (RD_HARPOON(p_port + hp_ext_status) &
2001 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
1da177e4 2002
5c04a7b8 2003 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1da177e4 2004
5c04a7b8
AD
2005 FPT_hostDataXferAbort(p_port, p_card,
2006 pCurrCard->currentSCCB);
2007 }
1da177e4 2008
5c04a7b8
AD
2009 if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
2010 {
2011 WR_HARPOON(p_port + hp_pci_stat_cfg,
2012 (RD_HARPOON(p_port + hp_pci_stat_cfg) &
2013 ~REC_MASTER_ABORT));
1da177e4 2014
5c04a7b8 2015 WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
1da177e4 2016
5c04a7b8 2017 }
1da177e4 2018
5c04a7b8 2019 if (pCurrCard->currentSCCB != NULL) {
1da177e4 2020
5c04a7b8
AD
2021 if (!pCurrCard->currentSCCB->HostStatus)
2022 pCurrCard->currentSCCB->HostStatus =
2023 SCCB_BM_ERR;
1da177e4 2024
5c04a7b8 2025 FPT_sxfrp(p_port, p_card);
1da177e4 2026
5c04a7b8
AD
2027 temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
2028 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2029 WR_HARPOON(p_port + hp_ee_ctrl,
2030 ((unsigned char)temp | SEE_MS | SEE_CS));
2031 WR_HARPOON(p_port + hp_ee_ctrl, temp);
1da177e4 2032
5c04a7b8
AD
2033 if (!
2034 (RDW_HARPOON((p_port + hp_intstat)) &
2035 (BUS_FREE | RESET))) {
2036 FPT_phaseDecode(p_port, p_card);
2037 }
2038 }
2039 }
1da177e4 2040
5c04a7b8 2041 else if (p_int & RESET) {
1da177e4 2042
5c04a7b8
AD
2043 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2044 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2045 if (pCurrCard->currentSCCB != NULL) {
1da177e4 2046
5c04a7b8 2047 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1da177e4 2048
5c04a7b8
AD
2049 FPT_hostDataXferAbort(p_port, p_card,
2050 pCurrCard->currentSCCB);
2051 }
1da177e4 2052
5c04a7b8 2053 DISABLE_AUTO(p_port);
1da177e4 2054
5c04a7b8 2055 FPT_sresb(p_port, p_card);
1da177e4 2056
5c04a7b8
AD
2057 while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2058 }
1da177e4 2059
5c04a7b8
AD
2060 pCurrNvRam = pCurrCard->pNvRamInfo;
2061 if (pCurrNvRam) {
2062 ScamFlg = pCurrNvRam->niScamConf;
2063 } else {
2064 ScamFlg =
2065 (unsigned char)FPT_utilEERead(p_port,
2066 SCAM_CONFIG / 2);
2067 }
1da177e4 2068
5c04a7b8 2069 FPT_XbowInit(p_port, ScamFlg);
1da177e4 2070
5c04a7b8 2071 FPT_scini(p_card, pCurrCard->ourId, 0);
1da177e4 2072
5c1b85e2 2073 return 0xFF;
5c04a7b8 2074 }
1da177e4 2075
5c04a7b8 2076 else if (p_int & FIFO) {
1da177e4 2077
5c04a7b8 2078 WRW_HARPOON((p_port + hp_intstat), FIFO);
1da177e4 2079
5c04a7b8
AD
2080 if (pCurrCard->currentSCCB != NULL)
2081 FPT_sxfrp(p_port, p_card);
2082 }
1da177e4 2083
5c04a7b8 2084 else if (p_int & TIMEOUT) {
1da177e4 2085
5c04a7b8 2086 DISABLE_AUTO(p_port);
1da177e4 2087
5c04a7b8
AD
2088 WRW_HARPOON((p_port + hp_intstat),
2089 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2090 IUNKWN));
1da177e4 2091
5c04a7b8 2092 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
1da177e4 2093
5c04a7b8
AD
2094 currTar_Info =
2095 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2096 if ((pCurrCard->globalFlags & F_CONLUN_IO)
2097 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2098 TAG_Q_TRYING))
2099 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2100 0;
1da177e4 2101 else
5c04a7b8 2102 currTar_Info->TarLUNBusy[0] = 0;
1da177e4 2103
5c04a7b8
AD
2104 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2105 currTar_Info->TarSyncCtrl = 0;
2106 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2107 }
1da177e4 2108
5c04a7b8
AD
2109 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2110 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2111 }
1da177e4 2112
5c04a7b8
AD
2113 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2114 currTar_Info);
1da177e4 2115
5c04a7b8 2116 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
1da177e4 2117
5c04a7b8 2118 }
1da177e4 2119
5c04a7b8 2120 else if (p_int & SCAM_SEL) {
1da177e4 2121
5c04a7b8
AD
2122 FPT_scarb(p_port, LEVEL2_TAR);
2123 FPT_scsel(p_port);
2124 FPT_scasid(p_card, p_port);
1da177e4 2125
5c04a7b8 2126 FPT_scbusf(p_port);
1da177e4 2127
5c04a7b8
AD
2128 WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2129 }
1da177e4 2130
5c1b85e2 2131 return 0x00;
1da177e4
LT
2132}
2133
1da177e4
LT
2134/*---------------------------------------------------------------------
2135 *
2136 * Function: SccbMgrTableInit
2137 *
2138 * Description: Initialize all Sccb manager data structures.
2139 *
2140 *---------------------------------------------------------------------*/
2141
cd9d715c 2142static void FPT_SccbMgrTableInitAll(void)
1da177e4 2143{
5c04a7b8 2144 unsigned char thisCard;
1da177e4 2145
5c04a7b8
AD
2146 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2147 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
1da177e4 2148
5c04a7b8
AD
2149 FPT_BL_Card[thisCard].ioPort = 0x00;
2150 FPT_BL_Card[thisCard].cardInfo = NULL;
2151 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2152 FPT_BL_Card[thisCard].ourId = 0x00;
2153 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2154 }
1da177e4
LT
2155}
2156
1da177e4
LT
2157/*---------------------------------------------------------------------
2158 *
2159 * Function: SccbMgrTableInit
2160 *
2161 * Description: Initialize all Sccb manager data structures.
2162 *
2163 *---------------------------------------------------------------------*/
2164
5c04a7b8
AD
2165static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2166 unsigned char p_card)
1da177e4 2167{
5c04a7b8 2168 unsigned char scsiID, qtag;
1da177e4 2169
5c04a7b8 2170 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
47b5d69c 2171 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
2172 }
2173
5c04a7b8
AD
2174 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2175 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2176 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2177 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2178 }
1da177e4 2179
5c04a7b8
AD
2180 pCurrCard->scanIndex = 0x00;
2181 pCurrCard->currentSCCB = NULL;
2182 pCurrCard->globalFlags = 0x00;
2183 pCurrCard->cmdCounter = 0x00;
1da177e4 2184 pCurrCard->tagQ_Lst = 0x01;
5c04a7b8 2185 pCurrCard->discQCount = 0;
1da177e4
LT
2186
2187}
2188
1da177e4
LT
2189/*---------------------------------------------------------------------
2190 *
2191 * Function: SccbMgrTableInit
2192 *
2193 * Description: Initialize all Sccb manager data structures.
2194 *
2195 *---------------------------------------------------------------------*/
2196
5c04a7b8
AD
2197static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2198 unsigned char target)
1da177e4
LT
2199{
2200
db038cf8 2201 unsigned char lun, qtag;
5c04a7b8 2202 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 2203
47b5d69c 2204 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2205
2206 currTar_Info->TarSelQ_Cnt = 0;
2207 currTar_Info->TarSyncCtrl = 0;
2208
2209 currTar_Info->TarSelQ_Head = NULL;
2210 currTar_Info->TarSelQ_Tail = NULL;
2211 currTar_Info->TarTagQ_Cnt = 0;
47b5d69c 2212 currTar_Info->TarLUN_CA = 0;
1da177e4 2213
5c04a7b8 2214 for (lun = 0; lun < MAX_LUN; lun++) {
47b5d69c 2215 currTar_Info->TarLUNBusy[lun] = 0;
1da177e4
LT
2216 currTar_Info->LunDiscQ_Idx[lun] = 0;
2217 }
2218
5c04a7b8
AD
2219 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2220 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2221 if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2222 target) {
47b5d69c
JB
2223 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2224 FPT_BL_Card[p_card].discQCount--;
1da177e4
LT
2225 }
2226 }
2227 }
2228}
2229
1da177e4
LT
2230/*---------------------------------------------------------------------
2231 *
2232 * Function: sfetm
2233 *
2234 * Description: Read in a message byte from the SCSI bus, and check
2235 * for a parity error.
2236 *
2237 *---------------------------------------------------------------------*/
2238
391e2f25 2239static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
1da177e4 2240{
db038cf8 2241 unsigned char message;
c823feeb 2242 unsigned short TimeOutLoop;
1da177e4
LT
2243
2244 TimeOutLoop = 0;
5c04a7b8
AD
2245 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2246 (TimeOutLoop++ < 20000)) {
2247 }
1da177e4 2248
5c04a7b8 2249 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
1da177e4 2250
5c04a7b8 2251 message = RD_HARPOON(port + hp_scsidata_0);
1da177e4 2252
5c04a7b8 2253 WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
1da177e4
LT
2254
2255 if (TimeOutLoop > 20000)
5c04a7b8
AD
2256 message = 0x00; /* force message byte = 0 if Time Out on Req */
2257
2258 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2259 (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2260 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2261 WR_HARPOON(port + hp_xferstat, 0);
2262 WR_HARPOON(port + hp_fiforead, 0);
2263 WR_HARPOON(port + hp_fifowrite, 0);
2264 if (pCurrSCCB != NULL) {
1da177e4
LT
2265 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2266 }
2267 message = 0x00;
5c04a7b8 2268 do {
1da177e4
LT
2269 ACCEPT_MSG_ATN(port);
2270 TimeOutLoop = 0;
5c04a7b8
AD
2271 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2272 (TimeOutLoop++ < 20000)) {
1da177e4 2273 }
5c04a7b8
AD
2274 if (TimeOutLoop > 20000) {
2275 WRW_HARPOON((port + hp_intstat), PARITY);
5c1b85e2 2276 return message;
5c04a7b8
AD
2277 }
2278 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2279 S_MSGI_PH) {
2280 WRW_HARPOON((port + hp_intstat), PARITY);
5c1b85e2 2281 return message;
1da177e4 2282 }
5c04a7b8 2283 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
1da177e4 2284
5c04a7b8 2285 RD_HARPOON(port + hp_scsidata_0);
1da177e4 2286
5c04a7b8 2287 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
1da177e4 2288
5c04a7b8 2289 } while (1);
1da177e4
LT
2290
2291 }
5c04a7b8
AD
2292 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2293 WR_HARPOON(port + hp_xferstat, 0);
2294 WR_HARPOON(port + hp_fiforead, 0);
2295 WR_HARPOON(port + hp_fifowrite, 0);
5c1b85e2 2296 return message;
1da177e4
LT
2297}
2298
1da177e4
LT
2299/*---------------------------------------------------------------------
2300 *
47b5d69c 2301 * Function: FPT_ssel
1da177e4
LT
2302 *
2303 * Description: Load up automation and select target device.
2304 *
2305 *---------------------------------------------------------------------*/
2306
391e2f25 2307static void FPT_ssel(u32 port, unsigned char p_card)
1da177e4
LT
2308{
2309
5c04a7b8 2310 unsigned char auto_loaded, i, target, *theCCB;
1da177e4 2311
391e2f25 2312 u32 cdb_reg;
5c04a7b8
AD
2313 struct sccb_card *CurrCard;
2314 struct sccb *currSCCB;
2315 struct sccb_mgr_tar_info *currTar_Info;
2316 unsigned char lastTag, lun;
1da177e4 2317
5c04a7b8
AD
2318 CurrCard = &FPT_BL_Card[p_card];
2319 currSCCB = CurrCard->currentSCCB;
2320 target = currSCCB->TargID;
2321 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2322 lastTag = CurrCard->tagQ_Lst;
1da177e4 2323
5c04a7b8 2324 ARAM_ACCESS(port);
1da177e4
LT
2325
2326 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2327 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2328
5c04a7b8
AD
2329 if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2330 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 2331
5c04a7b8 2332 lun = currSCCB->Lun;
1da177e4
LT
2333 else
2334 lun = 0;
2335
5c04a7b8
AD
2336 if (CurrCard->globalFlags & F_TAG_STARTED) {
2337 if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2338 if ((currTar_Info->TarLUN_CA == 0)
2339 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2340 == TAG_Q_TRYING)) {
2341
2342 if (currTar_Info->TarTagQ_Cnt != 0) {
2343 currTar_Info->TarLUNBusy[lun] = 1;
2344 FPT_queueSelectFail(CurrCard, p_card);
2345 SGRAM_ACCESS(port);
2346 return;
2347 }
1da177e4 2348
5c04a7b8
AD
2349 else {
2350 currTar_Info->TarLUNBusy[lun] = 1;
2351 }
1da177e4 2352
5c04a7b8
AD
2353 }
2354 /*End non-tagged */
2355 else {
2356 currTar_Info->TarLUNBusy[lun] = 1;
2357 }
1da177e4 2358
5c04a7b8
AD
2359 }
2360 /*!Use cmd Q Tagged */
2361 else {
2362 if (currTar_Info->TarLUN_CA == 1) {
2363 FPT_queueSelectFail(CurrCard, p_card);
2364 SGRAM_ACCESS(port);
2365 return;
2366 }
1da177e4 2367
5c04a7b8 2368 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4 2369
5c04a7b8 2370 } /*else use cmd Q tagged */
1da177e4 2371
5c04a7b8
AD
2372 }
2373 /*if glob tagged started */
2374 else {
2375 currTar_Info->TarLUNBusy[lun] = 1;
2376 }
1da177e4 2377
5c04a7b8
AD
2378 if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2379 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2380 || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2381 if (CurrCard->discQCount >= QUEUE_DEPTH) {
47b5d69c 2382 currTar_Info->TarLUNBusy[lun] = 1;
5c04a7b8 2383 FPT_queueSelectFail(CurrCard, p_card);
1da177e4
LT
2384 SGRAM_ACCESS(port);
2385 return;
2386 }
5c04a7b8
AD
2387 for (i = 1; i < QUEUE_DEPTH; i++) {
2388 if (++lastTag >= QUEUE_DEPTH)
2389 lastTag = 1;
2390 if (CurrCard->discQ_Tbl[lastTag] == NULL) {
1da177e4
LT
2391 CurrCard->tagQ_Lst = lastTag;
2392 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2393 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2394 CurrCard->discQCount++;
2395 break;
2396 }
2397 }
5c04a7b8 2398 if (i == QUEUE_DEPTH) {
47b5d69c 2399 currTar_Info->TarLUNBusy[lun] = 1;
5c04a7b8 2400 FPT_queueSelectFail(CurrCard, p_card);
1da177e4
LT
2401 SGRAM_ACCESS(port);
2402 return;
2403 }
2404 }
2405
5c04a7b8 2406 auto_loaded = 0;
1da177e4 2407
5c04a7b8
AD
2408 WR_HARPOON(port + hp_select_id, target);
2409 WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
1da177e4 2410
5c04a7b8
AD
2411 if (currSCCB->OperationCode == RESET_COMMAND) {
2412 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2413 (currSCCB->
2414 Sccb_idmsg & ~DISC_PRIV)));
1da177e4 2415
5c04a7b8 2416 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
1da177e4 2417
5c04a7b8 2418 currSCCB->Sccb_scsimsg = SMDEV_RESET;
1da177e4 2419
5c04a7b8
AD
2420 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2421 auto_loaded = 1;
2422 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
1da177e4 2423
5c04a7b8
AD
2424 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2425 currTar_Info->TarSyncCtrl = 0;
2426 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2427 }
1da177e4 2428
5c04a7b8
AD
2429 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2430 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2431 }
1da177e4 2432
5c04a7b8
AD
2433 FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2434 FPT_SccbMgrTableInitTarget(p_card, target);
1da177e4 2435
5c04a7b8 2436 }
1da177e4 2437
5c04a7b8
AD
2438 else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2439 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2440 (currSCCB->
2441 Sccb_idmsg & ~DISC_PRIV)));
1da177e4 2442
5c04a7b8 2443 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
1da177e4 2444
5c04a7b8
AD
2445 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2446 (((unsigned
2447 char)(currSCCB->
2448 ControlByte &
2449 TAG_TYPE_MASK)
2450 >> 6) | (unsigned char)
2451 0x20)));
2452 WRW_HARPOON((port + SYNC_MSGS + 2),
2453 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2454 WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
1da177e4 2455
5c04a7b8
AD
2456 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2457 auto_loaded = 1;
1da177e4 2458
5c04a7b8 2459 }
1da177e4 2460
5c04a7b8
AD
2461 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2462 auto_loaded = FPT_siwidn(port, p_card);
2463 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2464 }
1da177e4 2465
5c04a7b8
AD
2466 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2467 == SYNC_SUPPORTED)) {
2468 auto_loaded = FPT_sisyncn(port, p_card, 0);
2469 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2470 }
1da177e4 2471
5c04a7b8 2472 if (!auto_loaded) {
1da177e4 2473
5c04a7b8 2474 if (currSCCB->ControlByte & F_USE_CMD_Q) {
1da177e4 2475
5c04a7b8 2476 CurrCard->globalFlags |= F_TAG_STARTED;
1da177e4 2477
5c04a7b8
AD
2478 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2479 == TAG_Q_REJECT) {
2480 currSCCB->ControlByte &= ~F_USE_CMD_Q;
1da177e4 2481
5c04a7b8
AD
2482 /* Fix up the start instruction with a jump to
2483 Non-Tag-CMD handling */
2484 WRW_HARPOON((port + ID_MSG_STRT),
2485 BRH_OP + ALWAYS + NTCMD);
1da177e4 2486
5c04a7b8
AD
2487 WRW_HARPOON((port + NON_TAG_ID_MSG),
2488 (MPM_OP + AMSG_OUT +
2489 currSCCB->Sccb_idmsg));
1da177e4 2490
5c04a7b8
AD
2491 WR_HARPOON(port + hp_autostart_3,
2492 (SELECT + SELCHK_STRT));
1da177e4 2493
25985edc 2494 /* Setup our STATE so we know what happened when
5c04a7b8
AD
2495 the wheels fall off. */
2496 currSCCB->Sccb_scsistat = SELECT_ST;
1da177e4 2497
5c04a7b8
AD
2498 currTar_Info->TarLUNBusy[lun] = 1;
2499 }
1da177e4 2500
5c04a7b8
AD
2501 else {
2502 WRW_HARPOON((port + ID_MSG_STRT),
2503 (MPM_OP + AMSG_OUT +
2504 currSCCB->Sccb_idmsg));
2505
2506 WRW_HARPOON((port + ID_MSG_STRT + 2),
2507 (MPM_OP + AMSG_OUT +
2508 (((unsigned char)(currSCCB->
2509 ControlByte &
2510 TAG_TYPE_MASK)
2511 >> 6) | (unsigned char)0x20)));
2512
2513 for (i = 1; i < QUEUE_DEPTH; i++) {
2514 if (++lastTag >= QUEUE_DEPTH)
2515 lastTag = 1;
2516 if (CurrCard->discQ_Tbl[lastTag] ==
2517 NULL) {
2518 WRW_HARPOON((port +
2519 ID_MSG_STRT + 6),
2520 (MPM_OP + AMSG_OUT +
2521 lastTag));
1da177e4
LT
2522 CurrCard->tagQ_Lst = lastTag;
2523 currSCCB->Sccb_tag = lastTag;
5c04a7b8
AD
2524 CurrCard->discQ_Tbl[lastTag] =
2525 currSCCB;
1da177e4
LT
2526 CurrCard->discQCount++;
2527 break;
2528 }
2529 }
2530
5c04a7b8
AD
2531 if (i == QUEUE_DEPTH) {
2532 currTar_Info->TarLUNBusy[lun] = 1;
2533 FPT_queueSelectFail(CurrCard, p_card);
2534 SGRAM_ACCESS(port);
2535 return;
2536 }
1da177e4 2537
5c04a7b8 2538 currSCCB->Sccb_scsistat = SELECT_Q_ST;
1da177e4 2539
5c04a7b8
AD
2540 WR_HARPOON(port + hp_autostart_3,
2541 (SELECT + SELCHK_STRT));
2542 }
2543 }
1da177e4 2544
5c04a7b8 2545 else {
1da177e4 2546
5c04a7b8
AD
2547 WRW_HARPOON((port + ID_MSG_STRT),
2548 BRH_OP + ALWAYS + NTCMD);
1da177e4 2549
5c04a7b8
AD
2550 WRW_HARPOON((port + NON_TAG_ID_MSG),
2551 (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
1da177e4 2552
5c04a7b8 2553 currSCCB->Sccb_scsistat = SELECT_ST;
1da177e4 2554
5c04a7b8
AD
2555 WR_HARPOON(port + hp_autostart_3,
2556 (SELECT + SELCHK_STRT));
2557 }
1da177e4 2558
5c04a7b8 2559 theCCB = (unsigned char *)&currSCCB->Cdb[0];
1da177e4 2560
5c04a7b8 2561 cdb_reg = port + CMD_STRT;
1da177e4 2562
5c04a7b8
AD
2563 for (i = 0; i < currSCCB->CdbLength; i++) {
2564 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2565 cdb_reg += 2;
2566 theCCB++;
2567 }
1da177e4 2568
5c04a7b8
AD
2569 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2570 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
1da177e4 2571
5c04a7b8
AD
2572 }
2573 /* auto_loaded */
2574 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2575 WR_HARPOON(port + hp_xferstat, 0x00);
1da177e4 2576
5c04a7b8 2577 WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
1da177e4 2578
5c04a7b8 2579 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
1da177e4 2580
5c04a7b8
AD
2581 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2582 WR_HARPOON(port + hp_scsictrl_0,
2583 (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2584 } else {
1da177e4 2585
db038cf8 2586/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
1da177e4 2587 auto_loaded |= AUTO_IMMED; */
5c04a7b8 2588 auto_loaded = AUTO_IMMED;
1da177e4 2589
5c04a7b8 2590 DISABLE_AUTO(port);
1da177e4 2591
5c04a7b8
AD
2592 WR_HARPOON(port + hp_autostart_3, auto_loaded);
2593 }
1da177e4 2594
5c04a7b8 2595 SGRAM_ACCESS(port);
1da177e4
LT
2596}
2597
1da177e4
LT
2598/*---------------------------------------------------------------------
2599 *
47b5d69c 2600 * Function: FPT_sres
1da177e4
LT
2601 *
2602 * Description: Hookup the correct CCB and handle the incoming messages.
2603 *
2604 *---------------------------------------------------------------------*/
2605
391e2f25 2606static void FPT_sres(u32 port, unsigned char p_card,
5c04a7b8 2607 struct sccb_card *pCurrCard)
1da177e4
LT
2608{
2609
5c04a7b8 2610 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
1da177e4 2611
5c04a7b8
AD
2612 struct sccb_mgr_tar_info *currTar_Info;
2613 struct sccb *currSCCB;
1da177e4 2614
5c04a7b8
AD
2615 if (pCurrCard->currentSCCB != NULL) {
2616 currTar_Info =
2617 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2618 DISABLE_AUTO(port);
2619
5c04a7b8 2620 WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
1da177e4
LT
2621
2622 currSCCB = pCurrCard->currentSCCB;
5c04a7b8 2623 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
1da177e4
LT
2624 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2625 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2626 }
5c04a7b8 2627 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
1da177e4
LT
2628 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2629 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2630 }
5c04a7b8
AD
2631 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2632 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2633 TAG_Q_TRYING))) {
2634 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2635 if (currSCCB->Sccb_scsistat != ABORT_ST) {
1da177e4 2636 pCurrCard->discQCount--;
5c04a7b8
AD
2637 pCurrCard->discQ_Tbl[currTar_Info->
2638 LunDiscQ_Idx[currSCCB->
2639 Lun]]
2640 = NULL;
1da177e4 2641 }
5c04a7b8
AD
2642 } else {
2643 currTar_Info->TarLUNBusy[0] = 0;
2644 if (currSCCB->Sccb_tag) {
2645 if (currSCCB->Sccb_scsistat != ABORT_ST) {
1da177e4 2646 pCurrCard->discQCount--;
5c04a7b8
AD
2647 pCurrCard->discQ_Tbl[currSCCB->
2648 Sccb_tag] = NULL;
1da177e4 2649 }
5c04a7b8
AD
2650 } else {
2651 if (currSCCB->Sccb_scsistat != ABORT_ST) {
1da177e4 2652 pCurrCard->discQCount--;
5c04a7b8
AD
2653 pCurrCard->discQ_Tbl[currTar_Info->
2654 LunDiscQ_Idx[0]] =
2655 NULL;
1da177e4
LT
2656 }
2657 }
2658 }
2659
5c04a7b8 2660 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
1da177e4
LT
2661 }
2662
5c04a7b8 2663 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
1da177e4 2664
5c04a7b8 2665 our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
47b5d69c 2666 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4 2667
1da177e4 2668 msgRetryCount = 0;
5c04a7b8 2669 do {
1da177e4 2670
47b5d69c 2671 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2672 tag = 0;
2673
5c04a7b8
AD
2674 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2675 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
1da177e4 2676
5c04a7b8 2677 WRW_HARPOON((port + hp_intstat), PHASE);
1da177e4
LT
2678 return;
2679 }
2680 }
2681
5c04a7b8
AD
2682 WRW_HARPOON((port + hp_intstat), PHASE);
2683 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
1da177e4 2684
5c04a7b8
AD
2685 message = FPT_sfm(port, pCurrCard->currentSCCB);
2686 if (message) {
1da177e4 2687
5c04a7b8 2688 if (message <= (0x80 | LUN_MASK)) {
db038cf8 2689 lun = message & (unsigned char)LUN_MASK;
1da177e4 2690
5c04a7b8
AD
2691 if ((currTar_Info->
2692 TarStatus & TAR_TAG_Q_MASK) ==
2693 TAG_Q_TRYING) {
2694 if (currTar_Info->TarTagQ_Cnt !=
2695 0) {
2696
2697 if (!
2698 (currTar_Info->
2699 TarLUN_CA)) {
2700 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2701
2702 message =
2703 FPT_sfm
2704 (port,
2705 pCurrCard->
2706 currentSCCB);
2707 if (message) {
2708 ACCEPT_MSG
2709 (port);
1da177e4
LT
2710 }
2711
2712 else
5c04a7b8
AD
2713 message
2714 = 0;
2715
2716 if (message !=
2717 0) {
2718 tag =
2719 FPT_sfm
2720 (port,
2721 pCurrCard->
2722 currentSCCB);
2723
2724 if (!
2725 (tag))
2726 message
2727 =
2728 0;
1da177e4
LT
2729 }
2730
5c04a7b8
AD
2731 }
2732 /*C.A. exists! */
2733 }
2734 /*End Q cnt != 0 */
2735 }
2736 /*End Tag cmds supported! */
2737 }
2738 /*End valid ID message. */
2739 else {
1da177e4
LT
2740
2741 ACCEPT_MSG_ATN(port);
2742 }
2743
5c04a7b8
AD
2744 }
2745 /* End good id message. */
2746 else {
1da177e4 2747
47b5d69c 2748 message = 0;
1da177e4 2749 }
5c04a7b8 2750 } else {
1da177e4
LT
2751 ACCEPT_MSG_ATN(port);
2752
5c04a7b8
AD
2753 while (!
2754 (RDW_HARPOON((port + hp_intstat)) &
2755 (PHASE | RESET))
2756 && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2757 && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
1da177e4
LT
2758
2759 return;
2760 }
1da177e4 2761
5c04a7b8 2762 if (message == 0) {
1da177e4 2763 msgRetryCount++;
5c04a7b8 2764 if (msgRetryCount == 1) {
47b5d69c 2765 FPT_SendMsg(port, SMPARITY);
5c04a7b8 2766 } else {
47b5d69c 2767 FPT_SendMsg(port, SMDEV_RESET);
1da177e4 2768
5c04a7b8
AD
2769 FPT_sssyncv(port, our_target, NARROW_SCSI,
2770 currTar_Info);
1da177e4 2771
5c04a7b8
AD
2772 if (FPT_sccbMgrTbl[p_card][our_target].
2773 TarEEValue & EE_SYNC_MASK) {
2774
2775 FPT_sccbMgrTbl[p_card][our_target].
2776 TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
2777
2778 }
2779
5c04a7b8
AD
2780 if (FPT_sccbMgrTbl[p_card][our_target].
2781 TarEEValue & EE_WIDE_SCSI) {
1da177e4 2782
5c04a7b8
AD
2783 FPT_sccbMgrTbl[p_card][our_target].
2784 TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
2785 }
2786
5c04a7b8
AD
2787 FPT_queueFlushTargSccb(p_card, our_target,
2788 SCCB_COMPLETE);
2789 FPT_SccbMgrTableInitTarget(p_card, our_target);
1da177e4
LT
2790 return;
2791 }
2792 }
5c04a7b8 2793 } while (message == 0);
1da177e4 2794
5c04a7b8
AD
2795 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2796 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
47b5d69c 2797 currTar_Info->TarLUNBusy[lun] = 1;
5c04a7b8
AD
2798 pCurrCard->currentSCCB =
2799 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2800 if (pCurrCard->currentSCCB != NULL) {
1da177e4 2801 ACCEPT_MSG(port);
5c04a7b8 2802 } else {
1da177e4
LT
2803 ACCEPT_MSG_ATN(port);
2804 }
5c04a7b8 2805 } else {
47b5d69c 2806 currTar_Info->TarLUNBusy[0] = 1;
1da177e4 2807
5c04a7b8
AD
2808 if (tag) {
2809 if (pCurrCard->discQ_Tbl[tag] != NULL) {
2810 pCurrCard->currentSCCB =
2811 pCurrCard->discQ_Tbl[tag];
2812 currTar_Info->TarTagQ_Cnt--;
1da177e4 2813 ACCEPT_MSG(port);
5c04a7b8
AD
2814 } else {
2815 ACCEPT_MSG_ATN(port);
1da177e4 2816 }
5c04a7b8
AD
2817 } else {
2818 pCurrCard->currentSCCB =
2819 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2820 if (pCurrCard->currentSCCB != NULL) {
1da177e4 2821 ACCEPT_MSG(port);
5c04a7b8 2822 } else {
1da177e4
LT
2823 ACCEPT_MSG_ATN(port);
2824 }
2825 }
2826 }
2827
5c04a7b8
AD
2828 if (pCurrCard->currentSCCB != NULL) {
2829 if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2830 /* During Abort Tag command, the target could have got re-selected
2831 and completed the command. Check the select Q and remove the CCB
2832 if it is in the Select Q */
47b5d69c 2833 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
1da177e4
LT
2834 }
2835 }
2836
5c04a7b8
AD
2837 while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2838 !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2839 (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
1da177e4
LT
2840}
2841
391e2f25 2842static void FPT_SendMsg(u32 port, unsigned char message)
1da177e4 2843{
5c04a7b8
AD
2844 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2845 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
1da177e4 2846
5c04a7b8 2847 WRW_HARPOON((port + hp_intstat), PHASE);
1da177e4
LT
2848 return;
2849 }
2850 }
2851
5c04a7b8
AD
2852 WRW_HARPOON((port + hp_intstat), PHASE);
2853 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2854 WRW_HARPOON((port + hp_intstat),
2855 (BUS_FREE | PHASE | XFER_CNT_0));
1da177e4 2856
5c04a7b8 2857 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
1da177e4 2858
5c04a7b8 2859 WR_HARPOON(port + hp_scsidata_0, message);
1da177e4 2860
5c04a7b8 2861 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
1da177e4
LT
2862
2863 ACCEPT_MSG(port);
2864
5c04a7b8 2865 WR_HARPOON(port + hp_portctrl_0, 0x00);
1da177e4
LT
2866
2867 if ((message == SMABORT) || (message == SMDEV_RESET) ||
5c04a7b8
AD
2868 (message == SMABORT_TAG)) {
2869 while (!
2870 (RDW_HARPOON((port + hp_intstat)) &
2871 (BUS_FREE | PHASE))) {
2872 }
1da177e4 2873
5c04a7b8
AD
2874 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2875 WRW_HARPOON((port + hp_intstat), BUS_FREE);
1da177e4
LT
2876 }
2877 }
2878 }
2879}
2880
2881/*---------------------------------------------------------------------
2882 *
47b5d69c 2883 * Function: FPT_sdecm
1da177e4 2884 *
25985edc 2885 * Description: Determine the proper response to the message from the
1da177e4
LT
2886 * target device.
2887 *
2888 *---------------------------------------------------------------------*/
391e2f25 2889static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
1da177e4 2890{
5c04a7b8
AD
2891 struct sccb *currSCCB;
2892 struct sccb_card *CurrCard;
2893 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 2894
47b5d69c 2895 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
2896 currSCCB = CurrCard->currentSCCB;
2897
47b5d69c 2898 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 2899
5c04a7b8
AD
2900 if (message == SMREST_DATA_PTR) {
2901 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
1da177e4
LT
2902 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2903
47b5d69c 2904 FPT_hostDataXferRestart(currSCCB);
1da177e4
LT
2905 }
2906
2907 ACCEPT_MSG(port);
5c04a7b8
AD
2908 WR_HARPOON(port + hp_autostart_1,
2909 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
2910 }
2911
5c04a7b8 2912 else if (message == SMCMD_COMP) {
1da177e4 2913
5c04a7b8
AD
2914 if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2915 currTar_Info->TarStatus &=
2916 ~(unsigned char)TAR_TAG_Q_MASK;
db038cf8 2917 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
1da177e4
LT
2918 }
2919
2920 ACCEPT_MSG(port);
2921
2922 }
2923
5c04a7b8
AD
2924 else if ((message == SMNO_OP) || (message >= SMIDENT)
2925 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) {
1da177e4
LT
2926
2927 ACCEPT_MSG(port);
5c04a7b8
AD
2928 WR_HARPOON(port + hp_autostart_1,
2929 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
2930 }
2931
5c04a7b8 2932 else if (message == SMREJECT) {
1da177e4
LT
2933
2934 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
5c04a7b8
AD
2935 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2936 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2937 || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2938 TAG_Q_TRYING))
1da177e4 2939 {
5c04a7b8 2940 WRW_HARPOON((port + hp_intstat), BUS_FREE);
1da177e4
LT
2941
2942 ACCEPT_MSG(port);
2943
5c04a7b8
AD
2944 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2945 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
1da177e4 2946 {
5c04a7b8 2947 }
1da177e4 2948
5c04a7b8 2949 if (currSCCB->Lun == 0x00) {
adb11023 2950 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
1da177e4 2951
5c04a7b8
AD
2952 currTar_Info->TarStatus |=
2953 (unsigned char)SYNC_SUPPORTED;
1da177e4 2954
5c04a7b8
AD
2955 currTar_Info->TarEEValue &=
2956 ~EE_SYNC_MASK;
2957 }
1da177e4 2958
adb11023
NC
2959 else if (currSCCB->Sccb_scsistat ==
2960 SELECT_WN_ST) {
1da177e4 2961
5c04a7b8
AD
2962 currTar_Info->TarStatus =
2963 (currTar_Info->
2964 TarStatus & ~WIDE_ENABLED) |
2965 WIDE_NEGOCIATED;
1da177e4 2966
5c04a7b8
AD
2967 currTar_Info->TarEEValue &=
2968 ~EE_WIDE_SCSI;
1da177e4
LT
2969
2970 }
1da177e4 2971
5c04a7b8
AD
2972 else if ((currTar_Info->
2973 TarStatus & TAR_TAG_Q_MASK) ==
2974 TAG_Q_TRYING) {
2975 currTar_Info->TarStatus =
2976 (currTar_Info->
2977 TarStatus & ~(unsigned char)
2978 TAR_TAG_Q_MASK) | TAG_Q_REJECT;
1da177e4
LT
2979
2980 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2981 CurrCard->discQCount--;
5c04a7b8
AD
2982 CurrCard->discQ_Tbl[currSCCB->
2983 Sccb_tag] = NULL;
1da177e4
LT
2984 currSCCB->Sccb_tag = 0x00;
2985
2986 }
2987 }
2988
5c04a7b8 2989 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
1da177e4 2990
5c04a7b8
AD
2991 if (currSCCB->Lun == 0x00) {
2992 WRW_HARPOON((port + hp_intstat),
2993 BUS_FREE);
1da177e4
LT
2994 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2995 }
2996 }
2997
5c04a7b8 2998 else {
1da177e4 2999
5c04a7b8
AD
3000 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
3001 ((currTar_Info->
3002 TarStatus & TAR_TAG_Q_MASK) !=
3003 TAG_Q_TRYING))
3004 currTar_Info->TarLUNBusy[currSCCB->
3005 Lun] = 1;
1da177e4 3006 else
47b5d69c 3007 currTar_Info->TarLUNBusy[0] = 1;
1da177e4 3008
5c04a7b8
AD
3009 currSCCB->ControlByte &=
3010 ~(unsigned char)F_USE_CMD_Q;
1da177e4 3011
5c04a7b8
AD
3012 WR_HARPOON(port + hp_autostart_1,
3013 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3014
3015 }
3016 }
3017
5c04a7b8 3018 else {
1da177e4
LT
3019 ACCEPT_MSG(port);
3020
5c04a7b8
AD
3021 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
3022 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
1da177e4 3023 {
5c04a7b8
AD
3024 }
3025
3026 if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
3027 WR_HARPOON(port + hp_autostart_1,
3028 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3029 }
3030 }
3031 }
3032
5c04a7b8 3033 else if (message == SMEXT) {
1da177e4
LT
3034
3035 ACCEPT_MSG(port);
5c04a7b8 3036 FPT_shandem(port, p_card, currSCCB);
1da177e4
LT
3037 }
3038
5c04a7b8 3039 else if (message == SMIGNORWR) {
1da177e4 3040
5c04a7b8 3041 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
1da177e4 3042
5c04a7b8 3043 message = FPT_sfm(port, currSCCB);
1da177e4 3044
5c04a7b8 3045 if (currSCCB->Sccb_scsimsg != SMPARITY)
1da177e4 3046 ACCEPT_MSG(port);
5c04a7b8
AD
3047 WR_HARPOON(port + hp_autostart_1,
3048 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3049 }
3050
5c04a7b8 3051 else {
1da177e4
LT
3052
3053 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3054 currSCCB->Sccb_scsimsg = SMREJECT;
3055
3056 ACCEPT_MSG_ATN(port);
5c04a7b8
AD
3057 WR_HARPOON(port + hp_autostart_1,
3058 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3059 }
3060}
3061
1da177e4
LT
3062/*---------------------------------------------------------------------
3063 *
47b5d69c 3064 * Function: FPT_shandem
1da177e4
LT
3065 *
3066 * Description: Decide what to do with the extended message.
3067 *
3068 *---------------------------------------------------------------------*/
391e2f25 3069static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
1da177e4 3070{
5c04a7b8 3071 unsigned char length, message;
1da177e4 3072
5c04a7b8
AD
3073 length = FPT_sfm(port, pCurrSCCB);
3074 if (length) {
1da177e4
LT
3075
3076 ACCEPT_MSG(port);
5c04a7b8
AD
3077 message = FPT_sfm(port, pCurrSCCB);
3078 if (message) {
1da177e4 3079
5c04a7b8 3080 if (message == SMSYNC) {
1da177e4 3081
5c04a7b8 3082 if (length == 0x03) {
1da177e4
LT
3083
3084 ACCEPT_MSG(port);
5c04a7b8
AD
3085 FPT_stsyncn(port, p_card);
3086 } else {
1da177e4
LT
3087
3088 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3089 ACCEPT_MSG_ATN(port);
3090 }
5c04a7b8 3091 } else if (message == SMWDTR) {
1da177e4 3092
5c04a7b8 3093 if (length == 0x02) {
1da177e4
LT
3094
3095 ACCEPT_MSG(port);
5c04a7b8
AD
3096 FPT_stwidn(port, p_card);
3097 } else {
1da177e4
LT
3098
3099 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3100 ACCEPT_MSG_ATN(port);
3101
5c04a7b8
AD
3102 WR_HARPOON(port + hp_autostart_1,
3103 (AUTO_IMMED +
3104 DISCONNECT_START));
1da177e4 3105 }
5c04a7b8 3106 } else {
1da177e4
LT
3107
3108 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3109 ACCEPT_MSG_ATN(port);
3110
5c04a7b8
AD
3111 WR_HARPOON(port + hp_autostart_1,
3112 (AUTO_IMMED + DISCONNECT_START));
1da177e4 3113 }
5c04a7b8
AD
3114 } else {
3115 if (pCurrSCCB->Sccb_scsimsg != SMPARITY)
1da177e4 3116 ACCEPT_MSG(port);
5c04a7b8
AD
3117 WR_HARPOON(port + hp_autostart_1,
3118 (AUTO_IMMED + DISCONNECT_START));
1da177e4 3119 }
5c04a7b8
AD
3120 } else {
3121 if (pCurrSCCB->Sccb_scsimsg == SMPARITY)
3122 WR_HARPOON(port + hp_autostart_1,
3123 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3124 }
3125}
3126
1da177e4
LT
3127/*---------------------------------------------------------------------
3128 *
47b5d69c 3129 * Function: FPT_sisyncn
1da177e4
LT
3130 *
3131 * Description: Read in a message byte from the SCSI bus, and check
3132 * for a parity error.
3133 *
3134 *---------------------------------------------------------------------*/
3135
391e2f25 3136static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
5c04a7b8 3137 unsigned char syncFlag)
1da177e4 3138{
5c04a7b8
AD
3139 struct sccb *currSCCB;
3140 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 3141
5c04a7b8
AD
3142 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3143 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3144
5c04a7b8 3145 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
1da177e4 3146
5c04a7b8
AD
3147 WRW_HARPOON((port + ID_MSG_STRT),
3148 (MPM_OP + AMSG_OUT +
3149 (currSCCB->
3150 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
1da177e4 3151
5c04a7b8 3152 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
1da177e4 3153
5c04a7b8
AD
3154 WRW_HARPOON((port + SYNC_MSGS + 0),
3155 (MPM_OP + AMSG_OUT + SMEXT));
3156 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3157 WRW_HARPOON((port + SYNC_MSGS + 4),
3158 (MPM_OP + AMSG_OUT + SMSYNC));
1da177e4 3159
5c04a7b8 3160 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
1da177e4 3161
5c04a7b8
AD
3162 WRW_HARPOON((port + SYNC_MSGS + 6),
3163 (MPM_OP + AMSG_OUT + 12));
1da177e4 3164
5c04a7b8
AD
3165 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3166 EE_SYNC_10MB)
1da177e4 3167
5c04a7b8
AD
3168 WRW_HARPOON((port + SYNC_MSGS + 6),
3169 (MPM_OP + AMSG_OUT + 25));
1da177e4 3170
5c04a7b8
AD
3171 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3172 EE_SYNC_5MB)
1da177e4 3173
5c04a7b8
AD
3174 WRW_HARPOON((port + SYNC_MSGS + 6),
3175 (MPM_OP + AMSG_OUT + 50));
1da177e4 3176
1da177e4 3177 else
5c04a7b8
AD
3178 WRW_HARPOON((port + SYNC_MSGS + 6),
3179 (MPM_OP + AMSG_OUT + 00));
3180
3181 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3182 WRW_HARPOON((port + SYNC_MSGS + 10),
3183 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3184 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3185
3186 if (syncFlag == 0) {
3187 WR_HARPOON(port + hp_autostart_3,
3188 (SELECT + SELCHK_STRT));
3189 currTar_Info->TarStatus =
3190 ((currTar_Info->
3191 TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3192 (unsigned char)SYNC_TRYING);
3193 } else {
3194 WR_HARPOON(port + hp_autostart_3,
3195 (AUTO_IMMED + CMD_ONLY_STRT));
1da177e4
LT
3196 }
3197
5c1b85e2 3198 return 1;
5c04a7b8 3199 }
1da177e4 3200
5c04a7b8 3201 else {
1da177e4 3202
5c04a7b8
AD
3203 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3204 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
5c1b85e2 3205 return 0;
5c04a7b8 3206 }
1da177e4
LT
3207}
3208
1da177e4
LT
3209/*---------------------------------------------------------------------
3210 *
47b5d69c 3211 * Function: FPT_stsyncn
1da177e4
LT
3212 *
3213 * Description: The has sent us a Sync Nego message so handle it as
3214 * necessary.
3215 *
3216 *---------------------------------------------------------------------*/
391e2f25 3217static void FPT_stsyncn(u32 port, unsigned char p_card)
1da177e4 3218{
5c04a7b8
AD
3219 unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3220 struct sccb *currSCCB;
3221 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 3222
5c04a7b8
AD
3223 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3224 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3225
5c04a7b8 3226 sync_msg = FPT_sfm(port, currSCCB);
1da177e4 3227
5c04a7b8
AD
3228 if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3229 WR_HARPOON(port + hp_autostart_1,
3230 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3231 return;
3232 }
3233
5c04a7b8 3234 ACCEPT_MSG(port);
1da177e4 3235
5c04a7b8 3236 offset = FPT_sfm(port, currSCCB);
1da177e4 3237
5c04a7b8
AD
3238 if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3239 WR_HARPOON(port + hp_autostart_1,
3240 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3241 return;
3242 }
3243
5c04a7b8 3244 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
1da177e4 3245
5c04a7b8 3246 our_sync_msg = 12; /* Setup our Message to 20mb/s */
1da177e4 3247
5c04a7b8 3248 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
1da177e4 3249
5c04a7b8 3250 our_sync_msg = 25; /* Setup our Message to 10mb/s */
1da177e4 3251
5c04a7b8 3252 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
1da177e4 3253
5c04a7b8
AD
3254 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3255 else
1da177e4 3256
5c04a7b8 3257 our_sync_msg = 0; /* Message = Async */
1da177e4 3258
5c04a7b8
AD
3259 if (sync_msg < our_sync_msg) {
3260 sync_msg = our_sync_msg; /*if faster, then set to max. */
3261 }
1da177e4 3262
5c04a7b8
AD
3263 if (offset == ASYNC)
3264 sync_msg = ASYNC;
1da177e4 3265
5c04a7b8
AD
3266 if (offset > MAX_OFFSET)
3267 offset = MAX_OFFSET;
1da177e4 3268
5c04a7b8 3269 sync_reg = 0x00;
1da177e4 3270
5c04a7b8 3271 if (sync_msg > 12)
1da177e4 3272
5c04a7b8 3273 sync_reg = 0x20; /* Use 10MB/s */
1da177e4 3274
5c04a7b8 3275 if (sync_msg > 25)
1da177e4 3276
5c04a7b8 3277 sync_reg = 0x40; /* Use 6.6MB/s */
1da177e4 3278
5c04a7b8 3279 if (sync_msg > 38)
1da177e4 3280
5c04a7b8 3281 sync_reg = 0x60; /* Use 5MB/s */
1da177e4 3282
5c04a7b8 3283 if (sync_msg > 50)
1da177e4 3284
5c04a7b8 3285 sync_reg = 0x80; /* Use 4MB/s */
1da177e4 3286
5c04a7b8 3287 if (sync_msg > 62)
1da177e4 3288
5c04a7b8 3289 sync_reg = 0xA0; /* Use 3.33MB/s */
1da177e4 3290
5c04a7b8 3291 if (sync_msg > 75)
1da177e4 3292
5c04a7b8 3293 sync_reg = 0xC0; /* Use 2.85MB/s */
1da177e4 3294
5c04a7b8 3295 if (sync_msg > 87)
1da177e4 3296
5c04a7b8 3297 sync_reg = 0xE0; /* Use 2.5MB/s */
1da177e4 3298
5c04a7b8 3299 if (sync_msg > 100) {
1da177e4 3300
5c04a7b8
AD
3301 sync_reg = 0x00; /* Use ASYNC */
3302 offset = 0x00;
3303 }
1da177e4 3304
5c04a7b8 3305 if (currTar_Info->TarStatus & WIDE_ENABLED)
1da177e4 3306
5c04a7b8 3307 sync_reg |= offset;
1da177e4 3308
5c04a7b8 3309 else
1da177e4 3310
5c04a7b8 3311 sync_reg |= (offset | NARROW_SCSI);
1da177e4 3312
5c04a7b8 3313 FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
1da177e4 3314
5c04a7b8 3315 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
1da177e4 3316
5c04a7b8 3317 ACCEPT_MSG(port);
1da177e4 3318
5c04a7b8
AD
3319 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3320 ~(unsigned char)TAR_SYNC_MASK) |
3321 (unsigned char)SYNC_SUPPORTED);
1da177e4 3322
5c04a7b8
AD
3323 WR_HARPOON(port + hp_autostart_1,
3324 (AUTO_IMMED + DISCONNECT_START));
3325 }
1da177e4 3326
5c04a7b8 3327 else {
1da177e4 3328
5c04a7b8 3329 ACCEPT_MSG_ATN(port);
1da177e4 3330
5c04a7b8 3331 FPT_sisyncr(port, sync_msg, offset);
1da177e4 3332
5c04a7b8
AD
3333 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3334 ~(unsigned char)TAR_SYNC_MASK) |
3335 (unsigned char)SYNC_SUPPORTED);
3336 }
1da177e4
LT
3337}
3338
1da177e4
LT
3339/*---------------------------------------------------------------------
3340 *
47b5d69c 3341 * Function: FPT_sisyncr
1da177e4
LT
3342 *
3343 * Description: Answer the targets sync message.
3344 *
3345 *---------------------------------------------------------------------*/
391e2f25 3346static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
5c04a7b8 3347 unsigned char offset)
1da177e4 3348{
5c04a7b8
AD
3349 ARAM_ACCESS(port);
3350 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3351 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3352 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC));
3353 WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3354 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3355 WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3356 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3357 SGRAM_ACCESS(port);
3358
3359 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3360 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3361
3362 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3363
3364 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3365 }
1da177e4
LT
3366}
3367
1da177e4
LT
3368/*---------------------------------------------------------------------
3369 *
47b5d69c 3370 * Function: FPT_siwidn
1da177e4
LT
3371 *
3372 * Description: Read in a message byte from the SCSI bus, and check
3373 * for a parity error.
3374 *
3375 *---------------------------------------------------------------------*/
3376
391e2f25 3377static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
1da177e4 3378{
5c04a7b8
AD
3379 struct sccb *currSCCB;
3380 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 3381
5c04a7b8
AD
3382 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3383 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3384
5c04a7b8 3385 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
1da177e4 3386
5c04a7b8
AD
3387 WRW_HARPOON((port + ID_MSG_STRT),
3388 (MPM_OP + AMSG_OUT +
3389 (currSCCB->
3390 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
1da177e4 3391
5c04a7b8 3392 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
1da177e4 3393
5c04a7b8
AD
3394 WRW_HARPOON((port + SYNC_MSGS + 0),
3395 (MPM_OP + AMSG_OUT + SMEXT));
3396 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3397 WRW_HARPOON((port + SYNC_MSGS + 4),
3398 (MPM_OP + AMSG_OUT + SMWDTR));
3399 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3400 WRW_HARPOON((port + SYNC_MSGS + 8),
3401 (MPM_OP + AMSG_OUT + SM16BIT));
3402 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
1da177e4 3403
5c04a7b8 3404 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
1da177e4 3405
5c04a7b8
AD
3406 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3407 ~(unsigned char)TAR_WIDE_MASK) |
3408 (unsigned char)WIDE_ENABLED);
1da177e4 3409
5c1b85e2 3410 return 1;
5c04a7b8 3411 }
1da177e4 3412
5c04a7b8 3413 else {
1da177e4 3414
5c04a7b8
AD
3415 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3416 ~(unsigned char)TAR_WIDE_MASK) |
3417 WIDE_NEGOCIATED);
1da177e4 3418
5c04a7b8 3419 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
5c1b85e2 3420 return 0;
5c04a7b8 3421 }
1da177e4
LT
3422}
3423
1da177e4
LT
3424/*---------------------------------------------------------------------
3425 *
47b5d69c 3426 * Function: FPT_stwidn
1da177e4
LT
3427 *
3428 * Description: The has sent us a Wide Nego message so handle it as
3429 * necessary.
3430 *
3431 *---------------------------------------------------------------------*/
391e2f25 3432static void FPT_stwidn(u32 port, unsigned char p_card)
1da177e4 3433{
5c04a7b8
AD
3434 unsigned char width;
3435 struct sccb *currSCCB;
3436 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 3437
5c04a7b8
AD
3438 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3439 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3440
5c04a7b8 3441 width = FPT_sfm(port, currSCCB);
1da177e4 3442
5c04a7b8
AD
3443 if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3444 WR_HARPOON(port + hp_autostart_1,
3445 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
3446 return;
3447 }
3448
5c04a7b8
AD
3449 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3450 width = 0;
1da177e4 3451
5c04a7b8
AD
3452 if (width) {
3453 currTar_Info->TarStatus |= WIDE_ENABLED;
3454 width = 0;
3455 } else {
3456 width = NARROW_SCSI;
3457 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3458 }
1da177e4 3459
5c04a7b8 3460 FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
1da177e4 3461
5c04a7b8 3462 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
1da177e4 3463
5c04a7b8 3464 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
1da177e4 3465
5c04a7b8
AD
3466 if (!
3467 ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3468 SYNC_SUPPORTED)) {
3469 ACCEPT_MSG_ATN(port);
3470 ARAM_ACCESS(port);
3471 FPT_sisyncn(port, p_card, 1);
3472 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3473 SGRAM_ACCESS(port);
3474 } else {
3475 ACCEPT_MSG(port);
3476 WR_HARPOON(port + hp_autostart_1,
3477 (AUTO_IMMED + DISCONNECT_START));
1da177e4 3478 }
5c04a7b8 3479 }
1da177e4 3480
5c04a7b8 3481 else {
1da177e4 3482
5c04a7b8 3483 ACCEPT_MSG_ATN(port);
1da177e4 3484
5c04a7b8
AD
3485 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3486 width = SM16BIT;
3487 else
3488 width = SM8BIT;
1da177e4 3489
5c04a7b8 3490 FPT_siwidr(port, width);
1da177e4 3491
5c04a7b8
AD
3492 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3493 }
1da177e4
LT
3494}
3495
1da177e4
LT
3496/*---------------------------------------------------------------------
3497 *
47b5d69c 3498 * Function: FPT_siwidr
1da177e4
LT
3499 *
3500 * Description: Answer the targets Wide nego message.
3501 *
3502 *---------------------------------------------------------------------*/
391e2f25 3503static void FPT_siwidr(u32 port, unsigned char width)
1da177e4 3504{
5c04a7b8
AD
3505 ARAM_ACCESS(port);
3506 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3507 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3508 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR));
3509 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3510 WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3511 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3512 SGRAM_ACCESS(port);
1da177e4 3513
5c04a7b8
AD
3514 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3515 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
1da177e4 3516
5c04a7b8 3517 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
1da177e4 3518
5c04a7b8
AD
3519 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3520 }
1da177e4
LT
3521}
3522
1da177e4
LT
3523/*---------------------------------------------------------------------
3524 *
47b5d69c 3525 * Function: FPT_sssyncv
1da177e4
LT
3526 *
3527 * Description: Write the desired value to the Sync Register for the
3528 * ID specified.
3529 *
3530 *---------------------------------------------------------------------*/
391e2f25 3531static void FPT_sssyncv(u32 p_port, unsigned char p_id,
5c04a7b8
AD
3532 unsigned char p_sync_value,
3533 struct sccb_mgr_tar_info *currTar_Info)
1da177e4 3534{
5c04a7b8
AD
3535 unsigned char index;
3536
3537 index = p_id;
3538
3539 switch (index) {
3540
3541 case 0:
3542 index = 12; /* hp_synctarg_0 */
3543 break;
3544 case 1:
3545 index = 13; /* hp_synctarg_1 */
3546 break;
3547 case 2:
3548 index = 14; /* hp_synctarg_2 */
3549 break;
3550 case 3:
3551 index = 15; /* hp_synctarg_3 */
3552 break;
3553 case 4:
3554 index = 8; /* hp_synctarg_4 */
3555 break;
3556 case 5:
3557 index = 9; /* hp_synctarg_5 */
3558 break;
3559 case 6:
3560 index = 10; /* hp_synctarg_6 */
3561 break;
3562 case 7:
3563 index = 11; /* hp_synctarg_7 */
3564 break;
3565 case 8:
3566 index = 4; /* hp_synctarg_8 */
3567 break;
3568 case 9:
3569 index = 5; /* hp_synctarg_9 */
3570 break;
3571 case 10:
3572 index = 6; /* hp_synctarg_10 */
3573 break;
3574 case 11:
3575 index = 7; /* hp_synctarg_11 */
3576 break;
3577 case 12:
3578 index = 0; /* hp_synctarg_12 */
3579 break;
3580 case 13:
3581 index = 1; /* hp_synctarg_13 */
3582 break;
3583 case 14:
3584 index = 2; /* hp_synctarg_14 */
3585 break;
3586 case 15:
3587 index = 3; /* hp_synctarg_15 */
1da177e4 3588
5c04a7b8 3589 }
1da177e4 3590
5c04a7b8 3591 WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
1da177e4
LT
3592
3593 currTar_Info->TarSyncCtrl = p_sync_value;
3594}
3595
1da177e4
LT
3596/*---------------------------------------------------------------------
3597 *
47b5d69c 3598 * Function: FPT_sresb
1da177e4
LT
3599 *
3600 * Description: Reset the desired card's SCSI bus.
3601 *
3602 *---------------------------------------------------------------------*/
391e2f25 3603static void FPT_sresb(u32 port, unsigned char p_card)
1da177e4 3604{
5c04a7b8 3605 unsigned char scsiID, i;
1da177e4 3606
5c04a7b8 3607 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 3608
5c04a7b8
AD
3609 WR_HARPOON(port + hp_page_ctrl,
3610 (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3611 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
1da177e4 3612
5c04a7b8 3613 WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
1da177e4 3614
5c04a7b8
AD
3615 scsiID = RD_HARPOON(port + hp_seltimeout);
3616 WR_HARPOON(port + hp_seltimeout, TO_5ms);
3617 WRW_HARPOON((port + hp_intstat), TIMEOUT);
1da177e4 3618
5c04a7b8 3619 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
1da177e4 3620
5c04a7b8
AD
3621 while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3622 }
1da177e4 3623
5c04a7b8 3624 WR_HARPOON(port + hp_seltimeout, scsiID);
1da177e4 3625
5c04a7b8 3626 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
1da177e4 3627
5c04a7b8 3628 FPT_Wait(port, TO_5ms);
1da177e4 3629
5c04a7b8 3630 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
1da177e4 3631
5c04a7b8 3632 WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
1da177e4 3633
5c04a7b8
AD
3634 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3635 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4 3636
5c04a7b8
AD
3637 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3638 currTar_Info->TarSyncCtrl = 0;
3639 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3640 }
1da177e4 3641
5c04a7b8
AD
3642 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3643 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3644 }
1da177e4 3645
5c04a7b8 3646 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
1da177e4 3647
5c04a7b8
AD
3648 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3649 }
1da177e4 3650
5c04a7b8
AD
3651 FPT_BL_Card[p_card].scanIndex = 0x00;
3652 FPT_BL_Card[p_card].currentSCCB = NULL;
3653 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3654 | F_NEW_SCCB_CMD);
3655 FPT_BL_Card[p_card].cmdCounter = 0x00;
47b5d69c 3656 FPT_BL_Card[p_card].discQCount = 0x00;
5c04a7b8 3657 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
1da177e4 3658
5c04a7b8 3659 for (i = 0; i < QUEUE_DEPTH; i++)
47b5d69c 3660 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
1da177e4 3661
5c04a7b8
AD
3662 WR_HARPOON(port + hp_page_ctrl,
3663 (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
1da177e4
LT
3664
3665}
3666
3667/*---------------------------------------------------------------------
3668 *
47b5d69c 3669 * Function: FPT_ssenss
1da177e4
LT
3670 *
3671 * Description: Setup for the Auto Sense command.
3672 *
3673 *---------------------------------------------------------------------*/
5c04a7b8 3674static void FPT_ssenss(struct sccb_card *pCurrCard)
1da177e4 3675{
5c04a7b8
AD
3676 unsigned char i;
3677 struct sccb *currSCCB;
1da177e4 3678
5c04a7b8 3679 currSCCB = pCurrCard->currentSCCB;
1da177e4 3680
5c04a7b8 3681 currSCCB->Save_CdbLen = currSCCB->CdbLength;
1da177e4 3682
5c04a7b8 3683 for (i = 0; i < 6; i++) {
1da177e4 3684
5c04a7b8
AD
3685 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3686 }
1da177e4 3687
5c04a7b8
AD
3688 currSCCB->CdbLength = SIX_BYTE_CMD;
3689 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3690 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3691 currSCCB->Cdb[2] = 0x00;
3692 currSCCB->Cdb[3] = 0x00;
3693 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3694 currSCCB->Cdb[5] = 0x00;
1da177e4 3695
391e2f25 3696 currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
1da177e4 3697
5c04a7b8 3698 currSCCB->Sccb_ATC = 0x00;
1da177e4 3699
5c04a7b8 3700 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
1da177e4 3701
5c04a7b8 3702 currSCCB->Sccb_XferState &= ~F_SG_XFER;
1da177e4 3703
5c04a7b8 3704 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
1da177e4 3705
5c04a7b8 3706 currSCCB->ControlByte = 0x00;
1da177e4 3707
5c04a7b8 3708 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
1da177e4
LT
3709}
3710
1da177e4
LT
3711/*---------------------------------------------------------------------
3712 *
47b5d69c 3713 * Function: FPT_sxfrp
1da177e4
LT
3714 *
3715 * Description: Transfer data into the bit bucket until the device
3716 * decides to switch phase.
3717 *
3718 *---------------------------------------------------------------------*/
3719
391e2f25 3720static void FPT_sxfrp(u32 p_port, unsigned char p_card)
1da177e4 3721{
5c04a7b8 3722 unsigned char curr_phz;
1da177e4 3723
5c04a7b8 3724 DISABLE_AUTO(p_port);
1da177e4 3725
5c04a7b8 3726 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
1da177e4 3727
5c04a7b8
AD
3728 FPT_hostDataXferAbort(p_port, p_card,
3729 FPT_BL_Card[p_card].currentSCCB);
1da177e4 3730
5c04a7b8 3731 }
1da177e4 3732
5c04a7b8
AD
3733 /* If the Automation handled the end of the transfer then do not
3734 match the phase or we will get out of sync with the ISR. */
3735
3736 if (RDW_HARPOON((p_port + hp_intstat)) &
3737 (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3738 return;
3739
3740 WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3741
3742 curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
1da177e4 3743
5c04a7b8 3744 WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
1da177e4 3745
5c04a7b8 3746 WR_HARPOON(p_port + hp_scsisig, curr_phz);
1da177e4 3747
5c04a7b8
AD
3748 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3749 (curr_phz ==
3750 (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3751 {
3752 if (curr_phz & (unsigned char)SCSI_IOBIT) {
3753 WR_HARPOON(p_port + hp_portctrl_0,
3754 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
1da177e4 3755
5c04a7b8
AD
3756 if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3757 RD_HARPOON(p_port + hp_fifodata_0);
3758 }
3759 } else {
3760 WR_HARPOON(p_port + hp_portctrl_0,
3761 (SCSI_PORT | HOST_PORT | HOST_WRT));
3762 if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3763 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3764 }
3765 }
3766 } /* End of While loop for padding data I/O phase */
1da177e4 3767
5c04a7b8
AD
3768 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3769 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3770 break;
3771 }
1da177e4 3772
5c04a7b8
AD
3773 WR_HARPOON(p_port + hp_portctrl_0,
3774 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3775 while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3776 RD_HARPOON(p_port + hp_fifodata_0);
3777 }
1da177e4 3778
5c04a7b8
AD
3779 if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3780 WR_HARPOON(p_port + hp_autostart_0,
3781 (AUTO_IMMED + DISCONNECT_START));
3782 while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3783 }
1da177e4 3784
5c04a7b8
AD
3785 if (RDW_HARPOON((p_port + hp_intstat)) &
3786 (ICMD_COMP | ITAR_DISC))
3787 while (!
3788 (RDW_HARPOON((p_port + hp_intstat)) &
3789 (BUS_FREE | RSEL))) ;
3790 }
1da177e4
LT
3791}
3792
1da177e4
LT
3793/*---------------------------------------------------------------------
3794 *
47b5d69c 3795 * Function: FPT_schkdd
1da177e4
LT
3796 *
3797 * Description: Make sure data has been flushed from both FIFOs and abort
3798 * the operations if necessary.
3799 *
3800 *---------------------------------------------------------------------*/
3801
391e2f25 3802static void FPT_schkdd(u32 port, unsigned char p_card)
1da177e4 3803{
5c04a7b8 3804 unsigned short TimeOutLoop;
db038cf8 3805 unsigned char sPhase;
1da177e4 3806
5c04a7b8 3807 struct sccb *currSCCB;
1da177e4 3808
5c04a7b8 3809 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 3810
5c04a7b8
AD
3811 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3812 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3813 return;
3814 }
1da177e4 3815
5c04a7b8 3816 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
1da177e4 3817
5c04a7b8 3818 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
1da177e4 3819
5c04a7b8 3820 currSCCB->Sccb_XferCnt = 1;
1da177e4 3821
5c04a7b8
AD
3822 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3823 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3824 WR_HARPOON(port + hp_xferstat, 0x00);
3825 }
1da177e4 3826
5c04a7b8 3827 else {
1da177e4 3828
5c04a7b8 3829 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
1da177e4 3830
5c04a7b8
AD
3831 currSCCB->Sccb_XferCnt = 0;
3832 }
1da177e4 3833
5c04a7b8
AD
3834 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3835 (currSCCB->HostStatus == SCCB_COMPLETE)) {
1da177e4 3836
5c04a7b8
AD
3837 currSCCB->HostStatus = SCCB_PARITY_ERR;
3838 WRW_HARPOON((port + hp_intstat), PARITY);
3839 }
1da177e4 3840
5c04a7b8 3841 FPT_hostDataXferAbort(port, p_card, currSCCB);
1da177e4 3842
5c04a7b8
AD
3843 while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3844 }
1da177e4 3845
5c04a7b8 3846 TimeOutLoop = 0;
1da177e4 3847
5c04a7b8
AD
3848 while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3849 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3850 return;
3851 }
3852 if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3853 break;
3854 }
3855 if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3856 return;
3857 }
3858 if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3859 || (TimeOutLoop++ > 0x3000))
3860 break;
3861 }
1da177e4 3862
5c04a7b8
AD
3863 sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3864 if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3865 (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3866 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3867 (sPhase == (SCSI_BSY | S_DATAI_PH))) {
1da177e4 3868
5c04a7b8 3869 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
1da177e4 3870
5c04a7b8
AD
3871 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3872 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3873 FPT_phaseDataIn(port, p_card);
3874 }
1da177e4 3875
5c04a7b8
AD
3876 else {
3877 FPT_phaseDataOut(port, p_card);
3878 }
3879 } else {
3880 FPT_sxfrp(port, p_card);
3881 if (!(RDW_HARPOON((port + hp_intstat)) &
3882 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3883 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3884 FPT_phaseDecode(port, p_card);
3885 }
3886 }
1da177e4 3887
5c04a7b8 3888 }
1da177e4 3889
5c04a7b8
AD
3890 else {
3891 WR_HARPOON(port + hp_portctrl_0, 0x00);
3892 }
1da177e4
LT
3893}
3894
1da177e4
LT
3895/*---------------------------------------------------------------------
3896 *
47b5d69c 3897 * Function: FPT_sinits
1da177e4
LT
3898 *
3899 * Description: Setup SCCB manager fields in this SCCB.
3900 *
3901 *---------------------------------------------------------------------*/
3902
5c04a7b8 3903static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
1da177e4 3904{
5c04a7b8 3905 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 3906
5d7ebb9c 3907 if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
1da177e4
LT
3908 return;
3909 }
5c04a7b8 3910 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4 3911
5c04a7b8
AD
3912 p_sccb->Sccb_XferState = 0x00;
3913 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
1da177e4 3914
5c04a7b8
AD
3915 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3916 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
1da177e4 3917
5c04a7b8
AD
3918 p_sccb->Sccb_SGoffset = 0;
3919 p_sccb->Sccb_XferState = F_SG_XFER;
3920 p_sccb->Sccb_XferCnt = 0x00;
3921 }
1da177e4 3922
5c04a7b8 3923 if (p_sccb->DataLength == 0x00)
1da177e4 3924
5c04a7b8 3925 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
1da177e4 3926
5c04a7b8
AD
3927 if (p_sccb->ControlByte & F_USE_CMD_Q) {
3928 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3929 p_sccb->ControlByte &= ~F_USE_CMD_Q;
1da177e4 3930
5c04a7b8
AD
3931 else
3932 currTar_Info->TarStatus |= TAG_Q_TRYING;
3933 }
1da177e4
LT
3934
3935/* For !single SCSI device in system & device allow Disconnect
3936 or command is tag_q type then send Cmd with Disconnect Enable
3937 else send Cmd with Disconnect Disable */
3938
3939/*
47b5d69c 3940 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
1da177e4
LT
3941 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3942 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3943*/
5c04a7b8
AD
3944 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3945 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3946 p_sccb->Sccb_idmsg =
3947 (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
3948 }
1da177e4 3949
5c04a7b8 3950 else {
1da177e4 3951
5c04a7b8
AD
3952 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
3953 }
1da177e4 3954
5c04a7b8
AD
3955 p_sccb->HostStatus = 0x00;
3956 p_sccb->TargetStatus = 0x00;
3957 p_sccb->Sccb_tag = 0x00;
3958 p_sccb->Sccb_MGRFlags = 0x00;
3959 p_sccb->Sccb_sgseg = 0x00;
3960 p_sccb->Sccb_ATC = 0x00;
3961 p_sccb->Sccb_savedATC = 0x00;
1da177e4
LT
3962/*
3963 p_sccb->SccbVirtDataPtr = 0x00;
3964 p_sccb->Sccb_forwardlink = NULL;
3965 p_sccb->Sccb_backlink = NULL;
3966 */
5c04a7b8
AD
3967 p_sccb->Sccb_scsistat = BUS_FREE_ST;
3968 p_sccb->SccbStatus = SCCB_IN_PROCESS;
3969 p_sccb->Sccb_scsimsg = SMNO_OP;
1da177e4
LT
3970
3971}
3972
1da177e4
LT
3973/*---------------------------------------------------------------------
3974 *
3975 * Function: Phase Decode
3976 *
3977 * Description: Determine the phase and call the appropriate function.
3978 *
3979 *---------------------------------------------------------------------*/
3980
391e2f25 3981static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
1da177e4 3982{
5c04a7b8 3983 unsigned char phase_ref;
391e2f25 3984 void (*phase) (u32, unsigned char);
1da177e4 3985
5c04a7b8 3986 DISABLE_AUTO(p_port);
1da177e4 3987
5c04a7b8
AD
3988 phase_ref =
3989 (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
1da177e4 3990
5c04a7b8 3991 phase = FPT_s_PhaseTbl[phase_ref];
1da177e4 3992
5c04a7b8 3993 (*phase) (p_port, p_card); /* Call the correct phase func */
1da177e4
LT
3994}
3995
1da177e4
LT
3996/*---------------------------------------------------------------------
3997 *
3998 * Function: Data Out Phase
3999 *
4000 * Description: Start up both the BusMaster and Xbow.
4001 *
4002 *---------------------------------------------------------------------*/
4003
391e2f25 4004static void FPT_phaseDataOut(u32 port, unsigned char p_card)
1da177e4
LT
4005{
4006
5c04a7b8 4007 struct sccb *currSCCB;
1da177e4 4008
5c04a7b8
AD
4009 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4010 if (currSCCB == NULL) {
4011 return; /* Exit if No SCCB record */
4012 }
1da177e4 4013
5c04a7b8
AD
4014 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4015 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
1da177e4 4016
5c04a7b8 4017 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
1da177e4 4018
5c04a7b8 4019 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
1da177e4 4020
5c04a7b8 4021 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
1da177e4 4022
5c04a7b8 4023 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4 4024
5c04a7b8 4025 if (currSCCB->Sccb_XferCnt == 0) {
1da177e4 4026
5c04a7b8
AD
4027 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4028 (currSCCB->HostStatus == SCCB_COMPLETE))
4029 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
1da177e4 4030
5c04a7b8
AD
4031 FPT_sxfrp(port, p_card);
4032 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4033 FPT_phaseDecode(port, p_card);
4034 }
1da177e4
LT
4035}
4036
1da177e4
LT
4037/*---------------------------------------------------------------------
4038 *
4039 * Function: Data In Phase
4040 *
4041 * Description: Startup the BusMaster and the XBOW.
4042 *
4043 *---------------------------------------------------------------------*/
4044
391e2f25 4045static void FPT_phaseDataIn(u32 port, unsigned char p_card)
1da177e4
LT
4046{
4047
5c04a7b8 4048 struct sccb *currSCCB;
1da177e4 4049
5c04a7b8 4050 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4051
5c04a7b8
AD
4052 if (currSCCB == NULL) {
4053 return; /* Exit if No SCCB record */
4054 }
1da177e4 4055
5c04a7b8
AD
4056 currSCCB->Sccb_scsistat = DATA_IN_ST;
4057 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4058 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
1da177e4 4059
5c04a7b8 4060 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
1da177e4 4061
5c04a7b8 4062 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
1da177e4 4063
5c04a7b8 4064 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
1da177e4 4065
5c04a7b8 4066 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4 4067
5c04a7b8 4068 if (currSCCB->Sccb_XferCnt == 0) {
1da177e4 4069
5c04a7b8
AD
4070 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4071 (currSCCB->HostStatus == SCCB_COMPLETE))
4072 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
1da177e4 4073
5c04a7b8
AD
4074 FPT_sxfrp(port, p_card);
4075 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4076 FPT_phaseDecode(port, p_card);
1da177e4 4077
5c04a7b8 4078 }
1da177e4
LT
4079}
4080
4081/*---------------------------------------------------------------------
4082 *
4083 * Function: Command Phase
4084 *
4085 * Description: Load the CDB into the automation and start it up.
4086 *
4087 *---------------------------------------------------------------------*/
4088
391e2f25 4089static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
1da177e4 4090{
5c04a7b8 4091 struct sccb *currSCCB;
391e2f25 4092 u32 cdb_reg;
5c04a7b8 4093 unsigned char i;
1da177e4 4094
5c04a7b8 4095 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4096
5c04a7b8 4097 if (currSCCB->OperationCode == RESET_COMMAND) {
1da177e4 4098
5c04a7b8
AD
4099 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4100 currSCCB->CdbLength = SIX_BYTE_CMD;
4101 }
1da177e4 4102
5c04a7b8 4103 WR_HARPOON(p_port + hp_scsisig, 0x00);
1da177e4 4104
5c04a7b8 4105 ARAM_ACCESS(p_port);
1da177e4 4106
5c04a7b8 4107 cdb_reg = p_port + CMD_STRT;
1da177e4 4108
5c04a7b8 4109 for (i = 0; i < currSCCB->CdbLength; i++) {
1da177e4 4110
5c04a7b8 4111 if (currSCCB->OperationCode == RESET_COMMAND)
1da177e4 4112
5c04a7b8 4113 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
1da177e4 4114
5c04a7b8
AD
4115 else
4116 WRW_HARPOON(cdb_reg,
4117 (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4118 cdb_reg += 2;
4119 }
1da177e4 4120
5c04a7b8
AD
4121 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4122 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
1da177e4 4123
5c04a7b8 4124 WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
1da177e4 4125
5c04a7b8 4126 currSCCB->Sccb_scsistat = COMMAND_ST;
1da177e4 4127
5c04a7b8
AD
4128 WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4129 SGRAM_ACCESS(p_port);
1da177e4
LT
4130}
4131
1da177e4
LT
4132/*---------------------------------------------------------------------
4133 *
4134 * Function: Status phase
4135 *
4136 * Description: Bring in the status and command complete message bytes
4137 *
4138 *---------------------------------------------------------------------*/
4139
391e2f25 4140static void FPT_phaseStatus(u32 port, unsigned char p_card)
1da177e4 4141{
5c04a7b8
AD
4142 /* Start-up the automation to finish off this command and let the
4143 isr handle the interrupt for command complete when it comes in.
4144 We could wait here for the interrupt to be generated?
4145 */
1da177e4 4146
5c04a7b8 4147 WR_HARPOON(port + hp_scsisig, 0x00);
1da177e4 4148
5c04a7b8 4149 WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
1da177e4
LT
4150}
4151
1da177e4
LT
4152/*---------------------------------------------------------------------
4153 *
4154 * Function: Phase Message Out
4155 *
4156 * Description: Send out our message (if we have one) and handle whatever
4157 * else is involed.
4158 *
4159 *---------------------------------------------------------------------*/
4160
391e2f25 4161static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
1da177e4 4162{
5c04a7b8
AD
4163 unsigned char message, scsiID;
4164 struct sccb *currSCCB;
4165 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 4166
47b5d69c 4167 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4168
4169 if (currSCCB != NULL) {
4170
4171 message = currSCCB->Sccb_scsimsg;
4172 scsiID = currSCCB->TargID;
4173
5c04a7b8 4174 if (message == SMDEV_RESET) {
1da177e4 4175
47b5d69c 4176 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4 4177 currTar_Info->TarSyncCtrl = 0;
5c04a7b8 4178 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
1da177e4 4179
5c04a7b8
AD
4180 if (FPT_sccbMgrTbl[p_card][scsiID].
4181 TarEEValue & EE_SYNC_MASK) {
1da177e4 4182
5c04a7b8
AD
4183 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4184 ~TAR_SYNC_MASK;
1da177e4
LT
4185
4186 }
4187
5c04a7b8
AD
4188 if (FPT_sccbMgrTbl[p_card][scsiID].
4189 TarEEValue & EE_WIDE_SCSI) {
1da177e4 4190
5c04a7b8
AD
4191 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4192 ~TAR_WIDE_MASK;
1da177e4
LT
4193 }
4194
5c04a7b8
AD
4195 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4196 FPT_SccbMgrTableInitTarget(p_card, scsiID);
4197 } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
1da177e4 4198 currSCCB->HostStatus = SCCB_COMPLETE;
5c04a7b8
AD
4199 if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4200 NULL) {
4201 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4202 Sccb_tag] = NULL;
47b5d69c 4203 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
1da177e4 4204 }
1da177e4 4205
5c04a7b8 4206 }
1da177e4 4207
5c04a7b8 4208 else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
1da177e4 4209
5c04a7b8 4210 if (message == SMNO_OP) {
1da177e4 4211 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
5c04a7b8
AD
4212
4213 FPT_ssel(port, p_card);
1da177e4
LT
4214 return;
4215 }
5c04a7b8 4216 } else {
1da177e4
LT
4217
4218 if (message == SMABORT)
4219
5c04a7b8 4220 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
1da177e4
LT
4221 }
4222
5c04a7b8 4223 } else {
1da177e4
LT
4224 message = SMABORT;
4225 }
4226
5c04a7b8 4227 WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
1da177e4 4228
5c04a7b8 4229 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
1da177e4 4230
5c04a7b8 4231 WR_HARPOON(port + hp_scsidata_0, message);
1da177e4 4232
5c04a7b8 4233 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
1da177e4
LT
4234
4235 ACCEPT_MSG(port);
4236
5c04a7b8 4237 WR_HARPOON(port + hp_portctrl_0, 0x00);
1da177e4 4238
5c04a7b8
AD
4239 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4240 (message == SMABORT_TAG)) {
1da177e4 4241
5c04a7b8
AD
4242 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4243 }
1da177e4 4244
5c04a7b8
AD
4245 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4246 WRW_HARPOON((port + hp_intstat), BUS_FREE);
1da177e4 4247
5c04a7b8 4248 if (currSCCB != NULL) {
1da177e4 4249
5c04a7b8
AD
4250 if ((FPT_BL_Card[p_card].
4251 globalFlags & F_CONLUN_IO)
4252 &&
4253 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4254 TarStatus & TAR_TAG_Q_MASK) !=
4255 TAG_Q_TRYING))
4256 FPT_sccbMgrTbl[p_card][currSCCB->
4257 TargID].
4258 TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4259 else
5c04a7b8
AD
4260 FPT_sccbMgrTbl[p_card][currSCCB->
4261 TargID].
4262 TarLUNBusy[0] = 0;
1da177e4 4263
5c04a7b8
AD
4264 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4265 currSCCB, p_card);
1da177e4
LT
4266 }
4267
5c04a7b8
AD
4268 else {
4269 FPT_BL_Card[p_card].globalFlags |=
4270 F_NEW_SCCB_CMD;
1da177e4
LT
4271 }
4272 }
4273
5c04a7b8 4274 else {
1da177e4 4275
5c04a7b8 4276 FPT_sxfrp(port, p_card);
1da177e4
LT
4277 }
4278 }
4279
5c04a7b8 4280 else {
1da177e4 4281
5c04a7b8 4282 if (message == SMPARITY) {
1da177e4 4283 currSCCB->Sccb_scsimsg = SMNO_OP;
5c04a7b8
AD
4284 WR_HARPOON(port + hp_autostart_1,
4285 (AUTO_IMMED + DISCONNECT_START));
4286 } else {
4287 FPT_sxfrp(port, p_card);
1da177e4
LT
4288 }
4289 }
4290}
4291
1da177e4
LT
4292/*---------------------------------------------------------------------
4293 *
4294 * Function: Message In phase
4295 *
4296 * Description: Bring in the message and determine what to do with it.
4297 *
4298 *---------------------------------------------------------------------*/
4299
391e2f25 4300static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
1da177e4 4301{
db038cf8 4302 unsigned char message;
5c04a7b8 4303 struct sccb *currSCCB;
1da177e4 4304
47b5d69c 4305 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4306
5c04a7b8 4307 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
1da177e4 4308
47b5d69c 4309 FPT_phaseChkFifo(port, p_card);
1da177e4
LT
4310 }
4311
5c04a7b8
AD
4312 message = RD_HARPOON(port + hp_scsidata_0);
4313 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) {
1da177e4 4314
5c04a7b8
AD
4315 WR_HARPOON(port + hp_autostart_1,
4316 (AUTO_IMMED + END_DATA_START));
1da177e4
LT
4317
4318 }
4319
5c04a7b8 4320 else {
1da177e4 4321
5c04a7b8
AD
4322 message = FPT_sfm(port, currSCCB);
4323 if (message) {
1da177e4 4324
5c04a7b8 4325 FPT_sdecm(message, port, p_card);
1da177e4 4326
5c04a7b8
AD
4327 } else {
4328 if (currSCCB->Sccb_scsimsg != SMPARITY)
1da177e4 4329 ACCEPT_MSG(port);
5c04a7b8
AD
4330 WR_HARPOON(port + hp_autostart_1,
4331 (AUTO_IMMED + DISCONNECT_START));
1da177e4
LT
4332 }
4333 }
4334
4335}
4336
1da177e4
LT
4337/*---------------------------------------------------------------------
4338 *
4339 * Function: Illegal phase
4340 *
4341 * Description: Target switched to some illegal phase, so all we can do
4342 * is report an error back to the host (if that is possible)
4343 * and send an ABORT message to the misbehaving target.
4344 *
4345 *---------------------------------------------------------------------*/
4346
391e2f25 4347static void FPT_phaseIllegal(u32 port, unsigned char p_card)
1da177e4 4348{
5c04a7b8 4349 struct sccb *currSCCB;
1da177e4 4350
5c04a7b8 4351 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4352
5c04a7b8
AD
4353 WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4354 if (currSCCB != NULL) {
1da177e4 4355
5c04a7b8
AD
4356 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4357 currSCCB->Sccb_scsistat = ABORT_ST;
4358 currSCCB->Sccb_scsimsg = SMABORT;
4359 }
1da177e4 4360
5c04a7b8 4361 ACCEPT_MSG_ATN(port);
1da177e4
LT
4362}
4363
1da177e4
LT
4364/*---------------------------------------------------------------------
4365 *
4366 * Function: Phase Check FIFO
4367 *
4368 * Description: Make sure data has been flushed from both FIFOs and abort
4369 * the operations if necessary.
4370 *
4371 *---------------------------------------------------------------------*/
4372
391e2f25 4373static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
1da177e4 4374{
391e2f25 4375 u32 xfercnt;
5c04a7b8 4376 struct sccb *currSCCB;
1da177e4 4377
5c04a7b8 4378 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4379
5c04a7b8 4380 if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
1da177e4 4381
5c04a7b8
AD
4382 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4383 (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4384 }
1da177e4 4385
5c04a7b8
AD
4386 if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4387 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
1da177e4 4388
5c04a7b8 4389 currSCCB->Sccb_XferCnt = 0;
1da177e4 4390
5c04a7b8
AD
4391 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4392 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4393 currSCCB->HostStatus = SCCB_PARITY_ERR;
4394 WRW_HARPOON((port + hp_intstat), PARITY);
4395 }
1da177e4 4396
5c04a7b8 4397 FPT_hostDataXferAbort(port, p_card, currSCCB);
1da177e4 4398
5c04a7b8 4399 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4 4400
5c04a7b8
AD
4401 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4402 && (RD_HARPOON(port + hp_ext_status) &
4403 BM_CMD_BUSY)) {
4404 }
1da177e4 4405
5c04a7b8
AD
4406 }
4407 }
1da177e4 4408
5c04a7b8
AD
4409 /*End Data In specific code. */
4410 GET_XFER_CNT(port, xfercnt);
1da177e4 4411
5c04a7b8 4412 WR_HARPOON(port + hp_xfercnt_0, 0x00);
1da177e4 4413
5c04a7b8 4414 WR_HARPOON(port + hp_portctrl_0, 0x00);
1da177e4 4415
5c04a7b8 4416 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
1da177e4 4417
5c04a7b8 4418 currSCCB->Sccb_XferCnt = xfercnt;
1da177e4 4419
5c04a7b8
AD
4420 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4421 (currSCCB->HostStatus == SCCB_COMPLETE)) {
1da177e4 4422
5c04a7b8
AD
4423 currSCCB->HostStatus = SCCB_PARITY_ERR;
4424 WRW_HARPOON((port + hp_intstat), PARITY);
4425 }
1da177e4 4426
5c04a7b8 4427 FPT_hostDataXferAbort(port, p_card, currSCCB);
1da177e4 4428
5c04a7b8
AD
4429 WR_HARPOON(port + hp_fifowrite, 0x00);
4430 WR_HARPOON(port + hp_fiforead, 0x00);
4431 WR_HARPOON(port + hp_xferstat, 0x00);
1da177e4 4432
5c04a7b8 4433 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
1da177e4
LT
4434}
4435
1da177e4
LT
4436/*---------------------------------------------------------------------
4437 *
4438 * Function: Phase Bus Free
4439 *
4440 * Description: We just went bus free so figure out if it was
4441 * because of command complete or from a disconnect.
4442 *
4443 *---------------------------------------------------------------------*/
391e2f25 4444static void FPT_phaseBusFree(u32 port, unsigned char p_card)
1da177e4 4445{
5c04a7b8 4446 struct sccb *currSCCB;
1da177e4 4447
5c04a7b8 4448 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4449
5c04a7b8 4450 if (currSCCB != NULL) {
1da177e4 4451
5c04a7b8 4452 DISABLE_AUTO(port);
1da177e4 4453
5c04a7b8 4454 if (currSCCB->OperationCode == RESET_COMMAND) {
1da177e4 4455
5c04a7b8
AD
4456 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4457 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4458 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4459 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4460 TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4461 else
5c04a7b8
AD
4462 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4463 TarLUNBusy[0] = 0;
4464
4465 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4466 p_card);
4467
4468 FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4469
4470 }
4471
4472 else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4473 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4474 (unsigned char)SYNC_SUPPORTED;
4475 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4476 ~EE_SYNC_MASK;
4477 }
4478
4479 else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4480 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4481 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4482 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4483
4484 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4485 ~EE_WIDE_SCSI;
4486 }
4487
4488 else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4489 /* Make sure this is not a phony BUS_FREE. If we were
4490 reselected or if BUSY is NOT on then this is a
4491 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4492
4493 if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4494 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4495 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4496 TarStatus &= ~TAR_TAG_Q_MASK;
4497 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4498 TarStatus |= TAG_Q_REJECT;
4499 }
4500
4501 else {
4502 return;
4503 }
4504 }
1da177e4 4505
5c04a7b8 4506 else {
1da177e4 4507
5c04a7b8 4508 currSCCB->Sccb_scsistat = BUS_FREE_ST;
1da177e4 4509
5c04a7b8
AD
4510 if (!currSCCB->HostStatus) {
4511 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4512 }
1da177e4 4513
5c04a7b8
AD
4514 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4515 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4516 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4517 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4518 TarLUNBusy[currSCCB->Lun] = 0;
4519 else
4520 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4521 TarLUNBusy[0] = 0;
1da177e4 4522
5c04a7b8
AD
4523 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4524 p_card);
4525 return;
4526 }
1da177e4 4527
5c04a7b8 4528 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 4529
5c04a7b8
AD
4530 } /*end if !=null */
4531}
1da177e4 4532
1da177e4
LT
4533/*---------------------------------------------------------------------
4534 *
4535 * Function: Auto Load Default Map
4536 *
4537 * Description: Load the Automation RAM with the defualt map values.
4538 *
4539 *---------------------------------------------------------------------*/
391e2f25 4540static void FPT_autoLoadDefaultMap(u32 p_port)
1da177e4 4541{
391e2f25 4542 u32 map_addr;
5c04a7b8
AD
4543
4544 ARAM_ACCESS(p_port);
4545 map_addr = p_port + hp_aramBase;
4546
4547 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
4548 map_addr += 2;
4549 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
4550 map_addr += 2;
4551 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4552 map_addr += 2;
4553 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
4554 map_addr += 2;
4555 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
4556 map_addr += 2;
4557 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
4558 map_addr += 2;
4559 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
4560 map_addr += 2;
4561 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
4562 map_addr += 2;
4563 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
4564 map_addr += 2;
4565 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
4566 map_addr += 2;
4567 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
4568 map_addr += 2;
4569 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
4570 map_addr += 2;
4571 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
4572 map_addr += 2;
4573 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
4574 map_addr += 2;
4575 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
4576 map_addr += 2;
4577 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
4578 map_addr += 2;
4579 WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4580 map_addr += 2;
4581 WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
4582 map_addr += 2; /*This means AYNC DATA IN */
4583 WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4584 map_addr += 2;
4585 WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
4586 map_addr += 2;
4587 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4588 map_addr += 2;
4589 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4590 map_addr += 2;
4591 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
4592 map_addr += 2;
4593 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
4594 map_addr += 2;
4595 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4596 map_addr += 2;
4597 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4598 map_addr += 2;
4599 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
4600 map_addr += 2;
4601 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4602 map_addr += 2;
4603 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
4604 map_addr += 2;
4605 WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4606 map_addr += 2;
4607 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
4608 map_addr += 2;
4609 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4610 map_addr += 2;
4611 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4612 map_addr += 2;
4613 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4614 map_addr += 2;
4615 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4616 map_addr += 2;
4617 WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
4618 map_addr += 2;
4619
4620 WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4621 map_addr += 2;
4622 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4623 map_addr += 2;
4624 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4625 map_addr += 2;
4626 WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4627 map_addr += 2; /* DIDN'T GET ONE */
4628 WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
4629 map_addr += 2;
4630 WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4631 map_addr += 2;
4632 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4633
4634 SGRAM_ACCESS(p_port);
1da177e4
LT
4635}
4636
4637/*---------------------------------------------------------------------
4638 *
4639 * Function: Auto Command Complete
4640 *
4641 * Description: Post command back to host and find another command
4642 * to execute.
4643 *
4644 *---------------------------------------------------------------------*/
4645
391e2f25 4646static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
1da177e4 4647{
5c04a7b8
AD
4648 struct sccb *currSCCB;
4649 unsigned char status_byte;
1da177e4 4650
5c04a7b8 4651 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4652
5c04a7b8 4653 status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
1da177e4 4654
5c04a7b8 4655 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
1da177e4 4656
5c04a7b8 4657 if (status_byte != SSGOOD) {
1da177e4 4658
5c04a7b8 4659 if (status_byte == SSQ_FULL) {
1da177e4 4660
5c04a7b8
AD
4661 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4662 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4663 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4664 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4665 TarLUNBusy[currSCCB->Lun] = 1;
4666 if (FPT_BL_Card[p_card].discQCount != 0)
47b5d69c 4667 FPT_BL_Card[p_card].discQCount--;
5c04a7b8
AD
4668 FPT_BL_Card[p_card].
4669 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4670 [currSCCB->TargID].
4671 LunDiscQ_Idx[currSCCB->Lun]] =
4672 NULL;
4673 } else {
4674 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4675 TarLUNBusy[0] = 1;
4676 if (currSCCB->Sccb_tag) {
4677 if (FPT_BL_Card[p_card].discQCount != 0)
4678 FPT_BL_Card[p_card].
4679 discQCount--;
4680 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4681 Sccb_tag]
4682 = NULL;
4683 } else {
4684 if (FPT_BL_Card[p_card].discQCount != 0)
4685 FPT_BL_Card[p_card].
4686 discQCount--;
4687 FPT_BL_Card[p_card].
4688 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4689 [currSCCB->TargID].
4690 LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
4691 }
4692 }
4693
5c04a7b8 4694 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
1da177e4 4695
5c04a7b8 4696 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
1da177e4 4697
5c04a7b8
AD
4698 return;
4699 }
1da177e4 4700
5c04a7b8
AD
4701 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4702 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4703 (unsigned char)SYNC_SUPPORTED;
1da177e4 4704
5c04a7b8
AD
4705 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4706 ~EE_SYNC_MASK;
4707 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 4708
5c04a7b8
AD
4709 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4710 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4711 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4712 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4713 TarLUNBusy[currSCCB->Lun] = 1;
4714 if (FPT_BL_Card[p_card].discQCount != 0)
47b5d69c 4715 FPT_BL_Card[p_card].discQCount--;
5c04a7b8
AD
4716 FPT_BL_Card[p_card].
4717 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4718 [currSCCB->TargID].
4719 LunDiscQ_Idx[currSCCB->Lun]] =
4720 NULL;
4721 } else {
4722 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4723 TarLUNBusy[0] = 1;
4724 if (currSCCB->Sccb_tag) {
4725 if (FPT_BL_Card[p_card].discQCount != 0)
4726 FPT_BL_Card[p_card].
4727 discQCount--;
4728 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4729 Sccb_tag]
4730 = NULL;
4731 } else {
4732 if (FPT_BL_Card[p_card].discQCount != 0)
4733 FPT_BL_Card[p_card].
4734 discQCount--;
4735 FPT_BL_Card[p_card].
4736 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4737 [currSCCB->TargID].
4738 LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
4739 }
4740 }
5c04a7b8 4741 return;
1da177e4 4742
5c04a7b8 4743 }
1da177e4 4744
5c04a7b8 4745 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
1da177e4 4746
5c04a7b8
AD
4747 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4748 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4749 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
1da177e4 4750
5c04a7b8
AD
4751 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4752 ~EE_WIDE_SCSI;
4753 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 4754
5c04a7b8
AD
4755 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4756 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4757 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4758 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4759 TarLUNBusy[currSCCB->Lun] = 1;
4760 if (FPT_BL_Card[p_card].discQCount != 0)
47b5d69c 4761 FPT_BL_Card[p_card].discQCount--;
5c04a7b8
AD
4762 FPT_BL_Card[p_card].
4763 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4764 [currSCCB->TargID].
4765 LunDiscQ_Idx[currSCCB->Lun]] =
4766 NULL;
4767 } else {
4768 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4769 TarLUNBusy[0] = 1;
4770 if (currSCCB->Sccb_tag) {
4771 if (FPT_BL_Card[p_card].discQCount != 0)
4772 FPT_BL_Card[p_card].
4773 discQCount--;
4774 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4775 Sccb_tag]
4776 = NULL;
4777 } else {
4778 if (FPT_BL_Card[p_card].discQCount != 0)
4779 FPT_BL_Card[p_card].
4780 discQCount--;
4781 FPT_BL_Card[p_card].
4782 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4783 [currSCCB->TargID].
4784 LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
4785 }
4786 }
5c04a7b8
AD
4787 return;
4788
4789 }
4790
4791 if (status_byte == SSCHECK) {
4792 if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4793 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4794 TarEEValue & EE_SYNC_MASK) {
4795 FPT_sccbMgrTbl[p_card][currSCCB->
4796 TargID].
4797 TarStatus &= ~TAR_SYNC_MASK;
1da177e4 4798 }
5c04a7b8
AD
4799 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4800 TarEEValue & EE_WIDE_SCSI) {
4801 FPT_sccbMgrTbl[p_card][currSCCB->
4802 TargID].
4803 TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
4804 }
4805 }
4806 }
4807
5c04a7b8
AD
4808 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4809
4810 currSCCB->SccbStatus = SCCB_ERROR;
4811 currSCCB->TargetStatus = status_byte;
4812
4813 if (status_byte == SSCHECK) {
4814
4815 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4816 TarLUN_CA = 1;
4817
4818 if (currSCCB->RequestSenseLength !=
4819 NO_AUTO_REQUEST_SENSE) {
4820
4821 if (currSCCB->RequestSenseLength == 0)
4822 currSCCB->RequestSenseLength =
4823 14;
4824
4825 FPT_ssenss(&FPT_BL_Card[p_card]);
4826 FPT_BL_Card[p_card].globalFlags |=
4827 F_NEW_SCCB_CMD;
4828
4829 if (((FPT_BL_Card[p_card].
4830 globalFlags & F_CONLUN_IO)
4831 &&
4832 ((FPT_sccbMgrTbl[p_card]
4833 [currSCCB->TargID].
4834 TarStatus & TAR_TAG_Q_MASK) !=
4835 TAG_Q_TRYING))) {
4836 FPT_sccbMgrTbl[p_card]
4837 [currSCCB->TargID].
4838 TarLUNBusy[currSCCB->Lun] =
4839 1;
4840 if (FPT_BL_Card[p_card].
4841 discQCount != 0)
4842 FPT_BL_Card[p_card].
4843 discQCount--;
4844 FPT_BL_Card[p_card].
4845 discQ_Tbl[FPT_sccbMgrTbl
4846 [p_card]
4847 [currSCCB->
4848 TargID].
4849 LunDiscQ_Idx
4850 [currSCCB->Lun]] =
4851 NULL;
4852 } else {
4853 FPT_sccbMgrTbl[p_card]
4854 [currSCCB->TargID].
4855 TarLUNBusy[0] = 1;
4856 if (currSCCB->Sccb_tag) {
4857 if (FPT_BL_Card[p_card].
4858 discQCount != 0)
4859 FPT_BL_Card
4860 [p_card].
4861 discQCount--;
4862 FPT_BL_Card[p_card].
4863 discQ_Tbl[currSCCB->
4864 Sccb_tag]
4865 = NULL;
4866 } else {
4867 if (FPT_BL_Card[p_card].
4868 discQCount != 0)
4869 FPT_BL_Card
4870 [p_card].
4871 discQCount--;
4872 FPT_BL_Card[p_card].
4873 discQ_Tbl
4874 [FPT_sccbMgrTbl
4875 [p_card][currSCCB->
4876 TargID].
4877 LunDiscQ_Idx[0]] =
4878 NULL;
1da177e4
LT
4879 }
4880 }
5c04a7b8
AD
4881 return;
4882 }
4883 }
4884 }
4885 }
1da177e4 4886
5c04a7b8
AD
4887 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4888 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4889 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4890 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4891 Lun] = 0;
1da177e4 4892 else
5c04a7b8 4893 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4894
5c04a7b8 4895 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 4896}
1da177e4
LT
4897
4898#define SHORT_WAIT 0x0000000F
4899#define LONG_WAIT 0x0000FFFFL
4900
1da177e4
LT
4901/*---------------------------------------------------------------------
4902 *
4903 * Function: Data Transfer Processor
4904 *
4905 * Description: This routine performs two tasks.
4906 * (1) Start data transfer by calling HOST_DATA_XFER_START
4907 * function. Once data transfer is started, (2) Depends
4908 * on the type of data transfer mode Scatter/Gather mode
4909 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4910 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4911 * data transfer done. In Scatter/Gather mode, this routine
4912 * checks bus master command complete and dual rank busy
4913 * bit to keep chaining SC transfer command. Similarly,
4914 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4915 * (F_HOST_XFER_ACT bit) for data transfer done.
4916 *
4917 *---------------------------------------------------------------------*/
4918
391e2f25 4919static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
1da177e4 4920{
5c04a7b8 4921 struct sccb *currSCCB;
1da177e4 4922
5c04a7b8 4923 currSCCB = pCurrCard->currentSCCB;
1da177e4 4924
5c04a7b8
AD
4925 if (currSCCB->Sccb_XferState & F_SG_XFER) {
4926 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4927 {
4928 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4929 currSCCB->Sccb_SGoffset = 0x00;
4930 }
4931 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
1da177e4 4932
5c04a7b8
AD
4933 FPT_busMstrSGDataXferStart(port, currSCCB);
4934 }
4935
4936 else {
4937 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
1da177e4 4938 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
1da177e4 4939
5c04a7b8
AD
4940 FPT_busMstrDataXferStart(port, currSCCB);
4941 }
4942 }
1da177e4
LT
4943}
4944
1da177e4
LT
4945/*---------------------------------------------------------------------
4946 *
4947 * Function: BusMaster Scatter Gather Data Transfer Start
4948 *
4949 * Description:
4950 *
4951 *---------------------------------------------------------------------*/
391e2f25 4952static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
1da177e4 4953{
391e2f25 4954 u32 count, addr, tmpSGCnt;
5c04a7b8
AD
4955 unsigned int sg_index;
4956 unsigned char sg_count, i;
391e2f25
KA
4957 u32 reg_offset;
4958 struct blogic_sg_seg *segp;
1da177e4 4959
391e2f25
KA
4960 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4961 count = ((u32)HOST_RD_CMD) << 24;
4962 else
4963 count = ((u32)HOST_WRT_CMD) << 24;
1da177e4 4964
5c04a7b8
AD
4965 sg_count = 0;
4966 tmpSGCnt = 0;
4967 sg_index = pcurrSCCB->Sccb_sgseg;
4968 reg_offset = hp_aramBase;
1da177e4 4969
5c04a7b8
AD
4970 i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4971 ~(SGRAM_ARAM | SCATTER_EN));
1da177e4 4972
5c04a7b8 4973 WR_HARPOON(p_port + hp_page_ctrl, i);
1da177e4 4974
5c04a7b8 4975 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
391e2f25
KA
4976 ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4977 pcurrSCCB->DataLength)) {
1da177e4 4978
391e2f25
KA
4979 segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4980 sg_index;
4981 tmpSGCnt += segp->segbytes;
4982 count |= segp->segbytes;
4983 addr = segp->segdata;
1da177e4 4984
5c04a7b8 4985 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5c04a7b8
AD
4986 addr +=
4987 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4988 count =
4989 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5c04a7b8
AD
4990 tmpSGCnt = count & 0x00FFFFFFL;
4991 }
1da177e4 4992
5c04a7b8
AD
4993 WR_HARP32(p_port, reg_offset, addr);
4994 reg_offset += 4;
1da177e4 4995
5c04a7b8
AD
4996 WR_HARP32(p_port, reg_offset, count);
4997 reg_offset += 4;
1da177e4 4998
5c04a7b8
AD
4999 count &= 0xFF000000L;
5000 sg_index++;
5001 sg_count++;
1da177e4 5002
5c04a7b8 5003 } /*End While */
1da177e4 5004
5c04a7b8 5005 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
1da177e4 5006
5c04a7b8 5007 WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
1da177e4 5008
5c04a7b8 5009 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
1da177e4 5010
5c04a7b8 5011 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
1da177e4 5012
5c04a7b8
AD
5013 WR_HARPOON(p_port + hp_portctrl_0,
5014 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5015 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5016 }
1da177e4 5017
5c04a7b8 5018 else {
1da177e4 5019
5c04a7b8
AD
5020 if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
5021 (tmpSGCnt & 0x000000001)) {
1da177e4 5022
5c04a7b8
AD
5023 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5024 tmpSGCnt--;
5025 }
1da177e4 5026
5c04a7b8 5027 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
1da177e4 5028
5c04a7b8
AD
5029 WR_HARPOON(p_port + hp_portctrl_0,
5030 (SCSI_PORT | DMA_PORT | DMA_RD));
5031 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5032 }
1da177e4 5033
5c04a7b8 5034 WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
1da177e4
LT
5035
5036}
5037
1da177e4
LT
5038/*---------------------------------------------------------------------
5039 *
5040 * Function: BusMaster Data Transfer Start
5041 *
5042 * Description:
5043 *
5044 *---------------------------------------------------------------------*/
391e2f25 5045static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
1da177e4 5046{
391e2f25 5047 u32 addr, count;
1da177e4 5048
5c04a7b8 5049 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
1da177e4 5050
5c04a7b8 5051 count = pcurrSCCB->Sccb_XferCnt;
1da177e4 5052
391e2f25 5053 addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5c04a7b8 5054 }
1da177e4 5055
5c04a7b8
AD
5056 else {
5057 addr = pcurrSCCB->SensePointer;
5058 count = pcurrSCCB->RequestSenseLength;
1da177e4 5059
5c04a7b8 5060 }
1da177e4 5061
5c04a7b8 5062 HP_SETUP_ADDR_CNT(p_port, addr, count);
1da177e4 5063
5c04a7b8 5064 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
1da177e4 5065
5c04a7b8
AD
5066 WR_HARPOON(p_port + hp_portctrl_0,
5067 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5068 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
1da177e4 5069
5c04a7b8
AD
5070 WR_HARPOON(p_port + hp_xfer_cmd,
5071 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5072 }
1da177e4 5073
5c04a7b8 5074 else {
1da177e4 5075
5c04a7b8
AD
5076 WR_HARPOON(p_port + hp_portctrl_0,
5077 (SCSI_PORT | DMA_PORT | DMA_RD));
5078 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
1da177e4 5079
5c04a7b8
AD
5080 WR_HARPOON(p_port + hp_xfer_cmd,
5081 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
1da177e4 5082
5c04a7b8 5083 }
1da177e4
LT
5084}
5085
1da177e4
LT
5086/*---------------------------------------------------------------------
5087 *
5088 * Function: BusMaster Timeout Handler
5089 *
5090 * Description: This function is called after a bus master command busy time
5091 * out is detected. This routines issue halt state machine
5092 * with a software time out for command busy. If command busy
5093 * is still asserted at the end of the time out, it issues
5094 * hard abort with another software time out. It hard abort
5095 * command busy is also time out, it'll just give up.
5096 *
5097 *---------------------------------------------------------------------*/
391e2f25 5098static unsigned char FPT_busMstrTimeOut(u32 p_port)
1da177e4 5099{
5c04a7b8 5100 unsigned long timeout;
1da177e4 5101
5c04a7b8 5102 timeout = LONG_WAIT;
1da177e4 5103
5c04a7b8 5104 WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
1da177e4 5105
5c04a7b8
AD
5106 while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5107 && timeout--) {
5108 }
1da177e4 5109
5c04a7b8
AD
5110 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5111 WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
1da177e4 5112
5c04a7b8
AD
5113 timeout = LONG_WAIT;
5114 while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5115 && timeout--) {
5116 }
5117 }
1da177e4 5118
5c04a7b8 5119 RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
1da177e4 5120
5c04a7b8 5121 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5c1b85e2 5122 return 1;
5c04a7b8 5123 }
1da177e4 5124
5c04a7b8 5125 else {
5c1b85e2 5126 return 0;
5c04a7b8 5127 }
1da177e4
LT
5128}
5129
1da177e4
LT
5130/*---------------------------------------------------------------------
5131 *
5132 * Function: Host Data Transfer Abort
5133 *
5134 * Description: Abort any in progress transfer.
5135 *
5136 *---------------------------------------------------------------------*/
391e2f25 5137static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5c04a7b8 5138 struct sccb *pCurrSCCB)
1da177e4
LT
5139{
5140
5c04a7b8
AD
5141 unsigned long timeout;
5142 unsigned long remain_cnt;
391e2f25
KA
5143 u32 sg_ptr;
5144 struct blogic_sg_seg *segp;
1da177e4 5145
5c04a7b8 5146 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
1da177e4 5147
5c04a7b8 5148 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
1da177e4 5149
5c04a7b8 5150 if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
1da177e4 5151
5c04a7b8
AD
5152 WR_HARPOON(port + hp_bm_ctrl,
5153 (RD_HARPOON(port + hp_bm_ctrl) |
5154 FLUSH_XFER_CNTR));
5155 timeout = LONG_WAIT;
1da177e4 5156
5c04a7b8
AD
5157 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5158 && timeout--) {
5159 }
1da177e4 5160
5c04a7b8
AD
5161 WR_HARPOON(port + hp_bm_ctrl,
5162 (RD_HARPOON(port + hp_bm_ctrl) &
5163 ~FLUSH_XFER_CNTR));
1da177e4 5164
5c04a7b8 5165 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
1da177e4 5166
5c04a7b8 5167 if (FPT_busMstrTimeOut(port)) {
1da177e4 5168
5c04a7b8 5169 if (pCurrSCCB->HostStatus == 0x00)
1da177e4 5170
5c04a7b8
AD
5171 pCurrSCCB->HostStatus =
5172 SCCB_BM_ERR;
1da177e4 5173
5c04a7b8 5174 }
1da177e4 5175
5c04a7b8
AD
5176 if (RD_HARPOON(port + hp_int_status) &
5177 INT_EXT_STATUS)
1da177e4 5178
5c04a7b8
AD
5179 if (RD_HARPOON(port + hp_ext_status) &
5180 BAD_EXT_STATUS)
1da177e4 5181
5c04a7b8
AD
5182 if (pCurrSCCB->HostStatus ==
5183 0x00)
5184 {
5185 pCurrSCCB->HostStatus =
5186 SCCB_BM_ERR;
5187 }
5188 }
5189 }
5190 }
1da177e4 5191
5c04a7b8 5192 else if (pCurrSCCB->Sccb_XferCnt) {
1da177e4 5193
5c04a7b8 5194 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
1da177e4 5195
5c04a7b8
AD
5196 WR_HARPOON(port + hp_page_ctrl,
5197 (RD_HARPOON(port + hp_page_ctrl) &
5198 ~SCATTER_EN));
1da177e4 5199
5c04a7b8 5200 WR_HARPOON(port + hp_sg_addr, 0x00);
1da177e4 5201
5c04a7b8 5202 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
1da177e4 5203
5c04a7b8
AD
5204 if (sg_ptr >
5205 (unsigned int)(pCurrSCCB->DataLength /
5206 SG_ELEMENT_SIZE)) {
1da177e4 5207
391e2f25
KA
5208 sg_ptr = (u32)(pCurrSCCB->DataLength /
5209 SG_ELEMENT_SIZE);
5c04a7b8 5210 }
1da177e4 5211
5c04a7b8 5212 remain_cnt = pCurrSCCB->Sccb_XferCnt;
1da177e4 5213
5c04a7b8 5214 while (remain_cnt < 0x01000000L) {
1da177e4 5215
5c04a7b8 5216 sg_ptr--;
391e2f25
KA
5217 segp = (struct blogic_sg_seg *)(pCurrSCCB->
5218 DataPointer) + (sg_ptr * 2);
5219 if (remain_cnt > (unsigned long)segp->segbytes)
5c04a7b8 5220 remain_cnt -=
391e2f25
KA
5221 (unsigned long)segp->segbytes;
5222 else
5c04a7b8 5223 break;
5c04a7b8 5224 }
1da177e4 5225
5c04a7b8 5226 if (remain_cnt < 0x01000000L) {
1da177e4 5227
5c04a7b8 5228 pCurrSCCB->Sccb_SGoffset = remain_cnt;
1da177e4 5229
5c04a7b8 5230 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
1da177e4 5231
5c04a7b8
AD
5232 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5233 pCurrSCCB->DataLength && (remain_cnt == 0))
1da177e4 5234
5c04a7b8
AD
5235 pCurrSCCB->Sccb_XferState |=
5236 F_ALL_XFERRED;
5237 }
1da177e4 5238
5c04a7b8 5239 else {
1da177e4 5240
5c04a7b8 5241 if (pCurrSCCB->HostStatus == 0x00) {
1da177e4 5242
5c04a7b8
AD
5243 pCurrSCCB->HostStatus =
5244 SCCB_GROSS_FW_ERR;
5245 }
5246 }
5247 }
1da177e4 5248
5c04a7b8 5249 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
1da177e4 5250
5c04a7b8 5251 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
1da177e4 5252
5c04a7b8
AD
5253 FPT_busMstrTimeOut(port);
5254 }
1da177e4 5255
5c04a7b8 5256 else {
1da177e4 5257
5c04a7b8
AD
5258 if (RD_HARPOON(port + hp_int_status) &
5259 INT_EXT_STATUS) {
1da177e4 5260
5c04a7b8
AD
5261 if (RD_HARPOON(port + hp_ext_status) &
5262 BAD_EXT_STATUS) {
1da177e4 5263
5c04a7b8
AD
5264 if (pCurrSCCB->HostStatus ==
5265 0x00) {
1da177e4 5266
5c04a7b8
AD
5267 pCurrSCCB->HostStatus =
5268 SCCB_BM_ERR;
5269 }
5270 }
5271 }
1da177e4 5272
5c04a7b8
AD
5273 }
5274 }
1da177e4 5275
5c04a7b8 5276 else {
1da177e4 5277
5c04a7b8 5278 if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
1da177e4 5279
5c04a7b8 5280 timeout = SHORT_WAIT;
1da177e4 5281
5c04a7b8
AD
5282 while ((RD_HARPOON(port + hp_ext_status) &
5283 BM_CMD_BUSY)
5284 && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5285 BM_THRESHOLD) && timeout--) {
5286 }
5287 }
1da177e4 5288
5c04a7b8 5289 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
1da177e4 5290
5c04a7b8
AD
5291 WR_HARPOON(port + hp_bm_ctrl,
5292 (RD_HARPOON(port + hp_bm_ctrl) |
5293 FLUSH_XFER_CNTR));
1da177e4 5294
5c04a7b8 5295 timeout = LONG_WAIT;
1da177e4 5296
5c04a7b8
AD
5297 while ((RD_HARPOON(port + hp_ext_status) &
5298 BM_CMD_BUSY) && timeout--) {
5299 }
1da177e4 5300
5c04a7b8
AD
5301 WR_HARPOON(port + hp_bm_ctrl,
5302 (RD_HARPOON(port + hp_bm_ctrl) &
5303 ~FLUSH_XFER_CNTR));
1da177e4 5304
5c04a7b8
AD
5305 if (RD_HARPOON(port + hp_ext_status) &
5306 BM_CMD_BUSY) {
1da177e4 5307
5c04a7b8 5308 if (pCurrSCCB->HostStatus == 0x00) {
1da177e4 5309
5c04a7b8
AD
5310 pCurrSCCB->HostStatus =
5311 SCCB_BM_ERR;
5312 }
1da177e4 5313
5c04a7b8
AD
5314 FPT_busMstrTimeOut(port);
5315 }
5316 }
1da177e4 5317
5c04a7b8 5318 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
1da177e4 5319
5c04a7b8
AD
5320 if (RD_HARPOON(port + hp_ext_status) &
5321 BAD_EXT_STATUS) {
1da177e4 5322
5c04a7b8 5323 if (pCurrSCCB->HostStatus == 0x00) {
1da177e4 5324
5c04a7b8
AD
5325 pCurrSCCB->HostStatus =
5326 SCCB_BM_ERR;
5327 }
5328 }
5329 }
5330 }
1da177e4 5331
5c04a7b8 5332 }
1da177e4 5333
5c04a7b8 5334 else {
1da177e4 5335
5c04a7b8 5336 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
1da177e4 5337
5c04a7b8 5338 timeout = LONG_WAIT;
1da177e4 5339
5c04a7b8
AD
5340 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5341 && timeout--) {
5342 }
1da177e4 5343
5c04a7b8 5344 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
1da177e4 5345
5c04a7b8 5346 if (pCurrSCCB->HostStatus == 0x00) {
1da177e4 5347
5c04a7b8
AD
5348 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5349 }
1da177e4 5350
5c04a7b8
AD
5351 FPT_busMstrTimeOut(port);
5352 }
5353 }
1da177e4 5354
5c04a7b8 5355 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
1da177e4 5356
5c04a7b8 5357 if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
1da177e4 5358
5c04a7b8 5359 if (pCurrSCCB->HostStatus == 0x00) {
1da177e4 5360
5c04a7b8
AD
5361 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5362 }
5363 }
1da177e4 5364
5c04a7b8 5365 }
1da177e4 5366
5c04a7b8 5367 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
1da177e4 5368
5c04a7b8
AD
5369 WR_HARPOON(port + hp_page_ctrl,
5370 (RD_HARPOON(port + hp_page_ctrl) &
5371 ~SCATTER_EN));
1da177e4 5372
5c04a7b8 5373 WR_HARPOON(port + hp_sg_addr, 0x00);
1da177e4 5374
5c04a7b8 5375 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
1da177e4 5376
5c04a7b8 5377 pCurrSCCB->Sccb_SGoffset = 0x00;
1da177e4 5378
391e2f25
KA
5379 if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5380 pCurrSCCB->DataLength) {
1da177e4 5381
5c04a7b8 5382 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5c04a7b8
AD
5383 pCurrSCCB->Sccb_sgseg =
5384 (unsigned short)(pCurrSCCB->DataLength /
5385 SG_ELEMENT_SIZE);
5c04a7b8
AD
5386 }
5387 }
1da177e4 5388
5c04a7b8 5389 else {
5c04a7b8 5390 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5c04a7b8
AD
5391 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5392 }
5393 }
1da177e4 5394
5c04a7b8 5395 WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1da177e4
LT
5396}
5397
1da177e4
LT
5398/*---------------------------------------------------------------------
5399 *
5400 * Function: Host Data Transfer Restart
5401 *
5402 * Description: Reset the available count due to a restore data
5403 * pointers message.
5404 *
5405 *---------------------------------------------------------------------*/
5c04a7b8 5406static void FPT_hostDataXferRestart(struct sccb *currSCCB)
1da177e4 5407{
5c04a7b8
AD
5408 unsigned long data_count;
5409 unsigned int sg_index;
391e2f25 5410 struct blogic_sg_seg *segp;
1da177e4 5411
5c04a7b8 5412 if (currSCCB->Sccb_XferState & F_SG_XFER) {
1da177e4 5413
5c04a7b8 5414 currSCCB->Sccb_XferCnt = 0;
1da177e4 5415
5c04a7b8 5416 sg_index = 0xffff; /*Index by long words into sg list. */
391e2f25 5417 data_count = 0; /*Running count of SG xfer counts. */
1da177e4 5418
1da177e4 5419
5c04a7b8 5420 while (data_count < currSCCB->Sccb_ATC) {
1da177e4 5421
5c04a7b8 5422 sg_index++;
391e2f25
KA
5423 segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5424 (sg_index * 2);
5425 data_count += segp->segbytes;
5c04a7b8 5426 }
1da177e4 5427
5c04a7b8 5428 if (data_count == currSCCB->Sccb_ATC) {
1da177e4 5429
5c04a7b8
AD
5430 currSCCB->Sccb_SGoffset = 0;
5431 sg_index++;
5432 }
1da177e4 5433
5c04a7b8
AD
5434 else {
5435 currSCCB->Sccb_SGoffset =
5436 data_count - currSCCB->Sccb_ATC;
5437 }
1da177e4 5438
5c04a7b8
AD
5439 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5440 }
1da177e4 5441
5c04a7b8
AD
5442 else {
5443 currSCCB->Sccb_XferCnt =
5444 currSCCB->DataLength - currSCCB->Sccb_ATC;
5445 }
1da177e4 5446}
1da177e4 5447
1da177e4
LT
5448/*---------------------------------------------------------------------
5449 *
47b5d69c 5450 * Function: FPT_scini
1da177e4
LT
5451 *
5452 * Description: Setup all data structures necessary for SCAM selection.
5453 *
5454 *---------------------------------------------------------------------*/
5455
5c04a7b8
AD
5456static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5457 unsigned char p_power_up)
1da177e4
LT
5458{
5459
5c04a7b8 5460 unsigned char loser, assigned_id;
391e2f25 5461 u32 p_port;
1da177e4 5462
5c04a7b8
AD
5463 unsigned char i, k, ScamFlg;
5464 struct sccb_card *currCard;
5465 struct nvram_info *pCurrNvRam;
1da177e4 5466
5c04a7b8
AD
5467 currCard = &FPT_BL_Card[p_card];
5468 p_port = currCard->ioPort;
1da177e4
LT
5469 pCurrNvRam = currCard->pNvRamInfo;
5470
5c04a7b8 5471 if (pCurrNvRam) {
1da177e4
LT
5472 ScamFlg = pCurrNvRam->niScamConf;
5473 i = pCurrNvRam->niSysConf;
5c04a7b8
AD
5474 } else {
5475 ScamFlg =
5476 (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5477 i = (unsigned
5478 char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
1da177e4 5479 }
5c04a7b8 5480 if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
1da177e4
LT
5481 return;
5482
5c04a7b8 5483 FPT_inisci(p_card, p_port, p_our_id);
1da177e4 5484
5c04a7b8
AD
5485 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5486 too slow to return to SCAM selection */
1da177e4 5487
5c04a7b8
AD
5488 /* if (p_power_up)
5489 FPT_Wait1Second(p_port);
5490 else
5491 FPT_Wait(p_port, TO_250ms); */
1da177e4 5492
5c04a7b8 5493 FPT_Wait1Second(p_port);
1da177e4 5494
5c04a7b8
AD
5495 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5496 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5497 }
1da177e4 5498
5c04a7b8 5499 FPT_scsel(p_port);
1da177e4 5500
5c04a7b8
AD
5501 do {
5502 FPT_scxferc(p_port, SYNC_PTRN);
5503 FPT_scxferc(p_port, DOM_MSTR);
5504 loser =
5505 FPT_scsendi(p_port,
5506 &FPT_scamInfo[p_our_id].id_string[0]);
5507 } while (loser == 0xFF);
1da177e4 5508
5c04a7b8 5509 FPT_scbusf(p_port);
1da177e4 5510
5c04a7b8
AD
5511 if ((p_power_up) && (!loser)) {
5512 FPT_sresb(p_port, p_card);
5513 FPT_Wait(p_port, TO_250ms);
1da177e4 5514
5c04a7b8
AD
5515 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5516 }
1da177e4 5517
5c04a7b8 5518 FPT_scsel(p_port);
1da177e4 5519
5c04a7b8
AD
5520 do {
5521 FPT_scxferc(p_port, SYNC_PTRN);
5522 FPT_scxferc(p_port, DOM_MSTR);
5523 loser =
5524 FPT_scsendi(p_port,
5525 &FPT_scamInfo[p_our_id].
5526 id_string[0]);
5527 } while (loser == 0xFF);
1da177e4 5528
5c04a7b8
AD
5529 FPT_scbusf(p_port);
5530 }
5531 }
1da177e4 5532
5c04a7b8
AD
5533 else {
5534 loser = 0;
5535 }
1da177e4 5536
5c04a7b8
AD
5537 if (!loser) {
5538
5539 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5540
5541 if (ScamFlg & SCAM_ENABLED) {
5542
5543 for (i = 0; i < MAX_SCSI_TAR; i++) {
5544 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5545 (FPT_scamInfo[i].state == ID_UNUSED)) {
5546 if (FPT_scsell(p_port, i)) {
5547 FPT_scamInfo[i].state = LEGACY;
5548 if ((FPT_scamInfo[i].
5549 id_string[0] != 0xFF)
5550 || (FPT_scamInfo[i].
5551 id_string[1] != 0xFA)) {
5552
5553 FPT_scamInfo[i].
5554 id_string[0] = 0xFF;
5555 FPT_scamInfo[i].
5556 id_string[1] = 0xFA;
5557 if (pCurrNvRam == NULL)
5558 currCard->
5559 globalFlags
5560 |=
5561 F_UPDATE_EEPROM;
5562 }
5563 }
5564 }
5565 }
1da177e4 5566
5c04a7b8
AD
5567 FPT_sresb(p_port, p_card);
5568 FPT_Wait1Second(p_port);
5569 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5570 }
5571 FPT_scsel(p_port);
5572 FPT_scasid(p_card, p_port);
5573 }
1da177e4 5574
5c04a7b8 5575 }
1da177e4 5576
5c04a7b8
AD
5577 else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5578 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5579 assigned_id = 0;
5580 FPT_scwtsel(p_port);
1da177e4 5581
5c04a7b8
AD
5582 do {
5583 while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5584 }
1da177e4 5585
5c04a7b8
AD
5586 i = FPT_scxferc(p_port, 0x00);
5587 if (i == ASSIGN_ID) {
5588 if (!
5589 (FPT_scsendi
5590 (p_port,
5591 &FPT_scamInfo[p_our_id].id_string[0]))) {
5592 i = FPT_scxferc(p_port, 0x00);
5593 if (FPT_scvalq(i)) {
5594 k = FPT_scxferc(p_port, 0x00);
5595
5596 if (FPT_scvalq(k)) {
5597 currCard->ourId =
5598 ((unsigned char)(i
5599 <<
5600 3)
5601 +
5602 (k &
5603 (unsigned char)7))
5604 & (unsigned char)
5605 0x3F;
5606 FPT_inisci(p_card,
5607 p_port,
5608 p_our_id);
5609 FPT_scamInfo[currCard->
5610 ourId].
5611 state = ID_ASSIGNED;
5612 FPT_scamInfo[currCard->
5613 ourId].
5614 id_string[0]
5615 = SLV_TYPE_CODE0;
5616 assigned_id = 1;
5617 }
5618 }
5619 }
5620 }
1da177e4 5621
5c04a7b8
AD
5622 else if (i == SET_P_FLAG) {
5623 if (!(FPT_scsendi(p_port,
5624 &FPT_scamInfo[p_our_id].
5625 id_string[0])))
5626 FPT_scamInfo[p_our_id].id_string[0] |=
5627 0x80;
5628 }
5629 } while (!assigned_id);
1da177e4 5630
5c04a7b8
AD
5631 while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5632 }
5633 }
1da177e4 5634
5c04a7b8
AD
5635 if (ScamFlg & SCAM_ENABLED) {
5636 FPT_scbusf(p_port);
5637 if (currCard->globalFlags & F_UPDATE_EEPROM) {
5638 FPT_scsavdi(p_card, p_port);
5639 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5640 }
5641 }
1da177e4 5642
1da177e4
LT
5643/*
5644 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5645 {
47b5d69c
JB
5646 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5647 (FPT_scamInfo[i].state == LEGACY))
1da177e4
LT
5648 k++;
5649 }
5650
5651 if (k==2)
5652 currCard->globalFlags |= F_SINGLE_DEVICE;
5653 else
5654 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5655*/
5656}
5657
1da177e4
LT
5658/*---------------------------------------------------------------------
5659 *
47b5d69c 5660 * Function: FPT_scarb
1da177e4
LT
5661 *
5662 * Description: Gain control of the bus and wait SCAM select time (250ms)
5663 *
5664 *---------------------------------------------------------------------*/
5665
391e2f25 5666static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
1da177e4 5667{
5c04a7b8 5668 if (p_sel_type == INIT_SELTD) {
1da177e4 5669
5c04a7b8
AD
5670 while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5671 }
1da177e4 5672
5c04a7b8 5673 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5c1b85e2 5674 return 0;
1da177e4 5675
5c04a7b8 5676 if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5c1b85e2 5677 return 0;
1da177e4 5678
5c04a7b8
AD
5679 WR_HARPOON(p_port + hp_scsisig,
5680 (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
1da177e4 5681
5c04a7b8 5682 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
1da177e4 5683
5c04a7b8
AD
5684 WR_HARPOON(p_port + hp_scsisig,
5685 (RD_HARPOON(p_port + hp_scsisig) &
5686 ~SCSI_BSY));
5c1b85e2 5687 return 0;
5c04a7b8 5688 }
1da177e4 5689
5c04a7b8
AD
5690 WR_HARPOON(p_port + hp_scsisig,
5691 (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
1da177e4 5692
5c04a7b8 5693 if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
1da177e4 5694
5c04a7b8
AD
5695 WR_HARPOON(p_port + hp_scsisig,
5696 (RD_HARPOON(p_port + hp_scsisig) &
5697 ~(SCSI_BSY | SCSI_SEL)));
5c1b85e2 5698 return 0;
5c04a7b8
AD
5699 }
5700 }
1da177e4 5701
5c04a7b8
AD
5702 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5703 & ~ACTdeassert));
5704 WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5705 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5706 WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5707 WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
1da177e4 5708
5c04a7b8
AD
5709 WR_HARPOON(p_port + hp_scsisig,
5710 (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
1da177e4 5711
5c04a7b8
AD
5712 WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5713 & ~SCSI_BSY));
1da177e4 5714
5c04a7b8 5715 FPT_Wait(p_port, TO_250ms);
1da177e4 5716
5c1b85e2 5717 return 1;
1da177e4
LT
5718}
5719
1da177e4
LT
5720/*---------------------------------------------------------------------
5721 *
47b5d69c 5722 * Function: FPT_scbusf
1da177e4
LT
5723 *
5724 * Description: Release the SCSI bus and disable SCAM selection.
5725 *
5726 *---------------------------------------------------------------------*/
5727
391e2f25 5728static void FPT_scbusf(u32 p_port)
1da177e4 5729{
5c04a7b8
AD
5730 WR_HARPOON(p_port + hp_page_ctrl,
5731 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
1da177e4 5732
5c04a7b8 5733 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
1da177e4 5734
5c04a7b8
AD
5735 WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5736 & ~SCSI_BUS_EN));
1da177e4 5737
5c04a7b8 5738 WR_HARPOON(p_port + hp_scsisig, 0x00);
1da177e4 5739
5c04a7b8
AD
5740 WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5741 & ~SCAM_EN));
1da177e4 5742
5c04a7b8
AD
5743 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5744 | ACTdeassert));
1da177e4 5745
5c04a7b8 5746 WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
1da177e4 5747
5c04a7b8
AD
5748 WR_HARPOON(p_port + hp_page_ctrl,
5749 (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
1da177e4
LT
5750}
5751
1da177e4
LT
5752/*---------------------------------------------------------------------
5753 *
47b5d69c 5754 * Function: FPT_scasid
1da177e4
LT
5755 *
5756 * Description: Assign an ID to all the SCAM devices.
5757 *
5758 *---------------------------------------------------------------------*/
5759
391e2f25 5760static void FPT_scasid(unsigned char p_card, u32 p_port)
1da177e4 5761{
5c04a7b8 5762 unsigned char temp_id_string[ID_STRING_LENGTH];
1da177e4 5763
5c04a7b8 5764 unsigned char i, k, scam_id;
db038cf8 5765 unsigned char crcBytes[3];
5c04a7b8
AD
5766 struct nvram_info *pCurrNvRam;
5767 unsigned short *pCrcBytes;
1da177e4 5768
47b5d69c 5769 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4 5770
5c04a7b8 5771 i = 0;
1da177e4 5772
5c04a7b8 5773 while (!i) {
1da177e4 5774
5c04a7b8
AD
5775 for (k = 0; k < ID_STRING_LENGTH; k++) {
5776 temp_id_string[k] = (unsigned char)0x00;
5777 }
1da177e4 5778
5c04a7b8
AD
5779 FPT_scxferc(p_port, SYNC_PTRN);
5780 FPT_scxferc(p_port, ASSIGN_ID);
1da177e4 5781
5c04a7b8
AD
5782 if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5783 if (pCurrNvRam) {
fd1e29ed 5784 pCrcBytes = (unsigned short *)&crcBytes[0];
47b5d69c
JB
5785 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5786 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
1da177e4
LT
5787 temp_id_string[1] = crcBytes[2];
5788 temp_id_string[2] = crcBytes[0];
5789 temp_id_string[3] = crcBytes[1];
5c04a7b8
AD
5790 for (k = 4; k < ID_STRING_LENGTH; k++)
5791 temp_id_string[k] = (unsigned char)0x00;
1da177e4 5792 }
5c04a7b8 5793 i = FPT_scmachid(p_card, temp_id_string);
1da177e4 5794
5c04a7b8
AD
5795 if (i == CLR_PRIORITY) {
5796 FPT_scxferc(p_port, MISC_CODE);
5797 FPT_scxferc(p_port, CLR_P_FLAG);
5798 i = 0; /*Not the last ID yet. */
5799 }
1da177e4 5800
5c04a7b8
AD
5801 else if (i != NO_ID_AVAIL) {
5802 if (i < 8)
5803 FPT_scxferc(p_port, ID_0_7);
5804 else
5805 FPT_scxferc(p_port, ID_8_F);
1da177e4 5806
5c04a7b8 5807 scam_id = (i & (unsigned char)0x07);
1da177e4 5808
5c04a7b8
AD
5809 for (k = 1; k < 0x08; k <<= 1)
5810 if (!(k & i))
5811 scam_id += 0x08; /*Count number of zeros in DB0-3. */
1da177e4 5812
5c04a7b8 5813 FPT_scxferc(p_port, scam_id);
1da177e4 5814
5c04a7b8
AD
5815 i = 0; /*Not the last ID yet. */
5816 }
5817 }
1da177e4 5818
5c04a7b8
AD
5819 else {
5820 i = 1;
5821 }
1da177e4 5822
5c04a7b8 5823 } /*End while */
1da177e4 5824
5c04a7b8
AD
5825 FPT_scxferc(p_port, SYNC_PTRN);
5826 FPT_scxferc(p_port, CFG_CMPLT);
1da177e4
LT
5827}
5828
1da177e4
LT
5829/*---------------------------------------------------------------------
5830 *
47b5d69c 5831 * Function: FPT_scsel
1da177e4
LT
5832 *
5833 * Description: Select all the SCAM devices.
5834 *
5835 *---------------------------------------------------------------------*/
5836
391e2f25 5837static void FPT_scsel(u32 p_port)
1da177e4
LT
5838{
5839
5c04a7b8
AD
5840 WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5841 FPT_scwiros(p_port, SCSI_MSG);
1da177e4 5842
5c04a7b8 5843 WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
1da177e4 5844
5c04a7b8
AD
5845 WR_HARPOON(p_port + hp_scsisig,
5846 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5847 WR_HARPOON(p_port + hp_scsidata_0,
5848 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5849 (unsigned char)(BIT(7) + BIT(6))));
1da177e4 5850
5c04a7b8
AD
5851 WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5852 FPT_scwiros(p_port, SCSI_SEL);
1da177e4 5853
5c04a7b8
AD
5854 WR_HARPOON(p_port + hp_scsidata_0,
5855 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5856 ~(unsigned char)BIT(6)));
5857 FPT_scwirod(p_port, BIT(6));
1da177e4 5858
5c04a7b8
AD
5859 WR_HARPOON(p_port + hp_scsisig,
5860 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
1da177e4
LT
5861}
5862
1da177e4
LT
5863/*---------------------------------------------------------------------
5864 *
47b5d69c 5865 * Function: FPT_scxferc
1da177e4
LT
5866 *
5867 * Description: Handshake the p_data (DB4-0) across the bus.
5868 *
5869 *---------------------------------------------------------------------*/
5870
391e2f25 5871static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
1da177e4 5872{
5c04a7b8 5873 unsigned char curr_data, ret_data;
1da177e4 5874
5c04a7b8 5875 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
1da177e4 5876
5c04a7b8 5877 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
1da177e4 5878
5c04a7b8 5879 curr_data &= ~BIT(7);
1da177e4 5880
5c04a7b8 5881 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
1da177e4 5882
5c04a7b8
AD
5883 FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
5884 while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
1da177e4 5885
5c04a7b8 5886 ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
1da177e4 5887
5c04a7b8 5888 curr_data |= BIT(6);
1da177e4 5889
5c04a7b8 5890 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
1da177e4 5891
5c04a7b8 5892 curr_data &= ~BIT(5);
1da177e4 5893
5c04a7b8 5894 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
1da177e4 5895
5c04a7b8 5896 FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
1da177e4 5897
5c04a7b8
AD
5898 curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5899 curr_data |= BIT(7);
1da177e4 5900
5c04a7b8 5901 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
1da177e4 5902
5c04a7b8 5903 curr_data &= ~BIT(6);
1da177e4 5904
5c04a7b8 5905 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
1da177e4 5906
5c04a7b8 5907 FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
1da177e4 5908
5c1b85e2 5909 return ret_data;
1da177e4
LT
5910}
5911
1da177e4
LT
5912/*---------------------------------------------------------------------
5913 *
47b5d69c 5914 * Function: FPT_scsendi
1da177e4
LT
5915 *
5916 * Description: Transfer our Identification string to determine if we
5917 * will be the dominant master.
5918 *
5919 *---------------------------------------------------------------------*/
5920
391e2f25 5921static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
1da177e4 5922{
5c04a7b8 5923 unsigned char ret_data, byte_cnt, bit_cnt, defer;
1da177e4 5924
5c04a7b8 5925 defer = 0;
1da177e4 5926
5c04a7b8 5927 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
1da177e4 5928
5c04a7b8 5929 for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
1da177e4 5930
5c04a7b8
AD
5931 if (defer)
5932 ret_data = FPT_scxferc(p_port, 00);
1da177e4 5933
5c04a7b8 5934 else if (p_id_string[byte_cnt] & bit_cnt)
1da177e4 5935
5c04a7b8 5936 ret_data = FPT_scxferc(p_port, 02);
1da177e4 5937
5c04a7b8 5938 else {
1da177e4 5939
5c04a7b8
AD
5940 ret_data = FPT_scxferc(p_port, 01);
5941 if (ret_data & 02)
5942 defer = 1;
5943 }
1da177e4 5944
5c04a7b8 5945 if ((ret_data & 0x1C) == 0x10)
5c1b85e2 5946 return 0x00; /*End of isolation stage, we won! */
1da177e4 5947
5c04a7b8 5948 if (ret_data & 0x1C)
5c1b85e2 5949 return 0xFF;
1da177e4 5950
5c04a7b8 5951 if ((defer) && (!(ret_data & 0x1F)))
5c1b85e2 5952 return 0x01; /*End of isolation stage, we lost. */
1da177e4 5953
5c04a7b8 5954 } /*bit loop */
1da177e4 5955
5c04a7b8 5956 } /*byte loop */
1da177e4 5957
5c04a7b8 5958 if (defer)
5c1b85e2 5959 return 0x01; /*We lost */
5c04a7b8 5960 else
5c1b85e2 5961 return 0; /*We WON! Yeeessss! */
1da177e4
LT
5962}
5963
1da177e4
LT
5964/*---------------------------------------------------------------------
5965 *
47b5d69c 5966 * Function: FPT_sciso
1da177e4
LT
5967 *
5968 * Description: Transfer the Identification string.
5969 *
5970 *---------------------------------------------------------------------*/
5971
391e2f25 5972static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
1da177e4 5973{
5c04a7b8 5974 unsigned char ret_data, the_data, byte_cnt, bit_cnt;
1da177e4 5975
5c04a7b8 5976 the_data = 0;
1da177e4 5977
5c04a7b8 5978 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
1da177e4 5979
5c04a7b8 5980 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
1da177e4 5981
5c04a7b8 5982 ret_data = FPT_scxferc(p_port, 0);
1da177e4 5983
5c04a7b8 5984 if (ret_data & 0xFC)
5c1b85e2 5985 return 0xFF;
1da177e4 5986
5c04a7b8 5987 else {
1da177e4 5988
5c04a7b8
AD
5989 the_data <<= 1;
5990 if (ret_data & BIT(1)) {
5991 the_data |= 1;
5992 }
5993 }
1da177e4 5994
5c04a7b8 5995 if ((ret_data & 0x1F) == 0) {
1da177e4
LT
5996/*
5997 if(bit_cnt != 0 || bit_cnt != 8)
5998 {
5999 byte_cnt = 0;
6000 bit_cnt = 0;
47b5d69c
JB
6001 FPT_scxferc(p_port, SYNC_PTRN);
6002 FPT_scxferc(p_port, ASSIGN_ID);
1da177e4
LT
6003 continue;
6004 }
6005*/
5c04a7b8 6006 if (byte_cnt)
5c1b85e2 6007 return 0x00;
5c04a7b8 6008 else
5c1b85e2 6009 return 0xFF;
5c04a7b8 6010 }
1da177e4 6011
5c04a7b8 6012 } /*bit loop */
1da177e4 6013
5c04a7b8 6014 p_id_string[byte_cnt] = the_data;
1da177e4 6015
5c04a7b8 6016 } /*byte loop */
1da177e4 6017
5c1b85e2 6018 return 0;
1da177e4
LT
6019}
6020
1da177e4
LT
6021/*---------------------------------------------------------------------
6022 *
47b5d69c 6023 * Function: FPT_scwirod
1da177e4
LT
6024 *
6025 * Description: Sample the SCSI data bus making sure the signal has been
6026 * deasserted for the correct number of consecutive samples.
6027 *
6028 *---------------------------------------------------------------------*/
6029
391e2f25 6030static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
1da177e4 6031{
5c04a7b8 6032 unsigned char i;
1da177e4 6033
5c04a7b8
AD
6034 i = 0;
6035 while (i < MAX_SCSI_TAR) {
1da177e4 6036
5c04a7b8 6037 if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
1da177e4 6038
5c04a7b8 6039 i = 0;
1da177e4 6040
5c04a7b8 6041 else
1da177e4 6042
5c04a7b8 6043 i++;
1da177e4 6044
5c04a7b8 6045 }
1da177e4
LT
6046}
6047
1da177e4
LT
6048/*---------------------------------------------------------------------
6049 *
47b5d69c 6050 * Function: FPT_scwiros
1da177e4
LT
6051 *
6052 * Description: Sample the SCSI Signal lines making sure the signal has been
6053 * deasserted for the correct number of consecutive samples.
6054 *
6055 *---------------------------------------------------------------------*/
6056
391e2f25 6057static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
1da177e4 6058{
5c04a7b8 6059 unsigned char i;
1da177e4 6060
5c04a7b8
AD
6061 i = 0;
6062 while (i < MAX_SCSI_TAR) {
1da177e4 6063
5c04a7b8 6064 if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
1da177e4 6065
5c04a7b8 6066 i = 0;
1da177e4 6067
5c04a7b8 6068 else
1da177e4 6069
5c04a7b8 6070 i++;
1da177e4 6071
5c04a7b8 6072 }
47b5d69c 6073}
1da177e4 6074
47b5d69c
JB
6075/*---------------------------------------------------------------------
6076 *
6077 * Function: FPT_scvalq
6078 *
6079 * Description: Make sure we received a valid data byte.
6080 *
6081 *---------------------------------------------------------------------*/
1da177e4 6082
db038cf8 6083static unsigned char FPT_scvalq(unsigned char p_quintet)
47b5d69c 6084{
5c04a7b8 6085 unsigned char count;
1da177e4 6086
5c04a7b8
AD
6087 for (count = 1; count < 0x08; count <<= 1) {
6088 if (!(p_quintet & count))
6089 p_quintet -= 0x80;
6090 }
47b5d69c 6091
5c04a7b8 6092 if (p_quintet & 0x18)
5c1b85e2 6093 return 0;
47b5d69c 6094
5c04a7b8 6095 else
5c1b85e2 6096 return 1;
1da177e4
LT
6097}
6098
1da177e4
LT
6099/*---------------------------------------------------------------------
6100 *
47b5d69c 6101 * Function: FPT_scsell
1da177e4
LT
6102 *
6103 * Description: Select the specified device ID using a selection timeout
47b5d69c
JB
6104 * less than 4ms. If somebody responds then it is a legacy
6105 * drive and this ID must be marked as such.
1da177e4
LT
6106 *
6107 *---------------------------------------------------------------------*/
6108
391e2f25 6109static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
1da177e4 6110{
5c04a7b8 6111 unsigned long i;
1da177e4 6112
5c04a7b8
AD
6113 WR_HARPOON(p_port + hp_page_ctrl,
6114 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
1da177e4 6115
5c04a7b8 6116 ARAM_ACCESS(p_port);
1da177e4 6117
5c04a7b8
AD
6118 WR_HARPOON(p_port + hp_addstat,
6119 (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6120 WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
1da177e4 6121
5c04a7b8
AD
6122 for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6123 WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6124 }
6125 WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
1da177e4 6126
5c04a7b8
AD
6127 WRW_HARPOON((p_port + hp_intstat),
6128 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
1da177e4 6129
5c04a7b8 6130 WR_HARPOON(p_port + hp_select_id, targ_id);
1da177e4 6131
5c04a7b8
AD
6132 WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6133 WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6134 WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
1da177e4 6135
5c04a7b8
AD
6136 while (!(RDW_HARPOON((p_port + hp_intstat)) &
6137 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6138 }
1da177e4 6139
5c04a7b8
AD
6140 if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6141 FPT_Wait(p_port, TO_250ms);
1da177e4 6142
5c04a7b8 6143 DISABLE_AUTO(p_port);
1da177e4 6144
5c04a7b8
AD
6145 WR_HARPOON(p_port + hp_addstat,
6146 (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6147 WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
1da177e4 6148
5c04a7b8 6149 SGRAM_ACCESS(p_port);
1da177e4 6150
5c04a7b8 6151 if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
1da177e4 6152
5c04a7b8
AD
6153 WRW_HARPOON((p_port + hp_intstat),
6154 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
1da177e4 6155
5c04a7b8
AD
6156 WR_HARPOON(p_port + hp_page_ctrl,
6157 (RD_HARPOON(p_port + hp_page_ctrl) &
6158 ~G_INT_DISABLE));
1da177e4 6159
5c1b85e2 6160 return 0; /*No legacy device */
5c04a7b8 6161 }
1da177e4 6162
5c04a7b8 6163 else {
1da177e4 6164
5c04a7b8
AD
6165 while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6166 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6167 WR_HARPOON(p_port + hp_scsisig,
6168 (SCSI_ACK + S_ILL_PH));
6169 ACCEPT_MSG(p_port);
6170 }
1da177e4
LT
6171 }
6172
5c04a7b8 6173 WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
1da177e4 6174
5c04a7b8
AD
6175 WR_HARPOON(p_port + hp_page_ctrl,
6176 (RD_HARPOON(p_port + hp_page_ctrl) &
6177 ~G_INT_DISABLE));
1da177e4 6178
5c1b85e2 6179 return 1; /*Found one of them oldies! */
5c04a7b8 6180 }
1da177e4 6181}
1da177e4
LT
6182
6183/*---------------------------------------------------------------------
6184 *
47b5d69c 6185 * Function: FPT_scwtsel
1da177e4
LT
6186 *
6187 * Description: Wait to be selected by another SCAM initiator.
6188 *
6189 *---------------------------------------------------------------------*/
6190
391e2f25 6191static void FPT_scwtsel(u32 p_port)
1da177e4 6192{
5c04a7b8
AD
6193 while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6194 }
1da177e4
LT
6195}
6196
1da177e4
LT
6197/*---------------------------------------------------------------------
6198 *
47b5d69c 6199 * Function: FPT_inisci
1da177e4
LT
6200 *
6201 * Description: Setup the data Structure with the info from the EEPROM.
6202 *
6203 *---------------------------------------------------------------------*/
6204
391e2f25 6205static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
1da177e4 6206{
5c04a7b8
AD
6207 unsigned char i, k, max_id;
6208 unsigned short ee_data;
6209 struct nvram_info *pCurrNvRam;
1da177e4 6210
47b5d69c 6211 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4 6212
5c04a7b8
AD
6213 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6214 max_id = 0x08;
1da177e4 6215
5c04a7b8
AD
6216 else
6217 max_id = 0x10;
1da177e4 6218
5c04a7b8
AD
6219 if (pCurrNvRam) {
6220 for (i = 0; i < max_id; i++) {
1da177e4 6221
5c04a7b8
AD
6222 for (k = 0; k < 4; k++)
6223 FPT_scamInfo[i].id_string[k] =
6224 pCurrNvRam->niScamTbl[i][k];
6225 for (k = 4; k < ID_STRING_LENGTH; k++)
6226 FPT_scamInfo[i].id_string[k] =
6227 (unsigned char)0x00;
1da177e4 6228
5c04a7b8
AD
6229 if (FPT_scamInfo[i].id_string[0] == 0x00)
6230 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6231 else
6232 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6233
6234 }
5c04a7b8
AD
6235 } else {
6236 for (i = 0; i < max_id; i++) {
6237 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6238 ee_data =
6239 FPT_utilEERead(p_port,
6240 (unsigned
6241 short)((EE_SCAMBASE / 2) +
6242 (unsigned short)(i *
6243 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6244 FPT_scamInfo[i].id_string[k] =
6245 (unsigned char)ee_data;
6246 ee_data >>= 8;
6247 FPT_scamInfo[i].id_string[k + 1] =
6248 (unsigned char)ee_data;
6249 }
1da177e4 6250
5c04a7b8
AD
6251 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6252 (FPT_scamInfo[i].id_string[0] == 0xFF))
1da177e4 6253
5c04a7b8 6254 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4 6255
5c04a7b8
AD
6256 else
6257 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4 6258
5c04a7b8 6259 }
1da177e4 6260 }
5c04a7b8 6261 for (k = 0; k < ID_STRING_LENGTH; k++)
47b5d69c 6262 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
1da177e4
LT
6263
6264}
6265
6266/*---------------------------------------------------------------------
6267 *
47b5d69c 6268 * Function: FPT_scmachid
1da177e4
LT
6269 *
6270 * Description: Match the Device ID string with our values stored in
6271 * the EEPROM.
6272 *
6273 *---------------------------------------------------------------------*/
6274
5c04a7b8
AD
6275static unsigned char FPT_scmachid(unsigned char p_card,
6276 unsigned char p_id_string[])
1da177e4
LT
6277{
6278
5c04a7b8 6279 unsigned char i, k, match;
1da177e4 6280
5c04a7b8 6281 for (i = 0; i < MAX_SCSI_TAR; i++) {
1da177e4 6282
5c04a7b8 6283 match = 1;
1da177e4 6284
5c04a7b8
AD
6285 for (k = 0; k < ID_STRING_LENGTH; k++) {
6286 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6287 match = 0;
6288 }
1da177e4 6289
5c04a7b8
AD
6290 if (match) {
6291 FPT_scamInfo[i].state = ID_ASSIGNED;
5c1b85e2 6292 return i;
5c04a7b8 6293 }
1da177e4 6294
5c04a7b8 6295 }
1da177e4 6296
5c04a7b8
AD
6297 if (p_id_string[0] & BIT(5))
6298 i = 8;
6299 else
6300 i = MAX_SCSI_TAR;
1da177e4 6301
5c04a7b8
AD
6302 if (((p_id_string[0] & 0x06) == 0x02)
6303 || ((p_id_string[0] & 0x06) == 0x04))
6304 match = p_id_string[1] & (unsigned char)0x1F;
6305 else
6306 match = 7;
1da177e4 6307
5c04a7b8
AD
6308 while (i > 0) {
6309 i--;
1da177e4 6310
5c04a7b8
AD
6311 if (FPT_scamInfo[match].state == ID_UNUSED) {
6312 for (k = 0; k < ID_STRING_LENGTH; k++) {
6313 FPT_scamInfo[match].id_string[k] =
6314 p_id_string[k];
6315 }
1da177e4 6316
5c04a7b8 6317 FPT_scamInfo[match].state = ID_ASSIGNED;
1da177e4 6318
5c04a7b8
AD
6319 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6320 FPT_BL_Card[p_card].globalFlags |=
6321 F_UPDATE_EEPROM;
5c1b85e2 6322 return match;
1da177e4 6323
5c04a7b8 6324 }
1da177e4 6325
5c04a7b8 6326 match--;
1da177e4 6327
5c04a7b8
AD
6328 if (match == 0xFF) {
6329 if (p_id_string[0] & BIT(5))
6330 match = 7;
6331 else
6332 match = MAX_SCSI_TAR - 1;
6333 }
1da177e4 6334 }
1da177e4 6335
5c04a7b8 6336 if (p_id_string[0] & BIT(7)) {
5c1b85e2 6337 return CLR_PRIORITY;
5c04a7b8 6338 }
1da177e4 6339
5c04a7b8
AD
6340 if (p_id_string[0] & BIT(5))
6341 i = 8;
6342 else
6343 i = MAX_SCSI_TAR;
1da177e4 6344
5c04a7b8
AD
6345 if (((p_id_string[0] & 0x06) == 0x02)
6346 || ((p_id_string[0] & 0x06) == 0x04))
6347 match = p_id_string[1] & (unsigned char)0x1F;
6348 else
6349 match = 7;
1da177e4 6350
5c04a7b8 6351 while (i > 0) {
1da177e4 6352
5c04a7b8 6353 i--;
1da177e4 6354
5c04a7b8
AD
6355 if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6356 for (k = 0; k < ID_STRING_LENGTH; k++) {
6357 FPT_scamInfo[match].id_string[k] =
6358 p_id_string[k];
6359 }
1da177e4 6360
5c04a7b8
AD
6361 FPT_scamInfo[match].id_string[0] |= BIT(7);
6362 FPT_scamInfo[match].state = ID_ASSIGNED;
6363 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6364 FPT_BL_Card[p_card].globalFlags |=
6365 F_UPDATE_EEPROM;
5c1b85e2 6366 return match;
1da177e4 6367
5c04a7b8 6368 }
1da177e4 6369
5c04a7b8 6370 match--;
1da177e4 6371
5c04a7b8
AD
6372 if (match == 0xFF) {
6373 if (p_id_string[0] & BIT(5))
6374 match = 7;
6375 else
6376 match = MAX_SCSI_TAR - 1;
6377 }
1da177e4 6378 }
1da177e4 6379
5c1b85e2 6380 return NO_ID_AVAIL;
1da177e4
LT
6381}
6382
1da177e4
LT
6383/*---------------------------------------------------------------------
6384 *
47b5d69c 6385 * Function: FPT_scsavdi
1da177e4
LT
6386 *
6387 * Description: Save off the device SCAM ID strings.
6388 *
6389 *---------------------------------------------------------------------*/
6390
391e2f25 6391static void FPT_scsavdi(unsigned char p_card, u32 p_port)
1da177e4 6392{
5c04a7b8
AD
6393 unsigned char i, k, max_id;
6394 unsigned short ee_data, sum_data;
1da177e4 6395
5c04a7b8 6396 sum_data = 0x0000;
1da177e4 6397
5c04a7b8
AD
6398 for (i = 1; i < EE_SCAMBASE / 2; i++) {
6399 sum_data += FPT_utilEERead(p_port, i);
6400 }
1da177e4 6401
5c04a7b8 6402 FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
1da177e4 6403
5c04a7b8
AD
6404 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6405 max_id = 0x08;
1da177e4 6406
5c04a7b8
AD
6407 else
6408 max_id = 0x10;
6409
6410 for (i = 0; i < max_id; i++) {
6411
6412 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6413 ee_data = FPT_scamInfo[i].id_string[k + 1];
6414 ee_data <<= 8;
6415 ee_data |= FPT_scamInfo[i].id_string[k];
6416 sum_data += ee_data;
6417 FPT_utilEEWrite(p_port, ee_data,
6418 (unsigned short)((EE_SCAMBASE / 2) +
6419 (unsigned short)(i *
6420 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6421 }
6422 }
1da177e4 6423
5c04a7b8
AD
6424 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6425 FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
1da177e4 6426}
1da177e4
LT
6427
6428/*---------------------------------------------------------------------
6429 *
47b5d69c 6430 * Function: FPT_XbowInit
1da177e4
LT
6431 *
6432 * Description: Setup the Xbow for normal operation.
6433 *
6434 *---------------------------------------------------------------------*/
6435
391e2f25 6436static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
1da177e4 6437{
5c04a7b8 6438 unsigned char i;
1da177e4 6439
5c04a7b8
AD
6440 i = RD_HARPOON(port + hp_page_ctrl);
6441 WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
1da177e4 6442
5c04a7b8
AD
6443 WR_HARPOON(port + hp_scsireset, 0x00);
6444 WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
1da177e4 6445
5c04a7b8
AD
6446 WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6447 FIFO_CLR));
1da177e4 6448
5c04a7b8 6449 WR_HARPOON(port + hp_scsireset, SCSI_INI);
1da177e4 6450
5c04a7b8 6451 WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
1da177e4 6452
5c04a7b8
AD
6453 WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
6454 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
1da177e4 6455
5c04a7b8 6456 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
1da177e4 6457
5c04a7b8
AD
6458 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6459 BUS_FREE | XFER_CNT_0 | AUTO_INT;
1da177e4 6460
5c04a7b8 6461 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
47b5d69c 6462 FPT_default_intena |= SCAM_SEL;
1da177e4 6463
5c04a7b8 6464 WRW_HARPOON((port + hp_intena), FPT_default_intena);
1da177e4 6465
5c04a7b8 6466 WR_HARPOON(port + hp_seltimeout, TO_290ms);
1da177e4 6467
5c04a7b8
AD
6468 /* Turn on SCSI_MODE8 for narrow cards to fix the
6469 strapping issue with the DUAL CHANNEL card */
6470 if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6471 WR_HARPOON(port + hp_addstat, SCSI_MODE8);
1da177e4 6472
5c04a7b8 6473 WR_HARPOON(port + hp_page_ctrl, i);
1da177e4
LT
6474
6475}
6476
1da177e4
LT
6477/*---------------------------------------------------------------------
6478 *
47b5d69c 6479 * Function: FPT_BusMasterInit
1da177e4
LT
6480 *
6481 * Description: Initialize the BusMaster for normal operations.
6482 *
6483 *---------------------------------------------------------------------*/
6484
391e2f25 6485static void FPT_BusMasterInit(u32 p_port)
1da177e4
LT
6486{
6487
5c04a7b8
AD
6488 WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6489 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
1da177e4 6490
5c04a7b8 6491 WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
1da177e4 6492
5c04a7b8 6493 WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
1da177e4 6494
5c04a7b8 6495 WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
1da177e4 6496
5c04a7b8
AD
6497 RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6498 WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6499 WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6500 ~SCATTER_EN));
1da177e4
LT
6501}
6502
1da177e4
LT
6503/*---------------------------------------------------------------------
6504 *
47b5d69c 6505 * Function: FPT_DiagEEPROM
1da177e4
LT
6506 *
6507 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6508 * necessary.
6509 *
6510 *---------------------------------------------------------------------*/
6511
391e2f25 6512static void FPT_DiagEEPROM(u32 p_port)
1da177e4 6513{
5c04a7b8 6514 unsigned short index, temp, max_wd_cnt;
1da177e4 6515
5c04a7b8
AD
6516 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6517 max_wd_cnt = EEPROM_WD_CNT;
6518 else
6519 max_wd_cnt = EEPROM_WD_CNT * 2;
1da177e4 6520
5c04a7b8 6521 temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
1da177e4 6522
5c04a7b8 6523 if (temp == 0x4641) {
1da177e4 6524
5c04a7b8 6525 for (index = 2; index < max_wd_cnt; index++) {
1da177e4 6526
5c04a7b8 6527 temp += FPT_utilEERead(p_port, index);
1da177e4 6528
5c04a7b8 6529 }
1da177e4 6530
5c04a7b8 6531 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
1da177e4 6532
5c04a7b8
AD
6533 return; /*EEPROM is Okay so return now! */
6534 }
6535 }
1da177e4 6536
5c04a7b8 6537 FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
1da177e4 6538
5c04a7b8 6539 for (index = 0; index < max_wd_cnt; index++) {
1da177e4 6540
5c04a7b8
AD
6541 FPT_utilEEWrite(p_port, 0x0000, index);
6542 }
1da177e4 6543
5c04a7b8
AD
6544 temp = 0;
6545
6546 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6547 temp += 0x4641;
6548 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6549 temp += 0x3920;
6550 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6551 temp += 0x3033;
6552 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6553 temp += 0x2020;
6554 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6555 temp += 0x70D3;
6556 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6557 temp += 0x0010;
6558 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6559 temp += 0x0003;
6560 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6561 temp += 0x0007;
6562
6563 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6564 temp += 0x0000;
6565 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6566 temp += 0x0000;
6567 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6568 temp += 0x0000;
6569
6570 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6571 temp += 0x4242;
6572 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6573 temp += 0x4242;
6574 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6575 temp += 0x4242;
6576 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6577 temp += 0x4242;
6578 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6579 temp += 0x4242;
6580 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6581 temp += 0x4242;
6582 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6583 temp += 0x4242;
6584 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6585 temp += 0x4242;
6586
6587 FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
6588 temp += 0x6C46;
6589 FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
6590 temp += 0x7361;
6591 FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6592 temp += 0x5068;
6593 FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6594 temp += 0x696F;
6595 FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6596 temp += 0x746E;
6597 FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6598 temp += 0x4C20;
6599 FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6600 temp += 0x2054;
6601 FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6602 temp += 0x2020;
6603
6604 index = ((EE_SCAMBASE / 2) + (7 * 16));
6605 FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6606 temp += (0x0700 + TYPE_CODE0);
6607 index++;
6608 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6609 temp += 0x5542; /* BUSLOGIC */
6610 index++;
6611 FPT_utilEEWrite(p_port, 0x4C53, index);
6612 temp += 0x4C53;
6613 index++;
6614 FPT_utilEEWrite(p_port, 0x474F, index);
6615 temp += 0x474F;
6616 index++;
6617 FPT_utilEEWrite(p_port, 0x4349, index);
6618 temp += 0x4349;
6619 index++;
6620 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6621 temp += 0x5442; /* BT- 930 */
6622 index++;
6623 FPT_utilEEWrite(p_port, 0x202D, index);
6624 temp += 0x202D;
6625 index++;
6626 FPT_utilEEWrite(p_port, 0x3339, index);
6627 temp += 0x3339;
6628 index++; /*Serial # */
6629 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6630 temp += 0x2030;
6631 index++;
6632 FPT_utilEEWrite(p_port, 0x5453, index);
6633 temp += 0x5453;
6634 index++;
6635 FPT_utilEEWrite(p_port, 0x5645, index);
6636 temp += 0x5645;
6637 index++;
6638 FPT_utilEEWrite(p_port, 0x2045, index);
6639 temp += 0x2045;
6640 index++;
6641 FPT_utilEEWrite(p_port, 0x202F, index);
6642 temp += 0x202F;
6643 index++;
6644 FPT_utilEEWrite(p_port, 0x4F4A, index);
6645 temp += 0x4F4A;
6646 index++;
6647 FPT_utilEEWrite(p_port, 0x204E, index);
6648 temp += 0x204E;
6649 index++;
6650 FPT_utilEEWrite(p_port, 0x3539, index);
6651 temp += 0x3539;
6652
6653 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6654
6655 FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
1da177e4
LT
6656
6657}
6658
1da177e4
LT
6659/*---------------------------------------------------------------------
6660 *
6661 * Function: Queue Search Select
6662 *
6663 * Description: Try to find a new command to execute.
6664 *
6665 *---------------------------------------------------------------------*/
6666
5c04a7b8
AD
6667static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6668 unsigned char p_card)
1da177e4 6669{
5c04a7b8
AD
6670 unsigned char scan_ptr, lun;
6671 struct sccb_mgr_tar_info *currTar_Info;
6672 struct sccb *pOldSccb;
1da177e4 6673
5c04a7b8
AD
6674 scan_ptr = pCurrCard->scanIndex;
6675 do {
47b5d69c 6676 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
5c04a7b8
AD
6677 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6678 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6679 TAG_Q_TRYING)) {
6680 if (currTar_Info->TarSelQ_Cnt != 0) {
1da177e4
LT
6681
6682 scan_ptr++;
6683 if (scan_ptr == MAX_SCSI_TAR)
6684 scan_ptr = 0;
1da177e4 6685
5c04a7b8
AD
6686 for (lun = 0; lun < MAX_LUN; lun++) {
6687 if (currTar_Info->TarLUNBusy[lun] == 0) {
6688
6689 pCurrCard->currentSCCB =
6690 currTar_Info->TarSelQ_Head;
1da177e4
LT
6691 pOldSccb = NULL;
6692
5c04a7b8
AD
6693 while ((pCurrCard->
6694 currentSCCB != NULL)
6695 && (lun !=
6696 pCurrCard->
6697 currentSCCB->Lun)) {
6698 pOldSccb =
6699 pCurrCard->
6700 currentSCCB;
6701 pCurrCard->currentSCCB =
6702 (struct sccb
6703 *)(pCurrCard->
6704 currentSCCB)->
6705 Sccb_forwardlink;
1da177e4 6706 }
5c04a7b8
AD
6707 if (pCurrCard->currentSCCB ==
6708 NULL)
1da177e4 6709 continue;
5c04a7b8
AD
6710 if (pOldSccb != NULL) {
6711 pOldSccb->
6712 Sccb_forwardlink =
6713 (struct sccb
6714 *)(pCurrCard->
6715 currentSCCB)->
6716 Sccb_forwardlink;
6717 pOldSccb->
6718 Sccb_backlink =
6719 (struct sccb
6720 *)(pCurrCard->
6721 currentSCCB)->
6722 Sccb_backlink;
6723 currTar_Info->
6724 TarSelQ_Cnt--;
6725 } else {
6726 currTar_Info->
6727 TarSelQ_Head =
6728 (struct sccb
6729 *)(pCurrCard->
6730 currentSCCB)->
6731 Sccb_forwardlink;
6732
6733 if (currTar_Info->
6734 TarSelQ_Head ==
6735 NULL) {
6736 currTar_Info->
6737 TarSelQ_Tail
6738 = NULL;
6739 currTar_Info->
6740 TarSelQ_Cnt
6741 = 0;
6742 } else {
6743 currTar_Info->
6744 TarSelQ_Cnt--;
6745 currTar_Info->
6746 TarSelQ_Head->
6747 Sccb_backlink
6748 =
6749 (struct sccb
6750 *)NULL;
1da177e4
LT
6751 }
6752 }
5c04a7b8 6753 pCurrCard->scanIndex = scan_ptr;
1da177e4 6754
5c04a7b8
AD
6755 pCurrCard->globalFlags |=
6756 F_NEW_SCCB_CMD;
1da177e4 6757
5c04a7b8 6758 break;
1da177e4
LT
6759 }
6760 }
6761 }
6762
5c04a7b8 6763 else {
1da177e4
LT
6764 scan_ptr++;
6765 if (scan_ptr == MAX_SCSI_TAR) {
6766 scan_ptr = 0;
6767 }
6768 }
6769
5c04a7b8 6770 } else {
1da177e4 6771 if ((currTar_Info->TarSelQ_Cnt != 0) &&
5c04a7b8 6772 (currTar_Info->TarLUNBusy[0] == 0)) {
1da177e4 6773
5c04a7b8
AD
6774 pCurrCard->currentSCCB =
6775 currTar_Info->TarSelQ_Head;
1da177e4 6776
5c04a7b8
AD
6777 currTar_Info->TarSelQ_Head =
6778 (struct sccb *)(pCurrCard->currentSCCB)->
6779 Sccb_forwardlink;
1da177e4 6780
5c04a7b8 6781 if (currTar_Info->TarSelQ_Head == NULL) {
1da177e4
LT
6782 currTar_Info->TarSelQ_Tail = NULL;
6783 currTar_Info->TarSelQ_Cnt = 0;
5c04a7b8 6784 } else {
1da177e4 6785 currTar_Info->TarSelQ_Cnt--;
5c04a7b8
AD
6786 currTar_Info->TarSelQ_Head->
6787 Sccb_backlink = (struct sccb *)NULL;
1da177e4
LT
6788 }
6789
6790 scan_ptr++;
6791 if (scan_ptr == MAX_SCSI_TAR)
6792 scan_ptr = 0;
6793
6794 pCurrCard->scanIndex = scan_ptr;
6795
6796 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6797
6798 break;
6799 }
6800
5c04a7b8 6801 else {
1da177e4 6802 scan_ptr++;
5c04a7b8 6803 if (scan_ptr == MAX_SCSI_TAR) {
1da177e4
LT
6804 scan_ptr = 0;
6805 }
6806 }
6807 }
6808 } while (scan_ptr != pCurrCard->scanIndex);
6809}
6810
1da177e4
LT
6811/*---------------------------------------------------------------------
6812 *
6813 * Function: Queue Select Fail
6814 *
6815 * Description: Add the current SCCB to the head of the Queue.
6816 *
6817 *---------------------------------------------------------------------*/
6818
5c04a7b8
AD
6819static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6820 unsigned char p_card)
1da177e4 6821{
5c04a7b8
AD
6822 unsigned char thisTarg;
6823 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 6824
5c04a7b8
AD
6825 if (pCurrCard->currentSCCB != NULL) {
6826 thisTarg =
6827 (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6828 TargID);
6829 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4 6830
5c04a7b8 6831 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
1da177e4 6832
5c04a7b8
AD
6833 pCurrCard->currentSCCB->Sccb_forwardlink =
6834 currTar_Info->TarSelQ_Head;
1da177e4 6835
5c04a7b8
AD
6836 if (currTar_Info->TarSelQ_Cnt == 0) {
6837 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6838 }
1da177e4 6839
5c04a7b8
AD
6840 else {
6841 currTar_Info->TarSelQ_Head->Sccb_backlink =
6842 pCurrCard->currentSCCB;
6843 }
1da177e4 6844
5c04a7b8 6845 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
1da177e4 6846
5c04a7b8
AD
6847 pCurrCard->currentSCCB = NULL;
6848 currTar_Info->TarSelQ_Cnt++;
6849 }
1da177e4 6850}
5c04a7b8 6851
1da177e4
LT
6852/*---------------------------------------------------------------------
6853 *
6854 * Function: Queue Command Complete
6855 *
6856 * Description: Call the callback function with the current SCCB.
6857 *
6858 *---------------------------------------------------------------------*/
6859
5c04a7b8
AD
6860static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6861 struct sccb *p_sccb, unsigned char p_card)
1da177e4
LT
6862{
6863
5c04a7b8
AD
6864 unsigned char i, SCSIcmd;
6865 CALL_BK_FN callback;
6866 struct sccb_mgr_tar_info *currTar_Info;
6867
6868 SCSIcmd = p_sccb->Cdb[0];
6869
6870 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6871
6872 if ((p_sccb->
6873 ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6874 && (p_sccb->HostStatus == SCCB_COMPLETE)
6875 && (p_sccb->TargetStatus != SSCHECK))
6876
6877 if ((SCSIcmd == SCSI_READ) ||
6878 (SCSIcmd == SCSI_WRITE) ||
6879 (SCSIcmd == SCSI_READ_EXTENDED) ||
6880 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
6881 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
6882 (SCSIcmd == SCSI_START_STOP_UNIT) ||
6883 (pCurrCard->globalFlags & F_NO_FILTER)
6884 )
6885 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6886 }
1da177e4 6887
5c04a7b8
AD
6888 if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6889 if (p_sccb->HostStatus || p_sccb->TargetStatus)
6890 p_sccb->SccbStatus = SCCB_ERROR;
6891 else
6892 p_sccb->SccbStatus = SCCB_SUCCESS;
1da177e4
LT
6893 }
6894
5c04a7b8 6895 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
1da177e4 6896
5c04a7b8
AD
6897 p_sccb->CdbLength = p_sccb->Save_CdbLen;
6898 for (i = 0; i < 6; i++) {
6899 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6900 }
6901 }
1da177e4 6902
5c04a7b8
AD
6903 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6904 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
1da177e4 6905
5c04a7b8
AD
6906 FPT_utilUpdateResidual(p_sccb);
6907 }
1da177e4 6908
5c04a7b8
AD
6909 pCurrCard->cmdCounter--;
6910 if (!pCurrCard->cmdCounter) {
1da177e4 6911
5c04a7b8
AD
6912 if (pCurrCard->globalFlags & F_GREEN_PC) {
6913 WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6914 (PWR_DWN | CLKCTRL_DEFAULT));
6915 WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6916 }
1da177e4 6917
5c04a7b8
AD
6918 WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6919 (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6920 ~SCCB_MGR_ACTIVE));
1da177e4 6921
5c04a7b8 6922 }
1da177e4 6923
5c04a7b8
AD
6924 if (pCurrCard->discQCount != 0) {
6925 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6926 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6927 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6928 TAG_Q_TRYING))) {
1da177e4 6929 pCurrCard->discQCount--;
5c04a7b8
AD
6930 pCurrCard->discQ_Tbl[currTar_Info->
6931 LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6932 } else {
6933 if (p_sccb->Sccb_tag) {
1da177e4
LT
6934 pCurrCard->discQCount--;
6935 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
5c04a7b8 6936 } else {
1da177e4 6937 pCurrCard->discQCount--;
5c04a7b8
AD
6938 pCurrCard->discQ_Tbl[currTar_Info->
6939 LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
6940 }
6941 }
6942
6943 }
6944
5c04a7b8
AD
6945 callback = (CALL_BK_FN) p_sccb->SccbCallback;
6946 callback(p_sccb);
6947 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6948 pCurrCard->currentSCCB = NULL;
1da177e4 6949}
1da177e4 6950
1da177e4
LT
6951/*---------------------------------------------------------------------
6952 *
6953 * Function: Queue Disconnect
6954 *
6955 * Description: Add SCCB to our disconnect array.
6956 *
6957 *---------------------------------------------------------------------*/
5c04a7b8 6958static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
1da177e4 6959{
5c04a7b8 6960 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 6961
47b5d69c 6962 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4 6963
5c04a7b8
AD
6964 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6965 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6966 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6967 LunDiscQ_Idx[p_sccb->Lun]] =
6968 p_sccb;
6969 } else {
6970 if (p_sccb->Sccb_tag) {
6971 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6972 p_sccb;
6973 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6974 0;
47b5d69c 6975 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
5c04a7b8
AD
6976 } else {
6977 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6978 LunDiscQ_Idx[0]] = p_sccb;
1da177e4
LT
6979 }
6980 }
47b5d69c 6981 FPT_BL_Card[p_card].currentSCCB = NULL;
1da177e4
LT
6982}
6983
1da177e4
LT
6984/*---------------------------------------------------------------------
6985 *
6986 * Function: Queue Flush SCCB
6987 *
6988 * Description: Flush all SCCB's back to the host driver for this target.
6989 *
6990 *---------------------------------------------------------------------*/
6991
5c04a7b8 6992static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
1da177e4 6993{
5c04a7b8
AD
6994 unsigned char qtag, thisTarg;
6995 struct sccb *currSCCB;
6996 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 6997
5c04a7b8
AD
6998 currSCCB = FPT_BL_Card[p_card].currentSCCB;
6999 if (currSCCB != NULL) {
7000 thisTarg = (unsigned char)currSCCB->TargID;
7001 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7002
7003 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
1da177e4 7004
5c04a7b8
AD
7005 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7006 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
7007 thisTarg)) {
1da177e4 7008
5c04a7b8
AD
7009 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
7010 HostStatus = (unsigned char)error_code;
1da177e4 7011
5c04a7b8
AD
7012 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7013 FPT_BL_Card[p_card].
7014 discQ_Tbl[qtag], p_card);
1da177e4 7015
5c04a7b8
AD
7016 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7017 currTar_Info->TarTagQ_Cnt--;
1da177e4 7018
5c04a7b8
AD
7019 }
7020 }
1da177e4
LT
7021 }
7022
7023}
7024
7025/*---------------------------------------------------------------------
7026 *
7027 * Function: Queue Flush Target SCCB
7028 *
7029 * Description: Flush all SCCB's back to the host driver for this target.
7030 *
7031 *---------------------------------------------------------------------*/
7032
5c04a7b8
AD
7033static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7034 unsigned char error_code)
1da177e4 7035{
5c04a7b8
AD
7036 unsigned char qtag;
7037 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 7038
5c04a7b8 7039 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4 7040
5c04a7b8 7041 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
1da177e4 7042
5c04a7b8
AD
7043 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7044 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
1da177e4 7045
5c04a7b8
AD
7046 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7047 (unsigned char)error_code;
1da177e4 7048
5c04a7b8
AD
7049 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7050 FPT_BL_Card[p_card].
7051 discQ_Tbl[qtag], p_card);
1da177e4 7052
5c04a7b8
AD
7053 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7054 currTar_Info->TarTagQ_Cnt--;
1da177e4 7055
5c04a7b8
AD
7056 }
7057 }
1da177e4
LT
7058
7059}
7060
5c04a7b8 7061static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
1da177e4 7062{
5c04a7b8
AD
7063 struct sccb_mgr_tar_info *currTar_Info;
7064 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4 7065
5c04a7b8 7066 p_SCCB->Sccb_forwardlink = NULL;
1da177e4 7067
5c04a7b8 7068 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
1da177e4 7069
5c04a7b8 7070 if (currTar_Info->TarSelQ_Cnt == 0) {
1da177e4 7071
5c04a7b8
AD
7072 currTar_Info->TarSelQ_Head = p_SCCB;
7073 }
1da177e4 7074
5c04a7b8 7075 else {
1da177e4 7076
5c04a7b8
AD
7077 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7078 }
1da177e4 7079
5c04a7b8
AD
7080 currTar_Info->TarSelQ_Tail = p_SCCB;
7081 currTar_Info->TarSelQ_Cnt++;
1da177e4
LT
7082}
7083
1da177e4
LT
7084/*---------------------------------------------------------------------
7085 *
7086 * Function: Queue Find SCCB
7087 *
7088 * Description: Search the target select Queue for this SCCB, and
7089 * remove it if found.
7090 *
7091 *---------------------------------------------------------------------*/
7092
5c04a7b8
AD
7093static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7094 unsigned char p_card)
1da177e4 7095{
5c04a7b8
AD
7096 struct sccb *q_ptr;
7097 struct sccb_mgr_tar_info *currTar_Info;
1da177e4 7098
5c04a7b8 7099 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4 7100
5c04a7b8 7101 q_ptr = currTar_Info->TarSelQ_Head;
1da177e4 7102
5c04a7b8 7103 while (q_ptr != NULL) {
1da177e4 7104
5c04a7b8 7105 if (q_ptr == p_SCCB) {
1da177e4 7106
5c04a7b8 7107 if (currTar_Info->TarSelQ_Head == q_ptr) {
1da177e4 7108
5c04a7b8
AD
7109 currTar_Info->TarSelQ_Head =
7110 q_ptr->Sccb_forwardlink;
1da177e4
LT
7111 }
7112
5c04a7b8 7113 if (currTar_Info->TarSelQ_Tail == q_ptr) {
1da177e4 7114
5c04a7b8
AD
7115 currTar_Info->TarSelQ_Tail =
7116 q_ptr->Sccb_backlink;
1da177e4
LT
7117 }
7118
5c04a7b8
AD
7119 if (q_ptr->Sccb_forwardlink != NULL) {
7120 q_ptr->Sccb_forwardlink->Sccb_backlink =
7121 q_ptr->Sccb_backlink;
1da177e4
LT
7122 }
7123
5c04a7b8
AD
7124 if (q_ptr->Sccb_backlink != NULL) {
7125 q_ptr->Sccb_backlink->Sccb_forwardlink =
7126 q_ptr->Sccb_forwardlink;
1da177e4
LT
7127 }
7128
5c04a7b8 7129 currTar_Info->TarSelQ_Cnt--;
1da177e4 7130
5c1b85e2 7131 return 1;
5c04a7b8 7132 }
1da177e4 7133
5c04a7b8
AD
7134 else {
7135 q_ptr = q_ptr->Sccb_forwardlink;
7136 }
7137 }
1da177e4 7138
5c1b85e2 7139 return 0;
1da177e4
LT
7140
7141}
7142
1da177e4
LT
7143/*---------------------------------------------------------------------
7144 *
7145 * Function: Utility Update Residual Count
7146 *
7147 * Description: Update the XferCnt to the remaining byte count.
7148 * If we transferred all the data then just write zero.
7149 * If Non-SG transfer then report Total Cnt - Actual Transfer
7150 * Cnt. For SG transfers add the count fields of all
7151 * remaining SG elements, as well as any partial remaining
7152 * element.
7153 *
7154 *---------------------------------------------------------------------*/
7155
5c04a7b8 7156static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
1da177e4 7157{
5c04a7b8
AD
7158 unsigned long partial_cnt;
7159 unsigned int sg_index;
391e2f25 7160 struct blogic_sg_seg *segp;
1da177e4 7161
5c04a7b8 7162 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
1da177e4 7163
5c04a7b8
AD
7164 p_SCCB->DataLength = 0x0000;
7165 }
1da177e4 7166
5c04a7b8 7167 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
1da177e4 7168
5c04a7b8 7169 partial_cnt = 0x0000;
1da177e4 7170
5c04a7b8 7171 sg_index = p_SCCB->Sccb_sgseg;
1da177e4 7172
1da177e4 7173
5c04a7b8 7174 if (p_SCCB->Sccb_SGoffset) {
1da177e4
LT
7175
7176 partial_cnt = p_SCCB->Sccb_SGoffset;
7177 sg_index++;
5c04a7b8 7178 }
1da177e4 7179
5c04a7b8
AD
7180 while (((unsigned long)sg_index *
7181 (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
391e2f25
KA
7182 segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7183 (sg_index * 2);
7184 partial_cnt += segp->segbytes;
1da177e4 7185 sg_index++;
5c04a7b8 7186 }
1da177e4 7187
5c04a7b8
AD
7188 p_SCCB->DataLength = partial_cnt;
7189 }
1da177e4 7190
5c04a7b8 7191 else {
1da177e4 7192
5c04a7b8
AD
7193 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7194 }
1da177e4
LT
7195}
7196
1da177e4
LT
7197/*---------------------------------------------------------------------
7198 *
7199 * Function: Wait 1 Second
7200 *
7201 * Description: Wait for 1 second.
7202 *
7203 *---------------------------------------------------------------------*/
7204
391e2f25 7205static void FPT_Wait1Second(u32 p_port)
1da177e4 7206{
5c04a7b8 7207 unsigned char i;
1da177e4 7208
5c04a7b8 7209 for (i = 0; i < 4; i++) {
1da177e4 7210
5c04a7b8 7211 FPT_Wait(p_port, TO_250ms);
1da177e4 7212
5c04a7b8
AD
7213 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7214 break;
1da177e4 7215
5c04a7b8
AD
7216 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7217 break;
7218 }
1da177e4
LT
7219}
7220
1da177e4
LT
7221/*---------------------------------------------------------------------
7222 *
47b5d69c 7223 * Function: FPT_Wait
1da177e4
LT
7224 *
7225 * Description: Wait the desired delay.
7226 *
7227 *---------------------------------------------------------------------*/
7228
391e2f25 7229static void FPT_Wait(u32 p_port, unsigned char p_delay)
1da177e4 7230{
5c04a7b8
AD
7231 unsigned char old_timer;
7232 unsigned char green_flag;
1da177e4 7233
5c04a7b8 7234 old_timer = RD_HARPOON(p_port + hp_seltimeout);
1da177e4 7235
5c04a7b8
AD
7236 green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7237 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
1da177e4 7238
5c04a7b8
AD
7239 WR_HARPOON(p_port + hp_seltimeout, p_delay);
7240 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7241 WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
1da177e4 7242
5c04a7b8
AD
7243 WR_HARPOON(p_port + hp_portctrl_0,
7244 (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
1da177e4 7245
5c04a7b8 7246 while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
1da177e4 7247
5c04a7b8
AD
7248 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7249 break;
1da177e4 7250
5c04a7b8
AD
7251 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7252 break;
7253 }
1da177e4 7254
5c04a7b8
AD
7255 WR_HARPOON(p_port + hp_portctrl_0,
7256 (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
1da177e4 7257
5c04a7b8
AD
7258 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7259 WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
1da177e4 7260
5c04a7b8 7261 WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
1da177e4 7262
5c04a7b8 7263 WR_HARPOON(p_port + hp_seltimeout, old_timer);
1da177e4
LT
7264}
7265
1da177e4
LT
7266/*---------------------------------------------------------------------
7267 *
7268 * Function: Enable/Disable Write to EEPROM
7269 *
7270 * Description: The EEPROM must first be enabled for writes
7271 * A total of 9 clocks are needed.
7272 *
7273 *---------------------------------------------------------------------*/
7274
391e2f25 7275static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
1da177e4 7276{
5c04a7b8 7277 unsigned char ee_value;
1da177e4 7278
5c04a7b8
AD
7279 ee_value =
7280 (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7281 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
1da177e4 7282
5c04a7b8 7283 if (p_mode)
1da177e4 7284
5c04a7b8 7285 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
1da177e4 7286
5c04a7b8 7287 else
1da177e4 7288
5c04a7b8 7289 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
1da177e4 7290
5c04a7b8
AD
7291 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7292 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
1da177e4
LT
7293}
7294
1da177e4
LT
7295/*---------------------------------------------------------------------
7296 *
7297 * Function: Write EEPROM
7298 *
7299 * Description: Write a word to the EEPROM at the specified
7300 * address.
7301 *
7302 *---------------------------------------------------------------------*/
7303
391e2f25 7304static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
5c04a7b8 7305 unsigned short ee_addr)
1da177e4
LT
7306{
7307
5c04a7b8
AD
7308 unsigned char ee_value;
7309 unsigned short i;
1da177e4 7310
5c04a7b8
AD
7311 ee_value =
7312 (unsigned
7313 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7314 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
1da177e4 7315
5c04a7b8 7316 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
1da177e4 7317
5c04a7b8 7318 ee_value |= (SEE_MS + SEE_CS);
1da177e4 7319
5c04a7b8 7320 for (i = 0x8000; i != 0; i >>= 1) {
1da177e4 7321
5c04a7b8
AD
7322 if (i & ee_data)
7323 ee_value |= SEE_DO;
7324 else
7325 ee_value &= ~SEE_DO;
7326
7327 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7328 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7329 ee_value |= SEE_CLK; /* Clock data! */
7330 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7331 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7332 ee_value &= ~SEE_CLK;
7333 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7334 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7335 }
7336 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7337 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
1da177e4 7338
5c04a7b8 7339 FPT_Wait(p_port, TO_10ms);
1da177e4 7340
5c04a7b8
AD
7341 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7342 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7343 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
1da177e4
LT
7344}
7345
7346/*---------------------------------------------------------------------
7347 *
7348 * Function: Read EEPROM
7349 *
7350 * Description: Read a word from the EEPROM at the desired
7351 * address.
7352 *
7353 *---------------------------------------------------------------------*/
7354
391e2f25 7355static unsigned short FPT_utilEERead(u32 p_port,
5c04a7b8 7356 unsigned short ee_addr)
1da177e4 7357{
5c04a7b8 7358 unsigned short i, ee_data1, ee_data2;
1da177e4
LT
7359
7360 i = 0;
47b5d69c 7361 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
5c04a7b8 7362 do {
47b5d69c 7363 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4 7364
5c04a7b8 7365 if (ee_data1 == ee_data2)
5c1b85e2 7366 return ee_data1;
1da177e4
LT
7367
7368 ee_data1 = ee_data2;
7369 i++;
7370
5c04a7b8 7371 } while (i < 4);
1da177e4 7372
5c1b85e2 7373 return ee_data1;
1da177e4
LT
7374}
7375
7376/*---------------------------------------------------------------------
7377 *
7378 * Function: Read EEPROM Original
7379 *
7380 * Description: Read a word from the EEPROM at the desired
7381 * address.
7382 *
7383 *---------------------------------------------------------------------*/
7384
391e2f25 7385static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
1da177e4
LT
7386{
7387
5c04a7b8
AD
7388 unsigned char ee_value;
7389 unsigned short i, ee_data;
1da177e4 7390
5c04a7b8
AD
7391 ee_value =
7392 (unsigned
7393 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7394 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
1da177e4 7395
5c04a7b8 7396 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
1da177e4 7397
5c04a7b8
AD
7398 ee_value |= (SEE_MS + SEE_CS);
7399 ee_data = 0;
1da177e4 7400
5c04a7b8 7401 for (i = 1; i <= 16; i++) {
1da177e4 7402
5c04a7b8
AD
7403 ee_value |= SEE_CLK; /* Clock data! */
7404 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7405 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7406 ee_value &= ~SEE_CLK;
7407 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7408 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
1da177e4 7409
5c04a7b8 7410 ee_data <<= 1;
1da177e4 7411
5c04a7b8
AD
7412 if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7413 ee_data |= 1;
7414 }
1da177e4 7415
5c04a7b8
AD
7416 ee_value &= ~(SEE_MS + SEE_CS);
7417 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7418 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
1da177e4 7419
5c1b85e2 7420 return ee_data;
1da177e4
LT
7421}
7422
1da177e4
LT
7423/*---------------------------------------------------------------------
7424 *
7425 * Function: Send EE command and Address to the EEPROM
7426 *
7427 * Description: Transfers the correct command and sends the address
7428 * to the eeprom.
7429 *
7430 *---------------------------------------------------------------------*/
7431
391e2f25 7432static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
5c04a7b8 7433 unsigned short ee_addr)
1da177e4 7434{
5c04a7b8
AD
7435 unsigned char ee_value;
7436 unsigned char narrow_flg;
1da177e4 7437
5c04a7b8 7438 unsigned short i;
1da177e4 7439
5c04a7b8
AD
7440 narrow_flg =
7441 (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7442 NARROW_SCSI_CARD);
1da177e4 7443
5c04a7b8
AD
7444 ee_value = SEE_MS;
7445 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
1da177e4 7446
5c04a7b8
AD
7447 ee_value |= SEE_CS; /* Set CS to EEPROM */
7448 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
1da177e4 7449
5c04a7b8 7450 for (i = 0x04; i != 0; i >>= 1) {
1da177e4 7451
5c04a7b8
AD
7452 if (i & ee_cmd)
7453 ee_value |= SEE_DO;
7454 else
7455 ee_value &= ~SEE_DO;
7456
7457 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7458 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7459 ee_value |= SEE_CLK; /* Clock data! */
7460 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7461 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7462 ee_value &= ~SEE_CLK;
7463 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7464 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7465 }
1da177e4 7466
5c04a7b8
AD
7467 if (narrow_flg)
7468 i = 0x0080;
1da177e4 7469
5c04a7b8
AD
7470 else
7471 i = 0x0200;
1da177e4 7472
5c04a7b8 7473 while (i != 0) {
1da177e4 7474
5c04a7b8
AD
7475 if (i & ee_addr)
7476 ee_value |= SEE_DO;
7477 else
7478 ee_value &= ~SEE_DO;
7479
7480 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7481 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7482 ee_value |= SEE_CLK; /* Clock data! */
7483 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7484 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7485 ee_value &= ~SEE_CLK;
7486 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7487 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7488
7489 i >>= 1;
7490 }
1da177e4
LT
7491}
7492
c823feeb 7493static unsigned short FPT_CalcCrc16(unsigned char buffer[])
1da177e4 7494{
5c04a7b8
AD
7495 unsigned short crc = 0;
7496 int i, j;
7497 unsigned short ch;
7498 for (i = 0; i < ID_STRING_LENGTH; i++) {
7499 ch = (unsigned short)buffer[i];
7500 for (j = 0; j < 8; j++) {
7501 if ((crc ^ ch) & 1)
7502 crc = (crc >> 1) ^ CRCMASK;
7503 else
7504 crc >>= 1;
7505 ch >>= 1;
7506 }
7507 }
5c1b85e2 7508 return crc;
1da177e4
LT
7509}
7510
db038cf8 7511static unsigned char FPT_CalcLrc(unsigned char buffer[])
1da177e4
LT
7512{
7513 int i;
db038cf8 7514 unsigned char lrc;
1da177e4 7515 lrc = 0;
5c04a7b8 7516 for (i = 0; i < ID_STRING_LENGTH; i++)
1da177e4 7517 lrc ^= buffer[i];
5c1b85e2 7518 return lrc;
1da177e4
LT
7519}
7520
1da177e4
LT
7521/*
7522 The following inline definitions avoid type conflicts.
7523*/
7524
7525static inline unsigned char
839cb99e 7526FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
1da177e4 7527{
5c04a7b8
AD
7528 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7529 FlashPointInfo);
1da177e4
LT
7530}
7531
391e2f25 7532static inline void *
839cb99e 7533FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
1da177e4 7534{
5c04a7b8
AD
7535 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7536 FlashPointInfo);
1da177e4
LT
7537}
7538
7539static inline void
391e2f25 7540FlashPoint__ReleaseHostAdapter(void *CardHandle)
1da177e4 7541{
5c04a7b8 7542 FlashPoint_ReleaseHostAdapter(CardHandle);
1da177e4
LT
7543}
7544
1da177e4 7545static inline void
391e2f25 7546FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
1da177e4 7547{
5c04a7b8 7548 FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
1da177e4
LT
7549}
7550
1da177e4 7551static inline void
391e2f25 7552FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
1da177e4 7553{
5c04a7b8 7554 FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
1da177e4
LT
7555}
7556
2065e310 7557static inline bool
391e2f25 7558FlashPoint__InterruptPending(void *CardHandle)
1da177e4 7559{
5c04a7b8 7560 return FlashPoint_InterruptPending(CardHandle);
1da177e4
LT
7561}
7562
1da177e4 7563static inline int
391e2f25 7564FlashPoint__HandleInterrupt(void *CardHandle)
1da177e4 7565{
5c04a7b8 7566 return FlashPoint_HandleInterrupt(CardHandle);
1da177e4
LT
7567}
7568
1da177e4
LT
7569#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7570#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7571#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7572#define FlashPoint_StartCCB FlashPoint__StartCCB
7573#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7574#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7575#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7576
78b4b05d 7577#else /* !CONFIG_SCSI_FLASHPOINT */
1da177e4
LT
7578
7579/*
7580 Define prototypes for the FlashPoint SCCB Manager Functions.
7581*/
7582
839cb99e 7583extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
391e2f25
KA
7584extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7585extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7586extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7587extern bool FlashPoint_InterruptPending(void *);
7588extern int FlashPoint_HandleInterrupt(void *);
7589extern void FlashPoint_ReleaseHostAdapter(void *);
1da177e4 7590
78b4b05d 7591#endif /* CONFIG_SCSI_FLASHPOINT */