Back to home page

OSCL-LXR

 
 

    


0001 /*
0002 
0003   FlashPoint.c -- FlashPoint SCCB Manager for Linux
0004 
0005   This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
0006   Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
0007   Linux compatibility.  It was provided by BusLogic in the form of 16 separate
0008   source files, which would have unnecessarily cluttered the scsi directory, so
0009   the individual files have been combined into this single file.
0010 
0011   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
0012 
0013   This file is available under both the GNU General Public License
0014   and a BSD-style copyright; see LICENSE.FlashPoint for details.
0015 
0016 */
0017 
0018 
0019 #ifdef CONFIG_SCSI_FLASHPOINT
0020 
0021 #define MAX_CARDS   8
0022 #undef BUSTYPE_PCI
0023 
0024 #define CRCMASK 0xA001
0025 
0026 #define FAILURE         0xFFFFFFFFL
0027 
0028 struct sccb;
0029 typedef void (*CALL_BK_FN) (struct sccb *);
0030 
0031 struct sccb_mgr_info {
0032     u32 si_baseaddr;
0033     unsigned char si_present;
0034     unsigned char si_intvect;
0035     unsigned char si_id;
0036     unsigned char si_lun;
0037     u16 si_fw_revision;
0038     u16 si_per_targ_init_sync;
0039     u16 si_per_targ_fast_nego;
0040     u16 si_per_targ_ultra_nego;
0041     u16 si_per_targ_no_disc;
0042     u16 si_per_targ_wide_nego;
0043     u16 si_mflags;
0044     unsigned char si_card_family;
0045     unsigned char si_bustype;
0046     unsigned char si_card_model[3];
0047     unsigned char si_relative_cardnum;
0048     unsigned char si_reserved[4];
0049     u32 si_OS_reserved;
0050     unsigned char si_XlatInfo[4];
0051     u32 si_reserved2[5];
0052     u32 si_secondary_range;
0053 };
0054 
0055 #define SCSI_PARITY_ENA       0x0001
0056 #define LOW_BYTE_TERM         0x0010
0057 #define HIGH_BYTE_TERM        0x0020
0058 #define BUSTYPE_PCI   0x3
0059 
0060 #define SUPPORT_16TAR_32LUN   0x0002
0061 #define SOFT_RESET        0x0004
0062 #define EXTENDED_TRANSLATION      0x0008
0063 #define POST_ALL_UNDERRRUNS   0x0040
0064 #define FLAG_SCAM_ENABLED     0x0080
0065 #define FLAG_SCAM_LEVEL2      0x0100
0066 
0067 #define HARPOON_FAMILY        0x02
0068 
0069 /* SCCB struct used for both SCCB and UCB manager compiles! 
0070  * The UCB Manager treats the SCCB as it's 'native hardware structure' 
0071  */
0072 
0073 /*#pragma pack(1)*/
0074 struct sccb {
0075     unsigned char OperationCode;
0076     unsigned char ControlByte;
0077     unsigned char CdbLength;
0078     unsigned char RequestSenseLength;
0079     u32 DataLength;
0080     void *DataPointer;
0081     unsigned char CcbRes[2];
0082     unsigned char HostStatus;
0083     unsigned char TargetStatus;
0084     unsigned char TargID;
0085     unsigned char Lun;
0086     unsigned char Cdb[12];
0087     unsigned char CcbRes1;
0088     unsigned char Reserved1;
0089     u32 Reserved2;
0090     u32 SensePointer;
0091 
0092     CALL_BK_FN SccbCallback;    /* VOID (*SccbCallback)(); */
0093     u32 SccbIOPort;         /* Identifies board base port */
0094     unsigned char SccbStatus;
0095     unsigned char SCCBRes2;
0096     u16 SccbOSFlags;
0097 
0098     u32 Sccb_XferCnt;   /* actual transfer count */
0099     u32 Sccb_ATC;
0100     u32 SccbVirtDataPtr;    /* virtual addr for OS/2 */
0101     u32 Sccb_res1;
0102     u16 Sccb_MGRFlags;
0103     u16 Sccb_sgseg;
0104     unsigned char Sccb_scsimsg; /* identify msg for selection */
0105     unsigned char Sccb_tag;
0106     unsigned char Sccb_scsistat;
0107     unsigned char Sccb_idmsg;   /* image of last msg in */
0108     struct sccb *Sccb_forwardlink;
0109     struct sccb *Sccb_backlink;
0110     u32 Sccb_savedATC;
0111     unsigned char Save_Cdb[6];
0112     unsigned char Save_CdbLen;
0113     unsigned char Sccb_XferState;
0114     u32 Sccb_SGoffset;
0115 };
0116 
0117 #pragma pack()
0118 
0119 #define SCATTER_GATHER_COMMAND    0x02
0120 #define RESIDUAL_COMMAND          0x03
0121 #define RESIDUAL_SG_COMMAND       0x04
0122 #define RESET_COMMAND             0x81
0123 
0124 #define F_USE_CMD_Q              0x20   /*Inidcates TAGGED command. */
0125 #define TAG_TYPE_MASK            0xC0   /*Type of tag msg to send. */
0126 #define SCCB_DATA_XFER_OUT       0x10   /* Write */
0127 #define SCCB_DATA_XFER_IN        0x08   /* Read */
0128 
0129 #define NO_AUTO_REQUEST_SENSE    0x01   /* No Request Sense Buffer */
0130 
0131 #define BUS_FREE_ST     0
0132 #define SELECT_ST       1
0133 #define SELECT_BDR_ST   2   /* Select w\ Bus Device Reset */
0134 #define SELECT_SN_ST    3   /* Select w\ Sync Nego */
0135 #define SELECT_WN_ST    4   /* Select w\ Wide Data Nego */
0136 #define SELECT_Q_ST     5   /* Select w\ Tagged Q'ing */
0137 #define COMMAND_ST      6
0138 #define DATA_OUT_ST     7
0139 #define DATA_IN_ST      8
0140 #define DISCONNECT_ST   9
0141 #define ABORT_ST        11
0142 
0143 #define F_HOST_XFER_DIR                0x01
0144 #define F_ALL_XFERRED                  0x02
0145 #define F_SG_XFER                      0x04
0146 #define F_AUTO_SENSE                   0x08
0147 #define F_ODD_BALL_CNT                 0x10
0148 #define F_NO_DATA_YET                  0x80
0149 
0150 #define F_STATUSLOADED                 0x01
0151 #define F_DEV_SELECTED                 0x04
0152 
0153 #define SCCB_COMPLETE               0x00    /* SCCB completed without error */
0154 #define SCCB_DATA_UNDER_RUN         0x0C
0155 #define SCCB_SELECTION_TIMEOUT      0x11    /* Set SCSI selection timed out */
0156 #define SCCB_DATA_OVER_RUN          0x12
0157 #define SCCB_PHASE_SEQUENCE_FAIL    0x14    /* Target bus phase sequence failure */
0158 
0159 #define SCCB_GROSS_FW_ERR           0x27    /* Major problem! */
0160 #define SCCB_BM_ERR                 0x30    /* BusMaster error. */
0161 #define SCCB_PARITY_ERR             0x34    /* SCSI parity error */
0162 
0163 #define SCCB_IN_PROCESS            0x00
0164 #define SCCB_SUCCESS               0x01
0165 #define SCCB_ABORT                 0x02
0166 #define SCCB_ERROR                 0x04
0167 
0168 #define  ORION_FW_REV      3110
0169 
0170 #define QUEUE_DEPTH     254+1   /*1 for Normal disconnect 32 for Q'ing. */
0171 
0172 #define MAX_MB_CARDS    4   /* Max. no of cards suppoerted on Mother Board */
0173 
0174 #define MAX_SCSI_TAR    16
0175 #define MAX_LUN         32
0176 #define LUN_MASK            0x1f
0177 
0178 #define SG_BUF_CNT      16  /*Number of prefetched elements. */
0179 
0180 #define SG_ELEMENT_SIZE 8   /*Eight byte per element. */
0181 
0182 #define RD_HARPOON(ioport)          inb((u32)ioport)
0183 #define RDW_HARPOON(ioport)         inw((u32)ioport)
0184 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
0185 #define WR_HARPOON(ioport,val)      outb((u8) val, (u32)ioport)
0186 #define WRW_HARPOON(ioport,val)       outw((u16)val, (u32)ioport)
0187 #define WR_HARP32(ioport,offset,data)  outl(data, (u32)(ioport + offset))
0188 
0189 #define  TAR_SYNC_MASK     (BIT(7)+BIT(6))
0190 #define  SYNC_TRYING               BIT(6)
0191 #define  SYNC_SUPPORTED    (BIT(7)+BIT(6))
0192 
0193 #define  TAR_WIDE_MASK     (BIT(5)+BIT(4))
0194 #define  WIDE_ENABLED              BIT(4)
0195 #define  WIDE_NEGOCIATED   BIT(5)
0196 
0197 #define  TAR_TAG_Q_MASK    (BIT(3)+BIT(2))
0198 #define  TAG_Q_TRYING              BIT(2)
0199 #define  TAG_Q_REJECT      BIT(3)
0200 
0201 #define  TAR_ALLOW_DISC    BIT(0)
0202 
0203 #define  EE_SYNC_MASK      (BIT(0)+BIT(1))
0204 #define  EE_SYNC_5MB       BIT(0)
0205 #define  EE_SYNC_10MB      BIT(1)
0206 #define  EE_SYNC_20MB      (BIT(0)+BIT(1))
0207 
0208 #define  EE_WIDE_SCSI      BIT(7)
0209 
0210 struct sccb_mgr_tar_info {
0211 
0212     struct sccb *TarSelQ_Head;
0213     struct sccb *TarSelQ_Tail;
0214     unsigned char TarLUN_CA;    /*Contingent Allgiance */
0215     unsigned char TarTagQ_Cnt;
0216     unsigned char TarSelQ_Cnt;
0217     unsigned char TarStatus;
0218     unsigned char TarEEValue;
0219     unsigned char TarSyncCtrl;
0220     unsigned char TarReserved[2];   /* for alignment */
0221     unsigned char LunDiscQ_Idx[MAX_LUN];
0222     unsigned char TarLUNBusy[MAX_LUN];
0223 };
0224 
0225 struct nvram_info {
0226     unsigned char niModel;      /* Model No. of card */
0227     unsigned char niCardNo;     /* Card no. */
0228     u32 niBaseAddr;         /* Port Address of card */
0229     unsigned char niSysConf;    /* Adapter Configuration byte -
0230                        Byte 16 of eeprom map */
0231     unsigned char niScsiConf;   /* SCSI Configuration byte -
0232                        Byte 17 of eeprom map */
0233     unsigned char niScamConf;   /* SCAM Configuration byte -
0234                        Byte 20 of eeprom map */
0235     unsigned char niAdapId;     /* Host Adapter ID -
0236                        Byte 24 of eerpom map */
0237     unsigned char niSyncTbl[MAX_SCSI_TAR / 2];  /* Sync/Wide byte
0238                                of targets */
0239     unsigned char niScamTbl[MAX_SCSI_TAR][4];   /* Compressed Scam name
0240                                string of Targets */
0241 };
0242 
0243 #define MODEL_LT        1
0244 #define MODEL_DL        2
0245 #define MODEL_LW        3
0246 #define MODEL_DW        4
0247 
0248 struct sccb_card {
0249     struct sccb *currentSCCB;
0250     struct sccb_mgr_info *cardInfo;
0251 
0252     u32 ioPort;
0253 
0254     unsigned short cmdCounter;
0255     unsigned char discQCount;
0256     unsigned char tagQ_Lst;
0257     unsigned char cardIndex;
0258     unsigned char scanIndex;
0259     unsigned char globalFlags;
0260     unsigned char ourId;
0261     struct nvram_info *pNvRamInfo;
0262     struct sccb *discQ_Tbl[QUEUE_DEPTH];
0263 
0264 };
0265 
0266 #define F_TAG_STARTED       0x01
0267 #define F_CONLUN_IO         0x02
0268 #define F_DO_RENEGO         0x04
0269 #define F_NO_FILTER         0x08
0270 #define F_GREEN_PC          0x10
0271 #define F_HOST_XFER_ACT     0x20
0272 #define F_NEW_SCCB_CMD      0x40
0273 #define F_UPDATE_EEPROM     0x80
0274 
0275 #define  ID_STRING_LENGTH  32
0276 #define  TYPE_CODE0        0x63 /*Level2 Mstr (bits 7-6),  */
0277 
0278 #define  SLV_TYPE_CODE0    0xA3 /*Priority Bit set (bits 7-6),  */
0279 
0280 #define  ASSIGN_ID   0x00
0281 #define  SET_P_FLAG  0x01
0282 #define  CFG_CMPLT   0x03
0283 #define  DOM_MSTR    0x0F
0284 #define  SYNC_PTRN   0x1F
0285 
0286 #define  ID_0_7      0x18
0287 #define  ID_8_F      0x11
0288 #define  MISC_CODE   0x14
0289 #define  CLR_P_FLAG  0x18
0290 
0291 #define  INIT_SELTD  0x01
0292 #define  LEVEL2_TAR  0x02
0293 
0294 enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11,
0295         ID12,
0296     ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY,
0297     CLR_PRIORITY, NO_ID_AVAIL
0298 };
0299 
0300 typedef struct SCCBscam_info {
0301 
0302     unsigned char id_string[ID_STRING_LENGTH];
0303     enum scam_id_st state;
0304 
0305 } SCCBSCAM_INFO;
0306 
0307 
0308 #define  SMIDENT                 0x80
0309 #define  DISC_PRIV               0x40
0310 
0311 #define  SM8BIT                  0x00
0312 #define  SM16BIT                 0x01
0313 
0314 #define  SIX_BYTE_CMD            0x06
0315 #define  TWELVE_BYTE_CMD         0x0C
0316 
0317 #define  ASYNC                   0x00
0318 #define  MAX_OFFSET              0x0F   /* Maxbyteoffset for Sync Xfers */
0319 
0320 #define  EEPROM_WD_CNT     256
0321 
0322 #define  EEPROM_CHECK_SUM  0
0323 #define  FW_SIGNATURE      2
0324 #define  MODEL_NUMB_0      4
0325 #define  MODEL_NUMB_2      6
0326 #define  MODEL_NUMB_4      8
0327 #define  SYSTEM_CONFIG     16
0328 #define  SCSI_CONFIG       17
0329 #define  BIOS_CONFIG       18
0330 #define  SCAM_CONFIG       20
0331 #define  ADAPTER_SCSI_ID   24
0332 
0333 #define  IGNORE_B_SCAN     32
0334 #define  SEND_START_ENA    34
0335 #define  DEVICE_ENABLE     36
0336 
0337 #define  SYNC_RATE_TBL     38
0338 #define  SYNC_RATE_TBL01   38
0339 #define  SYNC_RATE_TBL23   40
0340 #define  SYNC_RATE_TBL45   42
0341 #define  SYNC_RATE_TBL67   44
0342 #define  SYNC_RATE_TBL89   46
0343 #define  SYNC_RATE_TBLab   48
0344 #define  SYNC_RATE_TBLcd   50
0345 #define  SYNC_RATE_TBLef   52
0346 
0347 #define  EE_SCAMBASE      256
0348 
0349 #define  SCAM_ENABLED   BIT(2)
0350 #define  SCAM_LEVEL2    BIT(3)
0351 
0352 #define RENEGO_ENA      BIT(10)
0353 #define CONNIO_ENA      BIT(11)
0354 #define  GREEN_PC_ENA   BIT(12)
0355 
0356 #define  AUTO_RATE_00   00
0357 #define  AUTO_RATE_05   01
0358 #define  AUTO_RATE_10   02
0359 #define  AUTO_RATE_20   03
0360 
0361 #define  WIDE_NEGO_BIT     BIT(7)
0362 #define  DISC_ENABLE_BIT   BIT(6)
0363 
0364 #define  hp_vendor_id_0       0x00  /* LSB */
0365 #define  ORION_VEND_0   0x4B
0366 
0367 #define  hp_vendor_id_1       0x01  /* MSB */
0368 #define  ORION_VEND_1   0x10
0369 
0370 #define  hp_device_id_0       0x02  /* LSB */
0371 #define  ORION_DEV_0    0x30
0372 
0373 #define  hp_device_id_1       0x03  /* MSB */
0374 #define  ORION_DEV_1    0x81
0375 
0376     /* Sub Vendor ID and Sub Device ID only available in
0377        Harpoon Version 2 and higher */
0378 
0379 #define  hp_sub_device_id_0   0x06  /* LSB */
0380 
0381 #define  hp_semaphore         0x0C
0382 #define SCCB_MGR_ACTIVE    BIT(0)
0383 #define TICKLE_ME          BIT(1)
0384 #define SCCB_MGR_PRESENT   BIT(3)
0385 #define BIOS_IN_USE        BIT(4)
0386 
0387 #define  hp_sys_ctrl          0x0F
0388 
0389 #define  STOP_CLK          BIT(0)   /*Turn off BusMaster Clock */
0390 #define  DRVR_RST          BIT(1)   /*Firmware Reset to 80C15 chip */
0391 #define  HALT_MACH         BIT(3)   /*Halt State Machine      */
0392 #define  HARD_ABORT        BIT(4)   /*Hard Abort              */
0393 
0394 #define  hp_host_blk_cnt      0x13
0395 
0396 #define  XFER_BLK64        0x06 /*     1 1 0 64 byte per block */
0397 
0398 #define  BM_THRESHOLD      0x40 /* PCI mode can only xfer 16 bytes */
0399 
0400 #define  hp_int_mask          0x17
0401 
0402 #define  INT_CMD_COMPL     BIT(0)   /* DMA command complete   */
0403 #define  INT_EXT_STATUS    BIT(1)   /* Extended Status Set    */
0404 
0405 #define  hp_xfer_cnt_lo       0x18
0406 #define  hp_xfer_cnt_hi       0x1A
0407 #define  hp_xfer_cmd          0x1B
0408 
0409 #define  XFER_HOST_DMA     0x00 /*     0 0 0 Transfer Host -> DMA */
0410 #define  XFER_DMA_HOST     0x01 /*     0 0 1 Transfer DMA  -> Host */
0411 
0412 #define  XFER_HOST_AUTO    0x00 /*     0 0 Auto Transfer Size   */
0413 
0414 #define  XFER_DMA_8BIT     0x20 /*     0 1 8 BIT  Transfer Size */
0415 
0416 #define  DISABLE_INT       BIT(7)   /*Do not interrupt at end of cmd. */
0417 
0418 #define  HOST_WRT_CMD      ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
0419 #define  HOST_RD_CMD       ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
0420 
0421 #define  hp_host_addr_lo      0x1C
0422 #define  hp_host_addr_hmi     0x1E
0423 
0424 #define  hp_ee_ctrl           0x22
0425 
0426 #define  EXT_ARB_ACK       BIT(7)
0427 #define  SCSI_TERM_ENA_H   BIT(6)   /* SCSI high byte terminator */
0428 #define  SEE_MS            BIT(5)
0429 #define  SEE_CS            BIT(3)
0430 #define  SEE_CLK           BIT(2)
0431 #define  SEE_DO            BIT(1)
0432 #define  SEE_DI            BIT(0)
0433 
0434 #define  EE_READ           0x06
0435 #define  EE_WRITE          0x05
0436 #define  EWEN              0x04
0437 #define  EWEN_ADDR         0x03C0
0438 #define  EWDS              0x04
0439 #define  EWDS_ADDR         0x0000
0440 
0441 #define  hp_bm_ctrl           0x26
0442 
0443 #define  SCSI_TERM_ENA_L   BIT(0)   /*Enable/Disable external terminators */
0444 #define  FLUSH_XFER_CNTR   BIT(1)   /*Flush transfer counter */
0445 #define  FORCE1_XFER       BIT(5)   /*Always xfer one byte in byte mode */
0446 #define  FAST_SINGLE       BIT(6)   /*?? */
0447 
0448 #define  BMCTRL_DEFAULT    (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
0449 
0450 #define  hp_sg_addr           0x28
0451 #define  hp_page_ctrl         0x29
0452 
0453 #define  SCATTER_EN        BIT(0)
0454 #define  SGRAM_ARAM        BIT(1)
0455 #define  G_INT_DISABLE     BIT(3)   /* Enable/Disable all Interrupts */
0456 #define  NARROW_SCSI_CARD  BIT(4)   /* NARROW/WIDE SCSI config pin */
0457 
0458 #define  hp_pci_stat_cfg      0x2D
0459 
0460 #define  REC_MASTER_ABORT  BIT(5)   /*received Master abort */
0461 
0462 #define  hp_rev_num           0x33
0463 
0464 #define  hp_stack_data        0x34
0465 #define  hp_stack_addr        0x35
0466 
0467 #define  hp_ext_status        0x36
0468 
0469 #define  BM_FORCE_OFF      BIT(0)   /*Bus Master is forced to get off */
0470 #define  PCI_TGT_ABORT     BIT(0)   /*PCI bus master transaction aborted */
0471 #define  PCI_DEV_TMOUT     BIT(1)   /*PCI Device Time out */
0472 #define  CMD_ABORTED       BIT(4)   /*Command aborted */
0473 #define  BM_PARITY_ERR     BIT(5)   /*parity error on data received   */
0474 #define  PIO_OVERRUN       BIT(6)   /*Slave data overrun */
0475 #define  BM_CMD_BUSY       BIT(7)   /*Bus master transfer command busy */
0476 #define  BAD_EXT_STATUS    (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
0477                                   BM_PARITY_ERR | PIO_OVERRUN)
0478 
0479 #define  hp_int_status        0x37
0480 
0481 #define  EXT_STATUS_ON     BIT(1)   /*Extended status is valid */
0482 #define  SCSI_INTERRUPT    BIT(2)   /*Global indication of a SCSI int. */
0483 #define  INT_ASSERTED      BIT(5)   /* */
0484 
0485 #define  hp_fifo_cnt          0x38
0486 
0487 #define  hp_intena       0x40
0488 
0489 #define  RESET       BIT(7)
0490 #define  PROG_HLT        BIT(6)
0491 #define  PARITY      BIT(5)
0492 #define  FIFO        BIT(4)
0493 #define  SEL         BIT(3)
0494 #define  SCAM_SEL        BIT(2)
0495 #define  RSEL        BIT(1)
0496 #define  TIMEOUT         BIT(0)
0497 #define  BUS_FREE        BIT(15)
0498 #define  XFER_CNT_0  BIT(14)
0499 #define  PHASE       BIT(13)
0500 #define  IUNKWN      BIT(12)
0501 #define  ICMD_COMP   BIT(11)
0502 #define  ITICKLE         BIT(10)
0503 #define  IDO_STRT        BIT(9)
0504 #define  ITAR_DISC   BIT(8)
0505 #define  AUTO_INT        (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
0506 #define  CLR_ALL_INT     0xFFFF
0507 #define  CLR_ALL_INT_1   0xFF00
0508 
0509 #define  hp_intstat      0x42
0510 
0511 #define  hp_scsisig           0x44
0512 
0513 #define  SCSI_SEL          BIT(7)
0514 #define  SCSI_BSY          BIT(6)
0515 #define  SCSI_REQ          BIT(5)
0516 #define  SCSI_ACK          BIT(4)
0517 #define  SCSI_ATN          BIT(3)
0518 #define  SCSI_CD           BIT(2)
0519 #define  SCSI_MSG          BIT(1)
0520 #define  SCSI_IOBIT        BIT(0)
0521 
0522 #define  S_SCSI_PHZ        (BIT(2)+BIT(1)+BIT(0))
0523 #define  S_MSGO_PH         (BIT(2)+BIT(1)       )
0524 #define  S_MSGI_PH         (BIT(2)+BIT(1)+BIT(0))
0525 #define  S_DATAI_PH        (              BIT(0))
0526 #define  S_DATAO_PH        0x00
0527 #define  S_ILL_PH          (       BIT(1)       )
0528 
0529 #define  hp_scsictrl_0        0x45
0530 
0531 #define  SEL_TAR           BIT(6)
0532 #define  ENA_ATN           BIT(4)
0533 #define  ENA_RESEL         BIT(2)
0534 #define  SCSI_RST          BIT(1)
0535 #define  ENA_SCAM_SEL      BIT(0)
0536 
0537 #define  hp_portctrl_0        0x46
0538 
0539 #define  SCSI_PORT         BIT(7)
0540 #define  SCSI_INBIT        BIT(6)
0541 #define  DMA_PORT          BIT(5)
0542 #define  DMA_RD            BIT(4)
0543 #define  HOST_PORT         BIT(3)
0544 #define  HOST_WRT          BIT(2)
0545 #define  SCSI_BUS_EN       BIT(1)
0546 #define  START_TO          BIT(0)
0547 
0548 #define  hp_scsireset         0x47
0549 
0550 #define  SCSI_INI          BIT(6)
0551 #define  SCAM_EN           BIT(5)
0552 #define  DMA_RESET         BIT(3)
0553 #define  HPSCSI_RESET      BIT(2)
0554 #define  PROG_RESET        BIT(1)
0555 #define  FIFO_CLR          BIT(0)
0556 
0557 #define  hp_xfercnt_0         0x48
0558 #define  hp_xfercnt_2         0x4A
0559 
0560 #define  hp_fifodata_0        0x4C
0561 #define  hp_addstat           0x4E
0562 
0563 #define  SCAM_TIMER        BIT(7)
0564 #define  SCSI_MODE8        BIT(3)
0565 #define  SCSI_PAR_ERR      BIT(0)
0566 
0567 #define  hp_prgmcnt_0         0x4F
0568 
0569 #define  hp_selfid_0          0x50
0570 #define  hp_selfid_1          0x51
0571 #define  hp_arb_id            0x52
0572 
0573 #define  hp_select_id         0x53
0574 
0575 #define  hp_synctarg_base     0x54
0576 #define  hp_synctarg_12       0x54
0577 #define  hp_synctarg_13       0x55
0578 #define  hp_synctarg_14       0x56
0579 #define  hp_synctarg_15       0x57
0580 
0581 #define  hp_synctarg_8        0x58
0582 #define  hp_synctarg_9        0x59
0583 #define  hp_synctarg_10       0x5A
0584 #define  hp_synctarg_11       0x5B
0585 
0586 #define  hp_synctarg_4        0x5C
0587 #define  hp_synctarg_5        0x5D
0588 #define  hp_synctarg_6        0x5E
0589 #define  hp_synctarg_7        0x5F
0590 
0591 #define  hp_synctarg_0        0x60
0592 #define  hp_synctarg_1        0x61
0593 #define  hp_synctarg_2        0x62
0594 #define  hp_synctarg_3        0x63
0595 
0596 #define  NARROW_SCSI       BIT(4)
0597 #define  DEFAULT_OFFSET    0x0F
0598 
0599 #define  hp_autostart_0       0x64
0600 #define  hp_autostart_1       0x65
0601 #define  hp_autostart_3       0x67
0602 
0603 #define  AUTO_IMMED    BIT(5)
0604 #define  SELECT   BIT(6)
0605 #define  END_DATA (BIT(7)+BIT(6))
0606 
0607 #define  hp_gp_reg_0          0x68
0608 #define  hp_gp_reg_1          0x69
0609 #define  hp_gp_reg_3          0x6B
0610 
0611 #define  hp_seltimeout        0x6C
0612 
0613 #define  TO_4ms            0x67 /* 3.9959ms */
0614 
0615 #define  TO_5ms            0x03 /* 4.9152ms */
0616 #define  TO_10ms           0x07 /* 11.xxxms */
0617 #define  TO_250ms          0x99 /* 250.68ms */
0618 #define  TO_290ms          0xB1 /* 289.99ms */
0619 
0620 #define  hp_clkctrl_0         0x6D
0621 
0622 #define  PWR_DWN           BIT(6)
0623 #define  ACTdeassert       BIT(4)
0624 #define  CLK_40MHZ         (BIT(1) + BIT(0))
0625 
0626 #define  CLKCTRL_DEFAULT   (ACTdeassert | CLK_40MHZ)
0627 
0628 #define  hp_fiforead          0x6E
0629 #define  hp_fifowrite         0x6F
0630 
0631 #define  hp_offsetctr         0x70
0632 #define  hp_xferstat          0x71
0633 
0634 #define  FIFO_EMPTY        BIT(6)
0635 
0636 #define  hp_portctrl_1        0x72
0637 
0638 #define  CHK_SCSI_P        BIT(3)
0639 #define  HOST_MODE8        BIT(0)
0640 
0641 #define  hp_xfer_pad          0x73
0642 
0643 #define  ID_UNLOCK         BIT(3)
0644 
0645 #define  hp_scsidata_0        0x74
0646 #define  hp_scsidata_1        0x75
0647 
0648 #define  hp_aramBase          0x80
0649 #define  BIOS_DATA_OFFSET     0x60
0650 #define  BIOS_RELATIVE_CARD   0x64
0651 
0652 #define  AR3      (BIT(9) + BIT(8))
0653 #define  SDATA    BIT(10)
0654 
0655 #define  CRD_OP   BIT(11)   /* Cmp Reg. w/ Data */
0656 
0657 #define  CRR_OP   BIT(12)   /* Cmp Reg. w. Reg. */
0658 
0659 #define  CPE_OP   (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
0660 
0661 #define  CPN_OP   (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
0662 
0663 #define  ADATA_OUT   0x00
0664 #define  ADATA_IN    BIT(8)
0665 #define  ACOMMAND    BIT(10)
0666 #define  ASTATUS     (BIT(10)+BIT(8))
0667 #define  AMSG_OUT    (BIT(10)+BIT(9))
0668 #define  AMSG_IN     (BIT(10)+BIT(9)+BIT(8))
0669 
0670 #define  BRH_OP   BIT(13)   /* Branch */
0671 
0672 #define  ALWAYS   0x00
0673 #define  EQUAL    BIT(8)
0674 #define  NOT_EQ   BIT(9)
0675 
0676 #define  TCB_OP   (BIT(13)+BIT(11)) /* Test condition & branch */
0677 
0678 #define  FIFO_0      BIT(10)
0679 
0680 #define  MPM_OP   BIT(15)   /* Match phase and move data */
0681 
0682 #define  MRR_OP   BIT(14)   /* Move DReg. to Reg. */
0683 
0684 #define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
0685 
0686 #define  D_AR0    0x00
0687 #define  D_AR1    BIT(0)
0688 #define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
0689 
0690 #define  RAT_OP      (BIT(14)+BIT(13)+BIT(11))
0691 
0692 #define  SSI_OP      (BIT(15)+BIT(11))
0693 
0694 #define  SSI_ITAR_DISC  (ITAR_DISC >> 8)
0695 #define  SSI_IDO_STRT   (IDO_STRT >> 8)
0696 
0697 #define  SSI_ICMD_COMP  (ICMD_COMP >> 8)
0698 #define  SSI_ITICKLE    (ITICKLE >> 8)
0699 
0700 #define  SSI_IUNKWN (IUNKWN >> 8)
0701 #define  SSI_INO_CC (IUNKWN >> 8)
0702 #define  SSI_IRFAIL (IUNKWN >> 8)
0703 
0704 #define  NP    0x10     /*Next Phase */
0705 #define  NTCMD 0x02     /*Non- Tagged Command start */
0706 #define  CMDPZ 0x04     /*Command phase */
0707 #define  DINT  0x12     /*Data Out/In interrupt */
0708 #define  DI    0x13     /*Data Out */
0709 #define  DC    0x19     /*Disconnect Message */
0710 #define  ST    0x1D     /*Status Phase */
0711 #define  UNKNWN 0x24        /*Unknown bus action */
0712 #define  CC    0x25     /*Command Completion failure */
0713 #define  TICK  0x26     /*New target reselected us. */
0714 #define  SELCHK 0x28        /*Select & Check SCSI ID latch reg */
0715 
0716 #define  ID_MSG_STRT    hp_aramBase + 0x00
0717 #define  NON_TAG_ID_MSG hp_aramBase + 0x06
0718 #define  CMD_STRT       hp_aramBase + 0x08
0719 #define  SYNC_MSGS      hp_aramBase + 0x08
0720 
0721 #define  TAG_STRT          0x00
0722 #define  DISCONNECT_START  0x10/2
0723 #define  END_DATA_START    0x14/2
0724 #define  CMD_ONLY_STRT     CMDPZ/2
0725 #define  SELCHK_STRT     SELCHK/2
0726 
0727 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
0728 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
0729                                  xfercnt <<= 16,\
0730                                  xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
0731  */
0732 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
0733          addr >>= 16,\
0734          WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
0735          WR_HARP32(port,hp_xfercnt_0,count),\
0736          WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
0737          count >>= 16,\
0738          WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
0739 
0740 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
0741                           WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
0742 
0743 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
0744                           WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
0745 
0746 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
0747                         WR_HARPOON(port+hp_scsireset, 0x00))
0748 
0749 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
0750                              (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
0751 
0752 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
0753                              (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
0754 
0755 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
0756                              (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
0757 
0758 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
0759                              (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
0760 
0761 static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
0762                  unsigned char syncFlag);
0763 static void FPT_ssel(u32 port, unsigned char p_card);
0764 static void FPT_sres(u32 port, unsigned char p_card,
0765              struct sccb_card *pCurrCard);
0766 static void FPT_shandem(u32 port, unsigned char p_card,
0767             struct sccb *pCurrSCCB);
0768 static void FPT_stsyncn(u32 port, unsigned char p_card);
0769 static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
0770             unsigned char offset);
0771 static void FPT_sssyncv(u32 p_port, unsigned char p_id,
0772             unsigned char p_sync_value,
0773             struct sccb_mgr_tar_info *currTar_Info);
0774 static void FPT_sresb(u32 port, unsigned char p_card);
0775 static void FPT_sxfrp(u32 p_port, unsigned char p_card);
0776 static void FPT_schkdd(u32 port, unsigned char p_card);
0777 static unsigned char FPT_RdStack(u32 port, unsigned char index);
0778 static void FPT_WrStack(u32 portBase, unsigned char index,
0779             unsigned char data);
0780 static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
0781 
0782 static void FPT_SendMsg(u32 port, unsigned char message);
0783 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
0784                    unsigned char error_code);
0785 
0786 static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
0787 static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
0788 
0789 static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
0790 static void FPT_stwidn(u32 port, unsigned char p_card);
0791 static void FPT_siwidr(u32 port, unsigned char width);
0792 
0793 static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
0794                 unsigned char p_card);
0795 static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
0796 static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
0797                  struct sccb *p_SCCB, unsigned char p_card);
0798 static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
0799                   unsigned char p_card);
0800 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
0801 static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
0802 static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
0803                        unsigned char p_card);
0804 static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
0805 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
0806 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
0807 
0808 static void FPT_Wait1Second(u32 p_port);
0809 static void FPT_Wait(u32 p_port, unsigned char p_delay);
0810 static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
0811 static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
0812                 unsigned short ee_addr);
0813 static unsigned short FPT_utilEERead(u32 p_port,
0814                      unsigned short ee_addr);
0815 static unsigned short FPT_utilEEReadOrg(u32 p_port,
0816                     unsigned short ee_addr);
0817 static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
0818                   unsigned short ee_addr);
0819 
0820 static void FPT_phaseDataOut(u32 port, unsigned char p_card);
0821 static void FPT_phaseDataIn(u32 port, unsigned char p_card);
0822 static void FPT_phaseCommand(u32 port, unsigned char p_card);
0823 static void FPT_phaseStatus(u32 port, unsigned char p_card);
0824 static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
0825 static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
0826 static void FPT_phaseIllegal(u32 port, unsigned char p_card);
0827 
0828 static void FPT_phaseDecode(u32 port, unsigned char p_card);
0829 static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
0830 static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
0831 
0832 static void FPT_XbowInit(u32 port, unsigned char scamFlg);
0833 static void FPT_BusMasterInit(u32 p_port);
0834 static void FPT_DiagEEPROM(u32 p_port);
0835 
0836 static void FPT_dataXferProcessor(u32 port,
0837                   struct sccb_card *pCurrCard);
0838 static void FPT_busMstrSGDataXferStart(u32 port,
0839                        struct sccb *pCurrSCCB);
0840 static void FPT_busMstrDataXferStart(u32 port,
0841                      struct sccb *pCurrSCCB);
0842 static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
0843                   struct sccb *pCurrSCCB);
0844 static void FPT_hostDataXferRestart(struct sccb *currSCCB);
0845 
0846 static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
0847                      unsigned char p_card,
0848                      struct sccb_card *pCurrCard,
0849                      unsigned short p_int);
0850 
0851 static void FPT_SccbMgrTableInitAll(void);
0852 static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
0853                      unsigned char p_card);
0854 static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
0855                        unsigned char target);
0856 
0857 static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
0858               unsigned char p_power_up);
0859 
0860 static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
0861 static void FPT_scbusf(u32 p_port);
0862 static void FPT_scsel(u32 p_port);
0863 static void FPT_scasid(unsigned char p_card, u32 p_port);
0864 static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
0865 static unsigned char FPT_scsendi(u32 p_port,
0866                  unsigned char p_id_string[]);
0867 static unsigned char FPT_sciso(u32 p_port,
0868                    unsigned char p_id_string[]);
0869 static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
0870 static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
0871 static unsigned char FPT_scvalq(unsigned char p_quintet);
0872 static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
0873 static void FPT_scwtsel(u32 p_port);
0874 static void FPT_inisci(unsigned char p_card, u32 p_port,
0875                unsigned char p_our_id);
0876 static void FPT_scsavdi(unsigned char p_card, u32 p_port);
0877 static unsigned char FPT_scmachid(unsigned char p_card,
0878                   unsigned char p_id_string[]);
0879 
0880 static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
0881 static void FPT_autoLoadDefaultMap(u32 p_port);
0882 
0883 static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
0884     { {{0}} };
0885 static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
0886 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
0887 static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
0888 
0889 static unsigned char FPT_mbCards = 0;
0890 static unsigned char FPT_scamHAString[] =
0891     { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
0892     ' ', 'B', 'T', '-', '9', '3', '0',
0893     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0894     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
0895 };
0896 
0897 static unsigned short FPT_default_intena = 0;
0898 
0899 static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
0900 0};
0901 
0902 /*---------------------------------------------------------------------
0903  *
0904  * Function: FlashPoint_ProbeHostAdapter
0905  *
0906  * Description: Setup and/or Search for cards and return info to caller.
0907  *
0908  *---------------------------------------------------------------------*/
0909 
0910 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
0911 {
0912     static unsigned char first_time = 1;
0913 
0914     unsigned char i, j, id, ScamFlg;
0915     unsigned short temp, temp2, temp3, temp4, temp5, temp6;
0916     u32 ioport;
0917     struct nvram_info *pCurrNvRam;
0918 
0919     ioport = pCardInfo->si_baseaddr;
0920 
0921     if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
0922         return (int)FAILURE;
0923 
0924     if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
0925         return (int)FAILURE;
0926 
0927     if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
0928         return (int)FAILURE;
0929 
0930     if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
0931         return (int)FAILURE;
0932 
0933     if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
0934 
0935 /* For new Harpoon then check for sub_device ID LSB
0936    the bits(0-3) must be all ZERO for compatible with
0937    current version of SCCBMgr, else skip this Harpoon
0938     device. */
0939 
0940         if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
0941             return (int)FAILURE;
0942     }
0943 
0944     if (first_time) {
0945         FPT_SccbMgrTableInitAll();
0946         first_time = 0;
0947         FPT_mbCards = 0;
0948     }
0949 
0950     if (FPT_RdStack(ioport, 0) != 0x00) {
0951         if (FPT_ChkIfChipInitialized(ioport) == 0) {
0952             pCurrNvRam = NULL;
0953             WR_HARPOON(ioport + hp_semaphore, 0x00);
0954             FPT_XbowInit(ioport, 0);    /*Must Init the SCSI before attempting */
0955             FPT_DiagEEPROM(ioport);
0956         } else {
0957             if (FPT_mbCards < MAX_MB_CARDS) {
0958                 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
0959                 FPT_mbCards++;
0960                 pCurrNvRam->niBaseAddr = ioport;
0961                 FPT_RNVRamData(pCurrNvRam);
0962             } else
0963                 return (int)FAILURE;
0964         }
0965     } else
0966         pCurrNvRam = NULL;
0967 
0968     WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
0969     WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
0970 
0971     if (pCurrNvRam)
0972         pCardInfo->si_id = pCurrNvRam->niAdapId;
0973     else
0974         pCardInfo->si_id =
0975             (unsigned
0976              char)(FPT_utilEERead(ioport,
0977                       (ADAPTER_SCSI_ID /
0978                        2)) & (unsigned char)0x0FF);
0979 
0980     pCardInfo->si_lun = 0x00;
0981     pCardInfo->si_fw_revision = ORION_FW_REV;
0982     temp2 = 0x0000;
0983     temp3 = 0x0000;
0984     temp4 = 0x0000;
0985     temp5 = 0x0000;
0986     temp6 = 0x0000;
0987 
0988     for (id = 0; id < (16 / 2); id++) {
0989 
0990         if (pCurrNvRam) {
0991             temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
0992             temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
0993                 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
0994         } else
0995             temp =
0996                 FPT_utilEERead(ioport,
0997                        (unsigned short)((SYNC_RATE_TBL / 2)
0998                                 + id));
0999 
1000         for (i = 0; i < 2; temp >>= 8, i++) {
1001 
1002             temp2 >>= 1;
1003             temp3 >>= 1;
1004             temp4 >>= 1;
1005             temp5 >>= 1;
1006             temp6 >>= 1;
1007             switch (temp & 0x3) {
1008             case AUTO_RATE_20:  /* Synchronous, 20 mega-transfers/second */
1009                 temp6 |= 0x8000;
1010                 fallthrough;
1011             case AUTO_RATE_10:  /* Synchronous, 10 mega-transfers/second */
1012                 temp5 |= 0x8000;
1013                 fallthrough;
1014             case AUTO_RATE_05:  /* Synchronous, 5 mega-transfers/second */
1015                 temp2 |= 0x8000;
1016                 fallthrough;
1017             case AUTO_RATE_00:  /* Asynchronous */
1018                 break;
1019             }
1020 
1021             if (temp & DISC_ENABLE_BIT)
1022                 temp3 |= 0x8000;
1023 
1024             if (temp & WIDE_NEGO_BIT)
1025                 temp4 |= 0x8000;
1026 
1027         }
1028     }
1029 
1030     pCardInfo->si_per_targ_init_sync = temp2;
1031     pCardInfo->si_per_targ_no_disc = temp3;
1032     pCardInfo->si_per_targ_wide_nego = temp4;
1033     pCardInfo->si_per_targ_fast_nego = temp5;
1034     pCardInfo->si_per_targ_ultra_nego = temp6;
1035 
1036     if (pCurrNvRam)
1037         i = pCurrNvRam->niSysConf;
1038     else
1039         i = (unsigned
1040              char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1041 
1042     if (pCurrNvRam)
1043         ScamFlg = pCurrNvRam->niScamConf;
1044     else
1045         ScamFlg =
1046             (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1047 
1048     pCardInfo->si_mflags = 0x0000;
1049 
1050     if (i & 0x01)
1051         pCardInfo->si_mflags |= SCSI_PARITY_ENA;
1052 
1053     if (!(i & 0x02))
1054         pCardInfo->si_mflags |= SOFT_RESET;
1055 
1056     if (i & 0x10)
1057         pCardInfo->si_mflags |= EXTENDED_TRANSLATION;
1058 
1059     if (ScamFlg & SCAM_ENABLED)
1060         pCardInfo->si_mflags |= FLAG_SCAM_ENABLED;
1061 
1062     if (ScamFlg & SCAM_LEVEL2)
1063         pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2;
1064 
1065     j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1066     if (i & 0x04) {
1067         j |= SCSI_TERM_ENA_L;
1068     }
1069     WR_HARPOON(ioport + hp_bm_ctrl, j);
1070 
1071     j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1072     if (i & 0x08) {
1073         j |= SCSI_TERM_ENA_H;
1074     }
1075     WR_HARPOON(ioport + hp_ee_ctrl, j);
1076 
1077     if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1078 
1079         pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN;
1080 
1081     pCardInfo->si_card_family = HARPOON_FAMILY;
1082     pCardInfo->si_bustype = BUSTYPE_PCI;
1083 
1084     if (pCurrNvRam) {
1085         pCardInfo->si_card_model[0] = '9';
1086         switch (pCurrNvRam->niModel & 0x0f) {
1087         case MODEL_LT:
1088             pCardInfo->si_card_model[1] = '3';
1089             pCardInfo->si_card_model[2] = '0';
1090             break;
1091         case MODEL_LW:
1092             pCardInfo->si_card_model[1] = '5';
1093             pCardInfo->si_card_model[2] = '0';
1094             break;
1095         case MODEL_DL:
1096             pCardInfo->si_card_model[1] = '3';
1097             pCardInfo->si_card_model[2] = '2';
1098             break;
1099         case MODEL_DW:
1100             pCardInfo->si_card_model[1] = '5';
1101             pCardInfo->si_card_model[2] = '2';
1102             break;
1103         }
1104     } else {
1105         temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1106         pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1107         temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1108 
1109         pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1110         pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1111     }
1112 
1113     if (pCardInfo->si_card_model[1] == '3') {
1114         if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1115             pCardInfo->si_mflags |= LOW_BYTE_TERM;
1116     } else if (pCardInfo->si_card_model[2] == '0') {
1117         temp = RD_HARPOON(ioport + hp_xfer_pad);
1118         WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1119         if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1120             pCardInfo->si_mflags |= LOW_BYTE_TERM;
1121         WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1122         if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1123             pCardInfo->si_mflags |= HIGH_BYTE_TERM;
1124         WR_HARPOON(ioport + hp_xfer_pad, temp);
1125     } else {
1126         temp = RD_HARPOON(ioport + hp_ee_ctrl);
1127         temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1128         WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1129         WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1130         temp3 = 0;
1131         for (i = 0; i < 8; i++) {
1132             temp3 <<= 1;
1133             if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1134                 temp3 |= 1;
1135             WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1136             WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1137         }
1138         WR_HARPOON(ioport + hp_ee_ctrl, temp);
1139         WR_HARPOON(ioport + hp_xfer_pad, temp2);
1140         if (!(temp3 & BIT(7)))
1141             pCardInfo->si_mflags |= LOW_BYTE_TERM;
1142         if (!(temp3 & BIT(6)))
1143             pCardInfo->si_mflags |= HIGH_BYTE_TERM;
1144     }
1145 
1146     ARAM_ACCESS(ioport);
1147 
1148     for (i = 0; i < 4; i++) {
1149 
1150         pCardInfo->si_XlatInfo[i] =
1151             RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1152     }
1153 
1154     /* return with -1 if no sort, else return with
1155        logical card number sorted by BIOS (zero-based) */
1156 
1157     pCardInfo->si_relative_cardnum =
1158         (unsigned
1159          char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1160 
1161     SGRAM_ACCESS(ioport);
1162 
1163     FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1164     FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1165     FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1166     FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1167     FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1168     FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1169     FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1170     FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1171 
1172     pCardInfo->si_present = 0x01;
1173 
1174     return 0;
1175 }
1176 
1177 /*---------------------------------------------------------------------
1178  *
1179  * Function: FlashPoint_HardwareResetHostAdapter
1180  *
1181  * Description: Setup adapter for normal operation (hard reset).
1182  *
1183  *---------------------------------------------------------------------*/
1184 
1185 static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1186                              *pCardInfo)
1187 {
1188     struct sccb_card *CurrCard = NULL;
1189     struct nvram_info *pCurrNvRam;
1190     unsigned char i, j, thisCard, ScamFlg;
1191     unsigned short temp, sync_bit_map, id;
1192     u32 ioport;
1193 
1194     ioport = pCardInfo->si_baseaddr;
1195 
1196     for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1197 
1198         if (thisCard == MAX_CARDS)
1199             return (void *)FAILURE;
1200 
1201         if (FPT_BL_Card[thisCard].ioPort == ioport) {
1202 
1203             CurrCard = &FPT_BL_Card[thisCard];
1204             FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1205             break;
1206         }
1207 
1208         else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1209 
1210             FPT_BL_Card[thisCard].ioPort = ioport;
1211             CurrCard = &FPT_BL_Card[thisCard];
1212 
1213             if (FPT_mbCards)
1214                 for (i = 0; i < FPT_mbCards; i++) {
1215                     if (CurrCard->ioPort ==
1216                         FPT_nvRamInfo[i].niBaseAddr)
1217                         CurrCard->pNvRamInfo =
1218                             &FPT_nvRamInfo[i];
1219                 }
1220             FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1221             CurrCard->cardIndex = thisCard;
1222             CurrCard->cardInfo = pCardInfo;
1223 
1224             break;
1225         }
1226     }
1227 
1228     pCurrNvRam = CurrCard->pNvRamInfo;
1229 
1230     if (pCurrNvRam) {
1231         ScamFlg = pCurrNvRam->niScamConf;
1232     } else {
1233         ScamFlg =
1234             (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1235     }
1236 
1237     FPT_BusMasterInit(ioport);
1238     FPT_XbowInit(ioport, ScamFlg);
1239 
1240     FPT_autoLoadDefaultMap(ioport);
1241 
1242     for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1243     }
1244 
1245     WR_HARPOON(ioport + hp_selfid_0, id);
1246     WR_HARPOON(ioport + hp_selfid_1, 0x00);
1247     WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1248     CurrCard->ourId = pCardInfo->si_id;
1249 
1250     i = (unsigned char)pCardInfo->si_mflags;
1251     if (i & SCSI_PARITY_ENA)
1252         WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1253 
1254     j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1255     if (i & LOW_BYTE_TERM)
1256         j |= SCSI_TERM_ENA_L;
1257     WR_HARPOON(ioport + hp_bm_ctrl, j);
1258 
1259     j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1260     if (i & HIGH_BYTE_TERM)
1261         j |= SCSI_TERM_ENA_H;
1262     WR_HARPOON(ioport + hp_ee_ctrl, j);
1263 
1264     if (!(pCardInfo->si_mflags & SOFT_RESET)) {
1265 
1266         FPT_sresb(ioport, thisCard);
1267 
1268         FPT_scini(thisCard, pCardInfo->si_id, 0);
1269     }
1270 
1271     if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS)
1272         CurrCard->globalFlags |= F_NO_FILTER;
1273 
1274     if (pCurrNvRam) {
1275         if (pCurrNvRam->niSysConf & 0x10)
1276             CurrCard->globalFlags |= F_GREEN_PC;
1277     } else {
1278         if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1279             CurrCard->globalFlags |= F_GREEN_PC;
1280     }
1281 
1282     /* Set global flag to indicate Re-Negotiation to be done on all
1283        ckeck condition */
1284     if (pCurrNvRam) {
1285         if (pCurrNvRam->niScsiConf & 0x04)
1286             CurrCard->globalFlags |= F_DO_RENEGO;
1287     } else {
1288         if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1289             CurrCard->globalFlags |= F_DO_RENEGO;
1290     }
1291 
1292     if (pCurrNvRam) {
1293         if (pCurrNvRam->niScsiConf & 0x08)
1294             CurrCard->globalFlags |= F_CONLUN_IO;
1295     } else {
1296         if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1297             CurrCard->globalFlags |= F_CONLUN_IO;
1298     }
1299 
1300     temp = pCardInfo->si_per_targ_no_disc;
1301 
1302     for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1303 
1304         if (temp & id)
1305             FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1306     }
1307 
1308     sync_bit_map = 0x0001;
1309 
1310     for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1311 
1312         if (pCurrNvRam) {
1313             temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1314             temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1315                 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1316         } else
1317             temp =
1318                 FPT_utilEERead(ioport,
1319                        (unsigned short)((SYNC_RATE_TBL / 2)
1320                                 + id));
1321 
1322         for (i = 0; i < 2; temp >>= 8, i++) {
1323 
1324             if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1325 
1326                 FPT_sccbMgrTbl[thisCard][id * 2 +
1327                              i].TarEEValue =
1328                     (unsigned char)temp;
1329             }
1330 
1331             else {
1332                 FPT_sccbMgrTbl[thisCard][id * 2 +
1333                              i].TarStatus |=
1334                     SYNC_SUPPORTED;
1335                 FPT_sccbMgrTbl[thisCard][id * 2 +
1336                              i].TarEEValue =
1337                     (unsigned char)(temp & ~EE_SYNC_MASK);
1338             }
1339 
1340 /*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1341             (id*2+i >= 8)){
1342 */
1343             if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1344 
1345                 FPT_sccbMgrTbl[thisCard][id * 2 +
1346                              i].TarEEValue |=
1347                     EE_WIDE_SCSI;
1348 
1349             }
1350 
1351             else {  /* NARROW SCSI */
1352                 FPT_sccbMgrTbl[thisCard][id * 2 +
1353                              i].TarStatus |=
1354                     WIDE_NEGOCIATED;
1355             }
1356 
1357             sync_bit_map <<= 1;
1358 
1359         }
1360     }
1361 
1362     WR_HARPOON((ioport + hp_semaphore),
1363            (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1364                    SCCB_MGR_PRESENT));
1365 
1366     return (void *)CurrCard;
1367 }
1368 
1369 static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1370 {
1371     unsigned char i;
1372     u32 portBase;
1373     u32 regOffset;
1374     u32 scamData;
1375     u32 *pScamTbl;
1376     struct nvram_info *pCurrNvRam;
1377 
1378     pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1379 
1380     if (pCurrNvRam) {
1381         FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1382         FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1383         FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1384         FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1385         FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1386 
1387         for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1388             FPT_WrStack(pCurrNvRam->niBaseAddr,
1389                     (unsigned char)(i + 5),
1390                     pCurrNvRam->niSyncTbl[i]);
1391 
1392         portBase = pCurrNvRam->niBaseAddr;
1393 
1394         for (i = 0; i < MAX_SCSI_TAR; i++) {
1395             regOffset = hp_aramBase + 64 + i * 4;
1396             pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1397             scamData = *pScamTbl;
1398             WR_HARP32(portBase, regOffset, scamData);
1399         }
1400 
1401     } else {
1402         FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1403     }
1404 }
1405 
1406 static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1407 {
1408     unsigned char i;
1409     u32 portBase;
1410     u32 regOffset;
1411     u32 scamData;
1412     u32 *pScamTbl;
1413 
1414     pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1415     pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1416     pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1417     pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1418     pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1419 
1420     for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1421         pNvRamInfo->niSyncTbl[i] =
1422             FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1423 
1424     portBase = pNvRamInfo->niBaseAddr;
1425 
1426     for (i = 0; i < MAX_SCSI_TAR; i++) {
1427         regOffset = hp_aramBase + 64 + i * 4;
1428         RD_HARP32(portBase, regOffset, scamData);
1429         pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1430         *pScamTbl = scamData;
1431     }
1432 
1433 }
1434 
1435 static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1436 {
1437     WR_HARPOON(portBase + hp_stack_addr, index);
1438     return RD_HARPOON(portBase + hp_stack_data);
1439 }
1440 
1441 static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1442 {
1443     WR_HARPOON(portBase + hp_stack_addr, index);
1444     WR_HARPOON(portBase + hp_stack_data, data);
1445 }
1446 
1447 static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1448 {
1449     if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1450         return 0;
1451     if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1452         != CLKCTRL_DEFAULT)
1453         return 0;
1454     if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1455         (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1456         return 1;
1457     return 0;
1458 
1459 }
1460 
1461 /*---------------------------------------------------------------------
1462  *
1463  * Function: FlashPoint_StartCCB
1464  *
1465  * Description: Start a command pointed to by p_Sccb. When the
1466  *              command is completed it will be returned via the
1467  *              callback function.
1468  *
1469  *---------------------------------------------------------------------*/
1470 static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1471 {
1472     u32 ioport;
1473     unsigned char thisCard, lun;
1474     struct sccb *pSaveSccb;
1475     CALL_BK_FN callback;
1476     struct sccb_card *pCurrCard = curr_card;
1477 
1478     thisCard = pCurrCard->cardIndex;
1479     ioport = pCurrCard->ioPort;
1480 
1481     if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1482 
1483         p_Sccb->HostStatus = SCCB_COMPLETE;
1484         p_Sccb->SccbStatus = SCCB_ERROR;
1485         callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1486         if (callback)
1487             callback(p_Sccb);
1488 
1489         return;
1490     }
1491 
1492     FPT_sinits(p_Sccb, thisCard);
1493 
1494     if (!pCurrCard->cmdCounter) {
1495         WR_HARPOON(ioport + hp_semaphore,
1496                (RD_HARPOON(ioport + hp_semaphore)
1497                 | SCCB_MGR_ACTIVE));
1498 
1499         if (pCurrCard->globalFlags & F_GREEN_PC) {
1500             WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1501             WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1502         }
1503     }
1504 
1505     pCurrCard->cmdCounter++;
1506 
1507     if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1508 
1509         WR_HARPOON(ioport + hp_semaphore,
1510                (RD_HARPOON(ioport + hp_semaphore)
1511                 | TICKLE_ME));
1512         if (p_Sccb->OperationCode == RESET_COMMAND) {
1513             pSaveSccb =
1514                 pCurrCard->currentSCCB;
1515             pCurrCard->currentSCCB = p_Sccb;
1516             FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1517             pCurrCard->currentSCCB =
1518                 pSaveSccb;
1519         } else {
1520             FPT_queueAddSccb(p_Sccb, thisCard);
1521         }
1522     }
1523 
1524     else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1525 
1526         if (p_Sccb->OperationCode == RESET_COMMAND) {
1527             pSaveSccb =
1528                 pCurrCard->currentSCCB;
1529             pCurrCard->currentSCCB = p_Sccb;
1530             FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1531             pCurrCard->currentSCCB =
1532                 pSaveSccb;
1533         } else {
1534             FPT_queueAddSccb(p_Sccb, thisCard);
1535         }
1536     }
1537 
1538     else {
1539 
1540         MDISABLE_INT(ioport);
1541 
1542         if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1543             ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1544               TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1545             lun = p_Sccb->Lun;
1546         else
1547             lun = 0;
1548         if ((pCurrCard->currentSCCB == NULL) &&
1549             (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1550             && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1551             == 0)) {
1552 
1553             pCurrCard->currentSCCB = p_Sccb;
1554             FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1555         }
1556 
1557         else {
1558 
1559             if (p_Sccb->OperationCode == RESET_COMMAND) {
1560                 pSaveSccb = pCurrCard->currentSCCB;
1561                 pCurrCard->currentSCCB = p_Sccb;
1562                 FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1563                             thisCard);
1564                 pCurrCard->currentSCCB = pSaveSccb;
1565             } else {
1566                 FPT_queueAddSccb(p_Sccb, thisCard);
1567             }
1568         }
1569 
1570         MENABLE_INT(ioport);
1571     }
1572 
1573 }
1574 
1575 /*---------------------------------------------------------------------
1576  *
1577  * Function: FlashPoint_AbortCCB
1578  *
1579  * Description: Abort the command pointed to by p_Sccb.  When the
1580  *              command is completed it will be returned via the
1581  *              callback function.
1582  *
1583  *---------------------------------------------------------------------*/
1584 static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
1585 {
1586     u32 ioport;
1587 
1588     unsigned char thisCard;
1589     CALL_BK_FN callback;
1590     struct sccb *pSaveSCCB;
1591     struct sccb_mgr_tar_info *currTar_Info;
1592 
1593     ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1594 
1595     thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1596 
1597     if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1598 
1599         if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1600 
1601             ((struct sccb_card *)pCurrCard)->cmdCounter--;
1602 
1603             if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1604                 WR_HARPOON(ioport + hp_semaphore,
1605                        (RD_HARPOON(ioport + hp_semaphore)
1606                         & (unsigned
1607                            char)(~(SCCB_MGR_ACTIVE |
1608                                TICKLE_ME))));
1609 
1610             p_Sccb->SccbStatus = SCCB_ABORT;
1611             callback = p_Sccb->SccbCallback;
1612             callback(p_Sccb);
1613 
1614             return 0;
1615         }
1616 
1617         else {
1618             if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1619                 p_Sccb) {
1620                 p_Sccb->SccbStatus = SCCB_ABORT;
1621                 return 0;
1622 
1623             }
1624 
1625             else {
1626                 if (p_Sccb->Sccb_tag) {
1627                     MDISABLE_INT(ioport);
1628                     if (((struct sccb_card *)pCurrCard)->
1629                         discQ_Tbl[p_Sccb->Sccb_tag] ==
1630                         p_Sccb) {
1631                         p_Sccb->SccbStatus = SCCB_ABORT;
1632                         p_Sccb->Sccb_scsistat =
1633                             ABORT_ST;
1634                         p_Sccb->Sccb_scsimsg =
1635                             ABORT_TASK;
1636 
1637                         if (((struct sccb_card *)
1638                              pCurrCard)->currentSCCB ==
1639                             NULL) {
1640                             ((struct sccb_card *)
1641                              pCurrCard)->
1642                     currentSCCB = p_Sccb;
1643                             FPT_ssel(ioport,
1644                                  thisCard);
1645                         } else {
1646                             pSaveSCCB =
1647                                 ((struct sccb_card
1648                                   *)pCurrCard)->
1649                                 currentSCCB;
1650                             ((struct sccb_card *)
1651                              pCurrCard)->
1652                     currentSCCB = p_Sccb;
1653                             FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1654                             ((struct sccb_card *)
1655                              pCurrCard)->
1656                     currentSCCB = pSaveSCCB;
1657                         }
1658                     }
1659                     MENABLE_INT(ioport);
1660                     return 0;
1661                 } else {
1662                     currTar_Info =
1663                         &FPT_sccbMgrTbl[thisCard][p_Sccb->
1664                                       TargID];
1665 
1666                     if (FPT_BL_Card[thisCard].
1667                         discQ_Tbl[currTar_Info->
1668                               LunDiscQ_Idx[p_Sccb->Lun]]
1669                         == p_Sccb) {
1670                         p_Sccb->SccbStatus = SCCB_ABORT;
1671                         return 0;
1672                     }
1673                 }
1674             }
1675         }
1676     }
1677     return -1;
1678 }
1679 
1680 /*---------------------------------------------------------------------
1681  *
1682  * Function: FlashPoint_InterruptPending
1683  *
1684  * Description: Do a quick check to determine if there is a pending
1685  *              interrupt for this card and disable the IRQ Pin if so.
1686  *
1687  *---------------------------------------------------------------------*/
1688 static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1689 {
1690     u32 ioport;
1691 
1692     ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1693 
1694     if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1695         return 1;
1696     }
1697 
1698     else
1699 
1700         return 0;
1701 }
1702 
1703 /*---------------------------------------------------------------------
1704  *
1705  * Function: FlashPoint_HandleInterrupt
1706  *
1707  * Description: This is our entry point when an interrupt is generated
1708  *              by the card and the upper level driver passes it on to
1709  *              us.
1710  *
1711  *---------------------------------------------------------------------*/
1712 static int FlashPoint_HandleInterrupt(void *pcard)
1713 {
1714     struct sccb *currSCCB;
1715     unsigned char thisCard, result, bm_status;
1716     unsigned short hp_int;
1717     unsigned char i, target;
1718     struct sccb_card *pCurrCard = pcard;
1719     u32 ioport;
1720 
1721     thisCard = pCurrCard->cardIndex;
1722     ioport = pCurrCard->ioPort;
1723 
1724     MDISABLE_INT(ioport);
1725 
1726     if (RD_HARPOON(ioport + hp_int_status) & EXT_STATUS_ON)
1727         bm_status = RD_HARPOON(ioport + hp_ext_status) &
1728                     (unsigned char)BAD_EXT_STATUS;
1729     else
1730         bm_status = 0;
1731 
1732     WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1733 
1734     while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1735                 FPT_default_intena) | bm_status) {
1736 
1737         currSCCB = pCurrCard->currentSCCB;
1738 
1739         if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1740             result =
1741                 FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
1742                         hp_int);
1743             WRW_HARPOON((ioport + hp_intstat),
1744                     (FIFO | TIMEOUT | RESET | SCAM_SEL));
1745             bm_status = 0;
1746 
1747             if (result) {
1748 
1749                 MENABLE_INT(ioport);
1750                 return result;
1751             }
1752         }
1753 
1754         else if (hp_int & ICMD_COMP) {
1755 
1756             if (!(hp_int & BUS_FREE)) {
1757                 /* Wait for the BusFree before starting a new command.  We
1758                    must also check for being reselected since the BusFree
1759                    may not show up if another device reselects us in 1.5us or
1760                    less.  SRR Wednesday, 3/8/1995.
1761                  */
1762                 while (!
1763                        (RDW_HARPOON((ioport + hp_intstat)) &
1764                     (BUS_FREE | RSEL))) ;
1765             }
1766 
1767             if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1768 
1769                 FPT_phaseChkFifo(ioport, thisCard);
1770 
1771 /*         WRW_HARPOON((ioport+hp_intstat),
1772             (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1773          */
1774 
1775             WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1776 
1777             FPT_autoCmdCmplt(ioport, thisCard);
1778 
1779         }
1780 
1781         else if (hp_int & ITAR_DISC) {
1782 
1783             if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1784                 FPT_phaseChkFifo(ioport, thisCard);
1785 
1786             if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1787                     SAVE_POINTERS) {
1788 
1789                 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1790                 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1791 
1792                 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1793             }
1794 
1795             currSCCB->Sccb_scsistat = DISCONNECT_ST;
1796             FPT_queueDisconnect(currSCCB, thisCard);
1797 
1798             /* Wait for the BusFree before starting a new command.  We
1799                must also check for being reselected since the BusFree
1800                may not show up if another device reselects us in 1.5us or
1801                less.  SRR Wednesday, 3/8/1995.
1802              */
1803             while (!
1804                    (RDW_HARPOON((ioport + hp_intstat)) &
1805                 (BUS_FREE | RSEL))
1806                    && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1807                     && RD_HARPOON((ioport + hp_scsisig)) ==
1808                     (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1809                      SCSI_IOBIT))) ;
1810 
1811             /*
1812                The additional loop exit condition above detects a timing problem
1813                with the revision D/E harpoon chips.  The caller should reset the
1814                host adapter to recover when 0xFE is returned.
1815              */
1816             if (!
1817                 (RDW_HARPOON((ioport + hp_intstat)) &
1818                  (BUS_FREE | RSEL))) {
1819                 MENABLE_INT(ioport);
1820                 return 0xFE;
1821             }
1822 
1823             WRW_HARPOON((ioport + hp_intstat),
1824                     (BUS_FREE | ITAR_DISC));
1825 
1826             pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1827 
1828         }
1829 
1830         else if (hp_int & RSEL) {
1831 
1832             WRW_HARPOON((ioport + hp_intstat),
1833                     (PROG_HLT | RSEL | PHASE | BUS_FREE));
1834 
1835             if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1836                 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1837                     FPT_phaseChkFifo(ioport, thisCard);
1838 
1839                 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1840                     SAVE_POINTERS) {
1841                     WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1842                     currSCCB->Sccb_XferState |=
1843                         F_NO_DATA_YET;
1844                     currSCCB->Sccb_savedATC =
1845                         currSCCB->Sccb_ATC;
1846                 }
1847 
1848                 WRW_HARPOON((ioport + hp_intstat),
1849                         (BUS_FREE | ITAR_DISC));
1850                 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1851                 FPT_queueDisconnect(currSCCB, thisCard);
1852             }
1853 
1854             FPT_sres(ioport, thisCard, pCurrCard);
1855             FPT_phaseDecode(ioport, thisCard);
1856 
1857         }
1858 
1859         else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1860 
1861             WRW_HARPOON((ioport + hp_intstat),
1862                     (IDO_STRT | XFER_CNT_0));
1863             FPT_phaseDecode(ioport, thisCard);
1864 
1865         }
1866 
1867         else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1868             WRW_HARPOON((ioport + hp_intstat),
1869                     (PHASE | IUNKWN | PROG_HLT));
1870             if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1871                  0x3f) < (unsigned char)SELCHK) {
1872                 FPT_phaseDecode(ioport, thisCard);
1873             } else {
1874                 /* Harpoon problem some SCSI target device respond to selection
1875                    with short BUSY pulse (<400ns) this will make the Harpoon is not able
1876                    to latch the correct Target ID into reg. x53.
1877                    The work around require to correct this reg. But when write to this
1878                    reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1879                    need to read this reg first then restore it later. After update to 0x53 */
1880 
1881                 i = (unsigned
1882                      char)(RD_HARPOON(ioport + hp_fifowrite));
1883                 target =
1884                     (unsigned
1885                      char)(RD_HARPOON(ioport + hp_gp_reg_3));
1886                 WR_HARPOON(ioport + hp_xfer_pad,
1887                        (unsigned char)ID_UNLOCK);
1888                 WR_HARPOON(ioport + hp_select_id,
1889                        (unsigned char)(target | target <<
1890                                4));
1891                 WR_HARPOON(ioport + hp_xfer_pad,
1892                        (unsigned char)0x00);
1893                 WR_HARPOON(ioport + hp_fifowrite, i);
1894                 WR_HARPOON(ioport + hp_autostart_3,
1895                        (AUTO_IMMED + TAG_STRT));
1896             }
1897         }
1898 
1899         else if (hp_int & XFER_CNT_0) {
1900 
1901             WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1902 
1903             FPT_schkdd(ioport, thisCard);
1904 
1905         }
1906 
1907         else if (hp_int & BUS_FREE) {
1908 
1909             WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1910 
1911             if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1912 
1913                 FPT_hostDataXferAbort(ioport, thisCard,
1914                               currSCCB);
1915             }
1916 
1917             FPT_phaseBusFree(ioport, thisCard);
1918         }
1919 
1920         else if (hp_int & ITICKLE) {
1921 
1922             WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1923             pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1924         }
1925 
1926         if (((struct sccb_card *)pCurrCard)->
1927             globalFlags & F_NEW_SCCB_CMD) {
1928 
1929             pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1930 
1931             if (pCurrCard->currentSCCB == NULL)
1932                 FPT_queueSearchSelect(pCurrCard, thisCard);
1933 
1934             if (pCurrCard->currentSCCB != NULL) {
1935                 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1936                 FPT_ssel(ioport, thisCard);
1937             }
1938 
1939             break;
1940 
1941         }
1942 
1943     }           /*end while */
1944 
1945     MENABLE_INT(ioport);
1946 
1947     return 0;
1948 }
1949 
1950 /*---------------------------------------------------------------------
1951  *
1952  * Function: Sccb_bad_isr
1953  *
1954  * Description: Some type of interrupt has occurred which is slightly
1955  *              out of the ordinary.  We will now decode it fully, in
1956  *              this routine.  This is broken up in an attempt to save
1957  *              processing time.
1958  *
1959  *---------------------------------------------------------------------*/
1960 static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1961                      struct sccb_card *pCurrCard,
1962                      unsigned short p_int)
1963 {
1964     unsigned char temp, ScamFlg;
1965     struct sccb_mgr_tar_info *currTar_Info;
1966     struct nvram_info *pCurrNvRam;
1967 
1968     if (RD_HARPOON(p_port + hp_ext_status) &
1969         (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
1970 
1971         if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1972 
1973             FPT_hostDataXferAbort(p_port, p_card,
1974                           pCurrCard->currentSCCB);
1975         }
1976 
1977         if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
1978         {
1979             WR_HARPOON(p_port + hp_pci_stat_cfg,
1980                    (RD_HARPOON(p_port + hp_pci_stat_cfg) &
1981                     ~REC_MASTER_ABORT));
1982 
1983             WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
1984 
1985         }
1986 
1987         if (pCurrCard->currentSCCB != NULL) {
1988 
1989             if (!pCurrCard->currentSCCB->HostStatus)
1990                 pCurrCard->currentSCCB->HostStatus =
1991                     SCCB_BM_ERR;
1992 
1993             FPT_sxfrp(p_port, p_card);
1994 
1995             temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
1996                            (EXT_ARB_ACK | SCSI_TERM_ENA_H));
1997             WR_HARPOON(p_port + hp_ee_ctrl,
1998                    ((unsigned char)temp | SEE_MS | SEE_CS));
1999             WR_HARPOON(p_port + hp_ee_ctrl, temp);
2000 
2001             if (!
2002                 (RDW_HARPOON((p_port + hp_intstat)) &
2003                  (BUS_FREE | RESET))) {
2004                 FPT_phaseDecode(p_port, p_card);
2005             }
2006         }
2007     }
2008 
2009     else if (p_int & RESET) {
2010 
2011         WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2012         WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2013         if (pCurrCard->currentSCCB != NULL) {
2014 
2015             if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2016 
2017                 FPT_hostDataXferAbort(p_port, p_card,
2018                               pCurrCard->currentSCCB);
2019         }
2020 
2021         DISABLE_AUTO(p_port);
2022 
2023         FPT_sresb(p_port, p_card);
2024 
2025         while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2026         }
2027 
2028         pCurrNvRam = pCurrCard->pNvRamInfo;
2029         if (pCurrNvRam) {
2030             ScamFlg = pCurrNvRam->niScamConf;
2031         } else {
2032             ScamFlg =
2033                 (unsigned char)FPT_utilEERead(p_port,
2034                               SCAM_CONFIG / 2);
2035         }
2036 
2037         FPT_XbowInit(p_port, ScamFlg);
2038 
2039         FPT_scini(p_card, pCurrCard->ourId, 0);
2040 
2041         return 0xFF;
2042     }
2043 
2044     else if (p_int & FIFO) {
2045 
2046         WRW_HARPOON((p_port + hp_intstat), FIFO);
2047 
2048         if (pCurrCard->currentSCCB != NULL)
2049             FPT_sxfrp(p_port, p_card);
2050     }
2051 
2052     else if (p_int & TIMEOUT) {
2053 
2054         DISABLE_AUTO(p_port);
2055 
2056         WRW_HARPOON((p_port + hp_intstat),
2057                 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2058                  IUNKWN));
2059 
2060         pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2061 
2062         currTar_Info =
2063             &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2064         if ((pCurrCard->globalFlags & F_CONLUN_IO)
2065             && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2066             TAG_Q_TRYING))
2067             currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2068                 0;
2069         else
2070             currTar_Info->TarLUNBusy[0] = 0;
2071 
2072         if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2073             currTar_Info->TarSyncCtrl = 0;
2074             currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2075         }
2076 
2077         if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2078             currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2079         }
2080 
2081         FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2082                 currTar_Info);
2083 
2084         FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2085 
2086     }
2087 
2088     else if (p_int & SCAM_SEL) {
2089 
2090         FPT_scarb(p_port, LEVEL2_TAR);
2091         FPT_scsel(p_port);
2092         FPT_scasid(p_card, p_port);
2093 
2094         FPT_scbusf(p_port);
2095 
2096         WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2097     }
2098 
2099     return 0x00;
2100 }
2101 
2102 /*---------------------------------------------------------------------
2103  *
2104  * Function: SccbMgrTableInit
2105  *
2106  * Description: Initialize all Sccb manager data structures.
2107  *
2108  *---------------------------------------------------------------------*/
2109 
2110 static void FPT_SccbMgrTableInitAll(void)
2111 {
2112     unsigned char thisCard;
2113 
2114     for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2115         FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2116 
2117         FPT_BL_Card[thisCard].ioPort = 0x00;
2118         FPT_BL_Card[thisCard].cardInfo = NULL;
2119         FPT_BL_Card[thisCard].cardIndex = 0xFF;
2120         FPT_BL_Card[thisCard].ourId = 0x00;
2121         FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2122     }
2123 }
2124 
2125 /*---------------------------------------------------------------------
2126  *
2127  * Function: SccbMgrTableInit
2128  *
2129  * Description: Initialize all Sccb manager data structures.
2130  *
2131  *---------------------------------------------------------------------*/
2132 
2133 static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2134                      unsigned char p_card)
2135 {
2136     unsigned char scsiID, qtag;
2137 
2138     for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2139         FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2140     }
2141 
2142     for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2143         FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2144         FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2145         FPT_SccbMgrTableInitTarget(p_card, scsiID);
2146     }
2147 
2148     pCurrCard->scanIndex = 0x00;
2149     pCurrCard->currentSCCB = NULL;
2150     pCurrCard->globalFlags = 0x00;
2151     pCurrCard->cmdCounter = 0x00;
2152     pCurrCard->tagQ_Lst = 0x01;
2153     pCurrCard->discQCount = 0;
2154 
2155 }
2156 
2157 /*---------------------------------------------------------------------
2158  *
2159  * Function: SccbMgrTableInit
2160  *
2161  * Description: Initialize all Sccb manager data structures.
2162  *
2163  *---------------------------------------------------------------------*/
2164 
2165 static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2166                        unsigned char target)
2167 {
2168 
2169     unsigned char lun, qtag;
2170     struct sccb_mgr_tar_info *currTar_Info;
2171 
2172     currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2173 
2174     currTar_Info->TarSelQ_Cnt = 0;
2175     currTar_Info->TarSyncCtrl = 0;
2176 
2177     currTar_Info->TarSelQ_Head = NULL;
2178     currTar_Info->TarSelQ_Tail = NULL;
2179     currTar_Info->TarTagQ_Cnt = 0;
2180     currTar_Info->TarLUN_CA = 0;
2181 
2182     for (lun = 0; lun < MAX_LUN; lun++) {
2183         currTar_Info->TarLUNBusy[lun] = 0;
2184         currTar_Info->LunDiscQ_Idx[lun] = 0;
2185     }
2186 
2187     for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2188         if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2189             if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2190                 target) {
2191                 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2192                 FPT_BL_Card[p_card].discQCount--;
2193             }
2194         }
2195     }
2196 }
2197 
2198 /*---------------------------------------------------------------------
2199  *
2200  * Function: sfetm
2201  *
2202  * Description: Read in a message byte from the SCSI bus, and check
2203  *              for a parity error.
2204  *
2205  *---------------------------------------------------------------------*/
2206 
2207 static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2208 {
2209     unsigned char message;
2210     unsigned short TimeOutLoop;
2211 
2212     TimeOutLoop = 0;
2213     while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2214            (TimeOutLoop++ < 20000)) {
2215     }
2216 
2217     WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2218 
2219     message = RD_HARPOON(port + hp_scsidata_0);
2220 
2221     WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2222 
2223     if (TimeOutLoop > 20000)
2224         message = 0x00; /* force message byte = 0 if Time Out on Req */
2225 
2226     if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2227         (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2228         WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2229         WR_HARPOON(port + hp_xferstat, 0);
2230         WR_HARPOON(port + hp_fiforead, 0);
2231         WR_HARPOON(port + hp_fifowrite, 0);
2232         if (pCurrSCCB != NULL) {
2233             pCurrSCCB->Sccb_scsimsg = MSG_PARITY_ERROR;
2234         }
2235         message = 0x00;
2236         do {
2237             ACCEPT_MSG_ATN(port);
2238             TimeOutLoop = 0;
2239             while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2240                    (TimeOutLoop++ < 20000)) {
2241             }
2242             if (TimeOutLoop > 20000) {
2243                 WRW_HARPOON((port + hp_intstat), PARITY);
2244                 return message;
2245             }
2246             if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2247                 S_MSGI_PH) {
2248                 WRW_HARPOON((port + hp_intstat), PARITY);
2249                 return message;
2250             }
2251             WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2252 
2253             RD_HARPOON(port + hp_scsidata_0);
2254 
2255             WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2256 
2257         } while (1);
2258 
2259     }
2260     WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2261     WR_HARPOON(port + hp_xferstat, 0);
2262     WR_HARPOON(port + hp_fiforead, 0);
2263     WR_HARPOON(port + hp_fifowrite, 0);
2264     return message;
2265 }
2266 
2267 /*---------------------------------------------------------------------
2268  *
2269  * Function: FPT_ssel
2270  *
2271  * Description: Load up automation and select target device.
2272  *
2273  *---------------------------------------------------------------------*/
2274 
2275 static void FPT_ssel(u32 port, unsigned char p_card)
2276 {
2277 
2278     unsigned char auto_loaded, i, target, *theCCB;
2279 
2280     u32 cdb_reg;
2281     struct sccb_card *CurrCard;
2282     struct sccb *currSCCB;
2283     struct sccb_mgr_tar_info *currTar_Info;
2284     unsigned char lastTag, lun;
2285 
2286     CurrCard = &FPT_BL_Card[p_card];
2287     currSCCB = CurrCard->currentSCCB;
2288     target = currSCCB->TargID;
2289     currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2290     lastTag = CurrCard->tagQ_Lst;
2291 
2292     ARAM_ACCESS(port);
2293 
2294     if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2295         currSCCB->ControlByte &= ~F_USE_CMD_Q;
2296 
2297     if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2298          ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2299 
2300         lun = currSCCB->Lun;
2301     else
2302         lun = 0;
2303 
2304     if (CurrCard->globalFlags & F_TAG_STARTED) {
2305         if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2306             if ((currTar_Info->TarLUN_CA == 0)
2307                 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2308                 == TAG_Q_TRYING)) {
2309 
2310                 if (currTar_Info->TarTagQ_Cnt != 0) {
2311                     currTar_Info->TarLUNBusy[lun] = 1;
2312                     FPT_queueSelectFail(CurrCard, p_card);
2313                     SGRAM_ACCESS(port);
2314                     return;
2315                 }
2316 
2317                 else {
2318                     currTar_Info->TarLUNBusy[lun] = 1;
2319                 }
2320 
2321             }
2322             /*End non-tagged */
2323             else {
2324                 currTar_Info->TarLUNBusy[lun] = 1;
2325             }
2326 
2327         }
2328         /*!Use cmd Q Tagged */
2329         else {
2330             if (currTar_Info->TarLUN_CA == 1) {
2331                 FPT_queueSelectFail(CurrCard, p_card);
2332                 SGRAM_ACCESS(port);
2333                 return;
2334             }
2335 
2336             currTar_Info->TarLUNBusy[lun] = 1;
2337 
2338         }       /*else use cmd Q tagged */
2339 
2340     }
2341     /*if glob tagged started */
2342     else {
2343         currTar_Info->TarLUNBusy[lun] = 1;
2344     }
2345 
2346     if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2347           ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2348          || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2349         if (CurrCard->discQCount >= QUEUE_DEPTH) {
2350             currTar_Info->TarLUNBusy[lun] = 1;
2351             FPT_queueSelectFail(CurrCard, p_card);
2352             SGRAM_ACCESS(port);
2353             return;
2354         }
2355         for (i = 1; i < QUEUE_DEPTH; i++) {
2356             if (++lastTag >= QUEUE_DEPTH)
2357                 lastTag = 1;
2358             if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2359                 CurrCard->tagQ_Lst = lastTag;
2360                 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2361                 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2362                 CurrCard->discQCount++;
2363                 break;
2364             }
2365         }
2366         if (i == QUEUE_DEPTH) {
2367             currTar_Info->TarLUNBusy[lun] = 1;
2368             FPT_queueSelectFail(CurrCard, p_card);
2369             SGRAM_ACCESS(port);
2370             return;
2371         }
2372     }
2373 
2374     auto_loaded = 0;
2375 
2376     WR_HARPOON(port + hp_select_id, target);
2377     WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
2378 
2379     if (currSCCB->OperationCode == RESET_COMMAND) {
2380         WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2381                            (currSCCB->
2382                             Sccb_idmsg & ~DISC_PRIV)));
2383 
2384         WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2385 
2386         currSCCB->Sccb_scsimsg = TARGET_RESET;
2387 
2388         WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2389         auto_loaded = 1;
2390         currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2391 
2392         if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2393             currTar_Info->TarSyncCtrl = 0;
2394             currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2395         }
2396 
2397         if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2398             currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2399         }
2400 
2401         FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2402         FPT_SccbMgrTableInitTarget(p_card, target);
2403 
2404     }
2405 
2406     else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2407         WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2408                            (currSCCB->
2409                             Sccb_idmsg & ~DISC_PRIV)));
2410 
2411         WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2412 
2413         WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2414                              (((unsigned
2415                             char)(currSCCB->
2416                                   ControlByte &
2417                                   TAG_TYPE_MASK)
2418                                >> 6) | (unsigned char)
2419                               0x20)));
2420         WRW_HARPOON((port + SYNC_MSGS + 2),
2421                 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2422         WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2423 
2424         WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2425         auto_loaded = 1;
2426 
2427     }
2428 
2429     else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2430         auto_loaded = FPT_siwidn(port, p_card);
2431         currSCCB->Sccb_scsistat = SELECT_WN_ST;
2432     }
2433 
2434     else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2435            == SYNC_SUPPORTED)) {
2436         auto_loaded = FPT_sisyncn(port, p_card, 0);
2437         currSCCB->Sccb_scsistat = SELECT_SN_ST;
2438     }
2439 
2440     if (!auto_loaded) {
2441 
2442         if (currSCCB->ControlByte & F_USE_CMD_Q) {
2443 
2444             CurrCard->globalFlags |= F_TAG_STARTED;
2445 
2446             if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2447                 == TAG_Q_REJECT) {
2448                 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2449 
2450                 /* Fix up the start instruction with a jump to
2451                    Non-Tag-CMD handling */
2452                 WRW_HARPOON((port + ID_MSG_STRT),
2453                         BRH_OP + ALWAYS + NTCMD);
2454 
2455                 WRW_HARPOON((port + NON_TAG_ID_MSG),
2456                         (MPM_OP + AMSG_OUT +
2457                          currSCCB->Sccb_idmsg));
2458 
2459                 WR_HARPOON(port + hp_autostart_3,
2460                        (SELECT + SELCHK_STRT));
2461 
2462                 /* Setup our STATE so we know what happened when
2463                    the wheels fall off. */
2464                 currSCCB->Sccb_scsistat = SELECT_ST;
2465 
2466                 currTar_Info->TarLUNBusy[lun] = 1;
2467             }
2468 
2469             else {
2470                 WRW_HARPOON((port + ID_MSG_STRT),
2471                         (MPM_OP + AMSG_OUT +
2472                          currSCCB->Sccb_idmsg));
2473 
2474                 WRW_HARPOON((port + ID_MSG_STRT + 2),
2475                         (MPM_OP + AMSG_OUT +
2476                          (((unsigned char)(currSCCB->
2477                                    ControlByte &
2478                                    TAG_TYPE_MASK)
2479                            >> 6) | (unsigned char)0x20)));
2480 
2481                 for (i = 1; i < QUEUE_DEPTH; i++) {
2482                     if (++lastTag >= QUEUE_DEPTH)
2483                         lastTag = 1;
2484                     if (CurrCard->discQ_Tbl[lastTag] ==
2485                         NULL) {
2486                         WRW_HARPOON((port +
2487                                  ID_MSG_STRT + 6),
2488                                 (MPM_OP + AMSG_OUT +
2489                                  lastTag));
2490                         CurrCard->tagQ_Lst = lastTag;
2491                         currSCCB->Sccb_tag = lastTag;
2492                         CurrCard->discQ_Tbl[lastTag] =
2493                             currSCCB;
2494                         CurrCard->discQCount++;
2495                         break;
2496                     }
2497                 }
2498 
2499                 if (i == QUEUE_DEPTH) {
2500                     currTar_Info->TarLUNBusy[lun] = 1;
2501                     FPT_queueSelectFail(CurrCard, p_card);
2502                     SGRAM_ACCESS(port);
2503                     return;
2504                 }
2505 
2506                 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2507 
2508                 WR_HARPOON(port + hp_autostart_3,
2509                        (SELECT + SELCHK_STRT));
2510             }
2511         }
2512 
2513         else {
2514 
2515             WRW_HARPOON((port + ID_MSG_STRT),
2516                     BRH_OP + ALWAYS + NTCMD);
2517 
2518             WRW_HARPOON((port + NON_TAG_ID_MSG),
2519                     (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2520 
2521             currSCCB->Sccb_scsistat = SELECT_ST;
2522 
2523             WR_HARPOON(port + hp_autostart_3,
2524                    (SELECT + SELCHK_STRT));
2525         }
2526 
2527         theCCB = (unsigned char *)&currSCCB->Cdb[0];
2528 
2529         cdb_reg = port + CMD_STRT;
2530 
2531         for (i = 0; i < currSCCB->CdbLength; i++) {
2532             WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2533             cdb_reg += 2;
2534             theCCB++;
2535         }
2536 
2537         if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2538             WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2539 
2540     }
2541     /* auto_loaded */
2542     WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2543     WR_HARPOON(port + hp_xferstat, 0x00);
2544 
2545     WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2546 
2547     WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2548 
2549     if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2550         WR_HARPOON(port + hp_scsictrl_0,
2551                (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2552     } else {
2553 
2554 /*      auto_loaded =  (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2555       auto_loaded |= AUTO_IMMED; */
2556         auto_loaded = AUTO_IMMED;
2557 
2558         DISABLE_AUTO(port);
2559 
2560         WR_HARPOON(port + hp_autostart_3, auto_loaded);
2561     }
2562 
2563     SGRAM_ACCESS(port);
2564 }
2565 
2566 /*---------------------------------------------------------------------
2567  *
2568  * Function: FPT_sres
2569  *
2570  * Description: Hookup the correct CCB and handle the incoming messages.
2571  *
2572  *---------------------------------------------------------------------*/
2573 
2574 static void FPT_sres(u32 port, unsigned char p_card,
2575              struct sccb_card *pCurrCard)
2576 {
2577 
2578     unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2579 
2580     struct sccb_mgr_tar_info *currTar_Info;
2581     struct sccb *currSCCB;
2582 
2583     if (pCurrCard->currentSCCB != NULL) {
2584         currTar_Info =
2585             &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2586         DISABLE_AUTO(port);
2587 
2588         WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2589 
2590         currSCCB = pCurrCard->currentSCCB;
2591         if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2592             currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2593             currSCCB->Sccb_scsistat = BUS_FREE_ST;
2594         }
2595         if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2596             currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2597             currSCCB->Sccb_scsistat = BUS_FREE_ST;
2598         }
2599         if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2600              ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2601               TAG_Q_TRYING))) {
2602             currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2603             if (currSCCB->Sccb_scsistat != ABORT_ST) {
2604                 pCurrCard->discQCount--;
2605                 pCurrCard->discQ_Tbl[currTar_Info->
2606                              LunDiscQ_Idx[currSCCB->
2607                                   Lun]]
2608                     = NULL;
2609             }
2610         } else {
2611             currTar_Info->TarLUNBusy[0] = 0;
2612             if (currSCCB->Sccb_tag) {
2613                 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2614                     pCurrCard->discQCount--;
2615                     pCurrCard->discQ_Tbl[currSCCB->
2616                                  Sccb_tag] = NULL;
2617                 }
2618             } else {
2619                 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2620                     pCurrCard->discQCount--;
2621                     pCurrCard->discQ_Tbl[currTar_Info->
2622                                  LunDiscQ_Idx[0]] =
2623                         NULL;
2624                 }
2625             }
2626         }
2627 
2628         FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2629     }
2630 
2631     WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2632 
2633     our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2634     currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2635 
2636     msgRetryCount = 0;
2637     do {
2638 
2639         currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2640         tag = 0;
2641 
2642         while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2643             if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2644 
2645                 WRW_HARPOON((port + hp_intstat), PHASE);
2646                 return;
2647             }
2648         }
2649 
2650         WRW_HARPOON((port + hp_intstat), PHASE);
2651         if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2652 
2653             message = FPT_sfm(port, pCurrCard->currentSCCB);
2654             if (message) {
2655 
2656                 if (message <= (0x80 | LUN_MASK)) {
2657                     lun = message & (unsigned char)LUN_MASK;
2658 
2659                     if ((currTar_Info->
2660                          TarStatus & TAR_TAG_Q_MASK) ==
2661                         TAG_Q_TRYING) {
2662                         if (currTar_Info->TarTagQ_Cnt !=
2663                             0) {
2664 
2665                             if (!
2666                                 (currTar_Info->
2667                                  TarLUN_CA)) {
2668                                 ACCEPT_MSG(port);   /*Release the ACK for ID msg. */
2669 
2670                                 message =
2671                                     FPT_sfm
2672                                     (port,
2673                                      pCurrCard->
2674                                      currentSCCB);
2675                                 if (message) {
2676                                     ACCEPT_MSG
2677                                         (port);
2678                                 }
2679 
2680                                 else
2681                                     message
2682                                         = 0;
2683 
2684                                 if (message !=
2685                                     0) {
2686                                     tag =
2687                                         FPT_sfm
2688                                         (port,
2689                                          pCurrCard->
2690                                          currentSCCB);
2691 
2692                                     if (!
2693                                         (tag))
2694                                         message
2695                                             =
2696                                             0;
2697                                 }
2698 
2699                             }
2700                             /*C.A. exists! */
2701                         }
2702                         /*End Q cnt != 0 */
2703                     }
2704                     /*End Tag cmds supported! */
2705                 }
2706                 /*End valid ID message.  */
2707                 else {
2708 
2709                     ACCEPT_MSG_ATN(port);
2710                 }
2711 
2712             }
2713             /* End good id message. */
2714             else {
2715 
2716                 message = 0;
2717             }
2718         } else {
2719             ACCEPT_MSG_ATN(port);
2720 
2721             while (!
2722                    (RDW_HARPOON((port + hp_intstat)) &
2723                 (PHASE | RESET))
2724                    && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2725                    && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2726 
2727             return;
2728         }
2729 
2730         if (message == 0) {
2731             msgRetryCount++;
2732             if (msgRetryCount == 1) {
2733                 FPT_SendMsg(port, MSG_PARITY_ERROR);
2734             } else {
2735                 FPT_SendMsg(port, TARGET_RESET);
2736 
2737                 FPT_sssyncv(port, our_target, NARROW_SCSI,
2738                         currTar_Info);
2739 
2740                 if (FPT_sccbMgrTbl[p_card][our_target].
2741                     TarEEValue & EE_SYNC_MASK) {
2742 
2743                     FPT_sccbMgrTbl[p_card][our_target].
2744                         TarStatus &= ~TAR_SYNC_MASK;
2745 
2746                 }
2747 
2748                 if (FPT_sccbMgrTbl[p_card][our_target].
2749                     TarEEValue & EE_WIDE_SCSI) {
2750 
2751                     FPT_sccbMgrTbl[p_card][our_target].
2752                         TarStatus &= ~TAR_WIDE_MASK;
2753                 }
2754 
2755                 FPT_queueFlushTargSccb(p_card, our_target,
2756                                SCCB_COMPLETE);
2757                 FPT_SccbMgrTableInitTarget(p_card, our_target);
2758                 return;
2759             }
2760         }
2761     } while (message == 0);
2762 
2763     if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2764          ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2765         currTar_Info->TarLUNBusy[lun] = 1;
2766         pCurrCard->currentSCCB =
2767             pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2768         if (pCurrCard->currentSCCB != NULL) {
2769             ACCEPT_MSG(port);
2770         } else {
2771             ACCEPT_MSG_ATN(port);
2772         }
2773     } else {
2774         currTar_Info->TarLUNBusy[0] = 1;
2775 
2776         if (tag) {
2777             if (pCurrCard->discQ_Tbl[tag] != NULL) {
2778                 pCurrCard->currentSCCB =
2779                     pCurrCard->discQ_Tbl[tag];
2780                 currTar_Info->TarTagQ_Cnt--;
2781                 ACCEPT_MSG(port);
2782             } else {
2783                 ACCEPT_MSG_ATN(port);
2784             }
2785         } else {
2786             pCurrCard->currentSCCB =
2787                 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2788             if (pCurrCard->currentSCCB != NULL) {
2789                 ACCEPT_MSG(port);
2790             } else {
2791                 ACCEPT_MSG_ATN(port);
2792             }
2793         }
2794     }
2795 
2796     if (pCurrCard->currentSCCB != NULL) {
2797         if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2798             /* During Abort Tag command, the target could have got re-selected
2799                and completed the command. Check the select Q and remove the CCB
2800                if it is in the Select Q */
2801             FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2802         }
2803     }
2804 
2805     while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2806            !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2807            (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2808 }
2809 
2810 static void FPT_SendMsg(u32 port, unsigned char message)
2811 {
2812     while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2813         if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2814 
2815             WRW_HARPOON((port + hp_intstat), PHASE);
2816             return;
2817         }
2818     }
2819 
2820     WRW_HARPOON((port + hp_intstat), PHASE);
2821     if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2822         WRW_HARPOON((port + hp_intstat),
2823                 (BUS_FREE | PHASE | XFER_CNT_0));
2824 
2825         WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2826 
2827         WR_HARPOON(port + hp_scsidata_0, message);
2828 
2829         WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2830 
2831         ACCEPT_MSG(port);
2832 
2833         WR_HARPOON(port + hp_portctrl_0, 0x00);
2834 
2835         if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
2836             (message == ABORT_TASK)) {
2837             while (!
2838                    (RDW_HARPOON((port + hp_intstat)) &
2839                 (BUS_FREE | PHASE))) {
2840             }
2841 
2842             if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2843                 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2844             }
2845         }
2846     }
2847 }
2848 
2849 /*---------------------------------------------------------------------
2850  *
2851  * Function: FPT_sdecm
2852  *
2853  * Description: Determine the proper response to the message from the
2854  *              target device.
2855  *
2856  *---------------------------------------------------------------------*/
2857 static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2858 {
2859     struct sccb *currSCCB;
2860     struct sccb_card *CurrCard;
2861     struct sccb_mgr_tar_info *currTar_Info;
2862 
2863     CurrCard = &FPT_BL_Card[p_card];
2864     currSCCB = CurrCard->currentSCCB;
2865 
2866     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2867 
2868     if (message == RESTORE_POINTERS) {
2869         if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2870             currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2871 
2872             FPT_hostDataXferRestart(currSCCB);
2873         }
2874 
2875         ACCEPT_MSG(port);
2876         WR_HARPOON(port + hp_autostart_1,
2877                (AUTO_IMMED + DISCONNECT_START));
2878     }
2879 
2880     else if (message == COMMAND_COMPLETE) {
2881 
2882         if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2883             currTar_Info->TarStatus &=
2884                 ~(unsigned char)TAR_TAG_Q_MASK;
2885             currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2886         }
2887 
2888         ACCEPT_MSG(port);
2889 
2890     }
2891 
2892     else if ((message == NOP) || (message >= IDENTIFY_BASE) ||
2893          (message == INITIATE_RECOVERY) ||
2894          (message == RELEASE_RECOVERY)) {
2895 
2896         ACCEPT_MSG(port);
2897         WR_HARPOON(port + hp_autostart_1,
2898                (AUTO_IMMED + DISCONNECT_START));
2899     }
2900 
2901     else if (message == MESSAGE_REJECT) {
2902 
2903         if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2904             (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2905             ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2906             || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2907             TAG_Q_TRYING))
2908         {
2909             WRW_HARPOON((port + hp_intstat), BUS_FREE);
2910 
2911             ACCEPT_MSG(port);
2912 
2913             while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2914                    (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2915             {
2916             }
2917 
2918             if (currSCCB->Lun == 0x00) {
2919                 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2920 
2921                     currTar_Info->TarStatus |=
2922                         (unsigned char)SYNC_SUPPORTED;
2923 
2924                     currTar_Info->TarEEValue &=
2925                         ~EE_SYNC_MASK;
2926                 }
2927 
2928                 else if (currSCCB->Sccb_scsistat ==
2929                       SELECT_WN_ST) {
2930 
2931                     currTar_Info->TarStatus =
2932                         (currTar_Info->
2933                          TarStatus & ~WIDE_ENABLED) |
2934                         WIDE_NEGOCIATED;
2935 
2936                     currTar_Info->TarEEValue &=
2937                         ~EE_WIDE_SCSI;
2938 
2939                 }
2940 
2941                 else if ((currTar_Info->
2942                       TarStatus & TAR_TAG_Q_MASK) ==
2943                      TAG_Q_TRYING) {
2944                     currTar_Info->TarStatus =
2945                         (currTar_Info->
2946                          TarStatus & ~(unsigned char)
2947                          TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2948 
2949                     currSCCB->ControlByte &= ~F_USE_CMD_Q;
2950                     CurrCard->discQCount--;
2951                     CurrCard->discQ_Tbl[currSCCB->
2952                                 Sccb_tag] = NULL;
2953                     currSCCB->Sccb_tag = 0x00;
2954 
2955                 }
2956             }
2957 
2958             if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2959 
2960                 if (currSCCB->Lun == 0x00) {
2961                     WRW_HARPOON((port + hp_intstat),
2962                             BUS_FREE);
2963                     CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2964                 }
2965             }
2966 
2967             else {
2968 
2969                 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
2970                     ((currTar_Info->
2971                       TarStatus & TAR_TAG_Q_MASK) !=
2972                      TAG_Q_TRYING))
2973                     currTar_Info->TarLUNBusy[currSCCB->
2974                                  Lun] = 1;
2975                 else
2976                     currTar_Info->TarLUNBusy[0] = 1;
2977 
2978                 currSCCB->ControlByte &=
2979                     ~(unsigned char)F_USE_CMD_Q;
2980 
2981                 WR_HARPOON(port + hp_autostart_1,
2982                        (AUTO_IMMED + DISCONNECT_START));
2983 
2984             }
2985         }
2986 
2987         else {
2988             ACCEPT_MSG(port);
2989 
2990             while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2991                    (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2992             {
2993             }
2994 
2995             if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
2996                 WR_HARPOON(port + hp_autostart_1,
2997                        (AUTO_IMMED + DISCONNECT_START));
2998             }
2999         }
3000     }
3001 
3002     else if (message == EXTENDED_MESSAGE) {
3003 
3004         ACCEPT_MSG(port);
3005         FPT_shandem(port, p_card, currSCCB);
3006     }
3007 
3008     else if (message == IGNORE_WIDE_RESIDUE) {
3009 
3010         ACCEPT_MSG(port);   /* ACK the RESIDUE MSG */
3011 
3012         message = FPT_sfm(port, currSCCB);
3013 
3014         if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
3015             ACCEPT_MSG(port);
3016         WR_HARPOON(port + hp_autostart_1,
3017                (AUTO_IMMED + DISCONNECT_START));
3018     }
3019 
3020     else {
3021 
3022         currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3023         currSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3024 
3025         ACCEPT_MSG_ATN(port);
3026         WR_HARPOON(port + hp_autostart_1,
3027                (AUTO_IMMED + DISCONNECT_START));
3028     }
3029 }
3030 
3031 /*---------------------------------------------------------------------
3032  *
3033  * Function: FPT_shandem
3034  *
3035  * Description: Decide what to do with the extended message.
3036  *
3037  *---------------------------------------------------------------------*/
3038 static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3039 {
3040     unsigned char length, message;
3041 
3042     length = FPT_sfm(port, pCurrSCCB);
3043     if (length) {
3044 
3045         ACCEPT_MSG(port);
3046         message = FPT_sfm(port, pCurrSCCB);
3047         if (message) {
3048 
3049             if (message == EXTENDED_SDTR) {
3050 
3051                 if (length == 0x03) {
3052 
3053                     ACCEPT_MSG(port);
3054                     FPT_stsyncn(port, p_card);
3055                 } else {
3056 
3057                     pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3058                     ACCEPT_MSG_ATN(port);
3059                 }
3060             } else if (message == EXTENDED_WDTR) {
3061 
3062                 if (length == 0x02) {
3063 
3064                     ACCEPT_MSG(port);
3065                     FPT_stwidn(port, p_card);
3066                 } else {
3067 
3068                     pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3069                     ACCEPT_MSG_ATN(port);
3070 
3071                     WR_HARPOON(port + hp_autostart_1,
3072                            (AUTO_IMMED +
3073                             DISCONNECT_START));
3074                 }
3075             } else {
3076 
3077                 pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3078                 ACCEPT_MSG_ATN(port);
3079 
3080                 WR_HARPOON(port + hp_autostart_1,
3081                        (AUTO_IMMED + DISCONNECT_START));
3082             }
3083         } else {
3084             if (pCurrSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
3085                 ACCEPT_MSG(port);
3086             WR_HARPOON(port + hp_autostart_1,
3087                    (AUTO_IMMED + DISCONNECT_START));
3088         }
3089     } else {
3090         if (pCurrSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)
3091             WR_HARPOON(port + hp_autostart_1,
3092                    (AUTO_IMMED + DISCONNECT_START));
3093     }
3094 }
3095 
3096 /*---------------------------------------------------------------------
3097  *
3098  * Function: FPT_sisyncn
3099  *
3100  * Description: Read in a message byte from the SCSI bus, and check
3101  *              for a parity error.
3102  *
3103  *---------------------------------------------------------------------*/
3104 
3105 static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3106                  unsigned char syncFlag)
3107 {
3108     struct sccb *currSCCB;
3109     struct sccb_mgr_tar_info *currTar_Info;
3110 
3111     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3112     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3113 
3114     if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3115 
3116         WRW_HARPOON((port + ID_MSG_STRT),
3117                 (MPM_OP + AMSG_OUT +
3118                  (currSCCB->
3119                   Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3120 
3121         WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3122 
3123         WRW_HARPOON((port + SYNC_MSGS + 0),
3124                 (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3125         WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3126         WRW_HARPOON((port + SYNC_MSGS + 4),
3127                 (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
3128 
3129         if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3130 
3131             WRW_HARPOON((port + SYNC_MSGS + 6),
3132                     (MPM_OP + AMSG_OUT + 12));
3133 
3134         else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3135              EE_SYNC_10MB)
3136 
3137             WRW_HARPOON((port + SYNC_MSGS + 6),
3138                     (MPM_OP + AMSG_OUT + 25));
3139 
3140         else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3141              EE_SYNC_5MB)
3142 
3143             WRW_HARPOON((port + SYNC_MSGS + 6),
3144                     (MPM_OP + AMSG_OUT + 50));
3145 
3146         else
3147             WRW_HARPOON((port + SYNC_MSGS + 6),
3148                     (MPM_OP + AMSG_OUT + 00));
3149 
3150         WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3151         WRW_HARPOON((port + SYNC_MSGS + 10),
3152                 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3153         WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3154 
3155         if (syncFlag == 0) {
3156             WR_HARPOON(port + hp_autostart_3,
3157                    (SELECT + SELCHK_STRT));
3158             currTar_Info->TarStatus =
3159                 ((currTar_Info->
3160                   TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3161                  (unsigned char)SYNC_TRYING);
3162         } else {
3163             WR_HARPOON(port + hp_autostart_3,
3164                    (AUTO_IMMED + CMD_ONLY_STRT));
3165         }
3166 
3167         return 1;
3168     }
3169 
3170     else {
3171 
3172         currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3173         currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3174         return 0;
3175     }
3176 }
3177 
3178 /*---------------------------------------------------------------------
3179  *
3180  * Function: FPT_stsyncn
3181  *
3182  * Description: The has sent us a Sync Nego message so handle it as
3183  *              necessary.
3184  *
3185  *---------------------------------------------------------------------*/
3186 static void FPT_stsyncn(u32 port, unsigned char p_card)
3187 {
3188     unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3189     struct sccb *currSCCB;
3190     struct sccb_mgr_tar_info *currTar_Info;
3191 
3192     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3193     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3194 
3195     sync_msg = FPT_sfm(port, currSCCB);
3196 
3197     if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3198         WR_HARPOON(port + hp_autostart_1,
3199                (AUTO_IMMED + DISCONNECT_START));
3200         return;
3201     }
3202 
3203     ACCEPT_MSG(port);
3204 
3205     offset = FPT_sfm(port, currSCCB);
3206 
3207     if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3208         WR_HARPOON(port + hp_autostart_1,
3209                (AUTO_IMMED + DISCONNECT_START));
3210         return;
3211     }
3212 
3213     if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3214 
3215         our_sync_msg = 12;  /* Setup our Message to 20mb/s */
3216 
3217     else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3218 
3219         our_sync_msg = 25;  /* Setup our Message to 10mb/s */
3220 
3221     else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3222 
3223         our_sync_msg = 50;  /* Setup our Message to 5mb/s */
3224     else
3225 
3226         our_sync_msg = 0;   /* Message = Async */
3227 
3228     if (sync_msg < our_sync_msg) {
3229         sync_msg = our_sync_msg;    /*if faster, then set to max. */
3230     }
3231 
3232     if (offset == ASYNC)
3233         sync_msg = ASYNC;
3234 
3235     if (offset > MAX_OFFSET)
3236         offset = MAX_OFFSET;
3237 
3238     sync_reg = 0x00;
3239 
3240     if (sync_msg > 12)
3241 
3242         sync_reg = 0x20;    /* Use 10MB/s */
3243 
3244     if (sync_msg > 25)
3245 
3246         sync_reg = 0x40;    /* Use 6.6MB/s */
3247 
3248     if (sync_msg > 38)
3249 
3250         sync_reg = 0x60;    /* Use 5MB/s */
3251 
3252     if (sync_msg > 50)
3253 
3254         sync_reg = 0x80;    /* Use 4MB/s */
3255 
3256     if (sync_msg > 62)
3257 
3258         sync_reg = 0xA0;    /* Use 3.33MB/s */
3259 
3260     if (sync_msg > 75)
3261 
3262         sync_reg = 0xC0;    /* Use 2.85MB/s */
3263 
3264     if (sync_msg > 87)
3265 
3266         sync_reg = 0xE0;    /* Use 2.5MB/s */
3267 
3268     if (sync_msg > 100) {
3269 
3270         sync_reg = 0x00;    /* Use ASYNC */
3271         offset = 0x00;
3272     }
3273 
3274     if (currTar_Info->TarStatus & WIDE_ENABLED)
3275 
3276         sync_reg |= offset;
3277 
3278     else
3279 
3280         sync_reg |= (offset | NARROW_SCSI);
3281 
3282     FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3283 
3284     if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3285 
3286         ACCEPT_MSG(port);
3287 
3288         currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3289                         ~(unsigned char)TAR_SYNC_MASK) |
3290                        (unsigned char)SYNC_SUPPORTED);
3291 
3292         WR_HARPOON(port + hp_autostart_1,
3293                (AUTO_IMMED + DISCONNECT_START));
3294     }
3295 
3296     else {
3297 
3298         ACCEPT_MSG_ATN(port);
3299 
3300         FPT_sisyncr(port, sync_msg, offset);
3301 
3302         currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3303                         ~(unsigned char)TAR_SYNC_MASK) |
3304                        (unsigned char)SYNC_SUPPORTED);
3305     }
3306 }
3307 
3308 /*---------------------------------------------------------------------
3309  *
3310  * Function: FPT_sisyncr
3311  *
3312  * Description: Answer the targets sync message.
3313  *
3314  *---------------------------------------------------------------------*/
3315 static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3316             unsigned char offset)
3317 {
3318     ARAM_ACCESS(port);
3319     WRW_HARPOON((port + SYNC_MSGS + 0),
3320             (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3321     WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3322     WRW_HARPOON((port + SYNC_MSGS + 4),
3323             (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
3324     WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3325     WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3326     WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3327     WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3328     SGRAM_ACCESS(port);
3329 
3330     WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3331     WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3332 
3333     WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3334 
3335     while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3336     }
3337 }
3338 
3339 /*---------------------------------------------------------------------
3340  *
3341  * Function: FPT_siwidn
3342  *
3343  * Description: Read in a message byte from the SCSI bus, and check
3344  *              for a parity error.
3345  *
3346  *---------------------------------------------------------------------*/
3347 
3348 static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3349 {
3350     struct sccb *currSCCB;
3351     struct sccb_mgr_tar_info *currTar_Info;
3352 
3353     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3354     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3355 
3356     if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3357 
3358         WRW_HARPOON((port + ID_MSG_STRT),
3359                 (MPM_OP + AMSG_OUT +
3360                  (currSCCB->
3361                   Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3362 
3363         WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3364 
3365         WRW_HARPOON((port + SYNC_MSGS + 0),
3366                 (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3367         WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3368         WRW_HARPOON((port + SYNC_MSGS + 4),
3369                 (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
3370         WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3371         WRW_HARPOON((port + SYNC_MSGS + 8),
3372                 (MPM_OP + AMSG_OUT + SM16BIT));
3373         WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3374 
3375         WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3376 
3377         currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3378                         ~(unsigned char)TAR_WIDE_MASK) |
3379                        (unsigned char)WIDE_ENABLED);
3380 
3381         return 1;
3382     }
3383 
3384     else {
3385 
3386         currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3387                         ~(unsigned char)TAR_WIDE_MASK) |
3388                        WIDE_NEGOCIATED);
3389 
3390         currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3391         return 0;
3392     }
3393 }
3394 
3395 /*---------------------------------------------------------------------
3396  *
3397  * Function: FPT_stwidn
3398  *
3399  * Description: The has sent us a Wide Nego message so handle it as
3400  *              necessary.
3401  *
3402  *---------------------------------------------------------------------*/
3403 static void FPT_stwidn(u32 port, unsigned char p_card)
3404 {
3405     unsigned char width;
3406     struct sccb *currSCCB;
3407     struct sccb_mgr_tar_info *currTar_Info;
3408 
3409     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3410     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3411 
3412     width = FPT_sfm(port, currSCCB);
3413 
3414     if ((width == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3415         WR_HARPOON(port + hp_autostart_1,
3416                (AUTO_IMMED + DISCONNECT_START));
3417         return;
3418     }
3419 
3420     if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3421         width = 0;
3422 
3423     if (width) {
3424         currTar_Info->TarStatus |= WIDE_ENABLED;
3425         width = 0;
3426     } else {
3427         width = NARROW_SCSI;
3428         currTar_Info->TarStatus &= ~WIDE_ENABLED;
3429     }
3430 
3431     FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3432 
3433     if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3434 
3435         currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3436 
3437         if (!
3438             ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3439              SYNC_SUPPORTED)) {
3440             ACCEPT_MSG_ATN(port);
3441             ARAM_ACCESS(port);
3442             FPT_sisyncn(port, p_card, 1);
3443             currSCCB->Sccb_scsistat = SELECT_SN_ST;
3444             SGRAM_ACCESS(port);
3445         } else {
3446             ACCEPT_MSG(port);
3447             WR_HARPOON(port + hp_autostart_1,
3448                    (AUTO_IMMED + DISCONNECT_START));
3449         }
3450     }
3451 
3452     else {
3453 
3454         ACCEPT_MSG_ATN(port);
3455 
3456         if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3457             width = SM16BIT;
3458         else
3459             width = SM8BIT;
3460 
3461         FPT_siwidr(port, width);
3462 
3463         currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3464     }
3465 }
3466 
3467 /*---------------------------------------------------------------------
3468  *
3469  * Function: FPT_siwidr
3470  *
3471  * Description: Answer the targets Wide nego message.
3472  *
3473  *---------------------------------------------------------------------*/
3474 static void FPT_siwidr(u32 port, unsigned char width)
3475 {
3476     ARAM_ACCESS(port);
3477     WRW_HARPOON((port + SYNC_MSGS + 0),
3478             (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3479     WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3480     WRW_HARPOON((port + SYNC_MSGS + 4),
3481             (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
3482     WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3483     WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3484     WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3485     SGRAM_ACCESS(port);
3486 
3487     WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3488     WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3489 
3490     WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3491 
3492     while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3493     }
3494 }
3495 
3496 /*---------------------------------------------------------------------
3497  *
3498  * Function: FPT_sssyncv
3499  *
3500  * Description: Write the desired value to the Sync Register for the
3501  *              ID specified.
3502  *
3503  *---------------------------------------------------------------------*/
3504 static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3505             unsigned char p_sync_value,
3506             struct sccb_mgr_tar_info *currTar_Info)
3507 {
3508     unsigned char index;
3509 
3510     index = p_id;
3511 
3512     switch (index) {
3513 
3514     case 0:
3515         index = 12; /* hp_synctarg_0 */
3516         break;
3517     case 1:
3518         index = 13; /* hp_synctarg_1 */
3519         break;
3520     case 2:
3521         index = 14; /* hp_synctarg_2 */
3522         break;
3523     case 3:
3524         index = 15; /* hp_synctarg_3 */
3525         break;
3526     case 4:
3527         index = 8;  /* hp_synctarg_4 */
3528         break;
3529     case 5:
3530         index = 9;  /* hp_synctarg_5 */
3531         break;
3532     case 6:
3533         index = 10; /* hp_synctarg_6 */
3534         break;
3535     case 7:
3536         index = 11; /* hp_synctarg_7 */
3537         break;
3538     case 8:
3539         index = 4;  /* hp_synctarg_8 */
3540         break;
3541     case 9:
3542         index = 5;  /* hp_synctarg_9 */
3543         break;
3544     case 10:
3545         index = 6;  /* hp_synctarg_10 */
3546         break;
3547     case 11:
3548         index = 7;  /* hp_synctarg_11 */
3549         break;
3550     case 12:
3551         index = 0;  /* hp_synctarg_12 */
3552         break;
3553     case 13:
3554         index = 1;  /* hp_synctarg_13 */
3555         break;
3556     case 14:
3557         index = 2;  /* hp_synctarg_14 */
3558         break;
3559     case 15:
3560         index = 3;  /* hp_synctarg_15 */
3561 
3562     }
3563 
3564     WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3565 
3566     currTar_Info->TarSyncCtrl = p_sync_value;
3567 }
3568 
3569 /*---------------------------------------------------------------------
3570  *
3571  * Function: FPT_sresb
3572  *
3573  * Description: Reset the desired card's SCSI bus.
3574  *
3575  *---------------------------------------------------------------------*/
3576 static void FPT_sresb(u32 port, unsigned char p_card)
3577 {
3578     unsigned char scsiID, i;
3579 
3580     struct sccb_mgr_tar_info *currTar_Info;
3581 
3582     WR_HARPOON(port + hp_page_ctrl,
3583            (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3584     WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3585 
3586     WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3587 
3588     scsiID = RD_HARPOON(port + hp_seltimeout);
3589     WR_HARPOON(port + hp_seltimeout, TO_5ms);
3590     WRW_HARPOON((port + hp_intstat), TIMEOUT);
3591 
3592     WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3593 
3594     while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3595     }
3596 
3597     WR_HARPOON(port + hp_seltimeout, scsiID);
3598 
3599     WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3600 
3601     FPT_Wait(port, TO_5ms);
3602 
3603     WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3604 
3605     WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3606 
3607     for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3608         currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3609 
3610         if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3611             currTar_Info->TarSyncCtrl = 0;
3612             currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3613         }
3614 
3615         if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3616             currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3617         }
3618 
3619         FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3620 
3621         FPT_SccbMgrTableInitTarget(p_card, scsiID);
3622     }
3623 
3624     FPT_BL_Card[p_card].scanIndex = 0x00;
3625     FPT_BL_Card[p_card].currentSCCB = NULL;
3626     FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3627                          | F_NEW_SCCB_CMD);
3628     FPT_BL_Card[p_card].cmdCounter = 0x00;
3629     FPT_BL_Card[p_card].discQCount = 0x00;
3630     FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3631 
3632     for (i = 0; i < QUEUE_DEPTH; i++)
3633         FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3634 
3635     WR_HARPOON(port + hp_page_ctrl,
3636            (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3637 
3638 }
3639 
3640 /*---------------------------------------------------------------------
3641  *
3642  * Function: FPT_ssenss
3643  *
3644  * Description: Setup for the Auto Sense command.
3645  *
3646  *---------------------------------------------------------------------*/
3647 static void FPT_ssenss(struct sccb_card *pCurrCard)
3648 {
3649     unsigned char i;
3650     struct sccb *currSCCB;
3651 
3652     currSCCB = pCurrCard->currentSCCB;
3653 
3654     currSCCB->Save_CdbLen = currSCCB->CdbLength;
3655 
3656     for (i = 0; i < 6; i++) {
3657 
3658         currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3659     }
3660 
3661     currSCCB->CdbLength = SIX_BYTE_CMD;
3662     currSCCB->Cdb[0] = REQUEST_SENSE;
3663     currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0;  /*Keep LUN. */
3664     currSCCB->Cdb[2] = 0x00;
3665     currSCCB->Cdb[3] = 0x00;
3666     currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3667     currSCCB->Cdb[5] = 0x00;
3668 
3669     currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3670 
3671     currSCCB->Sccb_ATC = 0x00;
3672 
3673     currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3674 
3675     currSCCB->Sccb_XferState &= ~F_SG_XFER;
3676 
3677     currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3678 
3679     currSCCB->ControlByte = 0x00;
3680 
3681     currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3682 }
3683 
3684 /*---------------------------------------------------------------------
3685  *
3686  * Function: FPT_sxfrp
3687  *
3688  * Description: Transfer data into the bit bucket until the device
3689  *              decides to switch phase.
3690  *
3691  *---------------------------------------------------------------------*/
3692 
3693 static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3694 {
3695     unsigned char curr_phz;
3696 
3697     DISABLE_AUTO(p_port);
3698 
3699     if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3700 
3701         FPT_hostDataXferAbort(p_port, p_card,
3702                       FPT_BL_Card[p_card].currentSCCB);
3703 
3704     }
3705 
3706     /* If the Automation handled the end of the transfer then do not
3707        match the phase or we will get out of sync with the ISR.       */
3708 
3709     if (RDW_HARPOON((p_port + hp_intstat)) &
3710         (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3711         return;
3712 
3713     WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3714 
3715     curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3716 
3717     WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3718 
3719     WR_HARPOON(p_port + hp_scsisig, curr_phz);
3720 
3721     while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3722            (curr_phz ==
3723         (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3724     {
3725         if (curr_phz & (unsigned char)SCSI_IOBIT) {
3726             WR_HARPOON(p_port + hp_portctrl_0,
3727                    (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3728 
3729             if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3730                 RD_HARPOON(p_port + hp_fifodata_0);
3731             }
3732         } else {
3733             WR_HARPOON(p_port + hp_portctrl_0,
3734                    (SCSI_PORT | HOST_PORT | HOST_WRT));
3735             if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3736                 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3737             }
3738         }
3739     }           /* End of While loop for padding data I/O phase */
3740 
3741     while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3742         if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3743             break;
3744     }
3745 
3746     WR_HARPOON(p_port + hp_portctrl_0,
3747            (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3748     while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3749         RD_HARPOON(p_port + hp_fifodata_0);
3750     }
3751 
3752     if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3753         WR_HARPOON(p_port + hp_autostart_0,
3754                (AUTO_IMMED + DISCONNECT_START));
3755         while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3756         }
3757 
3758         if (RDW_HARPOON((p_port + hp_intstat)) &
3759             (ICMD_COMP | ITAR_DISC))
3760             while (!
3761                    (RDW_HARPOON((p_port + hp_intstat)) &
3762                 (BUS_FREE | RSEL))) ;
3763     }
3764 }
3765 
3766 /*---------------------------------------------------------------------
3767  *
3768  * Function: FPT_schkdd
3769  *
3770  * Description: Make sure data has been flushed from both FIFOs and abort
3771  *              the operations if necessary.
3772  *
3773  *---------------------------------------------------------------------*/
3774 
3775 static void FPT_schkdd(u32 port, unsigned char p_card)
3776 {
3777     unsigned short TimeOutLoop;
3778     unsigned char sPhase;
3779 
3780     struct sccb *currSCCB;
3781 
3782     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3783 
3784     if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3785         (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3786         return;
3787     }
3788 
3789     if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3790 
3791         currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3792 
3793         currSCCB->Sccb_XferCnt = 1;
3794 
3795         currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3796         WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3797         WR_HARPOON(port + hp_xferstat, 0x00);
3798     }
3799 
3800     else {
3801 
3802         currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3803 
3804         currSCCB->Sccb_XferCnt = 0;
3805     }
3806 
3807     if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3808         (currSCCB->HostStatus == SCCB_COMPLETE)) {
3809 
3810         currSCCB->HostStatus = SCCB_PARITY_ERR;
3811         WRW_HARPOON((port + hp_intstat), PARITY);
3812     }
3813 
3814     FPT_hostDataXferAbort(port, p_card, currSCCB);
3815 
3816     while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3817     }
3818 
3819     TimeOutLoop = 0;
3820 
3821     while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3822         if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3823             return;
3824         }
3825         if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3826             break;
3827         }
3828         if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3829             return;
3830         }
3831         if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3832             || (TimeOutLoop++ > 0x3000))
3833             break;
3834     }
3835 
3836     sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3837     if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3838         (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3839         (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3840         (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3841 
3842         WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3843 
3844         if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3845             if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3846                 FPT_phaseDataIn(port, p_card);
3847             }
3848 
3849             else {
3850                 FPT_phaseDataOut(port, p_card);
3851             }
3852         } else {
3853             FPT_sxfrp(port, p_card);
3854             if (!(RDW_HARPOON((port + hp_intstat)) &
3855                   (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3856                 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3857                 FPT_phaseDecode(port, p_card);
3858             }
3859         }
3860 
3861     }
3862 
3863     else {
3864         WR_HARPOON(port + hp_portctrl_0, 0x00);
3865     }
3866 }
3867 
3868 /*---------------------------------------------------------------------
3869  *
3870  * Function: FPT_sinits
3871  *
3872  * Description: Setup SCCB manager fields in this SCCB.
3873  *
3874  *---------------------------------------------------------------------*/
3875 
3876 static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3877 {
3878     struct sccb_mgr_tar_info *currTar_Info;
3879 
3880     if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3881         return;
3882     }
3883     currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3884 
3885     p_sccb->Sccb_XferState = 0x00;
3886     p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3887 
3888     if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3889         (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3890 
3891         p_sccb->Sccb_SGoffset = 0;
3892         p_sccb->Sccb_XferState = F_SG_XFER;
3893         p_sccb->Sccb_XferCnt = 0x00;
3894     }
3895 
3896     if (p_sccb->DataLength == 0x00)
3897 
3898         p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3899 
3900     if (p_sccb->ControlByte & F_USE_CMD_Q) {
3901         if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3902             p_sccb->ControlByte &= ~F_USE_CMD_Q;
3903 
3904         else
3905             currTar_Info->TarStatus |= TAG_Q_TRYING;
3906     }
3907 
3908 /*      For !single SCSI device in system  & device allow Disconnect
3909     or command is tag_q type then send Cmd with Disconnect Enable
3910     else send Cmd with Disconnect Disable */
3911 
3912 /*
3913    if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3914       (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3915       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3916 */
3917     if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3918         (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3919         p_sccb->Sccb_idmsg = IDENTIFY(true, p_sccb->Lun);
3920     } else {
3921         p_sccb->Sccb_idmsg = IDENTIFY(false, p_sccb->Lun);
3922     }
3923 
3924     p_sccb->HostStatus = 0x00;
3925     p_sccb->TargetStatus = 0x00;
3926     p_sccb->Sccb_tag = 0x00;
3927     p_sccb->Sccb_MGRFlags = 0x00;
3928     p_sccb->Sccb_sgseg = 0x00;
3929     p_sccb->Sccb_ATC = 0x00;
3930     p_sccb->Sccb_savedATC = 0x00;
3931 /*
3932    p_sccb->SccbVirtDataPtr    = 0x00;
3933    p_sccb->Sccb_forwardlink   = NULL;
3934    p_sccb->Sccb_backlink      = NULL;
3935  */
3936     p_sccb->Sccb_scsistat = BUS_FREE_ST;
3937     p_sccb->SccbStatus = SCCB_IN_PROCESS;
3938     p_sccb->Sccb_scsimsg = NOP;
3939 
3940 }
3941 
3942 /*---------------------------------------------------------------------
3943  *
3944  * Function: Phase Decode
3945  *
3946  * Description: Determine the phase and call the appropriate function.
3947  *
3948  *---------------------------------------------------------------------*/
3949 
3950 static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3951 {
3952     unsigned char phase_ref;
3953     void (*phase) (u32, unsigned char);
3954 
3955     DISABLE_AUTO(p_port);
3956 
3957     phase_ref =
3958         (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3959 
3960     phase = FPT_s_PhaseTbl[phase_ref];
3961 
3962     (*phase) (p_port, p_card);  /* Call the correct phase func */
3963 }
3964 
3965 /*---------------------------------------------------------------------
3966  *
3967  * Function: Data Out Phase
3968  *
3969  * Description: Start up both the BusMaster and Xbow.
3970  *
3971  *---------------------------------------------------------------------*/
3972 
3973 static void FPT_phaseDataOut(u32 port, unsigned char p_card)
3974 {
3975 
3976     struct sccb *currSCCB;
3977 
3978     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3979     if (currSCCB == NULL) {
3980         return;     /* Exit if No SCCB record */
3981     }
3982 
3983     currSCCB->Sccb_scsistat = DATA_OUT_ST;
3984     currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
3985 
3986     WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3987 
3988     WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
3989 
3990     WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
3991 
3992     FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
3993 
3994     if (currSCCB->Sccb_XferCnt == 0) {
3995 
3996         if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
3997             (currSCCB->HostStatus == SCCB_COMPLETE))
3998             currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
3999 
4000         FPT_sxfrp(port, p_card);
4001         if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4002             FPT_phaseDecode(port, p_card);
4003     }
4004 }
4005 
4006 /*---------------------------------------------------------------------
4007  *
4008  * Function: Data In Phase
4009  *
4010  * Description: Startup the BusMaster and the XBOW.
4011  *
4012  *---------------------------------------------------------------------*/
4013 
4014 static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4015 {
4016 
4017     struct sccb *currSCCB;
4018 
4019     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4020 
4021     if (currSCCB == NULL) {
4022         return;     /* Exit if No SCCB record */
4023     }
4024 
4025     currSCCB->Sccb_scsistat = DATA_IN_ST;
4026     currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4027     currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4028 
4029     WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4030 
4031     WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4032 
4033     WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4034 
4035     FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4036 
4037     if (currSCCB->Sccb_XferCnt == 0) {
4038 
4039         if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4040             (currSCCB->HostStatus == SCCB_COMPLETE))
4041             currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4042 
4043         FPT_sxfrp(port, p_card);
4044         if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4045             FPT_phaseDecode(port, p_card);
4046 
4047     }
4048 }
4049 
4050 /*---------------------------------------------------------------------
4051  *
4052  * Function: Command Phase
4053  *
4054  * Description: Load the CDB into the automation and start it up.
4055  *
4056  *---------------------------------------------------------------------*/
4057 
4058 static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4059 {
4060     struct sccb *currSCCB;
4061     u32 cdb_reg;
4062     unsigned char i;
4063 
4064     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4065 
4066     if (currSCCB->OperationCode == RESET_COMMAND) {
4067 
4068         currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4069         currSCCB->CdbLength = SIX_BYTE_CMD;
4070     }
4071 
4072     WR_HARPOON(p_port + hp_scsisig, 0x00);
4073 
4074     ARAM_ACCESS(p_port);
4075 
4076     cdb_reg = p_port + CMD_STRT;
4077 
4078     for (i = 0; i < currSCCB->CdbLength; i++) {
4079 
4080         if (currSCCB->OperationCode == RESET_COMMAND)
4081 
4082             WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4083 
4084         else
4085             WRW_HARPOON(cdb_reg,
4086                     (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4087         cdb_reg += 2;
4088     }
4089 
4090     if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4091         WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4092 
4093     WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4094 
4095     currSCCB->Sccb_scsistat = COMMAND_ST;
4096 
4097     WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4098     SGRAM_ACCESS(p_port);
4099 }
4100 
4101 /*---------------------------------------------------------------------
4102  *
4103  * Function: Status phase
4104  *
4105  * Description: Bring in the status and command complete message bytes
4106  *
4107  *---------------------------------------------------------------------*/
4108 
4109 static void FPT_phaseStatus(u32 port, unsigned char p_card)
4110 {
4111     /* Start-up the automation to finish off this command and let the
4112        isr handle the interrupt for command complete when it comes in.
4113        We could wait here for the interrupt to be generated?
4114      */
4115 
4116     WR_HARPOON(port + hp_scsisig, 0x00);
4117 
4118     WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4119 }
4120 
4121 /*---------------------------------------------------------------------
4122  *
4123  * Function: Phase Message Out
4124  *
4125  * Description: Send out our message (if we have one) and handle whatever
4126  *              else is involed.
4127  *
4128  *---------------------------------------------------------------------*/
4129 
4130 static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4131 {
4132     unsigned char message, scsiID;
4133     struct sccb *currSCCB;
4134     struct sccb_mgr_tar_info *currTar_Info;
4135 
4136     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4137 
4138     if (currSCCB != NULL) {
4139 
4140         message = currSCCB->Sccb_scsimsg;
4141         scsiID = currSCCB->TargID;
4142 
4143         if (message == TARGET_RESET) {
4144 
4145             currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4146             currTar_Info->TarSyncCtrl = 0;
4147             FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4148 
4149             if (FPT_sccbMgrTbl[p_card][scsiID].
4150                 TarEEValue & EE_SYNC_MASK) {
4151 
4152                 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4153                     ~TAR_SYNC_MASK;
4154 
4155             }
4156 
4157             if (FPT_sccbMgrTbl[p_card][scsiID].
4158                 TarEEValue & EE_WIDE_SCSI) {
4159 
4160                 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4161                     ~TAR_WIDE_MASK;
4162             }
4163 
4164             FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4165             FPT_SccbMgrTableInitTarget(p_card, scsiID);
4166         } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4167             currSCCB->HostStatus = SCCB_COMPLETE;
4168             if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4169                 NULL) {
4170                 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4171                                   Sccb_tag] = NULL;
4172                 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4173             }
4174 
4175         }
4176 
4177         else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4178 
4179             if (message == NOP) {
4180                 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4181 
4182                 FPT_ssel(port, p_card);
4183                 return;
4184             }
4185         } else {
4186 
4187             if (message == ABORT_TASK_SET)
4188 
4189                 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4190         }
4191 
4192     } else {
4193         message = ABORT_TASK_SET;
4194     }
4195 
4196     WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4197 
4198     WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4199 
4200     WR_HARPOON(port + hp_scsidata_0, message);
4201 
4202     WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4203 
4204     ACCEPT_MSG(port);
4205 
4206     WR_HARPOON(port + hp_portctrl_0, 0x00);
4207 
4208     if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
4209         (message == ABORT_TASK)) {
4210 
4211         while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4212         }
4213 
4214         if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4215             WRW_HARPOON((port + hp_intstat), BUS_FREE);
4216 
4217             if (currSCCB != NULL) {
4218 
4219                 if ((FPT_BL_Card[p_card].
4220                      globalFlags & F_CONLUN_IO)
4221                     &&
4222                     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4223                       TarStatus & TAR_TAG_Q_MASK) !=
4224                      TAG_Q_TRYING))
4225                     FPT_sccbMgrTbl[p_card][currSCCB->
4226                                    TargID].
4227                         TarLUNBusy[currSCCB->Lun] = 0;
4228                 else
4229                     FPT_sccbMgrTbl[p_card][currSCCB->
4230                                    TargID].
4231                         TarLUNBusy[0] = 0;
4232 
4233                 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4234                              currSCCB, p_card);
4235             }
4236 
4237             else {
4238                 FPT_BL_Card[p_card].globalFlags |=
4239                     F_NEW_SCCB_CMD;
4240             }
4241         }
4242 
4243         else {
4244 
4245             FPT_sxfrp(port, p_card);
4246         }
4247     }
4248 
4249     else {
4250 
4251         if (message == MSG_PARITY_ERROR) {
4252             currSCCB->Sccb_scsimsg = NOP;
4253             WR_HARPOON(port + hp_autostart_1,
4254                    (AUTO_IMMED + DISCONNECT_START));
4255         } else {
4256             FPT_sxfrp(port, p_card);
4257         }
4258     }
4259 }
4260 
4261 /*---------------------------------------------------------------------
4262  *
4263  * Function: Message In phase
4264  *
4265  * Description: Bring in the message and determine what to do with it.
4266  *
4267  *---------------------------------------------------------------------*/
4268 
4269 static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4270 {
4271     unsigned char message;
4272     struct sccb *currSCCB;
4273 
4274     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4275 
4276     if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4277 
4278         FPT_phaseChkFifo(port, p_card);
4279     }
4280 
4281     message = RD_HARPOON(port + hp_scsidata_0);
4282     if ((message == DISCONNECT) || (message == SAVE_POINTERS)) {
4283 
4284         WR_HARPOON(port + hp_autostart_1,
4285                (AUTO_IMMED + END_DATA_START));
4286 
4287     }
4288 
4289     else {
4290 
4291         message = FPT_sfm(port, currSCCB);
4292         if (message) {
4293 
4294             FPT_sdecm(message, port, p_card);
4295 
4296         } else {
4297             if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
4298                 ACCEPT_MSG(port);
4299             WR_HARPOON(port + hp_autostart_1,
4300                    (AUTO_IMMED + DISCONNECT_START));
4301         }
4302     }
4303 
4304 }
4305 
4306 /*---------------------------------------------------------------------
4307  *
4308  * Function: Illegal phase
4309  *
4310  * Description: Target switched to some illegal phase, so all we can do
4311  *              is report an error back to the host (if that is possible)
4312  *              and send an ABORT message to the misbehaving target.
4313  *
4314  *---------------------------------------------------------------------*/
4315 
4316 static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4317 {
4318     struct sccb *currSCCB;
4319 
4320     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4321 
4322     WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4323     if (currSCCB != NULL) {
4324 
4325         currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4326         currSCCB->Sccb_scsistat = ABORT_ST;
4327         currSCCB->Sccb_scsimsg = ABORT_TASK_SET;
4328     }
4329 
4330     ACCEPT_MSG_ATN(port);
4331 }
4332 
4333 /*---------------------------------------------------------------------
4334  *
4335  * Function: Phase Check FIFO
4336  *
4337  * Description: Make sure data has been flushed from both FIFOs and abort
4338  *              the operations if necessary.
4339  *
4340  *---------------------------------------------------------------------*/
4341 
4342 static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4343 {
4344     u32 xfercnt;
4345     struct sccb *currSCCB;
4346 
4347     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4348 
4349     if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4350 
4351         while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4352                (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4353         }
4354 
4355         if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4356             currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4357 
4358             currSCCB->Sccb_XferCnt = 0;
4359 
4360             if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4361                 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4362                 currSCCB->HostStatus = SCCB_PARITY_ERR;
4363                 WRW_HARPOON((port + hp_intstat), PARITY);
4364             }
4365 
4366             FPT_hostDataXferAbort(port, p_card, currSCCB);
4367 
4368             FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4369 
4370             while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4371                    && (RD_HARPOON(port + hp_ext_status) &
4372                    BM_CMD_BUSY)) {
4373             }
4374 
4375         }
4376     }
4377 
4378     /*End Data In specific code. */
4379     GET_XFER_CNT(port, xfercnt);
4380 
4381     WR_HARPOON(port + hp_xfercnt_0, 0x00);
4382 
4383     WR_HARPOON(port + hp_portctrl_0, 0x00);
4384 
4385     currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4386 
4387     currSCCB->Sccb_XferCnt = xfercnt;
4388 
4389     if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4390         (currSCCB->HostStatus == SCCB_COMPLETE)) {
4391 
4392         currSCCB->HostStatus = SCCB_PARITY_ERR;
4393         WRW_HARPOON((port + hp_intstat), PARITY);
4394     }
4395 
4396     FPT_hostDataXferAbort(port, p_card, currSCCB);
4397 
4398     WR_HARPOON(port + hp_fifowrite, 0x00);
4399     WR_HARPOON(port + hp_fiforead, 0x00);
4400     WR_HARPOON(port + hp_xferstat, 0x00);
4401 
4402     WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4403 }
4404 
4405 /*---------------------------------------------------------------------
4406  *
4407  * Function: Phase Bus Free
4408  *
4409  * Description: We just went bus free so figure out if it was
4410  *              because of command complete or from a disconnect.
4411  *
4412  *---------------------------------------------------------------------*/
4413 static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4414 {
4415     struct sccb *currSCCB;
4416 
4417     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4418 
4419     if (currSCCB != NULL) {
4420 
4421         DISABLE_AUTO(port);
4422 
4423         if (currSCCB->OperationCode == RESET_COMMAND) {
4424 
4425             if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4426                 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4427                   TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4428                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4429                     TarLUNBusy[currSCCB->Lun] = 0;
4430             else
4431                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4432                     TarLUNBusy[0] = 0;
4433 
4434             FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4435                          p_card);
4436 
4437             FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4438 
4439         }
4440 
4441         else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4442             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4443                 (unsigned char)SYNC_SUPPORTED;
4444             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4445                 ~EE_SYNC_MASK;
4446         }
4447 
4448         else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4449             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4450                 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4451                  TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4452 
4453             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4454                 ~EE_WIDE_SCSI;
4455         }
4456 
4457         else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4458             /* Make sure this is not a phony BUS_FREE.  If we were
4459                reselected or if BUSY is NOT on then this is a
4460                valid BUS FREE.  SRR Wednesday, 5/10/1995.     */
4461 
4462             if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4463                 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4464                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4465                     TarStatus &= ~TAR_TAG_Q_MASK;
4466                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4467                     TarStatus |= TAG_Q_REJECT;
4468             }
4469 
4470             else {
4471                 return;
4472             }
4473         }
4474 
4475         else {
4476 
4477             currSCCB->Sccb_scsistat = BUS_FREE_ST;
4478 
4479             if (!currSCCB->HostStatus) {
4480                 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4481             }
4482 
4483             if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4484                 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4485                   TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4486                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4487                     TarLUNBusy[currSCCB->Lun] = 0;
4488             else
4489                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4490                     TarLUNBusy[0] = 0;
4491 
4492             FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4493                          p_card);
4494             return;
4495         }
4496 
4497         FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4498 
4499     }           /*end if !=null */
4500 }
4501 
4502 /*---------------------------------------------------------------------
4503  *
4504  * Function: Auto Load Default Map
4505  *
4506  * Description: Load the Automation RAM with the default map values.
4507  *
4508  *---------------------------------------------------------------------*/
4509 static void FPT_autoLoadDefaultMap(u32 p_port)
4510 {
4511     u32 map_addr;
4512 
4513     ARAM_ACCESS(p_port);
4514     map_addr = p_port + hp_aramBase;
4515 
4516     WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0));  /*ID MESSAGE */
4517     map_addr += 2;
4518     WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20));  /*SIMPLE TAG QUEUEING MSG */
4519     map_addr += 2;
4520     WRW_HARPOON(map_addr, RAT_OP);  /*RESET ATTENTION */
4521     map_addr += 2;
4522     WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00));  /*TAG ID MSG */
4523     map_addr += 2;
4524     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 0 */
4525     map_addr += 2;
4526     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 1 */
4527     map_addr += 2;
4528     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 2 */
4529     map_addr += 2;
4530     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 3 */
4531     map_addr += 2;
4532     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 4 */
4533     map_addr += 2;
4534     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 5 */
4535     map_addr += 2;
4536     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 6 */
4537     map_addr += 2;
4538     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 7 */
4539     map_addr += 2;
4540     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 8 */
4541     map_addr += 2;
4542     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 9 */
4543     map_addr += 2;
4544     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 10 */
4545     map_addr += 2;
4546     WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));  /*CDB BYTE 11 */
4547     map_addr += 2;
4548     WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4549     map_addr += 2;
4550     WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI));  /*JUMP IF NO DATA IN FIFO */
4551     map_addr += 2;      /*This means AYNC DATA IN */
4552     WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4553     map_addr += 2;
4554     WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT));  /*JUMP IF NOT DATA IN PHZ */
4555     map_addr += 2;
4556     WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4557     map_addr += 2;
4558     WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4559     map_addr += 2;
4560     WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC));  /*GO CHECK FOR DISCONNECT MSG */
4561     map_addr += 2;
4562     WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1));    /*SAVE DATA PTRS MSG */
4563     map_addr += 2;
4564     WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4565     map_addr += 2;
4566     WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4567     map_addr += 2;
4568     WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN));  /*UKNKNOWN MSG */
4569     map_addr += 2;
4570     WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4571     map_addr += 2;
4572     WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC));    /*STOP AND INTERRUPT */
4573     map_addr += 2;
4574     WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4575     map_addr += 2;
4576     WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0));    /*GET STATUS BYTE */
4577     map_addr += 2;
4578     WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4579     map_addr += 2;
4580     WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4581     map_addr += 2;
4582     WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC));  /*ERROR IF NOT CMD COMPLETE MSG. */
4583     map_addr += 2;
4584     WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4585     map_addr += 2;
4586     WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP));    /*END OF COMMAND */
4587     map_addr += 2;
4588 
4589     WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN));   /*RECEIVED UNKNOWN MSG BYTE */
4590     map_addr += 2;
4591     WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC));   /*NO COMMAND COMPLETE AFTER STATUS */
4592     map_addr += 2;
4593     WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE));  /*BIOS Tickled the Mgr */
4594     map_addr += 2;
4595     WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL));   /*EXPECTED ID/TAG MESSAGES AND */
4596     map_addr += 2;      /* DIDN'T GET ONE */
4597     WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG));    /* comp SCSI SEL ID & AR3 */
4598     map_addr += 2;
4599     WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4600     map_addr += 2;
4601     WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC));   /*NO COMMAND COMPLETE AFTER STATUS */
4602 
4603     SGRAM_ACCESS(p_port);
4604 }
4605 
4606 /*---------------------------------------------------------------------
4607  *
4608  * Function: Auto Command Complete
4609  *
4610  * Description: Post command back to host and find another command
4611  *              to execute.
4612  *
4613  *---------------------------------------------------------------------*/
4614 
4615 static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4616 {
4617     struct sccb *currSCCB;
4618     unsigned char status_byte;
4619 
4620     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4621 
4622     status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4623 
4624     FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4625 
4626     if (status_byte != SAM_STAT_GOOD) {
4627 
4628         if (status_byte == SAM_STAT_TASK_SET_FULL) {
4629 
4630             if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4631                  ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4632                    TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4633                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4634                     TarLUNBusy[currSCCB->Lun] = 1;
4635                 if (FPT_BL_Card[p_card].discQCount != 0)
4636                     FPT_BL_Card[p_card].discQCount--;
4637                 FPT_BL_Card[p_card].
4638                     discQ_Tbl[FPT_sccbMgrTbl[p_card]
4639                           [currSCCB->TargID].
4640                           LunDiscQ_Idx[currSCCB->Lun]] =
4641                     NULL;
4642             } else {
4643                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4644                     TarLUNBusy[0] = 1;
4645                 if (currSCCB->Sccb_tag) {
4646                     if (FPT_BL_Card[p_card].discQCount != 0)
4647                         FPT_BL_Card[p_card].
4648                             discQCount--;
4649                     FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4650                                       Sccb_tag]
4651                         = NULL;
4652                 } else {
4653                     if (FPT_BL_Card[p_card].discQCount != 0)
4654                         FPT_BL_Card[p_card].
4655                             discQCount--;
4656                     FPT_BL_Card[p_card].
4657                         discQ_Tbl[FPT_sccbMgrTbl[p_card]
4658                               [currSCCB->TargID].
4659                               LunDiscQ_Idx[0]] = NULL;
4660                 }
4661             }
4662 
4663             currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4664 
4665             FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4666 
4667             return;
4668         }
4669 
4670         if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4671             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4672                 (unsigned char)SYNC_SUPPORTED;
4673 
4674             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4675                 ~EE_SYNC_MASK;
4676             FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4677 
4678             if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4679                  ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4680                    TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4681                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4682                     TarLUNBusy[currSCCB->Lun] = 1;
4683                 if (FPT_BL_Card[p_card].discQCount != 0)
4684                     FPT_BL_Card[p_card].discQCount--;
4685                 FPT_BL_Card[p_card].
4686                     discQ_Tbl[FPT_sccbMgrTbl[p_card]
4687                           [currSCCB->TargID].
4688                           LunDiscQ_Idx[currSCCB->Lun]] =
4689                     NULL;
4690             } else {
4691                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4692                     TarLUNBusy[0] = 1;
4693                 if (currSCCB->Sccb_tag) {
4694                     if (FPT_BL_Card[p_card].discQCount != 0)
4695                         FPT_BL_Card[p_card].
4696                             discQCount--;
4697                     FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4698                                       Sccb_tag]
4699                         = NULL;
4700                 } else {
4701                     if (FPT_BL_Card[p_card].discQCount != 0)
4702                         FPT_BL_Card[p_card].
4703                             discQCount--;
4704                     FPT_BL_Card[p_card].
4705                         discQ_Tbl[FPT_sccbMgrTbl[p_card]
4706                               [currSCCB->TargID].
4707                               LunDiscQ_Idx[0]] = NULL;
4708                 }
4709             }
4710             return;
4711 
4712         }
4713 
4714         if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4715 
4716             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4717                 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4718                  TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4719 
4720             FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4721                 ~EE_WIDE_SCSI;
4722             FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4723 
4724             if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4725                  ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4726                    TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4727                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4728                     TarLUNBusy[currSCCB->Lun] = 1;
4729                 if (FPT_BL_Card[p_card].discQCount != 0)
4730                     FPT_BL_Card[p_card].discQCount--;
4731                 FPT_BL_Card[p_card].
4732                     discQ_Tbl[FPT_sccbMgrTbl[p_card]
4733                           [currSCCB->TargID].
4734                           LunDiscQ_Idx[currSCCB->Lun]] =
4735                     NULL;
4736             } else {
4737                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4738                     TarLUNBusy[0] = 1;
4739                 if (currSCCB->Sccb_tag) {
4740                     if (FPT_BL_Card[p_card].discQCount != 0)
4741                         FPT_BL_Card[p_card].
4742                             discQCount--;
4743                     FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4744                                       Sccb_tag]
4745                         = NULL;
4746                 } else {
4747                     if (FPT_BL_Card[p_card].discQCount != 0)
4748                         FPT_BL_Card[p_card].
4749                             discQCount--;
4750                     FPT_BL_Card[p_card].
4751                         discQ_Tbl[FPT_sccbMgrTbl[p_card]
4752                               [currSCCB->TargID].
4753                               LunDiscQ_Idx[0]] = NULL;
4754                 }
4755             }
4756             return;
4757 
4758         }
4759 
4760         if (status_byte == SAM_STAT_CHECK_CONDITION) {
4761             if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4762                 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4763                     TarEEValue & EE_SYNC_MASK) {
4764                     FPT_sccbMgrTbl[p_card][currSCCB->
4765                                    TargID].
4766                         TarStatus &= ~TAR_SYNC_MASK;
4767                 }
4768                 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4769                     TarEEValue & EE_WIDE_SCSI) {
4770                     FPT_sccbMgrTbl[p_card][currSCCB->
4771                                    TargID].
4772                         TarStatus &= ~TAR_WIDE_MASK;
4773                 }
4774             }
4775         }
4776 
4777         if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4778 
4779             currSCCB->SccbStatus = SCCB_ERROR;
4780             currSCCB->TargetStatus = status_byte;
4781 
4782             if (status_byte == SAM_STAT_CHECK_CONDITION) {
4783 
4784                 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4785                     TarLUN_CA = 1;
4786 
4787                 if (currSCCB->RequestSenseLength !=
4788                     NO_AUTO_REQUEST_SENSE) {
4789 
4790                     if (currSCCB->RequestSenseLength == 0)
4791                         currSCCB->RequestSenseLength =
4792                             14;
4793 
4794                     FPT_ssenss(&FPT_BL_Card[p_card]);
4795                     FPT_BL_Card[p_card].globalFlags |=
4796                         F_NEW_SCCB_CMD;
4797 
4798                     if (((FPT_BL_Card[p_card].
4799                           globalFlags & F_CONLUN_IO)
4800                          &&
4801                          ((FPT_sccbMgrTbl[p_card]
4802                            [currSCCB->TargID].
4803                            TarStatus & TAR_TAG_Q_MASK) !=
4804                           TAG_Q_TRYING))) {
4805                         FPT_sccbMgrTbl[p_card]
4806                             [currSCCB->TargID].
4807                             TarLUNBusy[currSCCB->Lun] =
4808                             1;
4809                         if (FPT_BL_Card[p_card].
4810                             discQCount != 0)
4811                             FPT_BL_Card[p_card].
4812                                 discQCount--;
4813                         FPT_BL_Card[p_card].
4814                             discQ_Tbl[FPT_sccbMgrTbl
4815                                   [p_card]
4816                                   [currSCCB->
4817                                    TargID].
4818                                   LunDiscQ_Idx
4819                                   [currSCCB->Lun]] =
4820                             NULL;
4821                     } else {
4822                         FPT_sccbMgrTbl[p_card]
4823                             [currSCCB->TargID].
4824                             TarLUNBusy[0] = 1;
4825                         if (currSCCB->Sccb_tag) {
4826                             if (FPT_BL_Card[p_card].
4827                                 discQCount != 0)
4828                                 FPT_BL_Card
4829                                     [p_card].
4830                                     discQCount--;
4831                             FPT_BL_Card[p_card].
4832                                 discQ_Tbl[currSCCB->
4833                                       Sccb_tag]
4834                                 = NULL;
4835                         } else {
4836                             if (FPT_BL_Card[p_card].
4837                                 discQCount != 0)
4838                                 FPT_BL_Card
4839                                     [p_card].
4840                                     discQCount--;
4841                             FPT_BL_Card[p_card].
4842                                 discQ_Tbl
4843                                 [FPT_sccbMgrTbl
4844                                  [p_card][currSCCB->
4845                                       TargID].
4846                                  LunDiscQ_Idx[0]] =
4847                                 NULL;
4848                         }
4849                     }
4850                     return;
4851                 }
4852             }
4853         }
4854     }
4855 
4856     if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4857         ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4858           TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4859         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4860                                     Lun] = 0;
4861     else
4862         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4863 
4864     FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4865 }
4866 
4867 #define SHORT_WAIT   0x0000000F
4868 #define LONG_WAIT    0x0000FFFFL
4869 
4870 /*---------------------------------------------------------------------
4871  *
4872  * Function: Data Transfer Processor
4873  *
4874  * Description: This routine performs two tasks.
4875  *              (1) Start data transfer by calling HOST_DATA_XFER_START
4876  *              function.  Once data transfer is started, (2) Depends
4877  *              on the type of data transfer mode Scatter/Gather mode
4878  *              or NON Scatter/Gather mode.  In NON Scatter/Gather mode,
4879  *              this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4880  *              data transfer done.  In Scatter/Gather mode, this routine
4881  *              checks bus master command complete and dual rank busy
4882  *              bit to keep chaining SC transfer command.  Similarly,
4883  *              in Scatter/Gather mode, it checks Sccb_MGRFlag
4884  *              (F_HOST_XFER_ACT bit) for data transfer done.
4885  *              
4886  *---------------------------------------------------------------------*/
4887 
4888 static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4889 {
4890     struct sccb *currSCCB;
4891 
4892     currSCCB = pCurrCard->currentSCCB;
4893 
4894     if (currSCCB->Sccb_XferState & F_SG_XFER) {
4895         if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4896         {
4897             currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4898             currSCCB->Sccb_SGoffset = 0x00;
4899         }
4900         pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4901 
4902         FPT_busMstrSGDataXferStart(port, currSCCB);
4903     }
4904 
4905     else {
4906         if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4907             pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4908 
4909             FPT_busMstrDataXferStart(port, currSCCB);
4910         }
4911     }
4912 }
4913 
4914 /*---------------------------------------------------------------------
4915  *
4916  * Function: BusMaster Scatter Gather Data Transfer Start
4917  *
4918  * Description:
4919  *
4920  *---------------------------------------------------------------------*/
4921 static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4922 {
4923     u32 count, addr, tmpSGCnt;
4924     unsigned int sg_index;
4925     unsigned char sg_count, i;
4926     u32 reg_offset;
4927     struct blogic_sg_seg *segp;
4928 
4929     if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4930         count = ((u32)HOST_RD_CMD) << 24;
4931     else
4932         count = ((u32)HOST_WRT_CMD) << 24;
4933 
4934     sg_count = 0;
4935     tmpSGCnt = 0;
4936     sg_index = pcurrSCCB->Sccb_sgseg;
4937     reg_offset = hp_aramBase;
4938 
4939     i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4940                 ~(SGRAM_ARAM | SCATTER_EN));
4941 
4942     WR_HARPOON(p_port + hp_page_ctrl, i);
4943 
4944     while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4945             ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4946             pcurrSCCB->DataLength)) {
4947 
4948         segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4949                 sg_index;
4950         tmpSGCnt += segp->segbytes;
4951         count |= segp->segbytes;
4952         addr = segp->segdata;
4953 
4954         if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4955             addr +=
4956                 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4957             count =
4958                 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4959             tmpSGCnt = count & 0x00FFFFFFL;
4960         }
4961 
4962         WR_HARP32(p_port, reg_offset, addr);
4963         reg_offset += 4;
4964 
4965         WR_HARP32(p_port, reg_offset, count);
4966         reg_offset += 4;
4967 
4968         count &= 0xFF000000L;
4969         sg_index++;
4970         sg_count++;
4971 
4972     }           /*End While */
4973 
4974     pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
4975 
4976     WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
4977 
4978     if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4979 
4980         WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
4981 
4982         WR_HARPOON(p_port + hp_portctrl_0,
4983                (DMA_PORT | SCSI_PORT | SCSI_INBIT));
4984         WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
4985     }
4986 
4987     else {
4988 
4989         if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
4990             (tmpSGCnt & 0x000000001)) {
4991 
4992             pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
4993             tmpSGCnt--;
4994         }
4995 
4996         WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
4997 
4998         WR_HARPOON(p_port + hp_portctrl_0,
4999                (SCSI_PORT | DMA_PORT | DMA_RD));
5000         WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5001     }
5002 
5003     WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5004 
5005 }
5006 
5007 /*---------------------------------------------------------------------
5008  *
5009  * Function: BusMaster Data Transfer Start
5010  *
5011  * Description: 
5012  *
5013  *---------------------------------------------------------------------*/
5014 static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5015 {
5016     u32 addr, count;
5017 
5018     if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5019 
5020         count = pcurrSCCB->Sccb_XferCnt;
5021 
5022         addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5023     }
5024 
5025     else {
5026         addr = pcurrSCCB->SensePointer;
5027         count = pcurrSCCB->RequestSenseLength;
5028 
5029     }
5030 
5031     HP_SETUP_ADDR_CNT(p_port, addr, count);
5032 
5033     if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5034 
5035         WR_HARPOON(p_port + hp_portctrl_0,
5036                (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5037         WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5038 
5039         WR_HARPOON(p_port + hp_xfer_cmd,
5040                (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5041     }
5042 
5043     else {
5044 
5045         WR_HARPOON(p_port + hp_portctrl_0,
5046                (SCSI_PORT | DMA_PORT | DMA_RD));
5047         WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5048 
5049         WR_HARPOON(p_port + hp_xfer_cmd,
5050                (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5051 
5052     }
5053 }
5054 
5055 /*---------------------------------------------------------------------
5056  *
5057  * Function: BusMaster Timeout Handler
5058  *
5059  * Description: This function is called after a bus master command busy time
5060  *               out is detected.  This routines issue halt state machine
5061  *               with a software time out for command busy.  If command busy
5062  *               is still asserted at the end of the time out, it issues
5063  *               hard abort with another software time out.  It hard abort
5064  *               command busy is also time out, it'll just give up.
5065  *
5066  *---------------------------------------------------------------------*/
5067 static unsigned char FPT_busMstrTimeOut(u32 p_port)
5068 {
5069     unsigned long timeout;
5070 
5071     timeout = LONG_WAIT;
5072 
5073     WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5074 
5075     while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5076            && timeout--) {
5077     }
5078 
5079     if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5080         WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5081 
5082         timeout = LONG_WAIT;
5083         while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5084                && timeout--) {
5085         }
5086     }
5087 
5088     RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
5089 
5090     if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5091         return 1;
5092     }
5093 
5094     else {
5095         return 0;
5096     }
5097 }
5098 
5099 /*---------------------------------------------------------------------
5100  *
5101  * Function: Host Data Transfer Abort
5102  *
5103  * Description: Abort any in progress transfer.
5104  *
5105  *---------------------------------------------------------------------*/
5106 static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5107                   struct sccb *pCurrSCCB)
5108 {
5109 
5110     unsigned long timeout;
5111     unsigned long remain_cnt;
5112     u32 sg_ptr;
5113     struct blogic_sg_seg *segp;
5114 
5115     FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5116 
5117     if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5118 
5119         if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5120 
5121             WR_HARPOON(port + hp_bm_ctrl,
5122                    (RD_HARPOON(port + hp_bm_ctrl) |
5123                     FLUSH_XFER_CNTR));
5124             timeout = LONG_WAIT;
5125 
5126             while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5127                    && timeout--) {
5128             }
5129 
5130             WR_HARPOON(port + hp_bm_ctrl,
5131                    (RD_HARPOON(port + hp_bm_ctrl) &
5132                     ~FLUSH_XFER_CNTR));
5133 
5134             if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5135 
5136                 if (FPT_busMstrTimeOut(port)) {
5137 
5138                     if (pCurrSCCB->HostStatus == 0x00)
5139 
5140                         pCurrSCCB->HostStatus =
5141                             SCCB_BM_ERR;
5142 
5143                 }
5144 
5145                 if (RD_HARPOON(port + hp_int_status) &
5146                     INT_EXT_STATUS)
5147 
5148                     if (RD_HARPOON(port + hp_ext_status) &
5149                         BAD_EXT_STATUS)
5150 
5151                         if (pCurrSCCB->HostStatus ==
5152                             0x00)
5153                         {
5154                             pCurrSCCB->HostStatus =
5155                                 SCCB_BM_ERR;
5156                         }
5157             }
5158         }
5159     }
5160 
5161     else if (pCurrSCCB->Sccb_XferCnt) {
5162 
5163         if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5164 
5165             WR_HARPOON(port + hp_page_ctrl,
5166                    (RD_HARPOON(port + hp_page_ctrl) &
5167                     ~SCATTER_EN));
5168 
5169             WR_HARPOON(port + hp_sg_addr, 0x00);
5170 
5171             sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5172 
5173             if (sg_ptr >
5174                 (unsigned int)(pCurrSCCB->DataLength /
5175                        SG_ELEMENT_SIZE)) {
5176 
5177                 sg_ptr = (u32)(pCurrSCCB->DataLength /
5178                             SG_ELEMENT_SIZE);
5179             }
5180 
5181             remain_cnt = pCurrSCCB->Sccb_XferCnt;
5182 
5183             while (remain_cnt < 0x01000000L) {
5184 
5185                 sg_ptr--;
5186                 segp = (struct blogic_sg_seg *)(pCurrSCCB->
5187                         DataPointer) + (sg_ptr * 2);
5188                 if (remain_cnt > (unsigned long)segp->segbytes)
5189                     remain_cnt -=
5190                         (unsigned long)segp->segbytes;
5191                 else
5192                     break;
5193             }
5194 
5195             if (remain_cnt < 0x01000000L) {
5196 
5197                 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5198 
5199                 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5200 
5201                 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5202                     pCurrSCCB->DataLength && (remain_cnt == 0))
5203 
5204                     pCurrSCCB->Sccb_XferState |=
5205                         F_ALL_XFERRED;
5206             }
5207 
5208             else {
5209 
5210                 if (pCurrSCCB->HostStatus == 0x00) {
5211 
5212                     pCurrSCCB->HostStatus =
5213                         SCCB_GROSS_FW_ERR;
5214                 }
5215             }
5216         }
5217 
5218         if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5219 
5220             if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5221 
5222                 FPT_busMstrTimeOut(port);
5223             }
5224 
5225             else {
5226 
5227                 if (RD_HARPOON(port + hp_int_status) &
5228                     INT_EXT_STATUS) {
5229 
5230                     if (RD_HARPOON(port + hp_ext_status) &
5231                         BAD_EXT_STATUS) {
5232 
5233                         if (pCurrSCCB->HostStatus ==
5234                             0x00) {
5235 
5236                             pCurrSCCB->HostStatus =
5237                                 SCCB_BM_ERR;
5238                         }
5239                     }
5240                 }
5241 
5242             }
5243         }
5244 
5245         else {
5246 
5247             if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5248 
5249                 timeout = SHORT_WAIT;
5250 
5251                 while ((RD_HARPOON(port + hp_ext_status) &
5252                     BM_CMD_BUSY)
5253                        && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5254                        BM_THRESHOLD) && timeout--) {
5255                 }
5256             }
5257 
5258             if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5259 
5260                 WR_HARPOON(port + hp_bm_ctrl,
5261                        (RD_HARPOON(port + hp_bm_ctrl) |
5262                         FLUSH_XFER_CNTR));
5263 
5264                 timeout = LONG_WAIT;
5265 
5266                 while ((RD_HARPOON(port + hp_ext_status) &
5267                     BM_CMD_BUSY) && timeout--) {
5268                 }
5269 
5270                 WR_HARPOON(port + hp_bm_ctrl,
5271                        (RD_HARPOON(port + hp_bm_ctrl) &
5272                         ~FLUSH_XFER_CNTR));
5273 
5274                 if (RD_HARPOON(port + hp_ext_status) &
5275                     BM_CMD_BUSY) {
5276 
5277                     if (pCurrSCCB->HostStatus == 0x00) {
5278 
5279                         pCurrSCCB->HostStatus =
5280                             SCCB_BM_ERR;
5281                     }
5282 
5283                     FPT_busMstrTimeOut(port);
5284                 }
5285             }
5286 
5287             if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5288 
5289                 if (RD_HARPOON(port + hp_ext_status) &
5290                     BAD_EXT_STATUS) {
5291 
5292                     if (pCurrSCCB->HostStatus == 0x00) {
5293 
5294                         pCurrSCCB->HostStatus =
5295                             SCCB_BM_ERR;
5296                     }
5297                 }
5298             }
5299         }
5300 
5301     }
5302 
5303     else {
5304 
5305         if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5306 
5307             timeout = LONG_WAIT;
5308 
5309             while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5310                    && timeout--) {
5311             }
5312 
5313             if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5314 
5315                 if (pCurrSCCB->HostStatus == 0x00) {
5316 
5317                     pCurrSCCB->HostStatus = SCCB_BM_ERR;
5318                 }
5319 
5320                 FPT_busMstrTimeOut(port);
5321             }
5322         }
5323 
5324         if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5325 
5326             if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5327 
5328                 if (pCurrSCCB->HostStatus == 0x00) {
5329 
5330                     pCurrSCCB->HostStatus = SCCB_BM_ERR;
5331                 }
5332             }
5333 
5334         }
5335 
5336         if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5337 
5338             WR_HARPOON(port + hp_page_ctrl,
5339                    (RD_HARPOON(port + hp_page_ctrl) &
5340                     ~SCATTER_EN));
5341 
5342             WR_HARPOON(port + hp_sg_addr, 0x00);
5343 
5344             pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5345 
5346             pCurrSCCB->Sccb_SGoffset = 0x00;
5347 
5348             if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5349                     pCurrSCCB->DataLength) {
5350 
5351                 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5352                 pCurrSCCB->Sccb_sgseg =
5353                     (unsigned short)(pCurrSCCB->DataLength /
5354                              SG_ELEMENT_SIZE);
5355             }
5356         }
5357 
5358         else {
5359             if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5360                 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5361         }
5362     }
5363 
5364     WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5365 }
5366 
5367 /*---------------------------------------------------------------------
5368  *
5369  * Function: Host Data Transfer Restart
5370  *
5371  * Description: Reset the available count due to a restore data
5372  *              pointers message.
5373  *
5374  *---------------------------------------------------------------------*/
5375 static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5376 {
5377     unsigned long data_count;
5378     unsigned int sg_index;
5379     struct blogic_sg_seg *segp;
5380 
5381     if (currSCCB->Sccb_XferState & F_SG_XFER) {
5382 
5383         currSCCB->Sccb_XferCnt = 0;
5384 
5385         sg_index = 0xffff;  /*Index by long words into sg list. */
5386         data_count = 0;     /*Running count of SG xfer counts. */
5387 
5388 
5389         while (data_count < currSCCB->Sccb_ATC) {
5390 
5391             sg_index++;
5392             segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5393                         (sg_index * 2);
5394             data_count += segp->segbytes;
5395         }
5396 
5397         if (data_count == currSCCB->Sccb_ATC) {
5398 
5399             currSCCB->Sccb_SGoffset = 0;
5400             sg_index++;
5401         }
5402 
5403         else {
5404             currSCCB->Sccb_SGoffset =
5405                 data_count - currSCCB->Sccb_ATC;
5406         }
5407 
5408         currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5409     }
5410 
5411     else {
5412         currSCCB->Sccb_XferCnt =
5413             currSCCB->DataLength - currSCCB->Sccb_ATC;
5414     }
5415 }
5416 
5417 /*---------------------------------------------------------------------
5418  *
5419  * Function: FPT_scini
5420  *
5421  * Description: Setup all data structures necessary for SCAM selection.
5422  *
5423  *---------------------------------------------------------------------*/
5424 
5425 static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5426               unsigned char p_power_up)
5427 {
5428 
5429     unsigned char loser, assigned_id;
5430     u32 p_port;
5431 
5432     unsigned char i, k, ScamFlg;
5433     struct sccb_card *currCard;
5434     struct nvram_info *pCurrNvRam;
5435 
5436     currCard = &FPT_BL_Card[p_card];
5437     p_port = currCard->ioPort;
5438     pCurrNvRam = currCard->pNvRamInfo;
5439 
5440     if (pCurrNvRam) {
5441         ScamFlg = pCurrNvRam->niScamConf;
5442         i = pCurrNvRam->niSysConf;
5443     } else {
5444         ScamFlg =
5445             (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5446         i = (unsigned
5447              char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5448     }
5449     if (!(i & 0x02))    /* check if reset bus in AutoSCSI parameter set */
5450         return;
5451 
5452     FPT_inisci(p_card, p_port, p_our_id);
5453 
5454     /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5455        too slow to return to SCAM selection */
5456 
5457     /* if (p_power_up)
5458        FPT_Wait1Second(p_port);
5459        else
5460        FPT_Wait(p_port, TO_250ms); */
5461 
5462     FPT_Wait1Second(p_port);
5463 
5464     if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5465         while (!(FPT_scarb(p_port, INIT_SELTD))) {
5466         }
5467 
5468         FPT_scsel(p_port);
5469 
5470         do {
5471             FPT_scxferc(p_port, SYNC_PTRN);
5472             FPT_scxferc(p_port, DOM_MSTR);
5473             loser =
5474                 FPT_scsendi(p_port,
5475                     &FPT_scamInfo[p_our_id].id_string[0]);
5476         } while (loser == 0xFF);
5477 
5478         FPT_scbusf(p_port);
5479 
5480         if ((p_power_up) && (!loser)) {
5481             FPT_sresb(p_port, p_card);
5482             FPT_Wait(p_port, TO_250ms);
5483 
5484             while (!(FPT_scarb(p_port, INIT_SELTD))) {
5485             }
5486 
5487             FPT_scsel(p_port);
5488 
5489             do {
5490                 FPT_scxferc(p_port, SYNC_PTRN);
5491                 FPT_scxferc(p_port, DOM_MSTR);
5492                 loser =
5493                     FPT_scsendi(p_port,
5494                         &FPT_scamInfo[p_our_id].
5495                         id_string[0]);
5496             } while (loser == 0xFF);
5497 
5498             FPT_scbusf(p_port);
5499         }
5500     }
5501 
5502     else {
5503         loser = 0;
5504     }
5505 
5506     if (!loser) {
5507 
5508         FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5509 
5510         if (ScamFlg & SCAM_ENABLED) {
5511 
5512             for (i = 0; i < MAX_SCSI_TAR; i++) {
5513                 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5514                     (FPT_scamInfo[i].state == ID_UNUSED)) {
5515                     if (FPT_scsell(p_port, i)) {
5516                         FPT_scamInfo[i].state = LEGACY;
5517                         if ((FPT_scamInfo[i].
5518                              id_string[0] != 0xFF)
5519                             || (FPT_scamInfo[i].
5520                             id_string[1] != 0xFA)) {
5521 
5522                             FPT_scamInfo[i].
5523                                 id_string[0] = 0xFF;
5524                             FPT_scamInfo[i].
5525                                 id_string[1] = 0xFA;
5526                             if (pCurrNvRam == NULL)
5527                                 currCard->
5528                                     globalFlags
5529                                     |=
5530                                     F_UPDATE_EEPROM;
5531                         }
5532                     }
5533                 }
5534             }
5535 
5536             FPT_sresb(p_port, p_card);
5537             FPT_Wait1Second(p_port);
5538             while (!(FPT_scarb(p_port, INIT_SELTD))) {
5539             }
5540             FPT_scsel(p_port);
5541             FPT_scasid(p_card, p_port);
5542         }
5543 
5544     }
5545 
5546     else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5547         FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5548         assigned_id = 0;
5549         FPT_scwtsel(p_port);
5550 
5551         do {
5552             while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5553             }
5554 
5555             i = FPT_scxferc(p_port, 0x00);
5556             if (i == ASSIGN_ID) {
5557                 if (!
5558                     (FPT_scsendi
5559                      (p_port,
5560                       &FPT_scamInfo[p_our_id].id_string[0]))) {
5561                     i = FPT_scxferc(p_port, 0x00);
5562                     if (FPT_scvalq(i)) {
5563                         k = FPT_scxferc(p_port, 0x00);
5564 
5565                         if (FPT_scvalq(k)) {
5566                             currCard->ourId =
5567                                 ((unsigned char)(i
5568                                          <<
5569                                          3)
5570                                  +
5571                                  (k &
5572                                   (unsigned char)7))
5573                                 & (unsigned char)
5574                                 0x3F;
5575                             FPT_inisci(p_card,
5576                                    p_port,
5577                                    p_our_id);
5578                             FPT_scamInfo[currCard->
5579                                      ourId].
5580                                 state = ID_ASSIGNED;
5581                             FPT_scamInfo[currCard->
5582                                      ourId].
5583                                 id_string[0]
5584                                 = SLV_TYPE_CODE0;
5585                             assigned_id = 1;
5586                         }
5587                     }
5588                 }
5589             }
5590 
5591             else if (i == SET_P_FLAG) {
5592                 if (!(FPT_scsendi(p_port,
5593                           &FPT_scamInfo[p_our_id].
5594                           id_string[0])))
5595                     FPT_scamInfo[p_our_id].id_string[0] |=
5596                         0x80;
5597             }
5598         } while (!assigned_id);
5599 
5600         while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5601         }
5602     }
5603 
5604     if (ScamFlg & SCAM_ENABLED) {
5605         FPT_scbusf(p_port);
5606         if (currCard->globalFlags & F_UPDATE_EEPROM) {
5607             FPT_scsavdi(p_card, p_port);
5608             currCard->globalFlags &= ~F_UPDATE_EEPROM;
5609         }
5610     }
5611 
5612 /*
5613    for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5614       {
5615       if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5616          (FPT_scamInfo[i].state == LEGACY))
5617          k++;
5618       }
5619 
5620    if (k==2)
5621       currCard->globalFlags |= F_SINGLE_DEVICE;
5622    else
5623       currCard->globalFlags &= ~F_SINGLE_DEVICE;
5624 */
5625 }
5626 
5627 /*---------------------------------------------------------------------
5628  *
5629  * Function: FPT_scarb
5630  *
5631  * Description: Gain control of the bus and wait SCAM select time (250ms)
5632  *
5633  *---------------------------------------------------------------------*/
5634 
5635 static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5636 {
5637     if (p_sel_type == INIT_SELTD) {
5638 
5639         while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5640         }
5641 
5642         if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5643             return 0;
5644 
5645         if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5646             return 0;
5647 
5648         WR_HARPOON(p_port + hp_scsisig,
5649                (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5650 
5651         if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5652 
5653             WR_HARPOON(p_port + hp_scsisig,
5654                    (RD_HARPOON(p_port + hp_scsisig) &
5655                     ~SCSI_BSY));
5656             return 0;
5657         }
5658 
5659         WR_HARPOON(p_port + hp_scsisig,
5660                (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5661 
5662         if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5663 
5664             WR_HARPOON(p_port + hp_scsisig,
5665                    (RD_HARPOON(p_port + hp_scsisig) &
5666                     ~(SCSI_BSY | SCSI_SEL)));
5667             return 0;
5668         }
5669     }
5670 
5671     WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5672                        & ~ACTdeassert));
5673     WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5674     WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5675     WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5676     WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5677 
5678     WR_HARPOON(p_port + hp_scsisig,
5679            (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5680 
5681     WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5682                      & ~SCSI_BSY));
5683 
5684     FPT_Wait(p_port, TO_250ms);
5685 
5686     return 1;
5687 }
5688 
5689 /*---------------------------------------------------------------------
5690  *
5691  * Function: FPT_scbusf
5692  *
5693  * Description: Release the SCSI bus and disable SCAM selection.
5694  *
5695  *---------------------------------------------------------------------*/
5696 
5697 static void FPT_scbusf(u32 p_port)
5698 {
5699     WR_HARPOON(p_port + hp_page_ctrl,
5700            (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5701 
5702     WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5703 
5704     WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5705                         & ~SCSI_BUS_EN));
5706 
5707     WR_HARPOON(p_port + hp_scsisig, 0x00);
5708 
5709     WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5710                        & ~SCAM_EN));
5711 
5712     WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5713                        | ACTdeassert));
5714 
5715     WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5716 
5717     WR_HARPOON(p_port + hp_page_ctrl,
5718            (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5719 }
5720 
5721 /*---------------------------------------------------------------------
5722  *
5723  * Function: FPT_scasid
5724  *
5725  * Description: Assign an ID to all the SCAM devices.
5726  *
5727  *---------------------------------------------------------------------*/
5728 
5729 static void FPT_scasid(unsigned char p_card, u32 p_port)
5730 {
5731     unsigned char temp_id_string[ID_STRING_LENGTH];
5732 
5733     unsigned char i, k, scam_id;
5734     unsigned char crcBytes[3];
5735     struct nvram_info *pCurrNvRam;
5736     unsigned short *pCrcBytes;
5737 
5738     pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5739 
5740     i = 0;
5741 
5742     while (!i) {
5743 
5744         for (k = 0; k < ID_STRING_LENGTH; k++) {
5745             temp_id_string[k] = (unsigned char)0x00;
5746         }
5747 
5748         FPT_scxferc(p_port, SYNC_PTRN);
5749         FPT_scxferc(p_port, ASSIGN_ID);
5750 
5751         if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5752             if (pCurrNvRam) {
5753                 pCrcBytes = (unsigned short *)&crcBytes[0];
5754                 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5755                 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5756                 temp_id_string[1] = crcBytes[2];
5757                 temp_id_string[2] = crcBytes[0];
5758                 temp_id_string[3] = crcBytes[1];
5759                 for (k = 4; k < ID_STRING_LENGTH; k++)
5760                     temp_id_string[k] = (unsigned char)0x00;
5761             }
5762             i = FPT_scmachid(p_card, temp_id_string);
5763 
5764             if (i == CLR_PRIORITY) {
5765                 FPT_scxferc(p_port, MISC_CODE);
5766                 FPT_scxferc(p_port, CLR_P_FLAG);
5767                 i = 0;  /*Not the last ID yet. */
5768             }
5769 
5770             else if (i != NO_ID_AVAIL) {
5771                 if (i < 8)
5772                     FPT_scxferc(p_port, ID_0_7);
5773                 else
5774                     FPT_scxferc(p_port, ID_8_F);
5775 
5776                 scam_id = (i & (unsigned char)0x07);
5777 
5778                 for (k = 1; k < 0x08; k <<= 1)
5779                     if (!(k & i))
5780                         scam_id += 0x08;    /*Count number of zeros in DB0-3. */
5781 
5782                 FPT_scxferc(p_port, scam_id);
5783 
5784                 i = 0;  /*Not the last ID yet. */
5785             }
5786         }
5787 
5788         else {
5789             i = 1;
5790         }
5791 
5792     }           /*End while */
5793 
5794     FPT_scxferc(p_port, SYNC_PTRN);
5795     FPT_scxferc(p_port, CFG_CMPLT);
5796 }
5797 
5798 /*---------------------------------------------------------------------
5799  *
5800  * Function: FPT_scsel
5801  *
5802  * Description: Select all the SCAM devices.
5803  *
5804  *---------------------------------------------------------------------*/
5805 
5806 static void FPT_scsel(u32 p_port)
5807 {
5808 
5809     WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5810     FPT_scwiros(p_port, SCSI_MSG);
5811 
5812     WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5813 
5814     WR_HARPOON(p_port + hp_scsisig,
5815            (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5816     WR_HARPOON(p_port + hp_scsidata_0,
5817            (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5818                    (unsigned char)(BIT(7) + BIT(6))));
5819 
5820     WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5821     FPT_scwiros(p_port, SCSI_SEL);
5822 
5823     WR_HARPOON(p_port + hp_scsidata_0,
5824            (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5825                    ~(unsigned char)BIT(6)));
5826     FPT_scwirod(p_port, BIT(6));
5827 
5828     WR_HARPOON(p_port + hp_scsisig,
5829            (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5830 }
5831 
5832 /*---------------------------------------------------------------------
5833  *
5834  * Function: FPT_scxferc
5835  *
5836  * Description: Handshake the p_data (DB4-0) across the bus.
5837  *
5838  *---------------------------------------------------------------------*/
5839 
5840 static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5841 {
5842     unsigned char curr_data, ret_data;
5843 
5844     curr_data = p_data | BIT(7) | BIT(5);   /*Start with DB7 & DB5 asserted. */
5845 
5846     WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5847 
5848     curr_data &= ~BIT(7);
5849 
5850     WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5851 
5852     FPT_scwirod(p_port, BIT(7));    /*Wait for DB7 to be released. */
5853     while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5854 
5855     ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5856 
5857     curr_data |= BIT(6);
5858 
5859     WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5860 
5861     curr_data &= ~BIT(5);
5862 
5863     WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5864 
5865     FPT_scwirod(p_port, BIT(5));    /*Wait for DB5 to be released. */
5866 
5867     curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5868     curr_data |= BIT(7);
5869 
5870     WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5871 
5872     curr_data &= ~BIT(6);
5873 
5874     WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5875 
5876     FPT_scwirod(p_port, BIT(6));    /*Wait for DB6 to be released. */
5877 
5878     return ret_data;
5879 }
5880 
5881 /*---------------------------------------------------------------------
5882  *
5883  * Function: FPT_scsendi
5884  *
5885  * Description: Transfer our Identification string to determine if we
5886  *              will be the dominant master.
5887  *
5888  *---------------------------------------------------------------------*/
5889 
5890 static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5891 {
5892     unsigned char ret_data, byte_cnt, bit_cnt, defer;
5893 
5894     defer = 0;
5895 
5896     for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5897 
5898         for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5899 
5900             if (defer)
5901                 ret_data = FPT_scxferc(p_port, 00);
5902 
5903             else if (p_id_string[byte_cnt] & bit_cnt)
5904 
5905                 ret_data = FPT_scxferc(p_port, 02);
5906 
5907             else {
5908 
5909                 ret_data = FPT_scxferc(p_port, 01);
5910                 if (ret_data & 02)
5911                     defer = 1;
5912             }
5913 
5914             if ((ret_data & 0x1C) == 0x10)
5915                 return 0x00;    /*End of isolation stage, we won! */
5916 
5917             if (ret_data & 0x1C)
5918                 return 0xFF;
5919 
5920             if ((defer) && (!(ret_data & 0x1F)))
5921                 return 0x01;    /*End of isolation stage, we lost. */
5922 
5923         }       /*bit loop */
5924 
5925     }           /*byte loop */
5926 
5927     if (defer)
5928         return 0x01;    /*We lost */
5929     else
5930         return 0;   /*We WON! Yeeessss! */
5931 }
5932 
5933 /*---------------------------------------------------------------------
5934  *
5935  * Function: FPT_sciso
5936  *
5937  * Description: Transfer the Identification string.
5938  *
5939  *---------------------------------------------------------------------*/
5940 
5941 static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5942 {
5943     unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5944 
5945     the_data = 0;
5946 
5947     for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5948 
5949         for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5950 
5951             ret_data = FPT_scxferc(p_port, 0);
5952 
5953             if (ret_data & 0xFC)
5954                 return 0xFF;
5955 
5956             else {
5957 
5958                 the_data <<= 1;
5959                 if (ret_data & BIT(1)) {
5960                     the_data |= 1;
5961                 }
5962             }
5963 
5964             if ((ret_data & 0x1F) == 0) {
5965 /*
5966                 if(bit_cnt != 0 || bit_cnt != 8)
5967                 {
5968                     byte_cnt = 0;
5969                     bit_cnt = 0;
5970                     FPT_scxferc(p_port, SYNC_PTRN);
5971                     FPT_scxferc(p_port, ASSIGN_ID);
5972                     continue;
5973                 }
5974 */
5975                 if (byte_cnt)
5976                     return 0x00;
5977                 else
5978                     return 0xFF;
5979             }
5980 
5981         }       /*bit loop */
5982 
5983         p_id_string[byte_cnt] = the_data;
5984 
5985     }           /*byte loop */
5986 
5987     return 0;
5988 }
5989 
5990 /*---------------------------------------------------------------------
5991  *
5992  * Function: FPT_scwirod
5993  *
5994  * Description: Sample the SCSI data bus making sure the signal has been
5995  *              deasserted for the correct number of consecutive samples.
5996  *
5997  *---------------------------------------------------------------------*/
5998 
5999 static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
6000 {
6001     unsigned char i;
6002 
6003     i = 0;
6004     while (i < MAX_SCSI_TAR) {
6005 
6006         if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6007 
6008             i = 0;
6009 
6010         else
6011 
6012             i++;
6013 
6014     }
6015 }
6016 
6017 /*---------------------------------------------------------------------
6018  *
6019  * Function: FPT_scwiros
6020  *
6021  * Description: Sample the SCSI Signal lines making sure the signal has been
6022  *              deasserted for the correct number of consecutive samples.
6023  *
6024  *---------------------------------------------------------------------*/
6025 
6026 static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6027 {
6028     unsigned char i;
6029 
6030     i = 0;
6031     while (i < MAX_SCSI_TAR) {
6032 
6033         if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6034 
6035             i = 0;
6036 
6037         else
6038 
6039             i++;
6040 
6041     }
6042 }
6043 
6044 /*---------------------------------------------------------------------
6045  *
6046  * Function: FPT_scvalq
6047  *
6048  * Description: Make sure we received a valid data byte.
6049  *
6050  *---------------------------------------------------------------------*/
6051 
6052 static unsigned char FPT_scvalq(unsigned char p_quintet)
6053 {
6054     unsigned char count;
6055 
6056     for (count = 1; count < 0x08; count <<= 1) {
6057         if (!(p_quintet & count))
6058             p_quintet -= 0x80;
6059     }
6060 
6061     if (p_quintet & 0x18)
6062         return 0;
6063 
6064     else
6065         return 1;
6066 }
6067 
6068 /*---------------------------------------------------------------------
6069  *
6070  * Function: FPT_scsell
6071  *
6072  * Description: Select the specified device ID using a selection timeout
6073  *              less than 4ms.  If somebody responds then it is a legacy
6074  *              drive and this ID must be marked as such.
6075  *
6076  *---------------------------------------------------------------------*/
6077 
6078 static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6079 {
6080     unsigned long i;
6081 
6082     WR_HARPOON(p_port + hp_page_ctrl,
6083            (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6084 
6085     ARAM_ACCESS(p_port);
6086 
6087     WR_HARPOON(p_port + hp_addstat,
6088            (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6089     WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6090 
6091     for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6092         WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6093     }
6094     WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6095 
6096     WRW_HARPOON((p_port + hp_intstat),
6097             (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6098 
6099     WR_HARPOON(p_port + hp_select_id, targ_id);
6100 
6101     WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6102     WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6103     WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6104 
6105     while (!(RDW_HARPOON((p_port + hp_intstat)) &
6106          (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6107     }
6108 
6109     if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6110         FPT_Wait(p_port, TO_250ms);
6111 
6112     DISABLE_AUTO(p_port);
6113 
6114     WR_HARPOON(p_port + hp_addstat,
6115            (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6116     WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6117 
6118     SGRAM_ACCESS(p_port);
6119 
6120     if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6121 
6122         WRW_HARPOON((p_port + hp_intstat),
6123                 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6124 
6125         WR_HARPOON(p_port + hp_page_ctrl,
6126                (RD_HARPOON(p_port + hp_page_ctrl) &
6127                 ~G_INT_DISABLE));
6128 
6129         return 0;   /*No legacy device */
6130     }
6131 
6132     else {
6133 
6134         while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6135             if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6136                 WR_HARPOON(p_port + hp_scsisig,
6137                        (SCSI_ACK + S_ILL_PH));
6138                 ACCEPT_MSG(p_port);
6139             }
6140         }
6141 
6142         WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6143 
6144         WR_HARPOON(p_port + hp_page_ctrl,
6145                (RD_HARPOON(p_port + hp_page_ctrl) &
6146                 ~G_INT_DISABLE));
6147 
6148         return 1;   /*Found one of them oldies! */
6149     }
6150 }
6151 
6152 /*---------------------------------------------------------------------
6153  *
6154  * Function: FPT_scwtsel
6155  *
6156  * Description: Wait to be selected by another SCAM initiator.
6157  *
6158  *---------------------------------------------------------------------*/
6159 
6160 static void FPT_scwtsel(u32 p_port)
6161 {
6162     while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6163     }
6164 }
6165 
6166 /*---------------------------------------------------------------------
6167  *
6168  * Function: FPT_inisci
6169  *
6170  * Description: Setup the data Structure with the info from the EEPROM.
6171  *
6172  *---------------------------------------------------------------------*/
6173 
6174 static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6175 {
6176     unsigned char i, k, max_id;
6177     unsigned short ee_data;
6178     struct nvram_info *pCurrNvRam;
6179 
6180     pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6181 
6182     if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6183         max_id = 0x08;
6184 
6185     else
6186         max_id = 0x10;
6187 
6188     if (pCurrNvRam) {
6189         for (i = 0; i < max_id; i++) {
6190 
6191             for (k = 0; k < 4; k++)
6192                 FPT_scamInfo[i].id_string[k] =
6193                     pCurrNvRam->niScamTbl[i][k];
6194             for (k = 4; k < ID_STRING_LENGTH; k++)
6195                 FPT_scamInfo[i].id_string[k] =
6196                     (unsigned char)0x00;
6197 
6198             if (FPT_scamInfo[i].id_string[0] == 0x00)
6199                 FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
6200             else
6201                 FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
6202 
6203         }
6204     } else {
6205         for (i = 0; i < max_id; i++) {
6206             for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6207                 ee_data =
6208                     FPT_utilEERead(p_port,
6209                            (unsigned
6210                             short)((EE_SCAMBASE / 2) +
6211                                (unsigned short)(i *
6212                                         ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6213                 FPT_scamInfo[i].id_string[k] =
6214                     (unsigned char)ee_data;
6215                 ee_data >>= 8;
6216                 FPT_scamInfo[i].id_string[k + 1] =
6217                     (unsigned char)ee_data;
6218             }
6219 
6220             if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6221                 (FPT_scamInfo[i].id_string[0] == 0xFF))
6222 
6223                 FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
6224 
6225             else
6226                 FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
6227 
6228         }
6229     }
6230     for (k = 0; k < ID_STRING_LENGTH; k++)
6231         FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6232 
6233 }
6234 
6235 /*---------------------------------------------------------------------
6236  *
6237  * Function: FPT_scmachid
6238  *
6239  * Description: Match the Device ID string with our values stored in
6240  *              the EEPROM.
6241  *
6242  *---------------------------------------------------------------------*/
6243 
6244 static unsigned char FPT_scmachid(unsigned char p_card,
6245                   unsigned char p_id_string[])
6246 {
6247 
6248     unsigned char i, k, match;
6249 
6250     for (i = 0; i < MAX_SCSI_TAR; i++) {
6251 
6252         match = 1;
6253 
6254         for (k = 0; k < ID_STRING_LENGTH; k++) {
6255             if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6256                 match = 0;
6257         }
6258 
6259         if (match) {
6260             FPT_scamInfo[i].state = ID_ASSIGNED;
6261             return i;
6262         }
6263 
6264     }
6265 
6266     if (p_id_string[0] & BIT(5))
6267         i = 8;
6268     else
6269         i = MAX_SCSI_TAR;
6270 
6271     if (((p_id_string[0] & 0x06) == 0x02)
6272         || ((p_id_string[0] & 0x06) == 0x04))
6273         match = p_id_string[1] & (unsigned char)0x1F;
6274     else
6275         match = 7;
6276 
6277     while (i > 0) {
6278         i--;
6279 
6280         if (FPT_scamInfo[match].state == ID_UNUSED) {
6281             for (k = 0; k < ID_STRING_LENGTH; k++) {
6282                 FPT_scamInfo[match].id_string[k] =
6283                     p_id_string[k];
6284             }
6285 
6286             FPT_scamInfo[match].state = ID_ASSIGNED;
6287 
6288             if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6289                 FPT_BL_Card[p_card].globalFlags |=
6290                     F_UPDATE_EEPROM;
6291             return match;
6292 
6293         }
6294 
6295         match--;
6296 
6297         if (match == 0xFF) {
6298             if (p_id_string[0] & BIT(5))
6299                 match = 7;
6300             else
6301                 match = MAX_SCSI_TAR - 1;
6302         }
6303     }
6304 
6305     if (p_id_string[0] & BIT(7)) {
6306         return CLR_PRIORITY;
6307     }
6308 
6309     if (p_id_string[0] & BIT(5))
6310         i = 8;
6311     else
6312         i = MAX_SCSI_TAR;
6313 
6314     if (((p_id_string[0] & 0x06) == 0x02)
6315         || ((p_id_string[0] & 0x06) == 0x04))
6316         match = p_id_string[1] & (unsigned char)0x1F;
6317     else
6318         match = 7;
6319 
6320     while (i > 0) {
6321 
6322         i--;
6323 
6324         if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6325             for (k = 0; k < ID_STRING_LENGTH; k++) {
6326                 FPT_scamInfo[match].id_string[k] =
6327                     p_id_string[k];
6328             }
6329 
6330             FPT_scamInfo[match].id_string[0] |= BIT(7);
6331             FPT_scamInfo[match].state = ID_ASSIGNED;
6332             if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6333                 FPT_BL_Card[p_card].globalFlags |=
6334                     F_UPDATE_EEPROM;
6335             return match;
6336 
6337         }
6338 
6339         match--;
6340 
6341         if (match == 0xFF) {
6342             if (p_id_string[0] & BIT(5))
6343                 match = 7;
6344             else
6345                 match = MAX_SCSI_TAR - 1;
6346         }
6347     }
6348 
6349     return NO_ID_AVAIL;
6350 }
6351 
6352 /*---------------------------------------------------------------------
6353  *
6354  * Function: FPT_scsavdi
6355  *
6356  * Description: Save off the device SCAM ID strings.
6357  *
6358  *---------------------------------------------------------------------*/
6359 
6360 static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6361 {
6362     unsigned char i, k, max_id;
6363     unsigned short ee_data, sum_data;
6364 
6365     sum_data = 0x0000;
6366 
6367     for (i = 1; i < EE_SCAMBASE / 2; i++) {
6368         sum_data += FPT_utilEERead(p_port, i);
6369     }
6370 
6371     FPT_utilEEWriteOnOff(p_port, 1);    /* Enable write access to the EEPROM */
6372 
6373     if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6374         max_id = 0x08;
6375 
6376     else
6377         max_id = 0x10;
6378 
6379     for (i = 0; i < max_id; i++) {
6380 
6381         for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6382             ee_data = FPT_scamInfo[i].id_string[k + 1];
6383             ee_data <<= 8;
6384             ee_data |= FPT_scamInfo[i].id_string[k];
6385             sum_data += ee_data;
6386             FPT_utilEEWrite(p_port, ee_data,
6387                     (unsigned short)((EE_SCAMBASE / 2) +
6388                              (unsigned short)(i *
6389                                       ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6390         }
6391     }
6392 
6393     FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6394     FPT_utilEEWriteOnOff(p_port, 0);    /* Turn off write access */
6395 }
6396 
6397 /*---------------------------------------------------------------------
6398  *
6399  * Function: FPT_XbowInit
6400  *
6401  * Description: Setup the Xbow for normal operation.
6402  *
6403  *---------------------------------------------------------------------*/
6404 
6405 static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6406 {
6407     unsigned char i;
6408 
6409     i = RD_HARPOON(port + hp_page_ctrl);
6410     WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6411 
6412     WR_HARPOON(port + hp_scsireset, 0x00);
6413     WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6414 
6415     WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6416                      FIFO_CLR));
6417 
6418     WR_HARPOON(port + hp_scsireset, SCSI_INI);
6419 
6420     WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6421 
6422     WR_HARPOON(port + hp_scsisig, 0x00);    /*  Clear any signals we might */
6423     WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6424 
6425     WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6426 
6427     FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6428         BUS_FREE | XFER_CNT_0 | AUTO_INT;
6429 
6430     if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6431         FPT_default_intena |= SCAM_SEL;
6432 
6433     WRW_HARPOON((port + hp_intena), FPT_default_intena);
6434 
6435     WR_HARPOON(port + hp_seltimeout, TO_290ms);
6436 
6437     /* Turn on SCSI_MODE8 for narrow cards to fix the
6438        strapping issue with the DUAL CHANNEL card */
6439     if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6440         WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6441 
6442     WR_HARPOON(port + hp_page_ctrl, i);
6443 
6444 }
6445 
6446 /*---------------------------------------------------------------------
6447  *
6448  * Function: FPT_BusMasterInit
6449  *
6450  * Description: Initialize the BusMaster for normal operations.
6451  *
6452  *---------------------------------------------------------------------*/
6453 
6454 static void FPT_BusMasterInit(u32 p_port)
6455 {
6456 
6457     WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6458     WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6459 
6460     WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6461 
6462     WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6463 
6464     WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6465 
6466     RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6467     WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6468     WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6469                        ~SCATTER_EN));
6470 }
6471 
6472 /*---------------------------------------------------------------------
6473  *
6474  * Function: FPT_DiagEEPROM
6475  *
6476  * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6477  *              necessary.
6478  *
6479  *---------------------------------------------------------------------*/
6480 
6481 static void FPT_DiagEEPROM(u32 p_port)
6482 {
6483     unsigned short index, temp, max_wd_cnt;
6484 
6485     if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6486         max_wd_cnt = EEPROM_WD_CNT;
6487     else
6488         max_wd_cnt = EEPROM_WD_CNT * 2;
6489 
6490     temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6491 
6492     if (temp == 0x4641) {
6493 
6494         for (index = 2; index < max_wd_cnt; index++) {
6495 
6496             temp += FPT_utilEERead(p_port, index);
6497 
6498         }
6499 
6500         if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6501 
6502             return; /*EEPROM is Okay so return now! */
6503         }
6504     }
6505 
6506     FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6507 
6508     for (index = 0; index < max_wd_cnt; index++) {
6509 
6510         FPT_utilEEWrite(p_port, 0x0000, index);
6511     }
6512 
6513     temp = 0;
6514 
6515     FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6516     temp += 0x4641;
6517     FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6518     temp += 0x3920;
6519     FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6520     temp += 0x3033;
6521     FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6522     temp += 0x2020;
6523     FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6524     temp += 0x70D3;
6525     FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6526     temp += 0x0010;
6527     FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6528     temp += 0x0003;
6529     FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6530     temp += 0x0007;
6531 
6532     FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6533     temp += 0x0000;
6534     FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6535     temp += 0x0000;
6536     FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6537     temp += 0x0000;
6538 
6539     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6540     temp += 0x4242;
6541     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6542     temp += 0x4242;
6543     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6544     temp += 0x4242;
6545     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6546     temp += 0x4242;
6547     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6548     temp += 0x4242;
6549     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6550     temp += 0x4242;
6551     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6552     temp += 0x4242;
6553     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6554     temp += 0x4242;
6555 
6556     FPT_utilEEWrite(p_port, 0x6C46, 64 / 2);    /*PRODUCT ID */
6557     temp += 0x6C46;
6558     FPT_utilEEWrite(p_port, 0x7361, 66 / 2);    /* FlashPoint LT   */
6559     temp += 0x7361;
6560     FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6561     temp += 0x5068;
6562     FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6563     temp += 0x696F;
6564     FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6565     temp += 0x746E;
6566     FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6567     temp += 0x4C20;
6568     FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6569     temp += 0x2054;
6570     FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6571     temp += 0x2020;
6572 
6573     index = ((EE_SCAMBASE / 2) + (7 * 16));
6574     FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6575     temp += (0x0700 + TYPE_CODE0);
6576     index++;
6577     FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6578     temp += 0x5542;     /* BUSLOGIC      */
6579     index++;
6580     FPT_utilEEWrite(p_port, 0x4C53, index);
6581     temp += 0x4C53;
6582     index++;
6583     FPT_utilEEWrite(p_port, 0x474F, index);
6584     temp += 0x474F;
6585     index++;
6586     FPT_utilEEWrite(p_port, 0x4349, index);
6587     temp += 0x4349;
6588     index++;
6589     FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6590     temp += 0x5442;     /* BT- 930           */
6591     index++;
6592     FPT_utilEEWrite(p_port, 0x202D, index);
6593     temp += 0x202D;
6594     index++;
6595     FPT_utilEEWrite(p_port, 0x3339, index);
6596     temp += 0x3339;
6597     index++;        /*Serial #          */
6598     FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567         */
6599     temp += 0x2030;
6600     index++;
6601     FPT_utilEEWrite(p_port, 0x5453, index);
6602     temp += 0x5453;
6603     index++;
6604     FPT_utilEEWrite(p_port, 0x5645, index);
6605     temp += 0x5645;
6606     index++;
6607     FPT_utilEEWrite(p_port, 0x2045, index);
6608     temp += 0x2045;
6609     index++;
6610     FPT_utilEEWrite(p_port, 0x202F, index);
6611     temp += 0x202F;
6612     index++;
6613     FPT_utilEEWrite(p_port, 0x4F4A, index);
6614     temp += 0x4F4A;
6615     index++;
6616     FPT_utilEEWrite(p_port, 0x204E, index);
6617     temp += 0x204E;
6618     index++;
6619     FPT_utilEEWrite(p_port, 0x3539, index);
6620     temp += 0x3539;
6621 
6622     FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6623 
6624     FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6625 
6626 }
6627 
6628 /*---------------------------------------------------------------------
6629  *
6630  * Function: Queue Search Select
6631  *
6632  * Description: Try to find a new command to execute.
6633  *
6634  *---------------------------------------------------------------------*/
6635 
6636 static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6637                   unsigned char p_card)
6638 {
6639     unsigned char scan_ptr, lun;
6640     struct sccb_mgr_tar_info *currTar_Info;
6641     struct sccb *pOldSccb;
6642 
6643     scan_ptr = pCurrCard->scanIndex;
6644     do {
6645         currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6646         if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6647             ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6648              TAG_Q_TRYING)) {
6649             if (currTar_Info->TarSelQ_Cnt != 0) {
6650 
6651                 scan_ptr++;
6652                 if (scan_ptr == MAX_SCSI_TAR)
6653                     scan_ptr = 0;
6654 
6655                 for (lun = 0; lun < MAX_LUN; lun++) {
6656                     if (currTar_Info->TarLUNBusy[lun] == 0) {
6657 
6658                         pCurrCard->currentSCCB =
6659                             currTar_Info->TarSelQ_Head;
6660                         pOldSccb = NULL;
6661 
6662                         while ((pCurrCard->
6663                             currentSCCB != NULL)
6664                                && (lun !=
6665                                pCurrCard->
6666                                currentSCCB->Lun)) {
6667                             pOldSccb =
6668                                 pCurrCard->
6669                                 currentSCCB;
6670                             pCurrCard->currentSCCB =
6671                                 (struct sccb
6672                                  *)(pCurrCard->
6673                                 currentSCCB)->
6674                                 Sccb_forwardlink;
6675                         }
6676                         if (pCurrCard->currentSCCB ==
6677                             NULL)
6678                             continue;
6679                         if (pOldSccb != NULL) {
6680                             pOldSccb->
6681                                 Sccb_forwardlink =
6682                                 (struct sccb
6683                                  *)(pCurrCard->
6684                                 currentSCCB)->
6685                                 Sccb_forwardlink;
6686                             pOldSccb->
6687                                 Sccb_backlink =
6688                                 (struct sccb
6689                                  *)(pCurrCard->
6690                                 currentSCCB)->
6691                                 Sccb_backlink;
6692                             currTar_Info->
6693                                 TarSelQ_Cnt--;
6694                         } else {
6695                             currTar_Info->
6696                                 TarSelQ_Head =
6697                                 (struct sccb
6698                                  *)(pCurrCard->
6699                                 currentSCCB)->
6700                                 Sccb_forwardlink;
6701 
6702                             if (currTar_Info->
6703                                 TarSelQ_Head ==
6704                                 NULL) {
6705                                 currTar_Info->
6706                                     TarSelQ_Tail
6707                                     = NULL;
6708                                 currTar_Info->
6709                                     TarSelQ_Cnt
6710                                     = 0;
6711                             } else {
6712                                 currTar_Info->
6713                                     TarSelQ_Cnt--;
6714                                 currTar_Info->
6715                                     TarSelQ_Head->
6716                                     Sccb_backlink
6717                                     =
6718                                     (struct sccb
6719                                      *)NULL;
6720                             }
6721                         }
6722                         pCurrCard->scanIndex = scan_ptr;
6723 
6724                         pCurrCard->globalFlags |=
6725                             F_NEW_SCCB_CMD;
6726 
6727                         break;
6728                     }
6729                 }
6730             }
6731 
6732             else {
6733                 scan_ptr++;
6734                 if (scan_ptr == MAX_SCSI_TAR) {
6735                     scan_ptr = 0;
6736                 }
6737             }
6738 
6739         } else {
6740             if ((currTar_Info->TarSelQ_Cnt != 0) &&
6741                 (currTar_Info->TarLUNBusy[0] == 0)) {
6742 
6743                 pCurrCard->currentSCCB =
6744                     currTar_Info->TarSelQ_Head;
6745 
6746                 currTar_Info->TarSelQ_Head =
6747                     (struct sccb *)(pCurrCard->currentSCCB)->
6748                     Sccb_forwardlink;
6749 
6750                 if (currTar_Info->TarSelQ_Head == NULL) {
6751                     currTar_Info->TarSelQ_Tail = NULL;
6752                     currTar_Info->TarSelQ_Cnt = 0;
6753                 } else {
6754                     currTar_Info->TarSelQ_Cnt--;
6755                     currTar_Info->TarSelQ_Head->
6756                         Sccb_backlink = (struct sccb *)NULL;
6757                 }
6758 
6759                 scan_ptr++;
6760                 if (scan_ptr == MAX_SCSI_TAR)
6761                     scan_ptr = 0;
6762 
6763                 pCurrCard->scanIndex = scan_ptr;
6764 
6765                 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6766 
6767                 break;
6768             }
6769 
6770             else {
6771                 scan_ptr++;
6772                 if (scan_ptr == MAX_SCSI_TAR) {
6773                     scan_ptr = 0;
6774                 }
6775             }
6776         }
6777     } while (scan_ptr != pCurrCard->scanIndex);
6778 }
6779 
6780 /*---------------------------------------------------------------------
6781  *
6782  * Function: Queue Select Fail
6783  *
6784  * Description: Add the current SCCB to the head of the Queue.
6785  *
6786  *---------------------------------------------------------------------*/
6787 
6788 static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6789                 unsigned char p_card)
6790 {
6791     unsigned char thisTarg;
6792     struct sccb_mgr_tar_info *currTar_Info;
6793 
6794     if (pCurrCard->currentSCCB != NULL) {
6795         thisTarg =
6796             (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6797                     TargID);
6798         currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6799 
6800         pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6801 
6802         pCurrCard->currentSCCB->Sccb_forwardlink =
6803             currTar_Info->TarSelQ_Head;
6804 
6805         if (currTar_Info->TarSelQ_Cnt == 0) {
6806             currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6807         }
6808 
6809         else {
6810             currTar_Info->TarSelQ_Head->Sccb_backlink =
6811                 pCurrCard->currentSCCB;
6812         }
6813 
6814         currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6815 
6816         pCurrCard->currentSCCB = NULL;
6817         currTar_Info->TarSelQ_Cnt++;
6818     }
6819 }
6820 
6821 /*---------------------------------------------------------------------
6822  *
6823  * Function: Queue Command Complete
6824  *
6825  * Description: Call the callback function with the current SCCB.
6826  *
6827  *---------------------------------------------------------------------*/
6828 
6829 static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6830                  struct sccb *p_sccb, unsigned char p_card)
6831 {
6832 
6833     unsigned char i, SCSIcmd;
6834     CALL_BK_FN callback;
6835     struct sccb_mgr_tar_info *currTar_Info;
6836 
6837     SCSIcmd = p_sccb->Cdb[0];
6838 
6839     if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6840 
6841         if ((p_sccb->
6842              ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6843             && (p_sccb->HostStatus == SCCB_COMPLETE)
6844             && (p_sccb->TargetStatus != SAM_STAT_CHECK_CONDITION))
6845 
6846             if ((SCSIcmd == READ_6) ||
6847                 (SCSIcmd == WRITE_6) ||
6848                 (SCSIcmd == READ_10) ||
6849                 (SCSIcmd == WRITE_10) ||
6850                 (SCSIcmd == WRITE_VERIFY) ||
6851                 (SCSIcmd == START_STOP) ||
6852                 (pCurrCard->globalFlags & F_NO_FILTER)
6853                 )
6854                 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6855     }
6856 
6857     if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6858         if (p_sccb->HostStatus || p_sccb->TargetStatus)
6859             p_sccb->SccbStatus = SCCB_ERROR;
6860         else
6861             p_sccb->SccbStatus = SCCB_SUCCESS;
6862     }
6863 
6864     if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6865 
6866         p_sccb->CdbLength = p_sccb->Save_CdbLen;
6867         for (i = 0; i < 6; i++) {
6868             p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6869         }
6870     }
6871 
6872     if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6873         (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6874 
6875         FPT_utilUpdateResidual(p_sccb);
6876     }
6877 
6878     pCurrCard->cmdCounter--;
6879     if (!pCurrCard->cmdCounter) {
6880 
6881         if (pCurrCard->globalFlags & F_GREEN_PC) {
6882             WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6883                    (PWR_DWN | CLKCTRL_DEFAULT));
6884             WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6885         }
6886 
6887         WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6888                (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6889                 ~SCCB_MGR_ACTIVE));
6890 
6891     }
6892 
6893     if (pCurrCard->discQCount != 0) {
6894         currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6895         if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6896              ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6897               TAG_Q_TRYING))) {
6898             pCurrCard->discQCount--;
6899             pCurrCard->discQ_Tbl[currTar_Info->
6900                          LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6901         } else {
6902             if (p_sccb->Sccb_tag) {
6903                 pCurrCard->discQCount--;
6904                 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6905             } else {
6906                 pCurrCard->discQCount--;
6907                 pCurrCard->discQ_Tbl[currTar_Info->
6908                              LunDiscQ_Idx[0]] = NULL;
6909             }
6910         }
6911 
6912     }
6913 
6914     callback = (CALL_BK_FN) p_sccb->SccbCallback;
6915     callback(p_sccb);
6916     pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6917     pCurrCard->currentSCCB = NULL;
6918 }
6919 
6920 /*---------------------------------------------------------------------
6921  *
6922  * Function: Queue Disconnect
6923  *
6924  * Description: Add SCCB to our disconnect array.
6925  *
6926  *---------------------------------------------------------------------*/
6927 static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6928 {
6929     struct sccb_mgr_tar_info *currTar_Info;
6930 
6931     currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6932 
6933     if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6934          ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6935         FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6936                           LunDiscQ_Idx[p_sccb->Lun]] =
6937             p_sccb;
6938     } else {
6939         if (p_sccb->Sccb_tag) {
6940             FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6941                 p_sccb;
6942             FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6943                 0;
6944             FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6945         } else {
6946             FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6947                               LunDiscQ_Idx[0]] = p_sccb;
6948         }
6949     }
6950     FPT_BL_Card[p_card].currentSCCB = NULL;
6951 }
6952 
6953 /*---------------------------------------------------------------------
6954  *
6955  * Function: Queue Flush SCCB
6956  *
6957  * Description: Flush all SCCB's back to the host driver for this target.
6958  *
6959  *---------------------------------------------------------------------*/
6960 
6961 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6962 {
6963     unsigned char qtag, thisTarg;
6964     struct sccb *currSCCB;
6965     struct sccb_mgr_tar_info *currTar_Info;
6966 
6967     currSCCB = FPT_BL_Card[p_card].currentSCCB;
6968     if (currSCCB != NULL) {
6969         thisTarg = (unsigned char)currSCCB->TargID;
6970         currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6971 
6972         for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
6973 
6974             if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
6975                 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
6976                  thisTarg)) {
6977 
6978                 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
6979                     HostStatus = (unsigned char)error_code;
6980 
6981                 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
6982                              FPT_BL_Card[p_card].
6983                              discQ_Tbl[qtag], p_card);
6984 
6985                 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
6986                 currTar_Info->TarTagQ_Cnt--;
6987 
6988             }
6989         }
6990     }
6991 
6992 }
6993 
6994 /*---------------------------------------------------------------------
6995  *
6996  * Function: Queue Flush Target SCCB
6997  *
6998  * Description: Flush all SCCB's back to the host driver for this target.
6999  *
7000  *---------------------------------------------------------------------*/
7001 
7002 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7003                    unsigned char error_code)
7004 {
7005     unsigned char qtag;
7006     struct sccb_mgr_tar_info *currTar_Info;
7007 
7008     currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7009 
7010     for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7011 
7012         if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7013             (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7014 
7015             FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7016                 (unsigned char)error_code;
7017 
7018             FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7019                          FPT_BL_Card[p_card].
7020                          discQ_Tbl[qtag], p_card);
7021 
7022             FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7023             currTar_Info->TarTagQ_Cnt--;
7024 
7025         }
7026     }
7027 
7028 }
7029 
7030 static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7031 {
7032     struct sccb_mgr_tar_info *currTar_Info;
7033     currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7034 
7035     p_SCCB->Sccb_forwardlink = NULL;
7036 
7037     p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7038 
7039     if (currTar_Info->TarSelQ_Cnt == 0) {
7040 
7041         currTar_Info->TarSelQ_Head = p_SCCB;
7042     }
7043 
7044     else {
7045 
7046         currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7047     }
7048 
7049     currTar_Info->TarSelQ_Tail = p_SCCB;
7050     currTar_Info->TarSelQ_Cnt++;
7051 }
7052 
7053 /*---------------------------------------------------------------------
7054  *
7055  * Function: Queue Find SCCB
7056  *
7057  * Description: Search the target select Queue for this SCCB, and
7058  *              remove it if found.
7059  *
7060  *---------------------------------------------------------------------*/
7061 
7062 static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7063                        unsigned char p_card)
7064 {
7065     struct sccb *q_ptr;
7066     struct sccb_mgr_tar_info *currTar_Info;
7067 
7068     currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7069 
7070     q_ptr = currTar_Info->TarSelQ_Head;
7071 
7072     while (q_ptr != NULL) {
7073 
7074         if (q_ptr == p_SCCB) {
7075 
7076             if (currTar_Info->TarSelQ_Head == q_ptr) {
7077 
7078                 currTar_Info->TarSelQ_Head =
7079                     q_ptr->Sccb_forwardlink;
7080             }
7081 
7082             if (currTar_Info->TarSelQ_Tail == q_ptr) {
7083 
7084                 currTar_Info->TarSelQ_Tail =
7085                     q_ptr->Sccb_backlink;
7086             }
7087 
7088             if (q_ptr->Sccb_forwardlink != NULL) {
7089                 q_ptr->Sccb_forwardlink->Sccb_backlink =
7090                     q_ptr->Sccb_backlink;
7091             }
7092 
7093             if (q_ptr->Sccb_backlink != NULL) {
7094                 q_ptr->Sccb_backlink->Sccb_forwardlink =
7095                     q_ptr->Sccb_forwardlink;
7096             }
7097 
7098             currTar_Info->TarSelQ_Cnt--;
7099 
7100             return 1;
7101         }
7102 
7103         else {
7104             q_ptr = q_ptr->Sccb_forwardlink;
7105         }
7106     }
7107 
7108     return 0;
7109 
7110 }
7111 
7112 /*---------------------------------------------------------------------
7113  *
7114  * Function: Utility Update Residual Count
7115  *
7116  * Description: Update the XferCnt to the remaining byte count.
7117  *              If we transferred all the data then just write zero.
7118  *              If Non-SG transfer then report Total Cnt - Actual Transfer
7119  *              Cnt.  For SG transfers add the count fields of all
7120  *              remaining SG elements, as well as any partial remaining
7121  *              element.
7122  *
7123  *---------------------------------------------------------------------*/
7124 
7125 static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7126 {
7127     unsigned long partial_cnt;
7128     unsigned int sg_index;
7129     struct blogic_sg_seg *segp;
7130 
7131     if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7132 
7133         p_SCCB->DataLength = 0x0000;
7134     }
7135 
7136     else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7137 
7138         partial_cnt = 0x0000;
7139 
7140         sg_index = p_SCCB->Sccb_sgseg;
7141 
7142 
7143         if (p_SCCB->Sccb_SGoffset) {
7144 
7145             partial_cnt = p_SCCB->Sccb_SGoffset;
7146             sg_index++;
7147         }
7148 
7149         while (((unsigned long)sg_index *
7150             (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7151             segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7152                     (sg_index * 2);
7153             partial_cnt += segp->segbytes;
7154             sg_index++;
7155         }
7156 
7157         p_SCCB->DataLength = partial_cnt;
7158     }
7159 
7160     else {
7161 
7162         p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7163     }
7164 }
7165 
7166 /*---------------------------------------------------------------------
7167  *
7168  * Function: Wait 1 Second
7169  *
7170  * Description: Wait for 1 second.
7171  *
7172  *---------------------------------------------------------------------*/
7173 
7174 static void FPT_Wait1Second(u32 p_port)
7175 {
7176     unsigned char i;
7177 
7178     for (i = 0; i < 4; i++) {
7179 
7180         FPT_Wait(p_port, TO_250ms);
7181 
7182         if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7183             break;
7184 
7185         if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7186             break;
7187     }
7188 }
7189 
7190 /*---------------------------------------------------------------------
7191  *
7192  * Function: FPT_Wait
7193  *
7194  * Description: Wait the desired delay.
7195  *
7196  *---------------------------------------------------------------------*/
7197 
7198 static void FPT_Wait(u32 p_port, unsigned char p_delay)
7199 {
7200     unsigned char old_timer;
7201     unsigned char green_flag;
7202 
7203     old_timer = RD_HARPOON(p_port + hp_seltimeout);
7204 
7205     green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7206     WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7207 
7208     WR_HARPOON(p_port + hp_seltimeout, p_delay);
7209     WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7210     WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7211 
7212     WR_HARPOON(p_port + hp_portctrl_0,
7213            (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7214 
7215     while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7216 
7217         if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7218             break;
7219 
7220         if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7221             break;
7222     }
7223 
7224     WR_HARPOON(p_port + hp_portctrl_0,
7225            (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7226 
7227     WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7228     WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7229 
7230     WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7231 
7232     WR_HARPOON(p_port + hp_seltimeout, old_timer);
7233 }
7234 
7235 /*---------------------------------------------------------------------
7236  *
7237  * Function: Enable/Disable Write to EEPROM
7238  *
7239  * Description: The EEPROM must first be enabled for writes
7240  *              A total of 9 clocks are needed.
7241  *
7242  *---------------------------------------------------------------------*/
7243 
7244 static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7245 {
7246     unsigned char ee_value;
7247 
7248     ee_value =
7249         (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7250                 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7251 
7252     if (p_mode)
7253 
7254         FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7255 
7256     else
7257 
7258         FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7259 
7260     WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));   /*Turn off CS */
7261     WR_HARPOON(p_port + hp_ee_ctrl, ee_value);  /*Turn off Master Select */
7262 }
7263 
7264 /*---------------------------------------------------------------------
7265  *
7266  * Function: Write EEPROM
7267  *
7268  * Description: Write a word to the EEPROM at the specified
7269  *              address.
7270  *
7271  *---------------------------------------------------------------------*/
7272 
7273 static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7274                 unsigned short ee_addr)
7275 {
7276 
7277     unsigned char ee_value;
7278     unsigned short i;
7279 
7280     ee_value =
7281         (unsigned
7282          char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7283             (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7284 
7285     FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7286 
7287     ee_value |= (SEE_MS + SEE_CS);
7288 
7289     for (i = 0x8000; i != 0; i >>= 1) {
7290 
7291         if (i & ee_data)
7292             ee_value |= SEE_DO;
7293         else
7294             ee_value &= ~SEE_DO;
7295 
7296         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7297         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7298         ee_value |= SEE_CLK;    /* Clock  data! */
7299         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7300         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7301         ee_value &= ~SEE_CLK;
7302         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7303         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7304     }
7305     ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7306     WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7307 
7308     FPT_Wait(p_port, TO_10ms);
7309 
7310     WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS));  /* Set CS to EEPROM */
7311     WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));   /* Turn off CS */
7312     WR_HARPOON(p_port + hp_ee_ctrl, ee_value);  /* Turn off Master Select */
7313 }
7314 
7315 /*---------------------------------------------------------------------
7316  *
7317  * Function: Read EEPROM
7318  *
7319  * Description: Read a word from the EEPROM at the desired
7320  *              address.
7321  *
7322  *---------------------------------------------------------------------*/
7323 
7324 static unsigned short FPT_utilEERead(u32 p_port,
7325                      unsigned short ee_addr)
7326 {
7327     unsigned short i, ee_data1, ee_data2;
7328 
7329     i = 0;
7330     ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7331     do {
7332         ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7333 
7334         if (ee_data1 == ee_data2)
7335             return ee_data1;
7336 
7337         ee_data1 = ee_data2;
7338         i++;
7339 
7340     } while (i < 4);
7341 
7342     return ee_data1;
7343 }
7344 
7345 /*---------------------------------------------------------------------
7346  *
7347  * Function: Read EEPROM Original 
7348  *
7349  * Description: Read a word from the EEPROM at the desired
7350  *              address.
7351  *
7352  *---------------------------------------------------------------------*/
7353 
7354 static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7355 {
7356 
7357     unsigned char ee_value;
7358     unsigned short i, ee_data;
7359 
7360     ee_value =
7361         (unsigned
7362          char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7363             (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7364 
7365     FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7366 
7367     ee_value |= (SEE_MS + SEE_CS);
7368     ee_data = 0;
7369 
7370     for (i = 1; i <= 16; i++) {
7371 
7372         ee_value |= SEE_CLK;    /* Clock  data! */
7373         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7374         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7375         ee_value &= ~SEE_CLK;
7376         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7377         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7378 
7379         ee_data <<= 1;
7380 
7381         if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7382             ee_data |= 1;
7383     }
7384 
7385     ee_value &= ~(SEE_MS + SEE_CS);
7386     WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));   /*Turn off CS */
7387     WR_HARPOON(p_port + hp_ee_ctrl, ee_value);  /*Turn off Master Select */
7388 
7389     return ee_data;
7390 }
7391 
7392 /*---------------------------------------------------------------------
7393  *
7394  * Function: Send EE command and Address to the EEPROM
7395  *
7396  * Description: Transfers the correct command and sends the address
7397  *              to the eeprom.
7398  *
7399  *---------------------------------------------------------------------*/
7400 
7401 static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7402                   unsigned short ee_addr)
7403 {
7404     unsigned char ee_value;
7405     unsigned char narrow_flg;
7406 
7407     unsigned short i;
7408 
7409     narrow_flg =
7410         (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7411                 NARROW_SCSI_CARD);
7412 
7413     ee_value = SEE_MS;
7414     WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7415 
7416     ee_value |= SEE_CS; /* Set CS to EEPROM */
7417     WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7418 
7419     for (i = 0x04; i != 0; i >>= 1) {
7420 
7421         if (i & ee_cmd)
7422             ee_value |= SEE_DO;
7423         else
7424             ee_value &= ~SEE_DO;
7425 
7426         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7427         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7428         ee_value |= SEE_CLK;    /* Clock  data! */
7429         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7430         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7431         ee_value &= ~SEE_CLK;
7432         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7433         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7434     }
7435 
7436     if (narrow_flg)
7437         i = 0x0080;
7438 
7439     else
7440         i = 0x0200;
7441 
7442     while (i != 0) {
7443 
7444         if (i & ee_addr)
7445             ee_value |= SEE_DO;
7446         else
7447             ee_value &= ~SEE_DO;
7448 
7449         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7450         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7451         ee_value |= SEE_CLK;    /* Clock  data! */
7452         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7453         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7454         ee_value &= ~SEE_CLK;
7455         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7456         WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7457 
7458         i >>= 1;
7459     }
7460 }
7461 
7462 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7463 {
7464     unsigned short crc = 0;
7465     int i, j;
7466     unsigned short ch;
7467     for (i = 0; i < ID_STRING_LENGTH; i++) {
7468         ch = (unsigned short)buffer[i];
7469         for (j = 0; j < 8; j++) {
7470             if ((crc ^ ch) & 1)
7471                 crc = (crc >> 1) ^ CRCMASK;
7472             else
7473                 crc >>= 1;
7474             ch >>= 1;
7475         }
7476     }
7477     return crc;
7478 }
7479 
7480 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7481 {
7482     int i;
7483     unsigned char lrc;
7484     lrc = 0;
7485     for (i = 0; i < ID_STRING_LENGTH; i++)
7486         lrc ^= buffer[i];
7487     return lrc;
7488 }
7489 
7490 /*
7491   The following inline definitions avoid type conflicts.
7492 */
7493 
7494 static inline unsigned char
7495 FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7496 {
7497     return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7498                        FlashPointInfo);
7499 }
7500 
7501 static inline void *
7502 FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7503 {
7504     return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7505                            FlashPointInfo);
7506 }
7507 
7508 static inline void
7509 FlashPoint__ReleaseHostAdapter(void *CardHandle)
7510 {
7511     FlashPoint_ReleaseHostAdapter(CardHandle);
7512 }
7513 
7514 static inline void
7515 FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7516 {
7517     FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7518 }
7519 
7520 static inline void
7521 FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7522 {
7523     FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7524 }
7525 
7526 static inline bool
7527 FlashPoint__InterruptPending(void *CardHandle)
7528 {
7529     return FlashPoint_InterruptPending(CardHandle);
7530 }
7531 
7532 static inline int
7533 FlashPoint__HandleInterrupt(void *CardHandle)
7534 {
7535     return FlashPoint_HandleInterrupt(CardHandle);
7536 }
7537 
7538 #define FlashPoint_ProbeHostAdapter     FlashPoint__ProbeHostAdapter
7539 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7540 #define FlashPoint_ReleaseHostAdapter       FlashPoint__ReleaseHostAdapter
7541 #define FlashPoint_StartCCB         FlashPoint__StartCCB
7542 #define FlashPoint_AbortCCB         FlashPoint__AbortCCB
7543 #define FlashPoint_InterruptPending     FlashPoint__InterruptPending
7544 #define FlashPoint_HandleInterrupt      FlashPoint__HandleInterrupt
7545 
7546 #else               /* !CONFIG_SCSI_FLASHPOINT */
7547 
7548 /*
7549   Define prototypes for the FlashPoint SCCB Manager Functions.
7550 */
7551 
7552 extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7553 extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7554 extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7555 extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7556 extern bool FlashPoint_InterruptPending(void *);
7557 extern int FlashPoint_HandleInterrupt(void *);
7558 extern void FlashPoint_ReleaseHostAdapter(void *);
7559 
7560 #endif              /* CONFIG_SCSI_FLASHPOINT */