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