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