cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

FlashPoint.c (196675B)


      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, bm_int_st;
   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 ((bm_int_st = 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 */