Linux Audio

Check our new training course

Open-source upstreaming

Need help get the support for your hardware in upstream Linux?
Loading...
v5.9
   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
  28struct sccb;
  29typedef void (*CALL_BK_FN) (struct sccb *);
  30
  31struct 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)*/
  74struct 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
 210struct 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
 225struct 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
 248struct 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
 294enum 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
 300typedef 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
 789static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
 790				 unsigned char syncFlag);
 791static void FPT_ssel(u32 port, unsigned char p_card);
 792static void FPT_sres(u32 port, unsigned char p_card,
 793		     struct sccb_card *pCurrCard);
 794static void FPT_shandem(u32 port, unsigned char p_card,
 795			struct sccb *pCurrSCCB);
 796static void FPT_stsyncn(u32 port, unsigned char p_card);
 797static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
 798			unsigned char offset);
 799static void FPT_sssyncv(u32 p_port, unsigned char p_id,
 800			unsigned char p_sync_value,
 801			struct sccb_mgr_tar_info *currTar_Info);
 802static void FPT_sresb(u32 port, unsigned char p_card);
 803static void FPT_sxfrp(u32 p_port, unsigned char p_card);
 804static void FPT_schkdd(u32 port, unsigned char p_card);
 805static unsigned char FPT_RdStack(u32 port, unsigned char index);
 806static void FPT_WrStack(u32 portBase, unsigned char index,
 807			unsigned char data);
 808static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
 809
 810static void FPT_SendMsg(u32 port, unsigned char message);
 811static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
 812				   unsigned char error_code);
 813
 814static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
 815static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
 816
 817static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
 818static void FPT_stwidn(u32 port, unsigned char p_card);
 819static void FPT_siwidr(u32 port, unsigned char width);
 820
 821static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
 822				unsigned char p_card);
 823static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
 824static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
 825				 struct sccb *p_SCCB, unsigned char p_card);
 826static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
 827				  unsigned char p_card);
 828static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
 829static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
 830static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
 831				       unsigned char p_card);
 832static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
 833static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
 834static unsigned char FPT_CalcLrc(unsigned char buffer[]);
 835
 836static void FPT_Wait1Second(u32 p_port);
 837static void FPT_Wait(u32 p_port, unsigned char p_delay);
 838static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
 839static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
 840			    unsigned short ee_addr);
 841static unsigned short FPT_utilEERead(u32 p_port,
 842				     unsigned short ee_addr);
 843static unsigned short FPT_utilEEReadOrg(u32 p_port,
 844					unsigned short ee_addr);
 845static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
 846				  unsigned short ee_addr);
 847
 848static void FPT_phaseDataOut(u32 port, unsigned char p_card);
 849static void FPT_phaseDataIn(u32 port, unsigned char p_card);
 850static void FPT_phaseCommand(u32 port, unsigned char p_card);
 851static void FPT_phaseStatus(u32 port, unsigned char p_card);
 852static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
 853static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
 854static void FPT_phaseIllegal(u32 port, unsigned char p_card);
 855
 856static void FPT_phaseDecode(u32 port, unsigned char p_card);
 857static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
 858static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
 859
 860static void FPT_XbowInit(u32 port, unsigned char scamFlg);
 861static void FPT_BusMasterInit(u32 p_port);
 862static void FPT_DiagEEPROM(u32 p_port);
 863
 864static void FPT_dataXferProcessor(u32 port,
 865				  struct sccb_card *pCurrCard);
 866static void FPT_busMstrSGDataXferStart(u32 port,
 867				       struct sccb *pCurrSCCB);
 868static void FPT_busMstrDataXferStart(u32 port,
 869				     struct sccb *pCurrSCCB);
 870static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
 871				  struct sccb *pCurrSCCB);
 872static void FPT_hostDataXferRestart(struct sccb *currSCCB);
 873
 874static 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
 879static void FPT_SccbMgrTableInitAll(void);
 880static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
 881				     unsigned char p_card);
 882static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
 883				       unsigned char target);
 884
 885static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
 886		      unsigned char p_power_up);
 887
 888static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
 889static void FPT_scbusf(u32 p_port);
 890static void FPT_scsel(u32 p_port);
 891static void FPT_scasid(unsigned char p_card, u32 p_port);
 892static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
 893static unsigned char FPT_scsendi(u32 p_port,
 894				 unsigned char p_id_string[]);
 895static unsigned char FPT_sciso(u32 p_port,
 896			       unsigned char p_id_string[]);
 897static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
 898static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
 899static unsigned char FPT_scvalq(unsigned char p_quintet);
 900static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
 901static void FPT_scwtsel(u32 p_port);
 902static void FPT_inisci(unsigned char p_card, u32 p_port,
 903		       unsigned char p_our_id);
 904static void FPT_scsavdi(unsigned char p_card, u32 p_port);
 905static unsigned char FPT_scmachid(unsigned char p_card,
 906				  unsigned char p_id_string[]);
 907
 908static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
 909static void FPT_autoLoadDefaultMap(u32 p_port);
 910
 911static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
 912    { {{0}} };
 913static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
 914static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
 915static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
 916
 917static unsigned char FPT_mbCards = 0;
 918static 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
 925static unsigned short FPT_default_intena = 0;
 926
 927static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
 9280};
 929
 930/*---------------------------------------------------------------------
 931 *
 932 * Function: FlashPoint_ProbeHostAdapter
 933 *
 934 * Description: Setup and/or Search for cards and return info to caller.
 935 *
 936 *---------------------------------------------------------------------*/
 937
 938static 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;
1038				fallthrough;
1039			case AUTO_RATE_10:	/* Synchronous, 10 mega-transfers/second */
1040				temp5 |= 0x8000;
1041				fallthrough;
1042			case AUTO_RATE_05:	/* Synchronous, 5 mega-transfers/second */
1043				temp2 |= 0x8000;
1044				fallthrough;
1045			case AUTO_RATE_00:	/* Asynchronous */
1046				break;
1047			}
1048
1049			if (temp & DISC_ENABLE_BIT)
1050				temp3 |= 0x8000;
1051
1052			if (temp & WIDE_NEGO_BIT)
1053				temp4 |= 0x8000;
1054
1055		}
1056	}
1057
1058	pCardInfo->si_per_targ_init_sync = temp2;
1059	pCardInfo->si_per_targ_no_disc = temp3;
1060	pCardInfo->si_per_targ_wide_nego = temp4;
1061	pCardInfo->si_per_targ_fast_nego = temp5;
1062	pCardInfo->si_per_targ_ultra_nego = temp6;
1063
1064	if (pCurrNvRam)
1065		i = pCurrNvRam->niSysConf;
1066	else
1067		i = (unsigned
1068		     char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1069
1070	if (pCurrNvRam)
1071		ScamFlg = pCurrNvRam->niScamConf;
1072	else
1073		ScamFlg =
1074		    (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1075
1076	pCardInfo->si_flags = 0x0000;
1077
1078	if (i & 0x01)
1079		pCardInfo->si_flags |= SCSI_PARITY_ENA;
1080
1081	if (!(i & 0x02))
1082		pCardInfo->si_flags |= SOFT_RESET;
1083
1084	if (i & 0x10)
1085		pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1086
1087	if (ScamFlg & SCAM_ENABLED)
1088		pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1089
1090	if (ScamFlg & SCAM_LEVEL2)
1091		pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1092
1093	j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1094	if (i & 0x04) {
1095		j |= SCSI_TERM_ENA_L;
1096	}
1097	WR_HARPOON(ioport + hp_bm_ctrl, j);
1098
1099	j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1100	if (i & 0x08) {
1101		j |= SCSI_TERM_ENA_H;
1102	}
1103	WR_HARPOON(ioport + hp_ee_ctrl, j);
1104
1105	if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1106
1107		pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1108
1109	pCardInfo->si_card_family = HARPOON_FAMILY;
1110	pCardInfo->si_bustype = BUSTYPE_PCI;
1111
1112	if (pCurrNvRam) {
1113		pCardInfo->si_card_model[0] = '9';
1114		switch (pCurrNvRam->niModel & 0x0f) {
1115		case MODEL_LT:
1116			pCardInfo->si_card_model[1] = '3';
1117			pCardInfo->si_card_model[2] = '0';
1118			break;
1119		case MODEL_LW:
1120			pCardInfo->si_card_model[1] = '5';
1121			pCardInfo->si_card_model[2] = '0';
1122			break;
1123		case MODEL_DL:
1124			pCardInfo->si_card_model[1] = '3';
1125			pCardInfo->si_card_model[2] = '2';
1126			break;
1127		case MODEL_DW:
1128			pCardInfo->si_card_model[1] = '5';
1129			pCardInfo->si_card_model[2] = '2';
1130			break;
1131		}
1132	} else {
1133		temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1134		pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1135		temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1136
1137		pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1138		pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1139	}
1140
1141	if (pCardInfo->si_card_model[1] == '3') {
1142		if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1143			pCardInfo->si_flags |= LOW_BYTE_TERM;
1144	} else if (pCardInfo->si_card_model[2] == '0') {
1145		temp = RD_HARPOON(ioport + hp_xfer_pad);
1146		WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1147		if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1148			pCardInfo->si_flags |= LOW_BYTE_TERM;
1149		WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1150		if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1151			pCardInfo->si_flags |= HIGH_BYTE_TERM;
1152		WR_HARPOON(ioport + hp_xfer_pad, temp);
1153	} else {
1154		temp = RD_HARPOON(ioport + hp_ee_ctrl);
1155		temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1156		WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1157		WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1158		temp3 = 0;
1159		for (i = 0; i < 8; i++) {
1160			temp3 <<= 1;
1161			if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1162				temp3 |= 1;
1163			WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1164			WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1165		}
1166		WR_HARPOON(ioport + hp_ee_ctrl, temp);
1167		WR_HARPOON(ioport + hp_xfer_pad, temp2);
1168		if (!(temp3 & BIT(7)))
1169			pCardInfo->si_flags |= LOW_BYTE_TERM;
1170		if (!(temp3 & BIT(6)))
1171			pCardInfo->si_flags |= HIGH_BYTE_TERM;
1172	}
1173
1174	ARAM_ACCESS(ioport);
1175
1176	for (i = 0; i < 4; i++) {
1177
1178		pCardInfo->si_XlatInfo[i] =
1179		    RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1180	}
1181
1182	/* return with -1 if no sort, else return with
1183	   logical card number sorted by BIOS (zero-based) */
1184
1185	pCardInfo->si_relative_cardnum =
1186	    (unsigned
1187	     char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1188
1189	SGRAM_ACCESS(ioport);
1190
1191	FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1192	FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1193	FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1194	FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1195	FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1196	FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1197	FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1198	FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1199
1200	pCardInfo->si_present = 0x01;
1201
1202	return 0;
1203}
1204
1205/*---------------------------------------------------------------------
1206 *
1207 * Function: FlashPoint_HardwareResetHostAdapter
1208 *
1209 * Description: Setup adapter for normal operation (hard reset).
1210 *
1211 *---------------------------------------------------------------------*/
1212
1213static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1214							 *pCardInfo)
1215{
1216	struct sccb_card *CurrCard = NULL;
1217	struct nvram_info *pCurrNvRam;
1218	unsigned char i, j, thisCard, ScamFlg;
1219	unsigned short temp, sync_bit_map, id;
1220	u32 ioport;
1221
1222	ioport = pCardInfo->si_baseaddr;
1223
1224	for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1225
1226		if (thisCard == MAX_CARDS)
1227			return (void *)FAILURE;
1228
1229		if (FPT_BL_Card[thisCard].ioPort == ioport) {
1230
1231			CurrCard = &FPT_BL_Card[thisCard];
1232			FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1233			break;
1234		}
1235
1236		else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1237
1238			FPT_BL_Card[thisCard].ioPort = ioport;
1239			CurrCard = &FPT_BL_Card[thisCard];
1240
1241			if (FPT_mbCards)
1242				for (i = 0; i < FPT_mbCards; i++) {
1243					if (CurrCard->ioPort ==
1244					    FPT_nvRamInfo[i].niBaseAddr)
1245						CurrCard->pNvRamInfo =
1246						    &FPT_nvRamInfo[i];
1247				}
1248			FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1249			CurrCard->cardIndex = thisCard;
1250			CurrCard->cardInfo = pCardInfo;
1251
1252			break;
1253		}
1254	}
1255
1256	pCurrNvRam = CurrCard->pNvRamInfo;
1257
1258	if (pCurrNvRam) {
1259		ScamFlg = pCurrNvRam->niScamConf;
1260	} else {
1261		ScamFlg =
1262		    (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1263	}
1264
1265	FPT_BusMasterInit(ioport);
1266	FPT_XbowInit(ioport, ScamFlg);
1267
1268	FPT_autoLoadDefaultMap(ioport);
1269
1270	for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1271	}
1272
1273	WR_HARPOON(ioport + hp_selfid_0, id);
1274	WR_HARPOON(ioport + hp_selfid_1, 0x00);
1275	WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1276	CurrCard->ourId = pCardInfo->si_id;
1277
1278	i = (unsigned char)pCardInfo->si_flags;
1279	if (i & SCSI_PARITY_ENA)
1280		WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1281
1282	j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1283	if (i & LOW_BYTE_TERM)
1284		j |= SCSI_TERM_ENA_L;
1285	WR_HARPOON(ioport + hp_bm_ctrl, j);
1286
1287	j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1288	if (i & HIGH_BYTE_TERM)
1289		j |= SCSI_TERM_ENA_H;
1290	WR_HARPOON(ioport + hp_ee_ctrl, j);
1291
1292	if (!(pCardInfo->si_flags & SOFT_RESET)) {
1293
1294		FPT_sresb(ioport, thisCard);
1295
1296		FPT_scini(thisCard, pCardInfo->si_id, 0);
1297	}
1298
1299	if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1300		CurrCard->globalFlags |= F_NO_FILTER;
1301
1302	if (pCurrNvRam) {
1303		if (pCurrNvRam->niSysConf & 0x10)
1304			CurrCard->globalFlags |= F_GREEN_PC;
1305	} else {
1306		if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1307			CurrCard->globalFlags |= F_GREEN_PC;
1308	}
1309
1310	/* Set global flag to indicate Re-Negotiation to be done on all
1311	   ckeck condition */
1312	if (pCurrNvRam) {
1313		if (pCurrNvRam->niScsiConf & 0x04)
1314			CurrCard->globalFlags |= F_DO_RENEGO;
1315	} else {
1316		if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1317			CurrCard->globalFlags |= F_DO_RENEGO;
1318	}
1319
1320	if (pCurrNvRam) {
1321		if (pCurrNvRam->niScsiConf & 0x08)
1322			CurrCard->globalFlags |= F_CONLUN_IO;
1323	} else {
1324		if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1325			CurrCard->globalFlags |= F_CONLUN_IO;
1326	}
1327
1328	temp = pCardInfo->si_per_targ_no_disc;
1329
1330	for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1331
1332		if (temp & id)
1333			FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1334	}
1335
1336	sync_bit_map = 0x0001;
1337
1338	for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1339
1340		if (pCurrNvRam) {
1341			temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1342			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1343			    (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1344		} else
1345			temp =
1346			    FPT_utilEERead(ioport,
1347					   (unsigned short)((SYNC_RATE_TBL / 2)
1348							    + id));
1349
1350		for (i = 0; i < 2; temp >>= 8, i++) {
1351
1352			if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1353
1354				FPT_sccbMgrTbl[thisCard][id * 2 +
1355							 i].TarEEValue =
1356				    (unsigned char)temp;
1357			}
1358
1359			else {
1360				FPT_sccbMgrTbl[thisCard][id * 2 +
1361							 i].TarStatus |=
1362				    SYNC_SUPPORTED;
1363				FPT_sccbMgrTbl[thisCard][id * 2 +
1364							 i].TarEEValue =
1365				    (unsigned char)(temp & ~EE_SYNC_MASK);
1366			}
1367
1368/*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1369            (id*2+i >= 8)){
1370*/
1371			if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1372
1373				FPT_sccbMgrTbl[thisCard][id * 2 +
1374							 i].TarEEValue |=
1375				    EE_WIDE_SCSI;
1376
1377			}
1378
1379			else {	/* NARROW SCSI */
1380				FPT_sccbMgrTbl[thisCard][id * 2 +
1381							 i].TarStatus |=
1382				    WIDE_NEGOCIATED;
1383			}
1384
1385			sync_bit_map <<= 1;
1386
1387		}
1388	}
1389
1390	WR_HARPOON((ioport + hp_semaphore),
1391		   (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1392				   SCCB_MGR_PRESENT));
1393
1394	return (void *)CurrCard;
1395}
1396
1397static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1398{
1399	unsigned char i;
1400	u32 portBase;
1401	u32 regOffset;
1402	u32 scamData;
1403	u32 *pScamTbl;
1404	struct nvram_info *pCurrNvRam;
1405
1406	pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1407
1408	if (pCurrNvRam) {
1409		FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1410		FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1411		FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1412		FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1413		FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1414
1415		for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1416			FPT_WrStack(pCurrNvRam->niBaseAddr,
1417				    (unsigned char)(i + 5),
1418				    pCurrNvRam->niSyncTbl[i]);
1419
1420		portBase = pCurrNvRam->niBaseAddr;
1421
1422		for (i = 0; i < MAX_SCSI_TAR; i++) {
1423			regOffset = hp_aramBase + 64 + i * 4;
1424			pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1425			scamData = *pScamTbl;
1426			WR_HARP32(portBase, regOffset, scamData);
1427		}
1428
1429	} else {
1430		FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1431	}
1432}
1433
1434static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1435{
1436	unsigned char i;
1437	u32 portBase;
1438	u32 regOffset;
1439	u32 scamData;
1440	u32 *pScamTbl;
1441
1442	pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1443	pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1444	pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1445	pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1446	pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1447
1448	for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1449		pNvRamInfo->niSyncTbl[i] =
1450		    FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1451
1452	portBase = pNvRamInfo->niBaseAddr;
1453
1454	for (i = 0; i < MAX_SCSI_TAR; i++) {
1455		regOffset = hp_aramBase + 64 + i * 4;
1456		RD_HARP32(portBase, regOffset, scamData);
1457		pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1458		*pScamTbl = scamData;
1459	}
1460
1461}
1462
1463static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1464{
1465	WR_HARPOON(portBase + hp_stack_addr, index);
1466	return RD_HARPOON(portBase + hp_stack_data);
1467}
1468
1469static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1470{
1471	WR_HARPOON(portBase + hp_stack_addr, index);
1472	WR_HARPOON(portBase + hp_stack_data, data);
1473}
1474
1475static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1476{
1477	if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1478		return 0;
1479	if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1480	    != CLKCTRL_DEFAULT)
1481		return 0;
1482	if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1483	    (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1484		return 1;
1485	return 0;
1486
1487}
1488
1489/*---------------------------------------------------------------------
1490 *
1491 * Function: FlashPoint_StartCCB
1492 *
1493 * Description: Start a command pointed to by p_Sccb. When the
1494 *              command is completed it will be returned via the
1495 *              callback function.
1496 *
1497 *---------------------------------------------------------------------*/
1498static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1499{
1500	u32 ioport;
1501	unsigned char thisCard, lun;
1502	struct sccb *pSaveSccb;
1503	CALL_BK_FN callback;
1504	struct sccb_card *pCurrCard = curr_card;
1505
1506	thisCard = pCurrCard->cardIndex;
1507	ioport = pCurrCard->ioPort;
1508
1509	if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1510
1511		p_Sccb->HostStatus = SCCB_COMPLETE;
1512		p_Sccb->SccbStatus = SCCB_ERROR;
1513		callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1514		if (callback)
1515			callback(p_Sccb);
1516
1517		return;
1518	}
1519
1520	FPT_sinits(p_Sccb, thisCard);
1521
1522	if (!pCurrCard->cmdCounter) {
1523		WR_HARPOON(ioport + hp_semaphore,
1524			   (RD_HARPOON(ioport + hp_semaphore)
1525			    | SCCB_MGR_ACTIVE));
1526
1527		if (pCurrCard->globalFlags & F_GREEN_PC) {
1528			WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1529			WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1530		}
1531	}
1532
1533	pCurrCard->cmdCounter++;
1534
1535	if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1536
1537		WR_HARPOON(ioport + hp_semaphore,
1538			   (RD_HARPOON(ioport + hp_semaphore)
1539			    | TICKLE_ME));
1540		if (p_Sccb->OperationCode == RESET_COMMAND) {
1541			pSaveSccb =
1542			    pCurrCard->currentSCCB;
1543			pCurrCard->currentSCCB = p_Sccb;
1544			FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1545			pCurrCard->currentSCCB =
1546			    pSaveSccb;
1547		} else {
1548			FPT_queueAddSccb(p_Sccb, thisCard);
1549		}
1550	}
1551
1552	else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1553
1554		if (p_Sccb->OperationCode == RESET_COMMAND) {
1555			pSaveSccb =
1556			    pCurrCard->currentSCCB;
1557			pCurrCard->currentSCCB = p_Sccb;
1558			FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1559			pCurrCard->currentSCCB =
1560			    pSaveSccb;
1561		} else {
1562			FPT_queueAddSccb(p_Sccb, thisCard);
1563		}
1564	}
1565
1566	else {
1567
1568		MDISABLE_INT(ioport);
1569
1570		if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1571		    ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1572		      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1573			lun = p_Sccb->Lun;
1574		else
1575			lun = 0;
1576		if ((pCurrCard->currentSCCB == NULL) &&
1577		    (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1578		    && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1579			== 0)) {
1580
1581			pCurrCard->currentSCCB = p_Sccb;
1582			FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1583		}
1584
1585		else {
1586
1587			if (p_Sccb->OperationCode == RESET_COMMAND) {
1588				pSaveSccb = pCurrCard->currentSCCB;
1589				pCurrCard->currentSCCB = p_Sccb;
1590				FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1591						    thisCard);
1592				pCurrCard->currentSCCB = pSaveSccb;
1593			} else {
1594				FPT_queueAddSccb(p_Sccb, thisCard);
1595			}
1596		}
1597
1598		MENABLE_INT(ioport);
1599	}
1600
1601}
1602
1603/*---------------------------------------------------------------------
1604 *
1605 * Function: FlashPoint_AbortCCB
1606 *
1607 * Description: Abort the command pointed to by p_Sccb.  When the
1608 *              command is completed it will be returned via the
1609 *              callback function.
1610 *
1611 *---------------------------------------------------------------------*/
1612static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
1613{
1614	u32 ioport;
1615
1616	unsigned char thisCard;
1617	CALL_BK_FN callback;
1618	unsigned char TID;
1619	struct sccb *pSaveSCCB;
1620	struct sccb_mgr_tar_info *currTar_Info;
1621
1622	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1623
1624	thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1625
1626	if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1627
1628		if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1629
1630			((struct sccb_card *)pCurrCard)->cmdCounter--;
1631
1632			if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1633				WR_HARPOON(ioport + hp_semaphore,
1634					   (RD_HARPOON(ioport + hp_semaphore)
1635					    & (unsigned
1636					       char)(~(SCCB_MGR_ACTIVE |
1637						       TICKLE_ME))));
1638
1639			p_Sccb->SccbStatus = SCCB_ABORT;
1640			callback = p_Sccb->SccbCallback;
1641			callback(p_Sccb);
1642
1643			return 0;
1644		}
1645
1646		else {
1647			if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1648			    p_Sccb) {
1649				p_Sccb->SccbStatus = SCCB_ABORT;
1650				return 0;
1651
1652			}
1653
1654			else {
1655
1656				TID = p_Sccb->TargID;
1657
1658				if (p_Sccb->Sccb_tag) {
1659					MDISABLE_INT(ioport);
1660					if (((struct sccb_card *)pCurrCard)->
1661					    discQ_Tbl[p_Sccb->Sccb_tag] ==
1662					    p_Sccb) {
1663						p_Sccb->SccbStatus = SCCB_ABORT;
1664						p_Sccb->Sccb_scsistat =
1665						    ABORT_ST;
1666						p_Sccb->Sccb_scsimsg =
1667						    SMABORT_TAG;
1668
1669						if (((struct sccb_card *)
1670						     pCurrCard)->currentSCCB ==
1671						    NULL) {
1672							((struct sccb_card *)
1673							 pCurrCard)->
1674					currentSCCB = p_Sccb;
1675							FPT_ssel(ioport,
1676								 thisCard);
1677						} else {
1678							pSaveSCCB =
1679							    ((struct sccb_card
1680							      *)pCurrCard)->
1681							    currentSCCB;
1682							((struct sccb_card *)
1683							 pCurrCard)->
1684					currentSCCB = p_Sccb;
1685							FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1686							((struct sccb_card *)
1687							 pCurrCard)->
1688					currentSCCB = pSaveSCCB;
1689						}
1690					}
1691					MENABLE_INT(ioport);
1692					return 0;
1693				} else {
1694					currTar_Info =
1695					    &FPT_sccbMgrTbl[thisCard][p_Sccb->
1696								      TargID];
1697
1698					if (FPT_BL_Card[thisCard].
1699					    discQ_Tbl[currTar_Info->
1700						      LunDiscQ_Idx[p_Sccb->Lun]]
1701					    == p_Sccb) {
1702						p_Sccb->SccbStatus = SCCB_ABORT;
1703						return 0;
1704					}
1705				}
1706			}
1707		}
1708	}
1709	return -1;
1710}
1711
1712/*---------------------------------------------------------------------
1713 *
1714 * Function: FlashPoint_InterruptPending
1715 *
1716 * Description: Do a quick check to determine if there is a pending
1717 *              interrupt for this card and disable the IRQ Pin if so.
1718 *
1719 *---------------------------------------------------------------------*/
1720static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1721{
1722	u32 ioport;
1723
1724	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1725
1726	if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1727		return 1;
1728	}
1729
1730	else
1731
1732		return 0;
1733}
1734
1735/*---------------------------------------------------------------------
1736 *
1737 * Function: FlashPoint_HandleInterrupt
1738 *
1739 * Description: This is our entry point when an interrupt is generated
1740 *              by the card and the upper level driver passes it on to
1741 *              us.
1742 *
1743 *---------------------------------------------------------------------*/
1744static int FlashPoint_HandleInterrupt(void *pcard)
1745{
1746	struct sccb *currSCCB;
1747	unsigned char thisCard, result, bm_status, bm_int_st;
1748	unsigned short hp_int;
1749	unsigned char i, target;
1750	struct sccb_card *pCurrCard = pcard;
1751	u32 ioport;
1752
1753	thisCard = pCurrCard->cardIndex;
1754	ioport = pCurrCard->ioPort;
1755
1756	MDISABLE_INT(ioport);
1757
1758	if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
1759		bm_status = RD_HARPOON(ioport + hp_ext_status) &
1760					(unsigned char)BAD_EXT_STATUS;
1761	else
1762		bm_status = 0;
1763
1764	WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1765
1766	while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1767				FPT_default_intena) | bm_status) {
1768
1769		currSCCB = pCurrCard->currentSCCB;
1770
1771		if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1772			result =
1773			    FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
1774						hp_int);
1775			WRW_HARPOON((ioport + hp_intstat),
1776				    (FIFO | TIMEOUT | RESET | SCAM_SEL));
1777			bm_status = 0;
1778
1779			if (result) {
1780
1781				MENABLE_INT(ioport);
1782				return result;
1783			}
1784		}
1785
1786		else if (hp_int & ICMD_COMP) {
1787
1788			if (!(hp_int & BUS_FREE)) {
1789				/* Wait for the BusFree before starting a new command.  We
1790				   must also check for being reselected since the BusFree
1791				   may not show up if another device reselects us in 1.5us or
1792				   less.  SRR Wednesday, 3/8/1995.
1793				 */
1794				while (!
1795				       (RDW_HARPOON((ioport + hp_intstat)) &
1796					(BUS_FREE | RSEL))) ;
1797			}
1798
1799			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1800
1801				FPT_phaseChkFifo(ioport, thisCard);
1802
1803/*         WRW_HARPOON((ioport+hp_intstat),
1804            (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1805         */
1806
1807			WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1808
1809			FPT_autoCmdCmplt(ioport, thisCard);
1810
1811		}
1812
1813		else if (hp_int & ITAR_DISC) {
1814
1815			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1816				FPT_phaseChkFifo(ioport, thisCard);
1817
1818			if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1819					SMSAVE_DATA_PTR) {
1820
1821				WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1822				currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1823
1824				currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1825			}
1826
1827			currSCCB->Sccb_scsistat = DISCONNECT_ST;
1828			FPT_queueDisconnect(currSCCB, thisCard);
1829
1830			/* Wait for the BusFree before starting a new command.  We
1831			   must also check for being reselected since the BusFree
1832			   may not show up if another device reselects us in 1.5us or
1833			   less.  SRR Wednesday, 3/8/1995.
1834			 */
1835			while (!
1836			       (RDW_HARPOON((ioport + hp_intstat)) &
1837				(BUS_FREE | RSEL))
1838			       && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1839				    && RD_HARPOON((ioport + hp_scsisig)) ==
1840				    (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1841				     SCSI_IOBIT))) ;
1842
1843			/*
1844			   The additional loop exit condition above detects a timing problem
1845			   with the revision D/E harpoon chips.  The caller should reset the
1846			   host adapter to recover when 0xFE is returned.
1847			 */
1848			if (!
1849			    (RDW_HARPOON((ioport + hp_intstat)) &
1850			     (BUS_FREE | RSEL))) {
1851				MENABLE_INT(ioport);
1852				return 0xFE;
1853			}
1854
1855			WRW_HARPOON((ioport + hp_intstat),
1856				    (BUS_FREE | ITAR_DISC));
1857
1858			pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1859
1860		}
1861
1862		else if (hp_int & RSEL) {
1863
1864			WRW_HARPOON((ioport + hp_intstat),
1865				    (PROG_HLT | RSEL | PHASE | BUS_FREE));
1866
1867			if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1868				if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1869					FPT_phaseChkFifo(ioport, thisCard);
1870
1871				if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1872				    SMSAVE_DATA_PTR) {
1873					WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1874					currSCCB->Sccb_XferState |=
1875					    F_NO_DATA_YET;
1876					currSCCB->Sccb_savedATC =
1877					    currSCCB->Sccb_ATC;
1878				}
1879
1880				WRW_HARPOON((ioport + hp_intstat),
1881					    (BUS_FREE | ITAR_DISC));
1882				currSCCB->Sccb_scsistat = DISCONNECT_ST;
1883				FPT_queueDisconnect(currSCCB, thisCard);
1884			}
1885
1886			FPT_sres(ioport, thisCard, pCurrCard);
1887			FPT_phaseDecode(ioport, thisCard);
1888
1889		}
1890
1891		else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1892
1893			WRW_HARPOON((ioport + hp_intstat),
1894				    (IDO_STRT | XFER_CNT_0));
1895			FPT_phaseDecode(ioport, thisCard);
1896
1897		}
1898
1899		else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1900			WRW_HARPOON((ioport + hp_intstat),
1901				    (PHASE | IUNKWN | PROG_HLT));
1902			if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1903			     0x3f) < (unsigned char)SELCHK) {
1904				FPT_phaseDecode(ioport, thisCard);
1905			} else {
1906				/* Harpoon problem some SCSI target device respond to selection
1907				   with short BUSY pulse (<400ns) this will make the Harpoon is not able
1908				   to latch the correct Target ID into reg. x53.
1909				   The work around require to correct this reg. But when write to this
1910				   reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1911				   need to read this reg first then restore it later. After update to 0x53 */
1912
1913				i = (unsigned
1914				     char)(RD_HARPOON(ioport + hp_fifowrite));
1915				target =
1916				    (unsigned
1917				     char)(RD_HARPOON(ioport + hp_gp_reg_3));
1918				WR_HARPOON(ioport + hp_xfer_pad,
1919					   (unsigned char)ID_UNLOCK);
1920				WR_HARPOON(ioport + hp_select_id,
1921					   (unsigned char)(target | target <<
1922							   4));
1923				WR_HARPOON(ioport + hp_xfer_pad,
1924					   (unsigned char)0x00);
1925				WR_HARPOON(ioport + hp_fifowrite, i);
1926				WR_HARPOON(ioport + hp_autostart_3,
1927					   (AUTO_IMMED + TAG_STRT));
1928			}
1929		}
1930
1931		else if (hp_int & XFER_CNT_0) {
1932
1933			WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1934
1935			FPT_schkdd(ioport, thisCard);
1936
1937		}
1938
1939		else if (hp_int & BUS_FREE) {
1940
1941			WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1942
1943			if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1944
1945				FPT_hostDataXferAbort(ioport, thisCard,
1946						      currSCCB);
1947			}
1948
1949			FPT_phaseBusFree(ioport, thisCard);
1950		}
1951
1952		else if (hp_int & ITICKLE) {
1953
1954			WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1955			pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1956		}
1957
1958		if (((struct sccb_card *)pCurrCard)->
1959		    globalFlags & F_NEW_SCCB_CMD) {
1960
1961			pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1962
1963			if (pCurrCard->currentSCCB == NULL)
1964				FPT_queueSearchSelect(pCurrCard, thisCard);
1965
1966			if (pCurrCard->currentSCCB != NULL) {
1967				pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1968				FPT_ssel(ioport, thisCard);
1969			}
1970
1971			break;
1972
1973		}
1974
1975	}			/*end while */
1976
1977	MENABLE_INT(ioport);
1978
1979	return 0;
1980}
1981
1982/*---------------------------------------------------------------------
1983 *
1984 * Function: Sccb_bad_isr
1985 *
1986 * Description: Some type of interrupt has occurred which is slightly
1987 *              out of the ordinary.  We will now decode it fully, in
1988 *              this routine.  This is broken up in an attempt to save
1989 *              processing time.
1990 *
1991 *---------------------------------------------------------------------*/
1992static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1993					 struct sccb_card *pCurrCard,
1994					 unsigned short p_int)
1995{
1996	unsigned char temp, ScamFlg;
1997	struct sccb_mgr_tar_info *currTar_Info;
1998	struct nvram_info *pCurrNvRam;
1999
2000	if (RD_HARPOON(p_port + hp_ext_status) &
2001	    (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
2002
2003		if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
2004
2005			FPT_hostDataXferAbort(p_port, p_card,
2006					      pCurrCard->currentSCCB);
2007		}
2008
2009		if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
2010		{
2011			WR_HARPOON(p_port + hp_pci_stat_cfg,
2012				   (RD_HARPOON(p_port + hp_pci_stat_cfg) &
2013				    ~REC_MASTER_ABORT));
2014
2015			WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
2016
2017		}
2018
2019		if (pCurrCard->currentSCCB != NULL) {
2020
2021			if (!pCurrCard->currentSCCB->HostStatus)
2022				pCurrCard->currentSCCB->HostStatus =
2023				    SCCB_BM_ERR;
2024
2025			FPT_sxfrp(p_port, p_card);
2026
2027			temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
2028					       (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2029			WR_HARPOON(p_port + hp_ee_ctrl,
2030				   ((unsigned char)temp | SEE_MS | SEE_CS));
2031			WR_HARPOON(p_port + hp_ee_ctrl, temp);
2032
2033			if (!
2034			    (RDW_HARPOON((p_port + hp_intstat)) &
2035			     (BUS_FREE | RESET))) {
2036				FPT_phaseDecode(p_port, p_card);
2037			}
2038		}
2039	}
2040
2041	else if (p_int & RESET) {
2042
2043		WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2044		WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2045		if (pCurrCard->currentSCCB != NULL) {
2046
2047			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2048
2049				FPT_hostDataXferAbort(p_port, p_card,
2050						      pCurrCard->currentSCCB);
2051		}
2052
2053		DISABLE_AUTO(p_port);
2054
2055		FPT_sresb(p_port, p_card);
2056
2057		while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2058		}
2059
2060		pCurrNvRam = pCurrCard->pNvRamInfo;
2061		if (pCurrNvRam) {
2062			ScamFlg = pCurrNvRam->niScamConf;
2063		} else {
2064			ScamFlg =
2065			    (unsigned char)FPT_utilEERead(p_port,
2066							  SCAM_CONFIG / 2);
2067		}
2068
2069		FPT_XbowInit(p_port, ScamFlg);
2070
2071		FPT_scini(p_card, pCurrCard->ourId, 0);
2072
2073		return 0xFF;
2074	}
2075
2076	else if (p_int & FIFO) {
2077
2078		WRW_HARPOON((p_port + hp_intstat), FIFO);
2079
2080		if (pCurrCard->currentSCCB != NULL)
2081			FPT_sxfrp(p_port, p_card);
2082	}
2083
2084	else if (p_int & TIMEOUT) {
2085
2086		DISABLE_AUTO(p_port);
2087
2088		WRW_HARPOON((p_port + hp_intstat),
2089			    (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2090			     IUNKWN));
2091
2092		pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2093
2094		currTar_Info =
2095		    &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2096		if ((pCurrCard->globalFlags & F_CONLUN_IO)
2097		    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2098			TAG_Q_TRYING))
2099			currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2100			    0;
2101		else
2102			currTar_Info->TarLUNBusy[0] = 0;
2103
2104		if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2105			currTar_Info->TarSyncCtrl = 0;
2106			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2107		}
2108
2109		if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2110			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2111		}
2112
2113		FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2114			    currTar_Info);
2115
2116		FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2117
2118	}
2119
2120	else if (p_int & SCAM_SEL) {
2121
2122		FPT_scarb(p_port, LEVEL2_TAR);
2123		FPT_scsel(p_port);
2124		FPT_scasid(p_card, p_port);
2125
2126		FPT_scbusf(p_port);
2127
2128		WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2129	}
2130
2131	return 0x00;
2132}
2133
2134/*---------------------------------------------------------------------
2135 *
2136 * Function: SccbMgrTableInit
2137 *
2138 * Description: Initialize all Sccb manager data structures.
2139 *
2140 *---------------------------------------------------------------------*/
2141
2142static void FPT_SccbMgrTableInitAll(void)
2143{
2144	unsigned char thisCard;
2145
2146	for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2147		FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2148
2149		FPT_BL_Card[thisCard].ioPort = 0x00;
2150		FPT_BL_Card[thisCard].cardInfo = NULL;
2151		FPT_BL_Card[thisCard].cardIndex = 0xFF;
2152		FPT_BL_Card[thisCard].ourId = 0x00;
2153		FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2154	}
2155}
2156
2157/*---------------------------------------------------------------------
2158 *
2159 * Function: SccbMgrTableInit
2160 *
2161 * Description: Initialize all Sccb manager data structures.
2162 *
2163 *---------------------------------------------------------------------*/
2164
2165static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2166				     unsigned char p_card)
2167{
2168	unsigned char scsiID, qtag;
2169
2170	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2171		FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2172	}
2173
2174	for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2175		FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2176		FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2177		FPT_SccbMgrTableInitTarget(p_card, scsiID);
2178	}
2179
2180	pCurrCard->scanIndex = 0x00;
2181	pCurrCard->currentSCCB = NULL;
2182	pCurrCard->globalFlags = 0x00;
2183	pCurrCard->cmdCounter = 0x00;
2184	pCurrCard->tagQ_Lst = 0x01;
2185	pCurrCard->discQCount = 0;
2186
2187}
2188
2189/*---------------------------------------------------------------------
2190 *
2191 * Function: SccbMgrTableInit
2192 *
2193 * Description: Initialize all Sccb manager data structures.
2194 *
2195 *---------------------------------------------------------------------*/
2196
2197static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2198				       unsigned char target)
2199{
2200
2201	unsigned char lun, qtag;
2202	struct sccb_mgr_tar_info *currTar_Info;
2203
2204	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2205
2206	currTar_Info->TarSelQ_Cnt = 0;
2207	currTar_Info->TarSyncCtrl = 0;
2208
2209	currTar_Info->TarSelQ_Head = NULL;
2210	currTar_Info->TarSelQ_Tail = NULL;
2211	currTar_Info->TarTagQ_Cnt = 0;
2212	currTar_Info->TarLUN_CA = 0;
2213
2214	for (lun = 0; lun < MAX_LUN; lun++) {
2215		currTar_Info->TarLUNBusy[lun] = 0;
2216		currTar_Info->LunDiscQ_Idx[lun] = 0;
2217	}
2218
2219	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2220		if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2221			if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2222			    target) {
2223				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2224				FPT_BL_Card[p_card].discQCount--;
2225			}
2226		}
2227	}
2228}
2229
2230/*---------------------------------------------------------------------
2231 *
2232 * Function: sfetm
2233 *
2234 * Description: Read in a message byte from the SCSI bus, and check
2235 *              for a parity error.
2236 *
2237 *---------------------------------------------------------------------*/
2238
2239static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2240{
2241	unsigned char message;
2242	unsigned short TimeOutLoop;
2243
2244	TimeOutLoop = 0;
2245	while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2246	       (TimeOutLoop++ < 20000)) {
2247	}
2248
2249	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2250
2251	message = RD_HARPOON(port + hp_scsidata_0);
2252
2253	WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2254
2255	if (TimeOutLoop > 20000)
2256		message = 0x00;	/* force message byte = 0 if Time Out on Req */
2257
2258	if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2259	    (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2260		WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2261		WR_HARPOON(port + hp_xferstat, 0);
2262		WR_HARPOON(port + hp_fiforead, 0);
2263		WR_HARPOON(port + hp_fifowrite, 0);
2264		if (pCurrSCCB != NULL) {
2265			pCurrSCCB->Sccb_scsimsg = SMPARITY;
2266		}
2267		message = 0x00;
2268		do {
2269			ACCEPT_MSG_ATN(port);
2270			TimeOutLoop = 0;
2271			while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2272			       (TimeOutLoop++ < 20000)) {
2273			}
2274			if (TimeOutLoop > 20000) {
2275				WRW_HARPOON((port + hp_intstat), PARITY);
2276				return message;
2277			}
2278			if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2279			    S_MSGI_PH) {
2280				WRW_HARPOON((port + hp_intstat), PARITY);
2281				return message;
2282			}
2283			WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2284
2285			RD_HARPOON(port + hp_scsidata_0);
2286
2287			WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2288
2289		} while (1);
2290
2291	}
2292	WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2293	WR_HARPOON(port + hp_xferstat, 0);
2294	WR_HARPOON(port + hp_fiforead, 0);
2295	WR_HARPOON(port + hp_fifowrite, 0);
2296	return message;
2297}
2298
2299/*---------------------------------------------------------------------
2300 *
2301 * Function: FPT_ssel
2302 *
2303 * Description: Load up automation and select target device.
2304 *
2305 *---------------------------------------------------------------------*/
2306
2307static void FPT_ssel(u32 port, unsigned char p_card)
2308{
2309
2310	unsigned char auto_loaded, i, target, *theCCB;
2311
2312	u32 cdb_reg;
2313	struct sccb_card *CurrCard;
2314	struct sccb *currSCCB;
2315	struct sccb_mgr_tar_info *currTar_Info;
2316	unsigned char lastTag, lun;
2317
2318	CurrCard = &FPT_BL_Card[p_card];
2319	currSCCB = CurrCard->currentSCCB;
2320	target = currSCCB->TargID;
2321	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2322	lastTag = CurrCard->tagQ_Lst;
2323
2324	ARAM_ACCESS(port);
2325
2326	if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2327		currSCCB->ControlByte &= ~F_USE_CMD_Q;
2328
2329	if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2330	     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2331
2332		lun = currSCCB->Lun;
2333	else
2334		lun = 0;
2335
2336	if (CurrCard->globalFlags & F_TAG_STARTED) {
2337		if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2338			if ((currTar_Info->TarLUN_CA == 0)
2339			    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2340				== TAG_Q_TRYING)) {
2341
2342				if (currTar_Info->TarTagQ_Cnt != 0) {
2343					currTar_Info->TarLUNBusy[lun] = 1;
2344					FPT_queueSelectFail(CurrCard, p_card);
2345					SGRAM_ACCESS(port);
2346					return;
2347				}
2348
2349				else {
2350					currTar_Info->TarLUNBusy[lun] = 1;
2351				}
2352
2353			}
2354			/*End non-tagged */
2355			else {
2356				currTar_Info->TarLUNBusy[lun] = 1;
2357			}
2358
2359		}
2360		/*!Use cmd Q Tagged */
2361		else {
2362			if (currTar_Info->TarLUN_CA == 1) {
2363				FPT_queueSelectFail(CurrCard, p_card);
2364				SGRAM_ACCESS(port);
2365				return;
2366			}
2367
2368			currTar_Info->TarLUNBusy[lun] = 1;
2369
2370		}		/*else use cmd Q tagged */
2371
2372	}
2373	/*if glob tagged started */
2374	else {
2375		currTar_Info->TarLUNBusy[lun] = 1;
2376	}
2377
2378	if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2379	      ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2380	     || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2381		if (CurrCard->discQCount >= QUEUE_DEPTH) {
2382			currTar_Info->TarLUNBusy[lun] = 1;
2383			FPT_queueSelectFail(CurrCard, p_card);
2384			SGRAM_ACCESS(port);
2385			return;
2386		}
2387		for (i = 1; i < QUEUE_DEPTH; i++) {
2388			if (++lastTag >= QUEUE_DEPTH)
2389				lastTag = 1;
2390			if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2391				CurrCard->tagQ_Lst = lastTag;
2392				currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2393				CurrCard->discQ_Tbl[lastTag] = currSCCB;
2394				CurrCard->discQCount++;
2395				break;
2396			}
2397		}
2398		if (i == QUEUE_DEPTH) {
2399			currTar_Info->TarLUNBusy[lun] = 1;
2400			FPT_queueSelectFail(CurrCard, p_card);
2401			SGRAM_ACCESS(port);
2402			return;
2403		}
2404	}
2405
2406	auto_loaded = 0;
2407
2408	WR_HARPOON(port + hp_select_id, target);
2409	WR_HARPOON(port + hp_gp_reg_3, target);	/* Use by new automation logic */
2410
2411	if (currSCCB->OperationCode == RESET_COMMAND) {
2412		WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2413						   (currSCCB->
2414						    Sccb_idmsg & ~DISC_PRIV)));
2415
2416		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2417
2418		currSCCB->Sccb_scsimsg = SMDEV_RESET;
2419
2420		WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2421		auto_loaded = 1;
2422		currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2423
2424		if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2425			currTar_Info->TarSyncCtrl = 0;
2426			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2427		}
2428
2429		if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2430			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2431		}
2432
2433		FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2434		FPT_SccbMgrTableInitTarget(p_card, target);
2435
2436	}
2437
2438	else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2439		WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2440						   (currSCCB->
2441						    Sccb_idmsg & ~DISC_PRIV)));
2442
2443		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2444
2445		WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2446						     (((unsigned
2447							char)(currSCCB->
2448							      ControlByte &
2449							      TAG_TYPE_MASK)
2450						       >> 6) | (unsigned char)
2451						      0x20)));
2452		WRW_HARPOON((port + SYNC_MSGS + 2),
2453			    (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2454		WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2455
2456		WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2457		auto_loaded = 1;
2458
2459	}
2460
2461	else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2462		auto_loaded = FPT_siwidn(port, p_card);
2463		currSCCB->Sccb_scsistat = SELECT_WN_ST;
2464	}
2465
2466	else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2467		   == SYNC_SUPPORTED)) {
2468		auto_loaded = FPT_sisyncn(port, p_card, 0);
2469		currSCCB->Sccb_scsistat = SELECT_SN_ST;
2470	}
2471
2472	if (!auto_loaded) {
2473
2474		if (currSCCB->ControlByte & F_USE_CMD_Q) {
2475
2476			CurrCard->globalFlags |= F_TAG_STARTED;
2477
2478			if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2479			    == TAG_Q_REJECT) {
2480				currSCCB->ControlByte &= ~F_USE_CMD_Q;
2481
2482				/* Fix up the start instruction with a jump to
2483				   Non-Tag-CMD handling */
2484				WRW_HARPOON((port + ID_MSG_STRT),
2485					    BRH_OP + ALWAYS + NTCMD);
2486
2487				WRW_HARPOON((port + NON_TAG_ID_MSG),
2488					    (MPM_OP + AMSG_OUT +
2489					     currSCCB->Sccb_idmsg));
2490
2491				WR_HARPOON(port + hp_autostart_3,
2492					   (SELECT + SELCHK_STRT));
2493
2494				/* Setup our STATE so we know what happened when
2495				   the wheels fall off. */
2496				currSCCB->Sccb_scsistat = SELECT_ST;
2497
2498				currTar_Info->TarLUNBusy[lun] = 1;
2499			}
2500
2501			else {
2502				WRW_HARPOON((port + ID_MSG_STRT),
2503					    (MPM_OP + AMSG_OUT +
2504					     currSCCB->Sccb_idmsg));
2505
2506				WRW_HARPOON((port + ID_MSG_STRT + 2),
2507					    (MPM_OP + AMSG_OUT +
2508					     (((unsigned char)(currSCCB->
2509							       ControlByte &
2510							       TAG_TYPE_MASK)
2511					       >> 6) | (unsigned char)0x20)));
2512
2513				for (i = 1; i < QUEUE_DEPTH; i++) {
2514					if (++lastTag >= QUEUE_DEPTH)
2515						lastTag = 1;
2516					if (CurrCard->discQ_Tbl[lastTag] ==
2517					    NULL) {
2518						WRW_HARPOON((port +
2519							     ID_MSG_STRT + 6),
2520							    (MPM_OP + AMSG_OUT +
2521							     lastTag));
2522						CurrCard->tagQ_Lst = lastTag;
2523						currSCCB->Sccb_tag = lastTag;
2524						CurrCard->discQ_Tbl[lastTag] =
2525						    currSCCB;
2526						CurrCard->discQCount++;
2527						break;
2528					}
2529				}
2530
2531				if (i == QUEUE_DEPTH) {
2532					currTar_Info->TarLUNBusy[lun] = 1;
2533					FPT_queueSelectFail(CurrCard, p_card);
2534					SGRAM_ACCESS(port);
2535					return;
2536				}
2537
2538				currSCCB->Sccb_scsistat = SELECT_Q_ST;
2539
2540				WR_HARPOON(port + hp_autostart_3,
2541					   (SELECT + SELCHK_STRT));
2542			}
2543		}
2544
2545		else {
2546
2547			WRW_HARPOON((port + ID_MSG_STRT),
2548				    BRH_OP + ALWAYS + NTCMD);
2549
2550			WRW_HARPOON((port + NON_TAG_ID_MSG),
2551				    (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2552
2553			currSCCB->Sccb_scsistat = SELECT_ST;
2554
2555			WR_HARPOON(port + hp_autostart_3,
2556				   (SELECT + SELCHK_STRT));
2557		}
2558
2559		theCCB = (unsigned char *)&currSCCB->Cdb[0];
2560
2561		cdb_reg = port + CMD_STRT;
2562
2563		for (i = 0; i < currSCCB->CdbLength; i++) {
2564			WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2565			cdb_reg += 2;
2566			theCCB++;
2567		}
2568
2569		if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2570			WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2571
2572	}
2573	/* auto_loaded */
2574	WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2575	WR_HARPOON(port + hp_xferstat, 0x00);
2576
2577	WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2578
2579	WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2580
2581	if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2582		WR_HARPOON(port + hp_scsictrl_0,
2583			   (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2584	} else {
2585
2586/*      auto_loaded =  (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2587      auto_loaded |= AUTO_IMMED; */
2588		auto_loaded = AUTO_IMMED;
2589
2590		DISABLE_AUTO(port);
2591
2592		WR_HARPOON(port + hp_autostart_3, auto_loaded);
2593	}
2594
2595	SGRAM_ACCESS(port);
2596}
2597
2598/*---------------------------------------------------------------------
2599 *
2600 * Function: FPT_sres
2601 *
2602 * Description: Hookup the correct CCB and handle the incoming messages.
2603 *
2604 *---------------------------------------------------------------------*/
2605
2606static void FPT_sres(u32 port, unsigned char p_card,
2607		     struct sccb_card *pCurrCard)
2608{
2609
2610	unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2611
2612	struct sccb_mgr_tar_info *currTar_Info;
2613	struct sccb *currSCCB;
2614
2615	if (pCurrCard->currentSCCB != NULL) {
2616		currTar_Info =
2617		    &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2618		DISABLE_AUTO(port);
2619
2620		WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2621
2622		currSCCB = pCurrCard->currentSCCB;
2623		if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2624			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2625			currSCCB->Sccb_scsistat = BUS_FREE_ST;
2626		}
2627		if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2628			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2629			currSCCB->Sccb_scsistat = BUS_FREE_ST;
2630		}
2631		if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2632		     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2633		      TAG_Q_TRYING))) {
2634			currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2635			if (currSCCB->Sccb_scsistat != ABORT_ST) {
2636				pCurrCard->discQCount--;
2637				pCurrCard->discQ_Tbl[currTar_Info->
2638						     LunDiscQ_Idx[currSCCB->
2639								  Lun]]
2640				    = NULL;
2641			}
2642		} else {
2643			currTar_Info->TarLUNBusy[0] = 0;
2644			if (currSCCB->Sccb_tag) {
2645				if (currSCCB->Sccb_scsistat != ABORT_ST) {
2646					pCurrCard->discQCount--;
2647					pCurrCard->discQ_Tbl[currSCCB->
2648							     Sccb_tag] = NULL;
2649				}
2650			} else {
2651				if (currSCCB->Sccb_scsistat != ABORT_ST) {
2652					pCurrCard->discQCount--;
2653					pCurrCard->discQ_Tbl[currTar_Info->
2654							     LunDiscQ_Idx[0]] =
2655					    NULL;
2656				}
2657			}
2658		}
2659
2660		FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2661	}
2662
2663	WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2664
2665	our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2666	currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2667
2668	msgRetryCount = 0;
2669	do {
2670
2671		currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2672		tag = 0;
2673
2674		while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2675			if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2676
2677				WRW_HARPOON((port + hp_intstat), PHASE);
2678				return;
2679			}
2680		}
2681
2682		WRW_HARPOON((port + hp_intstat), PHASE);
2683		if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2684
2685			message = FPT_sfm(port, pCurrCard->currentSCCB);
2686			if (message) {
2687
2688				if (message <= (0x80 | LUN_MASK)) {
2689					lun = message & (unsigned char)LUN_MASK;
2690
2691					if ((currTar_Info->
2692					     TarStatus & TAR_TAG_Q_MASK) ==
2693					    TAG_Q_TRYING) {
2694						if (currTar_Info->TarTagQ_Cnt !=
2695						    0) {
2696
2697							if (!
2698							    (currTar_Info->
2699							     TarLUN_CA)) {
2700								ACCEPT_MSG(port);	/*Release the ACK for ID msg. */
2701
2702								message =
2703								    FPT_sfm
2704								    (port,
2705								     pCurrCard->
2706								     currentSCCB);
2707								if (message) {
2708									ACCEPT_MSG
2709									    (port);
2710								}
2711
2712								else
2713									message
2714									    = 0;
2715
2716								if (message !=
2717								    0) {
2718									tag =
2719									    FPT_sfm
2720									    (port,
2721									     pCurrCard->
2722									     currentSCCB);
2723
2724									if (!
2725									    (tag))
2726										message
2727										    =
2728										    0;
2729								}
2730
2731							}
2732							/*C.A. exists! */
2733						}
2734						/*End Q cnt != 0 */
2735					}
2736					/*End Tag cmds supported! */
2737				}
2738				/*End valid ID message.  */
2739				else {
2740
2741					ACCEPT_MSG_ATN(port);
2742				}
2743
2744			}
2745			/* End good id message. */
2746			else {
2747
2748				message = 0;
2749			}
2750		} else {
2751			ACCEPT_MSG_ATN(port);
2752
2753			while (!
2754			       (RDW_HARPOON((port + hp_intstat)) &
2755				(PHASE | RESET))
2756			       && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2757			       && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2758
2759			return;
2760		}
2761
2762		if (message == 0) {
2763			msgRetryCount++;
2764			if (msgRetryCount == 1) {
2765				FPT_SendMsg(port, SMPARITY);
2766			} else {
2767				FPT_SendMsg(port, SMDEV_RESET);
2768
2769				FPT_sssyncv(port, our_target, NARROW_SCSI,
2770					    currTar_Info);
2771
2772				if (FPT_sccbMgrTbl[p_card][our_target].
2773				    TarEEValue & EE_SYNC_MASK) {
2774
2775					FPT_sccbMgrTbl[p_card][our_target].
2776					    TarStatus &= ~TAR_SYNC_MASK;
2777
2778				}
2779
2780				if (FPT_sccbMgrTbl[p_card][our_target].
2781				    TarEEValue & EE_WIDE_SCSI) {
2782
2783					FPT_sccbMgrTbl[p_card][our_target].
2784					    TarStatus &= ~TAR_WIDE_MASK;
2785				}
2786
2787				FPT_queueFlushTargSccb(p_card, our_target,
2788						       SCCB_COMPLETE);
2789				FPT_SccbMgrTableInitTarget(p_card, our_target);
2790				return;
2791			}
2792		}
2793	} while (message == 0);
2794
2795	if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2796	     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2797		currTar_Info->TarLUNBusy[lun] = 1;
2798		pCurrCard->currentSCCB =
2799		    pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2800		if (pCurrCard->currentSCCB != NULL) {
2801			ACCEPT_MSG(port);
2802		} else {
2803			ACCEPT_MSG_ATN(port);
2804		}
2805	} else {
2806		currTar_Info->TarLUNBusy[0] = 1;
2807
2808		if (tag) {
2809			if (pCurrCard->discQ_Tbl[tag] != NULL) {
2810				pCurrCard->currentSCCB =
2811				    pCurrCard->discQ_Tbl[tag];
2812				currTar_Info->TarTagQ_Cnt--;
2813				ACCEPT_MSG(port);
2814			} else {
2815				ACCEPT_MSG_ATN(port);
2816			}
2817		} else {
2818			pCurrCard->currentSCCB =
2819			    pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2820			if (pCurrCard->currentSCCB != NULL) {
2821				ACCEPT_MSG(port);
2822			} else {
2823				ACCEPT_MSG_ATN(port);
2824			}
2825		}
2826	}
2827
2828	if (pCurrCard->currentSCCB != NULL) {
2829		if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2830			/* During Abort Tag command, the target could have got re-selected
2831			   and completed the command. Check the select Q and remove the CCB
2832			   if it is in the Select Q */
2833			FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2834		}
2835	}
2836
2837	while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2838	       !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2839	       (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2840}
2841
2842static void FPT_SendMsg(u32 port, unsigned char message)
2843{
2844	while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2845		if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2846
2847			WRW_HARPOON((port + hp_intstat), PHASE);
2848			return;
2849		}
2850	}
2851
2852	WRW_HARPOON((port + hp_intstat), PHASE);
2853	if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2854		WRW_HARPOON((port + hp_intstat),
2855			    (BUS_FREE | PHASE | XFER_CNT_0));
2856
2857		WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2858
2859		WR_HARPOON(port + hp_scsidata_0, message);
2860
2861		WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2862
2863		ACCEPT_MSG(port);
2864
2865		WR_HARPOON(port + hp_portctrl_0, 0x00);
2866
2867		if ((message == SMABORT) || (message == SMDEV_RESET) ||
2868		    (message == SMABORT_TAG)) {
2869			while (!
2870			       (RDW_HARPOON((port + hp_intstat)) &
2871				(BUS_FREE | PHASE))) {
2872			}
2873
2874			if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2875				WRW_HARPOON((port + hp_intstat), BUS_FREE);
2876			}
2877		}
2878	}
2879}
2880
2881/*---------------------------------------------------------------------
2882 *
2883 * Function: FPT_sdecm
2884 *
2885 * Description: Determine the proper response to the message from the
2886 *              target device.
2887 *
2888 *---------------------------------------------------------------------*/
2889static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2890{
2891	struct sccb *currSCCB;
2892	struct sccb_card *CurrCard;
2893	struct sccb_mgr_tar_info *currTar_Info;
2894
2895	CurrCard = &FPT_BL_Card[p_card];
2896	currSCCB = CurrCard->currentSCCB;
2897
2898	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2899
2900	if (message == SMREST_DATA_PTR) {
2901		if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2902			currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2903
2904			FPT_hostDataXferRestart(currSCCB);
2905		}
2906
2907		ACCEPT_MSG(port);
2908		WR_HARPOON(port + hp_autostart_1,
2909			   (AUTO_IMMED + DISCONNECT_START));
2910	}
2911
2912	else if (message == SMCMD_COMP) {
2913
2914		if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2915			currTar_Info->TarStatus &=
2916			    ~(unsigned char)TAR_TAG_Q_MASK;
2917			currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2918		}
2919
2920		ACCEPT_MSG(port);
2921
2922	}
2923
2924	else if ((message == SMNO_OP) || (message >= SMIDENT)
2925		 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) {
 
2926
2927		ACCEPT_MSG(port);
2928		WR_HARPOON(port + hp_autostart_1,
2929			   (AUTO_IMMED + DISCONNECT_START));
2930	}
2931
2932	else if (message == SMREJECT) {
2933
2934		if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2935		    (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2936		    ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2937		    || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2938			TAG_Q_TRYING))
2939		{
2940			WRW_HARPOON((port + hp_intstat), BUS_FREE);
2941
2942			ACCEPT_MSG(port);
2943
2944			while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2945			       (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2946			{
2947			}
2948
2949			if (currSCCB->Lun == 0x00) {
2950				if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2951
2952					currTar_Info->TarStatus |=
2953					    (unsigned char)SYNC_SUPPORTED;
2954
2955					currTar_Info->TarEEValue &=
2956					    ~EE_SYNC_MASK;
2957				}
2958
2959				else if (currSCCB->Sccb_scsistat ==
2960					  SELECT_WN_ST) {
2961
2962					currTar_Info->TarStatus =
2963					    (currTar_Info->
2964					     TarStatus & ~WIDE_ENABLED) |
2965					    WIDE_NEGOCIATED;
2966
2967					currTar_Info->TarEEValue &=
2968					    ~EE_WIDE_SCSI;
2969
2970				}
2971
2972				else if ((currTar_Info->
2973					  TarStatus & TAR_TAG_Q_MASK) ==
2974					 TAG_Q_TRYING) {
2975					currTar_Info->TarStatus =
2976					    (currTar_Info->
2977					     TarStatus & ~(unsigned char)
2978					     TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2979
2980					currSCCB->ControlByte &= ~F_USE_CMD_Q;
2981					CurrCard->discQCount--;
2982					CurrCard->discQ_Tbl[currSCCB->
2983							    Sccb_tag] = NULL;
2984					currSCCB->Sccb_tag = 0x00;
2985
2986				}
2987			}
2988
2989			if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2990
2991				if (currSCCB->Lun == 0x00) {
2992					WRW_HARPOON((port + hp_intstat),
2993						    BUS_FREE);
2994					CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2995				}
2996			}
2997
2998			else {
2999
3000				if ((CurrCard->globalFlags & F_CONLUN_IO) &&
3001				    ((currTar_Info->
3002				      TarStatus & TAR_TAG_Q_MASK) !=
3003				     TAG_Q_TRYING))
3004					currTar_Info->TarLUNBusy[currSCCB->
3005								 Lun] = 1;
3006				else
3007					currTar_Info->TarLUNBusy[0] = 1;
3008
3009				currSCCB->ControlByte &=
3010				    ~(unsigned char)F_USE_CMD_Q;
3011
3012				WR_HARPOON(port + hp_autostart_1,
3013					   (AUTO_IMMED + DISCONNECT_START));
3014
3015			}
3016		}
3017
3018		else {
3019			ACCEPT_MSG(port);
3020
3021			while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
3022			       (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
3023			{
3024			}
3025
3026			if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
3027				WR_HARPOON(port + hp_autostart_1,
3028					   (AUTO_IMMED + DISCONNECT_START));
3029			}
3030		}
3031	}
3032
3033	else if (message == SMEXT) {
3034
3035		ACCEPT_MSG(port);
3036		FPT_shandem(port, p_card, currSCCB);
3037	}
3038
3039	else if (message == SMIGNORWR) {
3040
3041		ACCEPT_MSG(port);	/* ACK the RESIDUE MSG */
3042
3043		message = FPT_sfm(port, currSCCB);
3044
3045		if (currSCCB->Sccb_scsimsg != SMPARITY)
3046			ACCEPT_MSG(port);
3047		WR_HARPOON(port + hp_autostart_1,
3048			   (AUTO_IMMED + DISCONNECT_START));
3049	}
3050
3051	else {
3052
3053		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3054		currSCCB->Sccb_scsimsg = SMREJECT;
3055
3056		ACCEPT_MSG_ATN(port);
3057		WR_HARPOON(port + hp_autostart_1,
3058			   (AUTO_IMMED + DISCONNECT_START));
3059	}
3060}
3061
3062/*---------------------------------------------------------------------
3063 *
3064 * Function: FPT_shandem
3065 *
3066 * Description: Decide what to do with the extended message.
3067 *
3068 *---------------------------------------------------------------------*/
3069static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3070{
3071	unsigned char length, message;
3072
3073	length = FPT_sfm(port, pCurrSCCB);
3074	if (length) {
3075
3076		ACCEPT_MSG(port);
3077		message = FPT_sfm(port, pCurrSCCB);
3078		if (message) {
3079
3080			if (message == SMSYNC) {
3081
3082				if (length == 0x03) {
3083
3084					ACCEPT_MSG(port);
3085					FPT_stsyncn(port, p_card);
3086				} else {
3087
3088					pCurrSCCB->Sccb_scsimsg = SMREJECT;
3089					ACCEPT_MSG_ATN(port);
3090				}
3091			} else if (message == SMWDTR) {
3092
3093				if (length == 0x02) {
3094
3095					ACCEPT_MSG(port);
3096					FPT_stwidn(port, p_card);
3097				} else {
3098
3099					pCurrSCCB->Sccb_scsimsg = SMREJECT;
3100					ACCEPT_MSG_ATN(port);
3101
3102					WR_HARPOON(port + hp_autostart_1,
3103						   (AUTO_IMMED +
3104						    DISCONNECT_START));
3105				}
3106			} else {
3107
3108				pCurrSCCB->Sccb_scsimsg = SMREJECT;
3109				ACCEPT_MSG_ATN(port);
3110
3111				WR_HARPOON(port + hp_autostart_1,
3112					   (AUTO_IMMED + DISCONNECT_START));
3113			}
3114		} else {
3115			if (pCurrSCCB->Sccb_scsimsg != SMPARITY)
3116				ACCEPT_MSG(port);
3117			WR_HARPOON(port + hp_autostart_1,
3118				   (AUTO_IMMED + DISCONNECT_START));
3119		}
3120	} else {
3121		if (pCurrSCCB->Sccb_scsimsg == SMPARITY)
3122			WR_HARPOON(port + hp_autostart_1,
3123				   (AUTO_IMMED + DISCONNECT_START));
3124	}
3125}
3126
3127/*---------------------------------------------------------------------
3128 *
3129 * Function: FPT_sisyncn
3130 *
3131 * Description: Read in a message byte from the SCSI bus, and check
3132 *              for a parity error.
3133 *
3134 *---------------------------------------------------------------------*/
3135
3136static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3137				 unsigned char syncFlag)
3138{
3139	struct sccb *currSCCB;
3140	struct sccb_mgr_tar_info *currTar_Info;
3141
3142	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3143	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3144
3145	if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3146
3147		WRW_HARPOON((port + ID_MSG_STRT),
3148			    (MPM_OP + AMSG_OUT +
3149			     (currSCCB->
3150			      Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3151
3152		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3153
3154		WRW_HARPOON((port + SYNC_MSGS + 0),
3155			    (MPM_OP + AMSG_OUT + SMEXT));
3156		WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3157		WRW_HARPOON((port + SYNC_MSGS + 4),
3158			    (MPM_OP + AMSG_OUT + SMSYNC));
3159
3160		if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3161
3162			WRW_HARPOON((port + SYNC_MSGS + 6),
3163				    (MPM_OP + AMSG_OUT + 12));
3164
3165		else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3166			 EE_SYNC_10MB)
3167
3168			WRW_HARPOON((port + SYNC_MSGS + 6),
3169				    (MPM_OP + AMSG_OUT + 25));
3170
3171		else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3172			 EE_SYNC_5MB)
3173
3174			WRW_HARPOON((port + SYNC_MSGS + 6),
3175				    (MPM_OP + AMSG_OUT + 50));
3176
3177		else
3178			WRW_HARPOON((port + SYNC_MSGS + 6),
3179				    (MPM_OP + AMSG_OUT + 00));
3180
3181		WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3182		WRW_HARPOON((port + SYNC_MSGS + 10),
3183			    (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3184		WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3185
3186		if (syncFlag == 0) {
3187			WR_HARPOON(port + hp_autostart_3,
3188				   (SELECT + SELCHK_STRT));
3189			currTar_Info->TarStatus =
3190			    ((currTar_Info->
3191			      TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3192			     (unsigned char)SYNC_TRYING);
3193		} else {
3194			WR_HARPOON(port + hp_autostart_3,
3195				   (AUTO_IMMED + CMD_ONLY_STRT));
3196		}
3197
3198		return 1;
3199	}
3200
3201	else {
3202
3203		currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3204		currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3205		return 0;
3206	}
3207}
3208
3209/*---------------------------------------------------------------------
3210 *
3211 * Function: FPT_stsyncn
3212 *
3213 * Description: The has sent us a Sync Nego message so handle it as
3214 *              necessary.
3215 *
3216 *---------------------------------------------------------------------*/
3217static void FPT_stsyncn(u32 port, unsigned char p_card)
3218{
3219	unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3220	struct sccb *currSCCB;
3221	struct sccb_mgr_tar_info *currTar_Info;
3222
3223	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3224	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3225
3226	sync_msg = FPT_sfm(port, currSCCB);
3227
3228	if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3229		WR_HARPOON(port + hp_autostart_1,
3230			   (AUTO_IMMED + DISCONNECT_START));
3231		return;
3232	}
3233
3234	ACCEPT_MSG(port);
3235
3236	offset = FPT_sfm(port, currSCCB);
3237
3238	if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3239		WR_HARPOON(port + hp_autostart_1,
3240			   (AUTO_IMMED + DISCONNECT_START));
3241		return;
3242	}
3243
3244	if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3245
3246		our_sync_msg = 12;	/* Setup our Message to 20mb/s */
3247
3248	else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3249
3250		our_sync_msg = 25;	/* Setup our Message to 10mb/s */
3251
3252	else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3253
3254		our_sync_msg = 50;	/* Setup our Message to 5mb/s */
3255	else
3256
3257		our_sync_msg = 0;	/* Message = Async */
3258
3259	if (sync_msg < our_sync_msg) {
3260		sync_msg = our_sync_msg;	/*if faster, then set to max. */
3261	}
3262
3263	if (offset == ASYNC)
3264		sync_msg = ASYNC;
3265
3266	if (offset > MAX_OFFSET)
3267		offset = MAX_OFFSET;
3268
3269	sync_reg = 0x00;
3270
3271	if (sync_msg > 12)
3272
3273		sync_reg = 0x20;	/* Use 10MB/s */
3274
3275	if (sync_msg > 25)
3276
3277		sync_reg = 0x40;	/* Use 6.6MB/s */
3278
3279	if (sync_msg > 38)
3280
3281		sync_reg = 0x60;	/* Use 5MB/s */
3282
3283	if (sync_msg > 50)
3284
3285		sync_reg = 0x80;	/* Use 4MB/s */
3286
3287	if (sync_msg > 62)
3288
3289		sync_reg = 0xA0;	/* Use 3.33MB/s */
3290
3291	if (sync_msg > 75)
3292
3293		sync_reg = 0xC0;	/* Use 2.85MB/s */
3294
3295	if (sync_msg > 87)
3296
3297		sync_reg = 0xE0;	/* Use 2.5MB/s */
3298
3299	if (sync_msg > 100) {
3300
3301		sync_reg = 0x00;	/* Use ASYNC */
3302		offset = 0x00;
3303	}
3304
3305	if (currTar_Info->TarStatus & WIDE_ENABLED)
3306
3307		sync_reg |= offset;
3308
3309	else
3310
3311		sync_reg |= (offset | NARROW_SCSI);
3312
3313	FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3314
3315	if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3316
3317		ACCEPT_MSG(port);
3318
3319		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3320					    ~(unsigned char)TAR_SYNC_MASK) |
3321					   (unsigned char)SYNC_SUPPORTED);
3322
3323		WR_HARPOON(port + hp_autostart_1,
3324			   (AUTO_IMMED + DISCONNECT_START));
3325	}
3326
3327	else {
3328
3329		ACCEPT_MSG_ATN(port);
3330
3331		FPT_sisyncr(port, sync_msg, offset);
3332
3333		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3334					    ~(unsigned char)TAR_SYNC_MASK) |
3335					   (unsigned char)SYNC_SUPPORTED);
3336	}
3337}
3338
3339/*---------------------------------------------------------------------
3340 *
3341 * Function: FPT_sisyncr
3342 *
3343 * Description: Answer the targets sync message.
3344 *
3345 *---------------------------------------------------------------------*/
3346static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3347			unsigned char offset)
3348{
3349	ARAM_ACCESS(port);
3350	WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
 
3351	WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3352	WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC));
 
3353	WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3354	WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3355	WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3356	WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3357	SGRAM_ACCESS(port);
3358
3359	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3360	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3361
3362	WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3363
3364	while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3365	}
3366}
3367
3368/*---------------------------------------------------------------------
3369 *
3370 * Function: FPT_siwidn
3371 *
3372 * Description: Read in a message byte from the SCSI bus, and check
3373 *              for a parity error.
3374 *
3375 *---------------------------------------------------------------------*/
3376
3377static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3378{
3379	struct sccb *currSCCB;
3380	struct sccb_mgr_tar_info *currTar_Info;
3381
3382	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3383	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3384
3385	if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3386
3387		WRW_HARPOON((port + ID_MSG_STRT),
3388			    (MPM_OP + AMSG_OUT +
3389			     (currSCCB->
3390			      Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3391
3392		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3393
3394		WRW_HARPOON((port + SYNC_MSGS + 0),
3395			    (MPM_OP + AMSG_OUT + SMEXT));
3396		WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3397		WRW_HARPOON((port + SYNC_MSGS + 4),
3398			    (MPM_OP + AMSG_OUT + SMWDTR));
3399		WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3400		WRW_HARPOON((port + SYNC_MSGS + 8),
3401			    (MPM_OP + AMSG_OUT + SM16BIT));
3402		WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3403
3404		WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3405
3406		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3407					    ~(unsigned char)TAR_WIDE_MASK) |
3408					   (unsigned char)WIDE_ENABLED);
3409
3410		return 1;
3411	}
3412
3413	else {
3414
3415		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3416					    ~(unsigned char)TAR_WIDE_MASK) |
3417					   WIDE_NEGOCIATED);
3418
3419		currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3420		return 0;
3421	}
3422}
3423
3424/*---------------------------------------------------------------------
3425 *
3426 * Function: FPT_stwidn
3427 *
3428 * Description: The has sent us a Wide Nego message so handle it as
3429 *              necessary.
3430 *
3431 *---------------------------------------------------------------------*/
3432static void FPT_stwidn(u32 port, unsigned char p_card)
3433{
3434	unsigned char width;
3435	struct sccb *currSCCB;
3436	struct sccb_mgr_tar_info *currTar_Info;
3437
3438	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3439	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3440
3441	width = FPT_sfm(port, currSCCB);
3442
3443	if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3444		WR_HARPOON(port + hp_autostart_1,
3445			   (AUTO_IMMED + DISCONNECT_START));
3446		return;
3447	}
3448
3449	if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3450		width = 0;
3451
3452	if (width) {
3453		currTar_Info->TarStatus |= WIDE_ENABLED;
3454		width = 0;
3455	} else {
3456		width = NARROW_SCSI;
3457		currTar_Info->TarStatus &= ~WIDE_ENABLED;
3458	}
3459
3460	FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3461
3462	if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3463
3464		currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3465
3466		if (!
3467		    ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3468		     SYNC_SUPPORTED)) {
3469			ACCEPT_MSG_ATN(port);
3470			ARAM_ACCESS(port);
3471			FPT_sisyncn(port, p_card, 1);
3472			currSCCB->Sccb_scsistat = SELECT_SN_ST;
3473			SGRAM_ACCESS(port);
3474		} else {
3475			ACCEPT_MSG(port);
3476			WR_HARPOON(port + hp_autostart_1,
3477				   (AUTO_IMMED + DISCONNECT_START));
3478		}
3479	}
3480
3481	else {
3482
3483		ACCEPT_MSG_ATN(port);
3484
3485		if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3486			width = SM16BIT;
3487		else
3488			width = SM8BIT;
3489
3490		FPT_siwidr(port, width);
3491
3492		currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3493	}
3494}
3495
3496/*---------------------------------------------------------------------
3497 *
3498 * Function: FPT_siwidr
3499 *
3500 * Description: Answer the targets Wide nego message.
3501 *
3502 *---------------------------------------------------------------------*/
3503static void FPT_siwidr(u32 port, unsigned char width)
3504{
3505	ARAM_ACCESS(port);
3506	WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
 
3507	WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3508	WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR));
 
3509	WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3510	WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3511	WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3512	SGRAM_ACCESS(port);
3513
3514	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3515	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3516
3517	WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3518
3519	while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3520	}
3521}
3522
3523/*---------------------------------------------------------------------
3524 *
3525 * Function: FPT_sssyncv
3526 *
3527 * Description: Write the desired value to the Sync Register for the
3528 *              ID specified.
3529 *
3530 *---------------------------------------------------------------------*/
3531static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3532			unsigned char p_sync_value,
3533			struct sccb_mgr_tar_info *currTar_Info)
3534{
3535	unsigned char index;
3536
3537	index = p_id;
3538
3539	switch (index) {
3540
3541	case 0:
3542		index = 12;	/* hp_synctarg_0 */
3543		break;
3544	case 1:
3545		index = 13;	/* hp_synctarg_1 */
3546		break;
3547	case 2:
3548		index = 14;	/* hp_synctarg_2 */
3549		break;
3550	case 3:
3551		index = 15;	/* hp_synctarg_3 */
3552		break;
3553	case 4:
3554		index = 8;	/* hp_synctarg_4 */
3555		break;
3556	case 5:
3557		index = 9;	/* hp_synctarg_5 */
3558		break;
3559	case 6:
3560		index = 10;	/* hp_synctarg_6 */
3561		break;
3562	case 7:
3563		index = 11;	/* hp_synctarg_7 */
3564		break;
3565	case 8:
3566		index = 4;	/* hp_synctarg_8 */
3567		break;
3568	case 9:
3569		index = 5;	/* hp_synctarg_9 */
3570		break;
3571	case 10:
3572		index = 6;	/* hp_synctarg_10 */
3573		break;
3574	case 11:
3575		index = 7;	/* hp_synctarg_11 */
3576		break;
3577	case 12:
3578		index = 0;	/* hp_synctarg_12 */
3579		break;
3580	case 13:
3581		index = 1;	/* hp_synctarg_13 */
3582		break;
3583	case 14:
3584		index = 2;	/* hp_synctarg_14 */
3585		break;
3586	case 15:
3587		index = 3;	/* hp_synctarg_15 */
3588
3589	}
3590
3591	WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3592
3593	currTar_Info->TarSyncCtrl = p_sync_value;
3594}
3595
3596/*---------------------------------------------------------------------
3597 *
3598 * Function: FPT_sresb
3599 *
3600 * Description: Reset the desired card's SCSI bus.
3601 *
3602 *---------------------------------------------------------------------*/
3603static void FPT_sresb(u32 port, unsigned char p_card)
3604{
3605	unsigned char scsiID, i;
3606
3607	struct sccb_mgr_tar_info *currTar_Info;
3608
3609	WR_HARPOON(port + hp_page_ctrl,
3610		   (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3611	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3612
3613	WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3614
3615	scsiID = RD_HARPOON(port + hp_seltimeout);
3616	WR_HARPOON(port + hp_seltimeout, TO_5ms);
3617	WRW_HARPOON((port + hp_intstat), TIMEOUT);
3618
3619	WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3620
3621	while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3622	}
3623
3624	WR_HARPOON(port + hp_seltimeout, scsiID);
3625
3626	WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3627
3628	FPT_Wait(port, TO_5ms);
3629
3630	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3631
3632	WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3633
3634	for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3635		currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3636
3637		if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3638			currTar_Info->TarSyncCtrl = 0;
3639			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3640		}
3641
3642		if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3643			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3644		}
3645
3646		FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3647
3648		FPT_SccbMgrTableInitTarget(p_card, scsiID);
3649	}
3650
3651	FPT_BL_Card[p_card].scanIndex = 0x00;
3652	FPT_BL_Card[p_card].currentSCCB = NULL;
3653	FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3654					     | F_NEW_SCCB_CMD);
3655	FPT_BL_Card[p_card].cmdCounter = 0x00;
3656	FPT_BL_Card[p_card].discQCount = 0x00;
3657	FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3658
3659	for (i = 0; i < QUEUE_DEPTH; i++)
3660		FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3661
3662	WR_HARPOON(port + hp_page_ctrl,
3663		   (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3664
3665}
3666
3667/*---------------------------------------------------------------------
3668 *
3669 * Function: FPT_ssenss
3670 *
3671 * Description: Setup for the Auto Sense command.
3672 *
3673 *---------------------------------------------------------------------*/
3674static void FPT_ssenss(struct sccb_card *pCurrCard)
3675{
3676	unsigned char i;
3677	struct sccb *currSCCB;
3678
3679	currSCCB = pCurrCard->currentSCCB;
3680
3681	currSCCB->Save_CdbLen = currSCCB->CdbLength;
3682
3683	for (i = 0; i < 6; i++) {
3684
3685		currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3686	}
3687
3688	currSCCB->CdbLength = SIX_BYTE_CMD;
3689	currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3690	currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0;	/*Keep LUN. */
3691	currSCCB->Cdb[2] = 0x00;
3692	currSCCB->Cdb[3] = 0x00;
3693	currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3694	currSCCB->Cdb[5] = 0x00;
3695
3696	currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3697
3698	currSCCB->Sccb_ATC = 0x00;
3699
3700	currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3701
3702	currSCCB->Sccb_XferState &= ~F_SG_XFER;
3703
3704	currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3705
3706	currSCCB->ControlByte = 0x00;
3707
3708	currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3709}
3710
3711/*---------------------------------------------------------------------
3712 *
3713 * Function: FPT_sxfrp
3714 *
3715 * Description: Transfer data into the bit bucket until the device
3716 *              decides to switch phase.
3717 *
3718 *---------------------------------------------------------------------*/
3719
3720static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3721{
3722	unsigned char curr_phz;
3723
3724	DISABLE_AUTO(p_port);
3725
3726	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3727
3728		FPT_hostDataXferAbort(p_port, p_card,
3729				      FPT_BL_Card[p_card].currentSCCB);
3730
3731	}
3732
3733	/* If the Automation handled the end of the transfer then do not
3734	   match the phase or we will get out of sync with the ISR.       */
3735
3736	if (RDW_HARPOON((p_port + hp_intstat)) &
3737	    (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3738		return;
3739
3740	WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3741
3742	curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3743
3744	WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3745
3746	WR_HARPOON(p_port + hp_scsisig, curr_phz);
3747
3748	while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3749	       (curr_phz ==
3750		(RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3751	{
3752		if (curr_phz & (unsigned char)SCSI_IOBIT) {
3753			WR_HARPOON(p_port + hp_portctrl_0,
3754				   (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3755
3756			if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3757				RD_HARPOON(p_port + hp_fifodata_0);
3758			}
3759		} else {
3760			WR_HARPOON(p_port + hp_portctrl_0,
3761				   (SCSI_PORT | HOST_PORT | HOST_WRT));
3762			if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3763				WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3764			}
3765		}
3766	}			/* End of While loop for padding data I/O phase */
3767
3768	while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3769		if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3770			break;
3771	}
3772
3773	WR_HARPOON(p_port + hp_portctrl_0,
3774		   (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3775	while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3776		RD_HARPOON(p_port + hp_fifodata_0);
3777	}
3778
3779	if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3780		WR_HARPOON(p_port + hp_autostart_0,
3781			   (AUTO_IMMED + DISCONNECT_START));
3782		while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3783		}
3784
3785		if (RDW_HARPOON((p_port + hp_intstat)) &
3786		    (ICMD_COMP | ITAR_DISC))
3787			while (!
3788			       (RDW_HARPOON((p_port + hp_intstat)) &
3789				(BUS_FREE | RSEL))) ;
3790	}
3791}
3792
3793/*---------------------------------------------------------------------
3794 *
3795 * Function: FPT_schkdd
3796 *
3797 * Description: Make sure data has been flushed from both FIFOs and abort
3798 *              the operations if necessary.
3799 *
3800 *---------------------------------------------------------------------*/
3801
3802static void FPT_schkdd(u32 port, unsigned char p_card)
3803{
3804	unsigned short TimeOutLoop;
3805	unsigned char sPhase;
3806
3807	struct sccb *currSCCB;
3808
3809	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3810
3811	if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3812	    (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3813		return;
3814	}
3815
3816	if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3817
3818		currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3819
3820		currSCCB->Sccb_XferCnt = 1;
3821
3822		currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3823		WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3824		WR_HARPOON(port + hp_xferstat, 0x00);
3825	}
3826
3827	else {
3828
3829		currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3830
3831		currSCCB->Sccb_XferCnt = 0;
3832	}
3833
3834	if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3835	    (currSCCB->HostStatus == SCCB_COMPLETE)) {
3836
3837		currSCCB->HostStatus = SCCB_PARITY_ERR;
3838		WRW_HARPOON((port + hp_intstat), PARITY);
3839	}
3840
3841	FPT_hostDataXferAbort(port, p_card, currSCCB);
3842
3843	while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3844	}
3845
3846	TimeOutLoop = 0;
3847
3848	while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3849		if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3850			return;
3851		}
3852		if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3853			break;
3854		}
3855		if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3856			return;
3857		}
3858		if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3859		    || (TimeOutLoop++ > 0x3000))
3860			break;
3861	}
3862
3863	sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3864	if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3865	    (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3866	    (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3867	    (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3868
3869		WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3870
3871		if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3872			if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3873				FPT_phaseDataIn(port, p_card);
3874			}
3875
3876			else {
3877				FPT_phaseDataOut(port, p_card);
3878			}
3879		} else {
3880			FPT_sxfrp(port, p_card);
3881			if (!(RDW_HARPOON((port + hp_intstat)) &
3882			      (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3883				WRW_HARPOON((port + hp_intstat), AUTO_INT);
3884				FPT_phaseDecode(port, p_card);
3885			}
3886		}
3887
3888	}
3889
3890	else {
3891		WR_HARPOON(port + hp_portctrl_0, 0x00);
3892	}
3893}
3894
3895/*---------------------------------------------------------------------
3896 *
3897 * Function: FPT_sinits
3898 *
3899 * Description: Setup SCCB manager fields in this SCCB.
3900 *
3901 *---------------------------------------------------------------------*/
3902
3903static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3904{
3905	struct sccb_mgr_tar_info *currTar_Info;
3906
3907	if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3908		return;
3909	}
3910	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3911
3912	p_sccb->Sccb_XferState = 0x00;
3913	p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3914
3915	if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3916	    (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3917
3918		p_sccb->Sccb_SGoffset = 0;
3919		p_sccb->Sccb_XferState = F_SG_XFER;
3920		p_sccb->Sccb_XferCnt = 0x00;
3921	}
3922
3923	if (p_sccb->DataLength == 0x00)
3924
3925		p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3926
3927	if (p_sccb->ControlByte & F_USE_CMD_Q) {
3928		if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3929			p_sccb->ControlByte &= ~F_USE_CMD_Q;
3930
3931		else
3932			currTar_Info->TarStatus |= TAG_Q_TRYING;
3933	}
3934
3935/*      For !single SCSI device in system  & device allow Disconnect
3936	or command is tag_q type then send Cmd with Disconnect Enable
3937	else send Cmd with Disconnect Disable */
3938
3939/*
3940   if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3941      (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3942      (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3943*/
3944	if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3945	    (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3946		p_sccb->Sccb_idmsg =
3947		    (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
3948	}
3949
3950	else {
3951
3952		p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
3953	}
3954
3955	p_sccb->HostStatus = 0x00;
3956	p_sccb->TargetStatus = 0x00;
3957	p_sccb->Sccb_tag = 0x00;
3958	p_sccb->Sccb_MGRFlags = 0x00;
3959	p_sccb->Sccb_sgseg = 0x00;
3960	p_sccb->Sccb_ATC = 0x00;
3961	p_sccb->Sccb_savedATC = 0x00;
3962/*
3963   p_sccb->SccbVirtDataPtr    = 0x00;
3964   p_sccb->Sccb_forwardlink   = NULL;
3965   p_sccb->Sccb_backlink      = NULL;
3966 */
3967	p_sccb->Sccb_scsistat = BUS_FREE_ST;
3968	p_sccb->SccbStatus = SCCB_IN_PROCESS;
3969	p_sccb->Sccb_scsimsg = SMNO_OP;
3970
3971}
3972
3973/*---------------------------------------------------------------------
3974 *
3975 * Function: Phase Decode
3976 *
3977 * Description: Determine the phase and call the appropriate function.
3978 *
3979 *---------------------------------------------------------------------*/
3980
3981static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3982{
3983	unsigned char phase_ref;
3984	void (*phase) (u32, unsigned char);
3985
3986	DISABLE_AUTO(p_port);
3987
3988	phase_ref =
3989	    (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3990
3991	phase = FPT_s_PhaseTbl[phase_ref];
3992
3993	(*phase) (p_port, p_card);	/* Call the correct phase func */
3994}
3995
3996/*---------------------------------------------------------------------
3997 *
3998 * Function: Data Out Phase
3999 *
4000 * Description: Start up both the BusMaster and Xbow.
4001 *
4002 *---------------------------------------------------------------------*/
4003
4004static void FPT_phaseDataOut(u32 port, unsigned char p_card)
4005{
4006
4007	struct sccb *currSCCB;
4008
4009	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4010	if (currSCCB == NULL) {
4011		return;		/* Exit if No SCCB record */
4012	}
4013
4014	currSCCB->Sccb_scsistat = DATA_OUT_ST;
4015	currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4016
4017	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4018
4019	WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4020
4021	WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4022
4023	FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4024
4025	if (currSCCB->Sccb_XferCnt == 0) {
4026
4027		if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4028		    (currSCCB->HostStatus == SCCB_COMPLETE))
4029			currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4030
4031		FPT_sxfrp(port, p_card);
4032		if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4033			FPT_phaseDecode(port, p_card);
4034	}
4035}
4036
4037/*---------------------------------------------------------------------
4038 *
4039 * Function: Data In Phase
4040 *
4041 * Description: Startup the BusMaster and the XBOW.
4042 *
4043 *---------------------------------------------------------------------*/
4044
4045static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4046{
4047
4048	struct sccb *currSCCB;
4049
4050	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4051
4052	if (currSCCB == NULL) {
4053		return;		/* Exit if No SCCB record */
4054	}
4055
4056	currSCCB->Sccb_scsistat = DATA_IN_ST;
4057	currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4058	currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4059
4060	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4061
4062	WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4063
4064	WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4065
4066	FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4067
4068	if (currSCCB->Sccb_XferCnt == 0) {
4069
4070		if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4071		    (currSCCB->HostStatus == SCCB_COMPLETE))
4072			currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4073
4074		FPT_sxfrp(port, p_card);
4075		if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4076			FPT_phaseDecode(port, p_card);
4077
4078	}
4079}
4080
4081/*---------------------------------------------------------------------
4082 *
4083 * Function: Command Phase
4084 *
4085 * Description: Load the CDB into the automation and start it up.
4086 *
4087 *---------------------------------------------------------------------*/
4088
4089static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4090{
4091	struct sccb *currSCCB;
4092	u32 cdb_reg;
4093	unsigned char i;
4094
4095	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4096
4097	if (currSCCB->OperationCode == RESET_COMMAND) {
4098
4099		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4100		currSCCB->CdbLength = SIX_BYTE_CMD;
4101	}
4102
4103	WR_HARPOON(p_port + hp_scsisig, 0x00);
4104
4105	ARAM_ACCESS(p_port);
4106
4107	cdb_reg = p_port + CMD_STRT;
4108
4109	for (i = 0; i < currSCCB->CdbLength; i++) {
4110
4111		if (currSCCB->OperationCode == RESET_COMMAND)
4112
4113			WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4114
4115		else
4116			WRW_HARPOON(cdb_reg,
4117				    (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4118		cdb_reg += 2;
4119	}
4120
4121	if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4122		WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4123
4124	WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4125
4126	currSCCB->Sccb_scsistat = COMMAND_ST;
4127
4128	WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4129	SGRAM_ACCESS(p_port);
4130}
4131
4132/*---------------------------------------------------------------------
4133 *
4134 * Function: Status phase
4135 *
4136 * Description: Bring in the status and command complete message bytes
4137 *
4138 *---------------------------------------------------------------------*/
4139
4140static void FPT_phaseStatus(u32 port, unsigned char p_card)
4141{
4142	/* Start-up the automation to finish off this command and let the
4143	   isr handle the interrupt for command complete when it comes in.
4144	   We could wait here for the interrupt to be generated?
4145	 */
4146
4147	WR_HARPOON(port + hp_scsisig, 0x00);
4148
4149	WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4150}
4151
4152/*---------------------------------------------------------------------
4153 *
4154 * Function: Phase Message Out
4155 *
4156 * Description: Send out our message (if we have one) and handle whatever
4157 *              else is involed.
4158 *
4159 *---------------------------------------------------------------------*/
4160
4161static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4162{
4163	unsigned char message, scsiID;
4164	struct sccb *currSCCB;
4165	struct sccb_mgr_tar_info *currTar_Info;
4166
4167	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4168
4169	if (currSCCB != NULL) {
4170
4171		message = currSCCB->Sccb_scsimsg;
4172		scsiID = currSCCB->TargID;
4173
4174		if (message == SMDEV_RESET) {
4175
4176			currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4177			currTar_Info->TarSyncCtrl = 0;
4178			FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4179
4180			if (FPT_sccbMgrTbl[p_card][scsiID].
4181			    TarEEValue & EE_SYNC_MASK) {
4182
4183				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4184				    ~TAR_SYNC_MASK;
4185
4186			}
4187
4188			if (FPT_sccbMgrTbl[p_card][scsiID].
4189			    TarEEValue & EE_WIDE_SCSI) {
4190
4191				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4192				    ~TAR_WIDE_MASK;
4193			}
4194
4195			FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4196			FPT_SccbMgrTableInitTarget(p_card, scsiID);
4197		} else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4198			currSCCB->HostStatus = SCCB_COMPLETE;
4199			if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4200			    NULL) {
4201				FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4202							      Sccb_tag] = NULL;
4203				FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4204			}
4205
4206		}
4207
4208		else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4209
4210			if (message == SMNO_OP) {
4211				currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4212
4213				FPT_ssel(port, p_card);
4214				return;
4215			}
4216		} else {
4217
4218			if (message == SMABORT)
4219
4220				FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4221		}
4222
4223	} else {
4224		message = SMABORT;
4225	}
4226
4227	WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4228
4229	WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4230
4231	WR_HARPOON(port + hp_scsidata_0, message);
4232
4233	WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4234
4235	ACCEPT_MSG(port);
4236
4237	WR_HARPOON(port + hp_portctrl_0, 0x00);
4238
4239	if ((message == SMABORT) || (message == SMDEV_RESET) ||
4240	    (message == SMABORT_TAG)) {
4241
4242		while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4243		}
4244
4245		if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4246			WRW_HARPOON((port + hp_intstat), BUS_FREE);
4247
4248			if (currSCCB != NULL) {
4249
4250				if ((FPT_BL_Card[p_card].
4251				     globalFlags & F_CONLUN_IO)
4252				    &&
4253				    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4254				      TarStatus & TAR_TAG_Q_MASK) !=
4255				     TAG_Q_TRYING))
4256					FPT_sccbMgrTbl[p_card][currSCCB->
4257							       TargID].
4258					    TarLUNBusy[currSCCB->Lun] = 0;
4259				else
4260					FPT_sccbMgrTbl[p_card][currSCCB->
4261							       TargID].
4262					    TarLUNBusy[0] = 0;
4263
4264				FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4265						     currSCCB, p_card);
4266			}
4267
4268			else {
4269				FPT_BL_Card[p_card].globalFlags |=
4270				    F_NEW_SCCB_CMD;
4271			}
4272		}
4273
4274		else {
4275
4276			FPT_sxfrp(port, p_card);
4277		}
4278	}
4279
4280	else {
4281
4282		if (message == SMPARITY) {
4283			currSCCB->Sccb_scsimsg = SMNO_OP;
4284			WR_HARPOON(port + hp_autostart_1,
4285				   (AUTO_IMMED + DISCONNECT_START));
4286		} else {
4287			FPT_sxfrp(port, p_card);
4288		}
4289	}
4290}
4291
4292/*---------------------------------------------------------------------
4293 *
4294 * Function: Message In phase
4295 *
4296 * Description: Bring in the message and determine what to do with it.
4297 *
4298 *---------------------------------------------------------------------*/
4299
4300static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4301{
4302	unsigned char message;
4303	struct sccb *currSCCB;
4304
4305	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4306
4307	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4308
4309		FPT_phaseChkFifo(port, p_card);
4310	}
4311
4312	message = RD_HARPOON(port + hp_scsidata_0);
4313	if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) {
4314
4315		WR_HARPOON(port + hp_autostart_1,
4316			   (AUTO_IMMED + END_DATA_START));
4317
4318	}
4319
4320	else {
4321
4322		message = FPT_sfm(port, currSCCB);
4323		if (message) {
4324
4325			FPT_sdecm(message, port, p_card);
4326
4327		} else {
4328			if (currSCCB->Sccb_scsimsg != SMPARITY)
4329				ACCEPT_MSG(port);
4330			WR_HARPOON(port + hp_autostart_1,
4331				   (AUTO_IMMED + DISCONNECT_START));
4332		}
4333	}
4334
4335}
4336
4337/*---------------------------------------------------------------------
4338 *
4339 * Function: Illegal phase
4340 *
4341 * Description: Target switched to some illegal phase, so all we can do
4342 *              is report an error back to the host (if that is possible)
4343 *              and send an ABORT message to the misbehaving target.
4344 *
4345 *---------------------------------------------------------------------*/
4346
4347static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4348{
4349	struct sccb *currSCCB;
4350
4351	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4352
4353	WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4354	if (currSCCB != NULL) {
4355
4356		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4357		currSCCB->Sccb_scsistat = ABORT_ST;
4358		currSCCB->Sccb_scsimsg = SMABORT;
4359	}
4360
4361	ACCEPT_MSG_ATN(port);
4362}
4363
4364/*---------------------------------------------------------------------
4365 *
4366 * Function: Phase Check FIFO
4367 *
4368 * Description: Make sure data has been flushed from both FIFOs and abort
4369 *              the operations if necessary.
4370 *
4371 *---------------------------------------------------------------------*/
4372
4373static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4374{
4375	u32 xfercnt;
4376	struct sccb *currSCCB;
4377
4378	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4379
4380	if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4381
4382		while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4383		       (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4384		}
4385
4386		if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4387			currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4388
4389			currSCCB->Sccb_XferCnt = 0;
4390
4391			if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4392			    (currSCCB->HostStatus == SCCB_COMPLETE)) {
4393				currSCCB->HostStatus = SCCB_PARITY_ERR;
4394				WRW_HARPOON((port + hp_intstat), PARITY);
4395			}
4396
4397			FPT_hostDataXferAbort(port, p_card, currSCCB);
4398
4399			FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4400
4401			while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4402			       && (RD_HARPOON(port + hp_ext_status) &
4403				   BM_CMD_BUSY)) {
4404			}
4405
4406		}
4407	}
4408
4409	/*End Data In specific code. */
4410	GET_XFER_CNT(port, xfercnt);
4411
4412	WR_HARPOON(port + hp_xfercnt_0, 0x00);
4413
4414	WR_HARPOON(port + hp_portctrl_0, 0x00);
4415
4416	currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4417
4418	currSCCB->Sccb_XferCnt = xfercnt;
4419
4420	if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4421	    (currSCCB->HostStatus == SCCB_COMPLETE)) {
4422
4423		currSCCB->HostStatus = SCCB_PARITY_ERR;
4424		WRW_HARPOON((port + hp_intstat), PARITY);
4425	}
4426
4427	FPT_hostDataXferAbort(port, p_card, currSCCB);
4428
4429	WR_HARPOON(port + hp_fifowrite, 0x00);
4430	WR_HARPOON(port + hp_fiforead, 0x00);
4431	WR_HARPOON(port + hp_xferstat, 0x00);
4432
4433	WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4434}
4435
4436/*---------------------------------------------------------------------
4437 *
4438 * Function: Phase Bus Free
4439 *
4440 * Description: We just went bus free so figure out if it was
4441 *              because of command complete or from a disconnect.
4442 *
4443 *---------------------------------------------------------------------*/
4444static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4445{
4446	struct sccb *currSCCB;
4447
4448	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4449
4450	if (currSCCB != NULL) {
4451
4452		DISABLE_AUTO(port);
4453
4454		if (currSCCB->OperationCode == RESET_COMMAND) {
4455
4456			if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4457			    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4458			      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4459				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4460				    TarLUNBusy[currSCCB->Lun] = 0;
4461			else
4462				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4463				    TarLUNBusy[0] = 0;
4464
4465			FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4466					     p_card);
4467
4468			FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4469
4470		}
4471
4472		else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4473			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4474			    (unsigned char)SYNC_SUPPORTED;
4475			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4476			    ~EE_SYNC_MASK;
4477		}
4478
4479		else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4480			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4481			    (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4482			     TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4483
4484			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4485			    ~EE_WIDE_SCSI;
4486		}
4487
4488		else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4489			/* Make sure this is not a phony BUS_FREE.  If we were
4490			   reselected or if BUSY is NOT on then this is a
4491			   valid BUS FREE.  SRR Wednesday, 5/10/1995.     */
4492
4493			if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4494			    (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4495				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4496				    TarStatus &= ~TAR_TAG_Q_MASK;
4497				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4498				    TarStatus |= TAG_Q_REJECT;
4499			}
4500
4501			else {
4502				return;
4503			}
4504		}
4505
4506		else {
4507
4508			currSCCB->Sccb_scsistat = BUS_FREE_ST;
4509
4510			if (!currSCCB->HostStatus) {
4511				currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4512			}
4513
4514			if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4515			    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4516			      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4517				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4518				    TarLUNBusy[currSCCB->Lun] = 0;
4519			else
4520				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4521				    TarLUNBusy[0] = 0;
4522
4523			FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4524					     p_card);
4525			return;
4526		}
4527
4528		FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4529
4530	}			/*end if !=null */
4531}
4532
4533/*---------------------------------------------------------------------
4534 *
4535 * Function: Auto Load Default Map
4536 *
4537 * Description: Load the Automation RAM with the defualt map values.
4538 *
4539 *---------------------------------------------------------------------*/
4540static void FPT_autoLoadDefaultMap(u32 p_port)
4541{
4542	u32 map_addr;
4543
4544	ARAM_ACCESS(p_port);
4545	map_addr = p_port + hp_aramBase;
4546
4547	WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0));	/*ID MESSAGE */
4548	map_addr += 2;
4549	WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20));	/*SIMPLE TAG QUEUEING MSG */
4550	map_addr += 2;
4551	WRW_HARPOON(map_addr, RAT_OP);	/*RESET ATTENTION */
4552	map_addr += 2;
4553	WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00));	/*TAG ID MSG */
4554	map_addr += 2;
4555	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 0 */
4556	map_addr += 2;
4557	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 1 */
4558	map_addr += 2;
4559	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 2 */
4560	map_addr += 2;
4561	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 3 */
4562	map_addr += 2;
4563	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 4 */
4564	map_addr += 2;
4565	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 5 */
4566	map_addr += 2;
4567	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 6 */
4568	map_addr += 2;
4569	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 7 */
4570	map_addr += 2;
4571	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 8 */
4572	map_addr += 2;
4573	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 9 */
4574	map_addr += 2;
4575	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 10 */
4576	map_addr += 2;
4577	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 11 */
4578	map_addr += 2;
4579	WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT));	/*JUMP IF DATA OUT */
4580	map_addr += 2;
4581	WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI));	/*JUMP IF NO DATA IN FIFO */
4582	map_addr += 2;		/*This means AYNC DATA IN */
4583	WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT));	/*STOP AND INTERRUPT */
4584	map_addr += 2;
4585	WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT));	/*JUMP IF NOT DATA IN PHZ */
4586	map_addr += 2;
4587	WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST));	/*IF NOT MSG IN CHECK 4 DATA IN */
4588	map_addr += 2;
4589	WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02));	/*SAVE DATA PTR MSG? */
4590	map_addr += 2;
4591	WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC));	/*GO CHECK FOR DISCONNECT MSG */
4592	map_addr += 2;
4593	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1));	/*SAVE DATA PTRS MSG */
4594	map_addr += 2;
4595	WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST));	/*IF NOT MSG IN CHECK DATA IN */
4596	map_addr += 2;
4597	WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04));	/*DISCONNECT MSG? */
4598	map_addr += 2;
4599	WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN));	/*UKNKNOWN MSG */
4600	map_addr += 2;
4601	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET));	/*XFER DISCONNECT MSG */
4602	map_addr += 2;
4603	WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC));	/*STOP AND INTERRUPT */
4604	map_addr += 2;
4605	WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN));	/*JUMP IF NOT STATUS PHZ. */
4606	map_addr += 2;
4607	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0));	/*GET STATUS BYTE */
4608	map_addr += 2;
4609	WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC));	/*ERROR IF NOT MSG IN PHZ */
4610	map_addr += 2;
4611	WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00));	/*CHECK FOR CMD COMPLETE MSG. */
4612	map_addr += 2;
4613	WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC));	/*ERROR IF NOT CMD COMPLETE MSG. */
4614	map_addr += 2;
4615	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET));	/*GET CMD COMPLETE MSG */
4616	map_addr += 2;
4617	WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP));	/*END OF COMMAND */
4618	map_addr += 2;
4619
4620	WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN));	/*RECEIVED UNKNOWN MSG BYTE */
4621	map_addr += 2;
4622	WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC));	/*NO COMMAND COMPLETE AFTER STATUS */
4623	map_addr += 2;
4624	WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE));	/*BIOS Tickled the Mgr */
4625	map_addr += 2;
4626	WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL));	/*EXPECTED ID/TAG MESSAGES AND */
4627	map_addr += 2;		/* DIDN'T GET ONE */
4628	WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG));	/* comp SCSI SEL ID & AR3 */
4629	map_addr += 2;
4630	WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00));	/*SEL ID OK then Conti. */
4631	map_addr += 2;
4632	WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC));	/*NO COMMAND COMPLETE AFTER STATUS */
4633
4634	SGRAM_ACCESS(p_port);
4635}
4636
4637/*---------------------------------------------------------------------
4638 *
4639 * Function: Auto Command Complete
4640 *
4641 * Description: Post command back to host and find another command
4642 *              to execute.
4643 *
4644 *---------------------------------------------------------------------*/
4645
4646static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4647{
4648	struct sccb *currSCCB;
4649	unsigned char status_byte;
4650
4651	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4652
4653	status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4654
4655	FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4656
4657	if (status_byte != SSGOOD) {
4658
4659		if (status_byte == SSQ_FULL) {
4660
4661			if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4662			     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4663			       TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4664				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4665				    TarLUNBusy[currSCCB->Lun] = 1;
4666				if (FPT_BL_Card[p_card].discQCount != 0)
4667					FPT_BL_Card[p_card].discQCount--;
4668				FPT_BL_Card[p_card].
4669				    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4670					      [currSCCB->TargID].
4671					      LunDiscQ_Idx[currSCCB->Lun]] =
4672				    NULL;
4673			} else {
4674				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4675				    TarLUNBusy[0] = 1;
4676				if (currSCCB->Sccb_tag) {
4677					if (FPT_BL_Card[p_card].discQCount != 0)
4678						FPT_BL_Card[p_card].
4679						    discQCount--;
4680					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4681								      Sccb_tag]
4682					    = NULL;
4683				} else {
4684					if (FPT_BL_Card[p_card].discQCount != 0)
4685						FPT_BL_Card[p_card].
4686						    discQCount--;
4687					FPT_BL_Card[p_card].
4688					    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4689						      [currSCCB->TargID].
4690						      LunDiscQ_Idx[0]] = NULL;
4691				}
4692			}
4693
4694			currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4695
4696			FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4697
4698			return;
4699		}
4700
4701		if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4702			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4703			    (unsigned char)SYNC_SUPPORTED;
4704
4705			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4706			    ~EE_SYNC_MASK;
4707			FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4708
4709			if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4710			     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4711			       TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4712				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4713				    TarLUNBusy[currSCCB->Lun] = 1;
4714				if (FPT_BL_Card[p_card].discQCount != 0)
4715					FPT_BL_Card[p_card].discQCount--;
4716				FPT_BL_Card[p_card].
4717				    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4718					      [currSCCB->TargID].
4719					      LunDiscQ_Idx[currSCCB->Lun]] =
4720				    NULL;
4721			} else {
4722				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4723				    TarLUNBusy[0] = 1;
4724				if (currSCCB->Sccb_tag) {
4725					if (FPT_BL_Card[p_card].discQCount != 0)
4726						FPT_BL_Card[p_card].
4727						    discQCount--;
4728					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4729								      Sccb_tag]
4730					    = NULL;
4731				} else {
4732					if (FPT_BL_Card[p_card].discQCount != 0)
4733						FPT_BL_Card[p_card].
4734						    discQCount--;
4735					FPT_BL_Card[p_card].
4736					    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4737						      [currSCCB->TargID].
4738						      LunDiscQ_Idx[0]] = NULL;
4739				}
4740			}
4741			return;
4742
4743		}
4744
4745		if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4746
4747			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4748			    (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4749			     TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4750
4751			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4752			    ~EE_WIDE_SCSI;
4753			FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4754
4755			if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4756			     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4757			       TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4758				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4759				    TarLUNBusy[currSCCB->Lun] = 1;
4760				if (FPT_BL_Card[p_card].discQCount != 0)
4761					FPT_BL_Card[p_card].discQCount--;
4762				FPT_BL_Card[p_card].
4763				    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4764					      [currSCCB->TargID].
4765					      LunDiscQ_Idx[currSCCB->Lun]] =
4766				    NULL;
4767			} else {
4768				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4769				    TarLUNBusy[0] = 1;
4770				if (currSCCB->Sccb_tag) {
4771					if (FPT_BL_Card[p_card].discQCount != 0)
4772						FPT_BL_Card[p_card].
4773						    discQCount--;
4774					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4775								      Sccb_tag]
4776					    = NULL;
4777				} else {
4778					if (FPT_BL_Card[p_card].discQCount != 0)
4779						FPT_BL_Card[p_card].
4780						    discQCount--;
4781					FPT_BL_Card[p_card].
4782					    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4783						      [currSCCB->TargID].
4784						      LunDiscQ_Idx[0]] = NULL;
4785				}
4786			}
4787			return;
4788
4789		}
4790
4791		if (status_byte == SSCHECK) {
4792			if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4793				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4794				    TarEEValue & EE_SYNC_MASK) {
4795					FPT_sccbMgrTbl[p_card][currSCCB->
4796							       TargID].
4797					    TarStatus &= ~TAR_SYNC_MASK;
4798				}
4799				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4800				    TarEEValue & EE_WIDE_SCSI) {
4801					FPT_sccbMgrTbl[p_card][currSCCB->
4802							       TargID].
4803					    TarStatus &= ~TAR_WIDE_MASK;
4804				}
4805			}
4806		}
4807
4808		if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4809
4810			currSCCB->SccbStatus = SCCB_ERROR;
4811			currSCCB->TargetStatus = status_byte;
4812
4813			if (status_byte == SSCHECK) {
4814
4815				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4816				    TarLUN_CA = 1;
4817
4818				if (currSCCB->RequestSenseLength !=
4819				    NO_AUTO_REQUEST_SENSE) {
4820
4821					if (currSCCB->RequestSenseLength == 0)
4822						currSCCB->RequestSenseLength =
4823						    14;
4824
4825					FPT_ssenss(&FPT_BL_Card[p_card]);
4826					FPT_BL_Card[p_card].globalFlags |=
4827					    F_NEW_SCCB_CMD;
4828
4829					if (((FPT_BL_Card[p_card].
4830					      globalFlags & F_CONLUN_IO)
4831					     &&
4832					     ((FPT_sccbMgrTbl[p_card]
4833					       [currSCCB->TargID].
4834					       TarStatus & TAR_TAG_Q_MASK) !=
4835					      TAG_Q_TRYING))) {
4836						FPT_sccbMgrTbl[p_card]
4837						    [currSCCB->TargID].
4838						    TarLUNBusy[currSCCB->Lun] =
4839						    1;
4840						if (FPT_BL_Card[p_card].
4841						    discQCount != 0)
4842							FPT_BL_Card[p_card].
4843							    discQCount--;
4844						FPT_BL_Card[p_card].
4845						    discQ_Tbl[FPT_sccbMgrTbl
4846							      [p_card]
4847							      [currSCCB->
4848							       TargID].
4849							      LunDiscQ_Idx
4850							      [currSCCB->Lun]] =
4851						    NULL;
4852					} else {
4853						FPT_sccbMgrTbl[p_card]
4854						    [currSCCB->TargID].
4855						    TarLUNBusy[0] = 1;
4856						if (currSCCB->Sccb_tag) {
4857							if (FPT_BL_Card[p_card].
4858							    discQCount != 0)
4859								FPT_BL_Card
4860								    [p_card].
4861								    discQCount--;
4862							FPT_BL_Card[p_card].
4863							    discQ_Tbl[currSCCB->
4864								      Sccb_tag]
4865							    = NULL;
4866						} else {
4867							if (FPT_BL_Card[p_card].
4868							    discQCount != 0)
4869								FPT_BL_Card
4870								    [p_card].
4871								    discQCount--;
4872							FPT_BL_Card[p_card].
4873							    discQ_Tbl
4874							    [FPT_sccbMgrTbl
4875							     [p_card][currSCCB->
4876								      TargID].
4877							     LunDiscQ_Idx[0]] =
4878							    NULL;
4879						}
4880					}
4881					return;
4882				}
4883			}
4884		}
4885	}
4886
4887	if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4888	    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4889	      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4890		FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4891								    Lun] = 0;
4892	else
4893		FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4894
4895	FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4896}
4897
4898#define SHORT_WAIT   0x0000000F
4899#define LONG_WAIT    0x0000FFFFL
4900
4901/*---------------------------------------------------------------------
4902 *
4903 * Function: Data Transfer Processor
4904 *
4905 * Description: This routine performs two tasks.
4906 *              (1) Start data transfer by calling HOST_DATA_XFER_START
4907 *              function.  Once data transfer is started, (2) Depends
4908 *              on the type of data transfer mode Scatter/Gather mode
4909 *              or NON Scatter/Gather mode.  In NON Scatter/Gather mode,
4910 *              this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4911 *              data transfer done.  In Scatter/Gather mode, this routine
4912 *              checks bus master command complete and dual rank busy
4913 *              bit to keep chaining SC transfer command.  Similarly,
4914 *              in Scatter/Gather mode, it checks Sccb_MGRFlag
4915 *              (F_HOST_XFER_ACT bit) for data transfer done.
4916 *              
4917 *---------------------------------------------------------------------*/
4918
4919static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4920{
4921	struct sccb *currSCCB;
4922
4923	currSCCB = pCurrCard->currentSCCB;
4924
4925	if (currSCCB->Sccb_XferState & F_SG_XFER) {
4926		if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4927		{
4928			currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4929			currSCCB->Sccb_SGoffset = 0x00;
4930		}
4931		pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4932
4933		FPT_busMstrSGDataXferStart(port, currSCCB);
4934	}
4935
4936	else {
4937		if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4938			pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4939
4940			FPT_busMstrDataXferStart(port, currSCCB);
4941		}
4942	}
4943}
4944
4945/*---------------------------------------------------------------------
4946 *
4947 * Function: BusMaster Scatter Gather Data Transfer Start
4948 *
4949 * Description:
4950 *
4951 *---------------------------------------------------------------------*/
4952static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4953{
4954	u32 count, addr, tmpSGCnt;
4955	unsigned int sg_index;
4956	unsigned char sg_count, i;
4957	u32 reg_offset;
4958	struct blogic_sg_seg *segp;
4959
4960	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4961		count = ((u32)HOST_RD_CMD) << 24;
4962	else
4963		count = ((u32)HOST_WRT_CMD) << 24;
4964
4965	sg_count = 0;
4966	tmpSGCnt = 0;
4967	sg_index = pcurrSCCB->Sccb_sgseg;
4968	reg_offset = hp_aramBase;
4969
4970	i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4971			    ~(SGRAM_ARAM | SCATTER_EN));
4972
4973	WR_HARPOON(p_port + hp_page_ctrl, i);
4974
4975	while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4976			((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4977			pcurrSCCB->DataLength)) {
4978
4979		segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4980				sg_index;
4981		tmpSGCnt += segp->segbytes;
4982		count |= segp->segbytes;
4983		addr = segp->segdata;
4984
4985		if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4986			addr +=
4987			    ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4988			count =
4989			    (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4990			tmpSGCnt = count & 0x00FFFFFFL;
4991		}
4992
4993		WR_HARP32(p_port, reg_offset, addr);
4994		reg_offset += 4;
4995
4996		WR_HARP32(p_port, reg_offset, count);
4997		reg_offset += 4;
4998
4999		count &= 0xFF000000L;
5000		sg_index++;
5001		sg_count++;
5002
5003	}			/*End While */
5004
5005	pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5006
5007	WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
5008
5009	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5010
5011		WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5012
5013		WR_HARPOON(p_port + hp_portctrl_0,
5014			   (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5015		WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5016	}
5017
5018	else {
5019
5020		if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
5021		    (tmpSGCnt & 0x000000001)) {
5022
5023			pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5024			tmpSGCnt--;
5025		}
5026
5027		WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5028
5029		WR_HARPOON(p_port + hp_portctrl_0,
5030			   (SCSI_PORT | DMA_PORT | DMA_RD));
5031		WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5032	}
5033
5034	WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5035
5036}
5037
5038/*---------------------------------------------------------------------
5039 *
5040 * Function: BusMaster Data Transfer Start
5041 *
5042 * Description: 
5043 *
5044 *---------------------------------------------------------------------*/
5045static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5046{
5047	u32 addr, count;
5048
5049	if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5050
5051		count = pcurrSCCB->Sccb_XferCnt;
5052
5053		addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5054	}
5055
5056	else {
5057		addr = pcurrSCCB->SensePointer;
5058		count = pcurrSCCB->RequestSenseLength;
5059
5060	}
5061
5062	HP_SETUP_ADDR_CNT(p_port, addr, count);
5063
5064	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5065
5066		WR_HARPOON(p_port + hp_portctrl_0,
5067			   (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5068		WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5069
5070		WR_HARPOON(p_port + hp_xfer_cmd,
5071			   (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5072	}
5073
5074	else {
5075
5076		WR_HARPOON(p_port + hp_portctrl_0,
5077			   (SCSI_PORT | DMA_PORT | DMA_RD));
5078		WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5079
5080		WR_HARPOON(p_port + hp_xfer_cmd,
5081			   (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5082
5083	}
5084}
5085
5086/*---------------------------------------------------------------------
5087 *
5088 * Function: BusMaster Timeout Handler
5089 *
5090 * Description: This function is called after a bus master command busy time
5091 *               out is detected.  This routines issue halt state machine
5092 *               with a software time out for command busy.  If command busy
5093 *               is still asserted at the end of the time out, it issues
5094 *               hard abort with another software time out.  It hard abort
5095 *               command busy is also time out, it'll just give up.
5096 *
5097 *---------------------------------------------------------------------*/
5098static unsigned char FPT_busMstrTimeOut(u32 p_port)
5099{
5100	unsigned long timeout;
5101
5102	timeout = LONG_WAIT;
5103
5104	WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5105
5106	while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5107	       && timeout--) {
5108	}
5109
5110	if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5111		WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5112
5113		timeout = LONG_WAIT;
5114		while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5115		       && timeout--) {
5116		}
5117	}
5118
5119	RD_HARPOON(p_port + hp_int_status);	/*Clear command complete */
5120
5121	if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5122		return 1;
5123	}
5124
5125	else {
5126		return 0;
5127	}
5128}
5129
5130/*---------------------------------------------------------------------
5131 *
5132 * Function: Host Data Transfer Abort
5133 *
5134 * Description: Abort any in progress transfer.
5135 *
5136 *---------------------------------------------------------------------*/
5137static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5138				  struct sccb *pCurrSCCB)
5139{
5140
5141	unsigned long timeout;
5142	unsigned long remain_cnt;
5143	u32 sg_ptr;
5144	struct blogic_sg_seg *segp;
5145
5146	FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5147
5148	if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5149
5150		if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5151
5152			WR_HARPOON(port + hp_bm_ctrl,
5153				   (RD_HARPOON(port + hp_bm_ctrl) |
5154				    FLUSH_XFER_CNTR));
5155			timeout = LONG_WAIT;
5156
5157			while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5158			       && timeout--) {
5159			}
5160
5161			WR_HARPOON(port + hp_bm_ctrl,
5162				   (RD_HARPOON(port + hp_bm_ctrl) &
5163				    ~FLUSH_XFER_CNTR));
5164
5165			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5166
5167				if (FPT_busMstrTimeOut(port)) {
5168
5169					if (pCurrSCCB->HostStatus == 0x00)
5170
5171						pCurrSCCB->HostStatus =
5172						    SCCB_BM_ERR;
5173
5174				}
5175
5176				if (RD_HARPOON(port + hp_int_status) &
5177				    INT_EXT_STATUS)
5178
5179					if (RD_HARPOON(port + hp_ext_status) &
5180					    BAD_EXT_STATUS)
5181
5182						if (pCurrSCCB->HostStatus ==
5183						    0x00)
5184						{
5185							pCurrSCCB->HostStatus =
5186							    SCCB_BM_ERR;
5187						}
5188			}
5189		}
5190	}
5191
5192	else if (pCurrSCCB->Sccb_XferCnt) {
5193
5194		if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5195
5196			WR_HARPOON(port + hp_page_ctrl,
5197				   (RD_HARPOON(port + hp_page_ctrl) &
5198				    ~SCATTER_EN));
5199
5200			WR_HARPOON(port + hp_sg_addr, 0x00);
5201
5202			sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5203
5204			if (sg_ptr >
5205			    (unsigned int)(pCurrSCCB->DataLength /
5206					   SG_ELEMENT_SIZE)) {
5207
5208				sg_ptr = (u32)(pCurrSCCB->DataLength /
5209							SG_ELEMENT_SIZE);
5210			}
5211
5212			remain_cnt = pCurrSCCB->Sccb_XferCnt;
5213
5214			while (remain_cnt < 0x01000000L) {
5215
5216				sg_ptr--;
5217				segp = (struct blogic_sg_seg *)(pCurrSCCB->
5218						DataPointer) + (sg_ptr * 2);
5219				if (remain_cnt > (unsigned long)segp->segbytes)
5220					remain_cnt -=
5221						(unsigned long)segp->segbytes;
5222				else
5223					break;
5224			}
5225
5226			if (remain_cnt < 0x01000000L) {
5227
5228				pCurrSCCB->Sccb_SGoffset = remain_cnt;
5229
5230				pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5231
5232				if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5233				    pCurrSCCB->DataLength && (remain_cnt == 0))
5234
5235					pCurrSCCB->Sccb_XferState |=
5236					    F_ALL_XFERRED;
5237			}
5238
5239			else {
5240
5241				if (pCurrSCCB->HostStatus == 0x00) {
5242
5243					pCurrSCCB->HostStatus =
5244					    SCCB_GROSS_FW_ERR;
5245				}
5246			}
5247		}
5248
5249		if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5250
5251			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5252
5253				FPT_busMstrTimeOut(port);
5254			}
5255
5256			else {
5257
5258				if (RD_HARPOON(port + hp_int_status) &
5259				    INT_EXT_STATUS) {
5260
5261					if (RD_HARPOON(port + hp_ext_status) &
5262					    BAD_EXT_STATUS) {
5263
5264						if (pCurrSCCB->HostStatus ==
5265						    0x00) {
5266
5267							pCurrSCCB->HostStatus =
5268							    SCCB_BM_ERR;
5269						}
5270					}
5271				}
5272
5273			}
5274		}
5275
5276		else {
5277
5278			if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5279
5280				timeout = SHORT_WAIT;
5281
5282				while ((RD_HARPOON(port + hp_ext_status) &
5283					BM_CMD_BUSY)
5284				       && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5285					   BM_THRESHOLD) && timeout--) {
5286				}
5287			}
5288
5289			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5290
5291				WR_HARPOON(port + hp_bm_ctrl,
5292					   (RD_HARPOON(port + hp_bm_ctrl) |
5293					    FLUSH_XFER_CNTR));
5294
5295				timeout = LONG_WAIT;
5296
5297				while ((RD_HARPOON(port + hp_ext_status) &
5298					BM_CMD_BUSY) && timeout--) {
5299				}
5300
5301				WR_HARPOON(port + hp_bm_ctrl,
5302					   (RD_HARPOON(port + hp_bm_ctrl) &
5303					    ~FLUSH_XFER_CNTR));
5304
5305				if (RD_HARPOON(port + hp_ext_status) &
5306				    BM_CMD_BUSY) {
5307
5308					if (pCurrSCCB->HostStatus == 0x00) {
5309
5310						pCurrSCCB->HostStatus =
5311						    SCCB_BM_ERR;
5312					}
5313
5314					FPT_busMstrTimeOut(port);
5315				}
5316			}
5317
5318			if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5319
5320				if (RD_HARPOON(port + hp_ext_status) &
5321				    BAD_EXT_STATUS) {
5322
5323					if (pCurrSCCB->HostStatus == 0x00) {
5324
5325						pCurrSCCB->HostStatus =
5326						    SCCB_BM_ERR;
5327					}
5328				}
5329			}
5330		}
5331
5332	}
5333
5334	else {
5335
5336		if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5337
5338			timeout = LONG_WAIT;
5339
5340			while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5341			       && timeout--) {
5342			}
5343
5344			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5345
5346				if (pCurrSCCB->HostStatus == 0x00) {
5347
5348					pCurrSCCB->HostStatus = SCCB_BM_ERR;
5349				}
5350
5351				FPT_busMstrTimeOut(port);
5352			}
5353		}
5354
5355		if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5356
5357			if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5358
5359				if (pCurrSCCB->HostStatus == 0x00) {
5360
5361					pCurrSCCB->HostStatus = SCCB_BM_ERR;
5362				}
5363			}
5364
5365		}
5366
5367		if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5368
5369			WR_HARPOON(port + hp_page_ctrl,
5370				   (RD_HARPOON(port + hp_page_ctrl) &
5371				    ~SCATTER_EN));
5372
5373			WR_HARPOON(port + hp_sg_addr, 0x00);
5374
5375			pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5376
5377			pCurrSCCB->Sccb_SGoffset = 0x00;
5378
5379			if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5380					pCurrSCCB->DataLength) {
5381
5382				pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5383				pCurrSCCB->Sccb_sgseg =
5384				    (unsigned short)(pCurrSCCB->DataLength /
5385						     SG_ELEMENT_SIZE);
5386			}
5387		}
5388
5389		else {
5390			if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5391				pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5392		}
5393	}
5394
5395	WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5396}
5397
5398/*---------------------------------------------------------------------
5399 *
5400 * Function: Host Data Transfer Restart
5401 *
5402 * Description: Reset the available count due to a restore data
5403 *              pointers message.
5404 *
5405 *---------------------------------------------------------------------*/
5406static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5407{
5408	unsigned long data_count;
5409	unsigned int sg_index;
5410	struct blogic_sg_seg *segp;
5411
5412	if (currSCCB->Sccb_XferState & F_SG_XFER) {
5413
5414		currSCCB->Sccb_XferCnt = 0;
5415
5416		sg_index = 0xffff;	/*Index by long words into sg list. */
5417		data_count = 0;		/*Running count of SG xfer counts. */
5418
5419
5420		while (data_count < currSCCB->Sccb_ATC) {
5421
5422			sg_index++;
5423			segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5424						(sg_index * 2);
5425			data_count += segp->segbytes;
5426		}
5427
5428		if (data_count == currSCCB->Sccb_ATC) {
5429
5430			currSCCB->Sccb_SGoffset = 0;
5431			sg_index++;
5432		}
5433
5434		else {
5435			currSCCB->Sccb_SGoffset =
5436			    data_count - currSCCB->Sccb_ATC;
5437		}
5438
5439		currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5440	}
5441
5442	else {
5443		currSCCB->Sccb_XferCnt =
5444		    currSCCB->DataLength - currSCCB->Sccb_ATC;
5445	}
5446}
5447
5448/*---------------------------------------------------------------------
5449 *
5450 * Function: FPT_scini
5451 *
5452 * Description: Setup all data structures necessary for SCAM selection.
5453 *
5454 *---------------------------------------------------------------------*/
5455
5456static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5457		      unsigned char p_power_up)
5458{
5459
5460	unsigned char loser, assigned_id;
5461	u32 p_port;
5462
5463	unsigned char i, k, ScamFlg;
5464	struct sccb_card *currCard;
5465	struct nvram_info *pCurrNvRam;
5466
5467	currCard = &FPT_BL_Card[p_card];
5468	p_port = currCard->ioPort;
5469	pCurrNvRam = currCard->pNvRamInfo;
5470
5471	if (pCurrNvRam) {
5472		ScamFlg = pCurrNvRam->niScamConf;
5473		i = pCurrNvRam->niSysConf;
5474	} else {
5475		ScamFlg =
5476		    (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5477		i = (unsigned
5478		     char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5479	}
5480	if (!(i & 0x02))	/* check if reset bus in AutoSCSI parameter set */
5481		return;
5482
5483	FPT_inisci(p_card, p_port, p_our_id);
5484
5485	/* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5486	   too slow to return to SCAM selection */
5487
5488	/* if (p_power_up)
5489	   FPT_Wait1Second(p_port);
5490	   else
5491	   FPT_Wait(p_port, TO_250ms); */
5492
5493	FPT_Wait1Second(p_port);
5494
5495	if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5496		while (!(FPT_scarb(p_port, INIT_SELTD))) {
5497		}
5498
5499		FPT_scsel(p_port);
5500
5501		do {
5502			FPT_scxferc(p_port, SYNC_PTRN);
5503			FPT_scxferc(p_port, DOM_MSTR);
5504			loser =
5505			    FPT_scsendi(p_port,
5506					&FPT_scamInfo[p_our_id].id_string[0]);
5507		} while (loser == 0xFF);
5508
5509		FPT_scbusf(p_port);
5510
5511		if ((p_power_up) && (!loser)) {
5512			FPT_sresb(p_port, p_card);
5513			FPT_Wait(p_port, TO_250ms);
5514
5515			while (!(FPT_scarb(p_port, INIT_SELTD))) {
5516			}
5517
5518			FPT_scsel(p_port);
5519
5520			do {
5521				FPT_scxferc(p_port, SYNC_PTRN);
5522				FPT_scxferc(p_port, DOM_MSTR);
5523				loser =
5524				    FPT_scsendi(p_port,
5525						&FPT_scamInfo[p_our_id].
5526						id_string[0]);
5527			} while (loser == 0xFF);
5528
5529			FPT_scbusf(p_port);
5530		}
5531	}
5532
5533	else {
5534		loser = 0;
5535	}
5536
5537	if (!loser) {
5538
5539		FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5540
5541		if (ScamFlg & SCAM_ENABLED) {
5542
5543			for (i = 0; i < MAX_SCSI_TAR; i++) {
5544				if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5545				    (FPT_scamInfo[i].state == ID_UNUSED)) {
5546					if (FPT_scsell(p_port, i)) {
5547						FPT_scamInfo[i].state = LEGACY;
5548						if ((FPT_scamInfo[i].
5549						     id_string[0] != 0xFF)
5550						    || (FPT_scamInfo[i].
5551							id_string[1] != 0xFA)) {
5552
5553							FPT_scamInfo[i].
5554							    id_string[0] = 0xFF;
5555							FPT_scamInfo[i].
5556							    id_string[1] = 0xFA;
5557							if (pCurrNvRam == NULL)
5558								currCard->
5559								    globalFlags
5560								    |=
5561								    F_UPDATE_EEPROM;
5562						}
5563					}
5564				}
5565			}
5566
5567			FPT_sresb(p_port, p_card);
5568			FPT_Wait1Second(p_port);
5569			while (!(FPT_scarb(p_port, INIT_SELTD))) {
5570			}
5571			FPT_scsel(p_port);
5572			FPT_scasid(p_card, p_port);
5573		}
5574
5575	}
5576
5577	else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5578		FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5579		assigned_id = 0;
5580		FPT_scwtsel(p_port);
5581
5582		do {
5583			while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5584			}
5585
5586			i = FPT_scxferc(p_port, 0x00);
5587			if (i == ASSIGN_ID) {
5588				if (!
5589				    (FPT_scsendi
5590				     (p_port,
5591				      &FPT_scamInfo[p_our_id].id_string[0]))) {
5592					i = FPT_scxferc(p_port, 0x00);
5593					if (FPT_scvalq(i)) {
5594						k = FPT_scxferc(p_port, 0x00);
5595
5596						if (FPT_scvalq(k)) {
5597							currCard->ourId =
5598							    ((unsigned char)(i
5599									     <<
5600									     3)
5601							     +
5602							     (k &
5603							      (unsigned char)7))
5604							    & (unsigned char)
5605							    0x3F;
5606							FPT_inisci(p_card,
5607								   p_port,
5608								   p_our_id);
5609							FPT_scamInfo[currCard->
5610								     ourId].
5611							    state = ID_ASSIGNED;
5612							FPT_scamInfo[currCard->
5613								     ourId].
5614							    id_string[0]
5615							    = SLV_TYPE_CODE0;
5616							assigned_id = 1;
5617						}
5618					}
5619				}
5620			}
5621
5622			else if (i == SET_P_FLAG) {
5623				if (!(FPT_scsendi(p_port,
5624						  &FPT_scamInfo[p_our_id].
5625						  id_string[0])))
5626					FPT_scamInfo[p_our_id].id_string[0] |=
5627					    0x80;
5628			}
5629		} while (!assigned_id);
5630
5631		while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5632		}
5633	}
5634
5635	if (ScamFlg & SCAM_ENABLED) {
5636		FPT_scbusf(p_port);
5637		if (currCard->globalFlags & F_UPDATE_EEPROM) {
5638			FPT_scsavdi(p_card, p_port);
5639			currCard->globalFlags &= ~F_UPDATE_EEPROM;
5640		}
5641	}
5642
5643/*
5644   for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5645      {
5646      if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5647         (FPT_scamInfo[i].state == LEGACY))
5648         k++;
5649      }
5650
5651   if (k==2)
5652      currCard->globalFlags |= F_SINGLE_DEVICE;
5653   else
5654      currCard->globalFlags &= ~F_SINGLE_DEVICE;
5655*/
5656}
5657
5658/*---------------------------------------------------------------------
5659 *
5660 * Function: FPT_scarb
5661 *
5662 * Description: Gain control of the bus and wait SCAM select time (250ms)
5663 *
5664 *---------------------------------------------------------------------*/
5665
5666static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5667{
5668	if (p_sel_type == INIT_SELTD) {
5669
5670		while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5671		}
5672
5673		if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5674			return 0;
5675
5676		if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5677			return 0;
5678
5679		WR_HARPOON(p_port + hp_scsisig,
5680			   (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5681
5682		if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5683
5684			WR_HARPOON(p_port + hp_scsisig,
5685				   (RD_HARPOON(p_port + hp_scsisig) &
5686				    ~SCSI_BSY));
5687			return 0;
5688		}
5689
5690		WR_HARPOON(p_port + hp_scsisig,
5691			   (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5692
5693		if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5694
5695			WR_HARPOON(p_port + hp_scsisig,
5696				   (RD_HARPOON(p_port + hp_scsisig) &
5697				    ~(SCSI_BSY | SCSI_SEL)));
5698			return 0;
5699		}
5700	}
5701
5702	WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5703					   & ~ACTdeassert));
5704	WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5705	WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5706	WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5707	WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5708
5709	WR_HARPOON(p_port + hp_scsisig,
5710		   (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5711
5712	WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5713					 & ~SCSI_BSY));
5714
5715	FPT_Wait(p_port, TO_250ms);
5716
5717	return 1;
5718}
5719
5720/*---------------------------------------------------------------------
5721 *
5722 * Function: FPT_scbusf
5723 *
5724 * Description: Release the SCSI bus and disable SCAM selection.
5725 *
5726 *---------------------------------------------------------------------*/
5727
5728static void FPT_scbusf(u32 p_port)
5729{
5730	WR_HARPOON(p_port + hp_page_ctrl,
5731		   (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5732
5733	WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5734
5735	WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5736					    & ~SCSI_BUS_EN));
5737
5738	WR_HARPOON(p_port + hp_scsisig, 0x00);
5739
5740	WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5741					   & ~SCAM_EN));
5742
5743	WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5744					   | ACTdeassert));
5745
5746	WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5747
5748	WR_HARPOON(p_port + hp_page_ctrl,
5749		   (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5750}
5751
5752/*---------------------------------------------------------------------
5753 *
5754 * Function: FPT_scasid
5755 *
5756 * Description: Assign an ID to all the SCAM devices.
5757 *
5758 *---------------------------------------------------------------------*/
5759
5760static void FPT_scasid(unsigned char p_card, u32 p_port)
5761{
5762	unsigned char temp_id_string[ID_STRING_LENGTH];
5763
5764	unsigned char i, k, scam_id;
5765	unsigned char crcBytes[3];
5766	struct nvram_info *pCurrNvRam;
5767	unsigned short *pCrcBytes;
5768
5769	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5770
5771	i = 0;
5772
5773	while (!i) {
5774
5775		for (k = 0; k < ID_STRING_LENGTH; k++) {
5776			temp_id_string[k] = (unsigned char)0x00;
5777		}
5778
5779		FPT_scxferc(p_port, SYNC_PTRN);
5780		FPT_scxferc(p_port, ASSIGN_ID);
5781
5782		if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5783			if (pCurrNvRam) {
5784				pCrcBytes = (unsigned short *)&crcBytes[0];
5785				*pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5786				crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5787				temp_id_string[1] = crcBytes[2];
5788				temp_id_string[2] = crcBytes[0];
5789				temp_id_string[3] = crcBytes[1];
5790				for (k = 4; k < ID_STRING_LENGTH; k++)
5791					temp_id_string[k] = (unsigned char)0x00;
5792			}
5793			i = FPT_scmachid(p_card, temp_id_string);
5794
5795			if (i == CLR_PRIORITY) {
5796				FPT_scxferc(p_port, MISC_CODE);
5797				FPT_scxferc(p_port, CLR_P_FLAG);
5798				i = 0;	/*Not the last ID yet. */
5799			}
5800
5801			else if (i != NO_ID_AVAIL) {
5802				if (i < 8)
5803					FPT_scxferc(p_port, ID_0_7);
5804				else
5805					FPT_scxferc(p_port, ID_8_F);
5806
5807				scam_id = (i & (unsigned char)0x07);
5808
5809				for (k = 1; k < 0x08; k <<= 1)
5810					if (!(k & i))
5811						scam_id += 0x08;	/*Count number of zeros in DB0-3. */
5812
5813				FPT_scxferc(p_port, scam_id);
5814
5815				i = 0;	/*Not the last ID yet. */
5816			}
5817		}
5818
5819		else {
5820			i = 1;
5821		}
5822
5823	}			/*End while */
5824
5825	FPT_scxferc(p_port, SYNC_PTRN);
5826	FPT_scxferc(p_port, CFG_CMPLT);
5827}
5828
5829/*---------------------------------------------------------------------
5830 *
5831 * Function: FPT_scsel
5832 *
5833 * Description: Select all the SCAM devices.
5834 *
5835 *---------------------------------------------------------------------*/
5836
5837static void FPT_scsel(u32 p_port)
5838{
5839
5840	WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5841	FPT_scwiros(p_port, SCSI_MSG);
5842
5843	WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5844
5845	WR_HARPOON(p_port + hp_scsisig,
5846		   (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5847	WR_HARPOON(p_port + hp_scsidata_0,
5848		   (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5849				   (unsigned char)(BIT(7) + BIT(6))));
5850
5851	WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5852	FPT_scwiros(p_port, SCSI_SEL);
5853
5854	WR_HARPOON(p_port + hp_scsidata_0,
5855		   (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5856				   ~(unsigned char)BIT(6)));
5857	FPT_scwirod(p_port, BIT(6));
5858
5859	WR_HARPOON(p_port + hp_scsisig,
5860		   (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5861}
5862
5863/*---------------------------------------------------------------------
5864 *
5865 * Function: FPT_scxferc
5866 *
5867 * Description: Handshake the p_data (DB4-0) across the bus.
5868 *
5869 *---------------------------------------------------------------------*/
5870
5871static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5872{
5873	unsigned char curr_data, ret_data;
5874
5875	curr_data = p_data | BIT(7) | BIT(5);	/*Start with DB7 & DB5 asserted. */
5876
5877	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5878
5879	curr_data &= ~BIT(7);
5880
5881	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5882
5883	FPT_scwirod(p_port, BIT(7));	/*Wait for DB7 to be released. */
5884	while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5885
5886	ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5887
5888	curr_data |= BIT(6);
5889
5890	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5891
5892	curr_data &= ~BIT(5);
5893
5894	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5895
5896	FPT_scwirod(p_port, BIT(5));	/*Wait for DB5 to be released. */
5897
5898	curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0));	/*Release data bits */
5899	curr_data |= BIT(7);
5900
5901	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5902
5903	curr_data &= ~BIT(6);
5904
5905	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5906
5907	FPT_scwirod(p_port, BIT(6));	/*Wait for DB6 to be released. */
5908
5909	return ret_data;
5910}
5911
5912/*---------------------------------------------------------------------
5913 *
5914 * Function: FPT_scsendi
5915 *
5916 * Description: Transfer our Identification string to determine if we
5917 *              will be the dominant master.
5918 *
5919 *---------------------------------------------------------------------*/
5920
5921static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5922{
5923	unsigned char ret_data, byte_cnt, bit_cnt, defer;
5924
5925	defer = 0;
5926
5927	for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5928
5929		for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5930
5931			if (defer)
5932				ret_data = FPT_scxferc(p_port, 00);
5933
5934			else if (p_id_string[byte_cnt] & bit_cnt)
5935
5936				ret_data = FPT_scxferc(p_port, 02);
5937
5938			else {
5939
5940				ret_data = FPT_scxferc(p_port, 01);
5941				if (ret_data & 02)
5942					defer = 1;
5943			}
5944
5945			if ((ret_data & 0x1C) == 0x10)
5946				return 0x00;	/*End of isolation stage, we won! */
5947
5948			if (ret_data & 0x1C)
5949				return 0xFF;
5950
5951			if ((defer) && (!(ret_data & 0x1F)))
5952				return 0x01;	/*End of isolation stage, we lost. */
5953
5954		}		/*bit loop */
5955
5956	}			/*byte loop */
5957
5958	if (defer)
5959		return 0x01;	/*We lost */
5960	else
5961		return 0;	/*We WON! Yeeessss! */
5962}
5963
5964/*---------------------------------------------------------------------
5965 *
5966 * Function: FPT_sciso
5967 *
5968 * Description: Transfer the Identification string.
5969 *
5970 *---------------------------------------------------------------------*/
5971
5972static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5973{
5974	unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5975
5976	the_data = 0;
5977
5978	for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5979
5980		for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5981
5982			ret_data = FPT_scxferc(p_port, 0);
5983
5984			if (ret_data & 0xFC)
5985				return 0xFF;
5986
5987			else {
5988
5989				the_data <<= 1;
5990				if (ret_data & BIT(1)) {
5991					the_data |= 1;
5992				}
5993			}
5994
5995			if ((ret_data & 0x1F) == 0) {
5996/*
5997				if(bit_cnt != 0 || bit_cnt != 8)
5998				{
5999					byte_cnt = 0;
6000					bit_cnt = 0;
6001					FPT_scxferc(p_port, SYNC_PTRN);
6002					FPT_scxferc(p_port, ASSIGN_ID);
6003					continue;
6004				}
6005*/
6006				if (byte_cnt)
6007					return 0x00;
6008				else
6009					return 0xFF;
6010			}
6011
6012		}		/*bit loop */
6013
6014		p_id_string[byte_cnt] = the_data;
6015
6016	}			/*byte loop */
6017
6018	return 0;
6019}
6020
6021/*---------------------------------------------------------------------
6022 *
6023 * Function: FPT_scwirod
6024 *
6025 * Description: Sample the SCSI data bus making sure the signal has been
6026 *              deasserted for the correct number of consecutive samples.
6027 *
6028 *---------------------------------------------------------------------*/
6029
6030static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
6031{
6032	unsigned char i;
6033
6034	i = 0;
6035	while (i < MAX_SCSI_TAR) {
6036
6037		if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6038
6039			i = 0;
6040
6041		else
6042
6043			i++;
6044
6045	}
6046}
6047
6048/*---------------------------------------------------------------------
6049 *
6050 * Function: FPT_scwiros
6051 *
6052 * Description: Sample the SCSI Signal lines making sure the signal has been
6053 *              deasserted for the correct number of consecutive samples.
6054 *
6055 *---------------------------------------------------------------------*/
6056
6057static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6058{
6059	unsigned char i;
6060
6061	i = 0;
6062	while (i < MAX_SCSI_TAR) {
6063
6064		if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6065
6066			i = 0;
6067
6068		else
6069
6070			i++;
6071
6072	}
6073}
6074
6075/*---------------------------------------------------------------------
6076 *
6077 * Function: FPT_scvalq
6078 *
6079 * Description: Make sure we received a valid data byte.
6080 *
6081 *---------------------------------------------------------------------*/
6082
6083static unsigned char FPT_scvalq(unsigned char p_quintet)
6084{
6085	unsigned char count;
6086
6087	for (count = 1; count < 0x08; count <<= 1) {
6088		if (!(p_quintet & count))
6089			p_quintet -= 0x80;
6090	}
6091
6092	if (p_quintet & 0x18)
6093		return 0;
6094
6095	else
6096		return 1;
6097}
6098
6099/*---------------------------------------------------------------------
6100 *
6101 * Function: FPT_scsell
6102 *
6103 * Description: Select the specified device ID using a selection timeout
6104 *              less than 4ms.  If somebody responds then it is a legacy
6105 *              drive and this ID must be marked as such.
6106 *
6107 *---------------------------------------------------------------------*/
6108
6109static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6110{
6111	unsigned long i;
6112
6113	WR_HARPOON(p_port + hp_page_ctrl,
6114		   (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6115
6116	ARAM_ACCESS(p_port);
6117
6118	WR_HARPOON(p_port + hp_addstat,
6119		   (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6120	WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6121
6122	for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6123		WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6124	}
6125	WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6126
6127	WRW_HARPOON((p_port + hp_intstat),
6128		    (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6129
6130	WR_HARPOON(p_port + hp_select_id, targ_id);
6131
6132	WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6133	WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6134	WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6135
6136	while (!(RDW_HARPOON((p_port + hp_intstat)) &
6137		 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6138	}
6139
6140	if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6141		FPT_Wait(p_port, TO_250ms);
6142
6143	DISABLE_AUTO(p_port);
6144
6145	WR_HARPOON(p_port + hp_addstat,
6146		   (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6147	WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6148
6149	SGRAM_ACCESS(p_port);
6150
6151	if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6152
6153		WRW_HARPOON((p_port + hp_intstat),
6154			    (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6155
6156		WR_HARPOON(p_port + hp_page_ctrl,
6157			   (RD_HARPOON(p_port + hp_page_ctrl) &
6158			    ~G_INT_DISABLE));
6159
6160		return 0;	/*No legacy device */
6161	}
6162
6163	else {
6164
6165		while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6166			if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6167				WR_HARPOON(p_port + hp_scsisig,
6168					   (SCSI_ACK + S_ILL_PH));
6169				ACCEPT_MSG(p_port);
6170			}
6171		}
6172
6173		WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6174
6175		WR_HARPOON(p_port + hp_page_ctrl,
6176			   (RD_HARPOON(p_port + hp_page_ctrl) &
6177			    ~G_INT_DISABLE));
6178
6179		return 1;	/*Found one of them oldies! */
6180	}
6181}
6182
6183/*---------------------------------------------------------------------
6184 *
6185 * Function: FPT_scwtsel
6186 *
6187 * Description: Wait to be selected by another SCAM initiator.
6188 *
6189 *---------------------------------------------------------------------*/
6190
6191static void FPT_scwtsel(u32 p_port)
6192{
6193	while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6194	}
6195}
6196
6197/*---------------------------------------------------------------------
6198 *
6199 * Function: FPT_inisci
6200 *
6201 * Description: Setup the data Structure with the info from the EEPROM.
6202 *
6203 *---------------------------------------------------------------------*/
6204
6205static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6206{
6207	unsigned char i, k, max_id;
6208	unsigned short ee_data;
6209	struct nvram_info *pCurrNvRam;
6210
6211	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6212
6213	if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6214		max_id = 0x08;
6215
6216	else
6217		max_id = 0x10;
6218
6219	if (pCurrNvRam) {
6220		for (i = 0; i < max_id; i++) {
6221
6222			for (k = 0; k < 4; k++)
6223				FPT_scamInfo[i].id_string[k] =
6224				    pCurrNvRam->niScamTbl[i][k];
6225			for (k = 4; k < ID_STRING_LENGTH; k++)
6226				FPT_scamInfo[i].id_string[k] =
6227				    (unsigned char)0x00;
6228
6229			if (FPT_scamInfo[i].id_string[0] == 0x00)
6230				FPT_scamInfo[i].state = ID_UNUSED;	/*Default to unused ID. */
6231			else
6232				FPT_scamInfo[i].state = ID_UNASSIGNED;	/*Default to unassigned ID. */
6233
6234		}
6235	} else {
6236		for (i = 0; i < max_id; i++) {
6237			for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6238				ee_data =
6239				    FPT_utilEERead(p_port,
6240						   (unsigned
6241						    short)((EE_SCAMBASE / 2) +
6242							   (unsigned short)(i *
6243									    ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6244				FPT_scamInfo[i].id_string[k] =
6245				    (unsigned char)ee_data;
6246				ee_data >>= 8;
6247				FPT_scamInfo[i].id_string[k + 1] =
6248				    (unsigned char)ee_data;
6249			}
6250
6251			if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6252			    (FPT_scamInfo[i].id_string[0] == 0xFF))
6253
6254				FPT_scamInfo[i].state = ID_UNUSED;	/*Default to unused ID. */
6255
6256			else
6257				FPT_scamInfo[i].state = ID_UNASSIGNED;	/*Default to unassigned ID. */
6258
6259		}
6260	}
6261	for (k = 0; k < ID_STRING_LENGTH; k++)
6262		FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6263
6264}
6265
6266/*---------------------------------------------------------------------
6267 *
6268 * Function: FPT_scmachid
6269 *
6270 * Description: Match the Device ID string with our values stored in
6271 *              the EEPROM.
6272 *
6273 *---------------------------------------------------------------------*/
6274
6275static unsigned char FPT_scmachid(unsigned char p_card,
6276				  unsigned char p_id_string[])
6277{
6278
6279	unsigned char i, k, match;
6280
6281	for (i = 0; i < MAX_SCSI_TAR; i++) {
6282
6283		match = 1;
6284
6285		for (k = 0; k < ID_STRING_LENGTH; k++) {
6286			if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6287				match = 0;
6288		}
6289
6290		if (match) {
6291			FPT_scamInfo[i].state = ID_ASSIGNED;
6292			return i;
6293		}
6294
6295	}
6296
6297	if (p_id_string[0] & BIT(5))
6298		i = 8;
6299	else
6300		i = MAX_SCSI_TAR;
6301
6302	if (((p_id_string[0] & 0x06) == 0x02)
6303	    || ((p_id_string[0] & 0x06) == 0x04))
6304		match = p_id_string[1] & (unsigned char)0x1F;
6305	else
6306		match = 7;
6307
6308	while (i > 0) {
6309		i--;
6310
6311		if (FPT_scamInfo[match].state == ID_UNUSED) {
6312			for (k = 0; k < ID_STRING_LENGTH; k++) {
6313				FPT_scamInfo[match].id_string[k] =
6314				    p_id_string[k];
6315			}
6316
6317			FPT_scamInfo[match].state = ID_ASSIGNED;
6318
6319			if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6320				FPT_BL_Card[p_card].globalFlags |=
6321				    F_UPDATE_EEPROM;
6322			return match;
6323
6324		}
6325
6326		match--;
6327
6328		if (match == 0xFF) {
6329			if (p_id_string[0] & BIT(5))
6330				match = 7;
6331			else
6332				match = MAX_SCSI_TAR - 1;
6333		}
6334	}
6335
6336	if (p_id_string[0] & BIT(7)) {
6337		return CLR_PRIORITY;
6338	}
6339
6340	if (p_id_string[0] & BIT(5))
6341		i = 8;
6342	else
6343		i = MAX_SCSI_TAR;
6344
6345	if (((p_id_string[0] & 0x06) == 0x02)
6346	    || ((p_id_string[0] & 0x06) == 0x04))
6347		match = p_id_string[1] & (unsigned char)0x1F;
6348	else
6349		match = 7;
6350
6351	while (i > 0) {
6352
6353		i--;
6354
6355		if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6356			for (k = 0; k < ID_STRING_LENGTH; k++) {
6357				FPT_scamInfo[match].id_string[k] =
6358				    p_id_string[k];
6359			}
6360
6361			FPT_scamInfo[match].id_string[0] |= BIT(7);
6362			FPT_scamInfo[match].state = ID_ASSIGNED;
6363			if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6364				FPT_BL_Card[p_card].globalFlags |=
6365				    F_UPDATE_EEPROM;
6366			return match;
6367
6368		}
6369
6370		match--;
6371
6372		if (match == 0xFF) {
6373			if (p_id_string[0] & BIT(5))
6374				match = 7;
6375			else
6376				match = MAX_SCSI_TAR - 1;
6377		}
6378	}
6379
6380	return NO_ID_AVAIL;
6381}
6382
6383/*---------------------------------------------------------------------
6384 *
6385 * Function: FPT_scsavdi
6386 *
6387 * Description: Save off the device SCAM ID strings.
6388 *
6389 *---------------------------------------------------------------------*/
6390
6391static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6392{
6393	unsigned char i, k, max_id;
6394	unsigned short ee_data, sum_data;
6395
6396	sum_data = 0x0000;
6397
6398	for (i = 1; i < EE_SCAMBASE / 2; i++) {
6399		sum_data += FPT_utilEERead(p_port, i);
6400	}
6401
6402	FPT_utilEEWriteOnOff(p_port, 1);	/* Enable write access to the EEPROM */
6403
6404	if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6405		max_id = 0x08;
6406
6407	else
6408		max_id = 0x10;
6409
6410	for (i = 0; i < max_id; i++) {
6411
6412		for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6413			ee_data = FPT_scamInfo[i].id_string[k + 1];
6414			ee_data <<= 8;
6415			ee_data |= FPT_scamInfo[i].id_string[k];
6416			sum_data += ee_data;
6417			FPT_utilEEWrite(p_port, ee_data,
6418					(unsigned short)((EE_SCAMBASE / 2) +
6419							 (unsigned short)(i *
6420									  ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6421		}
6422	}
6423
6424	FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6425	FPT_utilEEWriteOnOff(p_port, 0);	/* Turn off write access */
6426}
6427
6428/*---------------------------------------------------------------------
6429 *
6430 * Function: FPT_XbowInit
6431 *
6432 * Description: Setup the Xbow for normal operation.
6433 *
6434 *---------------------------------------------------------------------*/
6435
6436static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6437{
6438	unsigned char i;
6439
6440	i = RD_HARPOON(port + hp_page_ctrl);
6441	WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6442
6443	WR_HARPOON(port + hp_scsireset, 0x00);
6444	WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6445
6446	WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6447					 FIFO_CLR));
6448
6449	WR_HARPOON(port + hp_scsireset, SCSI_INI);
6450
6451	WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6452
6453	WR_HARPOON(port + hp_scsisig, 0x00);	/*  Clear any signals we might */
6454	WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6455
6456	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6457
6458	FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6459	    BUS_FREE | XFER_CNT_0 | AUTO_INT;
6460
6461	if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6462		FPT_default_intena |= SCAM_SEL;
6463
6464	WRW_HARPOON((port + hp_intena), FPT_default_intena);
6465
6466	WR_HARPOON(port + hp_seltimeout, TO_290ms);
6467
6468	/* Turn on SCSI_MODE8 for narrow cards to fix the
6469	   strapping issue with the DUAL CHANNEL card */
6470	if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6471		WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6472
6473	WR_HARPOON(port + hp_page_ctrl, i);
6474
6475}
6476
6477/*---------------------------------------------------------------------
6478 *
6479 * Function: FPT_BusMasterInit
6480 *
6481 * Description: Initialize the BusMaster for normal operations.
6482 *
6483 *---------------------------------------------------------------------*/
6484
6485static void FPT_BusMasterInit(u32 p_port)
6486{
6487
6488	WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6489	WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6490
6491	WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6492
6493	WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6494
6495	WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6496
6497	RD_HARPOON(p_port + hp_int_status);	/*Clear interrupts. */
6498	WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6499	WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6500					   ~SCATTER_EN));
6501}
6502
6503/*---------------------------------------------------------------------
6504 *
6505 * Function: FPT_DiagEEPROM
6506 *
6507 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6508 *              necessary.
6509 *
6510 *---------------------------------------------------------------------*/
6511
6512static void FPT_DiagEEPROM(u32 p_port)
6513{
6514	unsigned short index, temp, max_wd_cnt;
6515
6516	if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6517		max_wd_cnt = EEPROM_WD_CNT;
6518	else
6519		max_wd_cnt = EEPROM_WD_CNT * 2;
6520
6521	temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6522
6523	if (temp == 0x4641) {
6524
6525		for (index = 2; index < max_wd_cnt; index++) {
6526
6527			temp += FPT_utilEERead(p_port, index);
6528
6529		}
6530
6531		if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6532
6533			return;	/*EEPROM is Okay so return now! */
6534		}
6535	}
6536
6537	FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6538
6539	for (index = 0; index < max_wd_cnt; index++) {
6540
6541		FPT_utilEEWrite(p_port, 0x0000, index);
6542	}
6543
6544	temp = 0;
6545
6546	FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6547	temp += 0x4641;
6548	FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6549	temp += 0x3920;
6550	FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6551	temp += 0x3033;
6552	FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6553	temp += 0x2020;
6554	FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6555	temp += 0x70D3;
6556	FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6557	temp += 0x0010;
6558	FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6559	temp += 0x0003;
6560	FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6561	temp += 0x0007;
6562
6563	FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6564	temp += 0x0000;
6565	FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6566	temp += 0x0000;
6567	FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6568	temp += 0x0000;
6569
6570	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6571	temp += 0x4242;
6572	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6573	temp += 0x4242;
6574	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6575	temp += 0x4242;
6576	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6577	temp += 0x4242;
6578	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6579	temp += 0x4242;
6580	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6581	temp += 0x4242;
6582	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6583	temp += 0x4242;
6584	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6585	temp += 0x4242;
6586
6587	FPT_utilEEWrite(p_port, 0x6C46, 64 / 2);	/*PRODUCT ID */
6588	temp += 0x6C46;
6589	FPT_utilEEWrite(p_port, 0x7361, 66 / 2);	/* FlashPoint LT   */
6590	temp += 0x7361;
6591	FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6592	temp += 0x5068;
6593	FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6594	temp += 0x696F;
6595	FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6596	temp += 0x746E;
6597	FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6598	temp += 0x4C20;
6599	FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6600	temp += 0x2054;
6601	FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6602	temp += 0x2020;
6603
6604	index = ((EE_SCAMBASE / 2) + (7 * 16));
6605	FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6606	temp += (0x0700 + TYPE_CODE0);
6607	index++;
6608	FPT_utilEEWrite(p_port, 0x5542, index);	/*Vendor ID code */
6609	temp += 0x5542;		/* BUSLOGIC      */
6610	index++;
6611	FPT_utilEEWrite(p_port, 0x4C53, index);
6612	temp += 0x4C53;
6613	index++;
6614	FPT_utilEEWrite(p_port, 0x474F, index);
6615	temp += 0x474F;
6616	index++;
6617	FPT_utilEEWrite(p_port, 0x4349, index);
6618	temp += 0x4349;
6619	index++;
6620	FPT_utilEEWrite(p_port, 0x5442, index);	/*Vendor unique code */
6621	temp += 0x5442;		/* BT- 930           */
6622	index++;
6623	FPT_utilEEWrite(p_port, 0x202D, index);
6624	temp += 0x202D;
6625	index++;
6626	FPT_utilEEWrite(p_port, 0x3339, index);
6627	temp += 0x3339;
6628	index++;		/*Serial #          */
6629	FPT_utilEEWrite(p_port, 0x2030, index);	/* 01234567         */
6630	temp += 0x2030;
6631	index++;
6632	FPT_utilEEWrite(p_port, 0x5453, index);
6633	temp += 0x5453;
6634	index++;
6635	FPT_utilEEWrite(p_port, 0x5645, index);
6636	temp += 0x5645;
6637	index++;
6638	FPT_utilEEWrite(p_port, 0x2045, index);
6639	temp += 0x2045;
6640	index++;
6641	FPT_utilEEWrite(p_port, 0x202F, index);
6642	temp += 0x202F;
6643	index++;
6644	FPT_utilEEWrite(p_port, 0x4F4A, index);
6645	temp += 0x4F4A;
6646	index++;
6647	FPT_utilEEWrite(p_port, 0x204E, index);
6648	temp += 0x204E;
6649	index++;
6650	FPT_utilEEWrite(p_port, 0x3539, index);
6651	temp += 0x3539;
6652
6653	FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6654
6655	FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6656
6657}
6658
6659/*---------------------------------------------------------------------
6660 *
6661 * Function: Queue Search Select
6662 *
6663 * Description: Try to find a new command to execute.
6664 *
6665 *---------------------------------------------------------------------*/
6666
6667static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6668				  unsigned char p_card)
6669{
6670	unsigned char scan_ptr, lun;
6671	struct sccb_mgr_tar_info *currTar_Info;
6672	struct sccb *pOldSccb;
6673
6674	scan_ptr = pCurrCard->scanIndex;
6675	do {
6676		currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6677		if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6678		    ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6679		     TAG_Q_TRYING)) {
6680			if (currTar_Info->TarSelQ_Cnt != 0) {
6681
6682				scan_ptr++;
6683				if (scan_ptr == MAX_SCSI_TAR)
6684					scan_ptr = 0;
6685
6686				for (lun = 0; lun < MAX_LUN; lun++) {
6687					if (currTar_Info->TarLUNBusy[lun] == 0) {
6688
6689						pCurrCard->currentSCCB =
6690						    currTar_Info->TarSelQ_Head;
6691						pOldSccb = NULL;
6692
6693						while ((pCurrCard->
6694							currentSCCB != NULL)
6695						       && (lun !=
6696							   pCurrCard->
6697							   currentSCCB->Lun)) {
6698							pOldSccb =
6699							    pCurrCard->
6700							    currentSCCB;
6701							pCurrCard->currentSCCB =
6702							    (struct sccb
6703							     *)(pCurrCard->
6704								currentSCCB)->
6705							    Sccb_forwardlink;
6706						}
6707						if (pCurrCard->currentSCCB ==
6708						    NULL)
6709							continue;
6710						if (pOldSccb != NULL) {
6711							pOldSccb->
6712							    Sccb_forwardlink =
6713							    (struct sccb
6714							     *)(pCurrCard->
6715								currentSCCB)->
6716							    Sccb_forwardlink;
6717							pOldSccb->
6718							    Sccb_backlink =
6719							    (struct sccb
6720							     *)(pCurrCard->
6721								currentSCCB)->
6722							    Sccb_backlink;
6723							currTar_Info->
6724							    TarSelQ_Cnt--;
6725						} else {
6726							currTar_Info->
6727							    TarSelQ_Head =
6728							    (struct sccb
6729							     *)(pCurrCard->
6730								currentSCCB)->
6731							    Sccb_forwardlink;
6732
6733							if (currTar_Info->
6734							    TarSelQ_Head ==
6735							    NULL) {
6736								currTar_Info->
6737								    TarSelQ_Tail
6738								    = NULL;
6739								currTar_Info->
6740								    TarSelQ_Cnt
6741								    = 0;
6742							} else {
6743								currTar_Info->
6744								    TarSelQ_Cnt--;
6745								currTar_Info->
6746								    TarSelQ_Head->
6747								    Sccb_backlink
6748								    =
6749								    (struct sccb
6750								     *)NULL;
6751							}
6752						}
6753						pCurrCard->scanIndex = scan_ptr;
6754
6755						pCurrCard->globalFlags |=
6756						    F_NEW_SCCB_CMD;
6757
6758						break;
6759					}
6760				}
6761			}
6762
6763			else {
6764				scan_ptr++;
6765				if (scan_ptr == MAX_SCSI_TAR) {
6766					scan_ptr = 0;
6767				}
6768			}
6769
6770		} else {
6771			if ((currTar_Info->TarSelQ_Cnt != 0) &&
6772			    (currTar_Info->TarLUNBusy[0] == 0)) {
6773
6774				pCurrCard->currentSCCB =
6775				    currTar_Info->TarSelQ_Head;
6776
6777				currTar_Info->TarSelQ_Head =
6778				    (struct sccb *)(pCurrCard->currentSCCB)->
6779				    Sccb_forwardlink;
6780
6781				if (currTar_Info->TarSelQ_Head == NULL) {
6782					currTar_Info->TarSelQ_Tail = NULL;
6783					currTar_Info->TarSelQ_Cnt = 0;
6784				} else {
6785					currTar_Info->TarSelQ_Cnt--;
6786					currTar_Info->TarSelQ_Head->
6787					    Sccb_backlink = (struct sccb *)NULL;
6788				}
6789
6790				scan_ptr++;
6791				if (scan_ptr == MAX_SCSI_TAR)
6792					scan_ptr = 0;
6793
6794				pCurrCard->scanIndex = scan_ptr;
6795
6796				pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6797
6798				break;
6799			}
6800
6801			else {
6802				scan_ptr++;
6803				if (scan_ptr == MAX_SCSI_TAR) {
6804					scan_ptr = 0;
6805				}
6806			}
6807		}
6808	} while (scan_ptr != pCurrCard->scanIndex);
6809}
6810
6811/*---------------------------------------------------------------------
6812 *
6813 * Function: Queue Select Fail
6814 *
6815 * Description: Add the current SCCB to the head of the Queue.
6816 *
6817 *---------------------------------------------------------------------*/
6818
6819static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6820				unsigned char p_card)
6821{
6822	unsigned char thisTarg;
6823	struct sccb_mgr_tar_info *currTar_Info;
6824
6825	if (pCurrCard->currentSCCB != NULL) {
6826		thisTarg =
6827		    (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6828				    TargID);
6829		currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6830
6831		pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6832
6833		pCurrCard->currentSCCB->Sccb_forwardlink =
6834		    currTar_Info->TarSelQ_Head;
6835
6836		if (currTar_Info->TarSelQ_Cnt == 0) {
6837			currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6838		}
6839
6840		else {
6841			currTar_Info->TarSelQ_Head->Sccb_backlink =
6842			    pCurrCard->currentSCCB;
6843		}
6844
6845		currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6846
6847		pCurrCard->currentSCCB = NULL;
6848		currTar_Info->TarSelQ_Cnt++;
6849	}
6850}
6851
6852/*---------------------------------------------------------------------
6853 *
6854 * Function: Queue Command Complete
6855 *
6856 * Description: Call the callback function with the current SCCB.
6857 *
6858 *---------------------------------------------------------------------*/
6859
6860static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6861				 struct sccb *p_sccb, unsigned char p_card)
6862{
6863
6864	unsigned char i, SCSIcmd;
6865	CALL_BK_FN callback;
6866	struct sccb_mgr_tar_info *currTar_Info;
6867
6868	SCSIcmd = p_sccb->Cdb[0];
6869
6870	if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6871
6872		if ((p_sccb->
6873		     ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6874		    && (p_sccb->HostStatus == SCCB_COMPLETE)
6875		    && (p_sccb->TargetStatus != SSCHECK))
6876
6877			if ((SCSIcmd == SCSI_READ) ||
6878			    (SCSIcmd == SCSI_WRITE) ||
6879			    (SCSIcmd == SCSI_READ_EXTENDED) ||
6880			    (SCSIcmd == SCSI_WRITE_EXTENDED) ||
6881			    (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
6882			    (SCSIcmd == SCSI_START_STOP_UNIT) ||
6883			    (pCurrCard->globalFlags & F_NO_FILTER)
6884			    )
6885				p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6886	}
6887
6888	if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6889		if (p_sccb->HostStatus || p_sccb->TargetStatus)
6890			p_sccb->SccbStatus = SCCB_ERROR;
6891		else
6892			p_sccb->SccbStatus = SCCB_SUCCESS;
6893	}
6894
6895	if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6896
6897		p_sccb->CdbLength = p_sccb->Save_CdbLen;
6898		for (i = 0; i < 6; i++) {
6899			p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6900		}
6901	}
6902
6903	if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6904	    (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6905
6906		FPT_utilUpdateResidual(p_sccb);
6907	}
6908
6909	pCurrCard->cmdCounter--;
6910	if (!pCurrCard->cmdCounter) {
6911
6912		if (pCurrCard->globalFlags & F_GREEN_PC) {
6913			WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6914				   (PWR_DWN | CLKCTRL_DEFAULT));
6915			WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6916		}
6917
6918		WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6919			   (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6920			    ~SCCB_MGR_ACTIVE));
6921
6922	}
6923
6924	if (pCurrCard->discQCount != 0) {
6925		currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6926		if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6927		     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6928		      TAG_Q_TRYING))) {
6929			pCurrCard->discQCount--;
6930			pCurrCard->discQ_Tbl[currTar_Info->
6931					     LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6932		} else {
6933			if (p_sccb->Sccb_tag) {
6934				pCurrCard->discQCount--;
6935				pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6936			} else {
6937				pCurrCard->discQCount--;
6938				pCurrCard->discQ_Tbl[currTar_Info->
6939						     LunDiscQ_Idx[0]] = NULL;
6940			}
6941		}
6942
6943	}
6944
6945	callback = (CALL_BK_FN) p_sccb->SccbCallback;
6946	callback(p_sccb);
6947	pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6948	pCurrCard->currentSCCB = NULL;
6949}
6950
6951/*---------------------------------------------------------------------
6952 *
6953 * Function: Queue Disconnect
6954 *
6955 * Description: Add SCCB to our disconnect array.
6956 *
6957 *---------------------------------------------------------------------*/
6958static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6959{
6960	struct sccb_mgr_tar_info *currTar_Info;
6961
6962	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6963
6964	if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6965	     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6966		FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6967					      LunDiscQ_Idx[p_sccb->Lun]] =
6968		    p_sccb;
6969	} else {
6970		if (p_sccb->Sccb_tag) {
6971			FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6972			    p_sccb;
6973			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6974			    0;
6975			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6976		} else {
6977			FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6978						      LunDiscQ_Idx[0]] = p_sccb;
6979		}
6980	}
6981	FPT_BL_Card[p_card].currentSCCB = NULL;
6982}
6983
6984/*---------------------------------------------------------------------
6985 *
6986 * Function: Queue Flush SCCB
6987 *
6988 * Description: Flush all SCCB's back to the host driver for this target.
6989 *
6990 *---------------------------------------------------------------------*/
6991
6992static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6993{
6994	unsigned char qtag, thisTarg;
6995	struct sccb *currSCCB;
6996	struct sccb_mgr_tar_info *currTar_Info;
6997
6998	currSCCB = FPT_BL_Card[p_card].currentSCCB;
6999	if (currSCCB != NULL) {
7000		thisTarg = (unsigned char)currSCCB->TargID;
7001		currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7002
7003		for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7004
7005			if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7006			    (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
7007			     thisTarg)) {
7008
7009				FPT_BL_Card[p_card].discQ_Tbl[qtag]->
7010				    HostStatus = (unsigned char)error_code;
7011
7012				FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7013						     FPT_BL_Card[p_card].
7014						     discQ_Tbl[qtag], p_card);
7015
7016				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7017				currTar_Info->TarTagQ_Cnt--;
7018
7019			}
7020		}
7021	}
7022
7023}
7024
7025/*---------------------------------------------------------------------
7026 *
7027 * Function: Queue Flush Target SCCB
7028 *
7029 * Description: Flush all SCCB's back to the host driver for this target.
7030 *
7031 *---------------------------------------------------------------------*/
7032
7033static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7034				   unsigned char error_code)
7035{
7036	unsigned char qtag;
7037	struct sccb_mgr_tar_info *currTar_Info;
7038
7039	currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7040
7041	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7042
7043		if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7044		    (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7045
7046			FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7047			    (unsigned char)error_code;
7048
7049			FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7050					     FPT_BL_Card[p_card].
7051					     discQ_Tbl[qtag], p_card);
7052
7053			FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7054			currTar_Info->TarTagQ_Cnt--;
7055
7056		}
7057	}
7058
7059}
7060
7061static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7062{
7063	struct sccb_mgr_tar_info *currTar_Info;
7064	currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7065
7066	p_SCCB->Sccb_forwardlink = NULL;
7067
7068	p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7069
7070	if (currTar_Info->TarSelQ_Cnt == 0) {
7071
7072		currTar_Info->TarSelQ_Head = p_SCCB;
7073	}
7074
7075	else {
7076
7077		currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7078	}
7079
7080	currTar_Info->TarSelQ_Tail = p_SCCB;
7081	currTar_Info->TarSelQ_Cnt++;
7082}
7083
7084/*---------------------------------------------------------------------
7085 *
7086 * Function: Queue Find SCCB
7087 *
7088 * Description: Search the target select Queue for this SCCB, and
7089 *              remove it if found.
7090 *
7091 *---------------------------------------------------------------------*/
7092
7093static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7094				       unsigned char p_card)
7095{
7096	struct sccb *q_ptr;
7097	struct sccb_mgr_tar_info *currTar_Info;
7098
7099	currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7100
7101	q_ptr = currTar_Info->TarSelQ_Head;
7102
7103	while (q_ptr != NULL) {
7104
7105		if (q_ptr == p_SCCB) {
7106
7107			if (currTar_Info->TarSelQ_Head == q_ptr) {
7108
7109				currTar_Info->TarSelQ_Head =
7110				    q_ptr->Sccb_forwardlink;
7111			}
7112
7113			if (currTar_Info->TarSelQ_Tail == q_ptr) {
7114
7115				currTar_Info->TarSelQ_Tail =
7116				    q_ptr->Sccb_backlink;
7117			}
7118
7119			if (q_ptr->Sccb_forwardlink != NULL) {
7120				q_ptr->Sccb_forwardlink->Sccb_backlink =
7121				    q_ptr->Sccb_backlink;
7122			}
7123
7124			if (q_ptr->Sccb_backlink != NULL) {
7125				q_ptr->Sccb_backlink->Sccb_forwardlink =
7126				    q_ptr->Sccb_forwardlink;
7127			}
7128
7129			currTar_Info->TarSelQ_Cnt--;
7130
7131			return 1;
7132		}
7133
7134		else {
7135			q_ptr = q_ptr->Sccb_forwardlink;
7136		}
7137	}
7138
7139	return 0;
7140
7141}
7142
7143/*---------------------------------------------------------------------
7144 *
7145 * Function: Utility Update Residual Count
7146 *
7147 * Description: Update the XferCnt to the remaining byte count.
7148 *              If we transferred all the data then just write zero.
7149 *              If Non-SG transfer then report Total Cnt - Actual Transfer
7150 *              Cnt.  For SG transfers add the count fields of all
7151 *              remaining SG elements, as well as any partial remaining
7152 *              element.
7153 *
7154 *---------------------------------------------------------------------*/
7155
7156static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7157{
7158	unsigned long partial_cnt;
7159	unsigned int sg_index;
7160	struct blogic_sg_seg *segp;
7161
7162	if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7163
7164		p_SCCB->DataLength = 0x0000;
7165	}
7166
7167	else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7168
7169		partial_cnt = 0x0000;
7170
7171		sg_index = p_SCCB->Sccb_sgseg;
7172
7173
7174		if (p_SCCB->Sccb_SGoffset) {
7175
7176			partial_cnt = p_SCCB->Sccb_SGoffset;
7177			sg_index++;
7178		}
7179
7180		while (((unsigned long)sg_index *
7181			(unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7182			segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7183					(sg_index * 2);
7184			partial_cnt += segp->segbytes;
7185			sg_index++;
7186		}
7187
7188		p_SCCB->DataLength = partial_cnt;
7189	}
7190
7191	else {
7192
7193		p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7194	}
7195}
7196
7197/*---------------------------------------------------------------------
7198 *
7199 * Function: Wait 1 Second
7200 *
7201 * Description: Wait for 1 second.
7202 *
7203 *---------------------------------------------------------------------*/
7204
7205static void FPT_Wait1Second(u32 p_port)
7206{
7207	unsigned char i;
7208
7209	for (i = 0; i < 4; i++) {
7210
7211		FPT_Wait(p_port, TO_250ms);
7212
7213		if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7214			break;
7215
7216		if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7217			break;
7218	}
7219}
7220
7221/*---------------------------------------------------------------------
7222 *
7223 * Function: FPT_Wait
7224 *
7225 * Description: Wait the desired delay.
7226 *
7227 *---------------------------------------------------------------------*/
7228
7229static void FPT_Wait(u32 p_port, unsigned char p_delay)
7230{
7231	unsigned char old_timer;
7232	unsigned char green_flag;
7233
7234	old_timer = RD_HARPOON(p_port + hp_seltimeout);
7235
7236	green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7237	WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7238
7239	WR_HARPOON(p_port + hp_seltimeout, p_delay);
7240	WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7241	WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7242
7243	WR_HARPOON(p_port + hp_portctrl_0,
7244		   (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7245
7246	while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7247
7248		if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7249			break;
7250
7251		if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7252			break;
7253	}
7254
7255	WR_HARPOON(p_port + hp_portctrl_0,
7256		   (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7257
7258	WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7259	WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7260
7261	WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7262
7263	WR_HARPOON(p_port + hp_seltimeout, old_timer);
7264}
7265
7266/*---------------------------------------------------------------------
7267 *
7268 * Function: Enable/Disable Write to EEPROM
7269 *
7270 * Description: The EEPROM must first be enabled for writes
7271 *              A total of 9 clocks are needed.
7272 *
7273 *---------------------------------------------------------------------*/
7274
7275static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7276{
7277	unsigned char ee_value;
7278
7279	ee_value =
7280	    (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7281			    (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7282
7283	if (p_mode)
7284
7285		FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7286
7287	else
7288
7289		FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7290
7291	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));	/*Turn off CS */
7292	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);	/*Turn off Master Select */
7293}
7294
7295/*---------------------------------------------------------------------
7296 *
7297 * Function: Write EEPROM
7298 *
7299 * Description: Write a word to the EEPROM at the specified
7300 *              address.
7301 *
7302 *---------------------------------------------------------------------*/
7303
7304static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7305			    unsigned short ee_addr)
7306{
7307
7308	unsigned char ee_value;
7309	unsigned short i;
7310
7311	ee_value =
7312	    (unsigned
7313	     char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7314		    (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7315
7316	FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7317
7318	ee_value |= (SEE_MS + SEE_CS);
7319
7320	for (i = 0x8000; i != 0; i >>= 1) {
7321
7322		if (i & ee_data)
7323			ee_value |= SEE_DO;
7324		else
7325			ee_value &= ~SEE_DO;
7326
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;	/* Clock  data! */
7330		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7331		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7332		ee_value &= ~SEE_CLK;
7333		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7334		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7335	}
7336	ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7337	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7338
7339	FPT_Wait(p_port, TO_10ms);
7340
7341	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS));	/* Set CS to EEPROM */
7342	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));	/* Turn off CS */
7343	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);	/* Turn off Master Select */
7344}
7345
7346/*---------------------------------------------------------------------
7347 *
7348 * Function: Read EEPROM
7349 *
7350 * Description: Read a word from the EEPROM at the desired
7351 *              address.
7352 *
7353 *---------------------------------------------------------------------*/
7354
7355static unsigned short FPT_utilEERead(u32 p_port,
7356				     unsigned short ee_addr)
7357{
7358	unsigned short i, ee_data1, ee_data2;
7359
7360	i = 0;
7361	ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7362	do {
7363		ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7364
7365		if (ee_data1 == ee_data2)
7366			return ee_data1;
7367
7368		ee_data1 = ee_data2;
7369		i++;
7370
7371	} while (i < 4);
7372
7373	return ee_data1;
7374}
7375
7376/*---------------------------------------------------------------------
7377 *
7378 * Function: Read EEPROM Original 
7379 *
7380 * Description: Read a word from the EEPROM at the desired
7381 *              address.
7382 *
7383 *---------------------------------------------------------------------*/
7384
7385static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7386{
7387
7388	unsigned char ee_value;
7389	unsigned short i, ee_data;
7390
7391	ee_value =
7392	    (unsigned
7393	     char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7394		    (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7395
7396	FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7397
7398	ee_value |= (SEE_MS + SEE_CS);
7399	ee_data = 0;
7400
7401	for (i = 1; i <= 16; i++) {
7402
7403		ee_value |= SEE_CLK;	/* Clock  data! */
7404		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7405		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7406		ee_value &= ~SEE_CLK;
7407		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7408		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7409
7410		ee_data <<= 1;
7411
7412		if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7413			ee_data |= 1;
7414	}
7415
7416	ee_value &= ~(SEE_MS + SEE_CS);
7417	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));	/*Turn off CS */
7418	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);	/*Turn off Master Select */
7419
7420	return ee_data;
7421}
7422
7423/*---------------------------------------------------------------------
7424 *
7425 * Function: Send EE command and Address to the EEPROM
7426 *
7427 * Description: Transfers the correct command and sends the address
7428 *              to the eeprom.
7429 *
7430 *---------------------------------------------------------------------*/
7431
7432static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7433				  unsigned short ee_addr)
7434{
7435	unsigned char ee_value;
7436	unsigned char narrow_flg;
7437
7438	unsigned short i;
7439
7440	narrow_flg =
7441	    (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7442			    NARROW_SCSI_CARD);
7443
7444	ee_value = SEE_MS;
7445	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7446
7447	ee_value |= SEE_CS;	/* Set CS to EEPROM */
7448	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7449
7450	for (i = 0x04; i != 0; i >>= 1) {
7451
7452		if (i & ee_cmd)
7453			ee_value |= SEE_DO;
7454		else
7455			ee_value &= ~SEE_DO;
7456
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;	/* Clock  data! */
7460		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7461		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7462		ee_value &= ~SEE_CLK;
7463		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7464		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7465	}
7466
7467	if (narrow_flg)
7468		i = 0x0080;
7469
7470	else
7471		i = 0x0200;
7472
7473	while (i != 0) {
7474
7475		if (i & ee_addr)
7476			ee_value |= SEE_DO;
7477		else
7478			ee_value &= ~SEE_DO;
7479
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;	/* Clock  data! */
7483		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7484		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7485		ee_value &= ~SEE_CLK;
7486		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7487		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7488
7489		i >>= 1;
7490	}
7491}
7492
7493static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7494{
7495	unsigned short crc = 0;
7496	int i, j;
7497	unsigned short ch;
7498	for (i = 0; i < ID_STRING_LENGTH; i++) {
7499		ch = (unsigned short)buffer[i];
7500		for (j = 0; j < 8; j++) {
7501			if ((crc ^ ch) & 1)
7502				crc = (crc >> 1) ^ CRCMASK;
7503			else
7504				crc >>= 1;
7505			ch >>= 1;
7506		}
7507	}
7508	return crc;
7509}
7510
7511static unsigned char FPT_CalcLrc(unsigned char buffer[])
7512{
7513	int i;
7514	unsigned char lrc;
7515	lrc = 0;
7516	for (i = 0; i < ID_STRING_LENGTH; i++)
7517		lrc ^= buffer[i];
7518	return lrc;
7519}
7520
7521/*
7522  The following inline definitions avoid type conflicts.
7523*/
7524
7525static inline unsigned char
7526FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7527{
7528	return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7529					   FlashPointInfo);
7530}
7531
7532static inline void *
7533FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7534{
7535	return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7536						   FlashPointInfo);
7537}
7538
7539static inline void
7540FlashPoint__ReleaseHostAdapter(void *CardHandle)
7541{
7542	FlashPoint_ReleaseHostAdapter(CardHandle);
7543}
7544
7545static inline void
7546FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7547{
7548	FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7549}
7550
7551static inline void
7552FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7553{
7554	FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7555}
7556
7557static inline bool
7558FlashPoint__InterruptPending(void *CardHandle)
7559{
7560	return FlashPoint_InterruptPending(CardHandle);
7561}
7562
7563static inline int
7564FlashPoint__HandleInterrupt(void *CardHandle)
7565{
7566	return FlashPoint_HandleInterrupt(CardHandle);
7567}
7568
7569#define FlashPoint_ProbeHostAdapter	    FlashPoint__ProbeHostAdapter
7570#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7571#define FlashPoint_ReleaseHostAdapter	    FlashPoint__ReleaseHostAdapter
7572#define FlashPoint_StartCCB		    FlashPoint__StartCCB
7573#define FlashPoint_AbortCCB		    FlashPoint__AbortCCB
7574#define FlashPoint_InterruptPending	    FlashPoint__InterruptPending
7575#define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
7576
7577#else				/* !CONFIG_SCSI_FLASHPOINT */
7578
7579/*
7580  Define prototypes for the FlashPoint SCCB Manager Functions.
7581*/
7582
7583extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7584extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7585extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7586extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7587extern bool FlashPoint_InterruptPending(void *);
7588extern int FlashPoint_HandleInterrupt(void *);
7589extern void FlashPoint_ReleaseHostAdapter(void *);
7590
7591#endif				/* CONFIG_SCSI_FLASHPOINT */
v6.13.7
   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
  28struct sccb;
  29typedef void (*CALL_BK_FN) (struct sccb *);
  30
  31struct 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_mflags;
  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)*/
  74struct 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
 210struct 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
 225struct 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
 248struct 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
 294enum 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
 300typedef struct SCCBscam_info {
 301
 302	unsigned char id_string[ID_STRING_LENGTH];
 303	enum scam_id_st state;
 304
 305} SCCBSCAM_INFO;
 306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 307
 308#define  SMIDENT                 0x80
 309#define  DISC_PRIV               0x40
 310
 
 
 311#define  SM8BIT                  0x00
 312#define  SM16BIT                 0x01
 
 313
 314#define  SIX_BYTE_CMD            0x06
 315#define  TWELVE_BYTE_CMD         0x0C
 316
 317#define  ASYNC                   0x00
 318#define  MAX_OFFSET              0x0F	/* Maxbyteoffset for Sync Xfers */
 319
 320#define  EEPROM_WD_CNT     256
 321
 322#define  EEPROM_CHECK_SUM  0
 323#define  FW_SIGNATURE      2
 324#define  MODEL_NUMB_0      4
 325#define  MODEL_NUMB_2      6
 326#define  MODEL_NUMB_4      8
 327#define  SYSTEM_CONFIG     16
 328#define  SCSI_CONFIG       17
 329#define  BIOS_CONFIG       18
 330#define  SCAM_CONFIG       20
 331#define  ADAPTER_SCSI_ID   24
 332
 333#define  IGNORE_B_SCAN     32
 334#define  SEND_START_ENA    34
 335#define  DEVICE_ENABLE     36
 336
 337#define  SYNC_RATE_TBL     38
 338#define  SYNC_RATE_TBL01   38
 339#define  SYNC_RATE_TBL23   40
 340#define  SYNC_RATE_TBL45   42
 341#define  SYNC_RATE_TBL67   44
 342#define  SYNC_RATE_TBL89   46
 343#define  SYNC_RATE_TBLab   48
 344#define  SYNC_RATE_TBLcd   50
 345#define  SYNC_RATE_TBLef   52
 346
 347#define  EE_SCAMBASE      256
 348
 349#define  SCAM_ENABLED   BIT(2)
 350#define  SCAM_LEVEL2    BIT(3)
 351
 352#define	RENEGO_ENA		BIT(10)
 353#define	CONNIO_ENA		BIT(11)
 354#define  GREEN_PC_ENA   BIT(12)
 355
 356#define  AUTO_RATE_00   00
 357#define  AUTO_RATE_05   01
 358#define  AUTO_RATE_10   02
 359#define  AUTO_RATE_20   03
 360
 361#define  WIDE_NEGO_BIT     BIT(7)
 362#define  DISC_ENABLE_BIT   BIT(6)
 363
 364#define  hp_vendor_id_0       0x00	/* LSB */
 365#define  ORION_VEND_0   0x4B
 366
 367#define  hp_vendor_id_1       0x01	/* MSB */
 368#define  ORION_VEND_1   0x10
 369
 370#define  hp_device_id_0       0x02	/* LSB */
 371#define  ORION_DEV_0    0x30
 372
 373#define  hp_device_id_1       0x03	/* MSB */
 374#define  ORION_DEV_1    0x81
 375
 376	/* Sub Vendor ID and Sub Device ID only available in
 377	   Harpoon Version 2 and higher */
 378
 379#define  hp_sub_device_id_0   0x06	/* LSB */
 380
 381#define  hp_semaphore         0x0C
 382#define SCCB_MGR_ACTIVE    BIT(0)
 383#define TICKLE_ME          BIT(1)
 384#define SCCB_MGR_PRESENT   BIT(3)
 385#define BIOS_IN_USE        BIT(4)
 386
 387#define  hp_sys_ctrl          0x0F
 388
 389#define  STOP_CLK          BIT(0)	/*Turn off BusMaster Clock */
 390#define  DRVR_RST          BIT(1)	/*Firmware Reset to 80C15 chip */
 391#define  HALT_MACH         BIT(3)	/*Halt State Machine      */
 392#define  HARD_ABORT        BIT(4)	/*Hard Abort              */
 393
 394#define  hp_host_blk_cnt      0x13
 395
 396#define  XFER_BLK64        0x06	/*     1 1 0 64 byte per block */
 397
 398#define  BM_THRESHOLD      0x40	/* PCI mode can only xfer 16 bytes */
 399
 400#define  hp_int_mask          0x17
 401
 402#define  INT_CMD_COMPL     BIT(0)	/* DMA command complete   */
 403#define  INT_EXT_STATUS    BIT(1)	/* Extended Status Set    */
 404
 405#define  hp_xfer_cnt_lo       0x18
 406#define  hp_xfer_cnt_hi       0x1A
 407#define  hp_xfer_cmd          0x1B
 408
 409#define  XFER_HOST_DMA     0x00	/*     0 0 0 Transfer Host -> DMA */
 410#define  XFER_DMA_HOST     0x01	/*     0 0 1 Transfer DMA  -> Host */
 411
 412#define  XFER_HOST_AUTO    0x00	/*     0 0 Auto Transfer Size   */
 413
 414#define  XFER_DMA_8BIT     0x20	/*     0 1 8 BIT  Transfer Size */
 415
 416#define  DISABLE_INT       BIT(7)	/*Do not interrupt at end of cmd. */
 417
 418#define  HOST_WRT_CMD      ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
 419#define  HOST_RD_CMD       ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
 420
 421#define  hp_host_addr_lo      0x1C
 422#define  hp_host_addr_hmi     0x1E
 423
 424#define  hp_ee_ctrl           0x22
 425
 426#define  EXT_ARB_ACK       BIT(7)
 427#define  SCSI_TERM_ENA_H   BIT(6)	/* SCSI high byte terminator */
 428#define  SEE_MS            BIT(5)
 429#define  SEE_CS            BIT(3)
 430#define  SEE_CLK           BIT(2)
 431#define  SEE_DO            BIT(1)
 432#define  SEE_DI            BIT(0)
 433
 434#define  EE_READ           0x06
 435#define  EE_WRITE          0x05
 436#define  EWEN              0x04
 437#define  EWEN_ADDR         0x03C0
 438#define  EWDS              0x04
 439#define  EWDS_ADDR         0x0000
 440
 441#define  hp_bm_ctrl           0x26
 442
 443#define  SCSI_TERM_ENA_L   BIT(0)	/*Enable/Disable external terminators */
 444#define  FLUSH_XFER_CNTR   BIT(1)	/*Flush transfer counter */
 445#define  FORCE1_XFER       BIT(5)	/*Always xfer one byte in byte mode */
 446#define  FAST_SINGLE       BIT(6)	/*?? */
 447
 448#define  BMCTRL_DEFAULT    (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
 449
 450#define  hp_sg_addr           0x28
 451#define  hp_page_ctrl         0x29
 452
 453#define  SCATTER_EN        BIT(0)
 454#define  SGRAM_ARAM        BIT(1)
 455#define  G_INT_DISABLE     BIT(3)	/* Enable/Disable all Interrupts */
 456#define  NARROW_SCSI_CARD  BIT(4)	/* NARROW/WIDE SCSI config pin */
 457
 458#define  hp_pci_stat_cfg      0x2D
 459
 460#define  REC_MASTER_ABORT  BIT(5)	/*received Master abort */
 461
 462#define  hp_rev_num           0x33
 463
 464#define  hp_stack_data        0x34
 465#define  hp_stack_addr        0x35
 466
 467#define  hp_ext_status        0x36
 468
 469#define  BM_FORCE_OFF      BIT(0)	/*Bus Master is forced to get off */
 470#define  PCI_TGT_ABORT     BIT(0)	/*PCI bus master transaction aborted */
 471#define  PCI_DEV_TMOUT     BIT(1)	/*PCI Device Time out */
 472#define  CMD_ABORTED       BIT(4)	/*Command aborted */
 473#define  BM_PARITY_ERR     BIT(5)	/*parity error on data received   */
 474#define  PIO_OVERRUN       BIT(6)	/*Slave data overrun */
 475#define  BM_CMD_BUSY       BIT(7)	/*Bus master transfer command busy */
 476#define  BAD_EXT_STATUS    (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
 477                                  BM_PARITY_ERR | PIO_OVERRUN)
 478
 479#define  hp_int_status        0x37
 480
 481#define  EXT_STATUS_ON     BIT(1)	/*Extended status is valid */
 482#define  SCSI_INTERRUPT    BIT(2)	/*Global indication of a SCSI int. */
 483#define  INT_ASSERTED      BIT(5)	/* */
 484
 485#define  hp_fifo_cnt          0x38
 486
 487#define  hp_intena		 0x40
 488
 489#define  RESET		 BIT(7)
 490#define  PROG_HLT		 BIT(6)
 491#define  PARITY		 BIT(5)
 492#define  FIFO		 BIT(4)
 493#define  SEL		 BIT(3)
 494#define  SCAM_SEL		 BIT(2)
 495#define  RSEL		 BIT(1)
 496#define  TIMEOUT		 BIT(0)
 497#define  BUS_FREE		 BIT(15)
 498#define  XFER_CNT_0	 BIT(14)
 499#define  PHASE		 BIT(13)
 500#define  IUNKWN		 BIT(12)
 501#define  ICMD_COMP	 BIT(11)
 502#define  ITICKLE		 BIT(10)
 503#define  IDO_STRT		 BIT(9)
 504#define  ITAR_DISC	 BIT(8)
 505#define  AUTO_INT		 (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
 506#define  CLR_ALL_INT	 0xFFFF
 507#define  CLR_ALL_INT_1	 0xFF00
 508
 509#define  hp_intstat		 0x42
 510
 511#define  hp_scsisig           0x44
 512
 513#define  SCSI_SEL          BIT(7)
 514#define  SCSI_BSY          BIT(6)
 515#define  SCSI_REQ          BIT(5)
 516#define  SCSI_ACK          BIT(4)
 517#define  SCSI_ATN          BIT(3)
 518#define  SCSI_CD           BIT(2)
 519#define  SCSI_MSG          BIT(1)
 520#define  SCSI_IOBIT        BIT(0)
 521
 522#define  S_SCSI_PHZ        (BIT(2)+BIT(1)+BIT(0))
 523#define  S_MSGO_PH         (BIT(2)+BIT(1)       )
 524#define  S_MSGI_PH         (BIT(2)+BIT(1)+BIT(0))
 525#define  S_DATAI_PH        (              BIT(0))
 526#define  S_DATAO_PH        0x00
 527#define  S_ILL_PH          (       BIT(1)       )
 528
 529#define  hp_scsictrl_0        0x45
 530
 531#define  SEL_TAR           BIT(6)
 532#define  ENA_ATN           BIT(4)
 533#define  ENA_RESEL         BIT(2)
 534#define  SCSI_RST          BIT(1)
 535#define  ENA_SCAM_SEL      BIT(0)
 536
 537#define  hp_portctrl_0        0x46
 538
 539#define  SCSI_PORT         BIT(7)
 540#define  SCSI_INBIT        BIT(6)
 541#define  DMA_PORT          BIT(5)
 542#define  DMA_RD            BIT(4)
 543#define  HOST_PORT         BIT(3)
 544#define  HOST_WRT          BIT(2)
 545#define  SCSI_BUS_EN       BIT(1)
 546#define  START_TO          BIT(0)
 547
 548#define  hp_scsireset         0x47
 549
 550#define  SCSI_INI          BIT(6)
 551#define  SCAM_EN           BIT(5)
 552#define  DMA_RESET         BIT(3)
 553#define  HPSCSI_RESET      BIT(2)
 554#define  PROG_RESET        BIT(1)
 555#define  FIFO_CLR          BIT(0)
 556
 557#define  hp_xfercnt_0         0x48
 558#define  hp_xfercnt_2         0x4A
 559
 560#define  hp_fifodata_0        0x4C
 561#define  hp_addstat           0x4E
 562
 563#define  SCAM_TIMER        BIT(7)
 564#define  SCSI_MODE8        BIT(3)
 565#define  SCSI_PAR_ERR      BIT(0)
 566
 567#define  hp_prgmcnt_0         0x4F
 568
 569#define  hp_selfid_0          0x50
 570#define  hp_selfid_1          0x51
 571#define  hp_arb_id            0x52
 572
 573#define  hp_select_id         0x53
 574
 575#define  hp_synctarg_base     0x54
 576#define  hp_synctarg_12       0x54
 577#define  hp_synctarg_13       0x55
 578#define  hp_synctarg_14       0x56
 579#define  hp_synctarg_15       0x57
 580
 581#define  hp_synctarg_8        0x58
 582#define  hp_synctarg_9        0x59
 583#define  hp_synctarg_10       0x5A
 584#define  hp_synctarg_11       0x5B
 585
 586#define  hp_synctarg_4        0x5C
 587#define  hp_synctarg_5        0x5D
 588#define  hp_synctarg_6        0x5E
 589#define  hp_synctarg_7        0x5F
 590
 591#define  hp_synctarg_0        0x60
 592#define  hp_synctarg_1        0x61
 593#define  hp_synctarg_2        0x62
 594#define  hp_synctarg_3        0x63
 595
 596#define  NARROW_SCSI       BIT(4)
 597#define  DEFAULT_OFFSET    0x0F
 598
 599#define  hp_autostart_0       0x64
 600#define  hp_autostart_1       0x65
 601#define  hp_autostart_3       0x67
 602
 603#define  AUTO_IMMED    BIT(5)
 604#define  SELECT   BIT(6)
 605#define  END_DATA (BIT(7)+BIT(6))
 606
 607#define  hp_gp_reg_0          0x68
 608#define  hp_gp_reg_1          0x69
 609#define  hp_gp_reg_3          0x6B
 610
 611#define  hp_seltimeout        0x6C
 612
 613#define  TO_4ms            0x67	/* 3.9959ms */
 614
 615#define  TO_5ms            0x03	/* 4.9152ms */
 616#define  TO_10ms           0x07	/* 11.xxxms */
 617#define  TO_250ms          0x99	/* 250.68ms */
 618#define  TO_290ms          0xB1	/* 289.99ms */
 619
 620#define  hp_clkctrl_0         0x6D
 621
 622#define  PWR_DWN           BIT(6)
 623#define  ACTdeassert       BIT(4)
 624#define  CLK_40MHZ         (BIT(1) + BIT(0))
 625
 626#define  CLKCTRL_DEFAULT   (ACTdeassert | CLK_40MHZ)
 627
 628#define  hp_fiforead          0x6E
 629#define  hp_fifowrite         0x6F
 630
 631#define  hp_offsetctr         0x70
 632#define  hp_xferstat          0x71
 633
 634#define  FIFO_EMPTY        BIT(6)
 635
 636#define  hp_portctrl_1        0x72
 637
 638#define  CHK_SCSI_P        BIT(3)
 639#define  HOST_MODE8        BIT(0)
 640
 641#define  hp_xfer_pad          0x73
 642
 643#define  ID_UNLOCK         BIT(3)
 644
 645#define  hp_scsidata_0        0x74
 646#define  hp_scsidata_1        0x75
 647
 648#define  hp_aramBase          0x80
 649#define  BIOS_DATA_OFFSET     0x60
 650#define  BIOS_RELATIVE_CARD   0x64
 651
 652#define  AR3      (BIT(9) + BIT(8))
 653#define  SDATA    BIT(10)
 654
 655#define  CRD_OP   BIT(11)	/* Cmp Reg. w/ Data */
 656
 657#define  CRR_OP   BIT(12)	/* Cmp Reg. w. Reg. */
 658
 659#define  CPE_OP   (BIT(14)+BIT(11))	/* Cmp SCSI phs & Branch EQ */
 660
 661#define  CPN_OP   (BIT(14)+BIT(12))	/* Cmp SCSI phs & Branch NOT EQ */
 662
 663#define  ADATA_OUT   0x00
 664#define  ADATA_IN    BIT(8)
 665#define  ACOMMAND    BIT(10)
 666#define  ASTATUS     (BIT(10)+BIT(8))
 667#define  AMSG_OUT    (BIT(10)+BIT(9))
 668#define  AMSG_IN     (BIT(10)+BIT(9)+BIT(8))
 669
 670#define  BRH_OP   BIT(13)	/* Branch */
 671
 672#define  ALWAYS   0x00
 673#define  EQUAL    BIT(8)
 674#define  NOT_EQ   BIT(9)
 675
 676#define  TCB_OP   (BIT(13)+BIT(11))	/* Test condition & branch */
 677
 678#define  FIFO_0      BIT(10)
 679
 680#define  MPM_OP   BIT(15)	/* Match phase and move data */
 681
 682#define  MRR_OP   BIT(14)	/* Move DReg. to Reg. */
 683
 684#define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
 685
 686#define  D_AR0    0x00
 687#define  D_AR1    BIT(0)
 688#define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
 689
 690#define  RAT_OP      (BIT(14)+BIT(13)+BIT(11))
 691
 692#define  SSI_OP      (BIT(15)+BIT(11))
 693
 694#define  SSI_ITAR_DISC	(ITAR_DISC >> 8)
 695#define  SSI_IDO_STRT	(IDO_STRT >> 8)
 696
 697#define  SSI_ICMD_COMP	(ICMD_COMP >> 8)
 698#define  SSI_ITICKLE	(ITICKLE >> 8)
 699
 700#define  SSI_IUNKWN	(IUNKWN >> 8)
 701#define  SSI_INO_CC	(IUNKWN >> 8)
 702#define  SSI_IRFAIL	(IUNKWN >> 8)
 703
 704#define  NP    0x10		/*Next Phase */
 705#define  NTCMD 0x02		/*Non- Tagged Command start */
 706#define  CMDPZ 0x04		/*Command phase */
 707#define  DINT  0x12		/*Data Out/In interrupt */
 708#define  DI    0x13		/*Data Out */
 709#define  DC    0x19		/*Disconnect Message */
 710#define  ST    0x1D		/*Status Phase */
 711#define  UNKNWN 0x24		/*Unknown bus action */
 712#define  CC    0x25		/*Command Completion failure */
 713#define  TICK  0x26		/*New target reselected us. */
 714#define  SELCHK 0x28		/*Select & Check SCSI ID latch reg */
 715
 716#define  ID_MSG_STRT    hp_aramBase + 0x00
 717#define  NON_TAG_ID_MSG hp_aramBase + 0x06
 718#define  CMD_STRT       hp_aramBase + 0x08
 719#define  SYNC_MSGS      hp_aramBase + 0x08
 720
 721#define  TAG_STRT          0x00
 722#define  DISCONNECT_START  0x10/2
 723#define  END_DATA_START    0x14/2
 724#define  CMD_ONLY_STRT     CMDPZ/2
 725#define  SELCHK_STRT     SELCHK/2
 726
 727#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
 728/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
 729                                 xfercnt <<= 16,\
 730                                 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
 731 */
 732#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
 733         addr >>= 16,\
 734         WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
 735         WR_HARP32(port,hp_xfercnt_0,count),\
 736         WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
 737         count >>= 16,\
 738         WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
 739
 740#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
 741                          WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
 742
 743#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
 744                          WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
 745
 746#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
 747                        WR_HARPOON(port+hp_scsireset, 0x00))
 748
 749#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
 750                             (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
 751
 752#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
 753                             (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
 754
 755#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
 756                             (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
 757
 758#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
 759                             (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
 760
 761static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
 762				 unsigned char syncFlag);
 763static void FPT_ssel(u32 port, unsigned char p_card);
 764static void FPT_sres(u32 port, unsigned char p_card,
 765		     struct sccb_card *pCurrCard);
 766static void FPT_shandem(u32 port, unsigned char p_card,
 767			struct sccb *pCurrSCCB);
 768static void FPT_stsyncn(u32 port, unsigned char p_card);
 769static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
 770			unsigned char offset);
 771static void FPT_sssyncv(u32 p_port, unsigned char p_id,
 772			unsigned char p_sync_value,
 773			struct sccb_mgr_tar_info *currTar_Info);
 774static void FPT_sresb(u32 port, unsigned char p_card);
 775static void FPT_sxfrp(u32 p_port, unsigned char p_card);
 776static void FPT_schkdd(u32 port, unsigned char p_card);
 777static unsigned char FPT_RdStack(u32 port, unsigned char index);
 778static void FPT_WrStack(u32 portBase, unsigned char index,
 779			unsigned char data);
 780static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
 781
 782static void FPT_SendMsg(u32 port, unsigned char message);
 783static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
 784				   unsigned char error_code);
 785
 786static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
 787static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
 788
 789static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
 790static void FPT_stwidn(u32 port, unsigned char p_card);
 791static void FPT_siwidr(u32 port, unsigned char width);
 792
 793static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
 794				unsigned char p_card);
 795static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
 796static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
 797				 struct sccb *p_SCCB, unsigned char p_card);
 798static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
 799				  unsigned char p_card);
 800static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
 801static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
 802static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
 803				       unsigned char p_card);
 804static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
 805static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
 806static unsigned char FPT_CalcLrc(unsigned char buffer[]);
 807
 808static void FPT_Wait1Second(u32 p_port);
 809static void FPT_Wait(u32 p_port, unsigned char p_delay);
 810static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
 811static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
 812			    unsigned short ee_addr);
 813static unsigned short FPT_utilEERead(u32 p_port,
 814				     unsigned short ee_addr);
 815static unsigned short FPT_utilEEReadOrg(u32 p_port,
 816					unsigned short ee_addr);
 817static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
 818				  unsigned short ee_addr);
 819
 820static void FPT_phaseDataOut(u32 port, unsigned char p_card);
 821static void FPT_phaseDataIn(u32 port, unsigned char p_card);
 822static void FPT_phaseCommand(u32 port, unsigned char p_card);
 823static void FPT_phaseStatus(u32 port, unsigned char p_card);
 824static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
 825static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
 826static void FPT_phaseIllegal(u32 port, unsigned char p_card);
 827
 828static void FPT_phaseDecode(u32 port, unsigned char p_card);
 829static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
 830static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
 831
 832static void FPT_XbowInit(u32 port, unsigned char scamFlg);
 833static void FPT_BusMasterInit(u32 p_port);
 834static void FPT_DiagEEPROM(u32 p_port);
 835
 836static void FPT_dataXferProcessor(u32 port,
 837				  struct sccb_card *pCurrCard);
 838static void FPT_busMstrSGDataXferStart(u32 port,
 839				       struct sccb *pCurrSCCB);
 840static void FPT_busMstrDataXferStart(u32 port,
 841				     struct sccb *pCurrSCCB);
 842static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
 843				  struct sccb *pCurrSCCB);
 844static void FPT_hostDataXferRestart(struct sccb *currSCCB);
 845
 846static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
 847					 unsigned char p_card,
 848					 struct sccb_card *pCurrCard,
 849					 unsigned short p_int);
 850
 851static void FPT_SccbMgrTableInitAll(void);
 852static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
 853				     unsigned char p_card);
 854static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
 855				       unsigned char target);
 856
 857static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
 858		      unsigned char p_power_up);
 859
 860static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
 861static void FPT_scbusf(u32 p_port);
 862static void FPT_scsel(u32 p_port);
 863static void FPT_scasid(unsigned char p_card, u32 p_port);
 864static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
 865static unsigned char FPT_scsendi(u32 p_port,
 866				 unsigned char p_id_string[]);
 867static unsigned char FPT_sciso(u32 p_port,
 868			       unsigned char p_id_string[]);
 869static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
 870static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
 871static unsigned char FPT_scvalq(unsigned char p_quintet);
 872static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
 873static void FPT_scwtsel(u32 p_port);
 874static void FPT_inisci(unsigned char p_card, u32 p_port,
 875		       unsigned char p_our_id);
 876static void FPT_scsavdi(unsigned char p_card, u32 p_port);
 877static unsigned char FPT_scmachid(unsigned char p_card,
 878				  unsigned char p_id_string[]);
 879
 880static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
 881static void FPT_autoLoadDefaultMap(u32 p_port);
 882
 883static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
 884    { {{0}} };
 885static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
 886static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
 887static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
 888
 889static unsigned char FPT_mbCards = 0;
 890static unsigned char FPT_scamHAString[] =
 891    { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
 892	' ', 'B', 'T', '-', '9', '3', '0',
 893	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 894	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
 895};
 896
 897static unsigned short FPT_default_intena = 0;
 898
 899static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
 9000};
 901
 902/*---------------------------------------------------------------------
 903 *
 904 * Function: FlashPoint_ProbeHostAdapter
 905 *
 906 * Description: Setup and/or Search for cards and return info to caller.
 907 *
 908 *---------------------------------------------------------------------*/
 909
 910static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
 911{
 912	static unsigned char first_time = 1;
 913
 914	unsigned char i, j, id, ScamFlg;
 915	unsigned short temp, temp2, temp3, temp4, temp5, temp6;
 916	u32 ioport;
 917	struct nvram_info *pCurrNvRam;
 918
 919	ioport = pCardInfo->si_baseaddr;
 920
 921	if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
 922		return (int)FAILURE;
 923
 924	if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
 925		return (int)FAILURE;
 926
 927	if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
 928		return (int)FAILURE;
 929
 930	if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
 931		return (int)FAILURE;
 932
 933	if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
 934
 935/* For new Harpoon then check for sub_device ID LSB
 936   the bits(0-3) must be all ZERO for compatible with
 937   current version of SCCBMgr, else skip this Harpoon
 938	device. */
 939
 940		if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
 941			return (int)FAILURE;
 942	}
 943
 944	if (first_time) {
 945		FPT_SccbMgrTableInitAll();
 946		first_time = 0;
 947		FPT_mbCards = 0;
 948	}
 949
 950	if (FPT_RdStack(ioport, 0) != 0x00) {
 951		if (FPT_ChkIfChipInitialized(ioport) == 0) {
 952			pCurrNvRam = NULL;
 953			WR_HARPOON(ioport + hp_semaphore, 0x00);
 954			FPT_XbowInit(ioport, 0);	/*Must Init the SCSI before attempting */
 955			FPT_DiagEEPROM(ioport);
 956		} else {
 957			if (FPT_mbCards < MAX_MB_CARDS) {
 958				pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
 959				FPT_mbCards++;
 960				pCurrNvRam->niBaseAddr = ioport;
 961				FPT_RNVRamData(pCurrNvRam);
 962			} else
 963				return (int)FAILURE;
 964		}
 965	} else
 966		pCurrNvRam = NULL;
 967
 968	WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
 969	WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
 970
 971	if (pCurrNvRam)
 972		pCardInfo->si_id = pCurrNvRam->niAdapId;
 973	else
 974		pCardInfo->si_id =
 975		    (unsigned
 976		     char)(FPT_utilEERead(ioport,
 977					  (ADAPTER_SCSI_ID /
 978					   2)) & (unsigned char)0x0FF);
 979
 980	pCardInfo->si_lun = 0x00;
 981	pCardInfo->si_fw_revision = ORION_FW_REV;
 982	temp2 = 0x0000;
 983	temp3 = 0x0000;
 984	temp4 = 0x0000;
 985	temp5 = 0x0000;
 986	temp6 = 0x0000;
 987
 988	for (id = 0; id < (16 / 2); id++) {
 989
 990		if (pCurrNvRam) {
 991			temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
 992			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
 993			    (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
 994		} else
 995			temp =
 996			    FPT_utilEERead(ioport,
 997					   (unsigned short)((SYNC_RATE_TBL / 2)
 998							    + id));
 999
1000		for (i = 0; i < 2; temp >>= 8, i++) {
1001
1002			temp2 >>= 1;
1003			temp3 >>= 1;
1004			temp4 >>= 1;
1005			temp5 >>= 1;
1006			temp6 >>= 1;
1007			switch (temp & 0x3) {
1008			case AUTO_RATE_20:	/* Synchronous, 20 mega-transfers/second */
1009				temp6 |= 0x8000;
1010				fallthrough;
1011			case AUTO_RATE_10:	/* Synchronous, 10 mega-transfers/second */
1012				temp5 |= 0x8000;
1013				fallthrough;
1014			case AUTO_RATE_05:	/* Synchronous, 5 mega-transfers/second */
1015				temp2 |= 0x8000;
1016				fallthrough;
1017			case AUTO_RATE_00:	/* Asynchronous */
1018				break;
1019			}
1020
1021			if (temp & DISC_ENABLE_BIT)
1022				temp3 |= 0x8000;
1023
1024			if (temp & WIDE_NEGO_BIT)
1025				temp4 |= 0x8000;
1026
1027		}
1028	}
1029
1030	pCardInfo->si_per_targ_init_sync = temp2;
1031	pCardInfo->si_per_targ_no_disc = temp3;
1032	pCardInfo->si_per_targ_wide_nego = temp4;
1033	pCardInfo->si_per_targ_fast_nego = temp5;
1034	pCardInfo->si_per_targ_ultra_nego = temp6;
1035
1036	if (pCurrNvRam)
1037		i = pCurrNvRam->niSysConf;
1038	else
1039		i = (unsigned
1040		     char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1041
1042	if (pCurrNvRam)
1043		ScamFlg = pCurrNvRam->niScamConf;
1044	else
1045		ScamFlg =
1046		    (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1047
1048	pCardInfo->si_mflags = 0x0000;
1049
1050	if (i & 0x01)
1051		pCardInfo->si_mflags |= SCSI_PARITY_ENA;
1052
1053	if (!(i & 0x02))
1054		pCardInfo->si_mflags |= SOFT_RESET;
1055
1056	if (i & 0x10)
1057		pCardInfo->si_mflags |= EXTENDED_TRANSLATION;
1058
1059	if (ScamFlg & SCAM_ENABLED)
1060		pCardInfo->si_mflags |= FLAG_SCAM_ENABLED;
1061
1062	if (ScamFlg & SCAM_LEVEL2)
1063		pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2;
1064
1065	j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1066	if (i & 0x04) {
1067		j |= SCSI_TERM_ENA_L;
1068	}
1069	WR_HARPOON(ioport + hp_bm_ctrl, j);
1070
1071	j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1072	if (i & 0x08) {
1073		j |= SCSI_TERM_ENA_H;
1074	}
1075	WR_HARPOON(ioport + hp_ee_ctrl, j);
1076
1077	if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1078
1079		pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN;
1080
1081	pCardInfo->si_card_family = HARPOON_FAMILY;
1082	pCardInfo->si_bustype = BUSTYPE_PCI;
1083
1084	if (pCurrNvRam) {
1085		pCardInfo->si_card_model[0] = '9';
1086		switch (pCurrNvRam->niModel & 0x0f) {
1087		case MODEL_LT:
1088			pCardInfo->si_card_model[1] = '3';
1089			pCardInfo->si_card_model[2] = '0';
1090			break;
1091		case MODEL_LW:
1092			pCardInfo->si_card_model[1] = '5';
1093			pCardInfo->si_card_model[2] = '0';
1094			break;
1095		case MODEL_DL:
1096			pCardInfo->si_card_model[1] = '3';
1097			pCardInfo->si_card_model[2] = '2';
1098			break;
1099		case MODEL_DW:
1100			pCardInfo->si_card_model[1] = '5';
1101			pCardInfo->si_card_model[2] = '2';
1102			break;
1103		}
1104	} else {
1105		temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1106		pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1107		temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1108
1109		pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1110		pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1111	}
1112
1113	if (pCardInfo->si_card_model[1] == '3') {
1114		if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1115			pCardInfo->si_mflags |= LOW_BYTE_TERM;
1116	} else if (pCardInfo->si_card_model[2] == '0') {
1117		temp = RD_HARPOON(ioport + hp_xfer_pad);
1118		WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1119		if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1120			pCardInfo->si_mflags |= LOW_BYTE_TERM;
1121		WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1122		if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1123			pCardInfo->si_mflags |= HIGH_BYTE_TERM;
1124		WR_HARPOON(ioport + hp_xfer_pad, temp);
1125	} else {
1126		temp = RD_HARPOON(ioport + hp_ee_ctrl);
1127		temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1128		WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1129		WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1130		temp3 = 0;
1131		for (i = 0; i < 8; i++) {
1132			temp3 <<= 1;
1133			if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1134				temp3 |= 1;
1135			WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1136			WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1137		}
1138		WR_HARPOON(ioport + hp_ee_ctrl, temp);
1139		WR_HARPOON(ioport + hp_xfer_pad, temp2);
1140		if (!(temp3 & BIT(7)))
1141			pCardInfo->si_mflags |= LOW_BYTE_TERM;
1142		if (!(temp3 & BIT(6)))
1143			pCardInfo->si_mflags |= HIGH_BYTE_TERM;
1144	}
1145
1146	ARAM_ACCESS(ioport);
1147
1148	for (i = 0; i < 4; i++) {
1149
1150		pCardInfo->si_XlatInfo[i] =
1151		    RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1152	}
1153
1154	/* return with -1 if no sort, else return with
1155	   logical card number sorted by BIOS (zero-based) */
1156
1157	pCardInfo->si_relative_cardnum =
1158	    (unsigned
1159	     char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1160
1161	SGRAM_ACCESS(ioport);
1162
1163	FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1164	FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1165	FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1166	FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1167	FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1168	FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1169	FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1170	FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1171
1172	pCardInfo->si_present = 0x01;
1173
1174	return 0;
1175}
1176
1177/*---------------------------------------------------------------------
1178 *
1179 * Function: FlashPoint_HardwareResetHostAdapter
1180 *
1181 * Description: Setup adapter for normal operation (hard reset).
1182 *
1183 *---------------------------------------------------------------------*/
1184
1185static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1186							 *pCardInfo)
1187{
1188	struct sccb_card *CurrCard = NULL;
1189	struct nvram_info *pCurrNvRam;
1190	unsigned char i, j, thisCard, ScamFlg;
1191	unsigned short temp, sync_bit_map, id;
1192	u32 ioport;
1193
1194	ioport = pCardInfo->si_baseaddr;
1195
1196	for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1197
1198		if (thisCard == MAX_CARDS)
1199			return (void *)FAILURE;
1200
1201		if (FPT_BL_Card[thisCard].ioPort == ioport) {
1202
1203			CurrCard = &FPT_BL_Card[thisCard];
1204			FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1205			break;
1206		}
1207
1208		else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1209
1210			FPT_BL_Card[thisCard].ioPort = ioport;
1211			CurrCard = &FPT_BL_Card[thisCard];
1212
1213			if (FPT_mbCards)
1214				for (i = 0; i < FPT_mbCards; i++) {
1215					if (CurrCard->ioPort ==
1216					    FPT_nvRamInfo[i].niBaseAddr)
1217						CurrCard->pNvRamInfo =
1218						    &FPT_nvRamInfo[i];
1219				}
1220			FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1221			CurrCard->cardIndex = thisCard;
1222			CurrCard->cardInfo = pCardInfo;
1223
1224			break;
1225		}
1226	}
1227
1228	pCurrNvRam = CurrCard->pNvRamInfo;
1229
1230	if (pCurrNvRam) {
1231		ScamFlg = pCurrNvRam->niScamConf;
1232	} else {
1233		ScamFlg =
1234		    (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1235	}
1236
1237	FPT_BusMasterInit(ioport);
1238	FPT_XbowInit(ioport, ScamFlg);
1239
1240	FPT_autoLoadDefaultMap(ioport);
1241
1242	for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1243	}
1244
1245	WR_HARPOON(ioport + hp_selfid_0, id);
1246	WR_HARPOON(ioport + hp_selfid_1, 0x00);
1247	WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1248	CurrCard->ourId = pCardInfo->si_id;
1249
1250	i = (unsigned char)pCardInfo->si_mflags;
1251	if (i & SCSI_PARITY_ENA)
1252		WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1253
1254	j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1255	if (i & LOW_BYTE_TERM)
1256		j |= SCSI_TERM_ENA_L;
1257	WR_HARPOON(ioport + hp_bm_ctrl, j);
1258
1259	j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1260	if (i & HIGH_BYTE_TERM)
1261		j |= SCSI_TERM_ENA_H;
1262	WR_HARPOON(ioport + hp_ee_ctrl, j);
1263
1264	if (!(pCardInfo->si_mflags & SOFT_RESET)) {
1265
1266		FPT_sresb(ioport, thisCard);
1267
1268		FPT_scini(thisCard, pCardInfo->si_id, 0);
1269	}
1270
1271	if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS)
1272		CurrCard->globalFlags |= F_NO_FILTER;
1273
1274	if (pCurrNvRam) {
1275		if (pCurrNvRam->niSysConf & 0x10)
1276			CurrCard->globalFlags |= F_GREEN_PC;
1277	} else {
1278		if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1279			CurrCard->globalFlags |= F_GREEN_PC;
1280	}
1281
1282	/* Set global flag to indicate Re-Negotiation to be done on all
1283	   ckeck condition */
1284	if (pCurrNvRam) {
1285		if (pCurrNvRam->niScsiConf & 0x04)
1286			CurrCard->globalFlags |= F_DO_RENEGO;
1287	} else {
1288		if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1289			CurrCard->globalFlags |= F_DO_RENEGO;
1290	}
1291
1292	if (pCurrNvRam) {
1293		if (pCurrNvRam->niScsiConf & 0x08)
1294			CurrCard->globalFlags |= F_CONLUN_IO;
1295	} else {
1296		if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1297			CurrCard->globalFlags |= F_CONLUN_IO;
1298	}
1299
1300	temp = pCardInfo->si_per_targ_no_disc;
1301
1302	for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1303
1304		if (temp & id)
1305			FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1306	}
1307
1308	sync_bit_map = 0x0001;
1309
1310	for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1311
1312		if (pCurrNvRam) {
1313			temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1314			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1315			    (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1316		} else
1317			temp =
1318			    FPT_utilEERead(ioport,
1319					   (unsigned short)((SYNC_RATE_TBL / 2)
1320							    + id));
1321
1322		for (i = 0; i < 2; temp >>= 8, i++) {
1323
1324			if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1325
1326				FPT_sccbMgrTbl[thisCard][id * 2 +
1327							 i].TarEEValue =
1328				    (unsigned char)temp;
1329			}
1330
1331			else {
1332				FPT_sccbMgrTbl[thisCard][id * 2 +
1333							 i].TarStatus |=
1334				    SYNC_SUPPORTED;
1335				FPT_sccbMgrTbl[thisCard][id * 2 +
1336							 i].TarEEValue =
1337				    (unsigned char)(temp & ~EE_SYNC_MASK);
1338			}
1339
1340/*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1341            (id*2+i >= 8)){
1342*/
1343			if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1344
1345				FPT_sccbMgrTbl[thisCard][id * 2 +
1346							 i].TarEEValue |=
1347				    EE_WIDE_SCSI;
1348
1349			}
1350
1351			else {	/* NARROW SCSI */
1352				FPT_sccbMgrTbl[thisCard][id * 2 +
1353							 i].TarStatus |=
1354				    WIDE_NEGOCIATED;
1355			}
1356
1357			sync_bit_map <<= 1;
1358
1359		}
1360	}
1361
1362	WR_HARPOON((ioport + hp_semaphore),
1363		   (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1364				   SCCB_MGR_PRESENT));
1365
1366	return (void *)CurrCard;
1367}
1368
1369static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1370{
1371	unsigned char i;
1372	u32 portBase;
1373	u32 regOffset;
1374	u32 scamData;
1375	u32 *pScamTbl;
1376	struct nvram_info *pCurrNvRam;
1377
1378	pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1379
1380	if (pCurrNvRam) {
1381		FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1382		FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1383		FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1384		FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1385		FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1386
1387		for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1388			FPT_WrStack(pCurrNvRam->niBaseAddr,
1389				    (unsigned char)(i + 5),
1390				    pCurrNvRam->niSyncTbl[i]);
1391
1392		portBase = pCurrNvRam->niBaseAddr;
1393
1394		for (i = 0; i < MAX_SCSI_TAR; i++) {
1395			regOffset = hp_aramBase + 64 + i * 4;
1396			pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1397			scamData = *pScamTbl;
1398			WR_HARP32(portBase, regOffset, scamData);
1399		}
1400
1401	} else {
1402		FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1403	}
1404}
1405
1406static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1407{
1408	unsigned char i;
1409	u32 portBase;
1410	u32 regOffset;
1411	u32 scamData;
1412	u32 *pScamTbl;
1413
1414	pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1415	pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1416	pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1417	pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1418	pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1419
1420	for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1421		pNvRamInfo->niSyncTbl[i] =
1422		    FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1423
1424	portBase = pNvRamInfo->niBaseAddr;
1425
1426	for (i = 0; i < MAX_SCSI_TAR; i++) {
1427		regOffset = hp_aramBase + 64 + i * 4;
1428		RD_HARP32(portBase, regOffset, scamData);
1429		pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1430		*pScamTbl = scamData;
1431	}
1432
1433}
1434
1435static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1436{
1437	WR_HARPOON(portBase + hp_stack_addr, index);
1438	return RD_HARPOON(portBase + hp_stack_data);
1439}
1440
1441static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1442{
1443	WR_HARPOON(portBase + hp_stack_addr, index);
1444	WR_HARPOON(portBase + hp_stack_data, data);
1445}
1446
1447static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1448{
1449	if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1450		return 0;
1451	if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1452	    != CLKCTRL_DEFAULT)
1453		return 0;
1454	if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1455	    (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1456		return 1;
1457	return 0;
1458
1459}
1460
1461/*---------------------------------------------------------------------
1462 *
1463 * Function: FlashPoint_StartCCB
1464 *
1465 * Description: Start a command pointed to by p_Sccb. When the
1466 *              command is completed it will be returned via the
1467 *              callback function.
1468 *
1469 *---------------------------------------------------------------------*/
1470static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1471{
1472	u32 ioport;
1473	unsigned char thisCard, lun;
1474	struct sccb *pSaveSccb;
1475	CALL_BK_FN callback;
1476	struct sccb_card *pCurrCard = curr_card;
1477
1478	thisCard = pCurrCard->cardIndex;
1479	ioport = pCurrCard->ioPort;
1480
1481	if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1482
1483		p_Sccb->HostStatus = SCCB_COMPLETE;
1484		p_Sccb->SccbStatus = SCCB_ERROR;
1485		callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1486		if (callback)
1487			callback(p_Sccb);
1488
1489		return;
1490	}
1491
1492	FPT_sinits(p_Sccb, thisCard);
1493
1494	if (!pCurrCard->cmdCounter) {
1495		WR_HARPOON(ioport + hp_semaphore,
1496			   (RD_HARPOON(ioport + hp_semaphore)
1497			    | SCCB_MGR_ACTIVE));
1498
1499		if (pCurrCard->globalFlags & F_GREEN_PC) {
1500			WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1501			WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1502		}
1503	}
1504
1505	pCurrCard->cmdCounter++;
1506
1507	if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1508
1509		WR_HARPOON(ioport + hp_semaphore,
1510			   (RD_HARPOON(ioport + hp_semaphore)
1511			    | TICKLE_ME));
1512		if (p_Sccb->OperationCode == RESET_COMMAND) {
1513			pSaveSccb =
1514			    pCurrCard->currentSCCB;
1515			pCurrCard->currentSCCB = p_Sccb;
1516			FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1517			pCurrCard->currentSCCB =
1518			    pSaveSccb;
1519		} else {
1520			FPT_queueAddSccb(p_Sccb, thisCard);
1521		}
1522	}
1523
1524	else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1525
1526		if (p_Sccb->OperationCode == RESET_COMMAND) {
1527			pSaveSccb =
1528			    pCurrCard->currentSCCB;
1529			pCurrCard->currentSCCB = p_Sccb;
1530			FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1531			pCurrCard->currentSCCB =
1532			    pSaveSccb;
1533		} else {
1534			FPT_queueAddSccb(p_Sccb, thisCard);
1535		}
1536	}
1537
1538	else {
1539
1540		MDISABLE_INT(ioport);
1541
1542		if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1543		    ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1544		      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1545			lun = p_Sccb->Lun;
1546		else
1547			lun = 0;
1548		if ((pCurrCard->currentSCCB == NULL) &&
1549		    (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1550		    && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1551			== 0)) {
1552
1553			pCurrCard->currentSCCB = p_Sccb;
1554			FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1555		}
1556
1557		else {
1558
1559			if (p_Sccb->OperationCode == RESET_COMMAND) {
1560				pSaveSccb = pCurrCard->currentSCCB;
1561				pCurrCard->currentSCCB = p_Sccb;
1562				FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1563						    thisCard);
1564				pCurrCard->currentSCCB = pSaveSccb;
1565			} else {
1566				FPT_queueAddSccb(p_Sccb, thisCard);
1567			}
1568		}
1569
1570		MENABLE_INT(ioport);
1571	}
1572
1573}
1574
1575/*---------------------------------------------------------------------
1576 *
1577 * Function: FlashPoint_AbortCCB
1578 *
1579 * Description: Abort the command pointed to by p_Sccb.  When the
1580 *              command is completed it will be returned via the
1581 *              callback function.
1582 *
1583 *---------------------------------------------------------------------*/
1584static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
1585{
1586	u32 ioport;
1587
1588	unsigned char thisCard;
1589	CALL_BK_FN callback;
 
1590	struct sccb *pSaveSCCB;
1591	struct sccb_mgr_tar_info *currTar_Info;
1592
1593	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1594
1595	thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1596
1597	if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1598
1599		if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1600
1601			((struct sccb_card *)pCurrCard)->cmdCounter--;
1602
1603			if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1604				WR_HARPOON(ioport + hp_semaphore,
1605					   (RD_HARPOON(ioport + hp_semaphore)
1606					    & (unsigned
1607					       char)(~(SCCB_MGR_ACTIVE |
1608						       TICKLE_ME))));
1609
1610			p_Sccb->SccbStatus = SCCB_ABORT;
1611			callback = p_Sccb->SccbCallback;
1612			callback(p_Sccb);
1613
1614			return 0;
1615		}
1616
1617		else {
1618			if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1619			    p_Sccb) {
1620				p_Sccb->SccbStatus = SCCB_ABORT;
1621				return 0;
1622
1623			}
1624
1625			else {
 
 
 
1626				if (p_Sccb->Sccb_tag) {
1627					MDISABLE_INT(ioport);
1628					if (((struct sccb_card *)pCurrCard)->
1629					    discQ_Tbl[p_Sccb->Sccb_tag] ==
1630					    p_Sccb) {
1631						p_Sccb->SccbStatus = SCCB_ABORT;
1632						p_Sccb->Sccb_scsistat =
1633						    ABORT_ST;
1634						p_Sccb->Sccb_scsimsg =
1635						    ABORT_TASK;
1636
1637						if (((struct sccb_card *)
1638						     pCurrCard)->currentSCCB ==
1639						    NULL) {
1640							((struct sccb_card *)
1641							 pCurrCard)->
1642					currentSCCB = p_Sccb;
1643							FPT_ssel(ioport,
1644								 thisCard);
1645						} else {
1646							pSaveSCCB =
1647							    ((struct sccb_card
1648							      *)pCurrCard)->
1649							    currentSCCB;
1650							((struct sccb_card *)
1651							 pCurrCard)->
1652					currentSCCB = p_Sccb;
1653							FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1654							((struct sccb_card *)
1655							 pCurrCard)->
1656					currentSCCB = pSaveSCCB;
1657						}
1658					}
1659					MENABLE_INT(ioport);
1660					return 0;
1661				} else {
1662					currTar_Info =
1663					    &FPT_sccbMgrTbl[thisCard][p_Sccb->
1664								      TargID];
1665
1666					if (FPT_BL_Card[thisCard].
1667					    discQ_Tbl[currTar_Info->
1668						      LunDiscQ_Idx[p_Sccb->Lun]]
1669					    == p_Sccb) {
1670						p_Sccb->SccbStatus = SCCB_ABORT;
1671						return 0;
1672					}
1673				}
1674			}
1675		}
1676	}
1677	return -1;
1678}
1679
1680/*---------------------------------------------------------------------
1681 *
1682 * Function: FlashPoint_InterruptPending
1683 *
1684 * Description: Do a quick check to determine if there is a pending
1685 *              interrupt for this card and disable the IRQ Pin if so.
1686 *
1687 *---------------------------------------------------------------------*/
1688static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1689{
1690	u32 ioport;
1691
1692	ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1693
1694	if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1695		return 1;
1696	}
1697
1698	else
1699
1700		return 0;
1701}
1702
1703/*---------------------------------------------------------------------
1704 *
1705 * Function: FlashPoint_HandleInterrupt
1706 *
1707 * Description: This is our entry point when an interrupt is generated
1708 *              by the card and the upper level driver passes it on to
1709 *              us.
1710 *
1711 *---------------------------------------------------------------------*/
1712static int FlashPoint_HandleInterrupt(void *pcard)
1713{
1714	struct sccb *currSCCB;
1715	unsigned char thisCard, result, bm_status;
1716	unsigned short hp_int;
1717	unsigned char i, target;
1718	struct sccb_card *pCurrCard = pcard;
1719	u32 ioport;
1720
1721	thisCard = pCurrCard->cardIndex;
1722	ioport = pCurrCard->ioPort;
1723
1724	MDISABLE_INT(ioport);
1725
1726	if (RD_HARPOON(ioport + hp_int_status) & EXT_STATUS_ON)
1727		bm_status = RD_HARPOON(ioport + hp_ext_status) &
1728					(unsigned char)BAD_EXT_STATUS;
1729	else
1730		bm_status = 0;
1731
1732	WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1733
1734	while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1735				FPT_default_intena) | bm_status) {
1736
1737		currSCCB = pCurrCard->currentSCCB;
1738
1739		if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1740			result =
1741			    FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
1742						hp_int);
1743			WRW_HARPOON((ioport + hp_intstat),
1744				    (FIFO | TIMEOUT | RESET | SCAM_SEL));
1745			bm_status = 0;
1746
1747			if (result) {
1748
1749				MENABLE_INT(ioport);
1750				return result;
1751			}
1752		}
1753
1754		else if (hp_int & ICMD_COMP) {
1755
1756			if (!(hp_int & BUS_FREE)) {
1757				/* Wait for the BusFree before starting a new command.  We
1758				   must also check for being reselected since the BusFree
1759				   may not show up if another device reselects us in 1.5us or
1760				   less.  SRR Wednesday, 3/8/1995.
1761				 */
1762				while (!
1763				       (RDW_HARPOON((ioport + hp_intstat)) &
1764					(BUS_FREE | RSEL))) ;
1765			}
1766
1767			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1768
1769				FPT_phaseChkFifo(ioport, thisCard);
1770
1771/*         WRW_HARPOON((ioport+hp_intstat),
1772            (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1773         */
1774
1775			WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1776
1777			FPT_autoCmdCmplt(ioport, thisCard);
1778
1779		}
1780
1781		else if (hp_int & ITAR_DISC) {
1782
1783			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1784				FPT_phaseChkFifo(ioport, thisCard);
1785
1786			if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1787					SAVE_POINTERS) {
1788
1789				WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1790				currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1791
1792				currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1793			}
1794
1795			currSCCB->Sccb_scsistat = DISCONNECT_ST;
1796			FPT_queueDisconnect(currSCCB, thisCard);
1797
1798			/* Wait for the BusFree before starting a new command.  We
1799			   must also check for being reselected since the BusFree
1800			   may not show up if another device reselects us in 1.5us or
1801			   less.  SRR Wednesday, 3/8/1995.
1802			 */
1803			while (!
1804			       (RDW_HARPOON((ioport + hp_intstat)) &
1805				(BUS_FREE | RSEL))
1806			       && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1807				    && RD_HARPOON((ioport + hp_scsisig)) ==
1808				    (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1809				     SCSI_IOBIT))) ;
1810
1811			/*
1812			   The additional loop exit condition above detects a timing problem
1813			   with the revision D/E harpoon chips.  The caller should reset the
1814			   host adapter to recover when 0xFE is returned.
1815			 */
1816			if (!
1817			    (RDW_HARPOON((ioport + hp_intstat)) &
1818			     (BUS_FREE | RSEL))) {
1819				MENABLE_INT(ioport);
1820				return 0xFE;
1821			}
1822
1823			WRW_HARPOON((ioport + hp_intstat),
1824				    (BUS_FREE | ITAR_DISC));
1825
1826			pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1827
1828		}
1829
1830		else if (hp_int & RSEL) {
1831
1832			WRW_HARPOON((ioport + hp_intstat),
1833				    (PROG_HLT | RSEL | PHASE | BUS_FREE));
1834
1835			if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1836				if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1837					FPT_phaseChkFifo(ioport, thisCard);
1838
1839				if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1840				    SAVE_POINTERS) {
1841					WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1842					currSCCB->Sccb_XferState |=
1843					    F_NO_DATA_YET;
1844					currSCCB->Sccb_savedATC =
1845					    currSCCB->Sccb_ATC;
1846				}
1847
1848				WRW_HARPOON((ioport + hp_intstat),
1849					    (BUS_FREE | ITAR_DISC));
1850				currSCCB->Sccb_scsistat = DISCONNECT_ST;
1851				FPT_queueDisconnect(currSCCB, thisCard);
1852			}
1853
1854			FPT_sres(ioport, thisCard, pCurrCard);
1855			FPT_phaseDecode(ioport, thisCard);
1856
1857		}
1858
1859		else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1860
1861			WRW_HARPOON((ioport + hp_intstat),
1862				    (IDO_STRT | XFER_CNT_0));
1863			FPT_phaseDecode(ioport, thisCard);
1864
1865		}
1866
1867		else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1868			WRW_HARPOON((ioport + hp_intstat),
1869				    (PHASE | IUNKWN | PROG_HLT));
1870			if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1871			     0x3f) < (unsigned char)SELCHK) {
1872				FPT_phaseDecode(ioport, thisCard);
1873			} else {
1874				/* Harpoon problem some SCSI target device respond to selection
1875				   with short BUSY pulse (<400ns) this will make the Harpoon is not able
1876				   to latch the correct Target ID into reg. x53.
1877				   The work around require to correct this reg. But when write to this
1878				   reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1879				   need to read this reg first then restore it later. After update to 0x53 */
1880
1881				i = (unsigned
1882				     char)(RD_HARPOON(ioport + hp_fifowrite));
1883				target =
1884				    (unsigned
1885				     char)(RD_HARPOON(ioport + hp_gp_reg_3));
1886				WR_HARPOON(ioport + hp_xfer_pad,
1887					   (unsigned char)ID_UNLOCK);
1888				WR_HARPOON(ioport + hp_select_id,
1889					   (unsigned char)(target | target <<
1890							   4));
1891				WR_HARPOON(ioport + hp_xfer_pad,
1892					   (unsigned char)0x00);
1893				WR_HARPOON(ioport + hp_fifowrite, i);
1894				WR_HARPOON(ioport + hp_autostart_3,
1895					   (AUTO_IMMED + TAG_STRT));
1896			}
1897		}
1898
1899		else if (hp_int & XFER_CNT_0) {
1900
1901			WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1902
1903			FPT_schkdd(ioport, thisCard);
1904
1905		}
1906
1907		else if (hp_int & BUS_FREE) {
1908
1909			WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1910
1911			if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1912
1913				FPT_hostDataXferAbort(ioport, thisCard,
1914						      currSCCB);
1915			}
1916
1917			FPT_phaseBusFree(ioport, thisCard);
1918		}
1919
1920		else if (hp_int & ITICKLE) {
1921
1922			WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1923			pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1924		}
1925
1926		if (((struct sccb_card *)pCurrCard)->
1927		    globalFlags & F_NEW_SCCB_CMD) {
1928
1929			pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1930
1931			if (pCurrCard->currentSCCB == NULL)
1932				FPT_queueSearchSelect(pCurrCard, thisCard);
1933
1934			if (pCurrCard->currentSCCB != NULL) {
1935				pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1936				FPT_ssel(ioport, thisCard);
1937			}
1938
1939			break;
1940
1941		}
1942
1943	}			/*end while */
1944
1945	MENABLE_INT(ioport);
1946
1947	return 0;
1948}
1949
1950/*---------------------------------------------------------------------
1951 *
1952 * Function: Sccb_bad_isr
1953 *
1954 * Description: Some type of interrupt has occurred which is slightly
1955 *              out of the ordinary.  We will now decode it fully, in
1956 *              this routine.  This is broken up in an attempt to save
1957 *              processing time.
1958 *
1959 *---------------------------------------------------------------------*/
1960static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1961					 struct sccb_card *pCurrCard,
1962					 unsigned short p_int)
1963{
1964	unsigned char temp, ScamFlg;
1965	struct sccb_mgr_tar_info *currTar_Info;
1966	struct nvram_info *pCurrNvRam;
1967
1968	if (RD_HARPOON(p_port + hp_ext_status) &
1969	    (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
1970
1971		if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1972
1973			FPT_hostDataXferAbort(p_port, p_card,
1974					      pCurrCard->currentSCCB);
1975		}
1976
1977		if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
1978		{
1979			WR_HARPOON(p_port + hp_pci_stat_cfg,
1980				   (RD_HARPOON(p_port + hp_pci_stat_cfg) &
1981				    ~REC_MASTER_ABORT));
1982
1983			WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
1984
1985		}
1986
1987		if (pCurrCard->currentSCCB != NULL) {
1988
1989			if (!pCurrCard->currentSCCB->HostStatus)
1990				pCurrCard->currentSCCB->HostStatus =
1991				    SCCB_BM_ERR;
1992
1993			FPT_sxfrp(p_port, p_card);
1994
1995			temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
1996					       (EXT_ARB_ACK | SCSI_TERM_ENA_H));
1997			WR_HARPOON(p_port + hp_ee_ctrl,
1998				   ((unsigned char)temp | SEE_MS | SEE_CS));
1999			WR_HARPOON(p_port + hp_ee_ctrl, temp);
2000
2001			if (!
2002			    (RDW_HARPOON((p_port + hp_intstat)) &
2003			     (BUS_FREE | RESET))) {
2004				FPT_phaseDecode(p_port, p_card);
2005			}
2006		}
2007	}
2008
2009	else if (p_int & RESET) {
2010
2011		WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2012		WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2013		if (pCurrCard->currentSCCB != NULL) {
2014
2015			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2016
2017				FPT_hostDataXferAbort(p_port, p_card,
2018						      pCurrCard->currentSCCB);
2019		}
2020
2021		DISABLE_AUTO(p_port);
2022
2023		FPT_sresb(p_port, p_card);
2024
2025		while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2026		}
2027
2028		pCurrNvRam = pCurrCard->pNvRamInfo;
2029		if (pCurrNvRam) {
2030			ScamFlg = pCurrNvRam->niScamConf;
2031		} else {
2032			ScamFlg =
2033			    (unsigned char)FPT_utilEERead(p_port,
2034							  SCAM_CONFIG / 2);
2035		}
2036
2037		FPT_XbowInit(p_port, ScamFlg);
2038
2039		FPT_scini(p_card, pCurrCard->ourId, 0);
2040
2041		return 0xFF;
2042	}
2043
2044	else if (p_int & FIFO) {
2045
2046		WRW_HARPOON((p_port + hp_intstat), FIFO);
2047
2048		if (pCurrCard->currentSCCB != NULL)
2049			FPT_sxfrp(p_port, p_card);
2050	}
2051
2052	else if (p_int & TIMEOUT) {
2053
2054		DISABLE_AUTO(p_port);
2055
2056		WRW_HARPOON((p_port + hp_intstat),
2057			    (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2058			     IUNKWN));
2059
2060		pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2061
2062		currTar_Info =
2063		    &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2064		if ((pCurrCard->globalFlags & F_CONLUN_IO)
2065		    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2066			TAG_Q_TRYING))
2067			currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2068			    0;
2069		else
2070			currTar_Info->TarLUNBusy[0] = 0;
2071
2072		if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2073			currTar_Info->TarSyncCtrl = 0;
2074			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2075		}
2076
2077		if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2078			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2079		}
2080
2081		FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2082			    currTar_Info);
2083
2084		FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2085
2086	}
2087
2088	else if (p_int & SCAM_SEL) {
2089
2090		FPT_scarb(p_port, LEVEL2_TAR);
2091		FPT_scsel(p_port);
2092		FPT_scasid(p_card, p_port);
2093
2094		FPT_scbusf(p_port);
2095
2096		WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2097	}
2098
2099	return 0x00;
2100}
2101
2102/*---------------------------------------------------------------------
2103 *
2104 * Function: SccbMgrTableInit
2105 *
2106 * Description: Initialize all Sccb manager data structures.
2107 *
2108 *---------------------------------------------------------------------*/
2109
2110static void FPT_SccbMgrTableInitAll(void)
2111{
2112	unsigned char thisCard;
2113
2114	for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2115		FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2116
2117		FPT_BL_Card[thisCard].ioPort = 0x00;
2118		FPT_BL_Card[thisCard].cardInfo = NULL;
2119		FPT_BL_Card[thisCard].cardIndex = 0xFF;
2120		FPT_BL_Card[thisCard].ourId = 0x00;
2121		FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2122	}
2123}
2124
2125/*---------------------------------------------------------------------
2126 *
2127 * Function: SccbMgrTableInit
2128 *
2129 * Description: Initialize all Sccb manager data structures.
2130 *
2131 *---------------------------------------------------------------------*/
2132
2133static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2134				     unsigned char p_card)
2135{
2136	unsigned char scsiID, qtag;
2137
2138	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2139		FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2140	}
2141
2142	for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2143		FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2144		FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2145		FPT_SccbMgrTableInitTarget(p_card, scsiID);
2146	}
2147
2148	pCurrCard->scanIndex = 0x00;
2149	pCurrCard->currentSCCB = NULL;
2150	pCurrCard->globalFlags = 0x00;
2151	pCurrCard->cmdCounter = 0x00;
2152	pCurrCard->tagQ_Lst = 0x01;
2153	pCurrCard->discQCount = 0;
2154
2155}
2156
2157/*---------------------------------------------------------------------
2158 *
2159 * Function: SccbMgrTableInit
2160 *
2161 * Description: Initialize all Sccb manager data structures.
2162 *
2163 *---------------------------------------------------------------------*/
2164
2165static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2166				       unsigned char target)
2167{
2168
2169	unsigned char lun, qtag;
2170	struct sccb_mgr_tar_info *currTar_Info;
2171
2172	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2173
2174	currTar_Info->TarSelQ_Cnt = 0;
2175	currTar_Info->TarSyncCtrl = 0;
2176
2177	currTar_Info->TarSelQ_Head = NULL;
2178	currTar_Info->TarSelQ_Tail = NULL;
2179	currTar_Info->TarTagQ_Cnt = 0;
2180	currTar_Info->TarLUN_CA = 0;
2181
2182	for (lun = 0; lun < MAX_LUN; lun++) {
2183		currTar_Info->TarLUNBusy[lun] = 0;
2184		currTar_Info->LunDiscQ_Idx[lun] = 0;
2185	}
2186
2187	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2188		if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2189			if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2190			    target) {
2191				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2192				FPT_BL_Card[p_card].discQCount--;
2193			}
2194		}
2195	}
2196}
2197
2198/*---------------------------------------------------------------------
2199 *
2200 * Function: sfetm
2201 *
2202 * Description: Read in a message byte from the SCSI bus, and check
2203 *              for a parity error.
2204 *
2205 *---------------------------------------------------------------------*/
2206
2207static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2208{
2209	unsigned char message;
2210	unsigned short TimeOutLoop;
2211
2212	TimeOutLoop = 0;
2213	while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2214	       (TimeOutLoop++ < 20000)) {
2215	}
2216
2217	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2218
2219	message = RD_HARPOON(port + hp_scsidata_0);
2220
2221	WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2222
2223	if (TimeOutLoop > 20000)
2224		message = 0x00;	/* force message byte = 0 if Time Out on Req */
2225
2226	if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2227	    (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2228		WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2229		WR_HARPOON(port + hp_xferstat, 0);
2230		WR_HARPOON(port + hp_fiforead, 0);
2231		WR_HARPOON(port + hp_fifowrite, 0);
2232		if (pCurrSCCB != NULL) {
2233			pCurrSCCB->Sccb_scsimsg = MSG_PARITY_ERROR;
2234		}
2235		message = 0x00;
2236		do {
2237			ACCEPT_MSG_ATN(port);
2238			TimeOutLoop = 0;
2239			while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2240			       (TimeOutLoop++ < 20000)) {
2241			}
2242			if (TimeOutLoop > 20000) {
2243				WRW_HARPOON((port + hp_intstat), PARITY);
2244				return message;
2245			}
2246			if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2247			    S_MSGI_PH) {
2248				WRW_HARPOON((port + hp_intstat), PARITY);
2249				return message;
2250			}
2251			WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2252
2253			RD_HARPOON(port + hp_scsidata_0);
2254
2255			WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2256
2257		} while (1);
2258
2259	}
2260	WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2261	WR_HARPOON(port + hp_xferstat, 0);
2262	WR_HARPOON(port + hp_fiforead, 0);
2263	WR_HARPOON(port + hp_fifowrite, 0);
2264	return message;
2265}
2266
2267/*---------------------------------------------------------------------
2268 *
2269 * Function: FPT_ssel
2270 *
2271 * Description: Load up automation and select target device.
2272 *
2273 *---------------------------------------------------------------------*/
2274
2275static void FPT_ssel(u32 port, unsigned char p_card)
2276{
2277
2278	unsigned char auto_loaded, i, target, *theCCB;
2279
2280	u32 cdb_reg;
2281	struct sccb_card *CurrCard;
2282	struct sccb *currSCCB;
2283	struct sccb_mgr_tar_info *currTar_Info;
2284	unsigned char lastTag, lun;
2285
2286	CurrCard = &FPT_BL_Card[p_card];
2287	currSCCB = CurrCard->currentSCCB;
2288	target = currSCCB->TargID;
2289	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2290	lastTag = CurrCard->tagQ_Lst;
2291
2292	ARAM_ACCESS(port);
2293
2294	if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2295		currSCCB->ControlByte &= ~F_USE_CMD_Q;
2296
2297	if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2298	     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2299
2300		lun = currSCCB->Lun;
2301	else
2302		lun = 0;
2303
2304	if (CurrCard->globalFlags & F_TAG_STARTED) {
2305		if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2306			if ((currTar_Info->TarLUN_CA == 0)
2307			    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2308				== TAG_Q_TRYING)) {
2309
2310				if (currTar_Info->TarTagQ_Cnt != 0) {
2311					currTar_Info->TarLUNBusy[lun] = 1;
2312					FPT_queueSelectFail(CurrCard, p_card);
2313					SGRAM_ACCESS(port);
2314					return;
2315				}
2316
2317				else {
2318					currTar_Info->TarLUNBusy[lun] = 1;
2319				}
2320
2321			}
2322			/*End non-tagged */
2323			else {
2324				currTar_Info->TarLUNBusy[lun] = 1;
2325			}
2326
2327		}
2328		/*!Use cmd Q Tagged */
2329		else {
2330			if (currTar_Info->TarLUN_CA == 1) {
2331				FPT_queueSelectFail(CurrCard, p_card);
2332				SGRAM_ACCESS(port);
2333				return;
2334			}
2335
2336			currTar_Info->TarLUNBusy[lun] = 1;
2337
2338		}		/*else use cmd Q tagged */
2339
2340	}
2341	/*if glob tagged started */
2342	else {
2343		currTar_Info->TarLUNBusy[lun] = 1;
2344	}
2345
2346	if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2347	      ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2348	     || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2349		if (CurrCard->discQCount >= QUEUE_DEPTH) {
2350			currTar_Info->TarLUNBusy[lun] = 1;
2351			FPT_queueSelectFail(CurrCard, p_card);
2352			SGRAM_ACCESS(port);
2353			return;
2354		}
2355		for (i = 1; i < QUEUE_DEPTH; i++) {
2356			if (++lastTag >= QUEUE_DEPTH)
2357				lastTag = 1;
2358			if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2359				CurrCard->tagQ_Lst = lastTag;
2360				currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2361				CurrCard->discQ_Tbl[lastTag] = currSCCB;
2362				CurrCard->discQCount++;
2363				break;
2364			}
2365		}
2366		if (i == QUEUE_DEPTH) {
2367			currTar_Info->TarLUNBusy[lun] = 1;
2368			FPT_queueSelectFail(CurrCard, p_card);
2369			SGRAM_ACCESS(port);
2370			return;
2371		}
2372	}
2373
2374	auto_loaded = 0;
2375
2376	WR_HARPOON(port + hp_select_id, target);
2377	WR_HARPOON(port + hp_gp_reg_3, target);	/* Use by new automation logic */
2378
2379	if (currSCCB->OperationCode == RESET_COMMAND) {
2380		WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2381						   (currSCCB->
2382						    Sccb_idmsg & ~DISC_PRIV)));
2383
2384		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2385
2386		currSCCB->Sccb_scsimsg = TARGET_RESET;
2387
2388		WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2389		auto_loaded = 1;
2390		currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2391
2392		if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2393			currTar_Info->TarSyncCtrl = 0;
2394			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2395		}
2396
2397		if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2398			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2399		}
2400
2401		FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2402		FPT_SccbMgrTableInitTarget(p_card, target);
2403
2404	}
2405
2406	else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2407		WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2408						   (currSCCB->
2409						    Sccb_idmsg & ~DISC_PRIV)));
2410
2411		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2412
2413		WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2414						     (((unsigned
2415							char)(currSCCB->
2416							      ControlByte &
2417							      TAG_TYPE_MASK)
2418						       >> 6) | (unsigned char)
2419						      0x20)));
2420		WRW_HARPOON((port + SYNC_MSGS + 2),
2421			    (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2422		WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2423
2424		WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2425		auto_loaded = 1;
2426
2427	}
2428
2429	else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2430		auto_loaded = FPT_siwidn(port, p_card);
2431		currSCCB->Sccb_scsistat = SELECT_WN_ST;
2432	}
2433
2434	else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2435		   == SYNC_SUPPORTED)) {
2436		auto_loaded = FPT_sisyncn(port, p_card, 0);
2437		currSCCB->Sccb_scsistat = SELECT_SN_ST;
2438	}
2439
2440	if (!auto_loaded) {
2441
2442		if (currSCCB->ControlByte & F_USE_CMD_Q) {
2443
2444			CurrCard->globalFlags |= F_TAG_STARTED;
2445
2446			if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2447			    == TAG_Q_REJECT) {
2448				currSCCB->ControlByte &= ~F_USE_CMD_Q;
2449
2450				/* Fix up the start instruction with a jump to
2451				   Non-Tag-CMD handling */
2452				WRW_HARPOON((port + ID_MSG_STRT),
2453					    BRH_OP + ALWAYS + NTCMD);
2454
2455				WRW_HARPOON((port + NON_TAG_ID_MSG),
2456					    (MPM_OP + AMSG_OUT +
2457					     currSCCB->Sccb_idmsg));
2458
2459				WR_HARPOON(port + hp_autostart_3,
2460					   (SELECT + SELCHK_STRT));
2461
2462				/* Setup our STATE so we know what happened when
2463				   the wheels fall off. */
2464				currSCCB->Sccb_scsistat = SELECT_ST;
2465
2466				currTar_Info->TarLUNBusy[lun] = 1;
2467			}
2468
2469			else {
2470				WRW_HARPOON((port + ID_MSG_STRT),
2471					    (MPM_OP + AMSG_OUT +
2472					     currSCCB->Sccb_idmsg));
2473
2474				WRW_HARPOON((port + ID_MSG_STRT + 2),
2475					    (MPM_OP + AMSG_OUT +
2476					     (((unsigned char)(currSCCB->
2477							       ControlByte &
2478							       TAG_TYPE_MASK)
2479					       >> 6) | (unsigned char)0x20)));
2480
2481				for (i = 1; i < QUEUE_DEPTH; i++) {
2482					if (++lastTag >= QUEUE_DEPTH)
2483						lastTag = 1;
2484					if (CurrCard->discQ_Tbl[lastTag] ==
2485					    NULL) {
2486						WRW_HARPOON((port +
2487							     ID_MSG_STRT + 6),
2488							    (MPM_OP + AMSG_OUT +
2489							     lastTag));
2490						CurrCard->tagQ_Lst = lastTag;
2491						currSCCB->Sccb_tag = lastTag;
2492						CurrCard->discQ_Tbl[lastTag] =
2493						    currSCCB;
2494						CurrCard->discQCount++;
2495						break;
2496					}
2497				}
2498
2499				if (i == QUEUE_DEPTH) {
2500					currTar_Info->TarLUNBusy[lun] = 1;
2501					FPT_queueSelectFail(CurrCard, p_card);
2502					SGRAM_ACCESS(port);
2503					return;
2504				}
2505
2506				currSCCB->Sccb_scsistat = SELECT_Q_ST;
2507
2508				WR_HARPOON(port + hp_autostart_3,
2509					   (SELECT + SELCHK_STRT));
2510			}
2511		}
2512
2513		else {
2514
2515			WRW_HARPOON((port + ID_MSG_STRT),
2516				    BRH_OP + ALWAYS + NTCMD);
2517
2518			WRW_HARPOON((port + NON_TAG_ID_MSG),
2519				    (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2520
2521			currSCCB->Sccb_scsistat = SELECT_ST;
2522
2523			WR_HARPOON(port + hp_autostart_3,
2524				   (SELECT + SELCHK_STRT));
2525		}
2526
2527		theCCB = (unsigned char *)&currSCCB->Cdb[0];
2528
2529		cdb_reg = port + CMD_STRT;
2530
2531		for (i = 0; i < currSCCB->CdbLength; i++) {
2532			WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2533			cdb_reg += 2;
2534			theCCB++;
2535		}
2536
2537		if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2538			WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2539
2540	}
2541	/* auto_loaded */
2542	WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2543	WR_HARPOON(port + hp_xferstat, 0x00);
2544
2545	WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2546
2547	WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2548
2549	if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2550		WR_HARPOON(port + hp_scsictrl_0,
2551			   (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2552	} else {
2553
2554/*      auto_loaded =  (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2555      auto_loaded |= AUTO_IMMED; */
2556		auto_loaded = AUTO_IMMED;
2557
2558		DISABLE_AUTO(port);
2559
2560		WR_HARPOON(port + hp_autostart_3, auto_loaded);
2561	}
2562
2563	SGRAM_ACCESS(port);
2564}
2565
2566/*---------------------------------------------------------------------
2567 *
2568 * Function: FPT_sres
2569 *
2570 * Description: Hookup the correct CCB and handle the incoming messages.
2571 *
2572 *---------------------------------------------------------------------*/
2573
2574static void FPT_sres(u32 port, unsigned char p_card,
2575		     struct sccb_card *pCurrCard)
2576{
2577
2578	unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2579
2580	struct sccb_mgr_tar_info *currTar_Info;
2581	struct sccb *currSCCB;
2582
2583	if (pCurrCard->currentSCCB != NULL) {
2584		currTar_Info =
2585		    &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2586		DISABLE_AUTO(port);
2587
2588		WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2589
2590		currSCCB = pCurrCard->currentSCCB;
2591		if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2592			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2593			currSCCB->Sccb_scsistat = BUS_FREE_ST;
2594		}
2595		if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2596			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2597			currSCCB->Sccb_scsistat = BUS_FREE_ST;
2598		}
2599		if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2600		     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2601		      TAG_Q_TRYING))) {
2602			currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2603			if (currSCCB->Sccb_scsistat != ABORT_ST) {
2604				pCurrCard->discQCount--;
2605				pCurrCard->discQ_Tbl[currTar_Info->
2606						     LunDiscQ_Idx[currSCCB->
2607								  Lun]]
2608				    = NULL;
2609			}
2610		} else {
2611			currTar_Info->TarLUNBusy[0] = 0;
2612			if (currSCCB->Sccb_tag) {
2613				if (currSCCB->Sccb_scsistat != ABORT_ST) {
2614					pCurrCard->discQCount--;
2615					pCurrCard->discQ_Tbl[currSCCB->
2616							     Sccb_tag] = NULL;
2617				}
2618			} else {
2619				if (currSCCB->Sccb_scsistat != ABORT_ST) {
2620					pCurrCard->discQCount--;
2621					pCurrCard->discQ_Tbl[currTar_Info->
2622							     LunDiscQ_Idx[0]] =
2623					    NULL;
2624				}
2625			}
2626		}
2627
2628		FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2629	}
2630
2631	WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2632
2633	our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
 
2634
2635	msgRetryCount = 0;
2636	do {
2637
2638		currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2639		tag = 0;
2640
2641		while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2642			if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2643
2644				WRW_HARPOON((port + hp_intstat), PHASE);
2645				return;
2646			}
2647		}
2648
2649		WRW_HARPOON((port + hp_intstat), PHASE);
2650		if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2651
2652			message = FPT_sfm(port, pCurrCard->currentSCCB);
2653			if (message) {
2654
2655				if (message <= (0x80 | LUN_MASK)) {
2656					lun = message & (unsigned char)LUN_MASK;
2657
2658					if ((currTar_Info->
2659					     TarStatus & TAR_TAG_Q_MASK) ==
2660					    TAG_Q_TRYING) {
2661						if (currTar_Info->TarTagQ_Cnt !=
2662						    0) {
2663
2664							if (!
2665							    (currTar_Info->
2666							     TarLUN_CA)) {
2667								ACCEPT_MSG(port);	/*Release the ACK for ID msg. */
2668
2669								message =
2670								    FPT_sfm
2671								    (port,
2672								     pCurrCard->
2673								     currentSCCB);
2674								if (message) {
2675									ACCEPT_MSG
2676									    (port);
2677								}
2678
2679								else
2680									message
2681									    = 0;
2682
2683								if (message !=
2684								    0) {
2685									tag =
2686									    FPT_sfm
2687									    (port,
2688									     pCurrCard->
2689									     currentSCCB);
2690
2691									if (!
2692									    (tag))
2693										message
2694										    =
2695										    0;
2696								}
2697
2698							}
2699							/*C.A. exists! */
2700						}
2701						/*End Q cnt != 0 */
2702					}
2703					/*End Tag cmds supported! */
2704				}
2705				/*End valid ID message.  */
2706				else {
2707
2708					ACCEPT_MSG_ATN(port);
2709				}
2710
2711			}
2712			/* End good id message. */
2713			else {
2714
2715				message = 0;
2716			}
2717		} else {
2718			ACCEPT_MSG_ATN(port);
2719
2720			while (!
2721			       (RDW_HARPOON((port + hp_intstat)) &
2722				(PHASE | RESET))
2723			       && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2724			       && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2725
2726			return;
2727		}
2728
2729		if (message == 0) {
2730			msgRetryCount++;
2731			if (msgRetryCount == 1) {
2732				FPT_SendMsg(port, MSG_PARITY_ERROR);
2733			} else {
2734				FPT_SendMsg(port, TARGET_RESET);
2735
2736				FPT_sssyncv(port, our_target, NARROW_SCSI,
2737					    currTar_Info);
2738
2739				if (FPT_sccbMgrTbl[p_card][our_target].
2740				    TarEEValue & EE_SYNC_MASK) {
2741
2742					FPT_sccbMgrTbl[p_card][our_target].
2743					    TarStatus &= ~TAR_SYNC_MASK;
2744
2745				}
2746
2747				if (FPT_sccbMgrTbl[p_card][our_target].
2748				    TarEEValue & EE_WIDE_SCSI) {
2749
2750					FPT_sccbMgrTbl[p_card][our_target].
2751					    TarStatus &= ~TAR_WIDE_MASK;
2752				}
2753
2754				FPT_queueFlushTargSccb(p_card, our_target,
2755						       SCCB_COMPLETE);
2756				FPT_SccbMgrTableInitTarget(p_card, our_target);
2757				return;
2758			}
2759		}
2760	} while (message == 0);
2761
2762	if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2763	     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2764		currTar_Info->TarLUNBusy[lun] = 1;
2765		pCurrCard->currentSCCB =
2766		    pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2767		if (pCurrCard->currentSCCB != NULL) {
2768			ACCEPT_MSG(port);
2769		} else {
2770			ACCEPT_MSG_ATN(port);
2771		}
2772	} else {
2773		currTar_Info->TarLUNBusy[0] = 1;
2774
2775		if (tag) {
2776			if (pCurrCard->discQ_Tbl[tag] != NULL) {
2777				pCurrCard->currentSCCB =
2778				    pCurrCard->discQ_Tbl[tag];
2779				currTar_Info->TarTagQ_Cnt--;
2780				ACCEPT_MSG(port);
2781			} else {
2782				ACCEPT_MSG_ATN(port);
2783			}
2784		} else {
2785			pCurrCard->currentSCCB =
2786			    pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2787			if (pCurrCard->currentSCCB != NULL) {
2788				ACCEPT_MSG(port);
2789			} else {
2790				ACCEPT_MSG_ATN(port);
2791			}
2792		}
2793	}
2794
2795	if (pCurrCard->currentSCCB != NULL) {
2796		if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2797			/* During Abort Tag command, the target could have got re-selected
2798			   and completed the command. Check the select Q and remove the CCB
2799			   if it is in the Select Q */
2800			FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2801		}
2802	}
2803
2804	while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2805	       !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2806	       (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2807}
2808
2809static void FPT_SendMsg(u32 port, unsigned char message)
2810{
2811	while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2812		if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2813
2814			WRW_HARPOON((port + hp_intstat), PHASE);
2815			return;
2816		}
2817	}
2818
2819	WRW_HARPOON((port + hp_intstat), PHASE);
2820	if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2821		WRW_HARPOON((port + hp_intstat),
2822			    (BUS_FREE | PHASE | XFER_CNT_0));
2823
2824		WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2825
2826		WR_HARPOON(port + hp_scsidata_0, message);
2827
2828		WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2829
2830		ACCEPT_MSG(port);
2831
2832		WR_HARPOON(port + hp_portctrl_0, 0x00);
2833
2834		if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
2835		    (message == ABORT_TASK)) {
2836			while (!
2837			       (RDW_HARPOON((port + hp_intstat)) &
2838				(BUS_FREE | PHASE))) {
2839			}
2840
2841			if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2842				WRW_HARPOON((port + hp_intstat), BUS_FREE);
2843			}
2844		}
2845	}
2846}
2847
2848/*---------------------------------------------------------------------
2849 *
2850 * Function: FPT_sdecm
2851 *
2852 * Description: Determine the proper response to the message from the
2853 *              target device.
2854 *
2855 *---------------------------------------------------------------------*/
2856static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2857{
2858	struct sccb *currSCCB;
2859	struct sccb_card *CurrCard;
2860	struct sccb_mgr_tar_info *currTar_Info;
2861
2862	CurrCard = &FPT_BL_Card[p_card];
2863	currSCCB = CurrCard->currentSCCB;
2864
2865	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2866
2867	if (message == RESTORE_POINTERS) {
2868		if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2869			currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2870
2871			FPT_hostDataXferRestart(currSCCB);
2872		}
2873
2874		ACCEPT_MSG(port);
2875		WR_HARPOON(port + hp_autostart_1,
2876			   (AUTO_IMMED + DISCONNECT_START));
2877	}
2878
2879	else if (message == COMMAND_COMPLETE) {
2880
2881		if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2882			currTar_Info->TarStatus &=
2883			    ~(unsigned char)TAR_TAG_Q_MASK;
2884			currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2885		}
2886
2887		ACCEPT_MSG(port);
2888
2889	}
2890
2891	else if ((message == NOP) || (message >= IDENTIFY_BASE) ||
2892		 (message == INITIATE_RECOVERY) ||
2893		 (message == RELEASE_RECOVERY)) {
2894
2895		ACCEPT_MSG(port);
2896		WR_HARPOON(port + hp_autostart_1,
2897			   (AUTO_IMMED + DISCONNECT_START));
2898	}
2899
2900	else if (message == MESSAGE_REJECT) {
2901
2902		if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2903		    (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2904		    ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2905		    || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2906			TAG_Q_TRYING))
2907		{
2908			WRW_HARPOON((port + hp_intstat), BUS_FREE);
2909
2910			ACCEPT_MSG(port);
2911
2912			while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2913			       (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2914			{
2915			}
2916
2917			if (currSCCB->Lun == 0x00) {
2918				if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2919
2920					currTar_Info->TarStatus |=
2921					    (unsigned char)SYNC_SUPPORTED;
2922
2923					currTar_Info->TarEEValue &=
2924					    ~EE_SYNC_MASK;
2925				}
2926
2927				else if (currSCCB->Sccb_scsistat ==
2928					  SELECT_WN_ST) {
2929
2930					currTar_Info->TarStatus =
2931					    (currTar_Info->
2932					     TarStatus & ~WIDE_ENABLED) |
2933					    WIDE_NEGOCIATED;
2934
2935					currTar_Info->TarEEValue &=
2936					    ~EE_WIDE_SCSI;
2937
2938				}
2939
2940				else if ((currTar_Info->
2941					  TarStatus & TAR_TAG_Q_MASK) ==
2942					 TAG_Q_TRYING) {
2943					currTar_Info->TarStatus =
2944					    (currTar_Info->
2945					     TarStatus & ~(unsigned char)
2946					     TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2947
2948					currSCCB->ControlByte &= ~F_USE_CMD_Q;
2949					CurrCard->discQCount--;
2950					CurrCard->discQ_Tbl[currSCCB->
2951							    Sccb_tag] = NULL;
2952					currSCCB->Sccb_tag = 0x00;
2953
2954				}
2955			}
2956
2957			if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2958
2959				if (currSCCB->Lun == 0x00) {
2960					WRW_HARPOON((port + hp_intstat),
2961						    BUS_FREE);
2962					CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2963				}
2964			}
2965
2966			else {
2967
2968				if ((CurrCard->globalFlags & F_CONLUN_IO) &&
2969				    ((currTar_Info->
2970				      TarStatus & TAR_TAG_Q_MASK) !=
2971				     TAG_Q_TRYING))
2972					currTar_Info->TarLUNBusy[currSCCB->
2973								 Lun] = 1;
2974				else
2975					currTar_Info->TarLUNBusy[0] = 1;
2976
2977				currSCCB->ControlByte &=
2978				    ~(unsigned char)F_USE_CMD_Q;
2979
2980				WR_HARPOON(port + hp_autostart_1,
2981					   (AUTO_IMMED + DISCONNECT_START));
2982
2983			}
2984		}
2985
2986		else {
2987			ACCEPT_MSG(port);
2988
2989			while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2990			       (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2991			{
2992			}
2993
2994			if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
2995				WR_HARPOON(port + hp_autostart_1,
2996					   (AUTO_IMMED + DISCONNECT_START));
2997			}
2998		}
2999	}
3000
3001	else if (message == EXTENDED_MESSAGE) {
3002
3003		ACCEPT_MSG(port);
3004		FPT_shandem(port, p_card, currSCCB);
3005	}
3006
3007	else if (message == IGNORE_WIDE_RESIDUE) {
3008
3009		ACCEPT_MSG(port);	/* ACK the RESIDUE MSG */
3010
3011		message = FPT_sfm(port, currSCCB);
3012
3013		if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
3014			ACCEPT_MSG(port);
3015		WR_HARPOON(port + hp_autostart_1,
3016			   (AUTO_IMMED + DISCONNECT_START));
3017	}
3018
3019	else {
3020
3021		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3022		currSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3023
3024		ACCEPT_MSG_ATN(port);
3025		WR_HARPOON(port + hp_autostart_1,
3026			   (AUTO_IMMED + DISCONNECT_START));
3027	}
3028}
3029
3030/*---------------------------------------------------------------------
3031 *
3032 * Function: FPT_shandem
3033 *
3034 * Description: Decide what to do with the extended message.
3035 *
3036 *---------------------------------------------------------------------*/
3037static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3038{
3039	unsigned char length, message;
3040
3041	length = FPT_sfm(port, pCurrSCCB);
3042	if (length) {
3043
3044		ACCEPT_MSG(port);
3045		message = FPT_sfm(port, pCurrSCCB);
3046		if (message) {
3047
3048			if (message == EXTENDED_SDTR) {
3049
3050				if (length == 0x03) {
3051
3052					ACCEPT_MSG(port);
3053					FPT_stsyncn(port, p_card);
3054				} else {
3055
3056					pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3057					ACCEPT_MSG_ATN(port);
3058				}
3059			} else if (message == EXTENDED_WDTR) {
3060
3061				if (length == 0x02) {
3062
3063					ACCEPT_MSG(port);
3064					FPT_stwidn(port, p_card);
3065				} else {
3066
3067					pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3068					ACCEPT_MSG_ATN(port);
3069
3070					WR_HARPOON(port + hp_autostart_1,
3071						   (AUTO_IMMED +
3072						    DISCONNECT_START));
3073				}
3074			} else {
3075
3076				pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3077				ACCEPT_MSG_ATN(port);
3078
3079				WR_HARPOON(port + hp_autostart_1,
3080					   (AUTO_IMMED + DISCONNECT_START));
3081			}
3082		} else {
3083			if (pCurrSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
3084				ACCEPT_MSG(port);
3085			WR_HARPOON(port + hp_autostart_1,
3086				   (AUTO_IMMED + DISCONNECT_START));
3087		}
3088	} else {
3089		if (pCurrSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)
3090			WR_HARPOON(port + hp_autostart_1,
3091				   (AUTO_IMMED + DISCONNECT_START));
3092	}
3093}
3094
3095/*---------------------------------------------------------------------
3096 *
3097 * Function: FPT_sisyncn
3098 *
3099 * Description: Read in a message byte from the SCSI bus, and check
3100 *              for a parity error.
3101 *
3102 *---------------------------------------------------------------------*/
3103
3104static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3105				 unsigned char syncFlag)
3106{
3107	struct sccb *currSCCB;
3108	struct sccb_mgr_tar_info *currTar_Info;
3109
3110	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3111	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3112
3113	if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3114
3115		WRW_HARPOON((port + ID_MSG_STRT),
3116			    (MPM_OP + AMSG_OUT +
3117			     (currSCCB->
3118			      Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3119
3120		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3121
3122		WRW_HARPOON((port + SYNC_MSGS + 0),
3123			    (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3124		WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3125		WRW_HARPOON((port + SYNC_MSGS + 4),
3126			    (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
3127
3128		if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3129
3130			WRW_HARPOON((port + SYNC_MSGS + 6),
3131				    (MPM_OP + AMSG_OUT + 12));
3132
3133		else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3134			 EE_SYNC_10MB)
3135
3136			WRW_HARPOON((port + SYNC_MSGS + 6),
3137				    (MPM_OP + AMSG_OUT + 25));
3138
3139		else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3140			 EE_SYNC_5MB)
3141
3142			WRW_HARPOON((port + SYNC_MSGS + 6),
3143				    (MPM_OP + AMSG_OUT + 50));
3144
3145		else
3146			WRW_HARPOON((port + SYNC_MSGS + 6),
3147				    (MPM_OP + AMSG_OUT + 00));
3148
3149		WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3150		WRW_HARPOON((port + SYNC_MSGS + 10),
3151			    (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3152		WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3153
3154		if (syncFlag == 0) {
3155			WR_HARPOON(port + hp_autostart_3,
3156				   (SELECT + SELCHK_STRT));
3157			currTar_Info->TarStatus =
3158			    ((currTar_Info->
3159			      TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3160			     (unsigned char)SYNC_TRYING);
3161		} else {
3162			WR_HARPOON(port + hp_autostart_3,
3163				   (AUTO_IMMED + CMD_ONLY_STRT));
3164		}
3165
3166		return 1;
3167	}
3168
3169	else {
3170
3171		currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3172		currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3173		return 0;
3174	}
3175}
3176
3177/*---------------------------------------------------------------------
3178 *
3179 * Function: FPT_stsyncn
3180 *
3181 * Description: The has sent us a Sync Nego message so handle it as
3182 *              necessary.
3183 *
3184 *---------------------------------------------------------------------*/
3185static void FPT_stsyncn(u32 port, unsigned char p_card)
3186{
3187	unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3188	struct sccb *currSCCB;
3189	struct sccb_mgr_tar_info *currTar_Info;
3190
3191	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3192	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3193
3194	sync_msg = FPT_sfm(port, currSCCB);
3195
3196	if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3197		WR_HARPOON(port + hp_autostart_1,
3198			   (AUTO_IMMED + DISCONNECT_START));
3199		return;
3200	}
3201
3202	ACCEPT_MSG(port);
3203
3204	offset = FPT_sfm(port, currSCCB);
3205
3206	if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3207		WR_HARPOON(port + hp_autostart_1,
3208			   (AUTO_IMMED + DISCONNECT_START));
3209		return;
3210	}
3211
3212	if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3213
3214		our_sync_msg = 12;	/* Setup our Message to 20mb/s */
3215
3216	else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3217
3218		our_sync_msg = 25;	/* Setup our Message to 10mb/s */
3219
3220	else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3221
3222		our_sync_msg = 50;	/* Setup our Message to 5mb/s */
3223	else
3224
3225		our_sync_msg = 0;	/* Message = Async */
3226
3227	if (sync_msg < our_sync_msg) {
3228		sync_msg = our_sync_msg;	/*if faster, then set to max. */
3229	}
3230
3231	if (offset == ASYNC)
3232		sync_msg = ASYNC;
3233
3234	if (offset > MAX_OFFSET)
3235		offset = MAX_OFFSET;
3236
3237	sync_reg = 0x00;
3238
3239	if (sync_msg > 12)
3240
3241		sync_reg = 0x20;	/* Use 10MB/s */
3242
3243	if (sync_msg > 25)
3244
3245		sync_reg = 0x40;	/* Use 6.6MB/s */
3246
3247	if (sync_msg > 38)
3248
3249		sync_reg = 0x60;	/* Use 5MB/s */
3250
3251	if (sync_msg > 50)
3252
3253		sync_reg = 0x80;	/* Use 4MB/s */
3254
3255	if (sync_msg > 62)
3256
3257		sync_reg = 0xA0;	/* Use 3.33MB/s */
3258
3259	if (sync_msg > 75)
3260
3261		sync_reg = 0xC0;	/* Use 2.85MB/s */
3262
3263	if (sync_msg > 87)
3264
3265		sync_reg = 0xE0;	/* Use 2.5MB/s */
3266
3267	if (sync_msg > 100) {
3268
3269		sync_reg = 0x00;	/* Use ASYNC */
3270		offset = 0x00;
3271	}
3272
3273	if (currTar_Info->TarStatus & WIDE_ENABLED)
3274
3275		sync_reg |= offset;
3276
3277	else
3278
3279		sync_reg |= (offset | NARROW_SCSI);
3280
3281	FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3282
3283	if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3284
3285		ACCEPT_MSG(port);
3286
3287		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3288					    ~(unsigned char)TAR_SYNC_MASK) |
3289					   (unsigned char)SYNC_SUPPORTED);
3290
3291		WR_HARPOON(port + hp_autostart_1,
3292			   (AUTO_IMMED + DISCONNECT_START));
3293	}
3294
3295	else {
3296
3297		ACCEPT_MSG_ATN(port);
3298
3299		FPT_sisyncr(port, sync_msg, offset);
3300
3301		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3302					    ~(unsigned char)TAR_SYNC_MASK) |
3303					   (unsigned char)SYNC_SUPPORTED);
3304	}
3305}
3306
3307/*---------------------------------------------------------------------
3308 *
3309 * Function: FPT_sisyncr
3310 *
3311 * Description: Answer the targets sync message.
3312 *
3313 *---------------------------------------------------------------------*/
3314static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3315			unsigned char offset)
3316{
3317	ARAM_ACCESS(port);
3318	WRW_HARPOON((port + SYNC_MSGS + 0),
3319		    (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3320	WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3321	WRW_HARPOON((port + SYNC_MSGS + 4),
3322		    (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
3323	WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3324	WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3325	WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3326	WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3327	SGRAM_ACCESS(port);
3328
3329	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3330	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3331
3332	WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3333
3334	while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3335	}
3336}
3337
3338/*---------------------------------------------------------------------
3339 *
3340 * Function: FPT_siwidn
3341 *
3342 * Description: Read in a message byte from the SCSI bus, and check
3343 *              for a parity error.
3344 *
3345 *---------------------------------------------------------------------*/
3346
3347static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3348{
3349	struct sccb *currSCCB;
3350	struct sccb_mgr_tar_info *currTar_Info;
3351
3352	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3353	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3354
3355	if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3356
3357		WRW_HARPOON((port + ID_MSG_STRT),
3358			    (MPM_OP + AMSG_OUT +
3359			     (currSCCB->
3360			      Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3361
3362		WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3363
3364		WRW_HARPOON((port + SYNC_MSGS + 0),
3365			    (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3366		WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3367		WRW_HARPOON((port + SYNC_MSGS + 4),
3368			    (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
3369		WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3370		WRW_HARPOON((port + SYNC_MSGS + 8),
3371			    (MPM_OP + AMSG_OUT + SM16BIT));
3372		WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3373
3374		WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3375
3376		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3377					    ~(unsigned char)TAR_WIDE_MASK) |
3378					   (unsigned char)WIDE_ENABLED);
3379
3380		return 1;
3381	}
3382
3383	else {
3384
3385		currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3386					    ~(unsigned char)TAR_WIDE_MASK) |
3387					   WIDE_NEGOCIATED);
3388
3389		currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3390		return 0;
3391	}
3392}
3393
3394/*---------------------------------------------------------------------
3395 *
3396 * Function: FPT_stwidn
3397 *
3398 * Description: The has sent us a Wide Nego message so handle it as
3399 *              necessary.
3400 *
3401 *---------------------------------------------------------------------*/
3402static void FPT_stwidn(u32 port, unsigned char p_card)
3403{
3404	unsigned char width;
3405	struct sccb *currSCCB;
3406	struct sccb_mgr_tar_info *currTar_Info;
3407
3408	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3409	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3410
3411	width = FPT_sfm(port, currSCCB);
3412
3413	if ((width == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3414		WR_HARPOON(port + hp_autostart_1,
3415			   (AUTO_IMMED + DISCONNECT_START));
3416		return;
3417	}
3418
3419	if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3420		width = 0;
3421
3422	if (width) {
3423		currTar_Info->TarStatus |= WIDE_ENABLED;
3424		width = 0;
3425	} else {
3426		width = NARROW_SCSI;
3427		currTar_Info->TarStatus &= ~WIDE_ENABLED;
3428	}
3429
3430	FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3431
3432	if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3433
3434		currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3435
3436		if (!
3437		    ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3438		     SYNC_SUPPORTED)) {
3439			ACCEPT_MSG_ATN(port);
3440			ARAM_ACCESS(port);
3441			FPT_sisyncn(port, p_card, 1);
3442			currSCCB->Sccb_scsistat = SELECT_SN_ST;
3443			SGRAM_ACCESS(port);
3444		} else {
3445			ACCEPT_MSG(port);
3446			WR_HARPOON(port + hp_autostart_1,
3447				   (AUTO_IMMED + DISCONNECT_START));
3448		}
3449	}
3450
3451	else {
3452
3453		ACCEPT_MSG_ATN(port);
3454
3455		if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3456			width = SM16BIT;
3457		else
3458			width = SM8BIT;
3459
3460		FPT_siwidr(port, width);
3461
3462		currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3463	}
3464}
3465
3466/*---------------------------------------------------------------------
3467 *
3468 * Function: FPT_siwidr
3469 *
3470 * Description: Answer the targets Wide nego message.
3471 *
3472 *---------------------------------------------------------------------*/
3473static void FPT_siwidr(u32 port, unsigned char width)
3474{
3475	ARAM_ACCESS(port);
3476	WRW_HARPOON((port + SYNC_MSGS + 0),
3477		    (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3478	WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3479	WRW_HARPOON((port + SYNC_MSGS + 4),
3480		    (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
3481	WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3482	WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3483	WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3484	SGRAM_ACCESS(port);
3485
3486	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3487	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3488
3489	WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3490
3491	while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3492	}
3493}
3494
3495/*---------------------------------------------------------------------
3496 *
3497 * Function: FPT_sssyncv
3498 *
3499 * Description: Write the desired value to the Sync Register for the
3500 *              ID specified.
3501 *
3502 *---------------------------------------------------------------------*/
3503static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3504			unsigned char p_sync_value,
3505			struct sccb_mgr_tar_info *currTar_Info)
3506{
3507	unsigned char index;
3508
3509	index = p_id;
3510
3511	switch (index) {
3512
3513	case 0:
3514		index = 12;	/* hp_synctarg_0 */
3515		break;
3516	case 1:
3517		index = 13;	/* hp_synctarg_1 */
3518		break;
3519	case 2:
3520		index = 14;	/* hp_synctarg_2 */
3521		break;
3522	case 3:
3523		index = 15;	/* hp_synctarg_3 */
3524		break;
3525	case 4:
3526		index = 8;	/* hp_synctarg_4 */
3527		break;
3528	case 5:
3529		index = 9;	/* hp_synctarg_5 */
3530		break;
3531	case 6:
3532		index = 10;	/* hp_synctarg_6 */
3533		break;
3534	case 7:
3535		index = 11;	/* hp_synctarg_7 */
3536		break;
3537	case 8:
3538		index = 4;	/* hp_synctarg_8 */
3539		break;
3540	case 9:
3541		index = 5;	/* hp_synctarg_9 */
3542		break;
3543	case 10:
3544		index = 6;	/* hp_synctarg_10 */
3545		break;
3546	case 11:
3547		index = 7;	/* hp_synctarg_11 */
3548		break;
3549	case 12:
3550		index = 0;	/* hp_synctarg_12 */
3551		break;
3552	case 13:
3553		index = 1;	/* hp_synctarg_13 */
3554		break;
3555	case 14:
3556		index = 2;	/* hp_synctarg_14 */
3557		break;
3558	case 15:
3559		index = 3;	/* hp_synctarg_15 */
3560
3561	}
3562
3563	WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3564
3565	currTar_Info->TarSyncCtrl = p_sync_value;
3566}
3567
3568/*---------------------------------------------------------------------
3569 *
3570 * Function: FPT_sresb
3571 *
3572 * Description: Reset the desired card's SCSI bus.
3573 *
3574 *---------------------------------------------------------------------*/
3575static void FPT_sresb(u32 port, unsigned char p_card)
3576{
3577	unsigned char scsiID, i;
3578
3579	struct sccb_mgr_tar_info *currTar_Info;
3580
3581	WR_HARPOON(port + hp_page_ctrl,
3582		   (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3583	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3584
3585	WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3586
3587	scsiID = RD_HARPOON(port + hp_seltimeout);
3588	WR_HARPOON(port + hp_seltimeout, TO_5ms);
3589	WRW_HARPOON((port + hp_intstat), TIMEOUT);
3590
3591	WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3592
3593	while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3594	}
3595
3596	WR_HARPOON(port + hp_seltimeout, scsiID);
3597
3598	WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3599
3600	FPT_Wait(port, TO_5ms);
3601
3602	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3603
3604	WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3605
3606	for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3607		currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3608
3609		if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3610			currTar_Info->TarSyncCtrl = 0;
3611			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3612		}
3613
3614		if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3615			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3616		}
3617
3618		FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3619
3620		FPT_SccbMgrTableInitTarget(p_card, scsiID);
3621	}
3622
3623	FPT_BL_Card[p_card].scanIndex = 0x00;
3624	FPT_BL_Card[p_card].currentSCCB = NULL;
3625	FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3626					     | F_NEW_SCCB_CMD);
3627	FPT_BL_Card[p_card].cmdCounter = 0x00;
3628	FPT_BL_Card[p_card].discQCount = 0x00;
3629	FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3630
3631	for (i = 0; i < QUEUE_DEPTH; i++)
3632		FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3633
3634	WR_HARPOON(port + hp_page_ctrl,
3635		   (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3636
3637}
3638
3639/*---------------------------------------------------------------------
3640 *
3641 * Function: FPT_ssenss
3642 *
3643 * Description: Setup for the Auto Sense command.
3644 *
3645 *---------------------------------------------------------------------*/
3646static void FPT_ssenss(struct sccb_card *pCurrCard)
3647{
3648	unsigned char i;
3649	struct sccb *currSCCB;
3650
3651	currSCCB = pCurrCard->currentSCCB;
3652
3653	currSCCB->Save_CdbLen = currSCCB->CdbLength;
3654
3655	for (i = 0; i < 6; i++) {
3656
3657		currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3658	}
3659
3660	currSCCB->CdbLength = SIX_BYTE_CMD;
3661	currSCCB->Cdb[0] = REQUEST_SENSE;
3662	currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0;	/*Keep LUN. */
3663	currSCCB->Cdb[2] = 0x00;
3664	currSCCB->Cdb[3] = 0x00;
3665	currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3666	currSCCB->Cdb[5] = 0x00;
3667
3668	currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3669
3670	currSCCB->Sccb_ATC = 0x00;
3671
3672	currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3673
3674	currSCCB->Sccb_XferState &= ~F_SG_XFER;
3675
3676	currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3677
3678	currSCCB->ControlByte = 0x00;
3679
3680	currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3681}
3682
3683/*---------------------------------------------------------------------
3684 *
3685 * Function: FPT_sxfrp
3686 *
3687 * Description: Transfer data into the bit bucket until the device
3688 *              decides to switch phase.
3689 *
3690 *---------------------------------------------------------------------*/
3691
3692static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3693{
3694	unsigned char curr_phz;
3695
3696	DISABLE_AUTO(p_port);
3697
3698	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3699
3700		FPT_hostDataXferAbort(p_port, p_card,
3701				      FPT_BL_Card[p_card].currentSCCB);
3702
3703	}
3704
3705	/* If the Automation handled the end of the transfer then do not
3706	   match the phase or we will get out of sync with the ISR.       */
3707
3708	if (RDW_HARPOON((p_port + hp_intstat)) &
3709	    (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3710		return;
3711
3712	WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3713
3714	curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3715
3716	WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3717
3718	WR_HARPOON(p_port + hp_scsisig, curr_phz);
3719
3720	while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3721	       (curr_phz ==
3722		(RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3723	{
3724		if (curr_phz & (unsigned char)SCSI_IOBIT) {
3725			WR_HARPOON(p_port + hp_portctrl_0,
3726				   (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3727
3728			if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3729				RD_HARPOON(p_port + hp_fifodata_0);
3730			}
3731		} else {
3732			WR_HARPOON(p_port + hp_portctrl_0,
3733				   (SCSI_PORT | HOST_PORT | HOST_WRT));
3734			if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3735				WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3736			}
3737		}
3738	}			/* End of While loop for padding data I/O phase */
3739
3740	while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3741		if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3742			break;
3743	}
3744
3745	WR_HARPOON(p_port + hp_portctrl_0,
3746		   (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3747	while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3748		RD_HARPOON(p_port + hp_fifodata_0);
3749	}
3750
3751	if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3752		WR_HARPOON(p_port + hp_autostart_0,
3753			   (AUTO_IMMED + DISCONNECT_START));
3754		while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3755		}
3756
3757		if (RDW_HARPOON((p_port + hp_intstat)) &
3758		    (ICMD_COMP | ITAR_DISC))
3759			while (!
3760			       (RDW_HARPOON((p_port + hp_intstat)) &
3761				(BUS_FREE | RSEL))) ;
3762	}
3763}
3764
3765/*---------------------------------------------------------------------
3766 *
3767 * Function: FPT_schkdd
3768 *
3769 * Description: Make sure data has been flushed from both FIFOs and abort
3770 *              the operations if necessary.
3771 *
3772 *---------------------------------------------------------------------*/
3773
3774static void FPT_schkdd(u32 port, unsigned char p_card)
3775{
3776	unsigned short TimeOutLoop;
3777	unsigned char sPhase;
3778
3779	struct sccb *currSCCB;
3780
3781	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3782
3783	if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3784	    (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3785		return;
3786	}
3787
3788	if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3789
3790		currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3791
3792		currSCCB->Sccb_XferCnt = 1;
3793
3794		currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3795		WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3796		WR_HARPOON(port + hp_xferstat, 0x00);
3797	}
3798
3799	else {
3800
3801		currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3802
3803		currSCCB->Sccb_XferCnt = 0;
3804	}
3805
3806	if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3807	    (currSCCB->HostStatus == SCCB_COMPLETE)) {
3808
3809		currSCCB->HostStatus = SCCB_PARITY_ERR;
3810		WRW_HARPOON((port + hp_intstat), PARITY);
3811	}
3812
3813	FPT_hostDataXferAbort(port, p_card, currSCCB);
3814
3815	while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3816	}
3817
3818	TimeOutLoop = 0;
3819
3820	while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3821		if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3822			return;
3823		}
3824		if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3825			break;
3826		}
3827		if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3828			return;
3829		}
3830		if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3831		    || (TimeOutLoop++ > 0x3000))
3832			break;
3833	}
3834
3835	sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3836	if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3837	    (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3838	    (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3839	    (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3840
3841		WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3842
3843		if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3844			if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3845				FPT_phaseDataIn(port, p_card);
3846			}
3847
3848			else {
3849				FPT_phaseDataOut(port, p_card);
3850			}
3851		} else {
3852			FPT_sxfrp(port, p_card);
3853			if (!(RDW_HARPOON((port + hp_intstat)) &
3854			      (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3855				WRW_HARPOON((port + hp_intstat), AUTO_INT);
3856				FPT_phaseDecode(port, p_card);
3857			}
3858		}
3859
3860	}
3861
3862	else {
3863		WR_HARPOON(port + hp_portctrl_0, 0x00);
3864	}
3865}
3866
3867/*---------------------------------------------------------------------
3868 *
3869 * Function: FPT_sinits
3870 *
3871 * Description: Setup SCCB manager fields in this SCCB.
3872 *
3873 *---------------------------------------------------------------------*/
3874
3875static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3876{
3877	struct sccb_mgr_tar_info *currTar_Info;
3878
3879	if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3880		return;
3881	}
3882	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3883
3884	p_sccb->Sccb_XferState = 0x00;
3885	p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3886
3887	if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3888	    (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3889
3890		p_sccb->Sccb_SGoffset = 0;
3891		p_sccb->Sccb_XferState = F_SG_XFER;
3892		p_sccb->Sccb_XferCnt = 0x00;
3893	}
3894
3895	if (p_sccb->DataLength == 0x00)
3896
3897		p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3898
3899	if (p_sccb->ControlByte & F_USE_CMD_Q) {
3900		if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3901			p_sccb->ControlByte &= ~F_USE_CMD_Q;
3902
3903		else
3904			currTar_Info->TarStatus |= TAG_Q_TRYING;
3905	}
3906
3907/*      For !single SCSI device in system  & device allow Disconnect
3908	or command is tag_q type then send Cmd with Disconnect Enable
3909	else send Cmd with Disconnect Disable */
3910
3911/*
3912   if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3913      (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3914      (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3915*/
3916	if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3917	    (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3918		p_sccb->Sccb_idmsg = IDENTIFY(true, p_sccb->Lun);
3919	} else {
3920		p_sccb->Sccb_idmsg = IDENTIFY(false, p_sccb->Lun);
 
 
 
 
3921	}
3922
3923	p_sccb->HostStatus = 0x00;
3924	p_sccb->TargetStatus = 0x00;
3925	p_sccb->Sccb_tag = 0x00;
3926	p_sccb->Sccb_MGRFlags = 0x00;
3927	p_sccb->Sccb_sgseg = 0x00;
3928	p_sccb->Sccb_ATC = 0x00;
3929	p_sccb->Sccb_savedATC = 0x00;
3930/*
3931   p_sccb->SccbVirtDataPtr    = 0x00;
3932   p_sccb->Sccb_forwardlink   = NULL;
3933   p_sccb->Sccb_backlink      = NULL;
3934 */
3935	p_sccb->Sccb_scsistat = BUS_FREE_ST;
3936	p_sccb->SccbStatus = SCCB_IN_PROCESS;
3937	p_sccb->Sccb_scsimsg = NOP;
3938
3939}
3940
3941/*---------------------------------------------------------------------
3942 *
3943 * Function: Phase Decode
3944 *
3945 * Description: Determine the phase and call the appropriate function.
3946 *
3947 *---------------------------------------------------------------------*/
3948
3949static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3950{
3951	unsigned char phase_ref;
3952	void (*phase) (u32, unsigned char);
3953
3954	DISABLE_AUTO(p_port);
3955
3956	phase_ref =
3957	    (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3958
3959	phase = FPT_s_PhaseTbl[phase_ref];
3960
3961	(*phase) (p_port, p_card);	/* Call the correct phase func */
3962}
3963
3964/*---------------------------------------------------------------------
3965 *
3966 * Function: Data Out Phase
3967 *
3968 * Description: Start up both the BusMaster and Xbow.
3969 *
3970 *---------------------------------------------------------------------*/
3971
3972static void FPT_phaseDataOut(u32 port, unsigned char p_card)
3973{
3974
3975	struct sccb *currSCCB;
3976
3977	currSCCB = FPT_BL_Card[p_card].currentSCCB;
3978	if (currSCCB == NULL) {
3979		return;		/* Exit if No SCCB record */
3980	}
3981
3982	currSCCB->Sccb_scsistat = DATA_OUT_ST;
3983	currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
3984
3985	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3986
3987	WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
3988
3989	WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
3990
3991	FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
3992
3993	if (currSCCB->Sccb_XferCnt == 0) {
3994
3995		if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
3996		    (currSCCB->HostStatus == SCCB_COMPLETE))
3997			currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
3998
3999		FPT_sxfrp(port, p_card);
4000		if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4001			FPT_phaseDecode(port, p_card);
4002	}
4003}
4004
4005/*---------------------------------------------------------------------
4006 *
4007 * Function: Data In Phase
4008 *
4009 * Description: Startup the BusMaster and the XBOW.
4010 *
4011 *---------------------------------------------------------------------*/
4012
4013static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4014{
4015
4016	struct sccb *currSCCB;
4017
4018	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4019
4020	if (currSCCB == NULL) {
4021		return;		/* Exit if No SCCB record */
4022	}
4023
4024	currSCCB->Sccb_scsistat = DATA_IN_ST;
4025	currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4026	currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4027
4028	WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4029
4030	WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4031
4032	WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4033
4034	FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4035
4036	if (currSCCB->Sccb_XferCnt == 0) {
4037
4038		if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4039		    (currSCCB->HostStatus == SCCB_COMPLETE))
4040			currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4041
4042		FPT_sxfrp(port, p_card);
4043		if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4044			FPT_phaseDecode(port, p_card);
4045
4046	}
4047}
4048
4049/*---------------------------------------------------------------------
4050 *
4051 * Function: Command Phase
4052 *
4053 * Description: Load the CDB into the automation and start it up.
4054 *
4055 *---------------------------------------------------------------------*/
4056
4057static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4058{
4059	struct sccb *currSCCB;
4060	u32 cdb_reg;
4061	unsigned char i;
4062
4063	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4064
4065	if (currSCCB->OperationCode == RESET_COMMAND) {
4066
4067		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4068		currSCCB->CdbLength = SIX_BYTE_CMD;
4069	}
4070
4071	WR_HARPOON(p_port + hp_scsisig, 0x00);
4072
4073	ARAM_ACCESS(p_port);
4074
4075	cdb_reg = p_port + CMD_STRT;
4076
4077	for (i = 0; i < currSCCB->CdbLength; i++) {
4078
4079		if (currSCCB->OperationCode == RESET_COMMAND)
4080
4081			WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4082
4083		else
4084			WRW_HARPOON(cdb_reg,
4085				    (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4086		cdb_reg += 2;
4087	}
4088
4089	if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4090		WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4091
4092	WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4093
4094	currSCCB->Sccb_scsistat = COMMAND_ST;
4095
4096	WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4097	SGRAM_ACCESS(p_port);
4098}
4099
4100/*---------------------------------------------------------------------
4101 *
4102 * Function: Status phase
4103 *
4104 * Description: Bring in the status and command complete message bytes
4105 *
4106 *---------------------------------------------------------------------*/
4107
4108static void FPT_phaseStatus(u32 port, unsigned char p_card)
4109{
4110	/* Start-up the automation to finish off this command and let the
4111	   isr handle the interrupt for command complete when it comes in.
4112	   We could wait here for the interrupt to be generated?
4113	 */
4114
4115	WR_HARPOON(port + hp_scsisig, 0x00);
4116
4117	WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4118}
4119
4120/*---------------------------------------------------------------------
4121 *
4122 * Function: Phase Message Out
4123 *
4124 * Description: Send out our message (if we have one) and handle whatever
4125 *              else is involed.
4126 *
4127 *---------------------------------------------------------------------*/
4128
4129static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4130{
4131	unsigned char message, scsiID;
4132	struct sccb *currSCCB;
4133	struct sccb_mgr_tar_info *currTar_Info;
4134
4135	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4136
4137	if (currSCCB != NULL) {
4138
4139		message = currSCCB->Sccb_scsimsg;
4140		scsiID = currSCCB->TargID;
4141
4142		if (message == TARGET_RESET) {
4143
4144			currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4145			currTar_Info->TarSyncCtrl = 0;
4146			FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4147
4148			if (FPT_sccbMgrTbl[p_card][scsiID].
4149			    TarEEValue & EE_SYNC_MASK) {
4150
4151				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4152				    ~TAR_SYNC_MASK;
4153
4154			}
4155
4156			if (FPT_sccbMgrTbl[p_card][scsiID].
4157			    TarEEValue & EE_WIDE_SCSI) {
4158
4159				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4160				    ~TAR_WIDE_MASK;
4161			}
4162
4163			FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4164			FPT_SccbMgrTableInitTarget(p_card, scsiID);
4165		} else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4166			currSCCB->HostStatus = SCCB_COMPLETE;
4167			if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4168			    NULL) {
4169				FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4170							      Sccb_tag] = NULL;
4171				FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4172			}
4173
4174		}
4175
4176		else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4177
4178			if (message == NOP) {
4179				currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4180
4181				FPT_ssel(port, p_card);
4182				return;
4183			}
4184		} else {
4185
4186			if (message == ABORT_TASK_SET)
4187
4188				FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4189		}
4190
4191	} else {
4192		message = ABORT_TASK_SET;
4193	}
4194
4195	WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4196
4197	WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4198
4199	WR_HARPOON(port + hp_scsidata_0, message);
4200
4201	WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4202
4203	ACCEPT_MSG(port);
4204
4205	WR_HARPOON(port + hp_portctrl_0, 0x00);
4206
4207	if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
4208	    (message == ABORT_TASK)) {
4209
4210		while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4211		}
4212
4213		if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4214			WRW_HARPOON((port + hp_intstat), BUS_FREE);
4215
4216			if (currSCCB != NULL) {
4217
4218				if ((FPT_BL_Card[p_card].
4219				     globalFlags & F_CONLUN_IO)
4220				    &&
4221				    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4222				      TarStatus & TAR_TAG_Q_MASK) !=
4223				     TAG_Q_TRYING))
4224					FPT_sccbMgrTbl[p_card][currSCCB->
4225							       TargID].
4226					    TarLUNBusy[currSCCB->Lun] = 0;
4227				else
4228					FPT_sccbMgrTbl[p_card][currSCCB->
4229							       TargID].
4230					    TarLUNBusy[0] = 0;
4231
4232				FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4233						     currSCCB, p_card);
4234			}
4235
4236			else {
4237				FPT_BL_Card[p_card].globalFlags |=
4238				    F_NEW_SCCB_CMD;
4239			}
4240		}
4241
4242		else {
4243
4244			FPT_sxfrp(port, p_card);
4245		}
4246	}
4247
4248	else {
4249
4250		if (message == MSG_PARITY_ERROR) {
4251			currSCCB->Sccb_scsimsg = NOP;
4252			WR_HARPOON(port + hp_autostart_1,
4253				   (AUTO_IMMED + DISCONNECT_START));
4254		} else {
4255			FPT_sxfrp(port, p_card);
4256		}
4257	}
4258}
4259
4260/*---------------------------------------------------------------------
4261 *
4262 * Function: Message In phase
4263 *
4264 * Description: Bring in the message and determine what to do with it.
4265 *
4266 *---------------------------------------------------------------------*/
4267
4268static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4269{
4270	unsigned char message;
4271	struct sccb *currSCCB;
4272
4273	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4274
4275	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4276
4277		FPT_phaseChkFifo(port, p_card);
4278	}
4279
4280	message = RD_HARPOON(port + hp_scsidata_0);
4281	if ((message == DISCONNECT) || (message == SAVE_POINTERS)) {
4282
4283		WR_HARPOON(port + hp_autostart_1,
4284			   (AUTO_IMMED + END_DATA_START));
4285
4286	}
4287
4288	else {
4289
4290		message = FPT_sfm(port, currSCCB);
4291		if (message) {
4292
4293			FPT_sdecm(message, port, p_card);
4294
4295		} else {
4296			if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
4297				ACCEPT_MSG(port);
4298			WR_HARPOON(port + hp_autostart_1,
4299				   (AUTO_IMMED + DISCONNECT_START));
4300		}
4301	}
4302
4303}
4304
4305/*---------------------------------------------------------------------
4306 *
4307 * Function: Illegal phase
4308 *
4309 * Description: Target switched to some illegal phase, so all we can do
4310 *              is report an error back to the host (if that is possible)
4311 *              and send an ABORT message to the misbehaving target.
4312 *
4313 *---------------------------------------------------------------------*/
4314
4315static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4316{
4317	struct sccb *currSCCB;
4318
4319	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4320
4321	WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4322	if (currSCCB != NULL) {
4323
4324		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4325		currSCCB->Sccb_scsistat = ABORT_ST;
4326		currSCCB->Sccb_scsimsg = ABORT_TASK_SET;
4327	}
4328
4329	ACCEPT_MSG_ATN(port);
4330}
4331
4332/*---------------------------------------------------------------------
4333 *
4334 * Function: Phase Check FIFO
4335 *
4336 * Description: Make sure data has been flushed from both FIFOs and abort
4337 *              the operations if necessary.
4338 *
4339 *---------------------------------------------------------------------*/
4340
4341static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4342{
4343	u32 xfercnt;
4344	struct sccb *currSCCB;
4345
4346	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4347
4348	if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4349
4350		while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4351		       (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4352		}
4353
4354		if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4355			currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4356
4357			currSCCB->Sccb_XferCnt = 0;
4358
4359			if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4360			    (currSCCB->HostStatus == SCCB_COMPLETE)) {
4361				currSCCB->HostStatus = SCCB_PARITY_ERR;
4362				WRW_HARPOON((port + hp_intstat), PARITY);
4363			}
4364
4365			FPT_hostDataXferAbort(port, p_card, currSCCB);
4366
4367			FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4368
4369			while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4370			       && (RD_HARPOON(port + hp_ext_status) &
4371				   BM_CMD_BUSY)) {
4372			}
4373
4374		}
4375	}
4376
4377	/*End Data In specific code. */
4378	GET_XFER_CNT(port, xfercnt);
4379
4380	WR_HARPOON(port + hp_xfercnt_0, 0x00);
4381
4382	WR_HARPOON(port + hp_portctrl_0, 0x00);
4383
4384	currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4385
4386	currSCCB->Sccb_XferCnt = xfercnt;
4387
4388	if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4389	    (currSCCB->HostStatus == SCCB_COMPLETE)) {
4390
4391		currSCCB->HostStatus = SCCB_PARITY_ERR;
4392		WRW_HARPOON((port + hp_intstat), PARITY);
4393	}
4394
4395	FPT_hostDataXferAbort(port, p_card, currSCCB);
4396
4397	WR_HARPOON(port + hp_fifowrite, 0x00);
4398	WR_HARPOON(port + hp_fiforead, 0x00);
4399	WR_HARPOON(port + hp_xferstat, 0x00);
4400
4401	WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4402}
4403
4404/*---------------------------------------------------------------------
4405 *
4406 * Function: Phase Bus Free
4407 *
4408 * Description: We just went bus free so figure out if it was
4409 *              because of command complete or from a disconnect.
4410 *
4411 *---------------------------------------------------------------------*/
4412static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4413{
4414	struct sccb *currSCCB;
4415
4416	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4417
4418	if (currSCCB != NULL) {
4419
4420		DISABLE_AUTO(port);
4421
4422		if (currSCCB->OperationCode == RESET_COMMAND) {
4423
4424			if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4425			    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4426			      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4427				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4428				    TarLUNBusy[currSCCB->Lun] = 0;
4429			else
4430				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4431				    TarLUNBusy[0] = 0;
4432
4433			FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4434					     p_card);
4435
4436			FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4437
4438		}
4439
4440		else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4441			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4442			    (unsigned char)SYNC_SUPPORTED;
4443			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4444			    ~EE_SYNC_MASK;
4445		}
4446
4447		else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4448			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4449			    (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4450			     TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4451
4452			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4453			    ~EE_WIDE_SCSI;
4454		}
4455
4456		else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4457			/* Make sure this is not a phony BUS_FREE.  If we were
4458			   reselected or if BUSY is NOT on then this is a
4459			   valid BUS FREE.  SRR Wednesday, 5/10/1995.     */
4460
4461			if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4462			    (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4463				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4464				    TarStatus &= ~TAR_TAG_Q_MASK;
4465				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4466				    TarStatus |= TAG_Q_REJECT;
4467			}
4468
4469			else {
4470				return;
4471			}
4472		}
4473
4474		else {
4475
4476			currSCCB->Sccb_scsistat = BUS_FREE_ST;
4477
4478			if (!currSCCB->HostStatus) {
4479				currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4480			}
4481
4482			if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4483			    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4484			      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4485				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4486				    TarLUNBusy[currSCCB->Lun] = 0;
4487			else
4488				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4489				    TarLUNBusy[0] = 0;
4490
4491			FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4492					     p_card);
4493			return;
4494		}
4495
4496		FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4497
4498	}			/*end if !=null */
4499}
4500
4501/*---------------------------------------------------------------------
4502 *
4503 * Function: Auto Load Default Map
4504 *
4505 * Description: Load the Automation RAM with the default map values.
4506 *
4507 *---------------------------------------------------------------------*/
4508static void FPT_autoLoadDefaultMap(u32 p_port)
4509{
4510	u32 map_addr;
4511
4512	ARAM_ACCESS(p_port);
4513	map_addr = p_port + hp_aramBase;
4514
4515	WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0));	/*ID MESSAGE */
4516	map_addr += 2;
4517	WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20));	/*SIMPLE TAG QUEUEING MSG */
4518	map_addr += 2;
4519	WRW_HARPOON(map_addr, RAT_OP);	/*RESET ATTENTION */
4520	map_addr += 2;
4521	WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00));	/*TAG ID MSG */
4522	map_addr += 2;
4523	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 0 */
4524	map_addr += 2;
4525	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 1 */
4526	map_addr += 2;
4527	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 2 */
4528	map_addr += 2;
4529	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 3 */
4530	map_addr += 2;
4531	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 4 */
4532	map_addr += 2;
4533	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 5 */
4534	map_addr += 2;
4535	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 6 */
4536	map_addr += 2;
4537	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 7 */
4538	map_addr += 2;
4539	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 8 */
4540	map_addr += 2;
4541	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 9 */
4542	map_addr += 2;
4543	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 10 */
4544	map_addr += 2;
4545	WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00));	/*CDB BYTE 11 */
4546	map_addr += 2;
4547	WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT));	/*JUMP IF DATA OUT */
4548	map_addr += 2;
4549	WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI));	/*JUMP IF NO DATA IN FIFO */
4550	map_addr += 2;		/*This means AYNC DATA IN */
4551	WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT));	/*STOP AND INTERRUPT */
4552	map_addr += 2;
4553	WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT));	/*JUMP IF NOT DATA IN PHZ */
4554	map_addr += 2;
4555	WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST));	/*IF NOT MSG IN CHECK 4 DATA IN */
4556	map_addr += 2;
4557	WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02));	/*SAVE DATA PTR MSG? */
4558	map_addr += 2;
4559	WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC));	/*GO CHECK FOR DISCONNECT MSG */
4560	map_addr += 2;
4561	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1));	/*SAVE DATA PTRS MSG */
4562	map_addr += 2;
4563	WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST));	/*IF NOT MSG IN CHECK DATA IN */
4564	map_addr += 2;
4565	WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04));	/*DISCONNECT MSG? */
4566	map_addr += 2;
4567	WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN));	/*UKNKNOWN MSG */
4568	map_addr += 2;
4569	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET));	/*XFER DISCONNECT MSG */
4570	map_addr += 2;
4571	WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC));	/*STOP AND INTERRUPT */
4572	map_addr += 2;
4573	WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN));	/*JUMP IF NOT STATUS PHZ. */
4574	map_addr += 2;
4575	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0));	/*GET STATUS BYTE */
4576	map_addr += 2;
4577	WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC));	/*ERROR IF NOT MSG IN PHZ */
4578	map_addr += 2;
4579	WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00));	/*CHECK FOR CMD COMPLETE MSG. */
4580	map_addr += 2;
4581	WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC));	/*ERROR IF NOT CMD COMPLETE MSG. */
4582	map_addr += 2;
4583	WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET));	/*GET CMD COMPLETE MSG */
4584	map_addr += 2;
4585	WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP));	/*END OF COMMAND */
4586	map_addr += 2;
4587
4588	WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN));	/*RECEIVED UNKNOWN MSG BYTE */
4589	map_addr += 2;
4590	WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC));	/*NO COMMAND COMPLETE AFTER STATUS */
4591	map_addr += 2;
4592	WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE));	/*BIOS Tickled the Mgr */
4593	map_addr += 2;
4594	WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL));	/*EXPECTED ID/TAG MESSAGES AND */
4595	map_addr += 2;		/* DIDN'T GET ONE */
4596	WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG));	/* comp SCSI SEL ID & AR3 */
4597	map_addr += 2;
4598	WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00));	/*SEL ID OK then Conti. */
4599	map_addr += 2;
4600	WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC));	/*NO COMMAND COMPLETE AFTER STATUS */
4601
4602	SGRAM_ACCESS(p_port);
4603}
4604
4605/*---------------------------------------------------------------------
4606 *
4607 * Function: Auto Command Complete
4608 *
4609 * Description: Post command back to host and find another command
4610 *              to execute.
4611 *
4612 *---------------------------------------------------------------------*/
4613
4614static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4615{
4616	struct sccb *currSCCB;
4617	unsigned char status_byte;
4618
4619	currSCCB = FPT_BL_Card[p_card].currentSCCB;
4620
4621	status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4622
4623	FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4624
4625	if (status_byte != SAM_STAT_GOOD) {
4626
4627		if (status_byte == SAM_STAT_TASK_SET_FULL) {
4628
4629			if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4630			     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4631			       TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4632				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4633				    TarLUNBusy[currSCCB->Lun] = 1;
4634				if (FPT_BL_Card[p_card].discQCount != 0)
4635					FPT_BL_Card[p_card].discQCount--;
4636				FPT_BL_Card[p_card].
4637				    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4638					      [currSCCB->TargID].
4639					      LunDiscQ_Idx[currSCCB->Lun]] =
4640				    NULL;
4641			} else {
4642				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4643				    TarLUNBusy[0] = 1;
4644				if (currSCCB->Sccb_tag) {
4645					if (FPT_BL_Card[p_card].discQCount != 0)
4646						FPT_BL_Card[p_card].
4647						    discQCount--;
4648					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4649								      Sccb_tag]
4650					    = NULL;
4651				} else {
4652					if (FPT_BL_Card[p_card].discQCount != 0)
4653						FPT_BL_Card[p_card].
4654						    discQCount--;
4655					FPT_BL_Card[p_card].
4656					    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4657						      [currSCCB->TargID].
4658						      LunDiscQ_Idx[0]] = NULL;
4659				}
4660			}
4661
4662			currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4663
4664			FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4665
4666			return;
4667		}
4668
4669		if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4670			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4671			    (unsigned char)SYNC_SUPPORTED;
4672
4673			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4674			    ~EE_SYNC_MASK;
4675			FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4676
4677			if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4678			     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4679			       TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4680				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4681				    TarLUNBusy[currSCCB->Lun] = 1;
4682				if (FPT_BL_Card[p_card].discQCount != 0)
4683					FPT_BL_Card[p_card].discQCount--;
4684				FPT_BL_Card[p_card].
4685				    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4686					      [currSCCB->TargID].
4687					      LunDiscQ_Idx[currSCCB->Lun]] =
4688				    NULL;
4689			} else {
4690				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4691				    TarLUNBusy[0] = 1;
4692				if (currSCCB->Sccb_tag) {
4693					if (FPT_BL_Card[p_card].discQCount != 0)
4694						FPT_BL_Card[p_card].
4695						    discQCount--;
4696					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4697								      Sccb_tag]
4698					    = NULL;
4699				} else {
4700					if (FPT_BL_Card[p_card].discQCount != 0)
4701						FPT_BL_Card[p_card].
4702						    discQCount--;
4703					FPT_BL_Card[p_card].
4704					    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4705						      [currSCCB->TargID].
4706						      LunDiscQ_Idx[0]] = NULL;
4707				}
4708			}
4709			return;
4710
4711		}
4712
4713		if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4714
4715			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4716			    (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4717			     TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4718
4719			FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4720			    ~EE_WIDE_SCSI;
4721			FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4722
4723			if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4724			     ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4725			       TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4726				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4727				    TarLUNBusy[currSCCB->Lun] = 1;
4728				if (FPT_BL_Card[p_card].discQCount != 0)
4729					FPT_BL_Card[p_card].discQCount--;
4730				FPT_BL_Card[p_card].
4731				    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4732					      [currSCCB->TargID].
4733					      LunDiscQ_Idx[currSCCB->Lun]] =
4734				    NULL;
4735			} else {
4736				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4737				    TarLUNBusy[0] = 1;
4738				if (currSCCB->Sccb_tag) {
4739					if (FPT_BL_Card[p_card].discQCount != 0)
4740						FPT_BL_Card[p_card].
4741						    discQCount--;
4742					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4743								      Sccb_tag]
4744					    = NULL;
4745				} else {
4746					if (FPT_BL_Card[p_card].discQCount != 0)
4747						FPT_BL_Card[p_card].
4748						    discQCount--;
4749					FPT_BL_Card[p_card].
4750					    discQ_Tbl[FPT_sccbMgrTbl[p_card]
4751						      [currSCCB->TargID].
4752						      LunDiscQ_Idx[0]] = NULL;
4753				}
4754			}
4755			return;
4756
4757		}
4758
4759		if (status_byte == SAM_STAT_CHECK_CONDITION) {
4760			if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4761				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4762				    TarEEValue & EE_SYNC_MASK) {
4763					FPT_sccbMgrTbl[p_card][currSCCB->
4764							       TargID].
4765					    TarStatus &= ~TAR_SYNC_MASK;
4766				}
4767				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4768				    TarEEValue & EE_WIDE_SCSI) {
4769					FPT_sccbMgrTbl[p_card][currSCCB->
4770							       TargID].
4771					    TarStatus &= ~TAR_WIDE_MASK;
4772				}
4773			}
4774		}
4775
4776		if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4777
4778			currSCCB->SccbStatus = SCCB_ERROR;
4779			currSCCB->TargetStatus = status_byte;
4780
4781			if (status_byte == SAM_STAT_CHECK_CONDITION) {
4782
4783				FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4784				    TarLUN_CA = 1;
4785
4786				if (currSCCB->RequestSenseLength !=
4787				    NO_AUTO_REQUEST_SENSE) {
4788
4789					if (currSCCB->RequestSenseLength == 0)
4790						currSCCB->RequestSenseLength =
4791						    14;
4792
4793					FPT_ssenss(&FPT_BL_Card[p_card]);
4794					FPT_BL_Card[p_card].globalFlags |=
4795					    F_NEW_SCCB_CMD;
4796
4797					if (((FPT_BL_Card[p_card].
4798					      globalFlags & F_CONLUN_IO)
4799					     &&
4800					     ((FPT_sccbMgrTbl[p_card]
4801					       [currSCCB->TargID].
4802					       TarStatus & TAR_TAG_Q_MASK) !=
4803					      TAG_Q_TRYING))) {
4804						FPT_sccbMgrTbl[p_card]
4805						    [currSCCB->TargID].
4806						    TarLUNBusy[currSCCB->Lun] =
4807						    1;
4808						if (FPT_BL_Card[p_card].
4809						    discQCount != 0)
4810							FPT_BL_Card[p_card].
4811							    discQCount--;
4812						FPT_BL_Card[p_card].
4813						    discQ_Tbl[FPT_sccbMgrTbl
4814							      [p_card]
4815							      [currSCCB->
4816							       TargID].
4817							      LunDiscQ_Idx
4818							      [currSCCB->Lun]] =
4819						    NULL;
4820					} else {
4821						FPT_sccbMgrTbl[p_card]
4822						    [currSCCB->TargID].
4823						    TarLUNBusy[0] = 1;
4824						if (currSCCB->Sccb_tag) {
4825							if (FPT_BL_Card[p_card].
4826							    discQCount != 0)
4827								FPT_BL_Card
4828								    [p_card].
4829								    discQCount--;
4830							FPT_BL_Card[p_card].
4831							    discQ_Tbl[currSCCB->
4832								      Sccb_tag]
4833							    = NULL;
4834						} else {
4835							if (FPT_BL_Card[p_card].
4836							    discQCount != 0)
4837								FPT_BL_Card
4838								    [p_card].
4839								    discQCount--;
4840							FPT_BL_Card[p_card].
4841							    discQ_Tbl
4842							    [FPT_sccbMgrTbl
4843							     [p_card][currSCCB->
4844								      TargID].
4845							     LunDiscQ_Idx[0]] =
4846							    NULL;
4847						}
4848					}
4849					return;
4850				}
4851			}
4852		}
4853	}
4854
4855	if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4856	    ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4857	      TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4858		FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4859								    Lun] = 0;
4860	else
4861		FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4862
4863	FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4864}
4865
4866#define SHORT_WAIT   0x0000000F
4867#define LONG_WAIT    0x0000FFFFL
4868
4869/*---------------------------------------------------------------------
4870 *
4871 * Function: Data Transfer Processor
4872 *
4873 * Description: This routine performs two tasks.
4874 *              (1) Start data transfer by calling HOST_DATA_XFER_START
4875 *              function.  Once data transfer is started, (2) Depends
4876 *              on the type of data transfer mode Scatter/Gather mode
4877 *              or NON Scatter/Gather mode.  In NON Scatter/Gather mode,
4878 *              this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4879 *              data transfer done.  In Scatter/Gather mode, this routine
4880 *              checks bus master command complete and dual rank busy
4881 *              bit to keep chaining SC transfer command.  Similarly,
4882 *              in Scatter/Gather mode, it checks Sccb_MGRFlag
4883 *              (F_HOST_XFER_ACT bit) for data transfer done.
4884 *              
4885 *---------------------------------------------------------------------*/
4886
4887static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4888{
4889	struct sccb *currSCCB;
4890
4891	currSCCB = pCurrCard->currentSCCB;
4892
4893	if (currSCCB->Sccb_XferState & F_SG_XFER) {
4894		if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4895		{
4896			currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4897			currSCCB->Sccb_SGoffset = 0x00;
4898		}
4899		pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4900
4901		FPT_busMstrSGDataXferStart(port, currSCCB);
4902	}
4903
4904	else {
4905		if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4906			pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4907
4908			FPT_busMstrDataXferStart(port, currSCCB);
4909		}
4910	}
4911}
4912
4913/*---------------------------------------------------------------------
4914 *
4915 * Function: BusMaster Scatter Gather Data Transfer Start
4916 *
4917 * Description:
4918 *
4919 *---------------------------------------------------------------------*/
4920static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4921{
4922	u32 count, addr, tmpSGCnt;
4923	unsigned int sg_index;
4924	unsigned char sg_count, i;
4925	u32 reg_offset;
4926	struct blogic_sg_seg *segp;
4927
4928	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4929		count = ((u32)HOST_RD_CMD) << 24;
4930	else
4931		count = ((u32)HOST_WRT_CMD) << 24;
4932
4933	sg_count = 0;
4934	tmpSGCnt = 0;
4935	sg_index = pcurrSCCB->Sccb_sgseg;
4936	reg_offset = hp_aramBase;
4937
4938	i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4939			    ~(SGRAM_ARAM | SCATTER_EN));
4940
4941	WR_HARPOON(p_port + hp_page_ctrl, i);
4942
4943	while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4944			((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4945			pcurrSCCB->DataLength)) {
4946
4947		segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4948				sg_index;
4949		tmpSGCnt += segp->segbytes;
4950		count |= segp->segbytes;
4951		addr = segp->segdata;
4952
4953		if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4954			addr +=
4955			    ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4956			count =
4957			    (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4958			tmpSGCnt = count & 0x00FFFFFFL;
4959		}
4960
4961		WR_HARP32(p_port, reg_offset, addr);
4962		reg_offset += 4;
4963
4964		WR_HARP32(p_port, reg_offset, count);
4965		reg_offset += 4;
4966
4967		count &= 0xFF000000L;
4968		sg_index++;
4969		sg_count++;
4970
4971	}			/*End While */
4972
4973	pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
4974
4975	WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
4976
4977	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4978
4979		WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
4980
4981		WR_HARPOON(p_port + hp_portctrl_0,
4982			   (DMA_PORT | SCSI_PORT | SCSI_INBIT));
4983		WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
4984	}
4985
4986	else {
4987
4988		if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
4989		    (tmpSGCnt & 0x000000001)) {
4990
4991			pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
4992			tmpSGCnt--;
4993		}
4994
4995		WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
4996
4997		WR_HARPOON(p_port + hp_portctrl_0,
4998			   (SCSI_PORT | DMA_PORT | DMA_RD));
4999		WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5000	}
5001
5002	WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5003
5004}
5005
5006/*---------------------------------------------------------------------
5007 *
5008 * Function: BusMaster Data Transfer Start
5009 *
5010 * Description: 
5011 *
5012 *---------------------------------------------------------------------*/
5013static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5014{
5015	u32 addr, count;
5016
5017	if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5018
5019		count = pcurrSCCB->Sccb_XferCnt;
5020
5021		addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5022	}
5023
5024	else {
5025		addr = pcurrSCCB->SensePointer;
5026		count = pcurrSCCB->RequestSenseLength;
5027
5028	}
5029
5030	HP_SETUP_ADDR_CNT(p_port, addr, count);
5031
5032	if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5033
5034		WR_HARPOON(p_port + hp_portctrl_0,
5035			   (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5036		WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5037
5038		WR_HARPOON(p_port + hp_xfer_cmd,
5039			   (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5040	}
5041
5042	else {
5043
5044		WR_HARPOON(p_port + hp_portctrl_0,
5045			   (SCSI_PORT | DMA_PORT | DMA_RD));
5046		WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5047
5048		WR_HARPOON(p_port + hp_xfer_cmd,
5049			   (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5050
5051	}
5052}
5053
5054/*---------------------------------------------------------------------
5055 *
5056 * Function: BusMaster Timeout Handler
5057 *
5058 * Description: This function is called after a bus master command busy time
5059 *               out is detected.  This routines issue halt state machine
5060 *               with a software time out for command busy.  If command busy
5061 *               is still asserted at the end of the time out, it issues
5062 *               hard abort with another software time out.  It hard abort
5063 *               command busy is also time out, it'll just give up.
5064 *
5065 *---------------------------------------------------------------------*/
5066static unsigned char FPT_busMstrTimeOut(u32 p_port)
5067{
5068	unsigned long timeout;
5069
5070	timeout = LONG_WAIT;
5071
5072	WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5073
5074	while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5075	       && timeout--) {
5076	}
5077
5078	if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5079		WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5080
5081		timeout = LONG_WAIT;
5082		while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5083		       && timeout--) {
5084		}
5085	}
5086
5087	RD_HARPOON(p_port + hp_int_status);	/*Clear command complete */
5088
5089	if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5090		return 1;
5091	}
5092
5093	else {
5094		return 0;
5095	}
5096}
5097
5098/*---------------------------------------------------------------------
5099 *
5100 * Function: Host Data Transfer Abort
5101 *
5102 * Description: Abort any in progress transfer.
5103 *
5104 *---------------------------------------------------------------------*/
5105static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5106				  struct sccb *pCurrSCCB)
5107{
5108
5109	unsigned long timeout;
5110	unsigned long remain_cnt;
5111	u32 sg_ptr;
5112	struct blogic_sg_seg *segp;
5113
5114	FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5115
5116	if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5117
5118		if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5119
5120			WR_HARPOON(port + hp_bm_ctrl,
5121				   (RD_HARPOON(port + hp_bm_ctrl) |
5122				    FLUSH_XFER_CNTR));
5123			timeout = LONG_WAIT;
5124
5125			while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5126			       && timeout--) {
5127			}
5128
5129			WR_HARPOON(port + hp_bm_ctrl,
5130				   (RD_HARPOON(port + hp_bm_ctrl) &
5131				    ~FLUSH_XFER_CNTR));
5132
5133			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5134
5135				if (FPT_busMstrTimeOut(port)) {
5136
5137					if (pCurrSCCB->HostStatus == 0x00)
5138
5139						pCurrSCCB->HostStatus =
5140						    SCCB_BM_ERR;
5141
5142				}
5143
5144				if (RD_HARPOON(port + hp_int_status) &
5145				    INT_EXT_STATUS)
5146
5147					if (RD_HARPOON(port + hp_ext_status) &
5148					    BAD_EXT_STATUS)
5149
5150						if (pCurrSCCB->HostStatus ==
5151						    0x00)
5152						{
5153							pCurrSCCB->HostStatus =
5154							    SCCB_BM_ERR;
5155						}
5156			}
5157		}
5158	}
5159
5160	else if (pCurrSCCB->Sccb_XferCnt) {
5161
5162		if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5163
5164			WR_HARPOON(port + hp_page_ctrl,
5165				   (RD_HARPOON(port + hp_page_ctrl) &
5166				    ~SCATTER_EN));
5167
5168			WR_HARPOON(port + hp_sg_addr, 0x00);
5169
5170			sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5171
5172			if (sg_ptr >
5173			    (unsigned int)(pCurrSCCB->DataLength /
5174					   SG_ELEMENT_SIZE)) {
5175
5176				sg_ptr = (u32)(pCurrSCCB->DataLength /
5177							SG_ELEMENT_SIZE);
5178			}
5179
5180			remain_cnt = pCurrSCCB->Sccb_XferCnt;
5181
5182			while (remain_cnt < 0x01000000L) {
5183
5184				sg_ptr--;
5185				segp = (struct blogic_sg_seg *)(pCurrSCCB->
5186						DataPointer) + (sg_ptr * 2);
5187				if (remain_cnt > (unsigned long)segp->segbytes)
5188					remain_cnt -=
5189						(unsigned long)segp->segbytes;
5190				else
5191					break;
5192			}
5193
5194			if (remain_cnt < 0x01000000L) {
5195
5196				pCurrSCCB->Sccb_SGoffset = remain_cnt;
5197
5198				pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5199
5200				if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5201				    pCurrSCCB->DataLength && (remain_cnt == 0))
5202
5203					pCurrSCCB->Sccb_XferState |=
5204					    F_ALL_XFERRED;
5205			}
5206
5207			else {
5208
5209				if (pCurrSCCB->HostStatus == 0x00) {
5210
5211					pCurrSCCB->HostStatus =
5212					    SCCB_GROSS_FW_ERR;
5213				}
5214			}
5215		}
5216
5217		if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5218
5219			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5220
5221				FPT_busMstrTimeOut(port);
5222			}
5223
5224			else {
5225
5226				if (RD_HARPOON(port + hp_int_status) &
5227				    INT_EXT_STATUS) {
5228
5229					if (RD_HARPOON(port + hp_ext_status) &
5230					    BAD_EXT_STATUS) {
5231
5232						if (pCurrSCCB->HostStatus ==
5233						    0x00) {
5234
5235							pCurrSCCB->HostStatus =
5236							    SCCB_BM_ERR;
5237						}
5238					}
5239				}
5240
5241			}
5242		}
5243
5244		else {
5245
5246			if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5247
5248				timeout = SHORT_WAIT;
5249
5250				while ((RD_HARPOON(port + hp_ext_status) &
5251					BM_CMD_BUSY)
5252				       && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5253					   BM_THRESHOLD) && timeout--) {
5254				}
5255			}
5256
5257			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5258
5259				WR_HARPOON(port + hp_bm_ctrl,
5260					   (RD_HARPOON(port + hp_bm_ctrl) |
5261					    FLUSH_XFER_CNTR));
5262
5263				timeout = LONG_WAIT;
5264
5265				while ((RD_HARPOON(port + hp_ext_status) &
5266					BM_CMD_BUSY) && timeout--) {
5267				}
5268
5269				WR_HARPOON(port + hp_bm_ctrl,
5270					   (RD_HARPOON(port + hp_bm_ctrl) &
5271					    ~FLUSH_XFER_CNTR));
5272
5273				if (RD_HARPOON(port + hp_ext_status) &
5274				    BM_CMD_BUSY) {
5275
5276					if (pCurrSCCB->HostStatus == 0x00) {
5277
5278						pCurrSCCB->HostStatus =
5279						    SCCB_BM_ERR;
5280					}
5281
5282					FPT_busMstrTimeOut(port);
5283				}
5284			}
5285
5286			if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5287
5288				if (RD_HARPOON(port + hp_ext_status) &
5289				    BAD_EXT_STATUS) {
5290
5291					if (pCurrSCCB->HostStatus == 0x00) {
5292
5293						pCurrSCCB->HostStatus =
5294						    SCCB_BM_ERR;
5295					}
5296				}
5297			}
5298		}
5299
5300	}
5301
5302	else {
5303
5304		if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5305
5306			timeout = LONG_WAIT;
5307
5308			while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5309			       && timeout--) {
5310			}
5311
5312			if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5313
5314				if (pCurrSCCB->HostStatus == 0x00) {
5315
5316					pCurrSCCB->HostStatus = SCCB_BM_ERR;
5317				}
5318
5319				FPT_busMstrTimeOut(port);
5320			}
5321		}
5322
5323		if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5324
5325			if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5326
5327				if (pCurrSCCB->HostStatus == 0x00) {
5328
5329					pCurrSCCB->HostStatus = SCCB_BM_ERR;
5330				}
5331			}
5332
5333		}
5334
5335		if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5336
5337			WR_HARPOON(port + hp_page_ctrl,
5338				   (RD_HARPOON(port + hp_page_ctrl) &
5339				    ~SCATTER_EN));
5340
5341			WR_HARPOON(port + hp_sg_addr, 0x00);
5342
5343			pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5344
5345			pCurrSCCB->Sccb_SGoffset = 0x00;
5346
5347			if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5348					pCurrSCCB->DataLength) {
5349
5350				pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5351				pCurrSCCB->Sccb_sgseg =
5352				    (unsigned short)(pCurrSCCB->DataLength /
5353						     SG_ELEMENT_SIZE);
5354			}
5355		}
5356
5357		else {
5358			if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5359				pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5360		}
5361	}
5362
5363	WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5364}
5365
5366/*---------------------------------------------------------------------
5367 *
5368 * Function: Host Data Transfer Restart
5369 *
5370 * Description: Reset the available count due to a restore data
5371 *              pointers message.
5372 *
5373 *---------------------------------------------------------------------*/
5374static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5375{
5376	unsigned long data_count;
5377	unsigned int sg_index;
5378	struct blogic_sg_seg *segp;
5379
5380	if (currSCCB->Sccb_XferState & F_SG_XFER) {
5381
5382		currSCCB->Sccb_XferCnt = 0;
5383
5384		sg_index = 0xffff;	/*Index by long words into sg list. */
5385		data_count = 0;		/*Running count of SG xfer counts. */
5386
5387
5388		while (data_count < currSCCB->Sccb_ATC) {
5389
5390			sg_index++;
5391			segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5392						(sg_index * 2);
5393			data_count += segp->segbytes;
5394		}
5395
5396		if (data_count == currSCCB->Sccb_ATC) {
5397
5398			currSCCB->Sccb_SGoffset = 0;
5399			sg_index++;
5400		}
5401
5402		else {
5403			currSCCB->Sccb_SGoffset =
5404			    data_count - currSCCB->Sccb_ATC;
5405		}
5406
5407		currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5408	}
5409
5410	else {
5411		currSCCB->Sccb_XferCnt =
5412		    currSCCB->DataLength - currSCCB->Sccb_ATC;
5413	}
5414}
5415
5416/*---------------------------------------------------------------------
5417 *
5418 * Function: FPT_scini
5419 *
5420 * Description: Setup all data structures necessary for SCAM selection.
5421 *
5422 *---------------------------------------------------------------------*/
5423
5424static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5425		      unsigned char p_power_up)
5426{
5427
5428	unsigned char loser, assigned_id;
5429	u32 p_port;
5430
5431	unsigned char i, k, ScamFlg;
5432	struct sccb_card *currCard;
5433	struct nvram_info *pCurrNvRam;
5434
5435	currCard = &FPT_BL_Card[p_card];
5436	p_port = currCard->ioPort;
5437	pCurrNvRam = currCard->pNvRamInfo;
5438
5439	if (pCurrNvRam) {
5440		ScamFlg = pCurrNvRam->niScamConf;
5441		i = pCurrNvRam->niSysConf;
5442	} else {
5443		ScamFlg =
5444		    (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5445		i = (unsigned
5446		     char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5447	}
5448	if (!(i & 0x02))	/* check if reset bus in AutoSCSI parameter set */
5449		return;
5450
5451	FPT_inisci(p_card, p_port, p_our_id);
5452
5453	/* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5454	   too slow to return to SCAM selection */
5455
5456	/* if (p_power_up)
5457	   FPT_Wait1Second(p_port);
5458	   else
5459	   FPT_Wait(p_port, TO_250ms); */
5460
5461	FPT_Wait1Second(p_port);
5462
5463	if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5464		while (!(FPT_scarb(p_port, INIT_SELTD))) {
5465		}
5466
5467		FPT_scsel(p_port);
5468
5469		do {
5470			FPT_scxferc(p_port, SYNC_PTRN);
5471			FPT_scxferc(p_port, DOM_MSTR);
5472			loser =
5473			    FPT_scsendi(p_port,
5474					&FPT_scamInfo[p_our_id].id_string[0]);
5475		} while (loser == 0xFF);
5476
5477		FPT_scbusf(p_port);
5478
5479		if ((p_power_up) && (!loser)) {
5480			FPT_sresb(p_port, p_card);
5481			FPT_Wait(p_port, TO_250ms);
5482
5483			while (!(FPT_scarb(p_port, INIT_SELTD))) {
5484			}
5485
5486			FPT_scsel(p_port);
5487
5488			do {
5489				FPT_scxferc(p_port, SYNC_PTRN);
5490				FPT_scxferc(p_port, DOM_MSTR);
5491				loser =
5492				    FPT_scsendi(p_port,
5493						&FPT_scamInfo[p_our_id].
5494						id_string[0]);
5495			} while (loser == 0xFF);
5496
5497			FPT_scbusf(p_port);
5498		}
5499	}
5500
5501	else {
5502		loser = 0;
5503	}
5504
5505	if (!loser) {
5506
5507		FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5508
5509		if (ScamFlg & SCAM_ENABLED) {
5510
5511			for (i = 0; i < MAX_SCSI_TAR; i++) {
5512				if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5513				    (FPT_scamInfo[i].state == ID_UNUSED)) {
5514					if (FPT_scsell(p_port, i)) {
5515						FPT_scamInfo[i].state = LEGACY;
5516						if ((FPT_scamInfo[i].
5517						     id_string[0] != 0xFF)
5518						    || (FPT_scamInfo[i].
5519							id_string[1] != 0xFA)) {
5520
5521							FPT_scamInfo[i].
5522							    id_string[0] = 0xFF;
5523							FPT_scamInfo[i].
5524							    id_string[1] = 0xFA;
5525							if (pCurrNvRam == NULL)
5526								currCard->
5527								    globalFlags
5528								    |=
5529								    F_UPDATE_EEPROM;
5530						}
5531					}
5532				}
5533			}
5534
5535			FPT_sresb(p_port, p_card);
5536			FPT_Wait1Second(p_port);
5537			while (!(FPT_scarb(p_port, INIT_SELTD))) {
5538			}
5539			FPT_scsel(p_port);
5540			FPT_scasid(p_card, p_port);
5541		}
5542
5543	}
5544
5545	else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5546		FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5547		assigned_id = 0;
5548		FPT_scwtsel(p_port);
5549
5550		do {
5551			while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5552			}
5553
5554			i = FPT_scxferc(p_port, 0x00);
5555			if (i == ASSIGN_ID) {
5556				if (!
5557				    (FPT_scsendi
5558				     (p_port,
5559				      &FPT_scamInfo[p_our_id].id_string[0]))) {
5560					i = FPT_scxferc(p_port, 0x00);
5561					if (FPT_scvalq(i)) {
5562						k = FPT_scxferc(p_port, 0x00);
5563
5564						if (FPT_scvalq(k)) {
5565							currCard->ourId =
5566							    ((unsigned char)(i
5567									     <<
5568									     3)
5569							     +
5570							     (k &
5571							      (unsigned char)7))
5572							    & (unsigned char)
5573							    0x3F;
5574							FPT_inisci(p_card,
5575								   p_port,
5576								   p_our_id);
5577							FPT_scamInfo[currCard->
5578								     ourId].
5579							    state = ID_ASSIGNED;
5580							FPT_scamInfo[currCard->
5581								     ourId].
5582							    id_string[0]
5583							    = SLV_TYPE_CODE0;
5584							assigned_id = 1;
5585						}
5586					}
5587				}
5588			}
5589
5590			else if (i == SET_P_FLAG) {
5591				if (!(FPT_scsendi(p_port,
5592						  &FPT_scamInfo[p_our_id].
5593						  id_string[0])))
5594					FPT_scamInfo[p_our_id].id_string[0] |=
5595					    0x80;
5596			}
5597		} while (!assigned_id);
5598
5599		while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5600		}
5601	}
5602
5603	if (ScamFlg & SCAM_ENABLED) {
5604		FPT_scbusf(p_port);
5605		if (currCard->globalFlags & F_UPDATE_EEPROM) {
5606			FPT_scsavdi(p_card, p_port);
5607			currCard->globalFlags &= ~F_UPDATE_EEPROM;
5608		}
5609	}
5610
5611/*
5612   for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5613      {
5614      if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5615         (FPT_scamInfo[i].state == LEGACY))
5616         k++;
5617      }
5618
5619   if (k==2)
5620      currCard->globalFlags |= F_SINGLE_DEVICE;
5621   else
5622      currCard->globalFlags &= ~F_SINGLE_DEVICE;
5623*/
5624}
5625
5626/*---------------------------------------------------------------------
5627 *
5628 * Function: FPT_scarb
5629 *
5630 * Description: Gain control of the bus and wait SCAM select time (250ms)
5631 *
5632 *---------------------------------------------------------------------*/
5633
5634static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5635{
5636	if (p_sel_type == INIT_SELTD) {
5637
5638		while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5639		}
5640
5641		if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5642			return 0;
5643
5644		if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5645			return 0;
5646
5647		WR_HARPOON(p_port + hp_scsisig,
5648			   (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5649
5650		if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5651
5652			WR_HARPOON(p_port + hp_scsisig,
5653				   (RD_HARPOON(p_port + hp_scsisig) &
5654				    ~SCSI_BSY));
5655			return 0;
5656		}
5657
5658		WR_HARPOON(p_port + hp_scsisig,
5659			   (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5660
5661		if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5662
5663			WR_HARPOON(p_port + hp_scsisig,
5664				   (RD_HARPOON(p_port + hp_scsisig) &
5665				    ~(SCSI_BSY | SCSI_SEL)));
5666			return 0;
5667		}
5668	}
5669
5670	WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5671					   & ~ACTdeassert));
5672	WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5673	WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5674	WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5675	WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5676
5677	WR_HARPOON(p_port + hp_scsisig,
5678		   (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5679
5680	WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5681					 & ~SCSI_BSY));
5682
5683	FPT_Wait(p_port, TO_250ms);
5684
5685	return 1;
5686}
5687
5688/*---------------------------------------------------------------------
5689 *
5690 * Function: FPT_scbusf
5691 *
5692 * Description: Release the SCSI bus and disable SCAM selection.
5693 *
5694 *---------------------------------------------------------------------*/
5695
5696static void FPT_scbusf(u32 p_port)
5697{
5698	WR_HARPOON(p_port + hp_page_ctrl,
5699		   (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5700
5701	WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5702
5703	WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5704					    & ~SCSI_BUS_EN));
5705
5706	WR_HARPOON(p_port + hp_scsisig, 0x00);
5707
5708	WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5709					   & ~SCAM_EN));
5710
5711	WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5712					   | ACTdeassert));
5713
5714	WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5715
5716	WR_HARPOON(p_port + hp_page_ctrl,
5717		   (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5718}
5719
5720/*---------------------------------------------------------------------
5721 *
5722 * Function: FPT_scasid
5723 *
5724 * Description: Assign an ID to all the SCAM devices.
5725 *
5726 *---------------------------------------------------------------------*/
5727
5728static void FPT_scasid(unsigned char p_card, u32 p_port)
5729{
5730	unsigned char temp_id_string[ID_STRING_LENGTH];
5731
5732	unsigned char i, k, scam_id;
5733	unsigned char crcBytes[3];
5734	struct nvram_info *pCurrNvRam;
5735	unsigned short *pCrcBytes;
5736
5737	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5738
5739	i = 0;
5740
5741	while (!i) {
5742
5743		for (k = 0; k < ID_STRING_LENGTH; k++) {
5744			temp_id_string[k] = (unsigned char)0x00;
5745		}
5746
5747		FPT_scxferc(p_port, SYNC_PTRN);
5748		FPT_scxferc(p_port, ASSIGN_ID);
5749
5750		if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5751			if (pCurrNvRam) {
5752				pCrcBytes = (unsigned short *)&crcBytes[0];
5753				*pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5754				crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5755				temp_id_string[1] = crcBytes[2];
5756				temp_id_string[2] = crcBytes[0];
5757				temp_id_string[3] = crcBytes[1];
5758				for (k = 4; k < ID_STRING_LENGTH; k++)
5759					temp_id_string[k] = (unsigned char)0x00;
5760			}
5761			i = FPT_scmachid(p_card, temp_id_string);
5762
5763			if (i == CLR_PRIORITY) {
5764				FPT_scxferc(p_port, MISC_CODE);
5765				FPT_scxferc(p_port, CLR_P_FLAG);
5766				i = 0;	/*Not the last ID yet. */
5767			}
5768
5769			else if (i != NO_ID_AVAIL) {
5770				if (i < 8)
5771					FPT_scxferc(p_port, ID_0_7);
5772				else
5773					FPT_scxferc(p_port, ID_8_F);
5774
5775				scam_id = (i & (unsigned char)0x07);
5776
5777				for (k = 1; k < 0x08; k <<= 1)
5778					if (!(k & i))
5779						scam_id += 0x08;	/*Count number of zeros in DB0-3. */
5780
5781				FPT_scxferc(p_port, scam_id);
5782
5783				i = 0;	/*Not the last ID yet. */
5784			}
5785		}
5786
5787		else {
5788			i = 1;
5789		}
5790
5791	}			/*End while */
5792
5793	FPT_scxferc(p_port, SYNC_PTRN);
5794	FPT_scxferc(p_port, CFG_CMPLT);
5795}
5796
5797/*---------------------------------------------------------------------
5798 *
5799 * Function: FPT_scsel
5800 *
5801 * Description: Select all the SCAM devices.
5802 *
5803 *---------------------------------------------------------------------*/
5804
5805static void FPT_scsel(u32 p_port)
5806{
5807
5808	WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5809	FPT_scwiros(p_port, SCSI_MSG);
5810
5811	WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5812
5813	WR_HARPOON(p_port + hp_scsisig,
5814		   (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5815	WR_HARPOON(p_port + hp_scsidata_0,
5816		   (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5817				   (unsigned char)(BIT(7) + BIT(6))));
5818
5819	WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5820	FPT_scwiros(p_port, SCSI_SEL);
5821
5822	WR_HARPOON(p_port + hp_scsidata_0,
5823		   (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5824				   ~(unsigned char)BIT(6)));
5825	FPT_scwirod(p_port, BIT(6));
5826
5827	WR_HARPOON(p_port + hp_scsisig,
5828		   (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5829}
5830
5831/*---------------------------------------------------------------------
5832 *
5833 * Function: FPT_scxferc
5834 *
5835 * Description: Handshake the p_data (DB4-0) across the bus.
5836 *
5837 *---------------------------------------------------------------------*/
5838
5839static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5840{
5841	unsigned char curr_data, ret_data;
5842
5843	curr_data = p_data | BIT(7) | BIT(5);	/*Start with DB7 & DB5 asserted. */
5844
5845	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5846
5847	curr_data &= ~BIT(7);
5848
5849	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5850
5851	FPT_scwirod(p_port, BIT(7));	/*Wait for DB7 to be released. */
5852	while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5853
5854	ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5855
5856	curr_data |= BIT(6);
5857
5858	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5859
5860	curr_data &= ~BIT(5);
5861
5862	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5863
5864	FPT_scwirod(p_port, BIT(5));	/*Wait for DB5 to be released. */
5865
5866	curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0));	/*Release data bits */
5867	curr_data |= BIT(7);
5868
5869	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5870
5871	curr_data &= ~BIT(6);
5872
5873	WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5874
5875	FPT_scwirod(p_port, BIT(6));	/*Wait for DB6 to be released. */
5876
5877	return ret_data;
5878}
5879
5880/*---------------------------------------------------------------------
5881 *
5882 * Function: FPT_scsendi
5883 *
5884 * Description: Transfer our Identification string to determine if we
5885 *              will be the dominant master.
5886 *
5887 *---------------------------------------------------------------------*/
5888
5889static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5890{
5891	unsigned char ret_data, byte_cnt, bit_cnt, defer;
5892
5893	defer = 0;
5894
5895	for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5896
5897		for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5898
5899			if (defer)
5900				ret_data = FPT_scxferc(p_port, 00);
5901
5902			else if (p_id_string[byte_cnt] & bit_cnt)
5903
5904				ret_data = FPT_scxferc(p_port, 02);
5905
5906			else {
5907
5908				ret_data = FPT_scxferc(p_port, 01);
5909				if (ret_data & 02)
5910					defer = 1;
5911			}
5912
5913			if ((ret_data & 0x1C) == 0x10)
5914				return 0x00;	/*End of isolation stage, we won! */
5915
5916			if (ret_data & 0x1C)
5917				return 0xFF;
5918
5919			if ((defer) && (!(ret_data & 0x1F)))
5920				return 0x01;	/*End of isolation stage, we lost. */
5921
5922		}		/*bit loop */
5923
5924	}			/*byte loop */
5925
5926	if (defer)
5927		return 0x01;	/*We lost */
5928	else
5929		return 0;	/*We WON! Yeeessss! */
5930}
5931
5932/*---------------------------------------------------------------------
5933 *
5934 * Function: FPT_sciso
5935 *
5936 * Description: Transfer the Identification string.
5937 *
5938 *---------------------------------------------------------------------*/
5939
5940static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5941{
5942	unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5943
5944	the_data = 0;
5945
5946	for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5947
5948		for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5949
5950			ret_data = FPT_scxferc(p_port, 0);
5951
5952			if (ret_data & 0xFC)
5953				return 0xFF;
5954
5955			else {
5956
5957				the_data <<= 1;
5958				if (ret_data & BIT(1)) {
5959					the_data |= 1;
5960				}
5961			}
5962
5963			if ((ret_data & 0x1F) == 0) {
5964/*
5965				if(bit_cnt != 0 || bit_cnt != 8)
5966				{
5967					byte_cnt = 0;
5968					bit_cnt = 0;
5969					FPT_scxferc(p_port, SYNC_PTRN);
5970					FPT_scxferc(p_port, ASSIGN_ID);
5971					continue;
5972				}
5973*/
5974				if (byte_cnt)
5975					return 0x00;
5976				else
5977					return 0xFF;
5978			}
5979
5980		}		/*bit loop */
5981
5982		p_id_string[byte_cnt] = the_data;
5983
5984	}			/*byte loop */
5985
5986	return 0;
5987}
5988
5989/*---------------------------------------------------------------------
5990 *
5991 * Function: FPT_scwirod
5992 *
5993 * Description: Sample the SCSI data bus making sure the signal has been
5994 *              deasserted for the correct number of consecutive samples.
5995 *
5996 *---------------------------------------------------------------------*/
5997
5998static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
5999{
6000	unsigned char i;
6001
6002	i = 0;
6003	while (i < MAX_SCSI_TAR) {
6004
6005		if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6006
6007			i = 0;
6008
6009		else
6010
6011			i++;
6012
6013	}
6014}
6015
6016/*---------------------------------------------------------------------
6017 *
6018 * Function: FPT_scwiros
6019 *
6020 * Description: Sample the SCSI Signal lines making sure the signal has been
6021 *              deasserted for the correct number of consecutive samples.
6022 *
6023 *---------------------------------------------------------------------*/
6024
6025static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6026{
6027	unsigned char i;
6028
6029	i = 0;
6030	while (i < MAX_SCSI_TAR) {
6031
6032		if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6033
6034			i = 0;
6035
6036		else
6037
6038			i++;
6039
6040	}
6041}
6042
6043/*---------------------------------------------------------------------
6044 *
6045 * Function: FPT_scvalq
6046 *
6047 * Description: Make sure we received a valid data byte.
6048 *
6049 *---------------------------------------------------------------------*/
6050
6051static unsigned char FPT_scvalq(unsigned char p_quintet)
6052{
6053	unsigned char count;
6054
6055	for (count = 1; count < 0x08; count <<= 1) {
6056		if (!(p_quintet & count))
6057			p_quintet -= 0x80;
6058	}
6059
6060	if (p_quintet & 0x18)
6061		return 0;
6062
6063	else
6064		return 1;
6065}
6066
6067/*---------------------------------------------------------------------
6068 *
6069 * Function: FPT_scsell
6070 *
6071 * Description: Select the specified device ID using a selection timeout
6072 *              less than 4ms.  If somebody responds then it is a legacy
6073 *              drive and this ID must be marked as such.
6074 *
6075 *---------------------------------------------------------------------*/
6076
6077static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6078{
6079	unsigned long i;
6080
6081	WR_HARPOON(p_port + hp_page_ctrl,
6082		   (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6083
6084	ARAM_ACCESS(p_port);
6085
6086	WR_HARPOON(p_port + hp_addstat,
6087		   (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6088	WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6089
6090	for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6091		WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6092	}
6093	WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6094
6095	WRW_HARPOON((p_port + hp_intstat),
6096		    (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6097
6098	WR_HARPOON(p_port + hp_select_id, targ_id);
6099
6100	WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6101	WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6102	WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6103
6104	while (!(RDW_HARPOON((p_port + hp_intstat)) &
6105		 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6106	}
6107
6108	if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6109		FPT_Wait(p_port, TO_250ms);
6110
6111	DISABLE_AUTO(p_port);
6112
6113	WR_HARPOON(p_port + hp_addstat,
6114		   (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6115	WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6116
6117	SGRAM_ACCESS(p_port);
6118
6119	if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6120
6121		WRW_HARPOON((p_port + hp_intstat),
6122			    (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6123
6124		WR_HARPOON(p_port + hp_page_ctrl,
6125			   (RD_HARPOON(p_port + hp_page_ctrl) &
6126			    ~G_INT_DISABLE));
6127
6128		return 0;	/*No legacy device */
6129	}
6130
6131	else {
6132
6133		while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6134			if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6135				WR_HARPOON(p_port + hp_scsisig,
6136					   (SCSI_ACK + S_ILL_PH));
6137				ACCEPT_MSG(p_port);
6138			}
6139		}
6140
6141		WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6142
6143		WR_HARPOON(p_port + hp_page_ctrl,
6144			   (RD_HARPOON(p_port + hp_page_ctrl) &
6145			    ~G_INT_DISABLE));
6146
6147		return 1;	/*Found one of them oldies! */
6148	}
6149}
6150
6151/*---------------------------------------------------------------------
6152 *
6153 * Function: FPT_scwtsel
6154 *
6155 * Description: Wait to be selected by another SCAM initiator.
6156 *
6157 *---------------------------------------------------------------------*/
6158
6159static void FPT_scwtsel(u32 p_port)
6160{
6161	while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6162	}
6163}
6164
6165/*---------------------------------------------------------------------
6166 *
6167 * Function: FPT_inisci
6168 *
6169 * Description: Setup the data Structure with the info from the EEPROM.
6170 *
6171 *---------------------------------------------------------------------*/
6172
6173static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6174{
6175	unsigned char i, k, max_id;
6176	unsigned short ee_data;
6177	struct nvram_info *pCurrNvRam;
6178
6179	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6180
6181	if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6182		max_id = 0x08;
6183
6184	else
6185		max_id = 0x10;
6186
6187	if (pCurrNvRam) {
6188		for (i = 0; i < max_id; i++) {
6189
6190			for (k = 0; k < 4; k++)
6191				FPT_scamInfo[i].id_string[k] =
6192				    pCurrNvRam->niScamTbl[i][k];
6193			for (k = 4; k < ID_STRING_LENGTH; k++)
6194				FPT_scamInfo[i].id_string[k] =
6195				    (unsigned char)0x00;
6196
6197			if (FPT_scamInfo[i].id_string[0] == 0x00)
6198				FPT_scamInfo[i].state = ID_UNUSED;	/*Default to unused ID. */
6199			else
6200				FPT_scamInfo[i].state = ID_UNASSIGNED;	/*Default to unassigned ID. */
6201
6202		}
6203	} else {
6204		for (i = 0; i < max_id; i++) {
6205			for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6206				ee_data =
6207				    FPT_utilEERead(p_port,
6208						   (unsigned
6209						    short)((EE_SCAMBASE / 2) +
6210							   (unsigned short)(i *
6211									    ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6212				FPT_scamInfo[i].id_string[k] =
6213				    (unsigned char)ee_data;
6214				ee_data >>= 8;
6215				FPT_scamInfo[i].id_string[k + 1] =
6216				    (unsigned char)ee_data;
6217			}
6218
6219			if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6220			    (FPT_scamInfo[i].id_string[0] == 0xFF))
6221
6222				FPT_scamInfo[i].state = ID_UNUSED;	/*Default to unused ID. */
6223
6224			else
6225				FPT_scamInfo[i].state = ID_UNASSIGNED;	/*Default to unassigned ID. */
6226
6227		}
6228	}
6229	for (k = 0; k < ID_STRING_LENGTH; k++)
6230		FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6231
6232}
6233
6234/*---------------------------------------------------------------------
6235 *
6236 * Function: FPT_scmachid
6237 *
6238 * Description: Match the Device ID string with our values stored in
6239 *              the EEPROM.
6240 *
6241 *---------------------------------------------------------------------*/
6242
6243static unsigned char FPT_scmachid(unsigned char p_card,
6244				  unsigned char p_id_string[])
6245{
6246
6247	unsigned char i, k, match;
6248
6249	for (i = 0; i < MAX_SCSI_TAR; i++) {
6250
6251		match = 1;
6252
6253		for (k = 0; k < ID_STRING_LENGTH; k++) {
6254			if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6255				match = 0;
6256		}
6257
6258		if (match) {
6259			FPT_scamInfo[i].state = ID_ASSIGNED;
6260			return i;
6261		}
6262
6263	}
6264
6265	if (p_id_string[0] & BIT(5))
6266		i = 8;
6267	else
6268		i = MAX_SCSI_TAR;
6269
6270	if (((p_id_string[0] & 0x06) == 0x02)
6271	    || ((p_id_string[0] & 0x06) == 0x04))
6272		match = p_id_string[1] & (unsigned char)0x1F;
6273	else
6274		match = 7;
6275
6276	while (i > 0) {
6277		i--;
6278
6279		if (FPT_scamInfo[match].state == ID_UNUSED) {
6280			for (k = 0; k < ID_STRING_LENGTH; k++) {
6281				FPT_scamInfo[match].id_string[k] =
6282				    p_id_string[k];
6283			}
6284
6285			FPT_scamInfo[match].state = ID_ASSIGNED;
6286
6287			if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6288				FPT_BL_Card[p_card].globalFlags |=
6289				    F_UPDATE_EEPROM;
6290			return match;
6291
6292		}
6293
6294		match--;
6295
6296		if (match == 0xFF) {
6297			if (p_id_string[0] & BIT(5))
6298				match = 7;
6299			else
6300				match = MAX_SCSI_TAR - 1;
6301		}
6302	}
6303
6304	if (p_id_string[0] & BIT(7)) {
6305		return CLR_PRIORITY;
6306	}
6307
6308	if (p_id_string[0] & BIT(5))
6309		i = 8;
6310	else
6311		i = MAX_SCSI_TAR;
6312
6313	if (((p_id_string[0] & 0x06) == 0x02)
6314	    || ((p_id_string[0] & 0x06) == 0x04))
6315		match = p_id_string[1] & (unsigned char)0x1F;
6316	else
6317		match = 7;
6318
6319	while (i > 0) {
6320
6321		i--;
6322
6323		if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6324			for (k = 0; k < ID_STRING_LENGTH; k++) {
6325				FPT_scamInfo[match].id_string[k] =
6326				    p_id_string[k];
6327			}
6328
6329			FPT_scamInfo[match].id_string[0] |= BIT(7);
6330			FPT_scamInfo[match].state = ID_ASSIGNED;
6331			if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6332				FPT_BL_Card[p_card].globalFlags |=
6333				    F_UPDATE_EEPROM;
6334			return match;
6335
6336		}
6337
6338		match--;
6339
6340		if (match == 0xFF) {
6341			if (p_id_string[0] & BIT(5))
6342				match = 7;
6343			else
6344				match = MAX_SCSI_TAR - 1;
6345		}
6346	}
6347
6348	return NO_ID_AVAIL;
6349}
6350
6351/*---------------------------------------------------------------------
6352 *
6353 * Function: FPT_scsavdi
6354 *
6355 * Description: Save off the device SCAM ID strings.
6356 *
6357 *---------------------------------------------------------------------*/
6358
6359static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6360{
6361	unsigned char i, k, max_id;
6362	unsigned short ee_data, sum_data;
6363
6364	sum_data = 0x0000;
6365
6366	for (i = 1; i < EE_SCAMBASE / 2; i++) {
6367		sum_data += FPT_utilEERead(p_port, i);
6368	}
6369
6370	FPT_utilEEWriteOnOff(p_port, 1);	/* Enable write access to the EEPROM */
6371
6372	if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6373		max_id = 0x08;
6374
6375	else
6376		max_id = 0x10;
6377
6378	for (i = 0; i < max_id; i++) {
6379
6380		for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6381			ee_data = FPT_scamInfo[i].id_string[k + 1];
6382			ee_data <<= 8;
6383			ee_data |= FPT_scamInfo[i].id_string[k];
6384			sum_data += ee_data;
6385			FPT_utilEEWrite(p_port, ee_data,
6386					(unsigned short)((EE_SCAMBASE / 2) +
6387							 (unsigned short)(i *
6388									  ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6389		}
6390	}
6391
6392	FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6393	FPT_utilEEWriteOnOff(p_port, 0);	/* Turn off write access */
6394}
6395
6396/*---------------------------------------------------------------------
6397 *
6398 * Function: FPT_XbowInit
6399 *
6400 * Description: Setup the Xbow for normal operation.
6401 *
6402 *---------------------------------------------------------------------*/
6403
6404static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6405{
6406	unsigned char i;
6407
6408	i = RD_HARPOON(port + hp_page_ctrl);
6409	WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6410
6411	WR_HARPOON(port + hp_scsireset, 0x00);
6412	WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6413
6414	WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6415					 FIFO_CLR));
6416
6417	WR_HARPOON(port + hp_scsireset, SCSI_INI);
6418
6419	WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6420
6421	WR_HARPOON(port + hp_scsisig, 0x00);	/*  Clear any signals we might */
6422	WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6423
6424	WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6425
6426	FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6427	    BUS_FREE | XFER_CNT_0 | AUTO_INT;
6428
6429	if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6430		FPT_default_intena |= SCAM_SEL;
6431
6432	WRW_HARPOON((port + hp_intena), FPT_default_intena);
6433
6434	WR_HARPOON(port + hp_seltimeout, TO_290ms);
6435
6436	/* Turn on SCSI_MODE8 for narrow cards to fix the
6437	   strapping issue with the DUAL CHANNEL card */
6438	if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6439		WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6440
6441	WR_HARPOON(port + hp_page_ctrl, i);
6442
6443}
6444
6445/*---------------------------------------------------------------------
6446 *
6447 * Function: FPT_BusMasterInit
6448 *
6449 * Description: Initialize the BusMaster for normal operations.
6450 *
6451 *---------------------------------------------------------------------*/
6452
6453static void FPT_BusMasterInit(u32 p_port)
6454{
6455
6456	WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6457	WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6458
6459	WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6460
6461	WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6462
6463	WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6464
6465	RD_HARPOON(p_port + hp_int_status);	/*Clear interrupts. */
6466	WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6467	WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6468					   ~SCATTER_EN));
6469}
6470
6471/*---------------------------------------------------------------------
6472 *
6473 * Function: FPT_DiagEEPROM
6474 *
6475 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6476 *              necessary.
6477 *
6478 *---------------------------------------------------------------------*/
6479
6480static void FPT_DiagEEPROM(u32 p_port)
6481{
6482	unsigned short index, temp, max_wd_cnt;
6483
6484	if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6485		max_wd_cnt = EEPROM_WD_CNT;
6486	else
6487		max_wd_cnt = EEPROM_WD_CNT * 2;
6488
6489	temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6490
6491	if (temp == 0x4641) {
6492
6493		for (index = 2; index < max_wd_cnt; index++) {
6494
6495			temp += FPT_utilEERead(p_port, index);
6496
6497		}
6498
6499		if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6500
6501			return;	/*EEPROM is Okay so return now! */
6502		}
6503	}
6504
6505	FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6506
6507	for (index = 0; index < max_wd_cnt; index++) {
6508
6509		FPT_utilEEWrite(p_port, 0x0000, index);
6510	}
6511
6512	temp = 0;
6513
6514	FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6515	temp += 0x4641;
6516	FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6517	temp += 0x3920;
6518	FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6519	temp += 0x3033;
6520	FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6521	temp += 0x2020;
6522	FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6523	temp += 0x70D3;
6524	FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6525	temp += 0x0010;
6526	FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6527	temp += 0x0003;
6528	FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6529	temp += 0x0007;
6530
6531	FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6532	temp += 0x0000;
6533	FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6534	temp += 0x0000;
6535	FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6536	temp += 0x0000;
6537
6538	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6539	temp += 0x4242;
6540	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6541	temp += 0x4242;
6542	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6543	temp += 0x4242;
6544	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6545	temp += 0x4242;
6546	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6547	temp += 0x4242;
6548	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6549	temp += 0x4242;
6550	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6551	temp += 0x4242;
6552	FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6553	temp += 0x4242;
6554
6555	FPT_utilEEWrite(p_port, 0x6C46, 64 / 2);	/*PRODUCT ID */
6556	temp += 0x6C46;
6557	FPT_utilEEWrite(p_port, 0x7361, 66 / 2);	/* FlashPoint LT   */
6558	temp += 0x7361;
6559	FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6560	temp += 0x5068;
6561	FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6562	temp += 0x696F;
6563	FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6564	temp += 0x746E;
6565	FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6566	temp += 0x4C20;
6567	FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6568	temp += 0x2054;
6569	FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6570	temp += 0x2020;
6571
6572	index = ((EE_SCAMBASE / 2) + (7 * 16));
6573	FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6574	temp += (0x0700 + TYPE_CODE0);
6575	index++;
6576	FPT_utilEEWrite(p_port, 0x5542, index);	/*Vendor ID code */
6577	temp += 0x5542;		/* BUSLOGIC      */
6578	index++;
6579	FPT_utilEEWrite(p_port, 0x4C53, index);
6580	temp += 0x4C53;
6581	index++;
6582	FPT_utilEEWrite(p_port, 0x474F, index);
6583	temp += 0x474F;
6584	index++;
6585	FPT_utilEEWrite(p_port, 0x4349, index);
6586	temp += 0x4349;
6587	index++;
6588	FPT_utilEEWrite(p_port, 0x5442, index);	/*Vendor unique code */
6589	temp += 0x5442;		/* BT- 930           */
6590	index++;
6591	FPT_utilEEWrite(p_port, 0x202D, index);
6592	temp += 0x202D;
6593	index++;
6594	FPT_utilEEWrite(p_port, 0x3339, index);
6595	temp += 0x3339;
6596	index++;		/*Serial #          */
6597	FPT_utilEEWrite(p_port, 0x2030, index);	/* 01234567         */
6598	temp += 0x2030;
6599	index++;
6600	FPT_utilEEWrite(p_port, 0x5453, index);
6601	temp += 0x5453;
6602	index++;
6603	FPT_utilEEWrite(p_port, 0x5645, index);
6604	temp += 0x5645;
6605	index++;
6606	FPT_utilEEWrite(p_port, 0x2045, index);
6607	temp += 0x2045;
6608	index++;
6609	FPT_utilEEWrite(p_port, 0x202F, index);
6610	temp += 0x202F;
6611	index++;
6612	FPT_utilEEWrite(p_port, 0x4F4A, index);
6613	temp += 0x4F4A;
6614	index++;
6615	FPT_utilEEWrite(p_port, 0x204E, index);
6616	temp += 0x204E;
6617	index++;
6618	FPT_utilEEWrite(p_port, 0x3539, index);
6619	temp += 0x3539;
6620
6621	FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6622
6623	FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6624
6625}
6626
6627/*---------------------------------------------------------------------
6628 *
6629 * Function: Queue Search Select
6630 *
6631 * Description: Try to find a new command to execute.
6632 *
6633 *---------------------------------------------------------------------*/
6634
6635static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6636				  unsigned char p_card)
6637{
6638	unsigned char scan_ptr, lun;
6639	struct sccb_mgr_tar_info *currTar_Info;
6640	struct sccb *pOldSccb;
6641
6642	scan_ptr = pCurrCard->scanIndex;
6643	do {
6644		currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6645		if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6646		    ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6647		     TAG_Q_TRYING)) {
6648			if (currTar_Info->TarSelQ_Cnt != 0) {
6649
6650				scan_ptr++;
6651				if (scan_ptr == MAX_SCSI_TAR)
6652					scan_ptr = 0;
6653
6654				for (lun = 0; lun < MAX_LUN; lun++) {
6655					if (currTar_Info->TarLUNBusy[lun] == 0) {
6656
6657						pCurrCard->currentSCCB =
6658						    currTar_Info->TarSelQ_Head;
6659						pOldSccb = NULL;
6660
6661						while ((pCurrCard->
6662							currentSCCB != NULL)
6663						       && (lun !=
6664							   pCurrCard->
6665							   currentSCCB->Lun)) {
6666							pOldSccb =
6667							    pCurrCard->
6668							    currentSCCB;
6669							pCurrCard->currentSCCB =
6670							    (struct sccb
6671							     *)(pCurrCard->
6672								currentSCCB)->
6673							    Sccb_forwardlink;
6674						}
6675						if (pCurrCard->currentSCCB ==
6676						    NULL)
6677							continue;
6678						if (pOldSccb != NULL) {
6679							pOldSccb->
6680							    Sccb_forwardlink =
6681							    (struct sccb
6682							     *)(pCurrCard->
6683								currentSCCB)->
6684							    Sccb_forwardlink;
6685							pOldSccb->
6686							    Sccb_backlink =
6687							    (struct sccb
6688							     *)(pCurrCard->
6689								currentSCCB)->
6690							    Sccb_backlink;
6691							currTar_Info->
6692							    TarSelQ_Cnt--;
6693						} else {
6694							currTar_Info->
6695							    TarSelQ_Head =
6696							    (struct sccb
6697							     *)(pCurrCard->
6698								currentSCCB)->
6699							    Sccb_forwardlink;
6700
6701							if (currTar_Info->
6702							    TarSelQ_Head ==
6703							    NULL) {
6704								currTar_Info->
6705								    TarSelQ_Tail
6706								    = NULL;
6707								currTar_Info->
6708								    TarSelQ_Cnt
6709								    = 0;
6710							} else {
6711								currTar_Info->
6712								    TarSelQ_Cnt--;
6713								currTar_Info->
6714								    TarSelQ_Head->
6715								    Sccb_backlink
6716								    =
6717								    (struct sccb
6718								     *)NULL;
6719							}
6720						}
6721						pCurrCard->scanIndex = scan_ptr;
6722
6723						pCurrCard->globalFlags |=
6724						    F_NEW_SCCB_CMD;
6725
6726						break;
6727					}
6728				}
6729			}
6730
6731			else {
6732				scan_ptr++;
6733				if (scan_ptr == MAX_SCSI_TAR) {
6734					scan_ptr = 0;
6735				}
6736			}
6737
6738		} else {
6739			if ((currTar_Info->TarSelQ_Cnt != 0) &&
6740			    (currTar_Info->TarLUNBusy[0] == 0)) {
6741
6742				pCurrCard->currentSCCB =
6743				    currTar_Info->TarSelQ_Head;
6744
6745				currTar_Info->TarSelQ_Head =
6746				    (struct sccb *)(pCurrCard->currentSCCB)->
6747				    Sccb_forwardlink;
6748
6749				if (currTar_Info->TarSelQ_Head == NULL) {
6750					currTar_Info->TarSelQ_Tail = NULL;
6751					currTar_Info->TarSelQ_Cnt = 0;
6752				} else {
6753					currTar_Info->TarSelQ_Cnt--;
6754					currTar_Info->TarSelQ_Head->
6755					    Sccb_backlink = (struct sccb *)NULL;
6756				}
6757
6758				scan_ptr++;
6759				if (scan_ptr == MAX_SCSI_TAR)
6760					scan_ptr = 0;
6761
6762				pCurrCard->scanIndex = scan_ptr;
6763
6764				pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6765
6766				break;
6767			}
6768
6769			else {
6770				scan_ptr++;
6771				if (scan_ptr == MAX_SCSI_TAR) {
6772					scan_ptr = 0;
6773				}
6774			}
6775		}
6776	} while (scan_ptr != pCurrCard->scanIndex);
6777}
6778
6779/*---------------------------------------------------------------------
6780 *
6781 * Function: Queue Select Fail
6782 *
6783 * Description: Add the current SCCB to the head of the Queue.
6784 *
6785 *---------------------------------------------------------------------*/
6786
6787static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6788				unsigned char p_card)
6789{
6790	unsigned char thisTarg;
6791	struct sccb_mgr_tar_info *currTar_Info;
6792
6793	if (pCurrCard->currentSCCB != NULL) {
6794		thisTarg =
6795		    (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6796				    TargID);
6797		currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6798
6799		pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6800
6801		pCurrCard->currentSCCB->Sccb_forwardlink =
6802		    currTar_Info->TarSelQ_Head;
6803
6804		if (currTar_Info->TarSelQ_Cnt == 0) {
6805			currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6806		}
6807
6808		else {
6809			currTar_Info->TarSelQ_Head->Sccb_backlink =
6810			    pCurrCard->currentSCCB;
6811		}
6812
6813		currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6814
6815		pCurrCard->currentSCCB = NULL;
6816		currTar_Info->TarSelQ_Cnt++;
6817	}
6818}
6819
6820/*---------------------------------------------------------------------
6821 *
6822 * Function: Queue Command Complete
6823 *
6824 * Description: Call the callback function with the current SCCB.
6825 *
6826 *---------------------------------------------------------------------*/
6827
6828static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6829				 struct sccb *p_sccb, unsigned char p_card)
6830{
6831
6832	unsigned char i, SCSIcmd;
6833	CALL_BK_FN callback;
6834	struct sccb_mgr_tar_info *currTar_Info;
6835
6836	SCSIcmd = p_sccb->Cdb[0];
6837
6838	if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6839
6840		if ((p_sccb->
6841		     ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6842		    && (p_sccb->HostStatus == SCCB_COMPLETE)
6843		    && (p_sccb->TargetStatus != SAM_STAT_CHECK_CONDITION))
6844
6845			if ((SCSIcmd == READ_6) ||
6846			    (SCSIcmd == WRITE_6) ||
6847			    (SCSIcmd == READ_10) ||
6848			    (SCSIcmd == WRITE_10) ||
6849			    (SCSIcmd == WRITE_VERIFY) ||
6850			    (SCSIcmd == START_STOP) ||
6851			    (pCurrCard->globalFlags & F_NO_FILTER)
6852			    )
6853				p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6854	}
6855
6856	if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6857		if (p_sccb->HostStatus || p_sccb->TargetStatus)
6858			p_sccb->SccbStatus = SCCB_ERROR;
6859		else
6860			p_sccb->SccbStatus = SCCB_SUCCESS;
6861	}
6862
6863	if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6864
6865		p_sccb->CdbLength = p_sccb->Save_CdbLen;
6866		for (i = 0; i < 6; i++) {
6867			p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6868		}
6869	}
6870
6871	if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6872	    (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6873
6874		FPT_utilUpdateResidual(p_sccb);
6875	}
6876
6877	pCurrCard->cmdCounter--;
6878	if (!pCurrCard->cmdCounter) {
6879
6880		if (pCurrCard->globalFlags & F_GREEN_PC) {
6881			WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6882				   (PWR_DWN | CLKCTRL_DEFAULT));
6883			WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6884		}
6885
6886		WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6887			   (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6888			    ~SCCB_MGR_ACTIVE));
6889
6890	}
6891
6892	if (pCurrCard->discQCount != 0) {
6893		currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6894		if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6895		     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6896		      TAG_Q_TRYING))) {
6897			pCurrCard->discQCount--;
6898			pCurrCard->discQ_Tbl[currTar_Info->
6899					     LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6900		} else {
6901			if (p_sccb->Sccb_tag) {
6902				pCurrCard->discQCount--;
6903				pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6904			} else {
6905				pCurrCard->discQCount--;
6906				pCurrCard->discQ_Tbl[currTar_Info->
6907						     LunDiscQ_Idx[0]] = NULL;
6908			}
6909		}
6910
6911	}
6912
6913	callback = (CALL_BK_FN) p_sccb->SccbCallback;
6914	callback(p_sccb);
6915	pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6916	pCurrCard->currentSCCB = NULL;
6917}
6918
6919/*---------------------------------------------------------------------
6920 *
6921 * Function: Queue Disconnect
6922 *
6923 * Description: Add SCCB to our disconnect array.
6924 *
6925 *---------------------------------------------------------------------*/
6926static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6927{
6928	struct sccb_mgr_tar_info *currTar_Info;
6929
6930	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6931
6932	if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6933	     ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6934		FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6935					      LunDiscQ_Idx[p_sccb->Lun]] =
6936		    p_sccb;
6937	} else {
6938		if (p_sccb->Sccb_tag) {
6939			FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6940			    p_sccb;
6941			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6942			    0;
6943			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6944		} else {
6945			FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6946						      LunDiscQ_Idx[0]] = p_sccb;
6947		}
6948	}
6949	FPT_BL_Card[p_card].currentSCCB = NULL;
6950}
6951
6952/*---------------------------------------------------------------------
6953 *
6954 * Function: Queue Flush SCCB
6955 *
6956 * Description: Flush all SCCB's back to the host driver for this target.
6957 *
6958 *---------------------------------------------------------------------*/
6959
6960static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6961{
6962	unsigned char qtag, thisTarg;
6963	struct sccb *currSCCB;
6964	struct sccb_mgr_tar_info *currTar_Info;
6965
6966	currSCCB = FPT_BL_Card[p_card].currentSCCB;
6967	if (currSCCB != NULL) {
6968		thisTarg = (unsigned char)currSCCB->TargID;
6969		currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6970
6971		for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
6972
6973			if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
6974			    (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
6975			     thisTarg)) {
6976
6977				FPT_BL_Card[p_card].discQ_Tbl[qtag]->
6978				    HostStatus = (unsigned char)error_code;
6979
6980				FPT_queueCmdComplete(&FPT_BL_Card[p_card],
6981						     FPT_BL_Card[p_card].
6982						     discQ_Tbl[qtag], p_card);
6983
6984				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
6985				currTar_Info->TarTagQ_Cnt--;
6986
6987			}
6988		}
6989	}
6990
6991}
6992
6993/*---------------------------------------------------------------------
6994 *
6995 * Function: Queue Flush Target SCCB
6996 *
6997 * Description: Flush all SCCB's back to the host driver for this target.
6998 *
6999 *---------------------------------------------------------------------*/
7000
7001static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7002				   unsigned char error_code)
7003{
7004	unsigned char qtag;
7005	struct sccb_mgr_tar_info *currTar_Info;
7006
7007	currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7008
7009	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7010
7011		if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7012		    (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7013
7014			FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7015			    (unsigned char)error_code;
7016
7017			FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7018					     FPT_BL_Card[p_card].
7019					     discQ_Tbl[qtag], p_card);
7020
7021			FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7022			currTar_Info->TarTagQ_Cnt--;
7023
7024		}
7025	}
7026
7027}
7028
7029static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7030{
7031	struct sccb_mgr_tar_info *currTar_Info;
7032	currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7033
7034	p_SCCB->Sccb_forwardlink = NULL;
7035
7036	p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7037
7038	if (currTar_Info->TarSelQ_Cnt == 0) {
7039
7040		currTar_Info->TarSelQ_Head = p_SCCB;
7041	}
7042
7043	else {
7044
7045		currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7046	}
7047
7048	currTar_Info->TarSelQ_Tail = p_SCCB;
7049	currTar_Info->TarSelQ_Cnt++;
7050}
7051
7052/*---------------------------------------------------------------------
7053 *
7054 * Function: Queue Find SCCB
7055 *
7056 * Description: Search the target select Queue for this SCCB, and
7057 *              remove it if found.
7058 *
7059 *---------------------------------------------------------------------*/
7060
7061static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7062				       unsigned char p_card)
7063{
7064	struct sccb *q_ptr;
7065	struct sccb_mgr_tar_info *currTar_Info;
7066
7067	currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7068
7069	q_ptr = currTar_Info->TarSelQ_Head;
7070
7071	while (q_ptr != NULL) {
7072
7073		if (q_ptr == p_SCCB) {
7074
7075			if (currTar_Info->TarSelQ_Head == q_ptr) {
7076
7077				currTar_Info->TarSelQ_Head =
7078				    q_ptr->Sccb_forwardlink;
7079			}
7080
7081			if (currTar_Info->TarSelQ_Tail == q_ptr) {
7082
7083				currTar_Info->TarSelQ_Tail =
7084				    q_ptr->Sccb_backlink;
7085			}
7086
7087			if (q_ptr->Sccb_forwardlink != NULL) {
7088				q_ptr->Sccb_forwardlink->Sccb_backlink =
7089				    q_ptr->Sccb_backlink;
7090			}
7091
7092			if (q_ptr->Sccb_backlink != NULL) {
7093				q_ptr->Sccb_backlink->Sccb_forwardlink =
7094				    q_ptr->Sccb_forwardlink;
7095			}
7096
7097			currTar_Info->TarSelQ_Cnt--;
7098
7099			return 1;
7100		}
7101
7102		else {
7103			q_ptr = q_ptr->Sccb_forwardlink;
7104		}
7105	}
7106
7107	return 0;
7108
7109}
7110
7111/*---------------------------------------------------------------------
7112 *
7113 * Function: Utility Update Residual Count
7114 *
7115 * Description: Update the XferCnt to the remaining byte count.
7116 *              If we transferred all the data then just write zero.
7117 *              If Non-SG transfer then report Total Cnt - Actual Transfer
7118 *              Cnt.  For SG transfers add the count fields of all
7119 *              remaining SG elements, as well as any partial remaining
7120 *              element.
7121 *
7122 *---------------------------------------------------------------------*/
7123
7124static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7125{
7126	unsigned long partial_cnt;
7127	unsigned int sg_index;
7128	struct blogic_sg_seg *segp;
7129
7130	if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7131
7132		p_SCCB->DataLength = 0x0000;
7133	}
7134
7135	else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7136
7137		partial_cnt = 0x0000;
7138
7139		sg_index = p_SCCB->Sccb_sgseg;
7140
7141
7142		if (p_SCCB->Sccb_SGoffset) {
7143
7144			partial_cnt = p_SCCB->Sccb_SGoffset;
7145			sg_index++;
7146		}
7147
7148		while (((unsigned long)sg_index *
7149			(unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7150			segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7151					(sg_index * 2);
7152			partial_cnt += segp->segbytes;
7153			sg_index++;
7154		}
7155
7156		p_SCCB->DataLength = partial_cnt;
7157	}
7158
7159	else {
7160
7161		p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7162	}
7163}
7164
7165/*---------------------------------------------------------------------
7166 *
7167 * Function: Wait 1 Second
7168 *
7169 * Description: Wait for 1 second.
7170 *
7171 *---------------------------------------------------------------------*/
7172
7173static void FPT_Wait1Second(u32 p_port)
7174{
7175	unsigned char i;
7176
7177	for (i = 0; i < 4; i++) {
7178
7179		FPT_Wait(p_port, TO_250ms);
7180
7181		if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7182			break;
7183
7184		if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7185			break;
7186	}
7187}
7188
7189/*---------------------------------------------------------------------
7190 *
7191 * Function: FPT_Wait
7192 *
7193 * Description: Wait the desired delay.
7194 *
7195 *---------------------------------------------------------------------*/
7196
7197static void FPT_Wait(u32 p_port, unsigned char p_delay)
7198{
7199	unsigned char old_timer;
7200	unsigned char green_flag;
7201
7202	old_timer = RD_HARPOON(p_port + hp_seltimeout);
7203
7204	green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7205	WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7206
7207	WR_HARPOON(p_port + hp_seltimeout, p_delay);
7208	WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7209	WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7210
7211	WR_HARPOON(p_port + hp_portctrl_0,
7212		   (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7213
7214	while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7215
7216		if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7217			break;
7218
7219		if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7220			break;
7221	}
7222
7223	WR_HARPOON(p_port + hp_portctrl_0,
7224		   (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7225
7226	WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7227	WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7228
7229	WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7230
7231	WR_HARPOON(p_port + hp_seltimeout, old_timer);
7232}
7233
7234/*---------------------------------------------------------------------
7235 *
7236 * Function: Enable/Disable Write to EEPROM
7237 *
7238 * Description: The EEPROM must first be enabled for writes
7239 *              A total of 9 clocks are needed.
7240 *
7241 *---------------------------------------------------------------------*/
7242
7243static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7244{
7245	unsigned char ee_value;
7246
7247	ee_value =
7248	    (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7249			    (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7250
7251	if (p_mode)
7252
7253		FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7254
7255	else
7256
7257		FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7258
7259	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));	/*Turn off CS */
7260	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);	/*Turn off Master Select */
7261}
7262
7263/*---------------------------------------------------------------------
7264 *
7265 * Function: Write EEPROM
7266 *
7267 * Description: Write a word to the EEPROM at the specified
7268 *              address.
7269 *
7270 *---------------------------------------------------------------------*/
7271
7272static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7273			    unsigned short ee_addr)
7274{
7275
7276	unsigned char ee_value;
7277	unsigned short i;
7278
7279	ee_value =
7280	    (unsigned
7281	     char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7282		    (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7283
7284	FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7285
7286	ee_value |= (SEE_MS + SEE_CS);
7287
7288	for (i = 0x8000; i != 0; i >>= 1) {
7289
7290		if (i & ee_data)
7291			ee_value |= SEE_DO;
7292		else
7293			ee_value &= ~SEE_DO;
7294
7295		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7296		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7297		ee_value |= SEE_CLK;	/* Clock  data! */
7298		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7299		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7300		ee_value &= ~SEE_CLK;
7301		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7302		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7303	}
7304	ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7305	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7306
7307	FPT_Wait(p_port, TO_10ms);
7308
7309	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS));	/* Set CS to EEPROM */
7310	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));	/* Turn off CS */
7311	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);	/* Turn off Master Select */
7312}
7313
7314/*---------------------------------------------------------------------
7315 *
7316 * Function: Read EEPROM
7317 *
7318 * Description: Read a word from the EEPROM at the desired
7319 *              address.
7320 *
7321 *---------------------------------------------------------------------*/
7322
7323static unsigned short FPT_utilEERead(u32 p_port,
7324				     unsigned short ee_addr)
7325{
7326	unsigned short i, ee_data1, ee_data2;
7327
7328	i = 0;
7329	ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7330	do {
7331		ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7332
7333		if (ee_data1 == ee_data2)
7334			return ee_data1;
7335
7336		ee_data1 = ee_data2;
7337		i++;
7338
7339	} while (i < 4);
7340
7341	return ee_data1;
7342}
7343
7344/*---------------------------------------------------------------------
7345 *
7346 * Function: Read EEPROM Original 
7347 *
7348 * Description: Read a word from the EEPROM at the desired
7349 *              address.
7350 *
7351 *---------------------------------------------------------------------*/
7352
7353static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7354{
7355
7356	unsigned char ee_value;
7357	unsigned short i, ee_data;
7358
7359	ee_value =
7360	    (unsigned
7361	     char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7362		    (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7363
7364	FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7365
7366	ee_value |= (SEE_MS + SEE_CS);
7367	ee_data = 0;
7368
7369	for (i = 1; i <= 16; i++) {
7370
7371		ee_value |= SEE_CLK;	/* Clock  data! */
7372		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7373		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7374		ee_value &= ~SEE_CLK;
7375		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7376		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7377
7378		ee_data <<= 1;
7379
7380		if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7381			ee_data |= 1;
7382	}
7383
7384	ee_value &= ~(SEE_MS + SEE_CS);
7385	WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));	/*Turn off CS */
7386	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);	/*Turn off Master Select */
7387
7388	return ee_data;
7389}
7390
7391/*---------------------------------------------------------------------
7392 *
7393 * Function: Send EE command and Address to the EEPROM
7394 *
7395 * Description: Transfers the correct command and sends the address
7396 *              to the eeprom.
7397 *
7398 *---------------------------------------------------------------------*/
7399
7400static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7401				  unsigned short ee_addr)
7402{
7403	unsigned char ee_value;
7404	unsigned char narrow_flg;
7405
7406	unsigned short i;
7407
7408	narrow_flg =
7409	    (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7410			    NARROW_SCSI_CARD);
7411
7412	ee_value = SEE_MS;
7413	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7414
7415	ee_value |= SEE_CS;	/* Set CS to EEPROM */
7416	WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7417
7418	for (i = 0x04; i != 0; i >>= 1) {
7419
7420		if (i & ee_cmd)
7421			ee_value |= SEE_DO;
7422		else
7423			ee_value &= ~SEE_DO;
7424
7425		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7426		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7427		ee_value |= SEE_CLK;	/* Clock  data! */
7428		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7429		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7430		ee_value &= ~SEE_CLK;
7431		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7432		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7433	}
7434
7435	if (narrow_flg)
7436		i = 0x0080;
7437
7438	else
7439		i = 0x0200;
7440
7441	while (i != 0) {
7442
7443		if (i & ee_addr)
7444			ee_value |= SEE_DO;
7445		else
7446			ee_value &= ~SEE_DO;
7447
7448		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7449		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7450		ee_value |= SEE_CLK;	/* Clock  data! */
7451		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7452		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7453		ee_value &= ~SEE_CLK;
7454		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7455		WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7456
7457		i >>= 1;
7458	}
7459}
7460
7461static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7462{
7463	unsigned short crc = 0;
7464	int i, j;
7465	unsigned short ch;
7466	for (i = 0; i < ID_STRING_LENGTH; i++) {
7467		ch = (unsigned short)buffer[i];
7468		for (j = 0; j < 8; j++) {
7469			if ((crc ^ ch) & 1)
7470				crc = (crc >> 1) ^ CRCMASK;
7471			else
7472				crc >>= 1;
7473			ch >>= 1;
7474		}
7475	}
7476	return crc;
7477}
7478
7479static unsigned char FPT_CalcLrc(unsigned char buffer[])
7480{
7481	int i;
7482	unsigned char lrc;
7483	lrc = 0;
7484	for (i = 0; i < ID_STRING_LENGTH; i++)
7485		lrc ^= buffer[i];
7486	return lrc;
7487}
7488
7489/*
7490  The following inline definitions avoid type conflicts.
7491*/
7492
7493static inline unsigned char
7494FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7495{
7496	return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7497					   FlashPointInfo);
7498}
7499
7500static inline void *
7501FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7502{
7503	return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7504						   FlashPointInfo);
7505}
7506
7507static inline void
7508FlashPoint__ReleaseHostAdapter(void *CardHandle)
7509{
7510	FlashPoint_ReleaseHostAdapter(CardHandle);
7511}
7512
7513static inline void
7514FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7515{
7516	FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7517}
7518
7519static inline void
7520FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7521{
7522	FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7523}
7524
7525static inline bool
7526FlashPoint__InterruptPending(void *CardHandle)
7527{
7528	return FlashPoint_InterruptPending(CardHandle);
7529}
7530
7531static inline int
7532FlashPoint__HandleInterrupt(void *CardHandle)
7533{
7534	return FlashPoint_HandleInterrupt(CardHandle);
7535}
7536
7537#define FlashPoint_ProbeHostAdapter	    FlashPoint__ProbeHostAdapter
7538#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7539#define FlashPoint_ReleaseHostAdapter	    FlashPoint__ReleaseHostAdapter
7540#define FlashPoint_StartCCB		    FlashPoint__StartCCB
7541#define FlashPoint_AbortCCB		    FlashPoint__AbortCCB
7542#define FlashPoint_InterruptPending	    FlashPoint__InterruptPending
7543#define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
7544
7545#else				/* !CONFIG_SCSI_FLASHPOINT */
7546
7547/*
7548  Define prototypes for the FlashPoint SCCB Manager Functions.
7549*/
7550
7551extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7552extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7553extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7554extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7555extern bool FlashPoint_InterruptPending(void *);
7556extern int FlashPoint_HandleInterrupt(void *);
7557extern void FlashPoint_ReleaseHostAdapter(void *);
7558
7559#endif				/* CONFIG_SCSI_FLASHPOINT */