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