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