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