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