Linux Audio

Check our new training course

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