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