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