Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2 
  3   FlashPoint.c -- FlashPoint SCCB Manager for Linux
  4 
  5   This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
  6   Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
  7   Linux compatibility.  It was provided by BusLogic in the form of 16 separate
  8   source files, which would have unnecessarily cluttered the scsi directory, so
  9   the individual files have been combined into this single file.
 10 
 11   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
 12 
 13   This file is available under both the GNU General Public License
 14   and a BSD-style copyright; see LICENSE.FlashPoint for details.
 15 
 16 */
 17 
 18 
 19 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
 20 
 21 #define MAX_CARDS       8
 22 #undef BUSTYPE_PCI
 23 
 24 #define CRCMASK 0xA001
 25 
 26 #define FAILURE         0xFFFFFFFFL
 27 
 28 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', '',
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] = '';
1109                         break;
1110                 case MODEL_LW:
1111                         pCardInfo->si_card_model[1] = '5';
1112                         pCardInfo->si_card_model[2] = '';
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] == '') {
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++) {