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