root/drivers/scsi/FlashPoint.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. FlashPoint_ProbeHostAdapter
  2. FlashPoint_HardwareResetHostAdapter
  3. FlashPoint_ReleaseHostAdapter
  4. FPT_RNVRamData
  5. FPT_RdStack
  6. FPT_WrStack
  7. FPT_ChkIfChipInitialized
  8. FlashPoint_StartCCB
  9. FlashPoint_AbortCCB
  10. FlashPoint_InterruptPending
  11. FlashPoint_HandleInterrupt
  12. FPT_SccbMgr_bad_isr
  13. FPT_SccbMgrTableInitAll
  14. FPT_SccbMgrTableInitCard
  15. FPT_SccbMgrTableInitTarget
  16. FPT_sfm
  17. FPT_ssel
  18. FPT_sres
  19. FPT_SendMsg
  20. FPT_sdecm
  21. FPT_shandem
  22. FPT_sisyncn
  23. FPT_stsyncn
  24. FPT_sisyncr
  25. FPT_siwidn
  26. FPT_stwidn
  27. FPT_siwidr
  28. FPT_sssyncv
  29. FPT_sresb
  30. FPT_ssenss
  31. FPT_sxfrp
  32. FPT_schkdd
  33. FPT_sinits
  34. FPT_phaseDecode
  35. FPT_phaseDataOut
  36. FPT_phaseDataIn
  37. FPT_phaseCommand
  38. FPT_phaseStatus
  39. FPT_phaseMsgOut
  40. FPT_phaseMsgIn
  41. FPT_phaseIllegal
  42. FPT_phaseChkFifo
  43. FPT_phaseBusFree
  44. FPT_autoLoadDefaultMap
  45. FPT_autoCmdCmplt
  46. FPT_dataXferProcessor
  47. FPT_busMstrSGDataXferStart
  48. FPT_busMstrDataXferStart
  49. FPT_busMstrTimeOut
  50. FPT_hostDataXferAbort
  51. FPT_hostDataXferRestart
  52. FPT_scini
  53. FPT_scarb
  54. FPT_scbusf
  55. FPT_scasid
  56. FPT_scsel
  57. FPT_scxferc
  58. FPT_scsendi
  59. FPT_sciso
  60. FPT_scwirod
  61. FPT_scwiros
  62. FPT_scvalq
  63. FPT_scsell
  64. FPT_scwtsel
  65. FPT_inisci
  66. FPT_scmachid
  67. FPT_scsavdi
  68. FPT_XbowInit
  69. FPT_BusMasterInit
  70. FPT_DiagEEPROM
  71. FPT_queueSearchSelect
  72. FPT_queueSelectFail
  73. FPT_queueCmdComplete
  74. FPT_queueDisconnect
  75. FPT_queueFlushSccb
  76. FPT_queueFlushTargSccb
  77. FPT_queueAddSccb
  78. FPT_queueFindSccb
  79. FPT_utilUpdateResidual
  80. FPT_Wait1Second
  81. FPT_Wait
  82. FPT_utilEEWriteOnOff
  83. FPT_utilEEWrite
  84. FPT_utilEERead
  85. FPT_utilEEReadOrg
  86. FPT_utilEESendCmdAddr
  87. FPT_CalcCrc16
  88. FPT_CalcLrc
  89. FlashPoint__ProbeHostAdapter
  90. FlashPoint__HardwareResetHostAdapter
  91. FlashPoint__ReleaseHostAdapter
  92. FlashPoint__StartCCB
  93. FlashPoint__AbortCCB
  94. FlashPoint__InterruptPending
  95. FlashPoint__HandleInterrupt

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

/* [<][>][^][v][top][bottom][index][help] */