xref: /openbmc/linux/drivers/scsi/FlashPoint.c (revision 85ae97d816da3f8af9dcfbc4197a2950b55c3b0d)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds 
31da177e4SLinus Torvalds   FlashPoint.c -- FlashPoint SCCB Manager for Linux
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds   This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
61da177e4SLinus Torvalds   Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
71da177e4SLinus Torvalds   Linux compatibility.  It was provided by BusLogic in the form of 16 separate
81da177e4SLinus Torvalds   source files, which would have unnecessarily cluttered the scsi directory, so
91da177e4SLinus Torvalds   the individual files have been combined into this single file.
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds   This file is available under both the GNU General Public License
141da177e4SLinus Torvalds   and a BSD-style copyright; see LICENSE.FlashPoint for details.
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds */
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds #include <linux/config.h>
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds #define MAX_CARDS	8
261da177e4SLinus Torvalds #undef BUSTYPE_PCI
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds #define OS_InPortByte(port)		inb(port)
301da177e4SLinus Torvalds #define OS_InPortWord(port)		inw(port)
311da177e4SLinus Torvalds #define OS_InPortLong(port)		inl(port)
321da177e4SLinus Torvalds #define OS_OutPortByte(port, value)	outb(value, port)
331da177e4SLinus Torvalds #define OS_OutPortWord(port, value)	outw(value, port)
341da177e4SLinus Torvalds #define OS_OutPortLong(port, value)	outl(value, port)
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds /*
381da177e4SLinus Torvalds   Define name replacements for compatibility with the Linux BusLogic Driver.
391da177e4SLinus Torvalds */
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds #define SccbMgr_sense_adapter		FlashPoint_ProbeHostAdapter
421da177e4SLinus Torvalds #define SccbMgr_config_adapter		FlashPoint_HardwareResetHostAdapter
431da177e4SLinus Torvalds #define SccbMgr_unload_card		FlashPoint_ReleaseHostAdapter
441da177e4SLinus Torvalds #define SccbMgr_start_sccb		FlashPoint_StartCCB
451da177e4SLinus Torvalds #define SccbMgr_abort_sccb		FlashPoint_AbortCCB
461da177e4SLinus Torvalds #define SccbMgr_my_int			FlashPoint_InterruptPending
471da177e4SLinus Torvalds #define SccbMgr_isr			FlashPoint_HandleInterrupt
481da177e4SLinus Torvalds 
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds #define CRCMASK	0xA001
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds #define FAILURE         0xFFFFFFFFL
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds typedef unsigned char   UCHAR;
601da177e4SLinus Torvalds typedef unsigned short  USHORT;
611da177e4SLinus Torvalds typedef unsigned int    UINT;
621da177e4SLinus Torvalds typedef unsigned long   ULONG;
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds typedef unsigned short          * ushort_ptr;
661da177e4SLinus Torvalds 
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds #define s08bits	char
691da177e4SLinus Torvalds #define s16bits 	short
701da177e4SLinus Torvalds #define s32bits	long
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds #define u08bits	unsigned s08bits
731da177e4SLinus Torvalds #define u16bits	unsigned s16bits
741da177e4SLinus Torvalds #define u32bits	unsigned s32bits
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds #define BIT(x)          ((UCHAR)(1<<(x)))    /* single-bit mask in bit position x */
791da177e4SLinus Torvalds #define BITW(x)          ((USHORT)(1<<(x)))  /* single-bit mask in bit position x */
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 
841da177e4SLinus Torvalds typedef struct _SCCB *PSCCB;
851da177e4SLinus Torvalds typedef void (*CALL_BK_FN)(PSCCB);
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds 
881da177e4SLinus Torvalds typedef struct SCCBMgr_info {
891da177e4SLinus Torvalds    ULONG    si_baseaddr;
901da177e4SLinus Torvalds    UCHAR    si_present;
911da177e4SLinus Torvalds    UCHAR    si_intvect;
921da177e4SLinus Torvalds    UCHAR    si_id;
931da177e4SLinus Torvalds    UCHAR    si_lun;
941da177e4SLinus Torvalds    USHORT   si_fw_revision;
951da177e4SLinus Torvalds    USHORT   si_per_targ_init_sync;
961da177e4SLinus Torvalds    USHORT   si_per_targ_fast_nego;
971da177e4SLinus Torvalds    USHORT   si_per_targ_ultra_nego;
981da177e4SLinus Torvalds    USHORT   si_per_targ_no_disc;
991da177e4SLinus Torvalds    USHORT   si_per_targ_wide_nego;
1001da177e4SLinus Torvalds    USHORT   si_flags;
1011da177e4SLinus Torvalds    UCHAR    si_card_family;
1021da177e4SLinus Torvalds    UCHAR    si_bustype;
1031da177e4SLinus Torvalds    UCHAR    si_card_model[3];
1041da177e4SLinus Torvalds    UCHAR    si_relative_cardnum;
1051da177e4SLinus Torvalds    UCHAR    si_reserved[4];
1061da177e4SLinus Torvalds    ULONG    si_OS_reserved;
1071da177e4SLinus Torvalds    UCHAR    si_XlatInfo[4];
1081da177e4SLinus Torvalds    ULONG    si_reserved2[5];
1091da177e4SLinus Torvalds    ULONG    si_secondary_range;
1101da177e4SLinus Torvalds } SCCBMGR_INFO;
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds #define SCSI_PARITY_ENA		  0x0001
1161da177e4SLinus Torvalds #define LOW_BYTE_TERM		  0x0010
1171da177e4SLinus Torvalds #define HIGH_BYTE_TERM		  0x0020
1181da177e4SLinus Torvalds #define BUSTYPE_PCI	  0x3
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds #define SUPPORT_16TAR_32LUN	  0x0002
1211da177e4SLinus Torvalds #define SOFT_RESET		  0x0004
1221da177e4SLinus Torvalds #define EXTENDED_TRANSLATION	  0x0008
1231da177e4SLinus Torvalds #define POST_ALL_UNDERRRUNS	  0x0040
1241da177e4SLinus Torvalds #define FLAG_SCAM_ENABLED	  0x0080
1251da177e4SLinus Torvalds #define FLAG_SCAM_LEVEL2	  0x0100
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds #define HARPOON_FAMILY        0x02
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds 
13432357988SAlexey Dobriyan /* SCCB struct used for both SCCB and UCB manager compiles!
1351da177e4SLinus Torvalds  * The UCB Manager treats the SCCB as it's 'native hardware structure'
1361da177e4SLinus Torvalds  */
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds #pragma pack(1)
1401da177e4SLinus Torvalds typedef struct _SCCB {
1411da177e4SLinus Torvalds    UCHAR OperationCode;
1421da177e4SLinus Torvalds    UCHAR ControlByte;
1431da177e4SLinus Torvalds    UCHAR CdbLength;
1441da177e4SLinus Torvalds    UCHAR RequestSenseLength;
1451da177e4SLinus Torvalds    ULONG DataLength;
1461da177e4SLinus Torvalds    ULONG DataPointer;
1471da177e4SLinus Torvalds    UCHAR CcbRes[2];
1481da177e4SLinus Torvalds    UCHAR HostStatus;
1491da177e4SLinus Torvalds    UCHAR TargetStatus;
1501da177e4SLinus Torvalds    UCHAR TargID;
1511da177e4SLinus Torvalds    UCHAR Lun;
1521da177e4SLinus Torvalds    UCHAR Cdb[12];
1531da177e4SLinus Torvalds    UCHAR CcbRes1;
1541da177e4SLinus Torvalds    UCHAR Reserved1;
1551da177e4SLinus Torvalds    ULONG Reserved2;
1561da177e4SLinus Torvalds    ULONG SensePointer;
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds 
1591da177e4SLinus Torvalds    CALL_BK_FN SccbCallback;                  /* VOID (*SccbCallback)(); */
1601da177e4SLinus Torvalds    ULONG  SccbIOPort;                        /* Identifies board base port */
1611da177e4SLinus Torvalds    UCHAR  SccbStatus;
1621da177e4SLinus Torvalds    UCHAR  SCCBRes2;
1631da177e4SLinus Torvalds    USHORT SccbOSFlags;
1641da177e4SLinus Torvalds 
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds    ULONG   Sccb_XferCnt;            /* actual transfer count */
1671da177e4SLinus Torvalds    ULONG   Sccb_ATC;
1681da177e4SLinus Torvalds    ULONG   SccbVirtDataPtr;         /* virtual addr for OS/2 */
1691da177e4SLinus Torvalds    ULONG   Sccb_res1;
1701da177e4SLinus Torvalds    USHORT  Sccb_MGRFlags;
1711da177e4SLinus Torvalds    USHORT  Sccb_sgseg;
1721da177e4SLinus Torvalds    UCHAR   Sccb_scsimsg;            /* identify msg for selection */
1731da177e4SLinus Torvalds    UCHAR   Sccb_tag;
1741da177e4SLinus Torvalds    UCHAR   Sccb_scsistat;
1751da177e4SLinus Torvalds    UCHAR   Sccb_idmsg;              /* image of last msg in */
1761da177e4SLinus Torvalds    PSCCB   Sccb_forwardlink;
1771da177e4SLinus Torvalds    PSCCB   Sccb_backlink;
1781da177e4SLinus Torvalds    ULONG   Sccb_savedATC;
1791da177e4SLinus Torvalds    UCHAR   Save_Cdb[6];
1801da177e4SLinus Torvalds    UCHAR   Save_CdbLen;
1811da177e4SLinus Torvalds    UCHAR   Sccb_XferState;
1821da177e4SLinus Torvalds    ULONG   Sccb_SGoffset;
1831da177e4SLinus Torvalds    } SCCB;
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds 
1861da177e4SLinus Torvalds #pragma pack()
1871da177e4SLinus Torvalds 
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds #define SCATTER_GATHER_COMMAND    0x02
1911da177e4SLinus Torvalds #define RESIDUAL_COMMAND          0x03
1921da177e4SLinus Torvalds #define RESIDUAL_SG_COMMAND       0x04
1931da177e4SLinus Torvalds #define RESET_COMMAND             0x81
1941da177e4SLinus Torvalds 
1951da177e4SLinus Torvalds 
1961da177e4SLinus Torvalds #define F_USE_CMD_Q              0x20     /*Inidcates TAGGED command. */
1971da177e4SLinus Torvalds #define TAG_TYPE_MASK            0xC0     /*Type of tag msg to send. */
1981da177e4SLinus Torvalds #define SCCB_DATA_XFER_OUT       0x10     /* Write */
1991da177e4SLinus Torvalds #define SCCB_DATA_XFER_IN        0x08     /* Read */
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds #define NO_AUTO_REQUEST_SENSE    0x01     /* No Request Sense Buffer */
2031da177e4SLinus Torvalds 
2041da177e4SLinus Torvalds 
2051da177e4SLinus Torvalds #define BUS_FREE_ST     0
2061da177e4SLinus Torvalds #define SELECT_ST       1
2071da177e4SLinus Torvalds #define SELECT_BDR_ST   2     /* Select w\ Bus Device Reset */
2081da177e4SLinus Torvalds #define SELECT_SN_ST    3     /* Select w\ Sync Nego */
2091da177e4SLinus Torvalds #define SELECT_WN_ST    4     /* Select w\ Wide Data Nego */
2101da177e4SLinus Torvalds #define SELECT_Q_ST     5     /* Select w\ Tagged Q'ing */
2111da177e4SLinus Torvalds #define COMMAND_ST      6
2121da177e4SLinus Torvalds #define DATA_OUT_ST     7
2131da177e4SLinus Torvalds #define DATA_IN_ST      8
2141da177e4SLinus Torvalds #define DISCONNECT_ST   9
2151da177e4SLinus Torvalds #define ABORT_ST        11
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds #define F_HOST_XFER_DIR                0x01
2191da177e4SLinus Torvalds #define F_ALL_XFERRED                  0x02
2201da177e4SLinus Torvalds #define F_SG_XFER                      0x04
2211da177e4SLinus Torvalds #define F_AUTO_SENSE                   0x08
2221da177e4SLinus Torvalds #define F_ODD_BALL_CNT                 0x10
2231da177e4SLinus Torvalds #define F_NO_DATA_YET                  0x80
2241da177e4SLinus Torvalds 
2251da177e4SLinus Torvalds 
2261da177e4SLinus Torvalds #define F_STATUSLOADED                 0x01
2271da177e4SLinus Torvalds #define F_DEV_SELECTED                 0x04
2281da177e4SLinus Torvalds 
2291da177e4SLinus Torvalds 
2301da177e4SLinus Torvalds #define SCCB_COMPLETE               0x00  /* SCCB completed without error */
2311da177e4SLinus Torvalds #define SCCB_DATA_UNDER_RUN         0x0C
2321da177e4SLinus Torvalds #define SCCB_SELECTION_TIMEOUT      0x11  /* Set SCSI selection timed out */
2331da177e4SLinus Torvalds #define SCCB_DATA_OVER_RUN          0x12
2341da177e4SLinus Torvalds #define SCCB_PHASE_SEQUENCE_FAIL    0x14  /* Target bus phase sequence failure */
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds #define SCCB_GROSS_FW_ERR           0x27  /* Major problem! */
2371da177e4SLinus Torvalds #define SCCB_BM_ERR                 0x30  /* BusMaster error. */
2381da177e4SLinus Torvalds #define SCCB_PARITY_ERR             0x34  /* SCSI parity error */
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds 
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds 
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds #define SCCB_IN_PROCESS            0x00
2451da177e4SLinus Torvalds #define SCCB_SUCCESS               0x01
2461da177e4SLinus Torvalds #define SCCB_ABORT                 0x02
2471da177e4SLinus Torvalds #define SCCB_ERROR                 0x04
2481da177e4SLinus Torvalds 
2491da177e4SLinus Torvalds 
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds #define  ORION_FW_REV      3110
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds #define QUEUE_DEPTH     254+1            /*1 for Normal disconnect 32 for Q'ing. */
2561da177e4SLinus Torvalds 
2571da177e4SLinus Torvalds #define	MAX_MB_CARDS	4					/* Max. no of cards suppoerted on Mother Board */
2581da177e4SLinus Torvalds 
2591da177e4SLinus Torvalds 
2601da177e4SLinus Torvalds #define MAX_SCSI_TAR    16
2611da177e4SLinus Torvalds #define MAX_LUN         32
2621da177e4SLinus Torvalds #define LUN_MASK			0x1f
2631da177e4SLinus Torvalds 
2641da177e4SLinus Torvalds #define SG_BUF_CNT      16             /*Number of prefetched elements. */
2651da177e4SLinus Torvalds 
2661da177e4SLinus Torvalds #define SG_ELEMENT_SIZE 8              /*Eight byte per element. */
2671da177e4SLinus Torvalds 
2681da177e4SLinus Torvalds 
2691da177e4SLinus Torvalds #define RD_HARPOON(ioport)          OS_InPortByte((u32bits)ioport)
2701da177e4SLinus Torvalds #define RDW_HARPOON(ioport)         OS_InPortWord((u32bits)ioport)
2711da177e4SLinus Torvalds #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
2721da177e4SLinus Torvalds #define WR_HARPOON(ioport,val)      OS_OutPortByte((u32bits)ioport,(u08bits) val)
2731da177e4SLinus Torvalds #define WRW_HARPOON(ioport,val)       OS_OutPortWord((u32bits)ioport,(u16bits)val)
2741da177e4SLinus Torvalds #define WR_HARP32(ioport,offset,data)  OS_OutPortLong((u32bits)(ioport + offset), data)
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds 
2771da177e4SLinus Torvalds #define  TAR_SYNC_MASK     (BIT(7)+BIT(6))
2781da177e4SLinus Torvalds #define  SYNC_TRYING               BIT(6)
2791da177e4SLinus Torvalds #define  SYNC_SUPPORTED    (BIT(7)+BIT(6))
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds #define  TAR_WIDE_MASK     (BIT(5)+BIT(4))
2821da177e4SLinus Torvalds #define  WIDE_ENABLED              BIT(4)
2831da177e4SLinus Torvalds #define  WIDE_NEGOCIATED   BIT(5)
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds #define  TAR_TAG_Q_MASK    (BIT(3)+BIT(2))
2861da177e4SLinus Torvalds #define  TAG_Q_TRYING              BIT(2)
2871da177e4SLinus Torvalds #define  TAG_Q_REJECT      BIT(3)
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds #define  TAR_ALLOW_DISC    BIT(0)
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds 
2921da177e4SLinus Torvalds #define  EE_SYNC_MASK      (BIT(0)+BIT(1))
2931da177e4SLinus Torvalds #define  EE_SYNC_5MB       BIT(0)
2941da177e4SLinus Torvalds #define  EE_SYNC_10MB      BIT(1)
2951da177e4SLinus Torvalds #define  EE_SYNC_20MB      (BIT(0)+BIT(1))
2961da177e4SLinus Torvalds 
2971da177e4SLinus Torvalds #define  EE_WIDE_SCSI      BIT(7)
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds 
3001da177e4SLinus Torvalds typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
3011da177e4SLinus Torvalds 
3021da177e4SLinus Torvalds 
3031da177e4SLinus Torvalds typedef struct SCCBMgr_tar_info {
3041da177e4SLinus Torvalds 
3051da177e4SLinus Torvalds    PSCCB    TarSelQ_Head;
3061da177e4SLinus Torvalds    PSCCB    TarSelQ_Tail;
3071da177e4SLinus Torvalds    UCHAR    TarLUN_CA;        /*Contingent Allgiance */
3081da177e4SLinus Torvalds    UCHAR    TarTagQ_Cnt;
3091da177e4SLinus Torvalds    UCHAR    TarSelQ_Cnt;
3101da177e4SLinus Torvalds    UCHAR    TarStatus;
3111da177e4SLinus Torvalds    UCHAR    TarEEValue;
3121da177e4SLinus Torvalds    UCHAR 	TarSyncCtrl;
3131da177e4SLinus Torvalds    UCHAR 	TarReserved[2];			/* for alignment */
3141da177e4SLinus Torvalds    UCHAR 	LunDiscQ_Idx[MAX_LUN];
3151da177e4SLinus Torvalds    UCHAR    TarLUNBusy[MAX_LUN];
3161da177e4SLinus Torvalds } SCCBMGR_TAR_INFO;
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds typedef struct NVRAMInfo {
3191da177e4SLinus Torvalds 	UCHAR		niModel;								/* Model No. of card */
3201da177e4SLinus Torvalds 	UCHAR		niCardNo;							/* Card no. */
3211da177e4SLinus Torvalds 	ULONG		niBaseAddr;							/* Port Address of card */
3221da177e4SLinus Torvalds 	UCHAR		niSysConf;							/* Adapter Configuration byte - Byte 16 of eeprom map */
3231da177e4SLinus Torvalds 	UCHAR		niScsiConf;							/* SCSI Configuration byte - Byte 17 of eeprom map */
3241da177e4SLinus Torvalds 	UCHAR		niScamConf;							/* SCAM Configuration byte - Byte 20 of eeprom map */
3251da177e4SLinus Torvalds 	UCHAR		niAdapId;							/* Host Adapter ID - Byte 24 of eerpom map */
3261da177e4SLinus Torvalds 	UCHAR		niSyncTbl[MAX_SCSI_TAR / 2];	/* Sync/Wide byte of targets */
3271da177e4SLinus Torvalds 	UCHAR		niScamTbl[MAX_SCSI_TAR][4];	/* Compressed Scam name string of Targets */
3281da177e4SLinus Torvalds }NVRAMINFO;
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds typedef NVRAMINFO *PNVRamInfo;
3311da177e4SLinus Torvalds 
3321da177e4SLinus Torvalds #define	MODEL_LT		1
3331da177e4SLinus Torvalds #define	MODEL_DL		2
3341da177e4SLinus Torvalds #define	MODEL_LW		3
3351da177e4SLinus Torvalds #define	MODEL_DW		4
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds 
3381da177e4SLinus Torvalds typedef struct SCCBcard {
3391da177e4SLinus Torvalds    PSCCB currentSCCB;
3401da177e4SLinus Torvalds    PSCCBMGR_INFO cardInfo;
3411da177e4SLinus Torvalds 
3421da177e4SLinus Torvalds    ULONG ioPort;
3431da177e4SLinus Torvalds 
3441da177e4SLinus Torvalds    USHORT cmdCounter;
3451da177e4SLinus Torvalds    UCHAR  discQCount;
3461da177e4SLinus Torvalds    UCHAR  tagQ_Lst;
3471da177e4SLinus Torvalds    UCHAR cardIndex;
3481da177e4SLinus Torvalds    UCHAR scanIndex;
3491da177e4SLinus Torvalds    UCHAR globalFlags;
3501da177e4SLinus Torvalds    UCHAR ourId;
3511da177e4SLinus Torvalds    PNVRamInfo pNvRamInfo;
3521da177e4SLinus Torvalds    PSCCB discQ_Tbl[QUEUE_DEPTH];
3531da177e4SLinus Torvalds 
3541da177e4SLinus Torvalds }SCCBCARD;
3551da177e4SLinus Torvalds 
3561da177e4SLinus Torvalds typedef struct SCCBcard *PSCCBcard;
3571da177e4SLinus Torvalds 
3581da177e4SLinus Torvalds 
3591da177e4SLinus Torvalds #define F_TAG_STARTED		0x01
3601da177e4SLinus Torvalds #define F_CONLUN_IO			0x02
3611da177e4SLinus Torvalds #define F_DO_RENEGO			0x04
3621da177e4SLinus Torvalds #define F_NO_FILTER			0x08
3631da177e4SLinus Torvalds #define F_GREEN_PC			0x10
3641da177e4SLinus Torvalds #define F_HOST_XFER_ACT		0x20
3651da177e4SLinus Torvalds #define F_NEW_SCCB_CMD		0x40
3661da177e4SLinus Torvalds #define F_UPDATE_EEPROM		0x80
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds 
3691da177e4SLinus Torvalds #define  ID_STRING_LENGTH  32
3701da177e4SLinus Torvalds #define  TYPE_CODE0        0x63           /*Level2 Mstr (bits 7-6),  */
3711da177e4SLinus Torvalds 
3721da177e4SLinus Torvalds 
3731da177e4SLinus Torvalds #define  SLV_TYPE_CODE0    0xA3           /*Priority Bit set (bits 7-6),  */
3741da177e4SLinus Torvalds 
3751da177e4SLinus Torvalds #define  ASSIGN_ID   0x00
3761da177e4SLinus Torvalds #define  SET_P_FLAG  0x01
3771da177e4SLinus Torvalds #define  CFG_CMPLT   0x03
3781da177e4SLinus Torvalds #define  DOM_MSTR    0x0F
3791da177e4SLinus Torvalds #define  SYNC_PTRN   0x1F
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds #define  ID_0_7      0x18
3821da177e4SLinus Torvalds #define  ID_8_F      0x11
3831da177e4SLinus Torvalds #define  MISC_CODE   0x14
3841da177e4SLinus Torvalds #define  CLR_P_FLAG  0x18
3851da177e4SLinus Torvalds 
3861da177e4SLinus Torvalds 
3871da177e4SLinus Torvalds 
3881da177e4SLinus Torvalds #define  INIT_SELTD  0x01
3891da177e4SLinus Torvalds #define  LEVEL2_TAR  0x02
3901da177e4SLinus Torvalds 
3911da177e4SLinus Torvalds 
3921da177e4SLinus Torvalds enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
3931da177e4SLinus Torvalds                   ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
3941da177e4SLinus Torvalds                   CLR_PRIORITY,NO_ID_AVAIL };
3951da177e4SLinus Torvalds 
3961da177e4SLinus Torvalds typedef struct SCCBscam_info {
3971da177e4SLinus Torvalds 
3981da177e4SLinus Torvalds    UCHAR    id_string[ID_STRING_LENGTH];
3991da177e4SLinus Torvalds    enum scam_id_st state;
4001da177e4SLinus Torvalds 
401*85ae97d8SAlexey Dobriyan } SCCBSCAM_INFO;
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds 
4041da177e4SLinus Torvalds #define  SCSI_REQUEST_SENSE      0x03
4051da177e4SLinus Torvalds #define  SCSI_READ               0x08
4061da177e4SLinus Torvalds #define  SCSI_WRITE              0x0A
4071da177e4SLinus Torvalds #define  SCSI_START_STOP_UNIT    0x1B
4081da177e4SLinus Torvalds #define  SCSI_READ_EXTENDED      0x28
4091da177e4SLinus Torvalds #define  SCSI_WRITE_EXTENDED     0x2A
4101da177e4SLinus Torvalds #define  SCSI_WRITE_AND_VERIFY   0x2E
4111da177e4SLinus Torvalds 
4121da177e4SLinus Torvalds 
4131da177e4SLinus Torvalds 
4141da177e4SLinus Torvalds #define  SSGOOD                  0x00
4151da177e4SLinus Torvalds #define  SSCHECK                 0x02
4161da177e4SLinus Torvalds #define  SSQ_FULL                0x28
4171da177e4SLinus Torvalds 
4181da177e4SLinus Torvalds 
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds #define  SMCMD_COMP              0x00
4221da177e4SLinus Torvalds #define  SMEXT                   0x01
4231da177e4SLinus Torvalds #define  SMSAVE_DATA_PTR         0x02
4241da177e4SLinus Torvalds #define  SMREST_DATA_PTR         0x03
4251da177e4SLinus Torvalds #define  SMDISC                  0x04
4261da177e4SLinus Torvalds #define  SMABORT                 0x06
4271da177e4SLinus Torvalds #define  SMREJECT                0x07
4281da177e4SLinus Torvalds #define  SMNO_OP                 0x08
4291da177e4SLinus Torvalds #define  SMPARITY                0x09
4301da177e4SLinus Torvalds #define  SMDEV_RESET             0x0C
4311da177e4SLinus Torvalds #define	SMABORT_TAG					0x0D
4321da177e4SLinus Torvalds #define	SMINIT_RECOVERY			0x0F
4331da177e4SLinus Torvalds #define	SMREL_RECOVERY				0x10
4341da177e4SLinus Torvalds 
4351da177e4SLinus Torvalds #define  SMIDENT                 0x80
4361da177e4SLinus Torvalds #define  DISC_PRIV               0x40
4371da177e4SLinus Torvalds 
4381da177e4SLinus Torvalds 
4391da177e4SLinus Torvalds #define  SMSYNC                  0x01
4401da177e4SLinus Torvalds #define  SMWDTR                  0x03
4411da177e4SLinus Torvalds #define  SM8BIT                  0x00
4421da177e4SLinus Torvalds #define  SM16BIT                 0x01
4431da177e4SLinus Torvalds #define  SMIGNORWR               0x23     /* Ignore Wide Residue */
4441da177e4SLinus Torvalds 
4451da177e4SLinus Torvalds 
4461da177e4SLinus Torvalds 
4471da177e4SLinus Torvalds 
4481da177e4SLinus Torvalds 
4491da177e4SLinus Torvalds 
4501da177e4SLinus Torvalds 
4511da177e4SLinus Torvalds 
4521da177e4SLinus Torvalds #define  SIX_BYTE_CMD            0x06
4531da177e4SLinus Torvalds #define  TWELVE_BYTE_CMD         0x0C
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds #define  ASYNC                   0x00
4561da177e4SLinus Torvalds #define  MAX_OFFSET              0x0F  /* Maxbyteoffset for Sync Xfers */
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds 
4591da177e4SLinus Torvalds #define  EEPROM_WD_CNT     256
4601da177e4SLinus Torvalds 
4611da177e4SLinus Torvalds #define  EEPROM_CHECK_SUM  0
4621da177e4SLinus Torvalds #define  FW_SIGNATURE      2
4631da177e4SLinus Torvalds #define  MODEL_NUMB_0      4
4641da177e4SLinus Torvalds #define  MODEL_NUMB_2      6
4651da177e4SLinus Torvalds #define  MODEL_NUMB_4      8
4661da177e4SLinus Torvalds #define  SYSTEM_CONFIG     16
4671da177e4SLinus Torvalds #define  SCSI_CONFIG       17
4681da177e4SLinus Torvalds #define  BIOS_CONFIG       18
4691da177e4SLinus Torvalds #define  SCAM_CONFIG       20
4701da177e4SLinus Torvalds #define  ADAPTER_SCSI_ID   24
4711da177e4SLinus Torvalds 
4721da177e4SLinus Torvalds 
4731da177e4SLinus Torvalds #define  IGNORE_B_SCAN     32
4741da177e4SLinus Torvalds #define  SEND_START_ENA    34
4751da177e4SLinus Torvalds #define  DEVICE_ENABLE     36
4761da177e4SLinus Torvalds 
4771da177e4SLinus Torvalds #define  SYNC_RATE_TBL     38
4781da177e4SLinus Torvalds #define  SYNC_RATE_TBL01   38
4791da177e4SLinus Torvalds #define  SYNC_RATE_TBL23   40
4801da177e4SLinus Torvalds #define  SYNC_RATE_TBL45   42
4811da177e4SLinus Torvalds #define  SYNC_RATE_TBL67   44
4821da177e4SLinus Torvalds #define  SYNC_RATE_TBL89   46
4831da177e4SLinus Torvalds #define  SYNC_RATE_TBLab   48
4841da177e4SLinus Torvalds #define  SYNC_RATE_TBLcd   50
4851da177e4SLinus Torvalds #define  SYNC_RATE_TBLef   52
4861da177e4SLinus Torvalds 
4871da177e4SLinus Torvalds 
4881da177e4SLinus Torvalds 
4891da177e4SLinus Torvalds #define  EE_SCAMBASE      256
4901da177e4SLinus Torvalds 
4911da177e4SLinus Torvalds 
4921da177e4SLinus Torvalds 
4931da177e4SLinus Torvalds    #define  SCAM_ENABLED   BIT(2)
4941da177e4SLinus Torvalds    #define  SCAM_LEVEL2    BIT(3)
4951da177e4SLinus Torvalds 
4961da177e4SLinus Torvalds 
4971da177e4SLinus Torvalds 	#define	RENEGO_ENA		BITW(10)
4981da177e4SLinus Torvalds 	#define	CONNIO_ENA		BITW(11)
4991da177e4SLinus Torvalds    #define  GREEN_PC_ENA   BITW(12)
5001da177e4SLinus Torvalds 
5011da177e4SLinus Torvalds 
5021da177e4SLinus Torvalds    #define  AUTO_RATE_00   00
5031da177e4SLinus Torvalds    #define  AUTO_RATE_05   01
5041da177e4SLinus Torvalds    #define  AUTO_RATE_10   02
5051da177e4SLinus Torvalds    #define  AUTO_RATE_20   03
5061da177e4SLinus Torvalds 
5071da177e4SLinus Torvalds    #define  WIDE_NEGO_BIT     BIT(7)
5081da177e4SLinus Torvalds    #define  DISC_ENABLE_BIT   BIT(6)
5091da177e4SLinus Torvalds 
5101da177e4SLinus Torvalds 
5111da177e4SLinus Torvalds 
5121da177e4SLinus Torvalds    #define  hp_vendor_id_0       0x00		/* LSB */
5131da177e4SLinus Torvalds       #define  ORION_VEND_0   0x4B
5141da177e4SLinus Torvalds 
5151da177e4SLinus Torvalds    #define  hp_vendor_id_1       0x01		/* MSB */
5161da177e4SLinus Torvalds       #define  ORION_VEND_1   0x10
5171da177e4SLinus Torvalds 
5181da177e4SLinus Torvalds    #define  hp_device_id_0       0x02		/* LSB */
5191da177e4SLinus Torvalds       #define  ORION_DEV_0    0x30
5201da177e4SLinus Torvalds 
5211da177e4SLinus Torvalds    #define  hp_device_id_1       0x03		/* MSB */
5221da177e4SLinus Torvalds       #define  ORION_DEV_1    0x81
5231da177e4SLinus Torvalds 
5241da177e4SLinus Torvalds 	/* Sub Vendor ID and Sub Device ID only available in
5251da177e4SLinus Torvalds 		Harpoon Version 2 and higher */
5261da177e4SLinus Torvalds 
5271da177e4SLinus Torvalds    #define  hp_sub_device_id_0   0x06		/* LSB */
5281da177e4SLinus Torvalds 
5291da177e4SLinus Torvalds 
5301da177e4SLinus Torvalds 
5311da177e4SLinus Torvalds    #define  hp_semaphore         0x0C
5321da177e4SLinus Torvalds       #define SCCB_MGR_ACTIVE    BIT(0)
5331da177e4SLinus Torvalds       #define TICKLE_ME          BIT(1)
5341da177e4SLinus Torvalds       #define SCCB_MGR_PRESENT   BIT(3)
5351da177e4SLinus Torvalds       #define BIOS_IN_USE        BIT(4)
5361da177e4SLinus Torvalds 
5371da177e4SLinus Torvalds 
5381da177e4SLinus Torvalds 
5391da177e4SLinus Torvalds    #define  hp_sys_ctrl          0x0F
5401da177e4SLinus Torvalds 
5411da177e4SLinus Torvalds       #define  STOP_CLK          BIT(0)      /*Turn off BusMaster Clock */
5421da177e4SLinus Torvalds       #define  DRVR_RST          BIT(1)      /*Firmware Reset to 80C15 chip */
5431da177e4SLinus Torvalds       #define  HALT_MACH         BIT(3)      /*Halt State Machine      */
5441da177e4SLinus Torvalds       #define  HARD_ABORT        BIT(4)      /*Hard Abort              */
5451da177e4SLinus Torvalds 
5461da177e4SLinus Torvalds 
5471da177e4SLinus Torvalds 
5481da177e4SLinus Torvalds 
5491da177e4SLinus Torvalds 
550*85ae97d8SAlexey Dobriyan 
551*85ae97d8SAlexey Dobriyan 
552*85ae97d8SAlexey Dobriyan 
5531da177e4SLinus Torvalds 
5541da177e4SLinus Torvalds    #define  hp_host_blk_cnt      0x13
5551da177e4SLinus Torvalds 
5561da177e4SLinus Torvalds       #define  XFER_BLK64        0x06     /*     1 1 0 64 byte per block*/
5571da177e4SLinus Torvalds 
5581da177e4SLinus Torvalds       #define  BM_THRESHOLD      0x40     /* PCI mode can only xfer 16 bytes*/
5591da177e4SLinus Torvalds 
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds 
5621da177e4SLinus Torvalds    #define  hp_int_mask          0x17
5631da177e4SLinus Torvalds 
5641da177e4SLinus Torvalds       #define  INT_CMD_COMPL     BIT(0)   /* DMA command complete   */
5651da177e4SLinus Torvalds       #define  INT_EXT_STATUS    BIT(1)   /* Extended Status Set    */
5661da177e4SLinus Torvalds 
5671da177e4SLinus Torvalds 
5681da177e4SLinus Torvalds    #define  hp_xfer_cnt_lo       0x18
5691da177e4SLinus Torvalds    #define  hp_xfer_cnt_hi       0x1A
5701da177e4SLinus Torvalds    #define  hp_xfer_cmd          0x1B
5711da177e4SLinus Torvalds 
5721da177e4SLinus Torvalds       #define  XFER_HOST_DMA     0x00     /*     0 0 0 Transfer Host -> DMA */
5731da177e4SLinus Torvalds       #define  XFER_DMA_HOST     0x01     /*     0 0 1 Transfer DMA  -> Host */
5741da177e4SLinus Torvalds 
5751da177e4SLinus Torvalds 
5761da177e4SLinus Torvalds       #define  XFER_HOST_AUTO    0x00     /*     0 0 Auto Transfer Size   */
5771da177e4SLinus Torvalds 
5781da177e4SLinus Torvalds       #define  XFER_DMA_8BIT     0x20     /*     0 1 8 BIT  Transfer Size */
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds       #define  DISABLE_INT       BIT(7)   /*Do not interrupt at end of cmd. */
5811da177e4SLinus Torvalds 
5821da177e4SLinus Torvalds       #define  HOST_WRT_CMD      ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
5831da177e4SLinus Torvalds       #define  HOST_RD_CMD       ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
5841da177e4SLinus Torvalds 
5851da177e4SLinus Torvalds    #define  hp_host_addr_lo      0x1C
5861da177e4SLinus Torvalds    #define  hp_host_addr_hmi     0x1E
5871da177e4SLinus Torvalds 
5881da177e4SLinus Torvalds    #define  hp_ee_ctrl           0x22
5891da177e4SLinus Torvalds 
5901da177e4SLinus Torvalds       #define  EXT_ARB_ACK       BIT(7)
5911da177e4SLinus Torvalds       #define  SCSI_TERM_ENA_H   BIT(6)   /* SCSI high byte terminator */
5921da177e4SLinus Torvalds       #define  SEE_MS            BIT(5)
5931da177e4SLinus Torvalds       #define  SEE_CS            BIT(3)
5941da177e4SLinus Torvalds       #define  SEE_CLK           BIT(2)
5951da177e4SLinus Torvalds       #define  SEE_DO            BIT(1)
5961da177e4SLinus Torvalds       #define  SEE_DI            BIT(0)
5971da177e4SLinus Torvalds 
5981da177e4SLinus Torvalds       #define  EE_READ           0x06
5991da177e4SLinus Torvalds       #define  EE_WRITE          0x05
6001da177e4SLinus Torvalds       #define  EWEN              0x04
6011da177e4SLinus Torvalds       #define  EWEN_ADDR         0x03C0
6021da177e4SLinus Torvalds       #define  EWDS              0x04
6031da177e4SLinus Torvalds       #define  EWDS_ADDR         0x0000
6041da177e4SLinus Torvalds 
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 
6081da177e4SLinus Torvalds 
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 
6111da177e4SLinus Torvalds    #define  hp_bm_ctrl           0x26
6121da177e4SLinus Torvalds 
6131da177e4SLinus Torvalds       #define  SCSI_TERM_ENA_L   BIT(0)   /*Enable/Disable external terminators */
6141da177e4SLinus Torvalds       #define  FLUSH_XFER_CNTR   BIT(1)   /*Flush transfer counter */
6151da177e4SLinus Torvalds       #define  FORCE1_XFER       BIT(5)   /*Always xfer one byte in byte mode */
6161da177e4SLinus Torvalds       #define  FAST_SINGLE       BIT(6)   /*?? */
6171da177e4SLinus Torvalds 
6181da177e4SLinus Torvalds       #define  BMCTRL_DEFAULT    (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
6191da177e4SLinus Torvalds 
6201da177e4SLinus Torvalds 
6211da177e4SLinus Torvalds    #define  hp_sg_addr           0x28
6221da177e4SLinus Torvalds    #define  hp_page_ctrl         0x29
6231da177e4SLinus Torvalds 
6241da177e4SLinus Torvalds       #define  SCATTER_EN        BIT(0)
6251da177e4SLinus Torvalds       #define  SGRAM_ARAM        BIT(1)
6261da177e4SLinus Torvalds       #define  G_INT_DISABLE     BIT(3)   /* Enable/Disable all Interrupts */
6271da177e4SLinus Torvalds       #define  NARROW_SCSI_CARD  BIT(4)   /* NARROW/WIDE SCSI config pin */
6281da177e4SLinus Torvalds 
6291da177e4SLinus Torvalds 
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 
6321da177e4SLinus Torvalds    #define  hp_pci_stat_cfg      0x2D
6331da177e4SLinus Torvalds 
6341da177e4SLinus Torvalds       #define  REC_MASTER_ABORT  BIT(5)   /*received Master abort */
6351da177e4SLinus Torvalds 
6361da177e4SLinus Torvalds 
6371da177e4SLinus Torvalds 
6381da177e4SLinus Torvalds 
6391da177e4SLinus Torvalds 
6401da177e4SLinus Torvalds 
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds 
6431da177e4SLinus Torvalds    #define  hp_rev_num           0x33
6441da177e4SLinus Torvalds 
6451da177e4SLinus Torvalds 
6461da177e4SLinus Torvalds    #define  hp_stack_data        0x34
6471da177e4SLinus Torvalds    #define  hp_stack_addr        0x35
6481da177e4SLinus Torvalds 
6491da177e4SLinus Torvalds    #define  hp_ext_status        0x36
6501da177e4SLinus Torvalds 
6511da177e4SLinus Torvalds       #define  BM_FORCE_OFF      BIT(0)   /*Bus Master is forced to get off */
6521da177e4SLinus Torvalds       #define  PCI_TGT_ABORT     BIT(0)   /*PCI bus master transaction aborted */
6531da177e4SLinus Torvalds       #define  PCI_DEV_TMOUT     BIT(1)   /*PCI Device Time out */
6541da177e4SLinus Torvalds       #define  CMD_ABORTED       BIT(4)   /*Command aborted */
6551da177e4SLinus Torvalds       #define  BM_PARITY_ERR     BIT(5)   /*parity error on data received   */
6561da177e4SLinus Torvalds       #define  PIO_OVERRUN       BIT(6)   /*Slave data overrun */
6571da177e4SLinus Torvalds       #define  BM_CMD_BUSY       BIT(7)   /*Bus master transfer command busy */
6581da177e4SLinus Torvalds       #define  BAD_EXT_STATUS    (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
6591da177e4SLinus Torvalds                                   BM_PARITY_ERR | PIO_OVERRUN)
6601da177e4SLinus Torvalds 
6611da177e4SLinus Torvalds    #define  hp_int_status        0x37
6621da177e4SLinus Torvalds 
6631da177e4SLinus Torvalds       #define  EXT_STATUS_ON     BIT(1)   /*Extended status is valid */
6641da177e4SLinus Torvalds       #define  SCSI_INTERRUPT    BIT(2)   /*Global indication of a SCSI int. */
6651da177e4SLinus Torvalds       #define  INT_ASSERTED      BIT(5)   /* */
6661da177e4SLinus Torvalds 
6671da177e4SLinus Torvalds 
6681da177e4SLinus Torvalds    #define  hp_fifo_cnt          0x38
6691da177e4SLinus Torvalds 
6701da177e4SLinus Torvalds 
6711da177e4SLinus Torvalds 
6721da177e4SLinus Torvalds 
6731da177e4SLinus Torvalds    #define  hp_intena		 0x40
6741da177e4SLinus Torvalds 
6751da177e4SLinus Torvalds       #define  RESET		 BITW(7)
6761da177e4SLinus Torvalds       #define  PROG_HLT		 BITW(6)
6771da177e4SLinus Torvalds       #define  PARITY		 BITW(5)
6781da177e4SLinus Torvalds       #define  FIFO		 BITW(4)
6791da177e4SLinus Torvalds       #define  SEL		 BITW(3)
6801da177e4SLinus Torvalds       #define  SCAM_SEL		 BITW(2)
6811da177e4SLinus Torvalds       #define  RSEL		 BITW(1)
6821da177e4SLinus Torvalds       #define  TIMEOUT		 BITW(0)
6831da177e4SLinus Torvalds       #define  BUS_FREE		 BITW(15)
6841da177e4SLinus Torvalds       #define  XFER_CNT_0	 BITW(14)
6851da177e4SLinus Torvalds       #define  PHASE		 BITW(13)
6861da177e4SLinus Torvalds       #define  IUNKWN		 BITW(12)
6871da177e4SLinus Torvalds       #define  ICMD_COMP	 BITW(11)
6881da177e4SLinus Torvalds       #define  ITICKLE		 BITW(10)
6891da177e4SLinus Torvalds       #define  IDO_STRT		 BITW(9)
6901da177e4SLinus Torvalds       #define  ITAR_DISC	 BITW(8)
6911da177e4SLinus Torvalds       #define  AUTO_INT		 (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
6921da177e4SLinus Torvalds       #define  CLR_ALL_INT	 0xFFFF
6931da177e4SLinus Torvalds       #define  CLR_ALL_INT_1	 0xFF00
6941da177e4SLinus Torvalds 
6951da177e4SLinus Torvalds    #define  hp_intstat		 0x42
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds    #define  hp_scsisig           0x44
6981da177e4SLinus Torvalds 
6991da177e4SLinus Torvalds       #define  SCSI_SEL          BIT(7)
7001da177e4SLinus Torvalds       #define  SCSI_BSY          BIT(6)
7011da177e4SLinus Torvalds       #define  SCSI_REQ          BIT(5)
7021da177e4SLinus Torvalds       #define  SCSI_ACK          BIT(4)
7031da177e4SLinus Torvalds       #define  SCSI_ATN          BIT(3)
7041da177e4SLinus Torvalds       #define  SCSI_CD           BIT(2)
7051da177e4SLinus Torvalds       #define  SCSI_MSG          BIT(1)
7061da177e4SLinus Torvalds       #define  SCSI_IOBIT        BIT(0)
7071da177e4SLinus Torvalds 
7081da177e4SLinus Torvalds       #define  S_SCSI_PHZ        (BIT(2)+BIT(1)+BIT(0))
7091da177e4SLinus Torvalds       #define  S_MSGO_PH         (BIT(2)+BIT(1)       )
7101da177e4SLinus Torvalds       #define  S_MSGI_PH         (BIT(2)+BIT(1)+BIT(0))
7111da177e4SLinus Torvalds       #define  S_DATAI_PH        (              BIT(0))
7121da177e4SLinus Torvalds       #define  S_DATAO_PH        0x00
7131da177e4SLinus Torvalds       #define  S_ILL_PH          (       BIT(1)       )
7141da177e4SLinus Torvalds 
7151da177e4SLinus Torvalds    #define  hp_scsictrl_0        0x45
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds       #define  SEL_TAR           BIT(6)
7181da177e4SLinus Torvalds       #define  ENA_ATN           BIT(4)
7191da177e4SLinus Torvalds       #define  ENA_RESEL         BIT(2)
7201da177e4SLinus Torvalds       #define  SCSI_RST          BIT(1)
7211da177e4SLinus Torvalds       #define  ENA_SCAM_SEL      BIT(0)
7221da177e4SLinus Torvalds 
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds 
7251da177e4SLinus Torvalds    #define  hp_portctrl_0        0x46
7261da177e4SLinus Torvalds 
7271da177e4SLinus Torvalds       #define  SCSI_PORT         BIT(7)
7281da177e4SLinus Torvalds       #define  SCSI_INBIT        BIT(6)
7291da177e4SLinus Torvalds       #define  DMA_PORT          BIT(5)
7301da177e4SLinus Torvalds       #define  DMA_RD            BIT(4)
7311da177e4SLinus Torvalds       #define  HOST_PORT         BIT(3)
7321da177e4SLinus Torvalds       #define  HOST_WRT          BIT(2)
7331da177e4SLinus Torvalds       #define  SCSI_BUS_EN       BIT(1)
7341da177e4SLinus Torvalds       #define  START_TO          BIT(0)
7351da177e4SLinus Torvalds 
7361da177e4SLinus Torvalds    #define  hp_scsireset         0x47
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds       #define  SCSI_INI          BIT(6)
7391da177e4SLinus Torvalds       #define  SCAM_EN           BIT(5)
7401da177e4SLinus Torvalds       #define  DMA_RESET         BIT(3)
7411da177e4SLinus Torvalds       #define  HPSCSI_RESET      BIT(2)
7421da177e4SLinus Torvalds       #define  PROG_RESET        BIT(1)
7431da177e4SLinus Torvalds       #define  FIFO_CLR          BIT(0)
7441da177e4SLinus Torvalds 
7451da177e4SLinus Torvalds    #define  hp_xfercnt_0         0x48
7461da177e4SLinus Torvalds    #define  hp_xfercnt_2         0x4A
7471da177e4SLinus Torvalds 
7481da177e4SLinus Torvalds    #define  hp_fifodata_0        0x4C
7491da177e4SLinus Torvalds    #define  hp_addstat           0x4E
7501da177e4SLinus Torvalds 
7511da177e4SLinus Torvalds       #define  SCAM_TIMER        BIT(7)
7521da177e4SLinus Torvalds       #define  SCSI_MODE8        BIT(3)
7531da177e4SLinus Torvalds       #define  SCSI_PAR_ERR      BIT(0)
7541da177e4SLinus Torvalds 
7551da177e4SLinus Torvalds    #define  hp_prgmcnt_0         0x4F
7561da177e4SLinus Torvalds 
7571da177e4SLinus Torvalds 
7581da177e4SLinus Torvalds    #define  hp_selfid_0          0x50
7591da177e4SLinus Torvalds    #define  hp_selfid_1          0x51
7601da177e4SLinus Torvalds    #define  hp_arb_id            0x52
7611da177e4SLinus Torvalds 
7621da177e4SLinus Torvalds 
7631da177e4SLinus Torvalds    #define  hp_select_id         0x53
7641da177e4SLinus Torvalds 
7651da177e4SLinus Torvalds 
7661da177e4SLinus Torvalds    #define  hp_synctarg_base     0x54
7671da177e4SLinus Torvalds    #define  hp_synctarg_12       0x54
7681da177e4SLinus Torvalds    #define  hp_synctarg_13       0x55
7691da177e4SLinus Torvalds    #define  hp_synctarg_14       0x56
7701da177e4SLinus Torvalds    #define  hp_synctarg_15       0x57
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds    #define  hp_synctarg_8        0x58
7731da177e4SLinus Torvalds    #define  hp_synctarg_9        0x59
7741da177e4SLinus Torvalds    #define  hp_synctarg_10       0x5A
7751da177e4SLinus Torvalds    #define  hp_synctarg_11       0x5B
7761da177e4SLinus Torvalds 
7771da177e4SLinus Torvalds    #define  hp_synctarg_4        0x5C
7781da177e4SLinus Torvalds    #define  hp_synctarg_5        0x5D
7791da177e4SLinus Torvalds    #define  hp_synctarg_6        0x5E
7801da177e4SLinus Torvalds    #define  hp_synctarg_7        0x5F
7811da177e4SLinus Torvalds 
7821da177e4SLinus Torvalds    #define  hp_synctarg_0        0x60
7831da177e4SLinus Torvalds    #define  hp_synctarg_1        0x61
7841da177e4SLinus Torvalds    #define  hp_synctarg_2        0x62
7851da177e4SLinus Torvalds    #define  hp_synctarg_3        0x63
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds       #define  NARROW_SCSI       BIT(4)
7881da177e4SLinus Torvalds       #define  DEFAULT_OFFSET    0x0F
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds    #define  hp_autostart_0       0x64
7911da177e4SLinus Torvalds    #define  hp_autostart_1       0x65
7921da177e4SLinus Torvalds    #define  hp_autostart_3       0x67
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds 
7951da177e4SLinus Torvalds 
7961da177e4SLinus Torvalds       #define  AUTO_IMMED    BIT(5)
7971da177e4SLinus Torvalds       #define  SELECT   BIT(6)
7981da177e4SLinus Torvalds       #define  END_DATA (BIT(7)+BIT(6))
7991da177e4SLinus Torvalds 
8001da177e4SLinus Torvalds    #define  hp_gp_reg_0          0x68
8011da177e4SLinus Torvalds    #define  hp_gp_reg_1          0x69
8021da177e4SLinus Torvalds    #define  hp_gp_reg_3          0x6B
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds    #define  hp_seltimeout        0x6C
8051da177e4SLinus Torvalds 
8061da177e4SLinus Torvalds 
8071da177e4SLinus Torvalds       #define  TO_4ms            0x67      /* 3.9959ms */
8081da177e4SLinus Torvalds 
8091da177e4SLinus Torvalds       #define  TO_5ms            0x03      /* 4.9152ms */
8101da177e4SLinus Torvalds       #define  TO_10ms           0x07      /* 11.xxxms */
8111da177e4SLinus Torvalds       #define  TO_250ms          0x99      /* 250.68ms */
8121da177e4SLinus Torvalds       #define  TO_290ms          0xB1      /* 289.99ms */
8131da177e4SLinus Torvalds 
8141da177e4SLinus Torvalds    #define  hp_clkctrl_0         0x6D
8151da177e4SLinus Torvalds 
8161da177e4SLinus Torvalds       #define  PWR_DWN           BIT(6)
8171da177e4SLinus Torvalds       #define  ACTdeassert       BIT(4)
8181da177e4SLinus Torvalds       #define  CLK_40MHZ         (BIT(1) + BIT(0))
8191da177e4SLinus Torvalds 
8201da177e4SLinus Torvalds       #define  CLKCTRL_DEFAULT   (ACTdeassert | CLK_40MHZ)
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds    #define  hp_fiforead          0x6E
8231da177e4SLinus Torvalds    #define  hp_fifowrite         0x6F
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds    #define  hp_offsetctr         0x70
8261da177e4SLinus Torvalds    #define  hp_xferstat          0x71
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds       #define  FIFO_EMPTY        BIT(6)
8291da177e4SLinus Torvalds 
8301da177e4SLinus Torvalds    #define  hp_portctrl_1        0x72
8311da177e4SLinus Torvalds 
8321da177e4SLinus Torvalds       #define  CHK_SCSI_P        BIT(3)
8331da177e4SLinus Torvalds       #define  HOST_MODE8        BIT(0)
8341da177e4SLinus Torvalds 
8351da177e4SLinus Torvalds    #define  hp_xfer_pad          0x73
8361da177e4SLinus Torvalds 
8371da177e4SLinus Torvalds       #define  ID_UNLOCK         BIT(3)
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds    #define  hp_scsidata_0        0x74
8401da177e4SLinus Torvalds    #define  hp_scsidata_1        0x75
8411da177e4SLinus Torvalds 
8421da177e4SLinus Torvalds 
8431da177e4SLinus Torvalds 
8441da177e4SLinus Torvalds    #define  hp_aramBase          0x80
8451da177e4SLinus Torvalds    #define  BIOS_DATA_OFFSET     0x60
8461da177e4SLinus Torvalds    #define  BIOS_RELATIVE_CARD   0x64
8471da177e4SLinus Torvalds 
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds 
8511da177e4SLinus Torvalds       #define  AR3      (BITW(9) + BITW(8))
8521da177e4SLinus Torvalds       #define  SDATA    BITW(10)
8531da177e4SLinus Torvalds 
8541da177e4SLinus Torvalds 
8551da177e4SLinus Torvalds       #define  CRD_OP   BITW(11)     /* Cmp Reg. w/ Data */
8561da177e4SLinus Torvalds 
8571da177e4SLinus Torvalds       #define  CRR_OP   BITW(12)     /* Cmp Reg. w. Reg. */
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds 
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds       #define  CPE_OP   (BITW(14)+BITW(11))  /* Cmp SCSI phs & Branch EQ */
8621da177e4SLinus Torvalds 
8631da177e4SLinus Torvalds       #define  CPN_OP   (BITW(14)+BITW(12))  /* Cmp SCSI phs & Branch NOT EQ */
8641da177e4SLinus Torvalds 
8651da177e4SLinus Torvalds 
8661da177e4SLinus Torvalds       #define  ADATA_OUT   0x00
8671da177e4SLinus Torvalds       #define  ADATA_IN    BITW(8)
8681da177e4SLinus Torvalds       #define  ACOMMAND    BITW(10)
8691da177e4SLinus Torvalds       #define  ASTATUS     (BITW(10)+BITW(8))
8701da177e4SLinus Torvalds       #define  AMSG_OUT    (BITW(10)+BITW(9))
8711da177e4SLinus Torvalds       #define  AMSG_IN     (BITW(10)+BITW(9)+BITW(8))
8721da177e4SLinus Torvalds 
8731da177e4SLinus Torvalds 
8741da177e4SLinus Torvalds       #define  BRH_OP   BITW(13)   /* Branch */
8751da177e4SLinus Torvalds 
8761da177e4SLinus Torvalds 
8771da177e4SLinus Torvalds       #define  ALWAYS   0x00
8781da177e4SLinus Torvalds       #define  EQUAL    BITW(8)
8791da177e4SLinus Torvalds       #define  NOT_EQ   BITW(9)
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds       #define  TCB_OP   (BITW(13)+BITW(11))    /* Test condition & branch */
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds 
8841da177e4SLinus Torvalds       #define  FIFO_0      BITW(10)
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds 
8871da177e4SLinus Torvalds       #define  MPM_OP   BITW(15)        /* Match phase and move data */
8881da177e4SLinus Torvalds 
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds       #define  MRR_OP   BITW(14)        /* Move DReg. to Reg. */
8911da177e4SLinus Torvalds 
8921da177e4SLinus Torvalds 
8931da177e4SLinus Torvalds       #define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
8941da177e4SLinus Torvalds 
8951da177e4SLinus Torvalds 
8961da177e4SLinus Torvalds       #define  D_AR0    0x00
8971da177e4SLinus Torvalds       #define  D_AR1    BIT(0)
8981da177e4SLinus Torvalds       #define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
8991da177e4SLinus Torvalds 
9001da177e4SLinus Torvalds 
9011da177e4SLinus Torvalds 
9021da177e4SLinus Torvalds 
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds 
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds 
9071da177e4SLinus Torvalds 
9081da177e4SLinus Torvalds       #define  RAT_OP      (BITW(14)+BITW(13)+BITW(11))
9091da177e4SLinus Torvalds 
9101da177e4SLinus Torvalds       #define  SSI_OP      (BITW(15)+BITW(11))
9111da177e4SLinus Torvalds 
9121da177e4SLinus Torvalds 
9131da177e4SLinus Torvalds       #define  SSI_ITAR_DISC	(ITAR_DISC >> 8)
9141da177e4SLinus Torvalds       #define  SSI_IDO_STRT	(IDO_STRT >> 8)
9151da177e4SLinus Torvalds 
9161da177e4SLinus Torvalds       #define  SSI_ICMD_COMP	(ICMD_COMP >> 8)
9171da177e4SLinus Torvalds       #define  SSI_ITICKLE	(ITICKLE >> 8)
9181da177e4SLinus Torvalds 
9191da177e4SLinus Torvalds       #define  SSI_IUNKWN	(IUNKWN >> 8)
9201da177e4SLinus Torvalds       #define  SSI_INO_CC	(IUNKWN >> 8)
9211da177e4SLinus Torvalds       #define  SSI_IRFAIL	(IUNKWN >> 8)
9221da177e4SLinus Torvalds 
9231da177e4SLinus Torvalds 
9241da177e4SLinus Torvalds       #define  NP    0x10     /*Next Phase */
9251da177e4SLinus Torvalds       #define  NTCMD 0x02     /*Non- Tagged Command start */
9261da177e4SLinus Torvalds       #define  CMDPZ 0x04     /*Command phase */
9271da177e4SLinus Torvalds       #define  DINT  0x12     /*Data Out/In interrupt */
9281da177e4SLinus Torvalds       #define  DI    0x13     /*Data Out */
9291da177e4SLinus Torvalds       #define  DC    0x19     /*Disconnect Message */
9301da177e4SLinus Torvalds       #define  ST    0x1D     /*Status Phase */
9311da177e4SLinus Torvalds       #define  UNKNWN 0x24    /*Unknown bus action */
9321da177e4SLinus Torvalds       #define  CC    0x25     /*Command Completion failure */
9331da177e4SLinus Torvalds       #define  TICK  0x26     /*New target reselected us. */
9341da177e4SLinus Torvalds       #define  SELCHK 0x28     /*Select & Check SCSI ID latch reg */
9351da177e4SLinus Torvalds 
9361da177e4SLinus Torvalds 
9371da177e4SLinus Torvalds       #define  ID_MSG_STRT    hp_aramBase + 0x00
9381da177e4SLinus Torvalds       #define  NON_TAG_ID_MSG hp_aramBase + 0x06
9391da177e4SLinus Torvalds       #define  CMD_STRT       hp_aramBase + 0x08
9401da177e4SLinus Torvalds       #define  SYNC_MSGS      hp_aramBase + 0x08
9411da177e4SLinus Torvalds 
9421da177e4SLinus Torvalds 
9431da177e4SLinus Torvalds 
9441da177e4SLinus Torvalds 
9451da177e4SLinus Torvalds 
9461da177e4SLinus Torvalds       #define  TAG_STRT          0x00
9471da177e4SLinus Torvalds       #define  DISCONNECT_START  0x10/2
9481da177e4SLinus Torvalds       #define  END_DATA_START    0x14/2
9491da177e4SLinus Torvalds       #define  CMD_ONLY_STRT     CMDPZ/2
9501da177e4SLinus Torvalds       #define  SELCHK_STRT     SELCHK/2
9511da177e4SLinus Torvalds 
9521da177e4SLinus Torvalds 
9531da177e4SLinus Torvalds 
9541da177e4SLinus Torvalds 
9551da177e4SLinus Torvalds 
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 
958*85ae97d8SAlexey Dobriyan 
9591da177e4SLinus Torvalds 
9601da177e4SLinus Torvalds #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
9611da177e4SLinus Torvalds /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
9621da177e4SLinus Torvalds                                  xfercnt <<= 16,\
9631da177e4SLinus Torvalds                                  xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
9641da177e4SLinus Torvalds  */
9651da177e4SLinus Torvalds #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
9661da177e4SLinus Torvalds          addr >>= 16,\
9671da177e4SLinus Torvalds          WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
9681da177e4SLinus Torvalds          WR_HARP32(port,hp_xfercnt_0,count),\
9691da177e4SLinus Torvalds          WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
9701da177e4SLinus Torvalds          count >>= 16,\
9711da177e4SLinus Torvalds          WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
9721da177e4SLinus Torvalds 
9731da177e4SLinus Torvalds #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
9741da177e4SLinus Torvalds                           WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
9751da177e4SLinus Torvalds 
9761da177e4SLinus Torvalds 
9771da177e4SLinus Torvalds #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
9781da177e4SLinus Torvalds                           WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
9791da177e4SLinus Torvalds 
9801da177e4SLinus Torvalds 
9811da177e4SLinus Torvalds 
9821da177e4SLinus Torvalds #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
9831da177e4SLinus Torvalds                         WR_HARPOON(port+hp_scsireset, 0x00))
9841da177e4SLinus Torvalds 
9851da177e4SLinus Torvalds #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
9861da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
9871da177e4SLinus Torvalds 
9881da177e4SLinus Torvalds #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
9891da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
9901da177e4SLinus Torvalds 
9911da177e4SLinus Torvalds #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
9921da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
9931da177e4SLinus Torvalds 
9941da177e4SLinus Torvalds #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
9951da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
9961da177e4SLinus Torvalds 
9971da177e4SLinus Torvalds 
9981da177e4SLinus Torvalds 
9991da177e4SLinus Torvalds 
100047b5d69cSJames Bottomley  static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
100147b5d69cSJames Bottomley  static void  FPT_ssel(ULONG port, UCHAR p_card);
100247b5d69cSJames Bottomley  static void  FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
100347b5d69cSJames Bottomley  static void  FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
100447b5d69cSJames Bottomley  static void  FPT_stsyncn(ULONG port, UCHAR p_card);
100547b5d69cSJames Bottomley  static void  FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
100647b5d69cSJames Bottomley  static void  FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
100747b5d69cSJames Bottomley  			 PSCCBMgr_tar_info currTar_Info);
100847b5d69cSJames Bottomley  static void  FPT_sresb(ULONG port, UCHAR p_card);
100947b5d69cSJames Bottomley  static void  FPT_sxfrp(ULONG p_port, UCHAR p_card);
101047b5d69cSJames Bottomley  static void  FPT_schkdd(ULONG port, UCHAR p_card);
101147b5d69cSJames Bottomley  static UCHAR FPT_RdStack(ULONG port, UCHAR index);
101247b5d69cSJames Bottomley  static void  FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
101347b5d69cSJames Bottomley  static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
10141da177e4SLinus Torvalds 
101547b5d69cSJames Bottomley  static void FPT_SendMsg(ULONG port, UCHAR message);
101647b5d69cSJames Bottomley  static void  FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
101747b5d69cSJames Bottomley  				    UCHAR error_code);
10181da177e4SLinus Torvalds 
101947b5d69cSJames Bottomley  static void  FPT_sinits(PSCCB p_sccb, UCHAR p_card);
102047b5d69cSJames Bottomley  static void  FPT_RNVRamData(PNVRamInfo pNvRamInfo);
10211da177e4SLinus Torvalds 
102247b5d69cSJames Bottomley  static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
102347b5d69cSJames Bottomley  static void  FPT_stwidn(ULONG port, UCHAR p_card);
102447b5d69cSJames Bottomley  static void  FPT_siwidr(ULONG port, UCHAR width);
10251da177e4SLinus Torvalds 
10261da177e4SLinus Torvalds 
102747b5d69cSJames Bottomley  static void  FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
102847b5d69cSJames Bottomley  static void  FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
102947b5d69cSJames Bottomley  static void  FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
103047b5d69cSJames Bottomley  				  UCHAR p_card);
103147b5d69cSJames Bottomley  static void  FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
103247b5d69cSJames Bottomley  static void  FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
103347b5d69cSJames Bottomley  static void  FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
103447b5d69cSJames Bottomley  static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
103547b5d69cSJames Bottomley  static void  FPT_utilUpdateResidual(PSCCB p_SCCB);
103647b5d69cSJames Bottomley  static USHORT FPT_CalcCrc16(UCHAR buffer[]);
103747b5d69cSJames Bottomley  static UCHAR  FPT_CalcLrc(UCHAR buffer[]);
10381da177e4SLinus Torvalds 
10391da177e4SLinus Torvalds 
104047b5d69cSJames Bottomley  static void  FPT_Wait1Second(ULONG p_port);
104147b5d69cSJames Bottomley  static void  FPT_Wait(ULONG p_port, UCHAR p_delay);
104247b5d69cSJames Bottomley  static void  FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
104347b5d69cSJames Bottomley  static void  FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
104447b5d69cSJames Bottomley  static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
104547b5d69cSJames Bottomley  static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
104647b5d69cSJames Bottomley  static void  FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
10471da177e4SLinus Torvalds 
10481da177e4SLinus Torvalds 
10491da177e4SLinus Torvalds 
105047b5d69cSJames Bottomley  static void  FPT_phaseDataOut(ULONG port, UCHAR p_card);
105147b5d69cSJames Bottomley  static void  FPT_phaseDataIn(ULONG port, UCHAR p_card);
105247b5d69cSJames Bottomley  static void  FPT_phaseCommand(ULONG port, UCHAR p_card);
105347b5d69cSJames Bottomley  static void  FPT_phaseStatus(ULONG port, UCHAR p_card);
105447b5d69cSJames Bottomley  static void  FPT_phaseMsgOut(ULONG port, UCHAR p_card);
105547b5d69cSJames Bottomley  static void  FPT_phaseMsgIn(ULONG port, UCHAR p_card);
105647b5d69cSJames Bottomley  static void  FPT_phaseIllegal(ULONG port, UCHAR p_card);
10571da177e4SLinus Torvalds 
105847b5d69cSJames Bottomley  static void  FPT_phaseDecode(ULONG port, UCHAR p_card);
105947b5d69cSJames Bottomley  static void  FPT_phaseChkFifo(ULONG port, UCHAR p_card);
106047b5d69cSJames Bottomley  static void  FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
10611da177e4SLinus Torvalds 
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds 
10641da177e4SLinus Torvalds 
106547b5d69cSJames Bottomley  static void  FPT_XbowInit(ULONG port, UCHAR scamFlg);
106647b5d69cSJames Bottomley  static void  FPT_BusMasterInit(ULONG p_port);
106747b5d69cSJames Bottomley  static void  FPT_DiagEEPROM(ULONG p_port);
10681da177e4SLinus Torvalds 
10691da177e4SLinus Torvalds 
10701da177e4SLinus Torvalds 
10711da177e4SLinus Torvalds 
107247b5d69cSJames Bottomley  static void  FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
107347b5d69cSJames Bottomley  static void  FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
107447b5d69cSJames Bottomley  static void  FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
107547b5d69cSJames Bottomley  static void  FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
107647b5d69cSJames Bottomley  static void  FPT_hostDataXferRestart(PSCCB currSCCB);
10771da177e4SLinus Torvalds 
10781da177e4SLinus Torvalds 
107947b5d69cSJames Bottomley  static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
108047b5d69cSJames Bottomley  				 PSCCBcard pCurrCard, USHORT p_int);
10811da177e4SLinus Torvalds 
108247b5d69cSJames Bottomley  static void  FPT_SccbMgrTableInitAll(void);
108347b5d69cSJames Bottomley  static void  FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
108447b5d69cSJames Bottomley  static void  FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
10851da177e4SLinus Torvalds 
10861da177e4SLinus Torvalds 
10871da177e4SLinus Torvalds 
108847b5d69cSJames Bottomley  static void  FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
10891da177e4SLinus Torvalds 
109047b5d69cSJames Bottomley  static int   FPT_scarb(ULONG p_port, UCHAR p_sel_type);
109147b5d69cSJames Bottomley  static void  FPT_scbusf(ULONG p_port);
109247b5d69cSJames Bottomley  static void  FPT_scsel(ULONG p_port);
109347b5d69cSJames Bottomley  static void  FPT_scasid(UCHAR p_card, ULONG p_port);
109447b5d69cSJames Bottomley  static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
109547b5d69cSJames Bottomley  static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
109647b5d69cSJames Bottomley  static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
109747b5d69cSJames Bottomley  static void  FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
109847b5d69cSJames Bottomley  static void  FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
109947b5d69cSJames Bottomley  static UCHAR FPT_scvalq(UCHAR p_quintet);
110047b5d69cSJames Bottomley  static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
110147b5d69cSJames Bottomley  static void  FPT_scwtsel(ULONG p_port);
110247b5d69cSJames Bottomley  static void  FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
110347b5d69cSJames Bottomley  static void  FPT_scsavdi(UCHAR p_card, ULONG p_port);
110447b5d69cSJames Bottomley  static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
11051da177e4SLinus Torvalds 
11061da177e4SLinus Torvalds 
110747b5d69cSJames Bottomley  static void  FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
110847b5d69cSJames Bottomley  static void  FPT_autoLoadDefaultMap(ULONG p_port);
11091da177e4SLinus Torvalds 
11101da177e4SLinus Torvalds 
11111da177e4SLinus Torvalds 
11121da177e4SLinus Torvalds 
111347b5d69cSJames Bottomley  static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
111447b5d69cSJames Bottomley  static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
111547b5d69cSJames Bottomley  static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
111647b5d69cSJames Bottomley  static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
11171da177e4SLinus Torvalds 
11181da177e4SLinus Torvalds 
111947b5d69cSJames Bottomley  static UCHAR FPT_mbCards = 0;
112047b5d69cSJames Bottomley  static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
112147b5d69cSJames Bottomley  				   ' ', 'B', 'T', '-', '9', '3', '0', \
112247b5d69cSJames Bottomley  				   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
112347b5d69cSJames Bottomley  				   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
11241da177e4SLinus Torvalds 
112547b5d69cSJames Bottomley  static USHORT FPT_default_intena = 0;
11261da177e4SLinus Torvalds 
11271da177e4SLinus Torvalds 
112847b5d69cSJames Bottomley  static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
11291da177e4SLinus Torvalds 
11301da177e4SLinus Torvalds 
11311da177e4SLinus Torvalds /*---------------------------------------------------------------------
11321da177e4SLinus Torvalds  *
11331da177e4SLinus Torvalds  * Function: SccbMgr_sense_adapter
11341da177e4SLinus Torvalds  *
11351da177e4SLinus Torvalds  * Description: Setup and/or Search for cards and return info to caller.
11361da177e4SLinus Torvalds  *
11371da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
11381da177e4SLinus Torvalds 
113947b5d69cSJames Bottomley  static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
11401da177e4SLinus Torvalds {
11411da177e4SLinus Torvalds    static UCHAR first_time = 1;
11421da177e4SLinus Torvalds 
11431da177e4SLinus Torvalds    UCHAR i,j,id,ScamFlg;
11441da177e4SLinus Torvalds    USHORT temp,temp2,temp3,temp4,temp5,temp6;
11451da177e4SLinus Torvalds    ULONG ioport;
11461da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
11471da177e4SLinus Torvalds 
11481da177e4SLinus Torvalds    ioport = pCardInfo->si_baseaddr;
11491da177e4SLinus Torvalds 
11501da177e4SLinus Torvalds 
11511da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
11521da177e4SLinus Torvalds       return((int)FAILURE);
11531da177e4SLinus Torvalds 
11541da177e4SLinus Torvalds    if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
11551da177e4SLinus Torvalds       return((int)FAILURE);
11561da177e4SLinus Torvalds 
11571da177e4SLinus Torvalds    if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
11581da177e4SLinus Torvalds       return((int)FAILURE);
11591da177e4SLinus Torvalds 
11601da177e4SLinus Torvalds    if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
11611da177e4SLinus Torvalds       return((int)FAILURE);
11621da177e4SLinus Torvalds 
11631da177e4SLinus Torvalds 
11641da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
11651da177e4SLinus Torvalds 
11661da177e4SLinus Torvalds /* For new Harpoon then check for sub_device ID LSB
11671da177e4SLinus Torvalds    the bits(0-3) must be all ZERO for compatible with
11681da177e4SLinus Torvalds    current version of SCCBMgr, else skip this Harpoon
11691da177e4SLinus Torvalds 	device. */
11701da177e4SLinus Torvalds 
11711da177e4SLinus Torvalds 	   if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
11721da177e4SLinus Torvalds 	      return((int)FAILURE);
11731da177e4SLinus Torvalds 	}
11741da177e4SLinus Torvalds 
11751da177e4SLinus Torvalds    if (first_time)
11761da177e4SLinus Torvalds       {
117747b5d69cSJames Bottomley        FPT_SccbMgrTableInitAll();
11781da177e4SLinus Torvalds       first_time = 0;
117947b5d69cSJames Bottomley  		FPT_mbCards = 0;
11801da177e4SLinus Torvalds       }
11811da177e4SLinus Torvalds 
118247b5d69cSJames Bottomley  	if(FPT_RdStack(ioport, 0) != 0x00) {
118347b5d69cSJames Bottomley  		if(FPT_ChkIfChipInitialized(ioport) == 0)
11841da177e4SLinus Torvalds 		{
11851da177e4SLinus Torvalds 			pCurrNvRam = NULL;
11861da177e4SLinus Torvalds 		   WR_HARPOON(ioport+hp_semaphore, 0x00);
118747b5d69cSJames Bottomley  			FPT_XbowInit(ioport, 0);             /*Must Init the SCSI before attempting */
118847b5d69cSJames Bottomley  			FPT_DiagEEPROM(ioport);
11891da177e4SLinus Torvalds 		}
11901da177e4SLinus Torvalds 		else
11911da177e4SLinus Torvalds 		{
119247b5d69cSJames Bottomley  			if(FPT_mbCards < MAX_MB_CARDS) {
119347b5d69cSJames Bottomley  				pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
119447b5d69cSJames Bottomley  				FPT_mbCards++;
11951da177e4SLinus Torvalds 				pCurrNvRam->niBaseAddr = ioport;
119647b5d69cSJames Bottomley  				FPT_RNVRamData(pCurrNvRam);
11971da177e4SLinus Torvalds 			}else
11981da177e4SLinus Torvalds 				return((int) FAILURE);
11991da177e4SLinus Torvalds 		}
12001da177e4SLinus Torvalds 	}else
12011da177e4SLinus Torvalds 		pCurrNvRam = NULL;
12021da177e4SLinus Torvalds 
12031da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
12041da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
12051da177e4SLinus Torvalds 
12061da177e4SLinus Torvalds 	if(pCurrNvRam)
12071da177e4SLinus Torvalds 		pCardInfo->si_id = pCurrNvRam->niAdapId;
12081da177e4SLinus Torvalds 	else
120947b5d69cSJames Bottomley  	   pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
12101da177e4SLinus Torvalds    	   (UCHAR)0x0FF);
12111da177e4SLinus Torvalds 
12121da177e4SLinus Torvalds    pCardInfo->si_lun = 0x00;
12131da177e4SLinus Torvalds    pCardInfo->si_fw_revision = ORION_FW_REV;
12141da177e4SLinus Torvalds    temp2 = 0x0000;
12151da177e4SLinus Torvalds    temp3 = 0x0000;
12161da177e4SLinus Torvalds    temp4 = 0x0000;
12171da177e4SLinus Torvalds    temp5 = 0x0000;
12181da177e4SLinus Torvalds    temp6 = 0x0000;
12191da177e4SLinus Torvalds 
12201da177e4SLinus Torvalds    for (id = 0; id < (16/2); id++) {
12211da177e4SLinus Torvalds 
12221da177e4SLinus Torvalds 		if(pCurrNvRam){
12231da177e4SLinus Torvalds 			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
12241da177e4SLinus Torvalds 			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
12251da177e4SLinus Torvalds 					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
12261da177e4SLinus Torvalds 		}else
122747b5d69cSJames Bottomley  	      temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
12281da177e4SLinus Torvalds 
12291da177e4SLinus Torvalds       for (i = 0; i < 2; temp >>=8,i++) {
12301da177e4SLinus Torvalds 
12311da177e4SLinus Torvalds          temp2 >>= 1;
12321da177e4SLinus Torvalds          temp3 >>= 1;
12331da177e4SLinus Torvalds          temp4 >>= 1;
12341da177e4SLinus Torvalds          temp5 >>= 1;
12351da177e4SLinus Torvalds          temp6 >>= 1;
12361da177e4SLinus Torvalds 	 switch (temp & 0x3)
12371da177e4SLinus Torvalds 	   {
12381da177e4SLinus Torvalds 	   case AUTO_RATE_20:	/* Synchronous, 20 mega-transfers/second */
12391da177e4SLinus Torvalds 	     temp6 |= 0x8000;	/* Fall through */
12401da177e4SLinus Torvalds 	   case AUTO_RATE_10:	/* Synchronous, 10 mega-transfers/second */
12411da177e4SLinus Torvalds 	     temp5 |= 0x8000;	/* Fall through */
12421da177e4SLinus Torvalds 	   case AUTO_RATE_05:	/* Synchronous, 5 mega-transfers/second */
12431da177e4SLinus Torvalds 	     temp2 |= 0x8000;	/* Fall through */
12441da177e4SLinus Torvalds 	   case AUTO_RATE_00:	/* Asynchronous */
12451da177e4SLinus Torvalds 	     break;
12461da177e4SLinus Torvalds 	   }
12471da177e4SLinus Torvalds 
12481da177e4SLinus Torvalds          if (temp & DISC_ENABLE_BIT)
12491da177e4SLinus Torvalds 	   temp3 |= 0x8000;
12501da177e4SLinus Torvalds 
12511da177e4SLinus Torvalds          if (temp & WIDE_NEGO_BIT)
12521da177e4SLinus Torvalds 	   temp4 |= 0x8000;
12531da177e4SLinus Torvalds 
12541da177e4SLinus Torvalds          }
12551da177e4SLinus Torvalds       }
12561da177e4SLinus Torvalds 
12571da177e4SLinus Torvalds    pCardInfo->si_per_targ_init_sync = temp2;
12581da177e4SLinus Torvalds    pCardInfo->si_per_targ_no_disc = temp3;
12591da177e4SLinus Torvalds    pCardInfo->si_per_targ_wide_nego = temp4;
12601da177e4SLinus Torvalds    pCardInfo->si_per_targ_fast_nego = temp5;
12611da177e4SLinus Torvalds    pCardInfo->si_per_targ_ultra_nego = temp6;
12621da177e4SLinus Torvalds 
12631da177e4SLinus Torvalds 	if(pCurrNvRam)
12641da177e4SLinus Torvalds 		i = pCurrNvRam->niSysConf;
12651da177e4SLinus Torvalds 	else
126647b5d69cSJames Bottomley  	   i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
12671da177e4SLinus Torvalds 
12681da177e4SLinus Torvalds 	if(pCurrNvRam)
12691da177e4SLinus Torvalds 		ScamFlg = pCurrNvRam->niScamConf;
12701da177e4SLinus Torvalds 	else
127147b5d69cSJames Bottomley  	   ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
12721da177e4SLinus Torvalds 
12731da177e4SLinus Torvalds    pCardInfo->si_flags = 0x0000;
12741da177e4SLinus Torvalds 
12751da177e4SLinus Torvalds    if (i & 0x01)
12761da177e4SLinus Torvalds       pCardInfo->si_flags |= SCSI_PARITY_ENA;
12771da177e4SLinus Torvalds 
12781da177e4SLinus Torvalds    if (!(i & 0x02))
12791da177e4SLinus Torvalds       pCardInfo->si_flags |= SOFT_RESET;
12801da177e4SLinus Torvalds 
12811da177e4SLinus Torvalds    if (i & 0x10)
12821da177e4SLinus Torvalds       pCardInfo->si_flags |= EXTENDED_TRANSLATION;
12831da177e4SLinus Torvalds 
12841da177e4SLinus Torvalds    if (ScamFlg & SCAM_ENABLED)
12851da177e4SLinus Torvalds      pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
12861da177e4SLinus Torvalds 
12871da177e4SLinus Torvalds    if (ScamFlg & SCAM_LEVEL2)
12881da177e4SLinus Torvalds      pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
12891da177e4SLinus Torvalds 
12901da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
12911da177e4SLinus Torvalds    if (i & 0x04) {
12921da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_L;
12931da177e4SLinus Torvalds       }
12941da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_bm_ctrl, j );
12951da177e4SLinus Torvalds 
12961da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
12971da177e4SLinus Torvalds    if (i & 0x08) {
12981da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_H;
12991da177e4SLinus Torvalds       }
13001da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_ee_ctrl, j );
13011da177e4SLinus Torvalds 
13021da177e4SLinus Torvalds    if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds       pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
13051da177e4SLinus Torvalds 
13061da177e4SLinus Torvalds    pCardInfo->si_card_family = HARPOON_FAMILY;
13071da177e4SLinus Torvalds    pCardInfo->si_bustype = BUSTYPE_PCI;
13081da177e4SLinus Torvalds 
13091da177e4SLinus Torvalds 	if(pCurrNvRam){
13101da177e4SLinus Torvalds    	pCardInfo->si_card_model[0] = '9';
13111da177e4SLinus Torvalds 		switch(pCurrNvRam->niModel & 0x0f){
13121da177e4SLinus Torvalds 			case MODEL_LT:
13131da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '3';
13141da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '0';
13151da177e4SLinus Torvalds 				break;
13161da177e4SLinus Torvalds 			case MODEL_LW:
13171da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '5';
13181da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '0';
13191da177e4SLinus Torvalds 				break;
13201da177e4SLinus Torvalds 			case MODEL_DL:
13211da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '3';
13221da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '2';
13231da177e4SLinus Torvalds 				break;
13241da177e4SLinus Torvalds 			case MODEL_DW:
13251da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '5';
13261da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '2';
13271da177e4SLinus Torvalds 				break;
13281da177e4SLinus Torvalds 		}
13291da177e4SLinus Torvalds 	}else{
133047b5d69cSJames Bottomley  	   temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
13311da177e4SLinus Torvalds    	pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
133247b5d69cSJames Bottomley  	   temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
13331da177e4SLinus Torvalds 
13341da177e4SLinus Torvalds    	pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
13351da177e4SLinus Torvalds 	   pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
13361da177e4SLinus Torvalds 	}
13371da177e4SLinus Torvalds 
13381da177e4SLinus Torvalds    if (pCardInfo->si_card_model[1] == '3')
13391da177e4SLinus Torvalds      {
13401da177e4SLinus Torvalds        if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
13411da177e4SLinus Torvalds 	 pCardInfo->si_flags |= LOW_BYTE_TERM;
13421da177e4SLinus Torvalds      }
13431da177e4SLinus Torvalds    else if (pCardInfo->si_card_model[2] == '0')
13441da177e4SLinus Torvalds      {
13451da177e4SLinus Torvalds        temp = RD_HARPOON(ioport+hp_xfer_pad);
13461da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
13471da177e4SLinus Torvalds        if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
13481da177e4SLinus Torvalds 	 pCardInfo->si_flags |= LOW_BYTE_TERM;
13491da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
13501da177e4SLinus Torvalds        if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
13511da177e4SLinus Torvalds 	 pCardInfo->si_flags |= HIGH_BYTE_TERM;
13521da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, temp);
13531da177e4SLinus Torvalds      }
13541da177e4SLinus Torvalds    else
13551da177e4SLinus Torvalds      {
13561da177e4SLinus Torvalds        temp = RD_HARPOON(ioport+hp_ee_ctrl);
13571da177e4SLinus Torvalds        temp2 = RD_HARPOON(ioport+hp_xfer_pad);
13581da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
13591da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
13601da177e4SLinus Torvalds        temp3 = 0;
13611da177e4SLinus Torvalds        for (i = 0; i < 8; i++)
13621da177e4SLinus Torvalds 	 {
13631da177e4SLinus Torvalds 	   temp3 <<= 1;
13641da177e4SLinus Torvalds 	   if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
13651da177e4SLinus Torvalds 	     temp3 |= 1;
13661da177e4SLinus Torvalds 	   WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
13671da177e4SLinus Torvalds 	   WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
13681da177e4SLinus Torvalds 	 }
13691da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_ee_ctrl, temp);
13701da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, temp2);
13711da177e4SLinus Torvalds        if (!(temp3 & BIT(7)))
13721da177e4SLinus Torvalds 	 pCardInfo->si_flags |= LOW_BYTE_TERM;
13731da177e4SLinus Torvalds        if (!(temp3 & BIT(6)))
13741da177e4SLinus Torvalds 	 pCardInfo->si_flags |= HIGH_BYTE_TERM;
13751da177e4SLinus Torvalds      }
13761da177e4SLinus Torvalds 
13771da177e4SLinus Torvalds 
13781da177e4SLinus Torvalds    ARAM_ACCESS(ioport);
13791da177e4SLinus Torvalds 
13801da177e4SLinus Torvalds    for ( i = 0; i < 4; i++ ) {
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds       pCardInfo->si_XlatInfo[i] =
13831da177e4SLinus Torvalds          RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
13841da177e4SLinus Torvalds       }
13851da177e4SLinus Torvalds 
13861da177e4SLinus Torvalds 	/* return with -1 if no sort, else return with
13871da177e4SLinus Torvalds 	   logical card number sorted by BIOS (zero-based) */
13881da177e4SLinus Torvalds 
13891da177e4SLinus Torvalds 	pCardInfo->si_relative_cardnum =
13901da177e4SLinus Torvalds 	(UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
13911da177e4SLinus Torvalds 
13921da177e4SLinus Torvalds    SGRAM_ACCESS(ioport);
13931da177e4SLinus Torvalds 
139447b5d69cSJames Bottomley     FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
139547b5d69cSJames Bottomley     FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
139647b5d69cSJames Bottomley     FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
139747b5d69cSJames Bottomley     FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
139847b5d69cSJames Bottomley     FPT_s_PhaseTbl[4] = FPT_phaseCommand;
139947b5d69cSJames Bottomley     FPT_s_PhaseTbl[5] = FPT_phaseStatus;
140047b5d69cSJames Bottomley     FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
140147b5d69cSJames Bottomley     FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
14021da177e4SLinus Torvalds 
14031da177e4SLinus Torvalds    pCardInfo->si_present = 0x01;
14041da177e4SLinus Torvalds 
14051da177e4SLinus Torvalds    return(0);
14061da177e4SLinus Torvalds }
14071da177e4SLinus Torvalds 
14081da177e4SLinus Torvalds 
14091da177e4SLinus Torvalds /*---------------------------------------------------------------------
14101da177e4SLinus Torvalds  *
14111da177e4SLinus Torvalds  * Function: SccbMgr_config_adapter
14121da177e4SLinus Torvalds  *
14131da177e4SLinus Torvalds  * Description: Setup adapter for normal operation (hard reset).
14141da177e4SLinus Torvalds  *
14151da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
14161da177e4SLinus Torvalds 
141747b5d69cSJames Bottomley  static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
14181da177e4SLinus Torvalds {
14191da177e4SLinus Torvalds    PSCCBcard CurrCard = NULL;
14201da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
14211da177e4SLinus Torvalds    UCHAR i,j,thisCard, ScamFlg;
14221da177e4SLinus Torvalds    USHORT temp,sync_bit_map,id;
14231da177e4SLinus Torvalds    ULONG ioport;
14241da177e4SLinus Torvalds 
14251da177e4SLinus Torvalds    ioport = pCardInfo->si_baseaddr;
14261da177e4SLinus Torvalds 
14271da177e4SLinus Torvalds    for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds       if (thisCard == MAX_CARDS) {
14301da177e4SLinus Torvalds 
14311da177e4SLinus Torvalds 	 return(FAILURE);
14321da177e4SLinus Torvalds          }
14331da177e4SLinus Torvalds 
143447b5d69cSJames Bottomley        if (FPT_BL_Card[thisCard].ioPort == ioport) {
14351da177e4SLinus Torvalds 
143647b5d69cSJames Bottomley           CurrCard = &FPT_BL_Card[thisCard];
143747b5d69cSJames Bottomley           FPT_SccbMgrTableInitCard(CurrCard,thisCard);
14381da177e4SLinus Torvalds          break;
14391da177e4SLinus Torvalds          }
14401da177e4SLinus Torvalds 
144147b5d69cSJames Bottomley        else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
14421da177e4SLinus Torvalds 
144347b5d69cSJames Bottomley           FPT_BL_Card[thisCard].ioPort = ioport;
144447b5d69cSJames Bottomley           CurrCard = &FPT_BL_Card[thisCard];
14451da177e4SLinus Torvalds 
144647b5d69cSJames Bottomley  			if(FPT_mbCards)
144747b5d69cSJames Bottomley  				for(i = 0; i < FPT_mbCards; i++){
144847b5d69cSJames Bottomley  					if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
144947b5d69cSJames Bottomley  						CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
14501da177e4SLinus Torvalds 				}
145147b5d69cSJames Bottomley           FPT_SccbMgrTableInitCard(CurrCard,thisCard);
14521da177e4SLinus Torvalds          CurrCard->cardIndex = thisCard;
14531da177e4SLinus Torvalds          CurrCard->cardInfo = pCardInfo;
14541da177e4SLinus Torvalds 
14551da177e4SLinus Torvalds 	 break;
14561da177e4SLinus Torvalds          }
14571da177e4SLinus Torvalds       }
14581da177e4SLinus Torvalds 
14591da177e4SLinus Torvalds 	pCurrNvRam = CurrCard->pNvRamInfo;
14601da177e4SLinus Torvalds 
14611da177e4SLinus Torvalds 	if(pCurrNvRam){
14621da177e4SLinus Torvalds 		ScamFlg = pCurrNvRam->niScamConf;
14631da177e4SLinus Torvalds 	}
14641da177e4SLinus Torvalds 	else{
146547b5d69cSJames Bottomley  	   ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
14661da177e4SLinus Torvalds 	}
14671da177e4SLinus Torvalds 
14681da177e4SLinus Torvalds 
146947b5d69cSJames Bottomley     FPT_BusMasterInit(ioport);
147047b5d69cSJames Bottomley     FPT_XbowInit(ioport, ScamFlg);
14711da177e4SLinus Torvalds 
147247b5d69cSJames Bottomley     FPT_autoLoadDefaultMap(ioport);
14731da177e4SLinus Torvalds 
14741da177e4SLinus Torvalds 
14751da177e4SLinus Torvalds    for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
14761da177e4SLinus Torvalds 
14771da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_selfid_0, id);
14781da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_selfid_1, 0x00);
14791da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
14801da177e4SLinus Torvalds    CurrCard->ourId = pCardInfo->si_id;
14811da177e4SLinus Torvalds 
14821da177e4SLinus Torvalds    i = (UCHAR) pCardInfo->si_flags;
14831da177e4SLinus Torvalds    if (i & SCSI_PARITY_ENA)
14841da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
14851da177e4SLinus Torvalds 
14861da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
14871da177e4SLinus Torvalds    if (i & LOW_BYTE_TERM)
14881da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_L;
14891da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_bm_ctrl, j);
14901da177e4SLinus Torvalds 
14911da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
14921da177e4SLinus Torvalds    if (i & HIGH_BYTE_TERM)
14931da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_H;
14941da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_ee_ctrl, j );
14951da177e4SLinus Torvalds 
14961da177e4SLinus Torvalds 
14971da177e4SLinus Torvalds    if (!(pCardInfo->si_flags & SOFT_RESET)) {
14981da177e4SLinus Torvalds 
149947b5d69cSJames Bottomley        FPT_sresb(ioport,thisCard);
15001da177e4SLinus Torvalds 
150147b5d69cSJames Bottomley           FPT_scini(thisCard, pCardInfo->si_id, 0);
15021da177e4SLinus Torvalds       }
15031da177e4SLinus Torvalds 
15041da177e4SLinus Torvalds 
15051da177e4SLinus Torvalds 
15061da177e4SLinus Torvalds    if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
15071da177e4SLinus Torvalds       CurrCard->globalFlags |= F_NO_FILTER;
15081da177e4SLinus Torvalds 
15091da177e4SLinus Torvalds 	if(pCurrNvRam){
15101da177e4SLinus Torvalds 		if(pCurrNvRam->niSysConf & 0x10)
15111da177e4SLinus Torvalds 			CurrCard->globalFlags |= F_GREEN_PC;
15121da177e4SLinus Torvalds 	}
15131da177e4SLinus Torvalds 	else{
151447b5d69cSJames Bottomley  	   if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
15151da177e4SLinus Torvalds    	   CurrCard->globalFlags |= F_GREEN_PC;
15161da177e4SLinus Torvalds 	}
15171da177e4SLinus Torvalds 
15181da177e4SLinus Torvalds 	/* Set global flag to indicate Re-Negotiation to be done on all
15191da177e4SLinus Torvalds 		ckeck condition */
15201da177e4SLinus Torvalds 	if(pCurrNvRam){
15211da177e4SLinus Torvalds 		if(pCurrNvRam->niScsiConf & 0x04)
15221da177e4SLinus Torvalds 			CurrCard->globalFlags |= F_DO_RENEGO;
15231da177e4SLinus Torvalds 	}
15241da177e4SLinus Torvalds 	else{
152547b5d69cSJames Bottomley  	   if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
15261da177e4SLinus Torvalds    	   CurrCard->globalFlags |= F_DO_RENEGO;
15271da177e4SLinus Torvalds 	}
15281da177e4SLinus Torvalds 
15291da177e4SLinus Torvalds 	if(pCurrNvRam){
15301da177e4SLinus Torvalds 		if(pCurrNvRam->niScsiConf & 0x08)
15311da177e4SLinus Torvalds 			CurrCard->globalFlags |= F_CONLUN_IO;
15321da177e4SLinus Torvalds 	}
15331da177e4SLinus Torvalds 	else{
153447b5d69cSJames Bottomley  	   if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
15351da177e4SLinus Torvalds    	   CurrCard->globalFlags |= F_CONLUN_IO;
15361da177e4SLinus Torvalds 	}
15371da177e4SLinus Torvalds 
15381da177e4SLinus Torvalds 
15391da177e4SLinus Torvalds    temp = pCardInfo->si_per_targ_no_disc;
15401da177e4SLinus Torvalds 
15411da177e4SLinus Torvalds    for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
15421da177e4SLinus Torvalds 
15431da177e4SLinus Torvalds       if (temp & id)
154447b5d69cSJames Bottomley  	 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
15451da177e4SLinus Torvalds       }
15461da177e4SLinus Torvalds 
15471da177e4SLinus Torvalds    sync_bit_map = 0x0001;
15481da177e4SLinus Torvalds 
15491da177e4SLinus Torvalds    for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
15501da177e4SLinus Torvalds 
15511da177e4SLinus Torvalds 		if(pCurrNvRam){
15521da177e4SLinus Torvalds 			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
15531da177e4SLinus Torvalds 			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
15541da177e4SLinus Torvalds 					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
15551da177e4SLinus Torvalds 		}else
155647b5d69cSJames Bottomley  	      temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
15571da177e4SLinus Torvalds 
15581da177e4SLinus Torvalds       for (i = 0; i < 2; temp >>=8,i++) {
15591da177e4SLinus Torvalds 
15601da177e4SLinus Torvalds          if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
15611da177e4SLinus Torvalds 
156247b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
15631da177e4SLinus Torvalds             }
15641da177e4SLinus Torvalds 
15651da177e4SLinus Torvalds          else {
156647b5d69cSJames Bottomley  	    FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
156747b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
15681da177e4SLinus Torvalds                (UCHAR)(temp & ~EE_SYNC_MASK);
15691da177e4SLinus Torvalds             }
15701da177e4SLinus Torvalds 
15711da177e4SLinus Torvalds /*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
15721da177e4SLinus Torvalds             (id*2+i >= 8)){
15731da177e4SLinus Torvalds */
15741da177e4SLinus Torvalds          if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
15751da177e4SLinus Torvalds 
157647b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
15771da177e4SLinus Torvalds 
15781da177e4SLinus Torvalds             }
15791da177e4SLinus Torvalds 
15801da177e4SLinus Torvalds          else { /* NARROW SCSI */
158147b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
15821da177e4SLinus Torvalds             }
15831da177e4SLinus Torvalds 
15841da177e4SLinus Torvalds 
15851da177e4SLinus Torvalds 	 sync_bit_map <<= 1;
15861da177e4SLinus Torvalds 
15871da177e4SLinus Torvalds 
15881da177e4SLinus Torvalds 
15891da177e4SLinus Torvalds          }
15901da177e4SLinus Torvalds       }
15911da177e4SLinus Torvalds 
15921da177e4SLinus Torvalds    WR_HARPOON((ioport+hp_semaphore),
15931da177e4SLinus Torvalds       (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
15941da177e4SLinus Torvalds 
15951da177e4SLinus Torvalds    return((ULONG)CurrCard);
15961da177e4SLinus Torvalds }
15971da177e4SLinus Torvalds 
159847b5d69cSJames Bottomley  static void SccbMgr_unload_card(ULONG pCurrCard)
15991da177e4SLinus Torvalds {
16001da177e4SLinus Torvalds 	UCHAR i;
16011da177e4SLinus Torvalds 	ULONG portBase;
16021da177e4SLinus Torvalds 	ULONG regOffset;
16031da177e4SLinus Torvalds 	ULONG scamData;
16041da177e4SLinus Torvalds 	ULONG *pScamTbl;
16051da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
16061da177e4SLinus Torvalds 
16071da177e4SLinus Torvalds 	pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
16081da177e4SLinus Torvalds 
16091da177e4SLinus Torvalds 	if(pCurrNvRam){
161047b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
161147b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
161247b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
161347b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
161447b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
16151da177e4SLinus Torvalds 
16161da177e4SLinus Torvalds 		for(i = 0; i < MAX_SCSI_TAR / 2; i++)
161747b5d69cSJames Bottomley  			FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
16181da177e4SLinus Torvalds 
16191da177e4SLinus Torvalds 		portBase = pCurrNvRam->niBaseAddr;
16201da177e4SLinus Torvalds 
16211da177e4SLinus Torvalds 		for(i = 0; i < MAX_SCSI_TAR; i++){
16221da177e4SLinus Torvalds 			regOffset = hp_aramBase + 64 + i*4;
16231da177e4SLinus Torvalds 			pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
16241da177e4SLinus Torvalds 			scamData = *pScamTbl;
16251da177e4SLinus Torvalds 			WR_HARP32(portBase, regOffset, scamData);
16261da177e4SLinus Torvalds 		}
16271da177e4SLinus Torvalds 
16281da177e4SLinus Torvalds 	}else{
162947b5d69cSJames Bottomley  		FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
16301da177e4SLinus Torvalds 	}
16311da177e4SLinus Torvalds }
16321da177e4SLinus Torvalds 
16331da177e4SLinus Torvalds 
163447b5d69cSJames Bottomley  static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
16351da177e4SLinus Torvalds {
16361da177e4SLinus Torvalds 	UCHAR i;
16371da177e4SLinus Torvalds 	ULONG portBase;
16381da177e4SLinus Torvalds 	ULONG regOffset;
16391da177e4SLinus Torvalds 	ULONG scamData;
16401da177e4SLinus Torvalds 	ULONG *pScamTbl;
16411da177e4SLinus Torvalds 
164247b5d69cSJames Bottomley  	pNvRamInfo->niModel    = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
164347b5d69cSJames Bottomley  	pNvRamInfo->niSysConf  = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
164447b5d69cSJames Bottomley  	pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
164547b5d69cSJames Bottomley  	pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
164647b5d69cSJames Bottomley  	pNvRamInfo->niAdapId   = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
16471da177e4SLinus Torvalds 
16481da177e4SLinus Torvalds 	for(i = 0; i < MAX_SCSI_TAR / 2; i++)
164947b5d69cSJames Bottomley  		pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
16501da177e4SLinus Torvalds 
16511da177e4SLinus Torvalds 	portBase = pNvRamInfo->niBaseAddr;
16521da177e4SLinus Torvalds 
16531da177e4SLinus Torvalds 	for(i = 0; i < MAX_SCSI_TAR; i++){
16541da177e4SLinus Torvalds 		regOffset = hp_aramBase + 64 + i*4;
16551da177e4SLinus Torvalds 		RD_HARP32(portBase, regOffset, scamData);
16561da177e4SLinus Torvalds 		pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
16571da177e4SLinus Torvalds 		*pScamTbl = scamData;
16581da177e4SLinus Torvalds 	}
16591da177e4SLinus Torvalds 
16601da177e4SLinus Torvalds }
16611da177e4SLinus Torvalds 
166247b5d69cSJames Bottomley  static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
16631da177e4SLinus Torvalds {
16641da177e4SLinus Torvalds 	WR_HARPOON(portBase + hp_stack_addr, index);
16651da177e4SLinus Torvalds 	return(RD_HARPOON(portBase + hp_stack_data));
16661da177e4SLinus Torvalds }
16671da177e4SLinus Torvalds 
166847b5d69cSJames Bottomley  static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
16691da177e4SLinus Torvalds {
16701da177e4SLinus Torvalds 	WR_HARPOON(portBase + hp_stack_addr, index);
16711da177e4SLinus Torvalds 	WR_HARPOON(portBase + hp_stack_data, data);
16721da177e4SLinus Torvalds }
16731da177e4SLinus Torvalds 
16741da177e4SLinus Torvalds 
167547b5d69cSJames Bottomley  static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
16761da177e4SLinus Torvalds {
167747b5d69cSJames Bottomley  	if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
167847b5d69cSJames Bottomley  		return(0);
16791da177e4SLinus Torvalds 	if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
16801da177e4SLinus Torvalds 								!= CLKCTRL_DEFAULT)
168147b5d69cSJames Bottomley  		return(0);
16821da177e4SLinus Torvalds 	if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
16831da177e4SLinus Torvalds 		(RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
168447b5d69cSJames Bottomley  		return(1);
168547b5d69cSJames Bottomley  	return(0);
16861da177e4SLinus Torvalds 
16871da177e4SLinus Torvalds }
16881da177e4SLinus Torvalds /*---------------------------------------------------------------------
16891da177e4SLinus Torvalds  *
16901da177e4SLinus Torvalds  * Function: SccbMgr_start_sccb
16911da177e4SLinus Torvalds  *
16921da177e4SLinus Torvalds  * Description: Start a command pointed to by p_Sccb. When the
16931da177e4SLinus Torvalds  *              command is completed it will be returned via the
16941da177e4SLinus Torvalds  *              callback function.
16951da177e4SLinus Torvalds  *
16961da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
169747b5d69cSJames Bottomley  static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
16981da177e4SLinus Torvalds {
16991da177e4SLinus Torvalds    ULONG ioport;
17001da177e4SLinus Torvalds    UCHAR thisCard, lun;
17011da177e4SLinus Torvalds 	PSCCB pSaveSccb;
17021da177e4SLinus Torvalds    CALL_BK_FN callback;
17031da177e4SLinus Torvalds 
17041da177e4SLinus Torvalds    thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
17051da177e4SLinus Torvalds    ioport = ((PSCCBcard) pCurrCard)->ioPort;
17061da177e4SLinus Torvalds 
17071da177e4SLinus Torvalds 	if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
17081da177e4SLinus Torvalds 	{
17091da177e4SLinus Torvalds 
17101da177e4SLinus Torvalds 		p_Sccb->HostStatus = SCCB_COMPLETE;
17111da177e4SLinus Torvalds 		p_Sccb->SccbStatus = SCCB_ERROR;
17121da177e4SLinus Torvalds 		callback = (CALL_BK_FN)p_Sccb->SccbCallback;
17131da177e4SLinus Torvalds 		if (callback)
17141da177e4SLinus Torvalds 			callback(p_Sccb);
17151da177e4SLinus Torvalds 
17161da177e4SLinus Torvalds 		return;
17171da177e4SLinus Torvalds 	}
17181da177e4SLinus Torvalds 
171947b5d69cSJames Bottomley     FPT_sinits(p_Sccb,thisCard);
17201da177e4SLinus Torvalds 
17211da177e4SLinus Torvalds 
17221da177e4SLinus Torvalds    if (!((PSCCBcard) pCurrCard)->cmdCounter)
17231da177e4SLinus Torvalds       {
17241da177e4SLinus Torvalds       WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
17251da177e4SLinus Torvalds          | SCCB_MGR_ACTIVE));
17261da177e4SLinus Torvalds 
17271da177e4SLinus Torvalds       if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
17281da177e4SLinus Torvalds          {
17291da177e4SLinus Torvalds 		 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
17301da177e4SLinus Torvalds 		 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
17311da177e4SLinus Torvalds          }
17321da177e4SLinus Torvalds       }
17331da177e4SLinus Torvalds 
17341da177e4SLinus Torvalds    ((PSCCBcard)pCurrCard)->cmdCounter++;
17351da177e4SLinus Torvalds 
17361da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
17371da177e4SLinus Torvalds 
17381da177e4SLinus Torvalds       WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
17391da177e4SLinus Torvalds          | TICKLE_ME));
17401da177e4SLinus Torvalds 		if(p_Sccb->OperationCode == RESET_COMMAND)
17411da177e4SLinus Torvalds 			{
17421da177e4SLinus Torvalds 				pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
17431da177e4SLinus Torvalds 				((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
174447b5d69cSJames Bottomley  				FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
17451da177e4SLinus Torvalds 				((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
17461da177e4SLinus Torvalds 			}
17471da177e4SLinus Torvalds 		else
17481da177e4SLinus Torvalds 			{
174947b5d69cSJames Bottomley  	      FPT_queueAddSccb(p_Sccb,thisCard);
17501da177e4SLinus Torvalds 			}
17511da177e4SLinus Torvalds       }
17521da177e4SLinus Torvalds 
17531da177e4SLinus Torvalds    else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
17541da177e4SLinus Torvalds 
17551da177e4SLinus Torvalds 			if(p_Sccb->OperationCode == RESET_COMMAND)
17561da177e4SLinus Torvalds 				{
17571da177e4SLinus Torvalds 					pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
17581da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
175947b5d69cSJames Bottomley  					FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
17601da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
17611da177e4SLinus Torvalds 				}
17621da177e4SLinus Torvalds 			else
17631da177e4SLinus Torvalds 				{
176447b5d69cSJames Bottomley  		      FPT_queueAddSccb(p_Sccb,thisCard);
17651da177e4SLinus Torvalds 				}
17661da177e4SLinus Torvalds       }
17671da177e4SLinus Torvalds 
17681da177e4SLinus Torvalds    else {
17691da177e4SLinus Torvalds 
17701da177e4SLinus Torvalds       MDISABLE_INT(ioport);
17711da177e4SLinus Torvalds 
17721da177e4SLinus Torvalds 		if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
177347b5d69cSJames Bottomley  			((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
17741da177e4SLinus Torvalds 			lun = p_Sccb->Lun;
17751da177e4SLinus Torvalds 		else
17761da177e4SLinus Torvalds 			lun = 0;
17771da177e4SLinus Torvalds       if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
177847b5d69cSJames Bottomley           (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
177947b5d69cSJames Bottomley           (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
178047b5d69cSJames Bottomley           == 0)) {
17811da177e4SLinus Torvalds 
17821da177e4SLinus Torvalds             ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
178347b5d69cSJames Bottomley  	    FPT_ssel(p_Sccb->SccbIOPort,thisCard);
17841da177e4SLinus Torvalds          }
17851da177e4SLinus Torvalds 
17861da177e4SLinus Torvalds       else {
17871da177e4SLinus Torvalds 
17881da177e4SLinus Torvalds 			if(p_Sccb->OperationCode == RESET_COMMAND)
17891da177e4SLinus Torvalds 				{
17901da177e4SLinus Torvalds 					pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
17911da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
179247b5d69cSJames Bottomley  					FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
17931da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
17941da177e4SLinus Torvalds 				}
17951da177e4SLinus Torvalds 			else
17961da177e4SLinus Torvalds 				{
179747b5d69cSJames Bottomley  	         	FPT_queueAddSccb(p_Sccb,thisCard);
17981da177e4SLinus Torvalds 				}
17991da177e4SLinus Torvalds          }
18001da177e4SLinus Torvalds 
18011da177e4SLinus Torvalds 
18021da177e4SLinus Torvalds       MENABLE_INT(ioport);
18031da177e4SLinus Torvalds       }
18041da177e4SLinus Torvalds 
18051da177e4SLinus Torvalds }
18061da177e4SLinus Torvalds 
18071da177e4SLinus Torvalds 
18081da177e4SLinus Torvalds /*---------------------------------------------------------------------
18091da177e4SLinus Torvalds  *
18101da177e4SLinus Torvalds  * Function: SccbMgr_abort_sccb
18111da177e4SLinus Torvalds  *
18121da177e4SLinus Torvalds  * Description: Abort the command pointed to by p_Sccb.  When the
18131da177e4SLinus Torvalds  *              command is completed it will be returned via the
18141da177e4SLinus Torvalds  *              callback function.
18151da177e4SLinus Torvalds  *
18161da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
181747b5d69cSJames Bottomley  static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
18181da177e4SLinus Torvalds {
18191da177e4SLinus Torvalds 	ULONG ioport;
18201da177e4SLinus Torvalds 
18211da177e4SLinus Torvalds 	UCHAR thisCard;
18221da177e4SLinus Torvalds 	CALL_BK_FN callback;
18231da177e4SLinus Torvalds 	UCHAR TID;
18241da177e4SLinus Torvalds 	PSCCB pSaveSCCB;
18251da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
18261da177e4SLinus Torvalds 
18271da177e4SLinus Torvalds 
18281da177e4SLinus Torvalds 	ioport = ((PSCCBcard) pCurrCard)->ioPort;
18291da177e4SLinus Torvalds 
18301da177e4SLinus Torvalds 	thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
18311da177e4SLinus Torvalds 
183247b5d69cSJames Bottomley  	if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
18331da177e4SLinus Torvalds 	{
18341da177e4SLinus Torvalds 
183547b5d69cSJames Bottomley  		if (FPT_queueFindSccb(p_Sccb,thisCard))
18361da177e4SLinus Torvalds 		{
18371da177e4SLinus Torvalds 
18381da177e4SLinus Torvalds 			((PSCCBcard)pCurrCard)->cmdCounter--;
18391da177e4SLinus Torvalds 
18401da177e4SLinus Torvalds 			if (!((PSCCBcard)pCurrCard)->cmdCounter)
18411da177e4SLinus Torvalds 				WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
18421da177e4SLinus Torvalds 					& (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
18431da177e4SLinus Torvalds 
18441da177e4SLinus Torvalds 			p_Sccb->SccbStatus = SCCB_ABORT;
18451da177e4SLinus Torvalds 			callback = p_Sccb->SccbCallback;
18461da177e4SLinus Torvalds 			callback(p_Sccb);
18471da177e4SLinus Torvalds 
18481da177e4SLinus Torvalds 			return(0);
18491da177e4SLinus Torvalds 		}
18501da177e4SLinus Torvalds 
18511da177e4SLinus Torvalds 		else
18521da177e4SLinus Torvalds 		{
18531da177e4SLinus Torvalds 			if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
18541da177e4SLinus Torvalds 			{
18551da177e4SLinus Torvalds 				p_Sccb->SccbStatus = SCCB_ABORT;
18561da177e4SLinus Torvalds 				return(0);
18571da177e4SLinus Torvalds 
18581da177e4SLinus Torvalds 			}
18591da177e4SLinus Torvalds 
18601da177e4SLinus Torvalds 			else
18611da177e4SLinus Torvalds 			{
18621da177e4SLinus Torvalds 
18631da177e4SLinus Torvalds 				TID = p_Sccb->TargID;
18641da177e4SLinus Torvalds 
18651da177e4SLinus Torvalds 
18661da177e4SLinus Torvalds 				if(p_Sccb->Sccb_tag)
18671da177e4SLinus Torvalds 				{
18681da177e4SLinus Torvalds 					MDISABLE_INT(ioport);
18691da177e4SLinus Torvalds 					if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
18701da177e4SLinus Torvalds 					{
18711da177e4SLinus Torvalds 						p_Sccb->SccbStatus = SCCB_ABORT;
18721da177e4SLinus Torvalds 						p_Sccb->Sccb_scsistat = ABORT_ST;
18731da177e4SLinus Torvalds 						p_Sccb->Sccb_scsimsg = SMABORT_TAG;
18741da177e4SLinus Torvalds 
18751da177e4SLinus Torvalds 						if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
18761da177e4SLinus Torvalds 						{
18771da177e4SLinus Torvalds 							((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
187847b5d69cSJames Bottomley  							FPT_ssel(ioport, thisCard);
18791da177e4SLinus Torvalds 						}
18801da177e4SLinus Torvalds 						else
18811da177e4SLinus Torvalds 						{
18821da177e4SLinus Torvalds 							pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
18831da177e4SLinus Torvalds 							((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
188447b5d69cSJames Bottomley  							FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
18851da177e4SLinus Torvalds 							((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
18861da177e4SLinus Torvalds 						}
18871da177e4SLinus Torvalds 					}
18881da177e4SLinus Torvalds 					MENABLE_INT(ioport);
18891da177e4SLinus Torvalds 					return(0);
18901da177e4SLinus Torvalds 				}
18911da177e4SLinus Torvalds 				else
18921da177e4SLinus Torvalds 				{
189347b5d69cSJames Bottomley  					currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
18941da177e4SLinus Torvalds 
189547b5d69cSJames Bottomley  					if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
18961da177e4SLinus Torvalds 							== p_Sccb)
18971da177e4SLinus Torvalds 					{
18981da177e4SLinus Torvalds 						p_Sccb->SccbStatus = SCCB_ABORT;
18991da177e4SLinus Torvalds 						return(0);
19001da177e4SLinus Torvalds 					}
19011da177e4SLinus Torvalds 				}
19021da177e4SLinus Torvalds 			}
19031da177e4SLinus Torvalds 		}
19041da177e4SLinus Torvalds 	}
19051da177e4SLinus Torvalds 	return(-1);
19061da177e4SLinus Torvalds }
19071da177e4SLinus Torvalds 
19081da177e4SLinus Torvalds 
19091da177e4SLinus Torvalds /*---------------------------------------------------------------------
19101da177e4SLinus Torvalds  *
19111da177e4SLinus Torvalds  * Function: SccbMgr_my_int
19121da177e4SLinus Torvalds  *
19131da177e4SLinus Torvalds  * Description: Do a quick check to determine if there is a pending
19141da177e4SLinus Torvalds  *              interrupt for this card and disable the IRQ Pin if so.
19151da177e4SLinus Torvalds  *
19161da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
191747b5d69cSJames Bottomley  static UCHAR SccbMgr_my_int(ULONG pCurrCard)
19181da177e4SLinus Torvalds {
19191da177e4SLinus Torvalds    ULONG ioport;
19201da177e4SLinus Torvalds 
19211da177e4SLinus Torvalds    ioport = ((PSCCBcard)pCurrCard)->ioPort;
19221da177e4SLinus Torvalds 
19231da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
19241da177e4SLinus Torvalds    {
192547b5d69cSJames Bottomley        return(1);
19261da177e4SLinus Torvalds    }
19271da177e4SLinus Torvalds 
19281da177e4SLinus Torvalds    else
19291da177e4SLinus Torvalds 
193047b5d69cSJames Bottomley        return(0);
19311da177e4SLinus Torvalds }
19321da177e4SLinus Torvalds 
19331da177e4SLinus Torvalds 
19341da177e4SLinus Torvalds 
19351da177e4SLinus Torvalds /*---------------------------------------------------------------------
19361da177e4SLinus Torvalds  *
19371da177e4SLinus Torvalds  * Function: SccbMgr_isr
19381da177e4SLinus Torvalds  *
19391da177e4SLinus Torvalds  * Description: This is our entry point when an interrupt is generated
19401da177e4SLinus Torvalds  *              by the card and the upper level driver passes it on to
19411da177e4SLinus Torvalds  *              us.
19421da177e4SLinus Torvalds  *
19431da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
194447b5d69cSJames Bottomley  static int SccbMgr_isr(ULONG pCurrCard)
19451da177e4SLinus Torvalds {
19461da177e4SLinus Torvalds    PSCCB currSCCB;
19471da177e4SLinus Torvalds    UCHAR thisCard,result,bm_status, bm_int_st;
19481da177e4SLinus Torvalds    USHORT hp_int;
19491da177e4SLinus Torvalds    UCHAR i, target;
19501da177e4SLinus Torvalds    ULONG ioport;
19511da177e4SLinus Torvalds 
19521da177e4SLinus Torvalds    thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
19531da177e4SLinus Torvalds    ioport = ((PSCCBcard)pCurrCard)->ioPort;
19541da177e4SLinus Torvalds 
19551da177e4SLinus Torvalds    MDISABLE_INT(ioport);
19561da177e4SLinus Torvalds 
19571da177e4SLinus Torvalds    if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
19581da177e4SLinus Torvalds 		bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
19591da177e4SLinus Torvalds    else
19601da177e4SLinus Torvalds       bm_status = 0;
19611da177e4SLinus Torvalds 
19621da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
19631da177e4SLinus Torvalds 
196447b5d69cSJames Bottomley     while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
19651da177e4SLinus Torvalds 	  bm_status)
19661da177e4SLinus Torvalds      {
19671da177e4SLinus Torvalds 
19681da177e4SLinus Torvalds        currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
19691da177e4SLinus Torvalds 
19701da177e4SLinus Torvalds       if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
197147b5d69cSJames Bottomley           result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
19721da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
19731da177e4SLinus Torvalds          bm_status = 0;
19741da177e4SLinus Torvalds 
19751da177e4SLinus Torvalds          if (result) {
19761da177e4SLinus Torvalds 
19771da177e4SLinus Torvalds             MENABLE_INT(ioport);
19781da177e4SLinus Torvalds             return(result);
19791da177e4SLinus Torvalds             }
19801da177e4SLinus Torvalds          }
19811da177e4SLinus Torvalds 
19821da177e4SLinus Torvalds 
19831da177e4SLinus Torvalds       else if (hp_int & ICMD_COMP) {
19841da177e4SLinus Torvalds 
19851da177e4SLinus Torvalds          if ( !(hp_int & BUS_FREE) ) {
19861da177e4SLinus Torvalds             /* Wait for the BusFree before starting a new command.  We
19871da177e4SLinus Torvalds                must also check for being reselected since the BusFree
19881da177e4SLinus Torvalds                may not show up if another device reselects us in 1.5us or
19891da177e4SLinus Torvalds                less.  SRR Wednesday, 3/8/1995.
19901da177e4SLinus Torvalds 	         */
19911da177e4SLinus Torvalds 	   while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
19921da177e4SLinus Torvalds 	 }
19931da177e4SLinus Torvalds 
19941da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
19951da177e4SLinus Torvalds 
199647b5d69cSJames Bottomley              FPT_phaseChkFifo(ioport, thisCard);
19971da177e4SLinus Torvalds 
19981da177e4SLinus Torvalds /*         WRW_HARPOON((ioport+hp_intstat),
19991da177e4SLinus Torvalds             (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
20001da177e4SLinus Torvalds          */
20011da177e4SLinus Torvalds 
20021da177e4SLinus Torvalds 		 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
20031da177e4SLinus Torvalds 
200447b5d69cSJames Bottomley           FPT_autoCmdCmplt(ioport,thisCard);
20051da177e4SLinus Torvalds 
20061da177e4SLinus Torvalds          }
20071da177e4SLinus Torvalds 
20081da177e4SLinus Torvalds 
20091da177e4SLinus Torvalds       else if (hp_int & ITAR_DISC)
20101da177e4SLinus Torvalds          {
20111da177e4SLinus Torvalds 
20121da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
20131da177e4SLinus Torvalds 
201447b5d69cSJames Bottomley              FPT_phaseChkFifo(ioport, thisCard);
20151da177e4SLinus Torvalds 
20161da177e4SLinus Torvalds             }
20171da177e4SLinus Torvalds 
20181da177e4SLinus Torvalds          if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
20191da177e4SLinus Torvalds 
20201da177e4SLinus Torvalds             WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
20211da177e4SLinus Torvalds             currSCCB->Sccb_XferState |= F_NO_DATA_YET;
20221da177e4SLinus Torvalds 
20231da177e4SLinus Torvalds             currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
20241da177e4SLinus Torvalds             }
20251da177e4SLinus Torvalds 
20261da177e4SLinus Torvalds          currSCCB->Sccb_scsistat = DISCONNECT_ST;
202747b5d69cSJames Bottomley           FPT_queueDisconnect(currSCCB,thisCard);
20281da177e4SLinus Torvalds 
20291da177e4SLinus Torvalds             /* Wait for the BusFree before starting a new command.  We
20301da177e4SLinus Torvalds                must also check for being reselected since the BusFree
20311da177e4SLinus Torvalds                may not show up if another device reselects us in 1.5us or
20321da177e4SLinus Torvalds                less.  SRR Wednesday, 3/8/1995.
20331da177e4SLinus Torvalds              */
20341da177e4SLinus Torvalds 	   while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
20351da177e4SLinus Torvalds 		  !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
20361da177e4SLinus Torvalds 		    RD_HARPOON((ioport+hp_scsisig)) ==
20371da177e4SLinus Torvalds 		    (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
20381da177e4SLinus Torvalds 
20391da177e4SLinus Torvalds 	   /*
20401da177e4SLinus Torvalds 	     The additional loop exit condition above detects a timing problem
20411da177e4SLinus Torvalds 	     with the revision D/E harpoon chips.  The caller should reset the
20421da177e4SLinus Torvalds 	     host adapter to recover when 0xFE is returned.
20431da177e4SLinus Torvalds 	   */
20441da177e4SLinus Torvalds 	   if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
20451da177e4SLinus Torvalds 	     {
20461da177e4SLinus Torvalds 	       MENABLE_INT(ioport);
20471da177e4SLinus Torvalds 	       return 0xFE;
20481da177e4SLinus Torvalds 	     }
20491da177e4SLinus Torvalds 
20501da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
20511da177e4SLinus Torvalds 
20521da177e4SLinus Torvalds 
20531da177e4SLinus Torvalds          ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
20541da177e4SLinus Torvalds 
20551da177e4SLinus Torvalds       	}
20561da177e4SLinus Torvalds 
20571da177e4SLinus Torvalds 
20581da177e4SLinus Torvalds       else if (hp_int & RSEL) {
20591da177e4SLinus Torvalds 
20601da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
20611da177e4SLinus Torvalds 
20621da177e4SLinus Torvalds          if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
20631da177e4SLinus Torvalds 		      {
20641da177e4SLinus Torvalds             if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
20651da177e4SLinus Torvalds 			      {
206647b5d69cSJames Bottomley                 FPT_phaseChkFifo(ioport, thisCard);
20671da177e4SLinus Torvalds                }
20681da177e4SLinus Torvalds 
20691da177e4SLinus Torvalds             if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
20701da177e4SLinus Torvalds 			      {
20711da177e4SLinus Torvalds                WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
20721da177e4SLinus Torvalds                currSCCB->Sccb_XferState |= F_NO_DATA_YET;
20731da177e4SLinus Torvalds                currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
20741da177e4SLinus Torvalds                }
20751da177e4SLinus Torvalds 
20761da177e4SLinus Torvalds             WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
20771da177e4SLinus Torvalds             currSCCB->Sccb_scsistat = DISCONNECT_ST;
207847b5d69cSJames Bottomley              FPT_queueDisconnect(currSCCB,thisCard);
20791da177e4SLinus Torvalds             }
20801da177e4SLinus Torvalds 
208147b5d69cSJames Bottomley           FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
208247b5d69cSJames Bottomley           FPT_phaseDecode(ioport,thisCard);
20831da177e4SLinus Torvalds 
20841da177e4SLinus Torvalds          }
20851da177e4SLinus Torvalds 
20861da177e4SLinus Torvalds 
20871da177e4SLinus Torvalds       else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
20881da177e4SLinus Torvalds          {
20891da177e4SLinus Torvalds 
20901da177e4SLinus Torvalds             WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
209147b5d69cSJames Bottomley              FPT_phaseDecode(ioport,thisCard);
20921da177e4SLinus Torvalds 
20931da177e4SLinus Torvalds          }
20941da177e4SLinus Torvalds 
20951da177e4SLinus Torvalds 
20961da177e4SLinus Torvalds       else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
20971da177e4SLinus Torvalds 		   {
20981da177e4SLinus Torvalds 	 	   WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
20991da177e4SLinus Torvalds 	 	   if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
21001da177e4SLinus Torvalds 	    		{
210147b5d69cSJames Bottomley  	    		FPT_phaseDecode(ioport,thisCard);
21021da177e4SLinus Torvalds 	    		}
21031da177e4SLinus Torvalds 	 	   else
21041da177e4SLinus Torvalds 	    		{
21051da177e4SLinus Torvalds    /* Harpoon problem some SCSI target device respond to selection
21061da177e4SLinus Torvalds    with short BUSY pulse (<400ns) this will make the Harpoon is not able
21071da177e4SLinus Torvalds    to latch the correct Target ID into reg. x53.
21081da177e4SLinus Torvalds    The work around require to correct this reg. But when write to this
21091da177e4SLinus Torvalds    reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
21101da177e4SLinus Torvalds    need to read this reg first then restore it later. After update to 0x53 */
21111da177e4SLinus Torvalds 
21121da177e4SLinus Torvalds 	    		i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
21131da177e4SLinus Torvalds 	    		target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
21141da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
21151da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
21161da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
21171da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_fifowrite, i);
21181da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
21191da177e4SLinus Torvalds 	    		}
21201da177e4SLinus Torvalds 	 	   }
21211da177e4SLinus Torvalds 
21221da177e4SLinus Torvalds       else if (hp_int & XFER_CNT_0) {
21231da177e4SLinus Torvalds 
21241da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
21251da177e4SLinus Torvalds 
212647b5d69cSJames Bottomley           FPT_schkdd(ioport,thisCard);
21271da177e4SLinus Torvalds 
21281da177e4SLinus Torvalds          }
21291da177e4SLinus Torvalds 
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds       else if (hp_int & BUS_FREE) {
21321da177e4SLinus Torvalds 
21331da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
21341da177e4SLinus Torvalds 
21351da177e4SLinus Torvalds         	if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
21361da177e4SLinus Torvalds 
213747b5d69cSJames Bottomley             	FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
21381da177e4SLinus Torvalds 				}
21391da177e4SLinus Torvalds 
214047b5d69cSJames Bottomley           FPT_phaseBusFree(ioport,thisCard);
21411da177e4SLinus Torvalds 			}
21421da177e4SLinus Torvalds 
21431da177e4SLinus Torvalds 
21441da177e4SLinus Torvalds       else if (hp_int & ITICKLE) {
21451da177e4SLinus Torvalds 
21461da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), ITICKLE);
21471da177e4SLinus Torvalds          ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
21481da177e4SLinus Torvalds          }
21491da177e4SLinus Torvalds 
21501da177e4SLinus Torvalds 
21511da177e4SLinus Torvalds 
21521da177e4SLinus Torvalds       if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
21531da177e4SLinus Torvalds 
21541da177e4SLinus Torvalds 
21551da177e4SLinus Torvalds          ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
21561da177e4SLinus Torvalds 
21571da177e4SLinus Torvalds 
21581da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
21591da177e4SLinus Torvalds 
216047b5d69cSJames Bottomley              FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
21611da177e4SLinus Torvalds             }
21621da177e4SLinus Torvalds 
21631da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
21641da177e4SLinus Torvalds             ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
216547b5d69cSJames Bottomley              FPT_ssel(ioport,thisCard);
21661da177e4SLinus Torvalds             }
21671da177e4SLinus Torvalds 
21681da177e4SLinus Torvalds          break;
21691da177e4SLinus Torvalds 
21701da177e4SLinus Torvalds          }
21711da177e4SLinus Torvalds 
21721da177e4SLinus Torvalds       }  /*end while */
21731da177e4SLinus Torvalds 
21741da177e4SLinus Torvalds    MENABLE_INT(ioport);
21751da177e4SLinus Torvalds 
21761da177e4SLinus Torvalds    return(0);
21771da177e4SLinus Torvalds }
21781da177e4SLinus Torvalds 
21791da177e4SLinus Torvalds /*---------------------------------------------------------------------
21801da177e4SLinus Torvalds  *
21811da177e4SLinus Torvalds  * Function: Sccb_bad_isr
21821da177e4SLinus Torvalds  *
21831da177e4SLinus Torvalds  * Description: Some type of interrupt has occurred which is slightly
21841da177e4SLinus Torvalds  *              out of the ordinary.  We will now decode it fully, in
21851da177e4SLinus Torvalds  *              this routine.  This is broken up in an attempt to save
21861da177e4SLinus Torvalds  *              processing time.
21871da177e4SLinus Torvalds  *
21881da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
218947b5d69cSJames Bottomley  static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
219047b5d69cSJames Bottomley  				 PSCCBcard pCurrCard, USHORT p_int)
21911da177e4SLinus Torvalds {
21921da177e4SLinus Torvalds    UCHAR temp, ScamFlg;
21931da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
21941da177e4SLinus Torvalds    PNVRamInfo pCurrNvRam;
21951da177e4SLinus Torvalds 
21961da177e4SLinus Torvalds 
21971da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_ext_status) &
21981da177e4SLinus Torvalds          (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
21991da177e4SLinus Torvalds       {
22001da177e4SLinus Torvalds 
22011da177e4SLinus Torvalds       if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
22021da177e4SLinus Torvalds          {
22031da177e4SLinus Torvalds 
220447b5d69cSJames Bottomley           FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
22051da177e4SLinus Torvalds          }
22061da177e4SLinus Torvalds 
22071da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
22081da177e4SLinus Torvalds 
22091da177e4SLinus Torvalds          {
22101da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_pci_stat_cfg,
22111da177e4SLinus Torvalds             (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
22121da177e4SLinus Torvalds 
22131da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
22141da177e4SLinus Torvalds 
22151da177e4SLinus Torvalds          }
22161da177e4SLinus Torvalds 
22171da177e4SLinus Torvalds       if (pCurrCard->currentSCCB != NULL)
22181da177e4SLinus Torvalds          {
22191da177e4SLinus Torvalds 
22201da177e4SLinus Torvalds          if (!pCurrCard->currentSCCB->HostStatus)
22211da177e4SLinus Torvalds             pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
22221da177e4SLinus Torvalds 
222347b5d69cSJames Bottomley           FPT_sxfrp(p_port,p_card);
22241da177e4SLinus Torvalds 
22251da177e4SLinus Torvalds 	     temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
22261da177e4SLinus Torvalds 							(EXT_ARB_ACK | SCSI_TERM_ENA_H));
22271da177e4SLinus Torvalds       	WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
22281da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_ee_ctrl, temp);
22291da177e4SLinus Torvalds 
22301da177e4SLinus Torvalds          if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
22311da177e4SLinus Torvalds             {
223247b5d69cSJames Bottomley              FPT_phaseDecode(p_port,p_card);
22331da177e4SLinus Torvalds             }
22341da177e4SLinus Torvalds          }
22351da177e4SLinus Torvalds       }
22361da177e4SLinus Torvalds 
22371da177e4SLinus Torvalds 
22381da177e4SLinus Torvalds    else if (p_int & RESET)
22391da177e4SLinus Torvalds          {
22401da177e4SLinus Torvalds 
22411da177e4SLinus Torvalds 				WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
22421da177e4SLinus Torvalds 				WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
22431da177e4SLinus Torvalds            if (pCurrCard->currentSCCB != NULL) {
22441da177e4SLinus Torvalds 
22451da177e4SLinus Torvalds                if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
22461da177e4SLinus Torvalds 
224747b5d69cSJames Bottomley                 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
22481da177e4SLinus Torvalds                }
22491da177e4SLinus Torvalds 
22501da177e4SLinus Torvalds 
22511da177e4SLinus Torvalds            DISABLE_AUTO(p_port);
22521da177e4SLinus Torvalds 
225347b5d69cSJames Bottomley             FPT_sresb(p_port,p_card);
22541da177e4SLinus Torvalds 
22551da177e4SLinus Torvalds            while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
22561da177e4SLinus Torvalds 
22571da177e4SLinus Torvalds 				pCurrNvRam = pCurrCard->pNvRamInfo;
22581da177e4SLinus Torvalds 				if(pCurrNvRam){
22591da177e4SLinus Torvalds 					ScamFlg = pCurrNvRam->niScamConf;
22601da177e4SLinus Torvalds 				}
22611da177e4SLinus Torvalds 				else{
226247b5d69cSJames Bottomley  				   ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
22631da177e4SLinus Torvalds 				}
22641da177e4SLinus Torvalds 
226547b5d69cSJames Bottomley             FPT_XbowInit(p_port, ScamFlg);
22661da177e4SLinus Torvalds 
226747b5d69cSJames Bottomley                 FPT_scini(p_card, pCurrCard->ourId, 0);
22681da177e4SLinus Torvalds 
22691da177e4SLinus Torvalds            return(0xFF);
22701da177e4SLinus Torvalds          }
22711da177e4SLinus Torvalds 
22721da177e4SLinus Torvalds 
22731da177e4SLinus Torvalds    else if (p_int & FIFO) {
22741da177e4SLinus Torvalds 
22751da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat), FIFO);
22761da177e4SLinus Torvalds 
22771da177e4SLinus Torvalds       if (pCurrCard->currentSCCB != NULL)
227847b5d69cSJames Bottomley           FPT_sxfrp(p_port,p_card);
22791da177e4SLinus Torvalds       }
22801da177e4SLinus Torvalds 
22811da177e4SLinus Torvalds    else if (p_int & TIMEOUT)
22821da177e4SLinus Torvalds       {
22831da177e4SLinus Torvalds 
22841da177e4SLinus Torvalds       DISABLE_AUTO(p_port);
22851da177e4SLinus Torvalds 
22861da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat),
22871da177e4SLinus Torvalds 		  (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
22881da177e4SLinus Torvalds 
22891da177e4SLinus Torvalds       pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
22901da177e4SLinus Torvalds 
22911da177e4SLinus Torvalds 
229247b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
22931da177e4SLinus Torvalds 		if((pCurrCard->globalFlags & F_CONLUN_IO) &&
22941da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
229547b5d69cSJames Bottomley  	      currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
22961da177e4SLinus Torvalds 		else
229747b5d69cSJames Bottomley  	      currTar_Info->TarLUNBusy[0] = 0;
22981da177e4SLinus Torvalds 
22991da177e4SLinus Torvalds 
23001da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
23011da177e4SLinus Torvalds          {
23021da177e4SLinus Torvalds 	       currTar_Info->TarSyncCtrl = 0;
23031da177e4SLinus Torvalds          currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
23041da177e4SLinus Torvalds          }
23051da177e4SLinus Torvalds 
23061da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
23071da177e4SLinus Torvalds          {
23081da177e4SLinus Torvalds          currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
23091da177e4SLinus Torvalds          }
23101da177e4SLinus Torvalds 
231147b5d69cSJames Bottomley        FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
23121da177e4SLinus Torvalds 
231347b5d69cSJames Bottomley        FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
23141da177e4SLinus Torvalds 
23151da177e4SLinus Torvalds       }
23161da177e4SLinus Torvalds 
23171da177e4SLinus Torvalds    else if (p_int & SCAM_SEL)
23181da177e4SLinus Torvalds       {
23191da177e4SLinus Torvalds 
232047b5d69cSJames Bottomley        FPT_scarb(p_port,LEVEL2_TAR);
232147b5d69cSJames Bottomley        FPT_scsel(p_port);
232247b5d69cSJames Bottomley        FPT_scasid(p_card, p_port);
23231da177e4SLinus Torvalds 
232447b5d69cSJames Bottomley        FPT_scbusf(p_port);
23251da177e4SLinus Torvalds 
23261da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
23271da177e4SLinus Torvalds       }
23281da177e4SLinus Torvalds 
23291da177e4SLinus Torvalds    return(0x00);
23301da177e4SLinus Torvalds }
23311da177e4SLinus Torvalds 
23321da177e4SLinus Torvalds 
23331da177e4SLinus Torvalds /*---------------------------------------------------------------------
23341da177e4SLinus Torvalds  *
23351da177e4SLinus Torvalds  * Function: SccbMgrTableInit
23361da177e4SLinus Torvalds  *
23371da177e4SLinus Torvalds  * Description: Initialize all Sccb manager data structures.
23381da177e4SLinus Torvalds  *
23391da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
23401da177e4SLinus Torvalds 
234147b5d69cSJames Bottomley  static void FPT_SccbMgrTableInitAll()
23421da177e4SLinus Torvalds {
23431da177e4SLinus Torvalds    UCHAR thisCard;
23441da177e4SLinus Torvalds 
23451da177e4SLinus Torvalds    for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
23461da177e4SLinus Torvalds       {
234747b5d69cSJames Bottomley        FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
23481da177e4SLinus Torvalds 
234947b5d69cSJames Bottomley        FPT_BL_Card[thisCard].ioPort      = 0x00;
235047b5d69cSJames Bottomley        FPT_BL_Card[thisCard].cardInfo    = NULL;
235147b5d69cSJames Bottomley        FPT_BL_Card[thisCard].cardIndex   = 0xFF;
235247b5d69cSJames Bottomley        FPT_BL_Card[thisCard].ourId       = 0x00;
235347b5d69cSJames Bottomley  		FPT_BL_Card[thisCard].pNvRamInfo	= NULL;
23541da177e4SLinus Torvalds       }
23551da177e4SLinus Torvalds }
23561da177e4SLinus Torvalds 
23571da177e4SLinus Torvalds 
23581da177e4SLinus Torvalds /*---------------------------------------------------------------------
23591da177e4SLinus Torvalds  *
23601da177e4SLinus Torvalds  * Function: SccbMgrTableInit
23611da177e4SLinus Torvalds  *
23621da177e4SLinus Torvalds  * Description: Initialize all Sccb manager data structures.
23631da177e4SLinus Torvalds  *
23641da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
23651da177e4SLinus Torvalds 
236647b5d69cSJames Bottomley  static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
23671da177e4SLinus Torvalds {
23681da177e4SLinus Torvalds    UCHAR scsiID, qtag;
23691da177e4SLinus Torvalds 
23701da177e4SLinus Torvalds 	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
23711da177e4SLinus Torvalds 	{
237247b5d69cSJames Bottomley  		FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
23731da177e4SLinus Torvalds 	}
23741da177e4SLinus Torvalds 
23751da177e4SLinus Torvalds    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
23761da177e4SLinus Torvalds       {
237747b5d69cSJames Bottomley        FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
237847b5d69cSJames Bottomley        FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
237947b5d69cSJames Bottomley        FPT_SccbMgrTableInitTarget(p_card, scsiID);
23801da177e4SLinus Torvalds       }
23811da177e4SLinus Torvalds 
23821da177e4SLinus Torvalds    pCurrCard->scanIndex = 0x00;
23831da177e4SLinus Torvalds    pCurrCard->currentSCCB = NULL;
23841da177e4SLinus Torvalds    pCurrCard->globalFlags = 0x00;
23851da177e4SLinus Torvalds    pCurrCard->cmdCounter  = 0x00;
23861da177e4SLinus Torvalds 	pCurrCard->tagQ_Lst = 0x01;
23871da177e4SLinus Torvalds 	pCurrCard->discQCount = 0;
23881da177e4SLinus Torvalds 
23891da177e4SLinus Torvalds 
23901da177e4SLinus Torvalds }
23911da177e4SLinus Torvalds 
23921da177e4SLinus Torvalds 
23931da177e4SLinus Torvalds /*---------------------------------------------------------------------
23941da177e4SLinus Torvalds  *
23951da177e4SLinus Torvalds  * Function: SccbMgrTableInit
23961da177e4SLinus Torvalds  *
23971da177e4SLinus Torvalds  * Description: Initialize all Sccb manager data structures.
23981da177e4SLinus Torvalds  *
23991da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
24001da177e4SLinus Torvalds 
240147b5d69cSJames Bottomley  static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
24021da177e4SLinus Torvalds {
24031da177e4SLinus Torvalds 
24041da177e4SLinus Torvalds 	UCHAR lun, qtag;
24051da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
24061da177e4SLinus Torvalds 
240747b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
24081da177e4SLinus Torvalds 
24091da177e4SLinus Torvalds 	currTar_Info->TarSelQ_Cnt = 0;
24101da177e4SLinus Torvalds 	currTar_Info->TarSyncCtrl = 0;
24111da177e4SLinus Torvalds 
24121da177e4SLinus Torvalds 	currTar_Info->TarSelQ_Head = NULL;
24131da177e4SLinus Torvalds 	currTar_Info->TarSelQ_Tail = NULL;
24141da177e4SLinus Torvalds 	currTar_Info->TarTagQ_Cnt = 0;
241547b5d69cSJames Bottomley  	currTar_Info->TarLUN_CA = 0;
24161da177e4SLinus Torvalds 
24171da177e4SLinus Torvalds 
24181da177e4SLinus Torvalds 	for (lun = 0; lun < MAX_LUN; lun++)
24191da177e4SLinus Torvalds 	{
242047b5d69cSJames Bottomley  		currTar_Info->TarLUNBusy[lun] = 0;
24211da177e4SLinus Torvalds 		currTar_Info->LunDiscQ_Idx[lun] = 0;
24221da177e4SLinus Torvalds 	}
24231da177e4SLinus Torvalds 
24241da177e4SLinus Torvalds 	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
24251da177e4SLinus Torvalds 	{
242647b5d69cSJames Bottomley  		if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
24271da177e4SLinus Torvalds 		{
242847b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
24291da177e4SLinus Torvalds 			{
243047b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
243147b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQCount--;
24321da177e4SLinus Torvalds 			}
24331da177e4SLinus Torvalds 		}
24341da177e4SLinus Torvalds 	}
24351da177e4SLinus Torvalds }
24361da177e4SLinus Torvalds 
24371da177e4SLinus Torvalds 
24381da177e4SLinus Torvalds /*---------------------------------------------------------------------
24391da177e4SLinus Torvalds  *
24401da177e4SLinus Torvalds  * Function: sfetm
24411da177e4SLinus Torvalds  *
24421da177e4SLinus Torvalds  * Description: Read in a message byte from the SCSI bus, and check
24431da177e4SLinus Torvalds  *              for a parity error.
24441da177e4SLinus Torvalds  *
24451da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
24461da177e4SLinus Torvalds 
244747b5d69cSJames Bottomley  static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
24481da177e4SLinus Torvalds {
24491da177e4SLinus Torvalds 	UCHAR message;
24501da177e4SLinus Torvalds 	USHORT TimeOutLoop;
24511da177e4SLinus Torvalds 
24521da177e4SLinus Torvalds 	TimeOutLoop = 0;
24531da177e4SLinus Torvalds 	while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
24541da177e4SLinus Torvalds 			(TimeOutLoop++ < 20000) ){}
24551da177e4SLinus Torvalds 
24561da177e4SLinus Torvalds 
24571da177e4SLinus Torvalds 	WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
24581da177e4SLinus Torvalds 
24591da177e4SLinus Torvalds 	message = RD_HARPOON(port+hp_scsidata_0);
24601da177e4SLinus Torvalds 
24611da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
24621da177e4SLinus Torvalds 
24631da177e4SLinus Torvalds 
24641da177e4SLinus Torvalds 	if (TimeOutLoop > 20000)
24651da177e4SLinus Torvalds 		message = 0x00;   /* force message byte = 0 if Time Out on Req */
24661da177e4SLinus Torvalds 
24671da177e4SLinus Torvalds 	if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
24681da177e4SLinus Torvalds 		(RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
24691da177e4SLinus Torvalds 	{
24701da177e4SLinus Torvalds 		WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
24711da177e4SLinus Torvalds 		WR_HARPOON(port+hp_xferstat, 0);
24721da177e4SLinus Torvalds 		WR_HARPOON(port+hp_fiforead, 0);
24731da177e4SLinus Torvalds 		WR_HARPOON(port+hp_fifowrite, 0);
24741da177e4SLinus Torvalds 		if (pCurrSCCB != NULL)
24751da177e4SLinus Torvalds 		{
24761da177e4SLinus Torvalds 			pCurrSCCB->Sccb_scsimsg = SMPARITY;
24771da177e4SLinus Torvalds 		}
24781da177e4SLinus Torvalds 		message = 0x00;
24791da177e4SLinus Torvalds 		do
24801da177e4SLinus Torvalds 		{
24811da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
24821da177e4SLinus Torvalds 			TimeOutLoop = 0;
24831da177e4SLinus Torvalds 			while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
24841da177e4SLinus Torvalds 				(TimeOutLoop++ < 20000) ){}
24851da177e4SLinus Torvalds 			if (TimeOutLoop > 20000)
24861da177e4SLinus Torvalds 			{
24871da177e4SLinus Torvalds 				WRW_HARPOON((port+hp_intstat), PARITY);
24881da177e4SLinus Torvalds 				return(message);
24891da177e4SLinus Torvalds 			}
24901da177e4SLinus Torvalds 			if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
24911da177e4SLinus Torvalds 			{
24921da177e4SLinus Torvalds 				WRW_HARPOON((port+hp_intstat), PARITY);
24931da177e4SLinus Torvalds 				return(message);
24941da177e4SLinus Torvalds 			}
24951da177e4SLinus Torvalds 			WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
24961da177e4SLinus Torvalds 
24971da177e4SLinus Torvalds 			RD_HARPOON(port+hp_scsidata_0);
24981da177e4SLinus Torvalds 
24991da177e4SLinus Torvalds 			WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
25001da177e4SLinus Torvalds 
25011da177e4SLinus Torvalds 		}while(1);
25021da177e4SLinus Torvalds 
25031da177e4SLinus Torvalds 	}
25041da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
25051da177e4SLinus Torvalds 	WR_HARPOON(port+hp_xferstat, 0);
25061da177e4SLinus Torvalds 	WR_HARPOON(port+hp_fiforead, 0);
25071da177e4SLinus Torvalds 	WR_HARPOON(port+hp_fifowrite, 0);
25081da177e4SLinus Torvalds 	return(message);
25091da177e4SLinus Torvalds }
25101da177e4SLinus Torvalds 
25111da177e4SLinus Torvalds 
25121da177e4SLinus Torvalds /*---------------------------------------------------------------------
25131da177e4SLinus Torvalds  *
251447b5d69cSJames Bottomley   * Function: FPT_ssel
25151da177e4SLinus Torvalds  *
25161da177e4SLinus Torvalds  * Description: Load up automation and select target device.
25171da177e4SLinus Torvalds  *
25181da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
25191da177e4SLinus Torvalds 
252047b5d69cSJames Bottomley  static void FPT_ssel(ULONG port, UCHAR p_card)
25211da177e4SLinus Torvalds {
25221da177e4SLinus Torvalds 
25231da177e4SLinus Torvalds    UCHAR auto_loaded, i, target, *theCCB;
25241da177e4SLinus Torvalds 
25251da177e4SLinus Torvalds    ULONG cdb_reg;
25261da177e4SLinus Torvalds    PSCCBcard CurrCard;
25271da177e4SLinus Torvalds    PSCCB currSCCB;
25281da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
25291da177e4SLinus Torvalds    UCHAR lastTag, lun;
25301da177e4SLinus Torvalds 
253147b5d69cSJames Bottomley     CurrCard = &FPT_BL_Card[p_card];
25321da177e4SLinus Torvalds    currSCCB = CurrCard->currentSCCB;
25331da177e4SLinus Torvalds    target = currSCCB->TargID;
253447b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][target];
25351da177e4SLinus Torvalds    lastTag = CurrCard->tagQ_Lst;
25361da177e4SLinus Torvalds 
25371da177e4SLinus Torvalds    ARAM_ACCESS(port);
25381da177e4SLinus Torvalds 
25391da177e4SLinus Torvalds 
25401da177e4SLinus Torvalds 	if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
25411da177e4SLinus Torvalds 		currSCCB->ControlByte &= ~F_USE_CMD_Q;
25421da177e4SLinus Torvalds 
25431da177e4SLinus Torvalds 	if(((CurrCard->globalFlags & F_CONLUN_IO) &&
25441da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
25451da177e4SLinus Torvalds 
25461da177e4SLinus Torvalds 	   lun = currSCCB->Lun;
25471da177e4SLinus Torvalds 	else
25481da177e4SLinus Torvalds 		lun = 0;
25491da177e4SLinus Torvalds 
25501da177e4SLinus Torvalds 
25511da177e4SLinus Torvalds    if (CurrCard->globalFlags & F_TAG_STARTED)
25521da177e4SLinus Torvalds       {
25531da177e4SLinus Torvalds       if (!(currSCCB->ControlByte & F_USE_CMD_Q))
25541da177e4SLinus Torvalds          {
255547b5d69cSJames Bottomley        	if ((currTar_Info->TarLUN_CA == 0)
25561da177e4SLinus Torvalds       	    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
25571da177e4SLinus Torvalds       	    == TAG_Q_TRYING))
25581da177e4SLinus Torvalds             {
25591da177e4SLinus Torvalds 
25601da177e4SLinus Torvalds 	         if (currTar_Info->TarTagQ_Cnt !=0)
25611da177e4SLinus Torvalds                   {
256247b5d69cSJames Bottomley           		   currTar_Info->TarLUNBusy[lun] = 1;
256347b5d69cSJames Bottomley              		FPT_queueSelectFail(CurrCard,p_card);
25641da177e4SLinus Torvalds 					   SGRAM_ACCESS(port);
25651da177e4SLinus Torvalds          		   return;
25661da177e4SLinus Torvalds          		   }
25671da177e4SLinus Torvalds 
25681da177e4SLinus Torvalds             else {
256947b5d69cSJames Bottomley           		  currTar_Info->TarLUNBusy[lun] = 1;
25701da177e4SLinus Torvalds          		  }
25711da177e4SLinus Torvalds 
25721da177e4SLinus Torvalds    	      }  /*End non-tagged */
25731da177e4SLinus Torvalds 
25741da177e4SLinus Torvalds 	      else {
257547b5d69cSJames Bottomley  	         currTar_Info->TarLUNBusy[lun] = 1;
25761da177e4SLinus Torvalds 	         }
25771da177e4SLinus Torvalds 
25781da177e4SLinus Torvalds 	      }  /*!Use cmd Q Tagged */
25791da177e4SLinus Torvalds 
25801da177e4SLinus Torvalds 	   else {
258147b5d69cSJames Bottomley     	     if (currTar_Info->TarLUN_CA == 1)
25821da177e4SLinus Torvalds                {
258347b5d69cSJames Bottomley        	      FPT_queueSelectFail(CurrCard,p_card);
25841da177e4SLinus Torvalds 				   SGRAM_ACCESS(port);
25851da177e4SLinus Torvalds       	      return;
25861da177e4SLinus Torvalds 	            }
25871da177e4SLinus Torvalds 
258847b5d69cSJames Bottomley  	        currTar_Info->TarLUNBusy[lun] = 1;
25891da177e4SLinus Torvalds 
25901da177e4SLinus Torvalds    	     }  /*else use cmd Q tagged */
25911da177e4SLinus Torvalds 
25921da177e4SLinus Torvalds       }  /*if glob tagged started */
25931da177e4SLinus Torvalds 
25941da177e4SLinus Torvalds    else {
259547b5d69cSJames Bottomley          currTar_Info->TarLUNBusy[lun] = 1;
25961da177e4SLinus Torvalds         }
25971da177e4SLinus Torvalds 
25981da177e4SLinus Torvalds 
25991da177e4SLinus Torvalds 
26001da177e4SLinus Torvalds 	if((((CurrCard->globalFlags & F_CONLUN_IO) &&
26011da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
26021da177e4SLinus Torvalds 		|| (!(currSCCB->ControlByte & F_USE_CMD_Q))))
26031da177e4SLinus Torvalds 	{
26041da177e4SLinus Torvalds 		if(CurrCard->discQCount >= QUEUE_DEPTH)
26051da177e4SLinus Torvalds 		{
260647b5d69cSJames Bottomley  			currTar_Info->TarLUNBusy[lun] = 1;
260747b5d69cSJames Bottomley  			FPT_queueSelectFail(CurrCard,p_card);
26081da177e4SLinus Torvalds 			SGRAM_ACCESS(port);
26091da177e4SLinus Torvalds 			return;
26101da177e4SLinus Torvalds 		}
26111da177e4SLinus Torvalds 		for (i = 1; i < QUEUE_DEPTH; i++)
26121da177e4SLinus Torvalds 		{
26131da177e4SLinus Torvalds 			if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
26141da177e4SLinus Torvalds 			if (CurrCard->discQ_Tbl[lastTag] == NULL)
26151da177e4SLinus Torvalds 			{
26161da177e4SLinus Torvalds 				CurrCard->tagQ_Lst = lastTag;
26171da177e4SLinus Torvalds 				currTar_Info->LunDiscQ_Idx[lun] = lastTag;
26181da177e4SLinus Torvalds 				CurrCard->discQ_Tbl[lastTag] = currSCCB;
26191da177e4SLinus Torvalds 				CurrCard->discQCount++;
26201da177e4SLinus Torvalds 				break;
26211da177e4SLinus Torvalds 			}
26221da177e4SLinus Torvalds 		}
26231da177e4SLinus Torvalds 		if(i == QUEUE_DEPTH)
26241da177e4SLinus Torvalds 		{
262547b5d69cSJames Bottomley  			currTar_Info->TarLUNBusy[lun] = 1;
262647b5d69cSJames Bottomley  			FPT_queueSelectFail(CurrCard,p_card);
26271da177e4SLinus Torvalds 			SGRAM_ACCESS(port);
26281da177e4SLinus Torvalds 			return;
26291da177e4SLinus Torvalds 		}
26301da177e4SLinus Torvalds 	}
26311da177e4SLinus Torvalds 
26321da177e4SLinus Torvalds 
26331da177e4SLinus Torvalds 
263447b5d69cSJames Bottomley     auto_loaded = 0;
26351da177e4SLinus Torvalds 
26361da177e4SLinus Torvalds    WR_HARPOON(port+hp_select_id, target);
26371da177e4SLinus Torvalds    WR_HARPOON(port+hp_gp_reg_3, target);  /* Use by new automation logic */
26381da177e4SLinus Torvalds 
26391da177e4SLinus Torvalds    if (currSCCB->OperationCode == RESET_COMMAND) {
26401da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
26411da177e4SLinus Torvalds                	 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
26421da177e4SLinus Torvalds 
26431da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
26441da177e4SLinus Torvalds 
26451da177e4SLinus Torvalds       currSCCB->Sccb_scsimsg = SMDEV_RESET;
26461da177e4SLinus Torvalds 
26471da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
264847b5d69cSJames Bottomley        auto_loaded = 1;
26491da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = SELECT_BDR_ST;
26501da177e4SLinus Torvalds 
26511da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
26521da177e4SLinus Torvalds          {
26531da177e4SLinus Torvalds 	       currTar_Info->TarSyncCtrl = 0;
26541da177e4SLinus Torvalds 	      currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
26551da177e4SLinus Torvalds 	      }
26561da177e4SLinus Torvalds 
26571da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
26581da177e4SLinus Torvalds          {
26591da177e4SLinus Torvalds       	currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
26601da177e4SLinus Torvalds       	}
26611da177e4SLinus Torvalds 
266247b5d69cSJames Bottomley        FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
266347b5d69cSJames Bottomley        FPT_SccbMgrTableInitTarget(p_card, target);
26641da177e4SLinus Torvalds 
26651da177e4SLinus Torvalds       }
26661da177e4SLinus Torvalds 
26671da177e4SLinus Torvalds 		else if(currSCCB->Sccb_scsistat == ABORT_ST)
26681da177e4SLinus Torvalds 		{
26691da177e4SLinus Torvalds 			WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
26701da177e4SLinus Torvalds 								(currSCCB->Sccb_idmsg & ~DISC_PRIV)));
26711da177e4SLinus Torvalds 
26721da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
26731da177e4SLinus Torvalds 
26741da177e4SLinus Torvalds 			WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
26751da177e4SLinus Torvalds 								(((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
26761da177e4SLinus Torvalds 								>> 6) | (UCHAR)0x20)));
26771da177e4SLinus Torvalds 			WRW_HARPOON((port+SYNC_MSGS+2),
26781da177e4SLinus Torvalds 							(MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
26791da177e4SLinus Torvalds 			WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
26801da177e4SLinus Torvalds 
26811da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
268247b5d69cSJames Bottomley  			auto_loaded = 1;
26831da177e4SLinus Torvalds 
26841da177e4SLinus Torvalds 		}
26851da177e4SLinus Torvalds 
26861da177e4SLinus Torvalds    else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED))  {
268747b5d69cSJames Bottomley        auto_loaded = FPT_siwidn(port,p_card);
26881da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = SELECT_WN_ST;
26891da177e4SLinus Torvalds       }
26901da177e4SLinus Torvalds 
26911da177e4SLinus Torvalds    else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
26921da177e4SLinus Torvalds       == SYNC_SUPPORTED))  {
269347b5d69cSJames Bottomley        auto_loaded = FPT_sisyncn(port,p_card, 0);
26941da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = SELECT_SN_ST;
26951da177e4SLinus Torvalds       }
26961da177e4SLinus Torvalds 
26971da177e4SLinus Torvalds 
26981da177e4SLinus Torvalds    if (!auto_loaded)
26991da177e4SLinus Torvalds       {
27001da177e4SLinus Torvalds 
27011da177e4SLinus Torvalds       if (currSCCB->ControlByte & F_USE_CMD_Q)
27021da177e4SLinus Torvalds          {
27031da177e4SLinus Torvalds 
27041da177e4SLinus Torvalds          CurrCard->globalFlags |= F_TAG_STARTED;
27051da177e4SLinus Torvalds 
27061da177e4SLinus Torvalds          if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
27071da177e4SLinus Torvalds             == TAG_Q_REJECT)
27081da177e4SLinus Torvalds             {
27091da177e4SLinus Torvalds             currSCCB->ControlByte &= ~F_USE_CMD_Q;
27101da177e4SLinus Torvalds 
27111da177e4SLinus Torvalds             /* Fix up the start instruction with a jump to
27121da177e4SLinus Torvalds                Non-Tag-CMD handling */
27131da177e4SLinus Torvalds             WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
27141da177e4SLinus Torvalds 
27151da177e4SLinus Torvalds             WRW_HARPOON((port+NON_TAG_ID_MSG),
27161da177e4SLinus Torvalds 	                     (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
27171da177e4SLinus Torvalds 
27181da177e4SLinus Torvalds 	         WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
27191da177e4SLinus Torvalds 
27201da177e4SLinus Torvalds 	         /* Setup our STATE so we know what happend when
27211da177e4SLinus Torvalds                the wheels fall off. */
27221da177e4SLinus Torvalds             currSCCB->Sccb_scsistat = SELECT_ST;
27231da177e4SLinus Torvalds 
272447b5d69cSJames Bottomley  	         currTar_Info->TarLUNBusy[lun] = 1;
27251da177e4SLinus Torvalds             }
27261da177e4SLinus Torvalds 
27271da177e4SLinus Torvalds          else
27281da177e4SLinus Torvalds             {
27291da177e4SLinus Torvalds             WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
27301da177e4SLinus Torvalds 
27311da177e4SLinus Torvalds             WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
27321da177e4SLinus Torvalds                         (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
27331da177e4SLinus Torvalds                         >> 6) | (UCHAR)0x20)));
27341da177e4SLinus Torvalds 
27351da177e4SLinus Torvalds 				for (i = 1; i < QUEUE_DEPTH; i++)
27361da177e4SLinus Torvalds 				{
27371da177e4SLinus Torvalds 					if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
27381da177e4SLinus Torvalds 					if (CurrCard->discQ_Tbl[lastTag] == NULL)
27391da177e4SLinus Torvalds 					{
27401da177e4SLinus Torvalds 						WRW_HARPOON((port+ID_MSG_STRT+6),
27411da177e4SLinus Torvalds 							(MPM_OP+AMSG_OUT+lastTag));
27421da177e4SLinus Torvalds 						CurrCard->tagQ_Lst = lastTag;
27431da177e4SLinus Torvalds 						currSCCB->Sccb_tag = lastTag;
27441da177e4SLinus Torvalds 						CurrCard->discQ_Tbl[lastTag] = currSCCB;
27451da177e4SLinus Torvalds 						CurrCard->discQCount++;
27461da177e4SLinus Torvalds 						break;
27471da177e4SLinus Torvalds 					}
27481da177e4SLinus Torvalds 				}
27491da177e4SLinus Torvalds 
27501da177e4SLinus Torvalds 
27511da177e4SLinus Torvalds             if ( i == QUEUE_DEPTH )
27521da177e4SLinus Torvalds                {
275347b5d69cSJames Bottomley     	         currTar_Info->TarLUNBusy[lun] = 1;
275447b5d69cSJames Bottomley                 FPT_queueSelectFail(CurrCard,p_card);
27551da177e4SLinus Torvalds 				   SGRAM_ACCESS(port);
27561da177e4SLinus Torvalds    	         return;
27571da177e4SLinus Torvalds    	         }
27581da177e4SLinus Torvalds 
27591da177e4SLinus Torvalds             currSCCB->Sccb_scsistat = SELECT_Q_ST;
27601da177e4SLinus Torvalds 
27611da177e4SLinus Torvalds    	      WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
27621da177e4SLinus Torvalds             }
27631da177e4SLinus Torvalds          }
27641da177e4SLinus Torvalds 
27651da177e4SLinus Torvalds       else
27661da177e4SLinus Torvalds          {
27671da177e4SLinus Torvalds 
27681da177e4SLinus Torvalds          WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
27691da177e4SLinus Torvalds 
27701da177e4SLinus Torvalds       	WRW_HARPOON((port+NON_TAG_ID_MSG),
27711da177e4SLinus Torvalds             (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
27721da177e4SLinus Torvalds 
27731da177e4SLinus Torvalds          currSCCB->Sccb_scsistat = SELECT_ST;
27741da177e4SLinus Torvalds 
27751da177e4SLinus Torvalds          WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
27761da177e4SLinus Torvalds          }
27771da177e4SLinus Torvalds 
27781da177e4SLinus Torvalds 
27791da177e4SLinus Torvalds       theCCB = (UCHAR *)&currSCCB->Cdb[0];
27801da177e4SLinus Torvalds 
27811da177e4SLinus Torvalds       cdb_reg = port + CMD_STRT;
27821da177e4SLinus Torvalds 
27831da177e4SLinus Torvalds       for (i=0; i < currSCCB->CdbLength; i++)
27841da177e4SLinus Torvalds          {
27851da177e4SLinus Torvalds          WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
27861da177e4SLinus Torvalds          cdb_reg +=2;
27871da177e4SLinus Torvalds          theCCB++;
27881da177e4SLinus Torvalds          }
27891da177e4SLinus Torvalds 
27901da177e4SLinus Torvalds       if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
27911da177e4SLinus Torvalds          WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+    NP));
27921da177e4SLinus Torvalds 
27931da177e4SLinus Torvalds       }  /* auto_loaded */
27941da177e4SLinus Torvalds 
27951da177e4SLinus Torvalds    WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
27961da177e4SLinus Torvalds    WR_HARPOON(port+hp_xferstat, 0x00);
27971da177e4SLinus Torvalds 
27981da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
27991da177e4SLinus Torvalds 
28001da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
28011da177e4SLinus Torvalds 
28021da177e4SLinus Torvalds 
28031da177e4SLinus Torvalds    if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
28041da177e4SLinus Torvalds       {
28051da177e4SLinus Torvalds       WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
28061da177e4SLinus Torvalds       }
28071da177e4SLinus Torvalds    else
28081da177e4SLinus Torvalds       {
28091da177e4SLinus Torvalds 
28101da177e4SLinus Torvalds /*      auto_loaded =  (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
28111da177e4SLinus Torvalds       auto_loaded |= AUTO_IMMED; */
28121da177e4SLinus Torvalds       auto_loaded = AUTO_IMMED;
28131da177e4SLinus Torvalds 
28141da177e4SLinus Torvalds       DISABLE_AUTO(port);
28151da177e4SLinus Torvalds 
28161da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_3, auto_loaded);
28171da177e4SLinus Torvalds       }
28181da177e4SLinus Torvalds 
28191da177e4SLinus Torvalds    SGRAM_ACCESS(port);
28201da177e4SLinus Torvalds }
28211da177e4SLinus Torvalds 
28221da177e4SLinus Torvalds 
28231da177e4SLinus Torvalds /*---------------------------------------------------------------------
28241da177e4SLinus Torvalds  *
282547b5d69cSJames Bottomley   * Function: FPT_sres
28261da177e4SLinus Torvalds  *
28271da177e4SLinus Torvalds  * Description: Hookup the correct CCB and handle the incoming messages.
28281da177e4SLinus Torvalds  *
28291da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
28301da177e4SLinus Torvalds 
283147b5d69cSJames Bottomley  static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
28321da177e4SLinus Torvalds {
28331da177e4SLinus Torvalds 
28341da177e4SLinus Torvalds    UCHAR our_target, message, lun = 0, tag, msgRetryCount;
28351da177e4SLinus Torvalds 
28361da177e4SLinus Torvalds 
28371da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
28381da177e4SLinus Torvalds 	PSCCB currSCCB;
28391da177e4SLinus Torvalds 
28401da177e4SLinus Torvalds 
28411da177e4SLinus Torvalds 
28421da177e4SLinus Torvalds 
28431da177e4SLinus Torvalds 	if(pCurrCard->currentSCCB != NULL)
28441da177e4SLinus Torvalds 	{
284547b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
28461da177e4SLinus Torvalds 		DISABLE_AUTO(port);
28471da177e4SLinus Torvalds 
28481da177e4SLinus Torvalds 
28491da177e4SLinus Torvalds 		WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
28501da177e4SLinus Torvalds 
28511da177e4SLinus Torvalds 
28521da177e4SLinus Torvalds 		currSCCB = pCurrCard->currentSCCB;
28531da177e4SLinus Torvalds 		if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
28541da177e4SLinus Torvalds 		{
28551da177e4SLinus Torvalds 			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
28561da177e4SLinus Torvalds 			currSCCB->Sccb_scsistat = BUS_FREE_ST;
28571da177e4SLinus Torvalds 		}
28581da177e4SLinus Torvalds 		if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
28591da177e4SLinus Torvalds 		{
28601da177e4SLinus Torvalds 			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
28611da177e4SLinus Torvalds 			currSCCB->Sccb_scsistat = BUS_FREE_ST;
28621da177e4SLinus Torvalds 		}
28631da177e4SLinus Torvalds 		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
28641da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
28651da177e4SLinus Torvalds 		{
286647b5d69cSJames Bottomley        	currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
28671da177e4SLinus Torvalds 			if(currSCCB->Sccb_scsistat != ABORT_ST)
28681da177e4SLinus Torvalds 			{
28691da177e4SLinus Torvalds 				pCurrCard->discQCount--;
28701da177e4SLinus Torvalds 				pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
28711da177e4SLinus Torvalds 													= NULL;
28721da177e4SLinus Torvalds 			}
28731da177e4SLinus Torvalds 		}
28741da177e4SLinus Torvalds 		else
28751da177e4SLinus Torvalds 		{
287647b5d69cSJames Bottomley  	      currTar_Info->TarLUNBusy[0] = 0;
28771da177e4SLinus Torvalds 			if(currSCCB->Sccb_tag)
28781da177e4SLinus Torvalds 			{
28791da177e4SLinus Torvalds 				if(currSCCB->Sccb_scsistat != ABORT_ST)
28801da177e4SLinus Torvalds 				{
28811da177e4SLinus Torvalds 					pCurrCard->discQCount--;
28821da177e4SLinus Torvalds 					pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
28831da177e4SLinus Torvalds 				}
28841da177e4SLinus Torvalds 			}else
28851da177e4SLinus Torvalds 			{
28861da177e4SLinus Torvalds 				if(currSCCB->Sccb_scsistat != ABORT_ST)
28871da177e4SLinus Torvalds 				{
28881da177e4SLinus Torvalds 					pCurrCard->discQCount--;
28891da177e4SLinus Torvalds 					pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
28901da177e4SLinus Torvalds 				}
28911da177e4SLinus Torvalds 			}
28921da177e4SLinus Torvalds 		}
28931da177e4SLinus Torvalds 
289447b5d69cSJames Bottomley        FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
28951da177e4SLinus Torvalds 	}
28961da177e4SLinus Torvalds 
28971da177e4SLinus Torvalds 	WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
28981da177e4SLinus Torvalds 
28991da177e4SLinus Torvalds 
29001da177e4SLinus Torvalds 	our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
290147b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
29021da177e4SLinus Torvalds 
29031da177e4SLinus Torvalds 
29041da177e4SLinus Torvalds 	msgRetryCount = 0;
29051da177e4SLinus Torvalds 	do
29061da177e4SLinus Torvalds 	{
29071da177e4SLinus Torvalds 
290847b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
29091da177e4SLinus Torvalds 		tag = 0;
29101da177e4SLinus Torvalds 
29111da177e4SLinus Torvalds 
29121da177e4SLinus Torvalds 		while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
29131da177e4SLinus Torvalds 		{
29141da177e4SLinus Torvalds 			if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
29151da177e4SLinus Torvalds 			{
29161da177e4SLinus Torvalds 
29171da177e4SLinus Torvalds 				WRW_HARPOON((port+hp_intstat), PHASE);
29181da177e4SLinus Torvalds 				return;
29191da177e4SLinus Torvalds 			}
29201da177e4SLinus Torvalds 		}
29211da177e4SLinus Torvalds 
29221da177e4SLinus Torvalds 		WRW_HARPOON((port+hp_intstat), PHASE);
29231da177e4SLinus Torvalds 		if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
29241da177e4SLinus Torvalds 		{
29251da177e4SLinus Torvalds 
292647b5d69cSJames Bottomley  			message = FPT_sfm(port,pCurrCard->currentSCCB);
29271da177e4SLinus Torvalds 			if (message)
29281da177e4SLinus Torvalds 			{
29291da177e4SLinus Torvalds 
29301da177e4SLinus Torvalds 				if (message <= (0x80 | LUN_MASK))
29311da177e4SLinus Torvalds 				{
29321da177e4SLinus Torvalds 					lun = message & (UCHAR)LUN_MASK;
29331da177e4SLinus Torvalds 
29341da177e4SLinus Torvalds 					if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
29351da177e4SLinus Torvalds 					{
29361da177e4SLinus Torvalds 						if (currTar_Info->TarTagQ_Cnt != 0)
29371da177e4SLinus Torvalds 						{
29381da177e4SLinus Torvalds 
29391da177e4SLinus Torvalds 							if (!(currTar_Info->TarLUN_CA))
29401da177e4SLinus Torvalds 							{
29411da177e4SLinus Torvalds 								ACCEPT_MSG(port);    /*Release the ACK for ID msg. */
29421da177e4SLinus Torvalds 
29431da177e4SLinus Torvalds 
294447b5d69cSJames Bottomley  								message = FPT_sfm(port,pCurrCard->currentSCCB);
29451da177e4SLinus Torvalds 								if (message)
29461da177e4SLinus Torvalds 								{
29471da177e4SLinus Torvalds 									ACCEPT_MSG(port);
29481da177e4SLinus Torvalds 								}
29491da177e4SLinus Torvalds 
29501da177e4SLinus Torvalds 								else
295147b5d69cSJames Bottomley     								message = 0;
29521da177e4SLinus Torvalds 
295347b5d69cSJames Bottomley  								if(message != 0)
29541da177e4SLinus Torvalds 								{
295547b5d69cSJames Bottomley  									tag = FPT_sfm(port,pCurrCard->currentSCCB);
29561da177e4SLinus Torvalds 
29571da177e4SLinus Torvalds 									if (!(tag))
295847b5d69cSJames Bottomley  										message = 0;
29591da177e4SLinus Torvalds 								}
29601da177e4SLinus Torvalds 
29611da177e4SLinus Torvalds 							} /*C.A. exists! */
29621da177e4SLinus Torvalds 
29631da177e4SLinus Torvalds 						} /*End Q cnt != 0 */
29641da177e4SLinus Torvalds 
29651da177e4SLinus Torvalds 					} /*End Tag cmds supported! */
29661da177e4SLinus Torvalds 
29671da177e4SLinus Torvalds 				} /*End valid ID message.  */
29681da177e4SLinus Torvalds 
29691da177e4SLinus Torvalds 				else
29701da177e4SLinus Torvalds 				{
29711da177e4SLinus Torvalds 
29721da177e4SLinus Torvalds 					ACCEPT_MSG_ATN(port);
29731da177e4SLinus Torvalds 				}
29741da177e4SLinus Torvalds 
29751da177e4SLinus Torvalds 			} /* End good id message. */
29761da177e4SLinus Torvalds 
29771da177e4SLinus Torvalds 			else
29781da177e4SLinus Torvalds 			{
29791da177e4SLinus Torvalds 
298047b5d69cSJames Bottomley  				message = 0;
29811da177e4SLinus Torvalds 			}
29821da177e4SLinus Torvalds 		}
29831da177e4SLinus Torvalds 		else
29841da177e4SLinus Torvalds 		{
29851da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
29861da177e4SLinus Torvalds 
29871da177e4SLinus Torvalds 		   while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
29881da177e4SLinus Torvalds 			  !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
29891da177e4SLinus Torvalds 			  (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
29901da177e4SLinus Torvalds 
29911da177e4SLinus Torvalds 			return;
29921da177e4SLinus Torvalds 		}
29931da177e4SLinus Torvalds 
299447b5d69cSJames Bottomley  		if(message == 0)
29951da177e4SLinus Torvalds 		{
29961da177e4SLinus Torvalds 			msgRetryCount++;
29971da177e4SLinus Torvalds 			if(msgRetryCount == 1)
29981da177e4SLinus Torvalds 			{
299947b5d69cSJames Bottomley  				FPT_SendMsg(port, SMPARITY);
30001da177e4SLinus Torvalds 			}
30011da177e4SLinus Torvalds 			else
30021da177e4SLinus Torvalds 			{
300347b5d69cSJames Bottomley  				FPT_SendMsg(port, SMDEV_RESET);
30041da177e4SLinus Torvalds 
300547b5d69cSJames Bottomley  				FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
30061da177e4SLinus Torvalds 
300747b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
30081da177e4SLinus Torvalds 				{
30091da177e4SLinus Torvalds 
301047b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
30111da177e4SLinus Torvalds 
30121da177e4SLinus Torvalds 				}
30131da177e4SLinus Torvalds 
301447b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
30151da177e4SLinus Torvalds 				{
30161da177e4SLinus Torvalds 
301747b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
30181da177e4SLinus Torvalds 				}
30191da177e4SLinus Torvalds 
30201da177e4SLinus Torvalds 
302147b5d69cSJames Bottomley  				FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
302247b5d69cSJames Bottomley  				FPT_SccbMgrTableInitTarget(p_card,our_target);
30231da177e4SLinus Torvalds 				return;
30241da177e4SLinus Torvalds 			}
30251da177e4SLinus Torvalds 		}
302647b5d69cSJames Bottomley  	}while(message == 0);
30271da177e4SLinus Torvalds 
30281da177e4SLinus Torvalds 
30291da177e4SLinus Torvalds 
30301da177e4SLinus Torvalds 	if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
30311da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
30321da177e4SLinus Torvalds 	{
303347b5d69cSJames Bottomley  		currTar_Info->TarLUNBusy[lun] = 1;
30341da177e4SLinus Torvalds 		pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
30351da177e4SLinus Torvalds 		if(pCurrCard->currentSCCB != NULL)
30361da177e4SLinus Torvalds 		{
30371da177e4SLinus Torvalds 			ACCEPT_MSG(port);
30381da177e4SLinus Torvalds 		}
30391da177e4SLinus Torvalds 		else
30401da177e4SLinus Torvalds 		{
30411da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
30421da177e4SLinus Torvalds 		}
30431da177e4SLinus Torvalds 	}
30441da177e4SLinus Torvalds 	else
30451da177e4SLinus Torvalds 	{
304647b5d69cSJames Bottomley  		currTar_Info->TarLUNBusy[0] = 1;
30471da177e4SLinus Torvalds 
30481da177e4SLinus Torvalds 
30491da177e4SLinus Torvalds 		if (tag)
30501da177e4SLinus Torvalds 		{
30511da177e4SLinus Torvalds 			if (pCurrCard->discQ_Tbl[tag] != NULL)
30521da177e4SLinus Torvalds 			{
30531da177e4SLinus Torvalds 				pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
30541da177e4SLinus Torvalds 		 		currTar_Info->TarTagQ_Cnt--;
30551da177e4SLinus Torvalds 				ACCEPT_MSG(port);
30561da177e4SLinus Torvalds 			}
30571da177e4SLinus Torvalds 			else
30581da177e4SLinus Torvalds 			{
30591da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
30601da177e4SLinus Torvalds 			}
30611da177e4SLinus Torvalds 		}else
30621da177e4SLinus Torvalds 		{
30631da177e4SLinus Torvalds 			pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
30641da177e4SLinus Torvalds 			if(pCurrCard->currentSCCB != NULL)
30651da177e4SLinus Torvalds 			{
30661da177e4SLinus Torvalds 				ACCEPT_MSG(port);
30671da177e4SLinus Torvalds 			}
30681da177e4SLinus Torvalds 			else
30691da177e4SLinus Torvalds 			{
30701da177e4SLinus Torvalds 				ACCEPT_MSG_ATN(port);
30711da177e4SLinus Torvalds 			}
30721da177e4SLinus Torvalds 		}
30731da177e4SLinus Torvalds 	}
30741da177e4SLinus Torvalds 
30751da177e4SLinus Torvalds 	if(pCurrCard->currentSCCB != NULL)
30761da177e4SLinus Torvalds 	{
30771da177e4SLinus Torvalds 		if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
30781da177e4SLinus Torvalds 		{
30791da177e4SLinus Torvalds 		/* During Abort Tag command, the target could have got re-selected
30801da177e4SLinus Torvalds 			and completed the command. Check the select Q and remove the CCB
30811da177e4SLinus Torvalds 			if it is in the Select Q */
308247b5d69cSJames Bottomley  			FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
30831da177e4SLinus Torvalds 		}
30841da177e4SLinus Torvalds 	}
30851da177e4SLinus Torvalds 
30861da177e4SLinus Torvalds 
30871da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
30881da177e4SLinus Torvalds 	  !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
30891da177e4SLinus Torvalds 	  (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
30901da177e4SLinus Torvalds }
30911da177e4SLinus Torvalds 
309247b5d69cSJames Bottomley  static void FPT_SendMsg(ULONG port, UCHAR message)
30931da177e4SLinus Torvalds {
30941da177e4SLinus Torvalds 	while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
30951da177e4SLinus Torvalds 	{
30961da177e4SLinus Torvalds 		if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
30971da177e4SLinus Torvalds 		{
30981da177e4SLinus Torvalds 
30991da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), PHASE);
31001da177e4SLinus Torvalds 			return;
31011da177e4SLinus Torvalds 		}
31021da177e4SLinus Torvalds 	}
31031da177e4SLinus Torvalds 
31041da177e4SLinus Torvalds 	WRW_HARPOON((port+hp_intstat), PHASE);
31051da177e4SLinus Torvalds 	if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
31061da177e4SLinus Torvalds 	{
31071da177e4SLinus Torvalds 		WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
31081da177e4SLinus Torvalds 
31091da177e4SLinus Torvalds 
31101da177e4SLinus Torvalds 		WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
31111da177e4SLinus Torvalds 
31121da177e4SLinus Torvalds 		WR_HARPOON(port+hp_scsidata_0,message);
31131da177e4SLinus Torvalds 
31141da177e4SLinus Torvalds 		WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
31151da177e4SLinus Torvalds 
31161da177e4SLinus Torvalds 		ACCEPT_MSG(port);
31171da177e4SLinus Torvalds 
31181da177e4SLinus Torvalds 		WR_HARPOON(port+hp_portctrl_0, 0x00);
31191da177e4SLinus Torvalds 
31201da177e4SLinus Torvalds 		if ((message == SMABORT) || (message == SMDEV_RESET) ||
31211da177e4SLinus Torvalds 				(message == SMABORT_TAG) )
31221da177e4SLinus Torvalds 		{
31231da177e4SLinus Torvalds 			while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
31241da177e4SLinus Torvalds 
31251da177e4SLinus Torvalds 			if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
31261da177e4SLinus Torvalds 			{
31271da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), BUS_FREE);
31281da177e4SLinus Torvalds 			}
31291da177e4SLinus Torvalds 		}
31301da177e4SLinus Torvalds 	}
31311da177e4SLinus Torvalds }
31321da177e4SLinus Torvalds 
31331da177e4SLinus Torvalds /*---------------------------------------------------------------------
31341da177e4SLinus Torvalds  *
313547b5d69cSJames Bottomley   * Function: FPT_sdecm
31361da177e4SLinus Torvalds  *
31371da177e4SLinus Torvalds  * Description: Determine the proper responce to the message from the
31381da177e4SLinus Torvalds  *              target device.
31391da177e4SLinus Torvalds  *
31401da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
314147b5d69cSJames Bottomley  static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
31421da177e4SLinus Torvalds {
31431da177e4SLinus Torvalds 	PSCCB currSCCB;
31441da177e4SLinus Torvalds 	PSCCBcard CurrCard;
31451da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
31461da177e4SLinus Torvalds 
314747b5d69cSJames Bottomley  	CurrCard = &FPT_BL_Card[p_card];
31481da177e4SLinus Torvalds 	currSCCB = CurrCard->currentSCCB;
31491da177e4SLinus Torvalds 
315047b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
31511da177e4SLinus Torvalds 
31521da177e4SLinus Torvalds 	if (message == SMREST_DATA_PTR)
31531da177e4SLinus Torvalds 	{
31541da177e4SLinus Torvalds 		if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
31551da177e4SLinus Torvalds 		{
31561da177e4SLinus Torvalds 			currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
31571da177e4SLinus Torvalds 
315847b5d69cSJames Bottomley  			FPT_hostDataXferRestart(currSCCB);
31591da177e4SLinus Torvalds 		}
31601da177e4SLinus Torvalds 
31611da177e4SLinus Torvalds 		ACCEPT_MSG(port);
31621da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
31631da177e4SLinus Torvalds 	}
31641da177e4SLinus Torvalds 
31651da177e4SLinus Torvalds 	else if (message == SMCMD_COMP)
31661da177e4SLinus Torvalds 	{
31671da177e4SLinus Torvalds 
31681da177e4SLinus Torvalds 
31691da177e4SLinus Torvalds 		if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
31701da177e4SLinus Torvalds 		{
31711da177e4SLinus Torvalds 			currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
31721da177e4SLinus Torvalds 			currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
31731da177e4SLinus Torvalds 		}
31741da177e4SLinus Torvalds 
31751da177e4SLinus Torvalds 		ACCEPT_MSG(port);
31761da177e4SLinus Torvalds 
31771da177e4SLinus Torvalds 	}
31781da177e4SLinus Torvalds 
31791da177e4SLinus Torvalds 	else if ((message == SMNO_OP) || (message >= SMIDENT)
31801da177e4SLinus Torvalds 			|| (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
31811da177e4SLinus Torvalds 	{
31821da177e4SLinus Torvalds 
31831da177e4SLinus Torvalds 		ACCEPT_MSG(port);
31841da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
31851da177e4SLinus Torvalds 	}
31861da177e4SLinus Torvalds 
31871da177e4SLinus Torvalds 	else if (message == SMREJECT)
31881da177e4SLinus Torvalds 	{
31891da177e4SLinus Torvalds 
31901da177e4SLinus Torvalds 		if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
31911da177e4SLinus Torvalds 				(currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
31921da177e4SLinus Torvalds 				((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
31931da177e4SLinus Torvalds 				((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
31941da177e4SLinus Torvalds 
31951da177e4SLinus Torvalds 		{
31961da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), BUS_FREE);
31971da177e4SLinus Torvalds 
31981da177e4SLinus Torvalds 			ACCEPT_MSG(port);
31991da177e4SLinus Torvalds 
32001da177e4SLinus Torvalds 
32011da177e4SLinus Torvalds 			while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
32021da177e4SLinus Torvalds 				(!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
32031da177e4SLinus Torvalds 
32041da177e4SLinus Torvalds 			if(currSCCB->Lun == 0x00)
32051da177e4SLinus Torvalds 			{
32061da177e4SLinus Torvalds 				if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
32071da177e4SLinus Torvalds 				{
32081da177e4SLinus Torvalds 
32091da177e4SLinus Torvalds 					currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
32101da177e4SLinus Torvalds 
32111da177e4SLinus Torvalds 					currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
32121da177e4SLinus Torvalds 				}
32131da177e4SLinus Torvalds 
32141da177e4SLinus Torvalds 				else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
32151da177e4SLinus Torvalds 				{
32161da177e4SLinus Torvalds 
32171da177e4SLinus Torvalds 
32181da177e4SLinus Torvalds 					currTar_Info->TarStatus = (currTar_Info->TarStatus &
32191da177e4SLinus Torvalds 													~WIDE_ENABLED) | WIDE_NEGOCIATED;
32201da177e4SLinus Torvalds 
32211da177e4SLinus Torvalds 					currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
32221da177e4SLinus Torvalds 
32231da177e4SLinus Torvalds 				}
32241da177e4SLinus Torvalds 
32251da177e4SLinus Torvalds 				else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
32261da177e4SLinus Torvalds 				{
32271da177e4SLinus Torvalds 					currTar_Info->TarStatus = (currTar_Info->TarStatus &
32281da177e4SLinus Torvalds 													~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
32291da177e4SLinus Torvalds 
32301da177e4SLinus Torvalds 
32311da177e4SLinus Torvalds 					currSCCB->ControlByte &= ~F_USE_CMD_Q;
32321da177e4SLinus Torvalds 					CurrCard->discQCount--;
32331da177e4SLinus Torvalds 					CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
32341da177e4SLinus Torvalds 					currSCCB->Sccb_tag = 0x00;
32351da177e4SLinus Torvalds 
32361da177e4SLinus Torvalds 				}
32371da177e4SLinus Torvalds 			}
32381da177e4SLinus Torvalds 
32391da177e4SLinus Torvalds 			if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
32401da177e4SLinus Torvalds 			{
32411da177e4SLinus Torvalds 
32421da177e4SLinus Torvalds 
32431da177e4SLinus Torvalds 				if(currSCCB->Lun == 0x00)
32441da177e4SLinus Torvalds 				{
32451da177e4SLinus Torvalds 					WRW_HARPOON((port+hp_intstat), BUS_FREE);
32461da177e4SLinus Torvalds 					CurrCard->globalFlags |= F_NEW_SCCB_CMD;
32471da177e4SLinus Torvalds 				}
32481da177e4SLinus Torvalds 			}
32491da177e4SLinus Torvalds 
32501da177e4SLinus Torvalds 			else
32511da177e4SLinus Torvalds 			{
32521da177e4SLinus Torvalds 
32531da177e4SLinus Torvalds 				if((CurrCard->globalFlags & F_CONLUN_IO) &&
32541da177e4SLinus Torvalds 					((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
325547b5d69cSJames Bottomley  					currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
32561da177e4SLinus Torvalds 				else
325747b5d69cSJames Bottomley  					currTar_Info->TarLUNBusy[0] = 1;
32581da177e4SLinus Torvalds 
32591da177e4SLinus Torvalds 
32601da177e4SLinus Torvalds 				currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
32611da177e4SLinus Torvalds 
32621da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
32631da177e4SLinus Torvalds 
32641da177e4SLinus Torvalds 			}
32651da177e4SLinus Torvalds 		}
32661da177e4SLinus Torvalds 
32671da177e4SLinus Torvalds 		else
32681da177e4SLinus Torvalds 		{
32691da177e4SLinus Torvalds 			ACCEPT_MSG(port);
32701da177e4SLinus Torvalds 
32711da177e4SLinus Torvalds 			while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
32721da177e4SLinus Torvalds 				(!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
32731da177e4SLinus Torvalds 
32741da177e4SLinus Torvalds 			if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
32751da177e4SLinus Torvalds 			{
32761da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
32771da177e4SLinus Torvalds 			}
32781da177e4SLinus Torvalds 		}
32791da177e4SLinus Torvalds 	}
32801da177e4SLinus Torvalds 
32811da177e4SLinus Torvalds 	else if (message == SMEXT)
32821da177e4SLinus Torvalds 	{
32831da177e4SLinus Torvalds 
32841da177e4SLinus Torvalds 		ACCEPT_MSG(port);
328547b5d69cSJames Bottomley  		FPT_shandem(port,p_card,currSCCB);
32861da177e4SLinus Torvalds 	}
32871da177e4SLinus Torvalds 
32881da177e4SLinus Torvalds 	else if (message == SMIGNORWR)
32891da177e4SLinus Torvalds 	{
32901da177e4SLinus Torvalds 
32911da177e4SLinus Torvalds 		ACCEPT_MSG(port);          /* ACK the RESIDUE MSG */
32921da177e4SLinus Torvalds 
329347b5d69cSJames Bottomley  		message = FPT_sfm(port,currSCCB);
32941da177e4SLinus Torvalds 
32951da177e4SLinus Torvalds 		if(currSCCB->Sccb_scsimsg != SMPARITY)
32961da177e4SLinus Torvalds 			ACCEPT_MSG(port);
32971da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
32981da177e4SLinus Torvalds 	}
32991da177e4SLinus Torvalds 
33001da177e4SLinus Torvalds 
33011da177e4SLinus Torvalds 	else
33021da177e4SLinus Torvalds 	{
33031da177e4SLinus Torvalds 
33041da177e4SLinus Torvalds 		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
33051da177e4SLinus Torvalds 		currSCCB->Sccb_scsimsg = SMREJECT;
33061da177e4SLinus Torvalds 
33071da177e4SLinus Torvalds 		ACCEPT_MSG_ATN(port);
33081da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
33091da177e4SLinus Torvalds 	}
33101da177e4SLinus Torvalds }
33111da177e4SLinus Torvalds 
33121da177e4SLinus Torvalds 
33131da177e4SLinus Torvalds /*---------------------------------------------------------------------
33141da177e4SLinus Torvalds  *
331547b5d69cSJames Bottomley   * Function: FPT_shandem
33161da177e4SLinus Torvalds  *
33171da177e4SLinus Torvalds  * Description: Decide what to do with the extended message.
33181da177e4SLinus Torvalds  *
33191da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
332047b5d69cSJames Bottomley  static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
33211da177e4SLinus Torvalds {
33221da177e4SLinus Torvalds 	UCHAR length,message;
33231da177e4SLinus Torvalds 
332447b5d69cSJames Bottomley  	length = FPT_sfm(port,pCurrSCCB);
33251da177e4SLinus Torvalds 	if (length)
33261da177e4SLinus Torvalds 	{
33271da177e4SLinus Torvalds 
33281da177e4SLinus Torvalds 		ACCEPT_MSG(port);
332947b5d69cSJames Bottomley  		message = FPT_sfm(port,pCurrSCCB);
33301da177e4SLinus Torvalds 		if (message)
33311da177e4SLinus Torvalds 		{
33321da177e4SLinus Torvalds 
33331da177e4SLinus Torvalds 			if (message == SMSYNC)
33341da177e4SLinus Torvalds 			{
33351da177e4SLinus Torvalds 
33361da177e4SLinus Torvalds 				if (length == 0x03)
33371da177e4SLinus Torvalds 				{
33381da177e4SLinus Torvalds 
33391da177e4SLinus Torvalds 					ACCEPT_MSG(port);
334047b5d69cSJames Bottomley  					FPT_stsyncn(port,p_card);
33411da177e4SLinus Torvalds 				}
33421da177e4SLinus Torvalds 				else
33431da177e4SLinus Torvalds 				{
33441da177e4SLinus Torvalds 
33451da177e4SLinus Torvalds 					pCurrSCCB->Sccb_scsimsg = SMREJECT;
33461da177e4SLinus Torvalds 					ACCEPT_MSG_ATN(port);
33471da177e4SLinus Torvalds 				}
33481da177e4SLinus Torvalds 			}
33491da177e4SLinus Torvalds 			else if (message == SMWDTR)
33501da177e4SLinus Torvalds 			{
33511da177e4SLinus Torvalds 
33521da177e4SLinus Torvalds 				if (length == 0x02)
33531da177e4SLinus Torvalds 				{
33541da177e4SLinus Torvalds 
33551da177e4SLinus Torvalds 					ACCEPT_MSG(port);
335647b5d69cSJames Bottomley  					FPT_stwidn(port,p_card);
33571da177e4SLinus Torvalds 				}
33581da177e4SLinus Torvalds 				else
33591da177e4SLinus Torvalds 				{
33601da177e4SLinus Torvalds 
33611da177e4SLinus Torvalds 					pCurrSCCB->Sccb_scsimsg = SMREJECT;
33621da177e4SLinus Torvalds 					ACCEPT_MSG_ATN(port);
33631da177e4SLinus Torvalds 
33641da177e4SLinus Torvalds 					WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
33651da177e4SLinus Torvalds 				}
33661da177e4SLinus Torvalds 			}
33671da177e4SLinus Torvalds 			else
33681da177e4SLinus Torvalds 			{
33691da177e4SLinus Torvalds 
33701da177e4SLinus Torvalds 				pCurrSCCB->Sccb_scsimsg = SMREJECT;
33711da177e4SLinus Torvalds 				ACCEPT_MSG_ATN(port);
33721da177e4SLinus Torvalds 
33731da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
33741da177e4SLinus Torvalds 			}
33751da177e4SLinus Torvalds 		}
33761da177e4SLinus Torvalds 		else
33771da177e4SLinus Torvalds 		{
33781da177e4SLinus Torvalds 			if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
33791da177e4SLinus Torvalds 				ACCEPT_MSG(port);
33801da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
33811da177e4SLinus Torvalds 		}
33821da177e4SLinus Torvalds 	}else
33831da177e4SLinus Torvalds 	{
33841da177e4SLinus Torvalds 			if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
33851da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
33861da177e4SLinus Torvalds 	}
33871da177e4SLinus Torvalds }
33881da177e4SLinus Torvalds 
33891da177e4SLinus Torvalds 
33901da177e4SLinus Torvalds /*---------------------------------------------------------------------
33911da177e4SLinus Torvalds  *
339247b5d69cSJames Bottomley   * Function: FPT_sisyncn
33931da177e4SLinus Torvalds  *
33941da177e4SLinus Torvalds  * Description: Read in a message byte from the SCSI bus, and check
33951da177e4SLinus Torvalds  *              for a parity error.
33961da177e4SLinus Torvalds  *
33971da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
33981da177e4SLinus Torvalds 
339947b5d69cSJames Bottomley  static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
34001da177e4SLinus Torvalds {
34011da177e4SLinus Torvalds    PSCCB currSCCB;
34021da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
34031da177e4SLinus Torvalds 
340447b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
340547b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
34061da177e4SLinus Torvalds 
34071da177e4SLinus Torvalds    if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
34081da177e4SLinus Torvalds 
34091da177e4SLinus Torvalds 
34101da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT),
34111da177e4SLinus Torvalds                  (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
34121da177e4SLinus Torvalds 
34131da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
34141da177e4SLinus Torvalds 
34151da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
34161da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03  ));
34171da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
34181da177e4SLinus Torvalds 
34191da177e4SLinus Torvalds 
34201da177e4SLinus Torvalds       if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
34211da177e4SLinus Torvalds 
34221da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
34231da177e4SLinus Torvalds 
34241da177e4SLinus Torvalds       else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
34251da177e4SLinus Torvalds 
34261da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
34271da177e4SLinus Torvalds 
34281da177e4SLinus Torvalds       else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
34291da177e4SLinus Torvalds 
34301da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
34311da177e4SLinus Torvalds 
34321da177e4SLinus Torvalds       else
34331da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
34341da177e4SLinus Torvalds 
34351da177e4SLinus Torvalds 
34361da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP                ));
34371da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
34381da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
34391da177e4SLinus Torvalds 
34401da177e4SLinus Torvalds 
344147b5d69cSJames Bottomley  		if(syncFlag == 0)
34421da177e4SLinus Torvalds 		{
34431da177e4SLinus Torvalds 		   WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
34441da177e4SLinus Torvalds 	      currTar_Info->TarStatus = ((currTar_Info->TarStatus &
34451da177e4SLinus Torvalds    	      ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
34461da177e4SLinus Torvalds 		}
34471da177e4SLinus Torvalds 		else
34481da177e4SLinus Torvalds 		{
34491da177e4SLinus Torvalds 		   WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
34501da177e4SLinus Torvalds 		}
34511da177e4SLinus Torvalds 
34521da177e4SLinus Torvalds 
345347b5d69cSJames Bottomley        return(1);
34541da177e4SLinus Torvalds       }
34551da177e4SLinus Torvalds 
34561da177e4SLinus Torvalds    else {
34571da177e4SLinus Torvalds 
34581da177e4SLinus Torvalds       currTar_Info->TarStatus |=	 (UCHAR)SYNC_SUPPORTED;
34591da177e4SLinus Torvalds       currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
346047b5d69cSJames Bottomley        return(0);
34611da177e4SLinus Torvalds       }
34621da177e4SLinus Torvalds }
34631da177e4SLinus Torvalds 
34641da177e4SLinus Torvalds 
34651da177e4SLinus Torvalds 
34661da177e4SLinus Torvalds /*---------------------------------------------------------------------
34671da177e4SLinus Torvalds  *
346847b5d69cSJames Bottomley   * Function: FPT_stsyncn
34691da177e4SLinus Torvalds  *
34701da177e4SLinus Torvalds  * Description: The has sent us a Sync Nego message so handle it as
34711da177e4SLinus Torvalds  *              necessary.
34721da177e4SLinus Torvalds  *
34731da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
347447b5d69cSJames Bottomley  static void FPT_stsyncn(ULONG port, UCHAR p_card)
34751da177e4SLinus Torvalds {
34761da177e4SLinus Torvalds    UCHAR sync_msg,offset,sync_reg,our_sync_msg;
34771da177e4SLinus Torvalds    PSCCB currSCCB;
34781da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
34791da177e4SLinus Torvalds 
348047b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
348147b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
34821da177e4SLinus Torvalds 
348347b5d69cSJames Bottomley     sync_msg = FPT_sfm(port,currSCCB);
34841da177e4SLinus Torvalds 
34851da177e4SLinus Torvalds 	if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
34861da177e4SLinus Torvalds 	{
34871da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
34881da177e4SLinus Torvalds 		return;
34891da177e4SLinus Torvalds 	}
34901da177e4SLinus Torvalds 
34911da177e4SLinus Torvalds    ACCEPT_MSG(port);
34921da177e4SLinus Torvalds 
34931da177e4SLinus Torvalds 
349447b5d69cSJames Bottomley     offset = FPT_sfm(port,currSCCB);
34951da177e4SLinus Torvalds 
34961da177e4SLinus Torvalds 	if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
34971da177e4SLinus Torvalds 	{
34981da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
34991da177e4SLinus Torvalds 		return;
35001da177e4SLinus Torvalds 	}
35011da177e4SLinus Torvalds 
35021da177e4SLinus Torvalds    if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
35031da177e4SLinus Torvalds 
35041da177e4SLinus Torvalds       our_sync_msg = 12;              /* Setup our Message to 20mb/s */
35051da177e4SLinus Torvalds 
35061da177e4SLinus Torvalds    else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
35071da177e4SLinus Torvalds 
35081da177e4SLinus Torvalds       our_sync_msg = 25;              /* Setup our Message to 10mb/s */
35091da177e4SLinus Torvalds 
35101da177e4SLinus Torvalds    else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
35111da177e4SLinus Torvalds 
35121da177e4SLinus Torvalds       our_sync_msg = 50;              /* Setup our Message to 5mb/s */
35131da177e4SLinus Torvalds    else
35141da177e4SLinus Torvalds 
35151da177e4SLinus Torvalds       our_sync_msg = 0;               /* Message = Async */
35161da177e4SLinus Torvalds 
35171da177e4SLinus Torvalds    if (sync_msg < our_sync_msg) {
35181da177e4SLinus Torvalds       sync_msg = our_sync_msg;    /*if faster, then set to max. */
35191da177e4SLinus Torvalds       }
35201da177e4SLinus Torvalds 
35211da177e4SLinus Torvalds    if (offset == ASYNC)
35221da177e4SLinus Torvalds       sync_msg = ASYNC;
35231da177e4SLinus Torvalds 
35241da177e4SLinus Torvalds    if (offset > MAX_OFFSET)
35251da177e4SLinus Torvalds       offset = MAX_OFFSET;
35261da177e4SLinus Torvalds 
35271da177e4SLinus Torvalds    sync_reg = 0x00;
35281da177e4SLinus Torvalds 
35291da177e4SLinus Torvalds    if (sync_msg > 12)
35301da177e4SLinus Torvalds 
35311da177e4SLinus Torvalds       sync_reg = 0x20;        /* Use 10MB/s */
35321da177e4SLinus Torvalds 
35331da177e4SLinus Torvalds    if (sync_msg > 25)
35341da177e4SLinus Torvalds 
35351da177e4SLinus Torvalds       sync_reg = 0x40;        /* Use 6.6MB/s */
35361da177e4SLinus Torvalds 
35371da177e4SLinus Torvalds    if (sync_msg > 38)
35381da177e4SLinus Torvalds 
35391da177e4SLinus Torvalds       sync_reg = 0x60;        /* Use 5MB/s */
35401da177e4SLinus Torvalds 
35411da177e4SLinus Torvalds    if (sync_msg > 50)
35421da177e4SLinus Torvalds 
35431da177e4SLinus Torvalds       sync_reg = 0x80;        /* Use 4MB/s */
35441da177e4SLinus Torvalds 
35451da177e4SLinus Torvalds    if (sync_msg > 62)
35461da177e4SLinus Torvalds 
35471da177e4SLinus Torvalds       sync_reg = 0xA0;        /* Use 3.33MB/s */
35481da177e4SLinus Torvalds 
35491da177e4SLinus Torvalds    if (sync_msg > 75)
35501da177e4SLinus Torvalds 
35511da177e4SLinus Torvalds       sync_reg = 0xC0;        /* Use 2.85MB/s */
35521da177e4SLinus Torvalds 
35531da177e4SLinus Torvalds    if (sync_msg > 87)
35541da177e4SLinus Torvalds 
35551da177e4SLinus Torvalds       sync_reg = 0xE0;        /* Use 2.5MB/s */
35561da177e4SLinus Torvalds 
35571da177e4SLinus Torvalds    if (sync_msg > 100) {
35581da177e4SLinus Torvalds 
35591da177e4SLinus Torvalds       sync_reg = 0x00;        /* Use ASYNC */
35601da177e4SLinus Torvalds       offset = 0x00;
35611da177e4SLinus Torvalds       }
35621da177e4SLinus Torvalds 
35631da177e4SLinus Torvalds 
35641da177e4SLinus Torvalds    if (currTar_Info->TarStatus & WIDE_ENABLED)
35651da177e4SLinus Torvalds 
35661da177e4SLinus Torvalds       sync_reg |= offset;
35671da177e4SLinus Torvalds 
35681da177e4SLinus Torvalds    else
35691da177e4SLinus Torvalds 
35701da177e4SLinus Torvalds       sync_reg |= (offset | NARROW_SCSI);
35711da177e4SLinus Torvalds 
357247b5d69cSJames Bottomley     FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
35731da177e4SLinus Torvalds 
35741da177e4SLinus Torvalds 
35751da177e4SLinus Torvalds    if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
35761da177e4SLinus Torvalds 
35771da177e4SLinus Torvalds 
35781da177e4SLinus Torvalds       ACCEPT_MSG(port);
35791da177e4SLinus Torvalds 
35801da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
35811da177e4SLinus Torvalds          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
35821da177e4SLinus Torvalds 
35831da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
35841da177e4SLinus Torvalds       }
35851da177e4SLinus Torvalds 
35861da177e4SLinus Torvalds    else {
35871da177e4SLinus Torvalds 
35881da177e4SLinus Torvalds 
35891da177e4SLinus Torvalds       ACCEPT_MSG_ATN(port);
35901da177e4SLinus Torvalds 
359147b5d69cSJames Bottomley        FPT_sisyncr(port,sync_msg,offset);
35921da177e4SLinus Torvalds 
35931da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
35941da177e4SLinus Torvalds          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
35951da177e4SLinus Torvalds       }
35961da177e4SLinus Torvalds }
35971da177e4SLinus Torvalds 
35981da177e4SLinus Torvalds 
35991da177e4SLinus Torvalds /*---------------------------------------------------------------------
36001da177e4SLinus Torvalds  *
360147b5d69cSJames Bottomley   * Function: FPT_sisyncr
36021da177e4SLinus Torvalds  *
36031da177e4SLinus Torvalds  * Description: Answer the targets sync message.
36041da177e4SLinus Torvalds  *
36051da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
360647b5d69cSJames Bottomley  static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
36071da177e4SLinus Torvalds {
36081da177e4SLinus Torvalds    ARAM_ACCESS(port);
36091da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
36101da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03  ));
36111da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
36121da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
36131da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP                ));
36141da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
36151da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
36161da177e4SLinus Torvalds    SGRAM_ACCESS(port);
36171da177e4SLinus Torvalds 
36181da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
36191da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
36201da177e4SLinus Torvalds 
36211da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
36221da177e4SLinus Torvalds 
36231da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
36241da177e4SLinus Torvalds }
36251da177e4SLinus Torvalds 
36261da177e4SLinus Torvalds 
36271da177e4SLinus Torvalds 
36281da177e4SLinus Torvalds /*---------------------------------------------------------------------
36291da177e4SLinus Torvalds  *
363047b5d69cSJames Bottomley   * Function: FPT_siwidn
36311da177e4SLinus Torvalds  *
36321da177e4SLinus Torvalds  * Description: Read in a message byte from the SCSI bus, and check
36331da177e4SLinus Torvalds  *              for a parity error.
36341da177e4SLinus Torvalds  *
36351da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
36361da177e4SLinus Torvalds 
363747b5d69cSJames Bottomley  static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
36381da177e4SLinus Torvalds {
36391da177e4SLinus Torvalds    PSCCB currSCCB;
36401da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
36411da177e4SLinus Torvalds 
364247b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
364347b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
36441da177e4SLinus Torvalds 
36451da177e4SLinus Torvalds    if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
36461da177e4SLinus Torvalds 
36471da177e4SLinus Torvalds 
36481da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT),
36491da177e4SLinus Torvalds 	              (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
36501da177e4SLinus Torvalds 
36511da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
36521da177e4SLinus Torvalds 
36531da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
36541da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02  ));
36551da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
36561da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP                ));
36571da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
36581da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP      ));
36591da177e4SLinus Torvalds 
36601da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
36611da177e4SLinus Torvalds 
36621da177e4SLinus Torvalds 
36631da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
36641da177e4SLinus Torvalds          ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
36651da177e4SLinus Torvalds 
366647b5d69cSJames Bottomley        return(1);
36671da177e4SLinus Torvalds       }
36681da177e4SLinus Torvalds 
36691da177e4SLinus Torvalds    else {
36701da177e4SLinus Torvalds 
36711da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
36721da177e4SLinus Torvalds                ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
36731da177e4SLinus Torvalds 
36741da177e4SLinus Torvalds       currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
367547b5d69cSJames Bottomley        return(0);
36761da177e4SLinus Torvalds       }
36771da177e4SLinus Torvalds }
36781da177e4SLinus Torvalds 
36791da177e4SLinus Torvalds 
36801da177e4SLinus Torvalds 
36811da177e4SLinus Torvalds /*---------------------------------------------------------------------
36821da177e4SLinus Torvalds  *
368347b5d69cSJames Bottomley   * Function: FPT_stwidn
36841da177e4SLinus Torvalds  *
36851da177e4SLinus Torvalds  * Description: The has sent us a Wide Nego message so handle it as
36861da177e4SLinus Torvalds  *              necessary.
36871da177e4SLinus Torvalds  *
36881da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
368947b5d69cSJames Bottomley  static void FPT_stwidn(ULONG port, UCHAR p_card)
36901da177e4SLinus Torvalds {
36911da177e4SLinus Torvalds    UCHAR width;
36921da177e4SLinus Torvalds    PSCCB currSCCB;
36931da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
36941da177e4SLinus Torvalds 
369547b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
369647b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
36971da177e4SLinus Torvalds 
369847b5d69cSJames Bottomley     width = FPT_sfm(port,currSCCB);
36991da177e4SLinus Torvalds 
37001da177e4SLinus Torvalds 	if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
37011da177e4SLinus Torvalds 	{
37021da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
37031da177e4SLinus Torvalds 		return;
37041da177e4SLinus Torvalds 	}
37051da177e4SLinus Torvalds 
37061da177e4SLinus Torvalds 
37071da177e4SLinus Torvalds    if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
37081da177e4SLinus Torvalds       width = 0;
37091da177e4SLinus Torvalds 
37101da177e4SLinus Torvalds    if (width) {
37111da177e4SLinus Torvalds       currTar_Info->TarStatus |= WIDE_ENABLED;
37121da177e4SLinus Torvalds       width = 0;
37131da177e4SLinus Torvalds       }
37141da177e4SLinus Torvalds    else {
37151da177e4SLinus Torvalds       width = NARROW_SCSI;
37161da177e4SLinus Torvalds       currTar_Info->TarStatus &= ~WIDE_ENABLED;
37171da177e4SLinus Torvalds       }
37181da177e4SLinus Torvalds 
37191da177e4SLinus Torvalds 
372047b5d69cSJames Bottomley     FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
37211da177e4SLinus Torvalds 
37221da177e4SLinus Torvalds 
37231da177e4SLinus Torvalds    if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
37241da177e4SLinus Torvalds 	{
37251da177e4SLinus Torvalds 
37261da177e4SLinus Torvalds 
37271da177e4SLinus Torvalds 
37281da177e4SLinus Torvalds       currTar_Info->TarStatus |=	 WIDE_NEGOCIATED;
37291da177e4SLinus Torvalds 
37301da177e4SLinus Torvalds 	   if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
37311da177e4SLinus Torvalds 		{
37321da177e4SLinus Torvalds 	      ACCEPT_MSG_ATN(port);
37331da177e4SLinus Torvalds 		   ARAM_ACCESS(port);
373447b5d69cSJames Bottomley  	     	FPT_sisyncn(port,p_card, 1);
37351da177e4SLinus Torvalds 	      currSCCB->Sccb_scsistat = SELECT_SN_ST;
37361da177e4SLinus Torvalds 		   SGRAM_ACCESS(port);
37371da177e4SLinus Torvalds 		}
37381da177e4SLinus Torvalds 		else
37391da177e4SLinus Torvalds 		{
37401da177e4SLinus Torvalds 	      ACCEPT_MSG(port);
37411da177e4SLinus Torvalds   		   WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
37421da177e4SLinus Torvalds 		}
37431da177e4SLinus Torvalds    }
37441da177e4SLinus Torvalds 
37451da177e4SLinus Torvalds    else {
37461da177e4SLinus Torvalds 
37471da177e4SLinus Torvalds 
37481da177e4SLinus Torvalds       ACCEPT_MSG_ATN(port);
37491da177e4SLinus Torvalds 
37501da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
37511da177e4SLinus Torvalds       	 width = SM16BIT;
37521da177e4SLinus Torvalds       else
37531da177e4SLinus Torvalds       	 width = SM8BIT;
37541da177e4SLinus Torvalds 
375547b5d69cSJames Bottomley        FPT_siwidr(port,width);
37561da177e4SLinus Torvalds 
37571da177e4SLinus Torvalds       currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
37581da177e4SLinus Torvalds       }
37591da177e4SLinus Torvalds }
37601da177e4SLinus Torvalds 
37611da177e4SLinus Torvalds 
37621da177e4SLinus Torvalds /*---------------------------------------------------------------------
37631da177e4SLinus Torvalds  *
376447b5d69cSJames Bottomley   * Function: FPT_siwidr
37651da177e4SLinus Torvalds  *
37661da177e4SLinus Torvalds  * Description: Answer the targets Wide nego message.
37671da177e4SLinus Torvalds  *
37681da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
376947b5d69cSJames Bottomley  static void FPT_siwidr(ULONG port, UCHAR width)
37701da177e4SLinus Torvalds {
37711da177e4SLinus Torvalds    ARAM_ACCESS(port);
37721da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
37731da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02  ));
37741da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
37751da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP                ));
37761da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
37771da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP      ));
37781da177e4SLinus Torvalds    SGRAM_ACCESS(port);
37791da177e4SLinus Torvalds 
37801da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
37811da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
37821da177e4SLinus Torvalds 
37831da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
37841da177e4SLinus Torvalds 
37851da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
37861da177e4SLinus Torvalds }
37871da177e4SLinus Torvalds 
37881da177e4SLinus Torvalds 
37891da177e4SLinus Torvalds 
37901da177e4SLinus Torvalds /*---------------------------------------------------------------------
37911da177e4SLinus Torvalds  *
379247b5d69cSJames Bottomley   * Function: FPT_sssyncv
37931da177e4SLinus Torvalds  *
37941da177e4SLinus Torvalds  * Description: Write the desired value to the Sync Register for the
37951da177e4SLinus Torvalds  *              ID specified.
37961da177e4SLinus Torvalds  *
37971da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
379847b5d69cSJames Bottomley  static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
379947b5d69cSJames Bottomley  			PSCCBMgr_tar_info currTar_Info)
38001da177e4SLinus Torvalds {
38011da177e4SLinus Torvalds    UCHAR index;
38021da177e4SLinus Torvalds 
38031da177e4SLinus Torvalds    index = p_id;
38041da177e4SLinus Torvalds 
38051da177e4SLinus Torvalds    switch (index) {
38061da177e4SLinus Torvalds 
38071da177e4SLinus Torvalds       case 0:
38081da177e4SLinus Torvalds 	 index = 12;             /* hp_synctarg_0 */
38091da177e4SLinus Torvalds 	 break;
38101da177e4SLinus Torvalds       case 1:
38111da177e4SLinus Torvalds 	 index = 13;             /* hp_synctarg_1 */
38121da177e4SLinus Torvalds 	 break;
38131da177e4SLinus Torvalds       case 2:
38141da177e4SLinus Torvalds 	 index = 14;             /* hp_synctarg_2 */
38151da177e4SLinus Torvalds 	 break;
38161da177e4SLinus Torvalds       case 3:
38171da177e4SLinus Torvalds 	 index = 15;             /* hp_synctarg_3 */
38181da177e4SLinus Torvalds 	 break;
38191da177e4SLinus Torvalds       case 4:
38201da177e4SLinus Torvalds 	 index = 8;              /* hp_synctarg_4 */
38211da177e4SLinus Torvalds 	 break;
38221da177e4SLinus Torvalds       case 5:
38231da177e4SLinus Torvalds 	 index = 9;              /* hp_synctarg_5 */
38241da177e4SLinus Torvalds 	 break;
38251da177e4SLinus Torvalds       case 6:
38261da177e4SLinus Torvalds 	 index = 10;             /* hp_synctarg_6 */
38271da177e4SLinus Torvalds 	 break;
38281da177e4SLinus Torvalds       case 7:
38291da177e4SLinus Torvalds 	 index = 11;             /* hp_synctarg_7 */
38301da177e4SLinus Torvalds 	 break;
38311da177e4SLinus Torvalds       case 8:
38321da177e4SLinus Torvalds 	 index = 4;              /* hp_synctarg_8 */
38331da177e4SLinus Torvalds 	 break;
38341da177e4SLinus Torvalds       case 9:
38351da177e4SLinus Torvalds 	 index = 5;              /* hp_synctarg_9 */
38361da177e4SLinus Torvalds 	 break;
38371da177e4SLinus Torvalds       case 10:
38381da177e4SLinus Torvalds 	 index = 6;              /* hp_synctarg_10 */
38391da177e4SLinus Torvalds 	 break;
38401da177e4SLinus Torvalds       case 11:
38411da177e4SLinus Torvalds 	 index = 7;              /* hp_synctarg_11 */
38421da177e4SLinus Torvalds 	 break;
38431da177e4SLinus Torvalds       case 12:
38441da177e4SLinus Torvalds 	 index = 0;              /* hp_synctarg_12 */
38451da177e4SLinus Torvalds 	 break;
38461da177e4SLinus Torvalds       case 13:
38471da177e4SLinus Torvalds 	 index = 1;              /* hp_synctarg_13 */
38481da177e4SLinus Torvalds 	 break;
38491da177e4SLinus Torvalds       case 14:
38501da177e4SLinus Torvalds 	 index = 2;              /* hp_synctarg_14 */
38511da177e4SLinus Torvalds 	 break;
38521da177e4SLinus Torvalds       case 15:
38531da177e4SLinus Torvalds 	 index = 3;              /* hp_synctarg_15 */
38541da177e4SLinus Torvalds 
38551da177e4SLinus Torvalds       }
38561da177e4SLinus Torvalds 
38571da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
38581da177e4SLinus Torvalds 
38591da177e4SLinus Torvalds 	currTar_Info->TarSyncCtrl = p_sync_value;
38601da177e4SLinus Torvalds }
38611da177e4SLinus Torvalds 
38621da177e4SLinus Torvalds 
38631da177e4SLinus Torvalds /*---------------------------------------------------------------------
38641da177e4SLinus Torvalds  *
386547b5d69cSJames Bottomley   * Function: FPT_sresb
38661da177e4SLinus Torvalds  *
38671da177e4SLinus Torvalds  * Description: Reset the desired card's SCSI bus.
38681da177e4SLinus Torvalds  *
38691da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
387047b5d69cSJames Bottomley  static void FPT_sresb(ULONG port, UCHAR p_card)
38711da177e4SLinus Torvalds {
38721da177e4SLinus Torvalds    UCHAR scsiID, i;
38731da177e4SLinus Torvalds 
38741da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
38751da177e4SLinus Torvalds 
38761da177e4SLinus Torvalds    WR_HARPOON(port+hp_page_ctrl,
38771da177e4SLinus Torvalds       (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
38781da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
38791da177e4SLinus Torvalds 
38801da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
38811da177e4SLinus Torvalds 
38821da177e4SLinus Torvalds    scsiID = RD_HARPOON(port+hp_seltimeout);
38831da177e4SLinus Torvalds    WR_HARPOON(port+hp_seltimeout,TO_5ms);
38841da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), TIMEOUT);
38851da177e4SLinus Torvalds 
38861da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
38871da177e4SLinus Torvalds 
38881da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
38891da177e4SLinus Torvalds 
38901da177e4SLinus Torvalds    WR_HARPOON(port+hp_seltimeout,scsiID);
38911da177e4SLinus Torvalds 
38921da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
38931da177e4SLinus Torvalds 
389447b5d69cSJames Bottomley     FPT_Wait(port, TO_5ms);
38951da177e4SLinus Torvalds 
38961da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
38971da177e4SLinus Torvalds 
38981da177e4SLinus Torvalds    WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
38991da177e4SLinus Torvalds 
39001da177e4SLinus Torvalds    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
39011da177e4SLinus Torvalds       {
390247b5d69cSJames Bottomley        currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
39031da177e4SLinus Torvalds 
39041da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
39051da177e4SLinus Torvalds          {
39061da177e4SLinus Torvalds 	      	currTar_Info->TarSyncCtrl = 0;
39071da177e4SLinus Torvalds 	      	currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
39081da177e4SLinus Torvalds 	      }
39091da177e4SLinus Torvalds 
39101da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
39111da177e4SLinus Torvalds          {
39121da177e4SLinus Torvalds       	currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
39131da177e4SLinus Torvalds       	}
39141da177e4SLinus Torvalds 
391547b5d69cSJames Bottomley        FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
39161da177e4SLinus Torvalds 
391747b5d69cSJames Bottomley        FPT_SccbMgrTableInitTarget(p_card, scsiID);
39181da177e4SLinus Torvalds       }
39191da177e4SLinus Torvalds 
392047b5d69cSJames Bottomley     FPT_BL_Card[p_card].scanIndex = 0x00;
392147b5d69cSJames Bottomley     FPT_BL_Card[p_card].currentSCCB = NULL;
392247b5d69cSJames Bottomley     FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
39231da177e4SLinus Torvalds 													| F_NEW_SCCB_CMD);
392447b5d69cSJames Bottomley     FPT_BL_Card[p_card].cmdCounter  = 0x00;
392547b5d69cSJames Bottomley  	FPT_BL_Card[p_card].discQCount = 0x00;
392647b5d69cSJames Bottomley     FPT_BL_Card[p_card].tagQ_Lst = 0x01;
39271da177e4SLinus Torvalds 
39281da177e4SLinus Torvalds 	for(i = 0; i < QUEUE_DEPTH; i++)
392947b5d69cSJames Bottomley  		FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
39301da177e4SLinus Torvalds 
39311da177e4SLinus Torvalds    WR_HARPOON(port+hp_page_ctrl,
39321da177e4SLinus Torvalds       (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
39331da177e4SLinus Torvalds 
39341da177e4SLinus Torvalds }
39351da177e4SLinus Torvalds 
39361da177e4SLinus Torvalds /*---------------------------------------------------------------------
39371da177e4SLinus Torvalds  *
393847b5d69cSJames Bottomley   * Function: FPT_ssenss
39391da177e4SLinus Torvalds  *
39401da177e4SLinus Torvalds  * Description: Setup for the Auto Sense command.
39411da177e4SLinus Torvalds  *
39421da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
394347b5d69cSJames Bottomley  static void FPT_ssenss(PSCCBcard pCurrCard)
39441da177e4SLinus Torvalds {
39451da177e4SLinus Torvalds    UCHAR i;
39461da177e4SLinus Torvalds    PSCCB currSCCB;
39471da177e4SLinus Torvalds 
39481da177e4SLinus Torvalds    currSCCB = pCurrCard->currentSCCB;
39491da177e4SLinus Torvalds 
39501da177e4SLinus Torvalds 
39511da177e4SLinus Torvalds    currSCCB->Save_CdbLen = currSCCB->CdbLength;
39521da177e4SLinus Torvalds 
39531da177e4SLinus Torvalds    for (i = 0; i < 6; i++) {
39541da177e4SLinus Torvalds 
39551da177e4SLinus Torvalds       currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
39561da177e4SLinus Torvalds       }
39571da177e4SLinus Torvalds 
39581da177e4SLinus Torvalds    currSCCB->CdbLength = SIX_BYTE_CMD;
39591da177e4SLinus Torvalds    currSCCB->Cdb[0]    = SCSI_REQUEST_SENSE;
39601da177e4SLinus Torvalds    currSCCB->Cdb[1]    = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
39611da177e4SLinus Torvalds    currSCCB->Cdb[2]    = 0x00;
39621da177e4SLinus Torvalds    currSCCB->Cdb[3]    = 0x00;
39631da177e4SLinus Torvalds    currSCCB->Cdb[4]    = currSCCB->RequestSenseLength;
39641da177e4SLinus Torvalds    currSCCB->Cdb[5]    = 0x00;
39651da177e4SLinus Torvalds 
39661da177e4SLinus Torvalds    currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
39671da177e4SLinus Torvalds 
39681da177e4SLinus Torvalds    currSCCB->Sccb_ATC = 0x00;
39691da177e4SLinus Torvalds 
39701da177e4SLinus Torvalds    currSCCB->Sccb_XferState |= F_AUTO_SENSE;
39711da177e4SLinus Torvalds 
39721da177e4SLinus Torvalds    currSCCB->Sccb_XferState &= ~F_SG_XFER;
39731da177e4SLinus Torvalds 
39741da177e4SLinus Torvalds    currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
39751da177e4SLinus Torvalds 
39761da177e4SLinus Torvalds    currSCCB->ControlByte = 0x00;
39771da177e4SLinus Torvalds 
39781da177e4SLinus Torvalds    currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
39791da177e4SLinus Torvalds }
39801da177e4SLinus Torvalds 
39811da177e4SLinus Torvalds 
39821da177e4SLinus Torvalds 
39831da177e4SLinus Torvalds /*---------------------------------------------------------------------
39841da177e4SLinus Torvalds  *
398547b5d69cSJames Bottomley   * Function: FPT_sxfrp
39861da177e4SLinus Torvalds  *
39871da177e4SLinus Torvalds  * Description: Transfer data into the bit bucket until the device
39881da177e4SLinus Torvalds  *              decides to switch phase.
39891da177e4SLinus Torvalds  *
39901da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
39911da177e4SLinus Torvalds 
399247b5d69cSJames Bottomley  static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
39931da177e4SLinus Torvalds {
39941da177e4SLinus Torvalds    UCHAR curr_phz;
39951da177e4SLinus Torvalds 
39961da177e4SLinus Torvalds 
39971da177e4SLinus Torvalds    DISABLE_AUTO(p_port);
39981da177e4SLinus Torvalds 
399947b5d69cSJames Bottomley     if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
40001da177e4SLinus Torvalds 
400147b5d69cSJames Bottomley        FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
40021da177e4SLinus Torvalds 
40031da177e4SLinus Torvalds       }
40041da177e4SLinus Torvalds 
40051da177e4SLinus Torvalds    /* If the Automation handled the end of the transfer then do not
40061da177e4SLinus Torvalds       match the phase or we will get out of sync with the ISR.       */
40071da177e4SLinus Torvalds 
40081da177e4SLinus Torvalds    if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
40091da177e4SLinus Torvalds       return;
40101da177e4SLinus Torvalds 
40111da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
40121da177e4SLinus Torvalds 
40131da177e4SLinus Torvalds    curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
40141da177e4SLinus Torvalds 
40151da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
40161da177e4SLinus Torvalds 
40171da177e4SLinus Torvalds 
40181da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, curr_phz);
40191da177e4SLinus Torvalds 
40201da177e4SLinus Torvalds    while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
40211da177e4SLinus Torvalds       (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
40221da177e4SLinus Torvalds       {
40231da177e4SLinus Torvalds       if (curr_phz & (UCHAR)SCSI_IOBIT)
40241da177e4SLinus Torvalds          {
40251da177e4SLinus Torvalds       	WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
40261da177e4SLinus Torvalds 
40271da177e4SLinus Torvalds 	      if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
40281da177e4SLinus Torvalds             {
40291da177e4SLinus Torvalds 	         RD_HARPOON(p_port+hp_fifodata_0);
40301da177e4SLinus Torvalds 	         }
40311da177e4SLinus Torvalds 	      }
40321da177e4SLinus Torvalds       else
40331da177e4SLinus Torvalds          {
40341da177e4SLinus Torvalds       	WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
40351da177e4SLinus Torvalds    	   if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
40361da177e4SLinus Torvalds             {
40371da177e4SLinus Torvalds 	         WR_HARPOON(p_port+hp_fifodata_0,0xFA);
40381da177e4SLinus Torvalds 	         }
40391da177e4SLinus Torvalds 	      }
40401da177e4SLinus Torvalds       } /* End of While loop for padding data I/O phase */
40411da177e4SLinus Torvalds 
40421da177e4SLinus Torvalds       while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
40431da177e4SLinus Torvalds          {
40441da177e4SLinus Torvalds          if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
40451da177e4SLinus Torvalds       	   break;
40461da177e4SLinus Torvalds          }
40471da177e4SLinus Torvalds 
40481da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
40491da177e4SLinus Torvalds       while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
40501da177e4SLinus Torvalds          {
40511da177e4SLinus Torvalds          RD_HARPOON(p_port+hp_fifodata_0);
40521da177e4SLinus Torvalds          }
40531da177e4SLinus Torvalds 
40541da177e4SLinus Torvalds       if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
40551da177e4SLinus Torvalds          {
40561da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
40571da177e4SLinus Torvalds          while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
40581da177e4SLinus Torvalds 
40591da177e4SLinus Torvalds          if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
40601da177e4SLinus Torvalds    	   while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
40611da177e4SLinus Torvalds          }
40621da177e4SLinus Torvalds }
40631da177e4SLinus Torvalds 
40641da177e4SLinus Torvalds 
40651da177e4SLinus Torvalds /*---------------------------------------------------------------------
40661da177e4SLinus Torvalds  *
406747b5d69cSJames Bottomley   * Function: FPT_schkdd
40681da177e4SLinus Torvalds  *
40691da177e4SLinus Torvalds  * Description: Make sure data has been flushed from both FIFOs and abort
40701da177e4SLinus Torvalds  *              the operations if necessary.
40711da177e4SLinus Torvalds  *
40721da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
40731da177e4SLinus Torvalds 
407447b5d69cSJames Bottomley  static void FPT_schkdd(ULONG port, UCHAR p_card)
40751da177e4SLinus Torvalds {
40761da177e4SLinus Torvalds    USHORT TimeOutLoop;
40771da177e4SLinus Torvalds 	UCHAR sPhase;
40781da177e4SLinus Torvalds 
40791da177e4SLinus Torvalds    PSCCB currSCCB;
40801da177e4SLinus Torvalds 
408147b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
40821da177e4SLinus Torvalds 
40831da177e4SLinus Torvalds 
40841da177e4SLinus Torvalds    if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
40851da177e4SLinus Torvalds        (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
40861da177e4SLinus Torvalds       return;
40871da177e4SLinus Torvalds       }
40881da177e4SLinus Torvalds 
40891da177e4SLinus Torvalds 
40901da177e4SLinus Torvalds 
40911da177e4SLinus Torvalds    if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
40921da177e4SLinus Torvalds       {
40931da177e4SLinus Torvalds 
40941da177e4SLinus Torvalds       currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
40951da177e4SLinus Torvalds 
40961da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = 1;
40971da177e4SLinus Torvalds 
40981da177e4SLinus Torvalds       currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
40991da177e4SLinus Torvalds       WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
41001da177e4SLinus Torvalds       WR_HARPOON(port+hp_xferstat, 0x00);
41011da177e4SLinus Torvalds       }
41021da177e4SLinus Torvalds 
41031da177e4SLinus Torvalds    else
41041da177e4SLinus Torvalds       {
41051da177e4SLinus Torvalds 
41061da177e4SLinus Torvalds       currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
41071da177e4SLinus Torvalds 
41081da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = 0;
41091da177e4SLinus Torvalds       }
41101da177e4SLinus Torvalds 
41111da177e4SLinus Torvalds    if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
41121da177e4SLinus Torvalds       (currSCCB->HostStatus == SCCB_COMPLETE)) {
41131da177e4SLinus Torvalds 
41141da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PARITY_ERR;
41151da177e4SLinus Torvalds       WRW_HARPOON((port+hp_intstat), PARITY);
41161da177e4SLinus Torvalds       }
41171da177e4SLinus Torvalds 
41181da177e4SLinus Torvalds 
411947b5d69cSJames Bottomley     FPT_hostDataXferAbort(port,p_card,currSCCB);
41201da177e4SLinus Torvalds 
41211da177e4SLinus Torvalds 
41221da177e4SLinus Torvalds    while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
41231da177e4SLinus Torvalds 
41241da177e4SLinus Torvalds    TimeOutLoop = 0;
41251da177e4SLinus Torvalds 
41261da177e4SLinus Torvalds    while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
41271da177e4SLinus Torvalds       {
41281da177e4SLinus Torvalds       if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
41291da177e4SLinus Torvalds 	      return;
41301da177e4SLinus Torvalds    	   }
41311da177e4SLinus Torvalds       if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
41321da177e4SLinus Torvalds 	      break;
41331da177e4SLinus Torvalds    	   }
41341da177e4SLinus Torvalds       if (RDW_HARPOON((port+hp_intstat)) & RESET) {
41351da177e4SLinus Torvalds 	      return;
41361da177e4SLinus Torvalds    	   }
41371da177e4SLinus Torvalds       if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
41381da177e4SLinus Torvalds    	   break;
41391da177e4SLinus Torvalds       }
41401da177e4SLinus Torvalds 
41411da177e4SLinus Torvalds 	sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
41421da177e4SLinus Torvalds    if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))                     ||
41431da177e4SLinus Torvalds       (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F)                       ||
41441da177e4SLinus Torvalds       (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
41451da177e4SLinus Torvalds       (sPhase == (SCSI_BSY | S_DATAI_PH)))
41461da177e4SLinus Torvalds       {
41471da177e4SLinus Torvalds 
41481da177e4SLinus Torvalds 	   WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
41491da177e4SLinus Torvalds 
41501da177e4SLinus Torvalds 	   if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
41511da177e4SLinus Torvalds          {
41521da177e4SLinus Torvalds 	      if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
415347b5d69cSJames Bottomley  	         FPT_phaseDataIn(port,p_card);
41541da177e4SLinus Torvalds 	      	}
41551da177e4SLinus Torvalds 
41561da177e4SLinus Torvalds 	   	else {
415747b5d69cSJames Bottomley  	       FPT_phaseDataOut(port,p_card);
41581da177e4SLinus Torvalds 	       	}
41591da177e4SLinus Torvalds 	   	}
41601da177e4SLinus Torvalds 		else
41611da177e4SLinus Torvalds       	{
416247b5d69cSJames Bottomley  	   	FPT_sxfrp(port,p_card);
41631da177e4SLinus Torvalds 	   	if (!(RDW_HARPOON((port+hp_intstat)) &
41641da177e4SLinus Torvalds 		      (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
41651da177e4SLinus Torvalds          {
41661da177e4SLinus Torvalds    		WRW_HARPOON((port+hp_intstat), AUTO_INT);
416747b5d69cSJames Bottomley  		   FPT_phaseDecode(port,p_card);
41681da177e4SLinus Torvalds 		   }
41691da177e4SLinus Torvalds 	   }
41701da177e4SLinus Torvalds 
41711da177e4SLinus Torvalds    }
41721da177e4SLinus Torvalds 
41731da177e4SLinus Torvalds    else {
41741da177e4SLinus Torvalds       WR_HARPOON(port+hp_portctrl_0, 0x00);
41751da177e4SLinus Torvalds       }
41761da177e4SLinus Torvalds }
41771da177e4SLinus Torvalds 
41781da177e4SLinus Torvalds 
41791da177e4SLinus Torvalds /*---------------------------------------------------------------------
41801da177e4SLinus Torvalds  *
418147b5d69cSJames Bottomley   * Function: FPT_sinits
41821da177e4SLinus Torvalds  *
41831da177e4SLinus Torvalds  * Description: Setup SCCB manager fields in this SCCB.
41841da177e4SLinus Torvalds  *
41851da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
41861da177e4SLinus Torvalds 
418747b5d69cSJames Bottomley  static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
41881da177e4SLinus Torvalds {
41891da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
41901da177e4SLinus Torvalds 
41911da177e4SLinus Torvalds 	if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
41921da177e4SLinus Torvalds 	{
41931da177e4SLinus Torvalds 		return;
41941da177e4SLinus Torvalds 	}
419547b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
41961da177e4SLinus Torvalds 
41971da177e4SLinus Torvalds    p_sccb->Sccb_XferState     = 0x00;
41981da177e4SLinus Torvalds    p_sccb->Sccb_XferCnt       = p_sccb->DataLength;
41991da177e4SLinus Torvalds 
42001da177e4SLinus Torvalds    if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
42011da177e4SLinus Torvalds       (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
42021da177e4SLinus Torvalds 
42031da177e4SLinus Torvalds       p_sccb->Sccb_SGoffset   = 0;
42041da177e4SLinus Torvalds       p_sccb->Sccb_XferState  = F_SG_XFER;
42051da177e4SLinus Torvalds       p_sccb->Sccb_XferCnt    = 0x00;
42061da177e4SLinus Torvalds       }
42071da177e4SLinus Torvalds 
42081da177e4SLinus Torvalds    if (p_sccb->DataLength == 0x00)
42091da177e4SLinus Torvalds 
42101da177e4SLinus Torvalds       p_sccb->Sccb_XferState |= F_ALL_XFERRED;
42111da177e4SLinus Torvalds 
42121da177e4SLinus Torvalds    if (p_sccb->ControlByte & F_USE_CMD_Q)
42131da177e4SLinus Torvalds       {
42141da177e4SLinus Torvalds       if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
42151da177e4SLinus Torvalds          p_sccb->ControlByte &= ~F_USE_CMD_Q;
42161da177e4SLinus Torvalds 
42171da177e4SLinus Torvalds       else
42181da177e4SLinus Torvalds 	      currTar_Info->TarStatus |= TAG_Q_TRYING;
42191da177e4SLinus Torvalds       }
42201da177e4SLinus Torvalds 
42211da177e4SLinus Torvalds /*      For !single SCSI device in system  & device allow Disconnect
42221da177e4SLinus Torvalds 	or command is tag_q type then send Cmd with Disconnect Enable
42231da177e4SLinus Torvalds 	else send Cmd with Disconnect Disable */
42241da177e4SLinus Torvalds 
42251da177e4SLinus Torvalds /*
422647b5d69cSJames Bottomley     if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
42271da177e4SLinus Torvalds       (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
42281da177e4SLinus Torvalds       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
42291da177e4SLinus Torvalds */
42301da177e4SLinus Torvalds    if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
42311da177e4SLinus Torvalds       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
42321da177e4SLinus Torvalds       p_sccb->Sccb_idmsg      = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
42331da177e4SLinus Torvalds       }
42341da177e4SLinus Torvalds 
42351da177e4SLinus Torvalds    else {
42361da177e4SLinus Torvalds 
42371da177e4SLinus Torvalds       p_sccb->Sccb_idmsg      = (UCHAR)SMIDENT | p_sccb->Lun;
42381da177e4SLinus Torvalds       }
42391da177e4SLinus Torvalds 
42401da177e4SLinus Torvalds    p_sccb->HostStatus         = 0x00;
42411da177e4SLinus Torvalds    p_sccb->TargetStatus       = 0x00;
42421da177e4SLinus Torvalds    p_sccb->Sccb_tag           = 0x00;
42431da177e4SLinus Torvalds    p_sccb->Sccb_MGRFlags      = 0x00;
42441da177e4SLinus Torvalds    p_sccb->Sccb_sgseg         = 0x00;
42451da177e4SLinus Torvalds    p_sccb->Sccb_ATC           = 0x00;
42461da177e4SLinus Torvalds    p_sccb->Sccb_savedATC      = 0x00;
42471da177e4SLinus Torvalds /*
42481da177e4SLinus Torvalds    p_sccb->SccbVirtDataPtr    = 0x00;
42491da177e4SLinus Torvalds    p_sccb->Sccb_forwardlink   = NULL;
42501da177e4SLinus Torvalds    p_sccb->Sccb_backlink      = NULL;
42511da177e4SLinus Torvalds  */
42521da177e4SLinus Torvalds    p_sccb->Sccb_scsistat      = BUS_FREE_ST;
42531da177e4SLinus Torvalds    p_sccb->SccbStatus         = SCCB_IN_PROCESS;
42541da177e4SLinus Torvalds    p_sccb->Sccb_scsimsg       = SMNO_OP;
42551da177e4SLinus Torvalds 
42561da177e4SLinus Torvalds }
42571da177e4SLinus Torvalds 
42581da177e4SLinus Torvalds 
42591da177e4SLinus Torvalds /*---------------------------------------------------------------------
42601da177e4SLinus Torvalds  *
42611da177e4SLinus Torvalds  * Function: Phase Decode
42621da177e4SLinus Torvalds  *
42631da177e4SLinus Torvalds  * Description: Determine the phase and call the appropriate function.
42641da177e4SLinus Torvalds  *
42651da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
42661da177e4SLinus Torvalds 
426747b5d69cSJames Bottomley  static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
42681da177e4SLinus Torvalds {
42691da177e4SLinus Torvalds    unsigned char phase_ref;
42701da177e4SLinus Torvalds    void (*phase) (ULONG, UCHAR);
42711da177e4SLinus Torvalds 
42721da177e4SLinus Torvalds 
42731da177e4SLinus Torvalds    DISABLE_AUTO(p_port);
42741da177e4SLinus Torvalds 
42751da177e4SLinus Torvalds    phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
42761da177e4SLinus Torvalds 
427747b5d69cSJames Bottomley     phase = FPT_s_PhaseTbl[phase_ref];
42781da177e4SLinus Torvalds 
42791da177e4SLinus Torvalds    (*phase)(p_port, p_card);           /* Call the correct phase func */
42801da177e4SLinus Torvalds }
42811da177e4SLinus Torvalds 
42821da177e4SLinus Torvalds 
42831da177e4SLinus Torvalds 
42841da177e4SLinus Torvalds /*---------------------------------------------------------------------
42851da177e4SLinus Torvalds  *
42861da177e4SLinus Torvalds  * Function: Data Out Phase
42871da177e4SLinus Torvalds  *
42881da177e4SLinus Torvalds  * Description: Start up both the BusMaster and Xbow.
42891da177e4SLinus Torvalds  *
42901da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
42911da177e4SLinus Torvalds 
429247b5d69cSJames Bottomley  static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
42931da177e4SLinus Torvalds {
42941da177e4SLinus Torvalds 
42951da177e4SLinus Torvalds    PSCCB currSCCB;
42961da177e4SLinus Torvalds 
429747b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
42981da177e4SLinus Torvalds    if (currSCCB == NULL)
42991da177e4SLinus Torvalds       {
43001da177e4SLinus Torvalds       return;  /* Exit if No SCCB record */
43011da177e4SLinus Torvalds       }
43021da177e4SLinus Torvalds 
43031da177e4SLinus Torvalds    currSCCB->Sccb_scsistat = DATA_OUT_ST;
43041da177e4SLinus Torvalds    currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
43051da177e4SLinus Torvalds 
43061da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
43071da177e4SLinus Torvalds 
43081da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
43091da177e4SLinus Torvalds 
43101da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
43111da177e4SLinus Torvalds 
431247b5d69cSJames Bottomley     FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
43131da177e4SLinus Torvalds 
43141da177e4SLinus Torvalds    if (currSCCB->Sccb_XferCnt == 0) {
43151da177e4SLinus Torvalds 
43161da177e4SLinus Torvalds 
43171da177e4SLinus Torvalds       if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
43181da177e4SLinus Torvalds 	 (currSCCB->HostStatus == SCCB_COMPLETE))
43191da177e4SLinus Torvalds 	 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
43201da177e4SLinus Torvalds 
432147b5d69cSJames Bottomley        FPT_sxfrp(port,p_card);
43221da177e4SLinus Torvalds       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
432347b5d69cSJames Bottomley  	    FPT_phaseDecode(port,p_card);
43241da177e4SLinus Torvalds       }
43251da177e4SLinus Torvalds }
43261da177e4SLinus Torvalds 
43271da177e4SLinus Torvalds 
43281da177e4SLinus Torvalds /*---------------------------------------------------------------------
43291da177e4SLinus Torvalds  *
43301da177e4SLinus Torvalds  * Function: Data In Phase
43311da177e4SLinus Torvalds  *
43321da177e4SLinus Torvalds  * Description: Startup the BusMaster and the XBOW.
43331da177e4SLinus Torvalds  *
43341da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
43351da177e4SLinus Torvalds 
433647b5d69cSJames Bottomley  static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
43371da177e4SLinus Torvalds {
43381da177e4SLinus Torvalds 
43391da177e4SLinus Torvalds    PSCCB currSCCB;
43401da177e4SLinus Torvalds 
434147b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
43421da177e4SLinus Torvalds 
43431da177e4SLinus Torvalds    if (currSCCB == NULL)
43441da177e4SLinus Torvalds       {
43451da177e4SLinus Torvalds       return;  /* Exit if No SCCB record */
43461da177e4SLinus Torvalds       }
43471da177e4SLinus Torvalds 
43481da177e4SLinus Torvalds 
43491da177e4SLinus Torvalds    currSCCB->Sccb_scsistat = DATA_IN_ST;
43501da177e4SLinus Torvalds    currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
43511da177e4SLinus Torvalds    currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
43521da177e4SLinus Torvalds 
43531da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
43541da177e4SLinus Torvalds 
43551da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
43561da177e4SLinus Torvalds 
43571da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
43581da177e4SLinus Torvalds 
435947b5d69cSJames Bottomley     FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
43601da177e4SLinus Torvalds 
43611da177e4SLinus Torvalds    if (currSCCB->Sccb_XferCnt == 0) {
43621da177e4SLinus Torvalds 
43631da177e4SLinus Torvalds 
43641da177e4SLinus Torvalds       if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
43651da177e4SLinus Torvalds 	 (currSCCB->HostStatus == SCCB_COMPLETE))
43661da177e4SLinus Torvalds 	 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
43671da177e4SLinus Torvalds 
436847b5d69cSJames Bottomley        FPT_sxfrp(port,p_card);
43691da177e4SLinus Torvalds       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
437047b5d69cSJames Bottomley  	    FPT_phaseDecode(port,p_card);
43711da177e4SLinus Torvalds 
43721da177e4SLinus Torvalds       }
43731da177e4SLinus Torvalds }
43741da177e4SLinus Torvalds 
43751da177e4SLinus Torvalds /*---------------------------------------------------------------------
43761da177e4SLinus Torvalds  *
43771da177e4SLinus Torvalds  * Function: Command Phase
43781da177e4SLinus Torvalds  *
43791da177e4SLinus Torvalds  * Description: Load the CDB into the automation and start it up.
43801da177e4SLinus Torvalds  *
43811da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
43821da177e4SLinus Torvalds 
438347b5d69cSJames Bottomley  static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
43841da177e4SLinus Torvalds {
43851da177e4SLinus Torvalds    PSCCB currSCCB;
43861da177e4SLinus Torvalds    ULONG cdb_reg;
43871da177e4SLinus Torvalds    UCHAR i;
43881da177e4SLinus Torvalds 
438947b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
43901da177e4SLinus Torvalds 
43911da177e4SLinus Torvalds    if (currSCCB->OperationCode == RESET_COMMAND) {
43921da177e4SLinus Torvalds 
43931da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
43941da177e4SLinus Torvalds       currSCCB->CdbLength = SIX_BYTE_CMD;
43951da177e4SLinus Torvalds       }
43961da177e4SLinus Torvalds 
43971da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, 0x00);
43981da177e4SLinus Torvalds 
43991da177e4SLinus Torvalds    ARAM_ACCESS(p_port);
44001da177e4SLinus Torvalds 
44011da177e4SLinus Torvalds 
44021da177e4SLinus Torvalds    cdb_reg = p_port + CMD_STRT;
44031da177e4SLinus Torvalds 
44041da177e4SLinus Torvalds    for (i=0; i < currSCCB->CdbLength; i++) {
44051da177e4SLinus Torvalds 
44061da177e4SLinus Torvalds       if (currSCCB->OperationCode == RESET_COMMAND)
44071da177e4SLinus Torvalds 
44081da177e4SLinus Torvalds 	 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
44091da177e4SLinus Torvalds 
44101da177e4SLinus Torvalds       else
44111da177e4SLinus Torvalds 	 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
44121da177e4SLinus Torvalds       cdb_reg +=2;
44131da177e4SLinus Torvalds       }
44141da177e4SLinus Torvalds 
44151da177e4SLinus Torvalds    if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
44161da177e4SLinus Torvalds       WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+    NP));
44171da177e4SLinus Torvalds 
44181da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
44191da177e4SLinus Torvalds 
44201da177e4SLinus Torvalds    currSCCB->Sccb_scsistat = COMMAND_ST;
44211da177e4SLinus Torvalds 
44221da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
44231da177e4SLinus Torvalds    SGRAM_ACCESS(p_port);
44241da177e4SLinus Torvalds }
44251da177e4SLinus Torvalds 
44261da177e4SLinus Torvalds 
44271da177e4SLinus Torvalds /*---------------------------------------------------------------------
44281da177e4SLinus Torvalds  *
44291da177e4SLinus Torvalds  * Function: Status phase
44301da177e4SLinus Torvalds  *
44311da177e4SLinus Torvalds  * Description: Bring in the status and command complete message bytes
44321da177e4SLinus Torvalds  *
44331da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
44341da177e4SLinus Torvalds 
443547b5d69cSJames Bottomley  static void FPT_phaseStatus(ULONG port, UCHAR p_card)
44361da177e4SLinus Torvalds {
44371da177e4SLinus Torvalds    /* Start-up the automation to finish off this command and let the
44381da177e4SLinus Torvalds       isr handle the interrupt for command complete when it comes in.
44391da177e4SLinus Torvalds       We could wait here for the interrupt to be generated?
44401da177e4SLinus Torvalds     */
44411da177e4SLinus Torvalds 
44421da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsisig, 0x00);
44431da177e4SLinus Torvalds 
44441da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
44451da177e4SLinus Torvalds }
44461da177e4SLinus Torvalds 
44471da177e4SLinus Torvalds 
44481da177e4SLinus Torvalds /*---------------------------------------------------------------------
44491da177e4SLinus Torvalds  *
44501da177e4SLinus Torvalds  * Function: Phase Message Out
44511da177e4SLinus Torvalds  *
44521da177e4SLinus Torvalds  * Description: Send out our message (if we have one) and handle whatever
44531da177e4SLinus Torvalds  *              else is involed.
44541da177e4SLinus Torvalds  *
44551da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
44561da177e4SLinus Torvalds 
445747b5d69cSJames Bottomley  static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
44581da177e4SLinus Torvalds {
44591da177e4SLinus Torvalds 	UCHAR message,scsiID;
44601da177e4SLinus Torvalds 	PSCCB currSCCB;
44611da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
44621da177e4SLinus Torvalds 
446347b5d69cSJames Bottomley  	currSCCB = FPT_BL_Card[p_card].currentSCCB;
44641da177e4SLinus Torvalds 
44651da177e4SLinus Torvalds 	if (currSCCB != NULL) {
44661da177e4SLinus Torvalds 
44671da177e4SLinus Torvalds 		message = currSCCB->Sccb_scsimsg;
44681da177e4SLinus Torvalds 		scsiID = currSCCB->TargID;
44691da177e4SLinus Torvalds 
44701da177e4SLinus Torvalds 		if (message == SMDEV_RESET)
44711da177e4SLinus Torvalds 		{
44721da177e4SLinus Torvalds 
44731da177e4SLinus Torvalds 
447447b5d69cSJames Bottomley  			currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
44751da177e4SLinus Torvalds 			currTar_Info->TarSyncCtrl = 0;
447647b5d69cSJames Bottomley  			FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
44771da177e4SLinus Torvalds 
447847b5d69cSJames Bottomley  			if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
44791da177e4SLinus Torvalds 			{
44801da177e4SLinus Torvalds 
448147b5d69cSJames Bottomley  				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
44821da177e4SLinus Torvalds 
44831da177e4SLinus Torvalds 			}
44841da177e4SLinus Torvalds 
448547b5d69cSJames Bottomley  			if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
44861da177e4SLinus Torvalds 			{
44871da177e4SLinus Torvalds 
448847b5d69cSJames Bottomley  				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
44891da177e4SLinus Torvalds 			}
44901da177e4SLinus Torvalds 
44911da177e4SLinus Torvalds 
449247b5d69cSJames Bottomley  			FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
449347b5d69cSJames Bottomley  			FPT_SccbMgrTableInitTarget(p_card,scsiID);
44941da177e4SLinus Torvalds 		}
44951da177e4SLinus Torvalds 		else if (currSCCB->Sccb_scsistat == ABORT_ST)
44961da177e4SLinus Torvalds 		{
44971da177e4SLinus Torvalds 			currSCCB->HostStatus = SCCB_COMPLETE;
449847b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
44991da177e4SLinus Torvalds 			{
450047b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
450147b5d69cSJames Bottomley  				FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
45021da177e4SLinus Torvalds 			}
45031da177e4SLinus Torvalds 
45041da177e4SLinus Torvalds 		}
45051da177e4SLinus Torvalds 
45061da177e4SLinus Torvalds 		else if (currSCCB->Sccb_scsistat < COMMAND_ST)
45071da177e4SLinus Torvalds 		{
45081da177e4SLinus Torvalds 
45091da177e4SLinus Torvalds 
45101da177e4SLinus Torvalds 			if(message == SMNO_OP)
45111da177e4SLinus Torvalds 			{
45121da177e4SLinus Torvalds 				currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
45131da177e4SLinus Torvalds 
451447b5d69cSJames Bottomley  				FPT_ssel(port,p_card);
45151da177e4SLinus Torvalds 				return;
45161da177e4SLinus Torvalds 			}
45171da177e4SLinus Torvalds 		}
45181da177e4SLinus Torvalds 		else
45191da177e4SLinus Torvalds 		{
45201da177e4SLinus Torvalds 
45211da177e4SLinus Torvalds 
45221da177e4SLinus Torvalds 			if (message == SMABORT)
45231da177e4SLinus Torvalds 
452447b5d69cSJames Bottomley  				FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
45251da177e4SLinus Torvalds 		}
45261da177e4SLinus Torvalds 
45271da177e4SLinus Torvalds 	}
45281da177e4SLinus Torvalds 	else
45291da177e4SLinus Torvalds 	{
45301da177e4SLinus Torvalds 		message = SMABORT;
45311da177e4SLinus Torvalds 	}
45321da177e4SLinus Torvalds 
45331da177e4SLinus Torvalds 	WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
45341da177e4SLinus Torvalds 
45351da177e4SLinus Torvalds 
45361da177e4SLinus Torvalds 	WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
45371da177e4SLinus Torvalds 
45381da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsidata_0,message);
45391da177e4SLinus Torvalds 
45401da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
45411da177e4SLinus Torvalds 
45421da177e4SLinus Torvalds 	ACCEPT_MSG(port);
45431da177e4SLinus Torvalds 
45441da177e4SLinus Torvalds 	WR_HARPOON(port+hp_portctrl_0, 0x00);
45451da177e4SLinus Torvalds 
45461da177e4SLinus Torvalds 	if ((message == SMABORT) || (message == SMDEV_RESET) ||
45471da177e4SLinus Torvalds 				(message == SMABORT_TAG) )
45481da177e4SLinus Torvalds 	{
45491da177e4SLinus Torvalds 
45501da177e4SLinus Torvalds 		while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
45511da177e4SLinus Torvalds 
45521da177e4SLinus Torvalds 		if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
45531da177e4SLinus Torvalds 		{
45541da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), BUS_FREE);
45551da177e4SLinus Torvalds 
45561da177e4SLinus Torvalds 			if (currSCCB != NULL)
45571da177e4SLinus Torvalds 			{
45581da177e4SLinus Torvalds 
455947b5d69cSJames Bottomley  				if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
456047b5d69cSJames Bottomley  					((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
456147b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
45621da177e4SLinus Torvalds 				else
456347b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
45641da177e4SLinus Torvalds 
456547b5d69cSJames Bottomley  				FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
45661da177e4SLinus Torvalds 			}
45671da177e4SLinus Torvalds 
45681da177e4SLinus Torvalds 			else
45691da177e4SLinus Torvalds 			{
457047b5d69cSJames Bottomley  				FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
45711da177e4SLinus Torvalds 			}
45721da177e4SLinus Torvalds 		}
45731da177e4SLinus Torvalds 
45741da177e4SLinus Torvalds 		else
45751da177e4SLinus Torvalds 		{
45761da177e4SLinus Torvalds 
457747b5d69cSJames Bottomley  			FPT_sxfrp(port,p_card);
45781da177e4SLinus Torvalds 		}
45791da177e4SLinus Torvalds 	}
45801da177e4SLinus Torvalds 
45811da177e4SLinus Torvalds 	else
45821da177e4SLinus Torvalds 	{
45831da177e4SLinus Torvalds 
45841da177e4SLinus Torvalds 		if(message == SMPARITY)
45851da177e4SLinus Torvalds 		{
45861da177e4SLinus Torvalds 			currSCCB->Sccb_scsimsg = SMNO_OP;
45871da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
45881da177e4SLinus Torvalds 		}
45891da177e4SLinus Torvalds 		else
45901da177e4SLinus Torvalds 		{
459147b5d69cSJames Bottomley  			FPT_sxfrp(port,p_card);
45921da177e4SLinus Torvalds 		}
45931da177e4SLinus Torvalds 	}
45941da177e4SLinus Torvalds }
45951da177e4SLinus Torvalds 
45961da177e4SLinus Torvalds 
45971da177e4SLinus Torvalds /*---------------------------------------------------------------------
45981da177e4SLinus Torvalds  *
45991da177e4SLinus Torvalds  * Function: Message In phase
46001da177e4SLinus Torvalds  *
46011da177e4SLinus Torvalds  * Description: Bring in the message and determine what to do with it.
46021da177e4SLinus Torvalds  *
46031da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
46041da177e4SLinus Torvalds 
460547b5d69cSJames Bottomley  static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
46061da177e4SLinus Torvalds {
46071da177e4SLinus Torvalds 	UCHAR message;
46081da177e4SLinus Torvalds 	PSCCB currSCCB;
46091da177e4SLinus Torvalds 
461047b5d69cSJames Bottomley  	currSCCB = FPT_BL_Card[p_card].currentSCCB;
46111da177e4SLinus Torvalds 
461247b5d69cSJames Bottomley  	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
46131da177e4SLinus Torvalds 	{
46141da177e4SLinus Torvalds 
461547b5d69cSJames Bottomley  		FPT_phaseChkFifo(port, p_card);
46161da177e4SLinus Torvalds 	}
46171da177e4SLinus Torvalds 
46181da177e4SLinus Torvalds 	message = RD_HARPOON(port+hp_scsidata_0);
46191da177e4SLinus Torvalds 	if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
46201da177e4SLinus Torvalds 	{
46211da177e4SLinus Torvalds 
46221da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
46231da177e4SLinus Torvalds 
46241da177e4SLinus Torvalds 	}
46251da177e4SLinus Torvalds 
46261da177e4SLinus Torvalds 	else
46271da177e4SLinus Torvalds 	{
46281da177e4SLinus Torvalds 
462947b5d69cSJames Bottomley  		message = FPT_sfm(port,currSCCB);
46301da177e4SLinus Torvalds 		if (message)
46311da177e4SLinus Torvalds 		{
46321da177e4SLinus Torvalds 
46331da177e4SLinus Torvalds 
463447b5d69cSJames Bottomley  			FPT_sdecm(message,port,p_card);
46351da177e4SLinus Torvalds 
46361da177e4SLinus Torvalds 		}
46371da177e4SLinus Torvalds 		else
46381da177e4SLinus Torvalds 		{
46391da177e4SLinus Torvalds 			if(currSCCB->Sccb_scsimsg != SMPARITY)
46401da177e4SLinus Torvalds 				ACCEPT_MSG(port);
46411da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
46421da177e4SLinus Torvalds 		}
46431da177e4SLinus Torvalds 	}
46441da177e4SLinus Torvalds 
46451da177e4SLinus Torvalds }
46461da177e4SLinus Torvalds 
46471da177e4SLinus Torvalds 
46481da177e4SLinus Torvalds /*---------------------------------------------------------------------
46491da177e4SLinus Torvalds  *
46501da177e4SLinus Torvalds  * Function: Illegal phase
46511da177e4SLinus Torvalds  *
46521da177e4SLinus Torvalds  * Description: Target switched to some illegal phase, so all we can do
46531da177e4SLinus Torvalds  *              is report an error back to the host (if that is possible)
46541da177e4SLinus Torvalds  *              and send an ABORT message to the misbehaving target.
46551da177e4SLinus Torvalds  *
46561da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
46571da177e4SLinus Torvalds 
465847b5d69cSJames Bottomley  static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
46591da177e4SLinus Torvalds {
46601da177e4SLinus Torvalds    PSCCB currSCCB;
46611da177e4SLinus Torvalds 
466247b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
46631da177e4SLinus Torvalds 
46641da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
46651da177e4SLinus Torvalds    if (currSCCB != NULL) {
46661da177e4SLinus Torvalds 
46671da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
46681da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = ABORT_ST;
46691da177e4SLinus Torvalds       currSCCB->Sccb_scsimsg = SMABORT;
46701da177e4SLinus Torvalds       }
46711da177e4SLinus Torvalds 
46721da177e4SLinus Torvalds    ACCEPT_MSG_ATN(port);
46731da177e4SLinus Torvalds }
46741da177e4SLinus Torvalds 
46751da177e4SLinus Torvalds 
46761da177e4SLinus Torvalds 
46771da177e4SLinus Torvalds /*---------------------------------------------------------------------
46781da177e4SLinus Torvalds  *
46791da177e4SLinus Torvalds  * Function: Phase Check FIFO
46801da177e4SLinus Torvalds  *
46811da177e4SLinus Torvalds  * Description: Make sure data has been flushed from both FIFOs and abort
46821da177e4SLinus Torvalds  *              the operations if necessary.
46831da177e4SLinus Torvalds  *
46841da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
46851da177e4SLinus Torvalds 
468647b5d69cSJames Bottomley  static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
46871da177e4SLinus Torvalds {
46881da177e4SLinus Torvalds    ULONG xfercnt;
46891da177e4SLinus Torvalds    PSCCB currSCCB;
46901da177e4SLinus Torvalds 
469147b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
46921da177e4SLinus Torvalds 
46931da177e4SLinus Torvalds    if (currSCCB->Sccb_scsistat == DATA_IN_ST)
46941da177e4SLinus Torvalds       {
46951da177e4SLinus Torvalds 
46961da177e4SLinus Torvalds       while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
46971da177e4SLinus Torvalds 	      (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
46981da177e4SLinus Torvalds 
46991da177e4SLinus Torvalds 
47001da177e4SLinus Torvalds       if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
47011da177e4SLinus Torvalds          {
47021da177e4SLinus Torvalds 	      currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
47031da177e4SLinus Torvalds 
47041da177e4SLinus Torvalds 	      currSCCB->Sccb_XferCnt = 0;
47051da177e4SLinus Torvalds 
47061da177e4SLinus Torvalds 	      if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
47071da177e4SLinus Torvalds 	            (currSCCB->HostStatus == SCCB_COMPLETE))
47081da177e4SLinus Torvalds             {
47091da177e4SLinus Torvalds 	         currSCCB->HostStatus = SCCB_PARITY_ERR;
47101da177e4SLinus Torvalds 	         WRW_HARPOON((port+hp_intstat), PARITY);
47111da177e4SLinus Torvalds 	         }
47121da177e4SLinus Torvalds 
471347b5d69cSJames Bottomley  	      FPT_hostDataXferAbort(port,p_card,currSCCB);
47141da177e4SLinus Torvalds 
471547b5d69cSJames Bottomley  	      FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
47161da177e4SLinus Torvalds 
47171da177e4SLinus Torvalds 	      while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
47181da177e4SLinus Torvalds 	         (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
47191da177e4SLinus Torvalds 
47201da177e4SLinus Torvalds 	      }
47211da177e4SLinus Torvalds       }  /*End Data In specific code. */
47221da177e4SLinus Torvalds 
47231da177e4SLinus Torvalds 
47241da177e4SLinus Torvalds 
47251da177e4SLinus Torvalds    GET_XFER_CNT(port,xfercnt);
47261da177e4SLinus Torvalds 
47271da177e4SLinus Torvalds 
47281da177e4SLinus Torvalds    WR_HARPOON(port+hp_xfercnt_0, 0x00);
47291da177e4SLinus Torvalds 
47301da177e4SLinus Torvalds 
47311da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, 0x00);
47321da177e4SLinus Torvalds 
47331da177e4SLinus Torvalds    currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
47341da177e4SLinus Torvalds 
47351da177e4SLinus Torvalds    currSCCB->Sccb_XferCnt = xfercnt;
47361da177e4SLinus Torvalds 
47371da177e4SLinus Torvalds    if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
47381da177e4SLinus Torvalds       (currSCCB->HostStatus == SCCB_COMPLETE)) {
47391da177e4SLinus Torvalds 
47401da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PARITY_ERR;
47411da177e4SLinus Torvalds       WRW_HARPOON((port+hp_intstat), PARITY);
47421da177e4SLinus Torvalds       }
47431da177e4SLinus Torvalds 
47441da177e4SLinus Torvalds 
474547b5d69cSJames Bottomley     FPT_hostDataXferAbort(port,p_card,currSCCB);
47461da177e4SLinus Torvalds 
47471da177e4SLinus Torvalds 
47481da177e4SLinus Torvalds    WR_HARPOON(port+hp_fifowrite, 0x00);
47491da177e4SLinus Torvalds    WR_HARPOON(port+hp_fiforead, 0x00);
47501da177e4SLinus Torvalds    WR_HARPOON(port+hp_xferstat, 0x00);
47511da177e4SLinus Torvalds 
47521da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
47531da177e4SLinus Torvalds }
47541da177e4SLinus Torvalds 
47551da177e4SLinus Torvalds 
47561da177e4SLinus Torvalds /*---------------------------------------------------------------------
47571da177e4SLinus Torvalds  *
47581da177e4SLinus Torvalds  * Function: Phase Bus Free
47591da177e4SLinus Torvalds  *
47601da177e4SLinus Torvalds  * Description: We just went bus free so figure out if it was
47611da177e4SLinus Torvalds  *              because of command complete or from a disconnect.
47621da177e4SLinus Torvalds  *
47631da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
476447b5d69cSJames Bottomley  static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
47651da177e4SLinus Torvalds {
47661da177e4SLinus Torvalds    PSCCB currSCCB;
47671da177e4SLinus Torvalds 
476847b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
47691da177e4SLinus Torvalds 
47701da177e4SLinus Torvalds    if (currSCCB != NULL)
47711da177e4SLinus Torvalds       {
47721da177e4SLinus Torvalds 
47731da177e4SLinus Torvalds       DISABLE_AUTO(port);
47741da177e4SLinus Torvalds 
47751da177e4SLinus Torvalds 
47761da177e4SLinus Torvalds       if (currSCCB->OperationCode == RESET_COMMAND)
47771da177e4SLinus Torvalds          {
47781da177e4SLinus Torvalds 
477947b5d69cSJames Bottomley  			if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
478047b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
478147b5d69cSJames Bottomley  	   		 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
47821da177e4SLinus Torvalds 			else
478347b5d69cSJames Bottomley  		   	 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
47841da177e4SLinus Torvalds 
478547b5d69cSJames Bottomley  	      FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
47861da177e4SLinus Torvalds 
478747b5d69cSJames Bottomley  	      FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
47881da177e4SLinus Torvalds 
47891da177e4SLinus Torvalds 	      }
47901da177e4SLinus Torvalds 
47911da177e4SLinus Torvalds       else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
47921da177e4SLinus Torvalds 	      {
479347b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
47941da177e4SLinus Torvalds 			         (UCHAR)SYNC_SUPPORTED;
479547b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
47961da177e4SLinus Torvalds 	      }
47971da177e4SLinus Torvalds 
47981da177e4SLinus Torvalds       else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
47991da177e4SLinus Torvalds 	      {
480047b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
480147b5d69cSJames Bottomley  		            (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
48021da177e4SLinus Torvalds 		   TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
48031da177e4SLinus Torvalds 
480447b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
48051da177e4SLinus Torvalds 	      }
48061da177e4SLinus Torvalds 
48071da177e4SLinus Torvalds       else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
48081da177e4SLinus Torvalds 	      {
48091da177e4SLinus Torvalds 	      /* Make sure this is not a phony BUS_FREE.  If we were
48101da177e4SLinus Torvalds 	      reselected or if BUSY is NOT on then this is a
48111da177e4SLinus Torvalds 	      valid BUS FREE.  SRR Wednesday, 5/10/1995.     */
48121da177e4SLinus Torvalds 
48131da177e4SLinus Torvalds 	      if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
48141da177e4SLinus Torvalds 	         (RDW_HARPOON((port+hp_intstat)) & RSEL))
48151da177e4SLinus Torvalds 	         {
481647b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
481747b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
48181da177e4SLinus Torvalds 	         }
48191da177e4SLinus Torvalds 
48201da177e4SLinus Torvalds 	      else
48211da177e4SLinus Torvalds             {
48221da177e4SLinus Torvalds 	         return;
48231da177e4SLinus Torvalds 	         }
48241da177e4SLinus Torvalds          }
48251da177e4SLinus Torvalds 
48261da177e4SLinus Torvalds       else
48271da177e4SLinus Torvalds 	      {
48281da177e4SLinus Torvalds 
48291da177e4SLinus Torvalds 	      currSCCB->Sccb_scsistat = BUS_FREE_ST;
48301da177e4SLinus Torvalds 
48311da177e4SLinus Torvalds          if (!currSCCB->HostStatus)
48321da177e4SLinus Torvalds 	         {
48331da177e4SLinus Torvalds 	         currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
48341da177e4SLinus Torvalds 	         }
48351da177e4SLinus Torvalds 
483647b5d69cSJames Bottomley  			if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
483747b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
483847b5d69cSJames Bottomley  	   		 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
48391da177e4SLinus Torvalds 			else
484047b5d69cSJames Bottomley  		   	 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
48411da177e4SLinus Torvalds 
484247b5d69cSJames Bottomley  	      FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
48431da177e4SLinus Torvalds 	      return;
48441da177e4SLinus Torvalds 	      }
48451da177e4SLinus Torvalds 
48461da177e4SLinus Torvalds 
484747b5d69cSJames Bottomley        FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
48481da177e4SLinus Torvalds 
48491da177e4SLinus Torvalds       } /*end if !=null */
48501da177e4SLinus Torvalds }
48511da177e4SLinus Torvalds 
48521da177e4SLinus Torvalds 
48531da177e4SLinus Torvalds 
48541da177e4SLinus Torvalds 
48551da177e4SLinus Torvalds /*---------------------------------------------------------------------
48561da177e4SLinus Torvalds  *
48571da177e4SLinus Torvalds  * Function: Auto Load Default Map
48581da177e4SLinus Torvalds  *
48591da177e4SLinus Torvalds  * Description: Load the Automation RAM with the defualt map values.
48601da177e4SLinus Torvalds  *
48611da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
486247b5d69cSJames Bottomley  static void FPT_autoLoadDefaultMap(ULONG p_port)
48631da177e4SLinus Torvalds {
48641da177e4SLinus Torvalds    ULONG map_addr;
48651da177e4SLinus Torvalds 
48661da177e4SLinus Torvalds    ARAM_ACCESS(p_port);
48671da177e4SLinus Torvalds    map_addr = p_port + hp_aramBase;
48681da177e4SLinus Torvalds 
48691da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0));  /*ID MESSAGE */
48701da177e4SLinus Torvalds    map_addr +=2;
48711da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20));  /*SIMPLE TAG QUEUEING MSG */
48721da177e4SLinus Torvalds    map_addr +=2;
48731da177e4SLinus Torvalds    WRW_HARPOON(map_addr, RAT_OP);                   /*RESET ATTENTION */
48741da177e4SLinus Torvalds    map_addr +=2;
48751da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00));  /*TAG ID MSG */
48761da177e4SLinus Torvalds    map_addr +=2;
48771da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 0 */
48781da177e4SLinus Torvalds    map_addr +=2;
48791da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 1 */
48801da177e4SLinus Torvalds    map_addr +=2;
48811da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 2 */
48821da177e4SLinus Torvalds    map_addr +=2;
48831da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 3 */
48841da177e4SLinus Torvalds    map_addr +=2;
48851da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 4 */
48861da177e4SLinus Torvalds    map_addr +=2;
48871da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 5 */
48881da177e4SLinus Torvalds    map_addr +=2;
48891da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 6 */
48901da177e4SLinus Torvalds    map_addr +=2;
48911da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 7 */
48921da177e4SLinus Torvalds    map_addr +=2;
48931da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 8 */
48941da177e4SLinus Torvalds    map_addr +=2;
48951da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 9 */
48961da177e4SLinus Torvalds    map_addr +=2;
48971da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 10 */
48981da177e4SLinus Torvalds    map_addr +=2;
48991da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 11 */
49001da177e4SLinus Torvalds    map_addr +=2;
49011da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
49021da177e4SLinus Torvalds    map_addr +=2;
49031da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI));     /*JUMP IF NO DATA IN FIFO */
49041da177e4SLinus Torvalds    map_addr +=2;                                   /*This means AYNC DATA IN */
49051da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+   SSI_IDO_STRT)); /*STOP AND INTERRUPT */
49061da177e4SLinus Torvalds    map_addr +=2;
49071da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT));   /*JUMP IF NOT DATA IN PHZ */
49081da177e4SLinus Torvalds    map_addr +=2;
49091da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  ST));    /*IF NOT MSG IN CHECK 4 DATA IN */
49101da177e4SLinus Torvalds    map_addr +=2;
49111da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x02));  /*SAVE DATA PTR MSG? */
49121da177e4SLinus Torvalds    map_addr +=2;
49131da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   DC));    /*GO CHECK FOR DISCONNECT MSG */
49141da177e4SLinus Torvalds    map_addr +=2;
49151da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+    D_AR1)); /*SAVE DATA PTRS MSG */
49161da177e4SLinus Torvalds    map_addr +=2;
49171da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  ST));    /*IF NOT MSG IN CHECK DATA IN */
49181da177e4SLinus Torvalds    map_addr +=2;
49191da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x04));  /*DISCONNECT MSG? */
49201da177e4SLinus Torvalds    map_addr +=2;
49211da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   UNKNWN));/*UKNKNOWN MSG */
49221da177e4SLinus Torvalds    map_addr +=2;
49231da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+    D_BUCKET));/*XFER DISCONNECT MSG */
49241da177e4SLinus Torvalds    map_addr +=2;
49251da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+          SSI_ITAR_DISC));/*STOP AND INTERRUPT */
49261da177e4SLinus Torvalds    map_addr +=2;
49271da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+  UNKNWN));/*JUMP IF NOT STATUS PHZ. */
49281da177e4SLinus Torvalds    map_addr +=2;
49291da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+  D_AR0));   /*GET STATUS BYTE */
49301da177e4SLinus Torvalds    map_addr +=2;
49311da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  CC));    /*ERROR IF NOT MSG IN PHZ */
49321da177e4SLinus Torvalds    map_addr +=2;
49331da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x00));  /*CHECK FOR CMD COMPLETE MSG. */
49341da177e4SLinus Torvalds    map_addr +=2;
49351da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   CC));    /*ERROR IF NOT CMD COMPLETE MSG. */
49361da177e4SLinus Torvalds    map_addr +=2;
49371da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+  D_BUCKET));/*GET CMD COMPLETE MSG */
49381da177e4SLinus Torvalds    map_addr +=2;
49391da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+       SSI_ICMD_COMP));/*END OF COMMAND */
49401da177e4SLinus Torvalds    map_addr +=2;
49411da177e4SLinus Torvalds 
49421da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN));  /*RECEIVED UNKNOWN MSG BYTE */
49431da177e4SLinus Torvalds    map_addr +=2;
49441da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC));  /*NO COMMAND COMPLETE AFTER STATUS */
49451da177e4SLinus Torvalds    map_addr +=2;
49461da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
49471da177e4SLinus Torvalds    map_addr +=2;
49481da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL));  /*EXPECTED ID/TAG MESSAGES AND */
49491da177e4SLinus Torvalds    map_addr +=2;                             /* DIDN'T GET ONE */
49501da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRR_OP+AR3+  S_IDREG)); /* comp SCSI SEL ID & AR3*/
49511da177e4SLinus Torvalds    map_addr +=2;
49521da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+EQUAL+   0x00));    /*SEL ID OK then Conti. */
49531da177e4SLinus Torvalds    map_addr +=2;
49541da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC));  /*NO COMMAND COMPLETE AFTER STATUS */
49551da177e4SLinus Torvalds 
49561da177e4SLinus Torvalds 
49571da177e4SLinus Torvalds 
49581da177e4SLinus Torvalds    SGRAM_ACCESS(p_port);
49591da177e4SLinus Torvalds }
49601da177e4SLinus Torvalds 
49611da177e4SLinus Torvalds /*---------------------------------------------------------------------
49621da177e4SLinus Torvalds  *
49631da177e4SLinus Torvalds  * Function: Auto Command Complete
49641da177e4SLinus Torvalds  *
49651da177e4SLinus Torvalds  * Description: Post command back to host and find another command
49661da177e4SLinus Torvalds  *              to execute.
49671da177e4SLinus Torvalds  *
49681da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
49691da177e4SLinus Torvalds 
497047b5d69cSJames Bottomley  static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
49711da177e4SLinus Torvalds {
49721da177e4SLinus Torvalds    PSCCB currSCCB;
49731da177e4SLinus Torvalds    UCHAR status_byte;
49741da177e4SLinus Torvalds 
497547b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
49761da177e4SLinus Torvalds 
49771da177e4SLinus Torvalds    status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
49781da177e4SLinus Torvalds 
497947b5d69cSJames Bottomley     FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
49801da177e4SLinus Torvalds 
49811da177e4SLinus Torvalds    if (status_byte != SSGOOD) {
49821da177e4SLinus Torvalds 
49831da177e4SLinus Torvalds       if (status_byte == SSQ_FULL) {
49841da177e4SLinus Torvalds 
49851da177e4SLinus Torvalds 
498647b5d69cSJames Bottomley  			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
498747b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
49881da177e4SLinus Torvalds 			{
498947b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
499047b5d69cSJames Bottomley  				if(FPT_BL_Card[p_card].discQCount != 0)
499147b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQCount--;
499247b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
49931da177e4SLinus Torvalds 			}
49941da177e4SLinus Torvalds 			else
49951da177e4SLinus Torvalds 			{
499647b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
49971da177e4SLinus Torvalds 				if(currSCCB->Sccb_tag)
49981da177e4SLinus Torvalds 				{
499947b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
500047b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
500147b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
50021da177e4SLinus Torvalds 				}else
50031da177e4SLinus Torvalds 				{
500447b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
500547b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
500647b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
50071da177e4SLinus Torvalds 				}
50081da177e4SLinus Torvalds 			}
50091da177e4SLinus Torvalds 
50101da177e4SLinus Torvalds          currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
50111da177e4SLinus Torvalds 
501247b5d69cSJames Bottomley           FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
50131da177e4SLinus Torvalds 
50141da177e4SLinus Torvalds          return;
50151da177e4SLinus Torvalds          }
50161da177e4SLinus Torvalds 
50171da177e4SLinus Torvalds       if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
50181da177e4SLinus Torvalds          {
501947b5d69cSJames Bottomley           FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
50201da177e4SLinus Torvalds             (UCHAR)SYNC_SUPPORTED;
50211da177e4SLinus Torvalds 
502247b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
502347b5d69cSJames Bottomley           FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
50241da177e4SLinus Torvalds 
502547b5d69cSJames Bottomley  			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
502647b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
50271da177e4SLinus Torvalds 			{
502847b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
502947b5d69cSJames Bottomley  				if(FPT_BL_Card[p_card].discQCount != 0)
503047b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQCount--;
503147b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
50321da177e4SLinus Torvalds 			}
50331da177e4SLinus Torvalds 			else
50341da177e4SLinus Torvalds 			{
503547b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
50361da177e4SLinus Torvalds 				if(currSCCB->Sccb_tag)
50371da177e4SLinus Torvalds 				{
503847b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
503947b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
504047b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
50411da177e4SLinus Torvalds 				}else
50421da177e4SLinus Torvalds 				{
504347b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
504447b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
504547b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
50461da177e4SLinus Torvalds 				}
50471da177e4SLinus Torvalds 			}
50481da177e4SLinus Torvalds          return;
50491da177e4SLinus Torvalds 
50501da177e4SLinus Torvalds          }
50511da177e4SLinus Torvalds 
50521da177e4SLinus Torvalds       if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
50531da177e4SLinus Torvalds          {
50541da177e4SLinus Torvalds 
505547b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
505647b5d69cSJames Bottomley  	         (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
50571da177e4SLinus Torvalds 	         TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
50581da177e4SLinus Torvalds 
505947b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
506047b5d69cSJames Bottomley           FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
50611da177e4SLinus Torvalds 
506247b5d69cSJames Bottomley  			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
506347b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
50641da177e4SLinus Torvalds 			{
506547b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
506647b5d69cSJames Bottomley  				if(FPT_BL_Card[p_card].discQCount != 0)
506747b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQCount--;
506847b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
50691da177e4SLinus Torvalds 			}
50701da177e4SLinus Torvalds 			else
50711da177e4SLinus Torvalds 			{
507247b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
50731da177e4SLinus Torvalds 				if(currSCCB->Sccb_tag)
50741da177e4SLinus Torvalds 				{
507547b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
507647b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
507747b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
50781da177e4SLinus Torvalds 				}else
50791da177e4SLinus Torvalds 				{
508047b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
508147b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
508247b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
50831da177e4SLinus Torvalds 				}
50841da177e4SLinus Torvalds 			}
50851da177e4SLinus Torvalds          return;
50861da177e4SLinus Torvalds 
50871da177e4SLinus Torvalds          }
50881da177e4SLinus Torvalds 
50891da177e4SLinus Torvalds 	   if (status_byte == SSCHECK)
50901da177e4SLinus Torvalds 		{
509147b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
50921da177e4SLinus Torvalds 			{
509347b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
50941da177e4SLinus Torvalds 				{
509547b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
50961da177e4SLinus Torvalds 				}
509747b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
50981da177e4SLinus Torvalds 				{
509947b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
51001da177e4SLinus Torvalds 				}
51011da177e4SLinus Torvalds 			}
51021da177e4SLinus Torvalds 		}
51031da177e4SLinus Torvalds 
51041da177e4SLinus Torvalds       if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
51051da177e4SLinus Torvalds 
51061da177e4SLinus Torvalds          currSCCB->SccbStatus = SCCB_ERROR;
51071da177e4SLinus Torvalds          currSCCB->TargetStatus = status_byte;
51081da177e4SLinus Torvalds 
51091da177e4SLinus Torvalds          if (status_byte == SSCHECK) {
51101da177e4SLinus Torvalds 
511147b5d69cSJames Bottomley              FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
511247b5d69cSJames Bottomley                 = 1;
51131da177e4SLinus Torvalds 
51141da177e4SLinus Torvalds 
51151da177e4SLinus Torvalds             if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
51161da177e4SLinus Torvalds 
51171da177e4SLinus Torvalds                if (currSCCB->RequestSenseLength == 0)
51181da177e4SLinus Torvalds                   currSCCB->RequestSenseLength = 14;
51191da177e4SLinus Torvalds 
512047b5d69cSJames Bottomley                 FPT_ssenss(&FPT_BL_Card[p_card]);
512147b5d69cSJames Bottomley                 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
51221da177e4SLinus Torvalds 
512347b5d69cSJames Bottomley   					if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
512447b5d69cSJames Bottomley  						((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
51251da177e4SLinus Torvalds 					{
512647b5d69cSJames Bottomley  			         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
512747b5d69cSJames Bottomley  						if(FPT_BL_Card[p_card].discQCount != 0)
512847b5d69cSJames Bottomley  							FPT_BL_Card[p_card].discQCount--;
512947b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
51301da177e4SLinus Torvalds 					}
51311da177e4SLinus Torvalds 					else
51321da177e4SLinus Torvalds 					{
513347b5d69cSJames Bottomley  	   		      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
51341da177e4SLinus Torvalds 						if(currSCCB->Sccb_tag)
51351da177e4SLinus Torvalds 						{
513647b5d69cSJames Bottomley  							if(FPT_BL_Card[p_card].discQCount != 0)
513747b5d69cSJames Bottomley  								FPT_BL_Card[p_card].discQCount--;
513847b5d69cSJames Bottomley  							FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
51391da177e4SLinus Torvalds 						}else
51401da177e4SLinus Torvalds 						{
514147b5d69cSJames Bottomley  							if(FPT_BL_Card[p_card].discQCount != 0)
514247b5d69cSJames Bottomley  								FPT_BL_Card[p_card].discQCount--;
514347b5d69cSJames Bottomley  							FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
51441da177e4SLinus Torvalds 						}
51451da177e4SLinus Torvalds 					}
51461da177e4SLinus Torvalds                return;
51471da177e4SLinus Torvalds                }
51481da177e4SLinus Torvalds             }
514947b5d69cSJames Bottomley           }
515047b5d69cSJames Bottomley        }
515147b5d69cSJames Bottomley  
515247b5d69cSJames Bottomley  
515347b5d69cSJames Bottomley  	if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
515447b5d69cSJames Bottomley  		((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
515547b5d69cSJames Bottomley  	   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
51561da177e4SLinus Torvalds 	else
515747b5d69cSJames Bottomley  	   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
515847b5d69cSJames Bottomley  
515947b5d69cSJames Bottomley  
516047b5d69cSJames Bottomley     FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
51611da177e4SLinus Torvalds }
51621da177e4SLinus Torvalds 
51631da177e4SLinus Torvalds #define SHORT_WAIT   0x0000000F
51641da177e4SLinus Torvalds #define LONG_WAIT    0x0000FFFFL
51651da177e4SLinus Torvalds 
51661da177e4SLinus Torvalds 
51671da177e4SLinus Torvalds /*---------------------------------------------------------------------
51681da177e4SLinus Torvalds  *
51691da177e4SLinus Torvalds  * Function: Data Transfer Processor
51701da177e4SLinus Torvalds  *
51711da177e4SLinus Torvalds  * Description: This routine performs two tasks.
51721da177e4SLinus Torvalds  *              (1) Start data transfer by calling HOST_DATA_XFER_START
51731da177e4SLinus Torvalds  *              function.  Once data transfer is started, (2) Depends
51741da177e4SLinus Torvalds  *              on the type of data transfer mode Scatter/Gather mode
51751da177e4SLinus Torvalds  *              or NON Scatter/Gather mode.  In NON Scatter/Gather mode,
51761da177e4SLinus Torvalds  *              this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
51771da177e4SLinus Torvalds  *              data transfer done.  In Scatter/Gather mode, this routine
51781da177e4SLinus Torvalds  *              checks bus master command complete and dual rank busy
51791da177e4SLinus Torvalds  *              bit to keep chaining SC transfer command.  Similarly,
51801da177e4SLinus Torvalds  *              in Scatter/Gather mode, it checks Sccb_MGRFlag
51811da177e4SLinus Torvalds  *              (F_HOST_XFER_ACT bit) for data transfer done.
51821da177e4SLinus Torvalds  *
51831da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
51841da177e4SLinus Torvalds 
518547b5d69cSJames Bottomley  static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
51861da177e4SLinus Torvalds {
51871da177e4SLinus Torvalds    PSCCB currSCCB;
51881da177e4SLinus Torvalds 
51891da177e4SLinus Torvalds    currSCCB = pCurrCard->currentSCCB;
51901da177e4SLinus Torvalds 
51911da177e4SLinus Torvalds       if (currSCCB->Sccb_XferState & F_SG_XFER)
51921da177e4SLinus Torvalds 			{
51931da177e4SLinus Torvalds 			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
51941da177e4SLinus Torvalds 
51951da177e4SLinus Torvalds 				{
51961da177e4SLinus Torvalds 		   	currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
51971da177e4SLinus Torvalds          	currSCCB->Sccb_SGoffset = 0x00;
51981da177e4SLinus Torvalds  				}
51991da177e4SLinus Torvalds 			pCurrCard->globalFlags |= F_HOST_XFER_ACT;
52001da177e4SLinus Torvalds 
520147b5d69cSJames Bottomley           FPT_busMstrSGDataXferStart(port, currSCCB);
52021da177e4SLinus Torvalds 			}
52031da177e4SLinus Torvalds 
52041da177e4SLinus Torvalds       else
52051da177e4SLinus Torvalds 			{
52061da177e4SLinus Torvalds 			if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
52071da177e4SLinus Torvalds 				{
52081da177e4SLinus Torvalds 				pCurrCard->globalFlags |= F_HOST_XFER_ACT;
52091da177e4SLinus Torvalds 
521047b5d69cSJames Bottomley           	FPT_busMstrDataXferStart(port, currSCCB);
52111da177e4SLinus Torvalds          	}
52121da177e4SLinus Torvalds 			}
52131da177e4SLinus Torvalds }
52141da177e4SLinus Torvalds 
52151da177e4SLinus Torvalds 
52161da177e4SLinus Torvalds /*---------------------------------------------------------------------
52171da177e4SLinus Torvalds  *
52181da177e4SLinus Torvalds  * Function: BusMaster Scatter Gather Data Transfer Start
52191da177e4SLinus Torvalds  *
52201da177e4SLinus Torvalds  * Description:
52211da177e4SLinus Torvalds  *
52221da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
522347b5d69cSJames Bottomley  static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
52241da177e4SLinus Torvalds {
52251da177e4SLinus Torvalds    ULONG count,addr,tmpSGCnt;
52261da177e4SLinus Torvalds    UINT sg_index;
52271da177e4SLinus Torvalds    UCHAR sg_count, i;
52281da177e4SLinus Torvalds    ULONG reg_offset;
52291da177e4SLinus Torvalds 
52301da177e4SLinus Torvalds 
52311da177e4SLinus Torvalds    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
52321da177e4SLinus Torvalds 
52331da177e4SLinus Torvalds       count =  ((ULONG) HOST_RD_CMD)<<24;
52341da177e4SLinus Torvalds       }
52351da177e4SLinus Torvalds 
52361da177e4SLinus Torvalds    else {
52371da177e4SLinus Torvalds       count =  ((ULONG) HOST_WRT_CMD)<<24;
52381da177e4SLinus Torvalds       }
52391da177e4SLinus Torvalds 
52401da177e4SLinus Torvalds    sg_count = 0;
52411da177e4SLinus Torvalds    tmpSGCnt = 0;
52421da177e4SLinus Torvalds    sg_index = pcurrSCCB->Sccb_sgseg;
52431da177e4SLinus Torvalds    reg_offset = hp_aramBase;
52441da177e4SLinus Torvalds 
52451da177e4SLinus Torvalds 
52461da177e4SLinus Torvalds 	i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
52471da177e4SLinus Torvalds 
52481da177e4SLinus Torvalds 
52491da177e4SLinus Torvalds 	WR_HARPOON(p_port+hp_page_ctrl, i);
52501da177e4SLinus Torvalds 
52511da177e4SLinus Torvalds    while ((sg_count < (UCHAR)SG_BUF_CNT) &&
52521da177e4SLinus Torvalds       ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
52531da177e4SLinus Torvalds 
52541da177e4SLinus Torvalds       tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
52551da177e4SLinus Torvalds          (sg_index * 2));
52561da177e4SLinus Torvalds 
52571da177e4SLinus Torvalds       count |= *(((ULONG *)pcurrSCCB->DataPointer)+
52581da177e4SLinus Torvalds          (sg_index * 2));
52591da177e4SLinus Torvalds 
52601da177e4SLinus Torvalds       addr = *(((ULONG *)pcurrSCCB->DataPointer)+
52611da177e4SLinus Torvalds          ((sg_index * 2) + 1));
52621da177e4SLinus Torvalds 
52631da177e4SLinus Torvalds 
52641da177e4SLinus Torvalds       if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
52651da177e4SLinus Torvalds 
52661da177e4SLinus Torvalds          addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
52671da177e4SLinus Torvalds          count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
52681da177e4SLinus Torvalds 
52691da177e4SLinus Torvalds          tmpSGCnt = count & 0x00FFFFFFL;
52701da177e4SLinus Torvalds          }
52711da177e4SLinus Torvalds 
52721da177e4SLinus Torvalds       WR_HARP32(p_port,reg_offset,addr);
52731da177e4SLinus Torvalds       reg_offset +=4;
52741da177e4SLinus Torvalds 
52751da177e4SLinus Torvalds       WR_HARP32(p_port,reg_offset,count);
52761da177e4SLinus Torvalds       reg_offset +=4;
52771da177e4SLinus Torvalds 
52781da177e4SLinus Torvalds       count &= 0xFF000000L;
52791da177e4SLinus Torvalds       sg_index++;
52801da177e4SLinus Torvalds       sg_count++;
52811da177e4SLinus Torvalds 
52821da177e4SLinus Torvalds       } /*End While */
52831da177e4SLinus Torvalds 
52841da177e4SLinus Torvalds    pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
52851da177e4SLinus Torvalds 
52861da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
52871da177e4SLinus Torvalds 
52881da177e4SLinus Torvalds    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
52891da177e4SLinus Torvalds 
52901da177e4SLinus Torvalds       WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
52911da177e4SLinus Torvalds 
52921da177e4SLinus Torvalds 
52931da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
52941da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
52951da177e4SLinus Torvalds       }
52961da177e4SLinus Torvalds 
52971da177e4SLinus Torvalds    else {
52981da177e4SLinus Torvalds 
52991da177e4SLinus Torvalds 
53001da177e4SLinus Torvalds       if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
53011da177e4SLinus Torvalds          (tmpSGCnt & 0x000000001))
53021da177e4SLinus Torvalds          {
53031da177e4SLinus Torvalds 
53041da177e4SLinus Torvalds          pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
53051da177e4SLinus Torvalds          tmpSGCnt--;
53061da177e4SLinus Torvalds          }
53071da177e4SLinus Torvalds 
53081da177e4SLinus Torvalds 
53091da177e4SLinus Torvalds       WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
53101da177e4SLinus Torvalds 
53111da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
53121da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
53131da177e4SLinus Torvalds       }
53141da177e4SLinus Torvalds 
53151da177e4SLinus Torvalds 
53161da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
53171da177e4SLinus Torvalds 
53181da177e4SLinus Torvalds }
53191da177e4SLinus Torvalds 
53201da177e4SLinus Torvalds 
53211da177e4SLinus Torvalds /*---------------------------------------------------------------------
53221da177e4SLinus Torvalds  *
53231da177e4SLinus Torvalds  * Function: BusMaster Data Transfer Start
53241da177e4SLinus Torvalds  *
53251da177e4SLinus Torvalds  * Description:
53261da177e4SLinus Torvalds  *
53271da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
532847b5d69cSJames Bottomley  static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
53291da177e4SLinus Torvalds {
53301da177e4SLinus Torvalds    ULONG addr,count;
53311da177e4SLinus Torvalds 
53321da177e4SLinus Torvalds    if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
53331da177e4SLinus Torvalds 
53341da177e4SLinus Torvalds       count = pcurrSCCB->Sccb_XferCnt;
53351da177e4SLinus Torvalds 
53361da177e4SLinus Torvalds       addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
53371da177e4SLinus Torvalds       }
53381da177e4SLinus Torvalds 
53391da177e4SLinus Torvalds    else {
53401da177e4SLinus Torvalds       addr = pcurrSCCB->SensePointer;
53411da177e4SLinus Torvalds       count = pcurrSCCB->RequestSenseLength;
53421da177e4SLinus Torvalds 
53431da177e4SLinus Torvalds       }
53441da177e4SLinus Torvalds 
53451da177e4SLinus Torvalds    HP_SETUP_ADDR_CNT(p_port,addr,count);
53461da177e4SLinus Torvalds 
53471da177e4SLinus Torvalds 
53481da177e4SLinus Torvalds    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
53491da177e4SLinus Torvalds 
53501da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
53511da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
53521da177e4SLinus Torvalds 
53531da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_xfer_cmd,
53541da177e4SLinus Torvalds          (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
53551da177e4SLinus Torvalds       }
53561da177e4SLinus Torvalds 
53571da177e4SLinus Torvalds    else {
53581da177e4SLinus Torvalds 
53591da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
53601da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
53611da177e4SLinus Torvalds 
53621da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_xfer_cmd,
53631da177e4SLinus Torvalds          (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
53641da177e4SLinus Torvalds 
53651da177e4SLinus Torvalds       }
53661da177e4SLinus Torvalds }
53671da177e4SLinus Torvalds 
53681da177e4SLinus Torvalds 
53691da177e4SLinus Torvalds /*---------------------------------------------------------------------
53701da177e4SLinus Torvalds  *
53711da177e4SLinus Torvalds  * Function: BusMaster Timeout Handler
53721da177e4SLinus Torvalds  *
53731da177e4SLinus Torvalds  * Description: This function is called after a bus master command busy time
53741da177e4SLinus Torvalds  *               out is detected.  This routines issue halt state machine
53751da177e4SLinus Torvalds  *               with a software time out for command busy.  If command busy
53761da177e4SLinus Torvalds  *               is still asserted at the end of the time out, it issues
53771da177e4SLinus Torvalds  *               hard abort with another software time out.  It hard abort
53781da177e4SLinus Torvalds  *               command busy is also time out, it'll just give up.
53791da177e4SLinus Torvalds  *
53801da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
538147b5d69cSJames Bottomley  static UCHAR FPT_busMstrTimeOut(ULONG p_port)
53821da177e4SLinus Torvalds {
53831da177e4SLinus Torvalds    ULONG timeout;
53841da177e4SLinus Torvalds 
53851da177e4SLinus Torvalds    timeout = LONG_WAIT;
53861da177e4SLinus Torvalds 
53871da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
53881da177e4SLinus Torvalds 
53891da177e4SLinus Torvalds    while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
53901da177e4SLinus Torvalds 
53911da177e4SLinus Torvalds 
53921da177e4SLinus Torvalds 
53931da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
53941da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
53951da177e4SLinus Torvalds 
53961da177e4SLinus Torvalds       timeout = LONG_WAIT;
53971da177e4SLinus Torvalds       while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
53981da177e4SLinus Torvalds       }
53991da177e4SLinus Torvalds 
54001da177e4SLinus Torvalds    RD_HARPOON(p_port+hp_int_status);           /*Clear command complete */
54011da177e4SLinus Torvalds 
54021da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
540347b5d69cSJames Bottomley        return(1);
54041da177e4SLinus Torvalds       }
54051da177e4SLinus Torvalds 
54061da177e4SLinus Torvalds    else {
540747b5d69cSJames Bottomley        return(0);
54081da177e4SLinus Torvalds       }
54091da177e4SLinus Torvalds }
54101da177e4SLinus Torvalds 
54111da177e4SLinus Torvalds 
54121da177e4SLinus Torvalds /*---------------------------------------------------------------------
54131da177e4SLinus Torvalds  *
54141da177e4SLinus Torvalds  * Function: Host Data Transfer Abort
54151da177e4SLinus Torvalds  *
54161da177e4SLinus Torvalds  * Description: Abort any in progress transfer.
54171da177e4SLinus Torvalds  *
54181da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
541947b5d69cSJames Bottomley  static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
54201da177e4SLinus Torvalds {
54211da177e4SLinus Torvalds 
54221da177e4SLinus Torvalds    ULONG timeout;
54231da177e4SLinus Torvalds    ULONG remain_cnt;
54241da177e4SLinus Torvalds    UINT sg_ptr;
54251da177e4SLinus Torvalds 
542647b5d69cSJames Bottomley     FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
54271da177e4SLinus Torvalds 
54281da177e4SLinus Torvalds    if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
54291da177e4SLinus Torvalds 
54301da177e4SLinus Torvalds 
54311da177e4SLinus Torvalds       if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
54321da177e4SLinus Torvalds 
54331da177e4SLinus Torvalds          WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
54341da177e4SLinus Torvalds          timeout = LONG_WAIT;
54351da177e4SLinus Torvalds 
54361da177e4SLinus Torvalds          while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
54371da177e4SLinus Torvalds 
54381da177e4SLinus Torvalds          WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
54391da177e4SLinus Torvalds 
54401da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
54411da177e4SLinus Torvalds 
544247b5d69cSJames Bottomley              if (FPT_busMstrTimeOut(port)) {
54431da177e4SLinus Torvalds 
54441da177e4SLinus Torvalds                if (pCurrSCCB->HostStatus == 0x00)
54451da177e4SLinus Torvalds 
54461da177e4SLinus Torvalds                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
54471da177e4SLinus Torvalds 
54481da177e4SLinus Torvalds                }
54491da177e4SLinus Torvalds 
54501da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
54511da177e4SLinus Torvalds 
54521da177e4SLinus Torvalds                if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
54531da177e4SLinus Torvalds 
54541da177e4SLinus Torvalds                   if (pCurrSCCB->HostStatus == 0x00)
54551da177e4SLinus Torvalds 
54561da177e4SLinus Torvalds                      {
54571da177e4SLinus Torvalds                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
54581da177e4SLinus Torvalds                      }
54591da177e4SLinus Torvalds             }
54601da177e4SLinus Torvalds          }
54611da177e4SLinus Torvalds       }
54621da177e4SLinus Torvalds 
54631da177e4SLinus Torvalds    else if (pCurrSCCB->Sccb_XferCnt) {
54641da177e4SLinus Torvalds 
54651da177e4SLinus Torvalds       if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
54661da177e4SLinus Torvalds 
54671da177e4SLinus Torvalds 
54681da177e4SLinus Torvalds               WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
54691da177e4SLinus Torvalds             ~SCATTER_EN));
54701da177e4SLinus Torvalds 
54711da177e4SLinus Torvalds          WR_HARPOON(port+hp_sg_addr,0x00);
54721da177e4SLinus Torvalds 
54731da177e4SLinus Torvalds          sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
54741da177e4SLinus Torvalds 
54751da177e4SLinus Torvalds          if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
54761da177e4SLinus Torvalds 
54771da177e4SLinus Torvalds             sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
54781da177e4SLinus Torvalds             }
54791da177e4SLinus Torvalds 
54801da177e4SLinus Torvalds          remain_cnt = pCurrSCCB->Sccb_XferCnt;
54811da177e4SLinus Torvalds 
54821da177e4SLinus Torvalds          while (remain_cnt < 0x01000000L) {
54831da177e4SLinus Torvalds 
54841da177e4SLinus Torvalds             sg_ptr--;
54851da177e4SLinus Torvalds 
54861da177e4SLinus Torvalds             if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
54871da177e4SLinus Torvalds                DataPointer) + (sg_ptr * 2)))) {
54881da177e4SLinus Torvalds 
54891da177e4SLinus Torvalds                remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
54901da177e4SLinus Torvalds                   DataPointer) + (sg_ptr * 2)));
54911da177e4SLinus Torvalds                }
54921da177e4SLinus Torvalds 
54931da177e4SLinus Torvalds             else {
54941da177e4SLinus Torvalds 
54951da177e4SLinus Torvalds                break;
54961da177e4SLinus Torvalds                }
54971da177e4SLinus Torvalds             }
54981da177e4SLinus Torvalds 
54991da177e4SLinus Torvalds 
55001da177e4SLinus Torvalds 
55011da177e4SLinus Torvalds          if (remain_cnt < 0x01000000L) {
55021da177e4SLinus Torvalds 
55031da177e4SLinus Torvalds 
55041da177e4SLinus Torvalds             pCurrSCCB->Sccb_SGoffset = remain_cnt;
55051da177e4SLinus Torvalds 
55061da177e4SLinus Torvalds             pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
55071da177e4SLinus Torvalds 
55081da177e4SLinus Torvalds 
55091da177e4SLinus Torvalds             if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
55101da177e4SLinus Torvalds                 && (remain_cnt == 0))
55111da177e4SLinus Torvalds 
55121da177e4SLinus Torvalds                pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
55131da177e4SLinus Torvalds             }
55141da177e4SLinus Torvalds 
55151da177e4SLinus Torvalds          else {
55161da177e4SLinus Torvalds 
55171da177e4SLinus Torvalds 
55181da177e4SLinus Torvalds             if (pCurrSCCB->HostStatus == 0x00) {
55191da177e4SLinus Torvalds 
55201da177e4SLinus Torvalds                pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
55211da177e4SLinus Torvalds                }
55221da177e4SLinus Torvalds             }
55231da177e4SLinus Torvalds          }
55241da177e4SLinus Torvalds 
55251da177e4SLinus Torvalds 
55261da177e4SLinus Torvalds       if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
55271da177e4SLinus Torvalds 
55281da177e4SLinus Torvalds 
55291da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
55301da177e4SLinus Torvalds 
553147b5d69cSJames Bottomley              FPT_busMstrTimeOut(port);
55321da177e4SLinus Torvalds             }
55331da177e4SLinus Torvalds 
55341da177e4SLinus Torvalds          else {
55351da177e4SLinus Torvalds 
55361da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
55371da177e4SLinus Torvalds 
55381da177e4SLinus Torvalds                if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
55391da177e4SLinus Torvalds 
55401da177e4SLinus Torvalds                   if (pCurrSCCB->HostStatus == 0x00) {
55411da177e4SLinus Torvalds 
55421da177e4SLinus Torvalds                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
55431da177e4SLinus Torvalds                      }
55441da177e4SLinus Torvalds                   }
55451da177e4SLinus Torvalds                }
55461da177e4SLinus Torvalds 
55471da177e4SLinus Torvalds             }
55481da177e4SLinus Torvalds          }
55491da177e4SLinus Torvalds 
55501da177e4SLinus Torvalds       else {
55511da177e4SLinus Torvalds 
55521da177e4SLinus Torvalds 
55531da177e4SLinus Torvalds          if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
55541da177e4SLinus Torvalds 
55551da177e4SLinus Torvalds             timeout = SHORT_WAIT;
55561da177e4SLinus Torvalds 
55571da177e4SLinus Torvalds             while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
55581da177e4SLinus Torvalds                ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
55591da177e4SLinus Torvalds                timeout--) {}
55601da177e4SLinus Torvalds             }
55611da177e4SLinus Torvalds 
55621da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
55631da177e4SLinus Torvalds 
55641da177e4SLinus Torvalds             WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
55651da177e4SLinus Torvalds                FLUSH_XFER_CNTR));
55661da177e4SLinus Torvalds 
55671da177e4SLinus Torvalds             timeout = LONG_WAIT;
55681da177e4SLinus Torvalds 
55691da177e4SLinus Torvalds             while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
55701da177e4SLinus Torvalds                timeout--) {}
55711da177e4SLinus Torvalds 
55721da177e4SLinus Torvalds             WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
55731da177e4SLinus Torvalds                ~FLUSH_XFER_CNTR));
55741da177e4SLinus Torvalds 
55751da177e4SLinus Torvalds 
55761da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
55771da177e4SLinus Torvalds 
55781da177e4SLinus Torvalds                if (pCurrSCCB->HostStatus == 0x00) {
55791da177e4SLinus Torvalds 
55801da177e4SLinus Torvalds                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
55811da177e4SLinus Torvalds                   }
55821da177e4SLinus Torvalds 
558347b5d69cSJames Bottomley                 FPT_busMstrTimeOut(port);
55841da177e4SLinus Torvalds                }
55851da177e4SLinus Torvalds             }
55861da177e4SLinus Torvalds 
55871da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
55881da177e4SLinus Torvalds 
55891da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
55901da177e4SLinus Torvalds 
55911da177e4SLinus Torvalds                if (pCurrSCCB->HostStatus == 0x00) {
55921da177e4SLinus Torvalds 
55931da177e4SLinus Torvalds                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
55941da177e4SLinus Torvalds                   }
55951da177e4SLinus Torvalds                }
55961da177e4SLinus Torvalds             }
55971da177e4SLinus Torvalds          }
55981da177e4SLinus Torvalds 
55991da177e4SLinus Torvalds       }
56001da177e4SLinus Torvalds 
56011da177e4SLinus Torvalds    else {
56021da177e4SLinus Torvalds 
56031da177e4SLinus Torvalds 
56041da177e4SLinus Torvalds       if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
56051da177e4SLinus Torvalds 
56061da177e4SLinus Torvalds          timeout = LONG_WAIT;
56071da177e4SLinus Torvalds 
56081da177e4SLinus Torvalds          while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
56091da177e4SLinus Torvalds 
56101da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
56111da177e4SLinus Torvalds 
56121da177e4SLinus Torvalds             if (pCurrSCCB->HostStatus == 0x00) {
56131da177e4SLinus Torvalds 
56141da177e4SLinus Torvalds                pCurrSCCB->HostStatus = SCCB_BM_ERR;
56151da177e4SLinus Torvalds                }
56161da177e4SLinus Torvalds 
561747b5d69cSJames Bottomley              FPT_busMstrTimeOut(port);
56181da177e4SLinus Torvalds             }
56191da177e4SLinus Torvalds          }
56201da177e4SLinus Torvalds 
56211da177e4SLinus Torvalds 
56221da177e4SLinus Torvalds       if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
56231da177e4SLinus Torvalds 
56241da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
56251da177e4SLinus Torvalds 
56261da177e4SLinus Torvalds             if (pCurrSCCB->HostStatus == 0x00) {
56271da177e4SLinus Torvalds 
56281da177e4SLinus Torvalds                pCurrSCCB->HostStatus = SCCB_BM_ERR;
56291da177e4SLinus Torvalds                }
56301da177e4SLinus Torvalds             }
56311da177e4SLinus Torvalds 
56321da177e4SLinus Torvalds          }
56331da177e4SLinus Torvalds 
56341da177e4SLinus Torvalds       if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
56351da177e4SLinus Torvalds 
56361da177e4SLinus Torvalds          WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
56371da177e4SLinus Torvalds                  ~SCATTER_EN));
56381da177e4SLinus Torvalds 
56391da177e4SLinus Torvalds          WR_HARPOON(port+hp_sg_addr,0x00);
56401da177e4SLinus Torvalds 
56411da177e4SLinus Torvalds          pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
56421da177e4SLinus Torvalds 
56431da177e4SLinus Torvalds          pCurrSCCB->Sccb_SGoffset = 0x00;
56441da177e4SLinus Torvalds 
56451da177e4SLinus Torvalds 
56461da177e4SLinus Torvalds          if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
56471da177e4SLinus Torvalds             pCurrSCCB->DataLength) {
56481da177e4SLinus Torvalds 
56491da177e4SLinus Torvalds             pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
56501da177e4SLinus Torvalds 
56511da177e4SLinus Torvalds             pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
56521da177e4SLinus Torvalds 
56531da177e4SLinus Torvalds             }
56541da177e4SLinus Torvalds          }
56551da177e4SLinus Torvalds 
56561da177e4SLinus Torvalds       else {
56571da177e4SLinus Torvalds 
56581da177e4SLinus Torvalds          if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
56591da177e4SLinus Torvalds 
56601da177e4SLinus Torvalds             pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
56611da177e4SLinus Torvalds          }
56621da177e4SLinus Torvalds       }
56631da177e4SLinus Torvalds 
56641da177e4SLinus Torvalds    WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
56651da177e4SLinus Torvalds }
56661da177e4SLinus Torvalds 
56671da177e4SLinus Torvalds 
56681da177e4SLinus Torvalds 
56691da177e4SLinus Torvalds /*---------------------------------------------------------------------
56701da177e4SLinus Torvalds  *
56711da177e4SLinus Torvalds  * Function: Host Data Transfer Restart
56721da177e4SLinus Torvalds  *
56731da177e4SLinus Torvalds  * Description: Reset the available count due to a restore data
56741da177e4SLinus Torvalds  *              pointers message.
56751da177e4SLinus Torvalds  *
56761da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
567747b5d69cSJames Bottomley  static void FPT_hostDataXferRestart(PSCCB currSCCB)
56781da177e4SLinus Torvalds {
56791da177e4SLinus Torvalds    ULONG data_count;
56801da177e4SLinus Torvalds    UINT  sg_index;
56811da177e4SLinus Torvalds    ULONG *sg_ptr;
56821da177e4SLinus Torvalds 
56831da177e4SLinus Torvalds    if (currSCCB->Sccb_XferState & F_SG_XFER) {
56841da177e4SLinus Torvalds 
56851da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = 0;
56861da177e4SLinus Torvalds 
56871da177e4SLinus Torvalds       sg_index = 0xffff;         /*Index by long words into sg list. */
56881da177e4SLinus Torvalds       data_count = 0;            /*Running count of SG xfer counts. */
56891da177e4SLinus Torvalds 
56901da177e4SLinus Torvalds       sg_ptr = (ULONG *)currSCCB->DataPointer;
56911da177e4SLinus Torvalds 
56921da177e4SLinus Torvalds       while (data_count < currSCCB->Sccb_ATC) {
56931da177e4SLinus Torvalds 
56941da177e4SLinus Torvalds          sg_index++;
56951da177e4SLinus Torvalds          data_count += *(sg_ptr+(sg_index * 2));
56961da177e4SLinus Torvalds          }
56971da177e4SLinus Torvalds 
56981da177e4SLinus Torvalds       if (data_count == currSCCB->Sccb_ATC) {
56991da177e4SLinus Torvalds 
57001da177e4SLinus Torvalds          currSCCB->Sccb_SGoffset = 0;
57011da177e4SLinus Torvalds          sg_index++;
57021da177e4SLinus Torvalds          }
57031da177e4SLinus Torvalds 
57041da177e4SLinus Torvalds       else {
57051da177e4SLinus Torvalds          currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
57061da177e4SLinus Torvalds          }
57071da177e4SLinus Torvalds 
57081da177e4SLinus Torvalds       currSCCB->Sccb_sgseg = (USHORT)sg_index;
57091da177e4SLinus Torvalds       }
57101da177e4SLinus Torvalds 
57111da177e4SLinus Torvalds    else {
57121da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
57131da177e4SLinus Torvalds       }
57141da177e4SLinus Torvalds }
57151da177e4SLinus Torvalds 
57161da177e4SLinus Torvalds 
57171da177e4SLinus Torvalds 
57181da177e4SLinus Torvalds /*---------------------------------------------------------------------
57191da177e4SLinus Torvalds  *
572047b5d69cSJames Bottomley   * Function: FPT_scini
57211da177e4SLinus Torvalds  *
57221da177e4SLinus Torvalds  * Description: Setup all data structures necessary for SCAM selection.
57231da177e4SLinus Torvalds  *
57241da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
57251da177e4SLinus Torvalds 
572647b5d69cSJames Bottomley  static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
57271da177e4SLinus Torvalds {
57281da177e4SLinus Torvalds 
57291da177e4SLinus Torvalds    UCHAR loser,assigned_id;
57301da177e4SLinus Torvalds    ULONG p_port;
57311da177e4SLinus Torvalds 
57321da177e4SLinus Torvalds    UCHAR i,k,ScamFlg ;
57331da177e4SLinus Torvalds    PSCCBcard currCard;
57341da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
57351da177e4SLinus Torvalds 
573647b5d69cSJames Bottomley     currCard = &FPT_BL_Card[p_card];
57371da177e4SLinus Torvalds    p_port = currCard->ioPort;
57381da177e4SLinus Torvalds 	pCurrNvRam = currCard->pNvRamInfo;
57391da177e4SLinus Torvalds 
57401da177e4SLinus Torvalds 
57411da177e4SLinus Torvalds 	if(pCurrNvRam){
57421da177e4SLinus Torvalds 		ScamFlg = pCurrNvRam->niScamConf;
57431da177e4SLinus Torvalds 		i = pCurrNvRam->niSysConf;
57441da177e4SLinus Torvalds 	}
57451da177e4SLinus Torvalds 	else{
574647b5d69cSJames Bottomley  	   ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
574747b5d69cSJames Bottomley  	   i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
57481da177e4SLinus Torvalds 	}
57491da177e4SLinus Torvalds 	if(!(i & 0x02))	/* check if reset bus in AutoSCSI parameter set */
57501da177e4SLinus Torvalds 		return;
57511da177e4SLinus Torvalds 
575247b5d69cSJames Bottomley     FPT_inisci(p_card,p_port, p_our_id);
57531da177e4SLinus Torvalds 
57541da177e4SLinus Torvalds    /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
57551da177e4SLinus Torvalds       too slow to return to SCAM selection */
57561da177e4SLinus Torvalds 
57571da177e4SLinus Torvalds    /* if (p_power_up)
575847b5d69cSJames Bottomley           FPT_Wait1Second(p_port);
57591da177e4SLinus Torvalds       else
576047b5d69cSJames Bottomley           FPT_Wait(p_port, TO_250ms); */
57611da177e4SLinus Torvalds 
576247b5d69cSJames Bottomley     FPT_Wait1Second(p_port);
57631da177e4SLinus Torvalds 
57641da177e4SLinus Torvalds    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
57651da177e4SLinus Torvalds       {
576647b5d69cSJames Bottomley        while (!(FPT_scarb(p_port,INIT_SELTD))) {}
57671da177e4SLinus Torvalds 
576847b5d69cSJames Bottomley        FPT_scsel(p_port);
57691da177e4SLinus Torvalds 
57701da177e4SLinus Torvalds       do {
577147b5d69cSJames Bottomley           FPT_scxferc(p_port,SYNC_PTRN);
577247b5d69cSJames Bottomley           FPT_scxferc(p_port,DOM_MSTR);
577347b5d69cSJames Bottomley           loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
57741da177e4SLinus Torvalds          } while ( loser == 0xFF );
57751da177e4SLinus Torvalds 
577647b5d69cSJames Bottomley        FPT_scbusf(p_port);
57771da177e4SLinus Torvalds 
57781da177e4SLinus Torvalds       if ((p_power_up) && (!loser))
57791da177e4SLinus Torvalds          {
578047b5d69cSJames Bottomley           FPT_sresb(p_port,p_card);
578147b5d69cSJames Bottomley           FPT_Wait(p_port, TO_250ms);
57821da177e4SLinus Torvalds 
578347b5d69cSJames Bottomley           while (!(FPT_scarb(p_port,INIT_SELTD))) {}
57841da177e4SLinus Torvalds 
578547b5d69cSJames Bottomley           FPT_scsel(p_port);
57861da177e4SLinus Torvalds 
57871da177e4SLinus Torvalds          do {
578847b5d69cSJames Bottomley              FPT_scxferc(p_port, SYNC_PTRN);
578947b5d69cSJames Bottomley              FPT_scxferc(p_port, DOM_MSTR);
579047b5d69cSJames Bottomley              loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
57911da177e4SLinus Torvalds                id_string[0]);
57921da177e4SLinus Torvalds             } while ( loser == 0xFF );
57931da177e4SLinus Torvalds 
579447b5d69cSJames Bottomley           FPT_scbusf(p_port);
57951da177e4SLinus Torvalds          }
57961da177e4SLinus Torvalds       }
57971da177e4SLinus Torvalds 
57981da177e4SLinus Torvalds    else
57991da177e4SLinus Torvalds       {
580047b5d69cSJames Bottomley        loser = 0;
58011da177e4SLinus Torvalds       }
58021da177e4SLinus Torvalds 
58031da177e4SLinus Torvalds 
58041da177e4SLinus Torvalds    if (!loser)
58051da177e4SLinus Torvalds       {
58061da177e4SLinus Torvalds 
580747b5d69cSJames Bottomley        FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
58081da177e4SLinus Torvalds 
58091da177e4SLinus Torvalds 
58101da177e4SLinus Torvalds 		if (ScamFlg & SCAM_ENABLED)
58111da177e4SLinus Torvalds 		{
58121da177e4SLinus Torvalds 
58131da177e4SLinus Torvalds 	      for (i=0; i < MAX_SCSI_TAR; i++)
58141da177e4SLinus Torvalds   		   {
581547b5d69cSJames Bottomley        	   if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
581647b5d69cSJames Bottomley    	      	   (FPT_scamInfo[i].state == ID_UNUSED))
58171da177e4SLinus Torvalds 	  	      {
581847b5d69cSJames Bottomley     	     	   if (FPT_scsell(p_port,i))
58191da177e4SLinus Torvalds       	  	   {
582047b5d69cSJames Bottomley              	   FPT_scamInfo[i].state = LEGACY;
582147b5d69cSJames Bottomley    	            	if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
582247b5d69cSJames Bottomley       	            	(FPT_scamInfo[i].id_string[1] != 0xFA))
58231da177e4SLinus Torvalds 	     	         {
58241da177e4SLinus Torvalds 
582547b5d69cSJames Bottomley     	        	      FPT_scamInfo[i].id_string[0] = 0xFF;
582647b5d69cSJames Bottomley        	        	   FPT_scamInfo[i].id_string[1] = 0xFA;
58271da177e4SLinus Torvalds 							if(pCurrNvRam == NULL)
58281da177e4SLinus Torvalds 	         	         currCard->globalFlags |= F_UPDATE_EEPROM;
58291da177e4SLinus Torvalds                	}
58301da177e4SLinus Torvalds 	  	         }
58311da177e4SLinus Torvalds    	  	   }
58321da177e4SLinus Torvalds       	}
58331da177e4SLinus Torvalds 
583447b5d69cSJames Bottomley  	      FPT_sresb(p_port,p_card);
583547b5d69cSJames Bottomley        	FPT_Wait1Second(p_port);
583647b5d69cSJames Bottomley           while (!(FPT_scarb(p_port,INIT_SELTD))) {}
583747b5d69cSJames Bottomley           FPT_scsel(p_port);
583847b5d69cSJames Bottomley           FPT_scasid(p_card, p_port);
58391da177e4SLinus Torvalds          }
58401da177e4SLinus Torvalds 
58411da177e4SLinus Torvalds       }
58421da177e4SLinus Torvalds 
58431da177e4SLinus Torvalds    else if ((loser) && (ScamFlg & SCAM_ENABLED))
58441da177e4SLinus Torvalds       {
584547b5d69cSJames Bottomley        FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
584647b5d69cSJames Bottomley        assigned_id = 0;
584747b5d69cSJames Bottomley        FPT_scwtsel(p_port);
58481da177e4SLinus Torvalds 
58491da177e4SLinus Torvalds       do {
585047b5d69cSJames Bottomley           while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
58511da177e4SLinus Torvalds 
585247b5d69cSJames Bottomley           i = FPT_scxferc(p_port,0x00);
58531da177e4SLinus Torvalds          if (i == ASSIGN_ID)
58541da177e4SLinus Torvalds             {
585547b5d69cSJames Bottomley              if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
58561da177e4SLinus Torvalds                   {
585747b5d69cSJames Bottomley                    i = FPT_scxferc(p_port,0x00);
585847b5d69cSJames Bottomley                    if (FPT_scvalq(i))
58591da177e4SLinus Torvalds                      {
586047b5d69cSJames Bottomley                       k = FPT_scxferc(p_port,0x00);
58611da177e4SLinus Torvalds 
586247b5d69cSJames Bottomley                       if (FPT_scvalq(k))
58631da177e4SLinus Torvalds                         {
58641da177e4SLinus Torvalds                         currCard->ourId =
58651da177e4SLinus Torvalds                            ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
586647b5d69cSJames Bottomley                          FPT_inisci(p_card, p_port, p_our_id);
586747b5d69cSJames Bottomley                          FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
586847b5d69cSJames Bottomley                          FPT_scamInfo[currCard->ourId].id_string[0]
58691da177e4SLinus Torvalds                            = SLV_TYPE_CODE0;
587047b5d69cSJames Bottomley                          assigned_id = 1;
58711da177e4SLinus Torvalds                         }
58721da177e4SLinus Torvalds                      }
58731da177e4SLinus Torvalds                   }
58741da177e4SLinus Torvalds             }
58751da177e4SLinus Torvalds 
58761da177e4SLinus Torvalds          else if (i == SET_P_FLAG)
58771da177e4SLinus Torvalds             {
587847b5d69cSJames Bottomley                 if (!(FPT_scsendi(p_port,
587947b5d69cSJames Bottomley                          &FPT_scamInfo[p_our_id].id_string[0])))
588047b5d69cSJames Bottomley                          FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
58811da177e4SLinus Torvalds             }
58821da177e4SLinus Torvalds          }while (!assigned_id);
58831da177e4SLinus Torvalds 
588447b5d69cSJames Bottomley        while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
58851da177e4SLinus Torvalds       }
58861da177e4SLinus Torvalds 
58871da177e4SLinus Torvalds    if (ScamFlg & SCAM_ENABLED)
58881da177e4SLinus Torvalds       {
588947b5d69cSJames Bottomley        FPT_scbusf(p_port);
58901da177e4SLinus Torvalds       if (currCard->globalFlags & F_UPDATE_EEPROM)
58911da177e4SLinus Torvalds          {
589247b5d69cSJames Bottomley           FPT_scsavdi(p_card, p_port);
58931da177e4SLinus Torvalds          currCard->globalFlags &= ~F_UPDATE_EEPROM;
58941da177e4SLinus Torvalds          }
58951da177e4SLinus Torvalds       }
58961da177e4SLinus Torvalds 
58971da177e4SLinus Torvalds 
58981da177e4SLinus Torvalds /*
58991da177e4SLinus Torvalds    for (i=0,k=0; i < MAX_SCSI_TAR; i++)
59001da177e4SLinus Torvalds       {
590147b5d69cSJames Bottomley        if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
590247b5d69cSJames Bottomley           (FPT_scamInfo[i].state == LEGACY))
59031da177e4SLinus Torvalds          k++;
59041da177e4SLinus Torvalds       }
59051da177e4SLinus Torvalds 
59061da177e4SLinus Torvalds    if (k==2)
59071da177e4SLinus Torvalds       currCard->globalFlags |= F_SINGLE_DEVICE;
59081da177e4SLinus Torvalds    else
59091da177e4SLinus Torvalds       currCard->globalFlags &= ~F_SINGLE_DEVICE;
59101da177e4SLinus Torvalds */
59111da177e4SLinus Torvalds }
59121da177e4SLinus Torvalds 
59131da177e4SLinus Torvalds 
59141da177e4SLinus Torvalds /*---------------------------------------------------------------------
59151da177e4SLinus Torvalds  *
591647b5d69cSJames Bottomley   * Function: FPT_scarb
59171da177e4SLinus Torvalds  *
59181da177e4SLinus Torvalds  * Description: Gain control of the bus and wait SCAM select time (250ms)
59191da177e4SLinus Torvalds  *
59201da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
59211da177e4SLinus Torvalds 
592247b5d69cSJames Bottomley  static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
59231da177e4SLinus Torvalds {
59241da177e4SLinus Torvalds    if (p_sel_type == INIT_SELTD)
59251da177e4SLinus Torvalds       {
59261da177e4SLinus Torvalds 
59271da177e4SLinus Torvalds       while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
59281da177e4SLinus Torvalds 
59291da177e4SLinus Torvalds 
59301da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
593147b5d69cSJames Bottomley           return(0);
59321da177e4SLinus Torvalds 
59331da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
593447b5d69cSJames Bottomley           return(0);
59351da177e4SLinus Torvalds 
59361da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
59371da177e4SLinus Torvalds 
59381da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
59391da177e4SLinus Torvalds 
59401da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
59411da177e4SLinus Torvalds             ~SCSI_BSY));
594247b5d69cSJames Bottomley           return(0);
59431da177e4SLinus Torvalds          }
59441da177e4SLinus Torvalds 
59451da177e4SLinus Torvalds 
59461da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
59471da177e4SLinus Torvalds 
59481da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
59491da177e4SLinus Torvalds 
59501da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
59511da177e4SLinus Torvalds             ~(SCSI_BSY | SCSI_SEL)));
595247b5d69cSJames Bottomley           return(0);
59531da177e4SLinus Torvalds          }
59541da177e4SLinus Torvalds       }
59551da177e4SLinus Torvalds 
59561da177e4SLinus Torvalds 
59571da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
59581da177e4SLinus Torvalds       & ~ACTdeassert));
59591da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
59601da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
59611da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_1, 0x00);
59621da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
59631da177e4SLinus Torvalds 
59641da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
59651da177e4SLinus Torvalds 
59661da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
59671da177e4SLinus Torvalds       & ~SCSI_BSY));
59681da177e4SLinus Torvalds 
596947b5d69cSJames Bottomley     FPT_Wait(p_port,TO_250ms);
59701da177e4SLinus Torvalds 
597147b5d69cSJames Bottomley     return(1);
59721da177e4SLinus Torvalds }
59731da177e4SLinus Torvalds 
59741da177e4SLinus Torvalds 
59751da177e4SLinus Torvalds /*---------------------------------------------------------------------
59761da177e4SLinus Torvalds  *
597747b5d69cSJames Bottomley   * Function: FPT_scbusf
59781da177e4SLinus Torvalds  *
59791da177e4SLinus Torvalds  * Description: Release the SCSI bus and disable SCAM selection.
59801da177e4SLinus Torvalds  *
59811da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
59821da177e4SLinus Torvalds 
598347b5d69cSJames Bottomley  static void FPT_scbusf(ULONG p_port)
59841da177e4SLinus Torvalds {
59851da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl,
59861da177e4SLinus Torvalds       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
59871da177e4SLinus Torvalds 
59881da177e4SLinus Torvalds 
59891da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
59901da177e4SLinus Torvalds 
59911da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
59921da177e4SLinus Torvalds       & ~SCSI_BUS_EN));
59931da177e4SLinus Torvalds 
59941da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, 0x00);
59951da177e4SLinus Torvalds 
59961da177e4SLinus Torvalds 
59971da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsireset,  (RD_HARPOON(p_port+hp_scsireset)
59981da177e4SLinus Torvalds       & ~SCAM_EN));
59991da177e4SLinus Torvalds 
60001da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
60011da177e4SLinus Torvalds       | ACTdeassert));
60021da177e4SLinus Torvalds 
60031da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
60041da177e4SLinus Torvalds 
60051da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl,
60061da177e4SLinus Torvalds       (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
60071da177e4SLinus Torvalds }
60081da177e4SLinus Torvalds 
60091da177e4SLinus Torvalds 
60101da177e4SLinus Torvalds 
60111da177e4SLinus Torvalds /*---------------------------------------------------------------------
60121da177e4SLinus Torvalds  *
601347b5d69cSJames Bottomley   * Function: FPT_scasid
60141da177e4SLinus Torvalds  *
60151da177e4SLinus Torvalds  * Description: Assign an ID to all the SCAM devices.
60161da177e4SLinus Torvalds  *
60171da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
60181da177e4SLinus Torvalds 
601947b5d69cSJames Bottomley  static void FPT_scasid(UCHAR p_card, ULONG p_port)
60201da177e4SLinus Torvalds {
60211da177e4SLinus Torvalds    UCHAR temp_id_string[ID_STRING_LENGTH];
60221da177e4SLinus Torvalds 
60231da177e4SLinus Torvalds    UCHAR i,k,scam_id;
60241da177e4SLinus Torvalds 	UCHAR crcBytes[3];
60251da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
60261da177e4SLinus Torvalds 	ushort_ptr pCrcBytes;
60271da177e4SLinus Torvalds 
602847b5d69cSJames Bottomley  	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
60291da177e4SLinus Torvalds 
603047b5d69cSJames Bottomley     i=0;
60311da177e4SLinus Torvalds 
60321da177e4SLinus Torvalds    while (!i)
60331da177e4SLinus Torvalds       {
60341da177e4SLinus Torvalds 
60351da177e4SLinus Torvalds       for (k=0; k < ID_STRING_LENGTH; k++)
60361da177e4SLinus Torvalds          {
60371da177e4SLinus Torvalds          temp_id_string[k] = (UCHAR) 0x00;
60381da177e4SLinus Torvalds          }
60391da177e4SLinus Torvalds 
604047b5d69cSJames Bottomley        FPT_scxferc(p_port,SYNC_PTRN);
604147b5d69cSJames Bottomley        FPT_scxferc(p_port,ASSIGN_ID);
60421da177e4SLinus Torvalds 
604347b5d69cSJames Bottomley        if (!(FPT_sciso(p_port,&temp_id_string[0])))
60441da177e4SLinus Torvalds          {
60451da177e4SLinus Torvalds 			if(pCurrNvRam){
60461da177e4SLinus Torvalds 				pCrcBytes = (ushort_ptr)&crcBytes[0];
604747b5d69cSJames Bottomley  				*pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
604847b5d69cSJames Bottomley  				crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
60491da177e4SLinus Torvalds 				temp_id_string[1] = crcBytes[2];
60501da177e4SLinus Torvalds 				temp_id_string[2] = crcBytes[0];
60511da177e4SLinus Torvalds 				temp_id_string[3] = crcBytes[1];
60521da177e4SLinus Torvalds 				for(k = 4; k < ID_STRING_LENGTH; k++)
60531da177e4SLinus Torvalds 					temp_id_string[k] = (UCHAR) 0x00;
60541da177e4SLinus Torvalds 			}
605547b5d69cSJames Bottomley           i = FPT_scmachid(p_card,temp_id_string);
60561da177e4SLinus Torvalds 
60571da177e4SLinus Torvalds          if (i == CLR_PRIORITY)
60581da177e4SLinus Torvalds             {
605947b5d69cSJames Bottomley              FPT_scxferc(p_port,MISC_CODE);
606047b5d69cSJames Bottomley              FPT_scxferc(p_port,CLR_P_FLAG);
606147b5d69cSJames Bottomley              i = 0;  /*Not the last ID yet. */
60621da177e4SLinus Torvalds             }
60631da177e4SLinus Torvalds 
60641da177e4SLinus Torvalds          else if (i != NO_ID_AVAIL)
60651da177e4SLinus Torvalds             {
60661da177e4SLinus Torvalds             if (i < 8 )
606747b5d69cSJames Bottomley                 FPT_scxferc(p_port,ID_0_7);
60681da177e4SLinus Torvalds             else
606947b5d69cSJames Bottomley                 FPT_scxferc(p_port,ID_8_F);
60701da177e4SLinus Torvalds 
60711da177e4SLinus Torvalds             scam_id = (i & (UCHAR) 0x07);
60721da177e4SLinus Torvalds 
60731da177e4SLinus Torvalds 
60741da177e4SLinus Torvalds             for (k=1; k < 0x08; k <<= 1)
60751da177e4SLinus Torvalds                if (!( k & i ))
60761da177e4SLinus Torvalds                   scam_id += 0x08;        /*Count number of zeros in DB0-3. */
60771da177e4SLinus Torvalds 
607847b5d69cSJames Bottomley              FPT_scxferc(p_port,scam_id);
60791da177e4SLinus Torvalds 
608047b5d69cSJames Bottomley              i = 0;  /*Not the last ID yet. */
60811da177e4SLinus Torvalds             }
60821da177e4SLinus Torvalds          }
60831da177e4SLinus Torvalds 
60841da177e4SLinus Torvalds       else
60851da177e4SLinus Torvalds          {
608647b5d69cSJames Bottomley           i = 1;
60871da177e4SLinus Torvalds          }
60881da177e4SLinus Torvalds 
60891da177e4SLinus Torvalds       }  /*End while */
60901da177e4SLinus Torvalds 
609147b5d69cSJames Bottomley     FPT_scxferc(p_port,SYNC_PTRN);
609247b5d69cSJames Bottomley     FPT_scxferc(p_port,CFG_CMPLT);
60931da177e4SLinus Torvalds }
60941da177e4SLinus Torvalds 
60951da177e4SLinus Torvalds 
60961da177e4SLinus Torvalds 
60971da177e4SLinus Torvalds 
60981da177e4SLinus Torvalds 
60991da177e4SLinus Torvalds /*---------------------------------------------------------------------
61001da177e4SLinus Torvalds  *
610147b5d69cSJames Bottomley   * Function: FPT_scsel
61021da177e4SLinus Torvalds  *
61031da177e4SLinus Torvalds  * Description: Select all the SCAM devices.
61041da177e4SLinus Torvalds  *
61051da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
61061da177e4SLinus Torvalds 
610747b5d69cSJames Bottomley  static void FPT_scsel(ULONG p_port)
61081da177e4SLinus Torvalds {
61091da177e4SLinus Torvalds 
61101da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
611147b5d69cSJames Bottomley     FPT_scwiros(p_port, SCSI_MSG);
61121da177e4SLinus Torvalds 
61131da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
61141da177e4SLinus Torvalds 
61151da177e4SLinus Torvalds 
61161da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
61171da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
61181da177e4SLinus Torvalds       (UCHAR)(BIT(7)+BIT(6))));
61191da177e4SLinus Torvalds 
61201da177e4SLinus Torvalds 
61211da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
612247b5d69cSJames Bottomley     FPT_scwiros(p_port, SCSI_SEL);
61231da177e4SLinus Torvalds 
61241da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
61251da177e4SLinus Torvalds       ~(UCHAR)BIT(6)));
612647b5d69cSJames Bottomley     FPT_scwirod(p_port, BIT(6));
61271da177e4SLinus Torvalds 
61281da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
61291da177e4SLinus Torvalds }
61301da177e4SLinus Torvalds 
61311da177e4SLinus Torvalds 
61321da177e4SLinus Torvalds 
61331da177e4SLinus Torvalds /*---------------------------------------------------------------------
61341da177e4SLinus Torvalds  *
613547b5d69cSJames Bottomley   * Function: FPT_scxferc
61361da177e4SLinus Torvalds  *
61371da177e4SLinus Torvalds  * Description: Handshake the p_data (DB4-0) across the bus.
61381da177e4SLinus Torvalds  *
61391da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
61401da177e4SLinus Torvalds 
614147b5d69cSJames Bottomley  static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
61421da177e4SLinus Torvalds {
61431da177e4SLinus Torvalds    UCHAR curr_data, ret_data;
61441da177e4SLinus Torvalds 
61451da177e4SLinus Torvalds    curr_data = p_data | BIT(7) | BIT(5);   /*Start with DB7 & DB5 asserted. */
61461da177e4SLinus Torvalds 
61471da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
61481da177e4SLinus Torvalds 
61491da177e4SLinus Torvalds    curr_data &= ~BIT(7);
61501da177e4SLinus Torvalds 
61511da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
61521da177e4SLinus Torvalds 
615347b5d69cSJames Bottomley     FPT_scwirod(p_port,BIT(7));              /*Wait for DB7 to be released. */
61541da177e4SLinus Torvalds 	while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
61551da177e4SLinus Torvalds 
61561da177e4SLinus Torvalds    ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
61571da177e4SLinus Torvalds 
61581da177e4SLinus Torvalds    curr_data |= BIT(6);
61591da177e4SLinus Torvalds 
61601da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
61611da177e4SLinus Torvalds 
61621da177e4SLinus Torvalds    curr_data &= ~BIT(5);
61631da177e4SLinus Torvalds 
61641da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
61651da177e4SLinus Torvalds 
616647b5d69cSJames Bottomley     FPT_scwirod(p_port,BIT(5));              /*Wait for DB5 to be released. */
61671da177e4SLinus Torvalds 
61681da177e4SLinus Torvalds    curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
61691da177e4SLinus Torvalds    curr_data |= BIT(7);
61701da177e4SLinus Torvalds 
61711da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
61721da177e4SLinus Torvalds 
61731da177e4SLinus Torvalds    curr_data &= ~BIT(6);
61741da177e4SLinus Torvalds 
61751da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
61761da177e4SLinus Torvalds 
617747b5d69cSJames Bottomley     FPT_scwirod(p_port,BIT(6));              /*Wait for DB6 to be released. */
61781da177e4SLinus Torvalds 
61791da177e4SLinus Torvalds    return(ret_data);
61801da177e4SLinus Torvalds }
61811da177e4SLinus Torvalds 
61821da177e4SLinus Torvalds 
61831da177e4SLinus Torvalds /*---------------------------------------------------------------------
61841da177e4SLinus Torvalds  *
618547b5d69cSJames Bottomley   * Function: FPT_scsendi
61861da177e4SLinus Torvalds  *
61871da177e4SLinus Torvalds  * Description: Transfer our Identification string to determine if we
61881da177e4SLinus Torvalds  *              will be the dominant master.
61891da177e4SLinus Torvalds  *
61901da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
61911da177e4SLinus Torvalds 
619247b5d69cSJames Bottomley  static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
61931da177e4SLinus Torvalds {
61941da177e4SLinus Torvalds    UCHAR ret_data,byte_cnt,bit_cnt,defer;
61951da177e4SLinus Torvalds 
619647b5d69cSJames Bottomley     defer = 0;
61971da177e4SLinus Torvalds 
61981da177e4SLinus Torvalds    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
61991da177e4SLinus Torvalds 
62001da177e4SLinus Torvalds       for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
62011da177e4SLinus Torvalds 
62021da177e4SLinus Torvalds          if (defer)
620347b5d69cSJames Bottomley              ret_data = FPT_scxferc(p_port,00);
62041da177e4SLinus Torvalds 
62051da177e4SLinus Torvalds          else if (p_id_string[byte_cnt] & bit_cnt)
62061da177e4SLinus Torvalds 
620747b5d69cSJames Bottomley                 ret_data = FPT_scxferc(p_port,02);
62081da177e4SLinus Torvalds 
62091da177e4SLinus Torvalds             else {
62101da177e4SLinus Torvalds 
621147b5d69cSJames Bottomley                 ret_data = FPT_scxferc(p_port,01);
62121da177e4SLinus Torvalds                if (ret_data & 02)
621347b5d69cSJames Bottomley                    defer = 1;
62141da177e4SLinus Torvalds                }
62151da177e4SLinus Torvalds 
62161da177e4SLinus Torvalds          if ((ret_data & 0x1C) == 0x10)
62171da177e4SLinus Torvalds             return(0x00);  /*End of isolation stage, we won! */
62181da177e4SLinus Torvalds 
62191da177e4SLinus Torvalds          if (ret_data & 0x1C)
62201da177e4SLinus Torvalds             return(0xFF);
62211da177e4SLinus Torvalds 
62221da177e4SLinus Torvalds          if ((defer) && (!(ret_data & 0x1F)))
62231da177e4SLinus Torvalds             return(0x01);  /*End of isolation stage, we lost. */
62241da177e4SLinus Torvalds 
62251da177e4SLinus Torvalds          } /*bit loop */
62261da177e4SLinus Torvalds 
62271da177e4SLinus Torvalds       } /*byte loop */
62281da177e4SLinus Torvalds 
62291da177e4SLinus Torvalds    if (defer)
62301da177e4SLinus Torvalds       return(0x01);  /*We lost */
62311da177e4SLinus Torvalds    else
62321da177e4SLinus Torvalds       return(0);  /*We WON! Yeeessss! */
62331da177e4SLinus Torvalds }
62341da177e4SLinus Torvalds 
62351da177e4SLinus Torvalds 
62361da177e4SLinus Torvalds 
62371da177e4SLinus Torvalds /*---------------------------------------------------------------------
62381da177e4SLinus Torvalds  *
623947b5d69cSJames Bottomley   * Function: FPT_sciso
62401da177e4SLinus Torvalds  *
62411da177e4SLinus Torvalds  * Description: Transfer the Identification string.
62421da177e4SLinus Torvalds  *
62431da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
62441da177e4SLinus Torvalds 
624547b5d69cSJames Bottomley  static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
62461da177e4SLinus Torvalds {
62471da177e4SLinus Torvalds    UCHAR ret_data,the_data,byte_cnt,bit_cnt;
62481da177e4SLinus Torvalds 
62491da177e4SLinus Torvalds    the_data = 0;
62501da177e4SLinus Torvalds 
62511da177e4SLinus Torvalds    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
62521da177e4SLinus Torvalds 
62531da177e4SLinus Torvalds       for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
62541da177e4SLinus Torvalds 
625547b5d69cSJames Bottomley           ret_data = FPT_scxferc(p_port,0);
62561da177e4SLinus Torvalds 
62571da177e4SLinus Torvalds          if (ret_data & 0xFC)
62581da177e4SLinus Torvalds             return(0xFF);
62591da177e4SLinus Torvalds 
62601da177e4SLinus Torvalds          else {
62611da177e4SLinus Torvalds 
62621da177e4SLinus Torvalds             the_data <<= 1;
62631da177e4SLinus Torvalds             if (ret_data & BIT(1)) {
62641da177e4SLinus Torvalds                the_data |= 1;
62651da177e4SLinus Torvalds                }
62661da177e4SLinus Torvalds             }
62671da177e4SLinus Torvalds 
62681da177e4SLinus Torvalds          if ((ret_data & 0x1F) == 0)
62691da177e4SLinus Torvalds 	   {
62701da177e4SLinus Torvalds /*
62711da177e4SLinus Torvalds 				if(bit_cnt != 0 || bit_cnt != 8)
62721da177e4SLinus Torvalds 				{
62731da177e4SLinus Torvalds 					byte_cnt = 0;
62741da177e4SLinus Torvalds 					bit_cnt = 0;
627547b5d69cSJames Bottomley  					FPT_scxferc(p_port, SYNC_PTRN);
627647b5d69cSJames Bottomley  					FPT_scxferc(p_port, ASSIGN_ID);
62771da177e4SLinus Torvalds 					continue;
62781da177e4SLinus Torvalds 				}
62791da177e4SLinus Torvalds */
62801da177e4SLinus Torvalds             if (byte_cnt)
62811da177e4SLinus Torvalds                return(0x00);
62821da177e4SLinus Torvalds             else
62831da177e4SLinus Torvalds                return(0xFF);
62841da177e4SLinus Torvalds 	   }
62851da177e4SLinus Torvalds 
62861da177e4SLinus Torvalds          } /*bit loop */
62871da177e4SLinus Torvalds 
62881da177e4SLinus Torvalds       p_id_string[byte_cnt] = the_data;
62891da177e4SLinus Torvalds 
62901da177e4SLinus Torvalds       } /*byte loop */
62911da177e4SLinus Torvalds 
62921da177e4SLinus Torvalds    return(0);
62931da177e4SLinus Torvalds }
62941da177e4SLinus Torvalds 
62951da177e4SLinus Torvalds 
62961da177e4SLinus Torvalds 
62971da177e4SLinus Torvalds /*---------------------------------------------------------------------
62981da177e4SLinus Torvalds  *
629947b5d69cSJames Bottomley   * Function: FPT_scwirod
63001da177e4SLinus Torvalds  *
63011da177e4SLinus Torvalds  * Description: Sample the SCSI data bus making sure the signal has been
63021da177e4SLinus Torvalds  *              deasserted for the correct number of consecutive samples.
63031da177e4SLinus Torvalds  *
63041da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
63051da177e4SLinus Torvalds 
630647b5d69cSJames Bottomley  static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
63071da177e4SLinus Torvalds {
63081da177e4SLinus Torvalds    UCHAR i;
63091da177e4SLinus Torvalds 
63101da177e4SLinus Torvalds    i = 0;
63111da177e4SLinus Torvalds    while ( i < MAX_SCSI_TAR ) {
63121da177e4SLinus Torvalds 
63131da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
63141da177e4SLinus Torvalds 
63151da177e4SLinus Torvalds          i = 0;
63161da177e4SLinus Torvalds 
63171da177e4SLinus Torvalds       else
63181da177e4SLinus Torvalds 
63191da177e4SLinus Torvalds          i++;
63201da177e4SLinus Torvalds 
63211da177e4SLinus Torvalds       }
63221da177e4SLinus Torvalds }
63231da177e4SLinus Torvalds 
63241da177e4SLinus Torvalds 
63251da177e4SLinus Torvalds 
63261da177e4SLinus Torvalds /*---------------------------------------------------------------------
63271da177e4SLinus Torvalds  *
632847b5d69cSJames Bottomley   * Function: FPT_scwiros
63291da177e4SLinus Torvalds  *
63301da177e4SLinus Torvalds  * Description: Sample the SCSI Signal lines making sure the signal has been
63311da177e4SLinus Torvalds  *              deasserted for the correct number of consecutive samples.
63321da177e4SLinus Torvalds  *
63331da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
63341da177e4SLinus Torvalds 
633547b5d69cSJames Bottomley  static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
63361da177e4SLinus Torvalds {
63371da177e4SLinus Torvalds    UCHAR i;
63381da177e4SLinus Torvalds 
63391da177e4SLinus Torvalds    i = 0;
63401da177e4SLinus Torvalds    while ( i < MAX_SCSI_TAR ) {
63411da177e4SLinus Torvalds 
63421da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
63431da177e4SLinus Torvalds 
63441da177e4SLinus Torvalds          i = 0;
63451da177e4SLinus Torvalds 
63461da177e4SLinus Torvalds       else
63471da177e4SLinus Torvalds 
63481da177e4SLinus Torvalds          i++;
63491da177e4SLinus Torvalds 
63501da177e4SLinus Torvalds       }
63511da177e4SLinus Torvalds }
63521da177e4SLinus Torvalds 
63531da177e4SLinus Torvalds 
63541da177e4SLinus Torvalds /*---------------------------------------------------------------------
63551da177e4SLinus Torvalds  *
635647b5d69cSJames Bottomley   * Function: FPT_scvalq
63571da177e4SLinus Torvalds  *
63581da177e4SLinus Torvalds  * Description: Make sure we received a valid data byte.
63591da177e4SLinus Torvalds  *
63601da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
63611da177e4SLinus Torvalds 
636247b5d69cSJames Bottomley  static UCHAR FPT_scvalq(UCHAR p_quintet)
63631da177e4SLinus Torvalds {
63641da177e4SLinus Torvalds    UCHAR count;
63651da177e4SLinus Torvalds 
63661da177e4SLinus Torvalds    for (count=1; count < 0x08; count<<=1) {
63671da177e4SLinus Torvalds       if (!(p_quintet & count))
63681da177e4SLinus Torvalds          p_quintet -= 0x80;
63691da177e4SLinus Torvalds       }
63701da177e4SLinus Torvalds 
63711da177e4SLinus Torvalds    if (p_quintet & 0x18)
637247b5d69cSJames Bottomley        return(0);
63731da177e4SLinus Torvalds 
63741da177e4SLinus Torvalds    else
637547b5d69cSJames Bottomley        return(1);
63761da177e4SLinus Torvalds }
63771da177e4SLinus Torvalds 
63781da177e4SLinus Torvalds 
63791da177e4SLinus Torvalds /*---------------------------------------------------------------------
63801da177e4SLinus Torvalds  *
638147b5d69cSJames Bottomley   * Function: FPT_scsell
63821da177e4SLinus Torvalds  *
63831da177e4SLinus Torvalds  * Description: Select the specified device ID using a selection timeout
63841da177e4SLinus Torvalds  *              less than 4ms.  If somebody responds then it is a legacy
63851da177e4SLinus Torvalds  *              drive and this ID must be marked as such.
63861da177e4SLinus Torvalds  *
63871da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
63881da177e4SLinus Torvalds 
638947b5d69cSJames Bottomley  static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
63901da177e4SLinus Torvalds {
63911da177e4SLinus Torvalds    ULONG i;
63921da177e4SLinus Torvalds 
63931da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl,
63941da177e4SLinus Torvalds       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
63951da177e4SLinus Torvalds 
63961da177e4SLinus Torvalds    ARAM_ACCESS(p_port);
63971da177e4SLinus Torvalds 
63981da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
63991da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
64001da177e4SLinus Torvalds 
64011da177e4SLinus Torvalds 
64021da177e4SLinus Torvalds    for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
64031da177e4SLinus Torvalds       WRW_HARPOON(i, (MPM_OP+ACOMMAND));
64041da177e4SLinus Torvalds       }
64051da177e4SLinus Torvalds    WRW_HARPOON(i, (BRH_OP+ALWAYS+    NP));
64061da177e4SLinus Torvalds 
64071da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat),
64081da177e4SLinus Torvalds 	       (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
64091da177e4SLinus Torvalds 
64101da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_select_id, targ_id);
64111da177e4SLinus Torvalds 
64121da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
64131da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
64141da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
64151da177e4SLinus Torvalds 
64161da177e4SLinus Torvalds 
64171da177e4SLinus Torvalds    while (!(RDW_HARPOON((p_port+hp_intstat)) &
64181da177e4SLinus Torvalds 	    (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
64191da177e4SLinus Torvalds 
64201da177e4SLinus Torvalds    if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
642147b5d69cSJames Bottomley           FPT_Wait(p_port, TO_250ms);
64221da177e4SLinus Torvalds 
64231da177e4SLinus Torvalds    DISABLE_AUTO(p_port);
64241da177e4SLinus Torvalds 
64251da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
64261da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
64271da177e4SLinus Torvalds 
64281da177e4SLinus Torvalds    SGRAM_ACCESS(p_port);
64291da177e4SLinus Torvalds 
64301da177e4SLinus Torvalds    if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
64311da177e4SLinus Torvalds 
64321da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat),
64331da177e4SLinus Torvalds 		  (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
64341da177e4SLinus Torvalds 
64351da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_page_ctrl,
64361da177e4SLinus Torvalds          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
64371da177e4SLinus Torvalds 
643847b5d69cSJames Bottomley        return(0);  /*No legacy device */
64391da177e4SLinus Torvalds       }
64401da177e4SLinus Torvalds 
64411da177e4SLinus Torvalds    else {
64421da177e4SLinus Torvalds 
64431da177e4SLinus Torvalds       while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
64441da177e4SLinus Torvalds 				if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
64451da177e4SLinus Torvalds 					{
64461da177e4SLinus Torvalds 					WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
64471da177e4SLinus Torvalds       			ACCEPT_MSG(p_port);
64481da177e4SLinus Torvalds 					}
64491da177e4SLinus Torvalds 		}
64501da177e4SLinus Torvalds 
64511da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
64521da177e4SLinus Torvalds 
64531da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_page_ctrl,
64541da177e4SLinus Torvalds          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
64551da177e4SLinus Torvalds 
645647b5d69cSJames Bottomley        return(1);  /*Found one of them oldies! */
64571da177e4SLinus Torvalds       }
64581da177e4SLinus Torvalds }
64591da177e4SLinus Torvalds 
64601da177e4SLinus Torvalds /*---------------------------------------------------------------------
64611da177e4SLinus Torvalds  *
646247b5d69cSJames Bottomley   * Function: FPT_scwtsel
64631da177e4SLinus Torvalds  *
64641da177e4SLinus Torvalds  * Description: Wait to be selected by another SCAM initiator.
64651da177e4SLinus Torvalds  *
64661da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
64671da177e4SLinus Torvalds 
646847b5d69cSJames Bottomley  static void FPT_scwtsel(ULONG p_port)
64691da177e4SLinus Torvalds {
64701da177e4SLinus Torvalds    while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
64711da177e4SLinus Torvalds }
64721da177e4SLinus Torvalds 
64731da177e4SLinus Torvalds 
64741da177e4SLinus Torvalds /*---------------------------------------------------------------------
64751da177e4SLinus Torvalds  *
647647b5d69cSJames Bottomley   * Function: FPT_inisci
64771da177e4SLinus Torvalds  *
64781da177e4SLinus Torvalds  * Description: Setup the data Structure with the info from the EEPROM.
64791da177e4SLinus Torvalds  *
64801da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
64811da177e4SLinus Torvalds 
648247b5d69cSJames Bottomley  static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
64831da177e4SLinus Torvalds {
64841da177e4SLinus Torvalds    UCHAR i,k,max_id;
64851da177e4SLinus Torvalds    USHORT ee_data;
64861da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
64871da177e4SLinus Torvalds 
648847b5d69cSJames Bottomley  	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
64891da177e4SLinus Torvalds 
64901da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
64911da177e4SLinus Torvalds       max_id = 0x08;
64921da177e4SLinus Torvalds 
64931da177e4SLinus Torvalds    else
64941da177e4SLinus Torvalds       max_id = 0x10;
64951da177e4SLinus Torvalds 
64961da177e4SLinus Torvalds 	if(pCurrNvRam){
64971da177e4SLinus Torvalds 		for(i = 0; i < max_id; i++){
64981da177e4SLinus Torvalds 
64991da177e4SLinus Torvalds 			for(k = 0; k < 4; k++)
650047b5d69cSJames Bottomley  				FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
65011da177e4SLinus Torvalds 			for(k = 4; k < ID_STRING_LENGTH; k++)
650247b5d69cSJames Bottomley  				FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
65031da177e4SLinus Torvalds 
650447b5d69cSJames Bottomley  	      if(FPT_scamInfo[i].id_string[0] == 0x00)
650547b5d69cSJames Bottomley        	   FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
65061da177e4SLinus Torvalds 	      else
650747b5d69cSJames Bottomley     	      FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
65081da177e4SLinus Torvalds 
65091da177e4SLinus Torvalds 		}
65101da177e4SLinus Torvalds 	}else {
65111da177e4SLinus Torvalds 	   for (i=0; i < max_id; i++)
65121da177e4SLinus Torvalds    	   {
65131da177e4SLinus Torvalds       	for (k=0; k < ID_STRING_LENGTH; k+=2)
65141da177e4SLinus Torvalds 	         {
651547b5d69cSJames Bottomley     	      ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
65161da177e4SLinus Torvalds       	     (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
651747b5d69cSJames Bottomley           	FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
65181da177e4SLinus Torvalds 	         ee_data >>= 8;
651947b5d69cSJames Bottomley     	      FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
65201da177e4SLinus Torvalds       	   }
65211da177e4SLinus Torvalds 
652247b5d69cSJames Bottomley  	      if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
652347b5d69cSJames Bottomley     	       (FPT_scamInfo[i].id_string[0] == 0xFF))
65241da177e4SLinus Torvalds 
652547b5d69cSJames Bottomley        	   FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
65261da177e4SLinus Torvalds 
65271da177e4SLinus Torvalds 	      else
652847b5d69cSJames Bottomley     	      FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
65291da177e4SLinus Torvalds 
65301da177e4SLinus Torvalds       	}
65311da177e4SLinus Torvalds 	}
65321da177e4SLinus Torvalds 	for(k = 0; k < ID_STRING_LENGTH; k++)
653347b5d69cSJames Bottomley  		FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
65341da177e4SLinus Torvalds 
65351da177e4SLinus Torvalds }
65361da177e4SLinus Torvalds 
65371da177e4SLinus Torvalds /*---------------------------------------------------------------------
65381da177e4SLinus Torvalds  *
653947b5d69cSJames Bottomley   * Function: FPT_scmachid
65401da177e4SLinus Torvalds  *
65411da177e4SLinus Torvalds  * Description: Match the Device ID string with our values stored in
65421da177e4SLinus Torvalds  *              the EEPROM.
65431da177e4SLinus Torvalds  *
65441da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
65451da177e4SLinus Torvalds 
654647b5d69cSJames Bottomley  static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
65471da177e4SLinus Torvalds {
65481da177e4SLinus Torvalds 
65491da177e4SLinus Torvalds    UCHAR i,k,match;
65501da177e4SLinus Torvalds 
65511da177e4SLinus Torvalds 
65521da177e4SLinus Torvalds    for (i=0; i < MAX_SCSI_TAR; i++) {
65531da177e4SLinus Torvalds 
655447b5d69cSJames Bottomley           match = 1;
65551da177e4SLinus Torvalds 
65561da177e4SLinus Torvalds          for (k=0; k < ID_STRING_LENGTH; k++)
65571da177e4SLinus Torvalds             {
655847b5d69cSJames Bottomley              if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
655947b5d69cSJames Bottomley                 match = 0;
65601da177e4SLinus Torvalds             }
65611da177e4SLinus Torvalds 
65621da177e4SLinus Torvalds          if (match)
65631da177e4SLinus Torvalds             {
656447b5d69cSJames Bottomley              FPT_scamInfo[i].state = ID_ASSIGNED;
65651da177e4SLinus Torvalds             return(i);
65661da177e4SLinus Torvalds             }
65671da177e4SLinus Torvalds 
65681da177e4SLinus Torvalds       }
65691da177e4SLinus Torvalds 
65701da177e4SLinus Torvalds 
65711da177e4SLinus Torvalds 
65721da177e4SLinus Torvalds    if (p_id_string[0] & BIT(5))
65731da177e4SLinus Torvalds       i = 8;
65741da177e4SLinus Torvalds    else
65751da177e4SLinus Torvalds       i = MAX_SCSI_TAR;
65761da177e4SLinus Torvalds 
65771da177e4SLinus Torvalds    if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
65781da177e4SLinus Torvalds       match = p_id_string[1] & (UCHAR) 0x1F;
65791da177e4SLinus Torvalds    else
65801da177e4SLinus Torvalds       match = 7;
65811da177e4SLinus Torvalds 
65821da177e4SLinus Torvalds    while (i > 0)
65831da177e4SLinus Torvalds       {
65841da177e4SLinus Torvalds       i--;
65851da177e4SLinus Torvalds 
658647b5d69cSJames Bottomley        if (FPT_scamInfo[match].state == ID_UNUSED)
65871da177e4SLinus Torvalds          {
65881da177e4SLinus Torvalds          for (k=0; k < ID_STRING_LENGTH; k++)
65891da177e4SLinus Torvalds             {
659047b5d69cSJames Bottomley              FPT_scamInfo[match].id_string[k] = p_id_string[k];
65911da177e4SLinus Torvalds             }
65921da177e4SLinus Torvalds 
659347b5d69cSJames Bottomley           FPT_scamInfo[match].state = ID_ASSIGNED;
65941da177e4SLinus Torvalds 
659547b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
659647b5d69cSJames Bottomley  	         FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
65971da177e4SLinus Torvalds          return(match);
65981da177e4SLinus Torvalds 
65991da177e4SLinus Torvalds          }
66001da177e4SLinus Torvalds 
66011da177e4SLinus Torvalds 
66021da177e4SLinus Torvalds       match--;
66031da177e4SLinus Torvalds 
66041da177e4SLinus Torvalds       if (match == 0xFF)
66051da177e4SLinus Torvalds 	{
66061da177e4SLinus Torvalds          if (p_id_string[0] & BIT(5))
66071da177e4SLinus Torvalds             match = 7;
66081da177e4SLinus Torvalds          else
66091da177e4SLinus Torvalds             match = MAX_SCSI_TAR-1;
66101da177e4SLinus Torvalds 	}
66111da177e4SLinus Torvalds       }
66121da177e4SLinus Torvalds 
66131da177e4SLinus Torvalds 
66141da177e4SLinus Torvalds 
66151da177e4SLinus Torvalds    if (p_id_string[0] & BIT(7))
66161da177e4SLinus Torvalds       {
66171da177e4SLinus Torvalds       return(CLR_PRIORITY);
66181da177e4SLinus Torvalds       }
66191da177e4SLinus Torvalds 
66201da177e4SLinus Torvalds 
66211da177e4SLinus Torvalds    if (p_id_string[0] & BIT(5))
66221da177e4SLinus Torvalds       i = 8;
66231da177e4SLinus Torvalds    else
66241da177e4SLinus Torvalds       i = MAX_SCSI_TAR;
66251da177e4SLinus Torvalds 
66261da177e4SLinus Torvalds    if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
66271da177e4SLinus Torvalds       match = p_id_string[1] & (UCHAR) 0x1F;
66281da177e4SLinus Torvalds    else
66291da177e4SLinus Torvalds       match = 7;
66301da177e4SLinus Torvalds 
66311da177e4SLinus Torvalds    while (i > 0)
66321da177e4SLinus Torvalds       {
66331da177e4SLinus Torvalds 
66341da177e4SLinus Torvalds       i--;
66351da177e4SLinus Torvalds 
663647b5d69cSJames Bottomley        if (FPT_scamInfo[match].state == ID_UNASSIGNED)
66371da177e4SLinus Torvalds          {
66381da177e4SLinus Torvalds          for (k=0; k < ID_STRING_LENGTH; k++)
66391da177e4SLinus Torvalds             {
664047b5d69cSJames Bottomley              FPT_scamInfo[match].id_string[k] = p_id_string[k];
66411da177e4SLinus Torvalds             }
66421da177e4SLinus Torvalds 
664347b5d69cSJames Bottomley           FPT_scamInfo[match].id_string[0] |= BIT(7);
664447b5d69cSJames Bottomley           FPT_scamInfo[match].state = ID_ASSIGNED;
664547b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
664647b5d69cSJames Bottomley  	         FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
66471da177e4SLinus Torvalds          return(match);
66481da177e4SLinus Torvalds 
66491da177e4SLinus Torvalds          }
66501da177e4SLinus Torvalds 
66511da177e4SLinus Torvalds 
66521da177e4SLinus Torvalds       match--;
66531da177e4SLinus Torvalds 
66541da177e4SLinus Torvalds       if (match == 0xFF)
66551da177e4SLinus Torvalds 	{
66561da177e4SLinus Torvalds          if (p_id_string[0] & BIT(5))
66571da177e4SLinus Torvalds             match = 7;
66581da177e4SLinus Torvalds          else
66591da177e4SLinus Torvalds             match = MAX_SCSI_TAR-1;
66601da177e4SLinus Torvalds 	}
66611da177e4SLinus Torvalds       }
66621da177e4SLinus Torvalds 
66631da177e4SLinus Torvalds    return(NO_ID_AVAIL);
66641da177e4SLinus Torvalds }
66651da177e4SLinus Torvalds 
66661da177e4SLinus Torvalds 
66671da177e4SLinus Torvalds /*---------------------------------------------------------------------
66681da177e4SLinus Torvalds  *
666947b5d69cSJames Bottomley   * Function: FPT_scsavdi
66701da177e4SLinus Torvalds  *
66711da177e4SLinus Torvalds  * Description: Save off the device SCAM ID strings.
66721da177e4SLinus Torvalds  *
66731da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
66741da177e4SLinus Torvalds 
667547b5d69cSJames Bottomley  static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
66761da177e4SLinus Torvalds {
66771da177e4SLinus Torvalds    UCHAR i,k,max_id;
66781da177e4SLinus Torvalds    USHORT ee_data,sum_data;
66791da177e4SLinus Torvalds 
66801da177e4SLinus Torvalds 
66811da177e4SLinus Torvalds    sum_data = 0x0000;
66821da177e4SLinus Torvalds 
66831da177e4SLinus Torvalds    for (i = 1; i < EE_SCAMBASE/2; i++)
66841da177e4SLinus Torvalds       {
668547b5d69cSJames Bottomley        sum_data += FPT_utilEERead(p_port, i);
66861da177e4SLinus Torvalds       }
66871da177e4SLinus Torvalds 
66881da177e4SLinus Torvalds 
668947b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,1);   /* Enable write access to the EEPROM */
66901da177e4SLinus Torvalds 
66911da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
66921da177e4SLinus Torvalds       max_id = 0x08;
66931da177e4SLinus Torvalds 
66941da177e4SLinus Torvalds    else
66951da177e4SLinus Torvalds       max_id = 0x10;
66961da177e4SLinus Torvalds 
66971da177e4SLinus Torvalds    for (i=0; i < max_id; i++)
66981da177e4SLinus Torvalds       {
66991da177e4SLinus Torvalds 
67001da177e4SLinus Torvalds       for (k=0; k < ID_STRING_LENGTH; k+=2)
67011da177e4SLinus Torvalds          {
670247b5d69cSJames Bottomley           ee_data = FPT_scamInfo[i].id_string[k+1];
67031da177e4SLinus Torvalds          ee_data <<= 8;
670447b5d69cSJames Bottomley           ee_data |= FPT_scamInfo[i].id_string[k];
67051da177e4SLinus Torvalds          sum_data += ee_data;
670647b5d69cSJames Bottomley           FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
67071da177e4SLinus Torvalds             (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
67081da177e4SLinus Torvalds          }
67091da177e4SLinus Torvalds       }
67101da177e4SLinus Torvalds 
67111da177e4SLinus Torvalds 
671247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
671347b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,0);   /* Turn off write access */
67141da177e4SLinus Torvalds }
67151da177e4SLinus Torvalds 
67161da177e4SLinus Torvalds /*---------------------------------------------------------------------
67171da177e4SLinus Torvalds  *
671847b5d69cSJames Bottomley   * Function: FPT_XbowInit
67191da177e4SLinus Torvalds  *
67201da177e4SLinus Torvalds  * Description: Setup the Xbow for normal operation.
67211da177e4SLinus Torvalds  *
67221da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
67231da177e4SLinus Torvalds 
672447b5d69cSJames Bottomley  static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
67251da177e4SLinus Torvalds {
67261da177e4SLinus Torvalds UCHAR i;
67271da177e4SLinus Torvalds 
67281da177e4SLinus Torvalds 	i = RD_HARPOON(port+hp_page_ctrl);
67291da177e4SLinus Torvalds 	WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
67301da177e4SLinus Torvalds 
67311da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsireset,0x00);
67321da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
67331da177e4SLinus Torvalds 
67341da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
67351da177e4SLinus Torvalds 				 FIFO_CLR));
67361da177e4SLinus Torvalds 
67371da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsireset,SCSI_INI);
67381da177e4SLinus Torvalds 
67391da177e4SLinus Torvalds    WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
67401da177e4SLinus Torvalds 
67411da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsisig,0x00);         /*  Clear any signals we might */
67421da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
67431da177e4SLinus Torvalds 
67441da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
67451da177e4SLinus Torvalds 
674647b5d69cSJames Bottomley     FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
67471da177e4SLinus Torvalds 		    BUS_FREE | XFER_CNT_0 | AUTO_INT;
67481da177e4SLinus Torvalds 
67491da177e4SLinus Torvalds    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
675047b5d69cSJames Bottomley  		FPT_default_intena |= SCAM_SEL;
67511da177e4SLinus Torvalds 
675247b5d69cSJames Bottomley     WRW_HARPOON((port+hp_intena), FPT_default_intena);
67531da177e4SLinus Torvalds 
67541da177e4SLinus Torvalds    WR_HARPOON(port+hp_seltimeout,TO_290ms);
67551da177e4SLinus Torvalds 
67561da177e4SLinus Torvalds    /* Turn on SCSI_MODE8 for narrow cards to fix the
67571da177e4SLinus Torvalds       strapping issue with the DUAL CHANNEL card */
67581da177e4SLinus Torvalds    if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
67591da177e4SLinus Torvalds       WR_HARPOON(port+hp_addstat,SCSI_MODE8);
67601da177e4SLinus Torvalds 
67611da177e4SLinus Torvalds 	WR_HARPOON(port+hp_page_ctrl, i);
67621da177e4SLinus Torvalds 
67631da177e4SLinus Torvalds }
67641da177e4SLinus Torvalds 
67651da177e4SLinus Torvalds 
67661da177e4SLinus Torvalds /*---------------------------------------------------------------------
67671da177e4SLinus Torvalds  *
676847b5d69cSJames Bottomley   * Function: FPT_BusMasterInit
67691da177e4SLinus Torvalds  *
67701da177e4SLinus Torvalds  * Description: Initialize the BusMaster for normal operations.
67711da177e4SLinus Torvalds  *
67721da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
67731da177e4SLinus Torvalds 
677447b5d69cSJames Bottomley  static void FPT_BusMasterInit(ULONG p_port)
67751da177e4SLinus Torvalds {
67761da177e4SLinus Torvalds 
67771da177e4SLinus Torvalds 
67781da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
67791da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
67801da177e4SLinus Torvalds 
67811da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
67821da177e4SLinus Torvalds 
67831da177e4SLinus Torvalds 
67841da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
67851da177e4SLinus Torvalds 
67861da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
67871da177e4SLinus Torvalds 
67881da177e4SLinus Torvalds 
67891da177e4SLinus Torvalds    RD_HARPOON(p_port+hp_int_status);        /*Clear interrupts. */
67901da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
67911da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
67921da177e4SLinus Torvalds       ~SCATTER_EN));
67931da177e4SLinus Torvalds }
67941da177e4SLinus Torvalds 
67951da177e4SLinus Torvalds 
67961da177e4SLinus Torvalds /*---------------------------------------------------------------------
67971da177e4SLinus Torvalds  *
679847b5d69cSJames Bottomley   * Function: FPT_DiagEEPROM
67991da177e4SLinus Torvalds  *
68001da177e4SLinus Torvalds  * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
68011da177e4SLinus Torvalds  *              necessary.
68021da177e4SLinus Torvalds  *
68031da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
68041da177e4SLinus Torvalds 
680547b5d69cSJames Bottomley  static void FPT_DiagEEPROM(ULONG p_port)
68061da177e4SLinus Torvalds {
68071da177e4SLinus Torvalds    USHORT index,temp,max_wd_cnt;
68081da177e4SLinus Torvalds 
68091da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
68101da177e4SLinus Torvalds       max_wd_cnt = EEPROM_WD_CNT;
68111da177e4SLinus Torvalds    else
68121da177e4SLinus Torvalds       max_wd_cnt = EEPROM_WD_CNT * 2;
68131da177e4SLinus Torvalds 
681447b5d69cSJames Bottomley     temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
68151da177e4SLinus Torvalds 
68161da177e4SLinus Torvalds    if (temp == 0x4641) {
68171da177e4SLinus Torvalds 
68181da177e4SLinus Torvalds       for (index = 2; index < max_wd_cnt; index++) {
68191da177e4SLinus Torvalds 
682047b5d69cSJames Bottomley           temp += FPT_utilEERead(p_port, index);
68211da177e4SLinus Torvalds 
68221da177e4SLinus Torvalds          }
68231da177e4SLinus Torvalds 
682447b5d69cSJames Bottomley        if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
68251da177e4SLinus Torvalds 
68261da177e4SLinus Torvalds          return;          /*EEPROM is Okay so return now! */
68271da177e4SLinus Torvalds          }
68281da177e4SLinus Torvalds       }
68291da177e4SLinus Torvalds 
68301da177e4SLinus Torvalds 
683147b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
68321da177e4SLinus Torvalds 
68331da177e4SLinus Torvalds    for (index = 0; index < max_wd_cnt; index++) {
68341da177e4SLinus Torvalds 
683547b5d69cSJames Bottomley        FPT_utilEEWrite(p_port, 0x0000, index);
68361da177e4SLinus Torvalds       }
68371da177e4SLinus Torvalds 
68381da177e4SLinus Torvalds    temp = 0;
68391da177e4SLinus Torvalds 
684047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
68411da177e4SLinus Torvalds    temp += 0x4641;
684247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
68431da177e4SLinus Torvalds    temp += 0x3920;
684447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
68451da177e4SLinus Torvalds    temp += 0x3033;
684647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
68471da177e4SLinus Torvalds    temp += 0x2020;
684847b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
68491da177e4SLinus Torvalds    temp += 0x70D3;
685047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
68511da177e4SLinus Torvalds    temp += 0x0010;
685247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
68531da177e4SLinus Torvalds    temp += 0x0003;
685447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
68551da177e4SLinus Torvalds    temp += 0x0007;
68561da177e4SLinus Torvalds 
685747b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
68581da177e4SLinus Torvalds    temp += 0x0000;
685947b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
68601da177e4SLinus Torvalds    temp += 0x0000;
686147b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
68621da177e4SLinus Torvalds    temp += 0x0000;
68631da177e4SLinus Torvalds 
686447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
68651da177e4SLinus Torvalds    temp += 0x4242;
686647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
68671da177e4SLinus Torvalds    temp += 0x4242;
686847b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
68691da177e4SLinus Torvalds    temp += 0x4242;
687047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
68711da177e4SLinus Torvalds    temp += 0x4242;
687247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
68731da177e4SLinus Torvalds    temp += 0x4242;
687447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
68751da177e4SLinus Torvalds    temp += 0x4242;
687647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
68771da177e4SLinus Torvalds    temp += 0x4242;
687847b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
68791da177e4SLinus Torvalds    temp += 0x4242;
68801da177e4SLinus Torvalds 
68811da177e4SLinus Torvalds 
688247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x6C46, 64/2);  /*PRODUCT ID */
68831da177e4SLinus Torvalds    temp += 0x6C46;
688447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x7361, 66/2);  /* FlashPoint LT   */
68851da177e4SLinus Torvalds    temp += 0x7361;
688647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5068, 68/2);
68871da177e4SLinus Torvalds    temp += 0x5068;
688847b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x696F, 70/2);
68891da177e4SLinus Torvalds    temp += 0x696F;
689047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x746E, 72/2);
68911da177e4SLinus Torvalds    temp += 0x746E;
689247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4C20, 74/2);
68931da177e4SLinus Torvalds    temp += 0x4C20;
689447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2054, 76/2);
68951da177e4SLinus Torvalds    temp += 0x2054;
689647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2020, 78/2);
68971da177e4SLinus Torvalds    temp += 0x2020;
68981da177e4SLinus Torvalds 
68991da177e4SLinus Torvalds    index = ((EE_SCAMBASE/2)+(7*16));
690047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
69011da177e4SLinus Torvalds    temp += (0x0700+TYPE_CODE0);
69021da177e4SLinus Torvalds    index++;
690347b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5542, index);            /*Vendor ID code */
69041da177e4SLinus Torvalds    temp += 0x5542;                                /* BUSLOGIC      */
69051da177e4SLinus Torvalds    index++;
690647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4C53, index);
69071da177e4SLinus Torvalds    temp += 0x4C53;
69081da177e4SLinus Torvalds    index++;
690947b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x474F, index);
69101da177e4SLinus Torvalds    temp += 0x474F;
69111da177e4SLinus Torvalds    index++;
691247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4349, index);
69131da177e4SLinus Torvalds    temp += 0x4349;
69141da177e4SLinus Torvalds    index++;
691547b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5442, index);            /*Vendor unique code */
69161da177e4SLinus Torvalds    temp += 0x5442;                         /* BT- 930           */
69171da177e4SLinus Torvalds    index++;
691847b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x202D, index);
69191da177e4SLinus Torvalds    temp += 0x202D;
69201da177e4SLinus Torvalds    index++;
692147b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3339, index);
69221da177e4SLinus Torvalds    temp += 0x3339;
69231da177e4SLinus Torvalds    index++;                                 /*Serial #          */
692447b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2030, index);             /* 01234567         */
69251da177e4SLinus Torvalds    temp += 0x2030;
69261da177e4SLinus Torvalds    index++;
692747b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5453, index);
69281da177e4SLinus Torvalds    temp += 0x5453;
69291da177e4SLinus Torvalds    index++;
693047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5645, index);
69311da177e4SLinus Torvalds    temp += 0x5645;
69321da177e4SLinus Torvalds    index++;
693347b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2045, index);
69341da177e4SLinus Torvalds    temp += 0x2045;
69351da177e4SLinus Torvalds    index++;
693647b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x202F, index);
69371da177e4SLinus Torvalds    temp += 0x202F;
69381da177e4SLinus Torvalds    index++;
693947b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4F4A, index);
69401da177e4SLinus Torvalds    temp += 0x4F4A;
69411da177e4SLinus Torvalds    index++;
694247b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x204E, index);
69431da177e4SLinus Torvalds    temp += 0x204E;
69441da177e4SLinus Torvalds    index++;
694547b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3539, index);
69461da177e4SLinus Torvalds    temp += 0x3539;
69471da177e4SLinus Torvalds 
69481da177e4SLinus Torvalds 
69491da177e4SLinus Torvalds 
695047b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
69511da177e4SLinus Torvalds 
695247b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
69531da177e4SLinus Torvalds 
69541da177e4SLinus Torvalds }
69551da177e4SLinus Torvalds 
69561da177e4SLinus Torvalds 
69571da177e4SLinus Torvalds /*---------------------------------------------------------------------
69581da177e4SLinus Torvalds  *
69591da177e4SLinus Torvalds  * Function: Queue Search Select
69601da177e4SLinus Torvalds  *
69611da177e4SLinus Torvalds  * Description: Try to find a new command to execute.
69621da177e4SLinus Torvalds  *
69631da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
69641da177e4SLinus Torvalds 
696547b5d69cSJames Bottomley  static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
69661da177e4SLinus Torvalds {
69671da177e4SLinus Torvalds    UCHAR scan_ptr, lun;
69681da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
69691da177e4SLinus Torvalds 	PSCCB pOldSccb;
69701da177e4SLinus Torvalds 
69711da177e4SLinus Torvalds    scan_ptr = pCurrCard->scanIndex;
69721da177e4SLinus Torvalds 	do
69731da177e4SLinus Torvalds 	{
697447b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
69751da177e4SLinus Torvalds 		if((pCurrCard->globalFlags & F_CONLUN_IO) &&
69761da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
69771da177e4SLinus Torvalds 		{
69781da177e4SLinus Torvalds 			if (currTar_Info->TarSelQ_Cnt != 0)
69791da177e4SLinus Torvalds 			{
69801da177e4SLinus Torvalds 
69811da177e4SLinus Torvalds 				scan_ptr++;
69821da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR)
69831da177e4SLinus Torvalds 					scan_ptr = 0;
69841da177e4SLinus Torvalds 
69851da177e4SLinus Torvalds 				for(lun=0; lun < MAX_LUN; lun++)
69861da177e4SLinus Torvalds 				{
698747b5d69cSJames Bottomley  					if(currTar_Info->TarLUNBusy[lun] == 0)
69881da177e4SLinus Torvalds 					{
69891da177e4SLinus Torvalds 
69901da177e4SLinus Torvalds 						pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
69911da177e4SLinus Torvalds 						pOldSccb = NULL;
69921da177e4SLinus Torvalds 
69931da177e4SLinus Torvalds 						while((pCurrCard->currentSCCB != NULL) &&
69941da177e4SLinus Torvalds 								 (lun != pCurrCard->currentSCCB->Lun))
69951da177e4SLinus Torvalds 						{
69961da177e4SLinus Torvalds 							pOldSccb = pCurrCard->currentSCCB;
69971da177e4SLinus Torvalds 							pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
69981da177e4SLinus Torvalds 																	Sccb_forwardlink;
69991da177e4SLinus Torvalds 						}
70001da177e4SLinus Torvalds 						if(pCurrCard->currentSCCB == NULL)
70011da177e4SLinus Torvalds 							continue;
70021da177e4SLinus Torvalds 						if(pOldSccb != NULL)
70031da177e4SLinus Torvalds 						{
70041da177e4SLinus Torvalds 							pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
70051da177e4SLinus Torvalds 																	Sccb_forwardlink;
70061da177e4SLinus Torvalds 							pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
70071da177e4SLinus Torvalds 																	Sccb_backlink;
70081da177e4SLinus Torvalds 							currTar_Info->TarSelQ_Cnt--;
70091da177e4SLinus Torvalds 						}
70101da177e4SLinus Torvalds 						else
70111da177e4SLinus Torvalds 						{
70121da177e4SLinus Torvalds 							currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
70131da177e4SLinus Torvalds 
70141da177e4SLinus Torvalds 							if (currTar_Info->TarSelQ_Head == NULL)
70151da177e4SLinus Torvalds 							{
70161da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Tail = NULL;
70171da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Cnt = 0;
70181da177e4SLinus Torvalds 							}
70191da177e4SLinus Torvalds 							else
70201da177e4SLinus Torvalds 							{
70211da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Cnt--;
70221da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
70231da177e4SLinus Torvalds 							}
70241da177e4SLinus Torvalds 						}
70251da177e4SLinus Torvalds 					pCurrCard->scanIndex = scan_ptr;
70261da177e4SLinus Torvalds 
70271da177e4SLinus Torvalds 					pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
70281da177e4SLinus Torvalds 
70291da177e4SLinus Torvalds 					break;
70301da177e4SLinus Torvalds 					}
70311da177e4SLinus Torvalds 				}
70321da177e4SLinus Torvalds 			}
70331da177e4SLinus Torvalds 
70341da177e4SLinus Torvalds 			else
70351da177e4SLinus Torvalds 			{
70361da177e4SLinus Torvalds 				scan_ptr++;
70371da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR) {
70381da177e4SLinus Torvalds 					scan_ptr = 0;
70391da177e4SLinus Torvalds 				}
70401da177e4SLinus Torvalds 			}
70411da177e4SLinus Torvalds 
70421da177e4SLinus Torvalds 		}
70431da177e4SLinus Torvalds 		else
70441da177e4SLinus Torvalds 		{
70451da177e4SLinus Torvalds 			if ((currTar_Info->TarSelQ_Cnt != 0) &&
704647b5d69cSJames Bottomley  				(currTar_Info->TarLUNBusy[0] == 0))
70471da177e4SLinus Torvalds 			{
70481da177e4SLinus Torvalds 
70491da177e4SLinus Torvalds 				pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
70501da177e4SLinus Torvalds 
70511da177e4SLinus Torvalds 				currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
70521da177e4SLinus Torvalds 
70531da177e4SLinus Torvalds 				if (currTar_Info->TarSelQ_Head == NULL)
70541da177e4SLinus Torvalds 				{
70551da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Tail = NULL;
70561da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Cnt = 0;
70571da177e4SLinus Torvalds 				}
70581da177e4SLinus Torvalds 				else
70591da177e4SLinus Torvalds 				{
70601da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Cnt--;
70611da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
70621da177e4SLinus Torvalds 				}
70631da177e4SLinus Torvalds 
70641da177e4SLinus Torvalds 				scan_ptr++;
70651da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR)
70661da177e4SLinus Torvalds 					scan_ptr = 0;
70671da177e4SLinus Torvalds 
70681da177e4SLinus Torvalds 				pCurrCard->scanIndex = scan_ptr;
70691da177e4SLinus Torvalds 
70701da177e4SLinus Torvalds 				pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
70711da177e4SLinus Torvalds 
70721da177e4SLinus Torvalds 				break;
70731da177e4SLinus Torvalds 			}
70741da177e4SLinus Torvalds 
70751da177e4SLinus Torvalds 			else
70761da177e4SLinus Torvalds 			{
70771da177e4SLinus Torvalds 				scan_ptr++;
70781da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR)
70791da177e4SLinus Torvalds 				{
70801da177e4SLinus Torvalds 					scan_ptr = 0;
70811da177e4SLinus Torvalds 				}
70821da177e4SLinus Torvalds 			}
70831da177e4SLinus Torvalds 		}
70841da177e4SLinus Torvalds 	} while (scan_ptr != pCurrCard->scanIndex);
70851da177e4SLinus Torvalds }
70861da177e4SLinus Torvalds 
70871da177e4SLinus Torvalds 
70881da177e4SLinus Torvalds /*---------------------------------------------------------------------
70891da177e4SLinus Torvalds  *
70901da177e4SLinus Torvalds  * Function: Queue Select Fail
70911da177e4SLinus Torvalds  *
70921da177e4SLinus Torvalds  * Description: Add the current SCCB to the head of the Queue.
70931da177e4SLinus Torvalds  *
70941da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
70951da177e4SLinus Torvalds 
709647b5d69cSJames Bottomley  static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
70971da177e4SLinus Torvalds {
70981da177e4SLinus Torvalds    UCHAR thisTarg;
70991da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
71001da177e4SLinus Torvalds 
71011da177e4SLinus Torvalds    if (pCurrCard->currentSCCB != NULL)
71021da177e4SLinus Torvalds 	  {
71031da177e4SLinus Torvalds 	  thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
710447b5d69cSJames Bottomley        currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
71051da177e4SLinus Torvalds 
71061da177e4SLinus Torvalds       pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
71071da177e4SLinus Torvalds 
71081da177e4SLinus Torvalds       pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
71091da177e4SLinus Torvalds 
71101da177e4SLinus Torvalds 	  if (currTar_Info->TarSelQ_Cnt == 0)
71111da177e4SLinus Torvalds 		 {
71121da177e4SLinus Torvalds 		 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
71131da177e4SLinus Torvalds 		 }
71141da177e4SLinus Torvalds 
71151da177e4SLinus Torvalds 	  else
71161da177e4SLinus Torvalds 		 {
71171da177e4SLinus Torvalds 		 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
71181da177e4SLinus Torvalds 		 }
71191da177e4SLinus Torvalds 
71201da177e4SLinus Torvalds 
71211da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
71221da177e4SLinus Torvalds 
71231da177e4SLinus Torvalds 	  pCurrCard->currentSCCB = NULL;
71241da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Cnt++;
71251da177e4SLinus Torvalds 	  }
71261da177e4SLinus Torvalds }
71271da177e4SLinus Torvalds /*---------------------------------------------------------------------
71281da177e4SLinus Torvalds  *
71291da177e4SLinus Torvalds  * Function: Queue Command Complete
71301da177e4SLinus Torvalds  *
71311da177e4SLinus Torvalds  * Description: Call the callback function with the current SCCB.
71321da177e4SLinus Torvalds  *
71331da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
71341da177e4SLinus Torvalds 
713547b5d69cSJames Bottomley  static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
713647b5d69cSJames Bottomley  				 UCHAR p_card)
71371da177e4SLinus Torvalds {
71381da177e4SLinus Torvalds 
71391da177e4SLinus Torvalds    UCHAR i, SCSIcmd;
71401da177e4SLinus Torvalds    CALL_BK_FN callback;
71411da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
71421da177e4SLinus Torvalds 
71431da177e4SLinus Torvalds    SCSIcmd = p_sccb->Cdb[0];
71441da177e4SLinus Torvalds 
71451da177e4SLinus Torvalds 
71461da177e4SLinus Torvalds    if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
71471da177e4SLinus Torvalds 
71481da177e4SLinus Torvalds 	  if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
71491da177e4SLinus Torvalds 		 (p_sccb->HostStatus == SCCB_COMPLETE)                             &&
71501da177e4SLinus Torvalds 		 (p_sccb->TargetStatus != SSCHECK))
71511da177e4SLinus Torvalds 
71521da177e4SLinus Torvalds 		 if ((SCSIcmd == SCSI_READ)             ||
71531da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_WRITE)            ||
71541da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_READ_EXTENDED)    ||
71551da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_WRITE_EXTENDED)   ||
71561da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
71571da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_START_STOP_UNIT)  ||
71581da177e4SLinus Torvalds 			 (pCurrCard->globalFlags & F_NO_FILTER)
71591da177e4SLinus Torvalds 			)
71601da177e4SLinus Torvalds 			   p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
71611da177e4SLinus Torvalds 	  }
71621da177e4SLinus Torvalds 
71631da177e4SLinus Torvalds 
71641da177e4SLinus Torvalds 	if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
71651da177e4SLinus Torvalds 	{
71661da177e4SLinus Torvalds 	   if (p_sccb->HostStatus || p_sccb->TargetStatus)
71671da177e4SLinus Torvalds 		  p_sccb->SccbStatus = SCCB_ERROR;
71681da177e4SLinus Torvalds 	   else
71691da177e4SLinus Torvalds 		  p_sccb->SccbStatus = SCCB_SUCCESS;
71701da177e4SLinus Torvalds 	}
71711da177e4SLinus Torvalds 
71721da177e4SLinus Torvalds    if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
71731da177e4SLinus Torvalds 
71741da177e4SLinus Torvalds 	  p_sccb->CdbLength = p_sccb->Save_CdbLen;
71751da177e4SLinus Torvalds 	  for (i=0; i < 6; i++) {
71761da177e4SLinus Torvalds 		 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
71771da177e4SLinus Torvalds 		 }
71781da177e4SLinus Torvalds 	  }
71791da177e4SLinus Torvalds 
71801da177e4SLinus Torvalds    if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
71811da177e4SLinus Torvalds 	  (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
71821da177e4SLinus Torvalds 
718347b5d69cSJames Bottomley  		 FPT_utilUpdateResidual(p_sccb);
71841da177e4SLinus Torvalds 		 }
71851da177e4SLinus Torvalds 
71861da177e4SLinus Torvalds    pCurrCard->cmdCounter--;
71871da177e4SLinus Torvalds    if (!pCurrCard->cmdCounter) {
71881da177e4SLinus Torvalds 
71891da177e4SLinus Torvalds 	  if (pCurrCard->globalFlags & F_GREEN_PC) {
71901da177e4SLinus Torvalds 		 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
71911da177e4SLinus Torvalds 		 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
71921da177e4SLinus Torvalds 		 }
71931da177e4SLinus Torvalds 
71941da177e4SLinus Torvalds 	  WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
71951da177e4SLinus Torvalds 	  (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
71961da177e4SLinus Torvalds 
71971da177e4SLinus Torvalds 	  }
71981da177e4SLinus Torvalds 
71991da177e4SLinus Torvalds 	if(pCurrCard->discQCount != 0)
72001da177e4SLinus Torvalds 	{
720147b5d69cSJames Bottomley        currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
72021da177e4SLinus Torvalds 		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
72031da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
72041da177e4SLinus Torvalds 		{
72051da177e4SLinus Torvalds 			pCurrCard->discQCount--;
72061da177e4SLinus Torvalds 			pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
72071da177e4SLinus Torvalds 		}
72081da177e4SLinus Torvalds 		else
72091da177e4SLinus Torvalds 		{
72101da177e4SLinus Torvalds 			if(p_sccb->Sccb_tag)
72111da177e4SLinus Torvalds 			{
72121da177e4SLinus Torvalds 				pCurrCard->discQCount--;
72131da177e4SLinus Torvalds 				pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
72141da177e4SLinus Torvalds 			}else
72151da177e4SLinus Torvalds 			{
72161da177e4SLinus Torvalds 				pCurrCard->discQCount--;
72171da177e4SLinus Torvalds 				pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
72181da177e4SLinus Torvalds 			}
72191da177e4SLinus Torvalds 		}
72201da177e4SLinus Torvalds 
72211da177e4SLinus Torvalds 	}
72221da177e4SLinus Torvalds 
72231da177e4SLinus Torvalds 	callback = (CALL_BK_FN)p_sccb->SccbCallback;
72241da177e4SLinus Torvalds    callback(p_sccb);
72251da177e4SLinus Torvalds    pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
72261da177e4SLinus Torvalds    pCurrCard->currentSCCB = NULL;
72271da177e4SLinus Torvalds }
72281da177e4SLinus Torvalds 
72291da177e4SLinus Torvalds 
72301da177e4SLinus Torvalds /*---------------------------------------------------------------------
72311da177e4SLinus Torvalds  *
72321da177e4SLinus Torvalds  * Function: Queue Disconnect
72331da177e4SLinus Torvalds  *
72341da177e4SLinus Torvalds  * Description: Add SCCB to our disconnect array.
72351da177e4SLinus Torvalds  *
72361da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
723747b5d69cSJames Bottomley  static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
72381da177e4SLinus Torvalds {
72391da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
72401da177e4SLinus Torvalds 
724147b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
72421da177e4SLinus Torvalds 
724347b5d69cSJames Bottomley  	if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
72441da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
72451da177e4SLinus Torvalds 	{
724647b5d69cSJames Bottomley  		FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
72471da177e4SLinus Torvalds 	}
72481da177e4SLinus Torvalds 	else
72491da177e4SLinus Torvalds 	{
72501da177e4SLinus Torvalds 		if (p_sccb->Sccb_tag)
72511da177e4SLinus Torvalds 		{
725247b5d69cSJames Bottomley  			FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
725347b5d69cSJames Bottomley  			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
725447b5d69cSJames Bottomley  			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
72551da177e4SLinus Torvalds 		}else
72561da177e4SLinus Torvalds 		{
725747b5d69cSJames Bottomley  			FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
72581da177e4SLinus Torvalds 		}
72591da177e4SLinus Torvalds 	}
726047b5d69cSJames Bottomley  	FPT_BL_Card[p_card].currentSCCB = NULL;
72611da177e4SLinus Torvalds }
72621da177e4SLinus Torvalds 
72631da177e4SLinus Torvalds 
72641da177e4SLinus Torvalds /*---------------------------------------------------------------------
72651da177e4SLinus Torvalds  *
72661da177e4SLinus Torvalds  * Function: Queue Flush SCCB
72671da177e4SLinus Torvalds  *
72681da177e4SLinus Torvalds  * Description: Flush all SCCB's back to the host driver for this target.
72691da177e4SLinus Torvalds  *
72701da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
72711da177e4SLinus Torvalds 
727247b5d69cSJames Bottomley  static void  FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
72731da177e4SLinus Torvalds {
72741da177e4SLinus Torvalds    UCHAR qtag,thisTarg;
72751da177e4SLinus Torvalds    PSCCB currSCCB;
72761da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
72771da177e4SLinus Torvalds 
727847b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
72791da177e4SLinus Torvalds 	if(currSCCB != NULL)
72801da177e4SLinus Torvalds 	{
72811da177e4SLinus Torvalds 	   thisTarg = (UCHAR)currSCCB->TargID;
728247b5d69cSJames Bottomley     	currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
72831da177e4SLinus Torvalds 
72841da177e4SLinus Torvalds 	   for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
72851da177e4SLinus Torvalds 
728647b5d69cSJames Bottomley  		  if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
728747b5d69cSJames Bottomley  					(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
72881da177e4SLinus Torvalds 			 {
72891da177e4SLinus Torvalds 
729047b5d69cSJames Bottomley  			 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
72911da177e4SLinus Torvalds 
729247b5d69cSJames Bottomley  			 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
72931da177e4SLinus Torvalds 
729447b5d69cSJames Bottomley  			 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
72951da177e4SLinus Torvalds 			 currTar_Info->TarTagQ_Cnt--;
72961da177e4SLinus Torvalds 
72971da177e4SLinus Torvalds 			 }
72981da177e4SLinus Torvalds 		  }
72991da177e4SLinus Torvalds 	}
73001da177e4SLinus Torvalds 
73011da177e4SLinus Torvalds }
73021da177e4SLinus Torvalds 
73031da177e4SLinus Torvalds /*---------------------------------------------------------------------
73041da177e4SLinus Torvalds  *
73051da177e4SLinus Torvalds  * Function: Queue Flush Target SCCB
73061da177e4SLinus Torvalds  *
73071da177e4SLinus Torvalds  * Description: Flush all SCCB's back to the host driver for this target.
73081da177e4SLinus Torvalds  *
73091da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
73101da177e4SLinus Torvalds 
731147b5d69cSJames Bottomley  static void  FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
731247b5d69cSJames Bottomley  				    UCHAR error_code)
73131da177e4SLinus Torvalds {
73141da177e4SLinus Torvalds    UCHAR qtag;
73151da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
73161da177e4SLinus Torvalds 
731747b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
73181da177e4SLinus Torvalds 
73191da177e4SLinus Torvalds    for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
73201da177e4SLinus Torvalds 
732147b5d69cSJames Bottomley  	  if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
732247b5d69cSJames Bottomley  				(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
73231da177e4SLinus Torvalds 		 {
73241da177e4SLinus Torvalds 
732547b5d69cSJames Bottomley  		 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
73261da177e4SLinus Torvalds 
732747b5d69cSJames Bottomley  		 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
73281da177e4SLinus Torvalds 
732947b5d69cSJames Bottomley  		 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
73301da177e4SLinus Torvalds 		 currTar_Info->TarTagQ_Cnt--;
73311da177e4SLinus Torvalds 
73321da177e4SLinus Torvalds 		 }
73331da177e4SLinus Torvalds 	  }
73341da177e4SLinus Torvalds 
73351da177e4SLinus Torvalds }
73361da177e4SLinus Torvalds 
73371da177e4SLinus Torvalds 
73381da177e4SLinus Torvalds 
73391da177e4SLinus Torvalds 
73401da177e4SLinus Torvalds 
734147b5d69cSJames Bottomley  static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
73421da177e4SLinus Torvalds {
73431da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
734447b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
73451da177e4SLinus Torvalds 
73461da177e4SLinus Torvalds    p_SCCB->Sccb_forwardlink = NULL;
73471da177e4SLinus Torvalds 
73481da177e4SLinus Torvalds    p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
73491da177e4SLinus Torvalds 
73501da177e4SLinus Torvalds    if (currTar_Info->TarSelQ_Cnt == 0) {
73511da177e4SLinus Torvalds 
73521da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Head = p_SCCB;
73531da177e4SLinus Torvalds 	  }
73541da177e4SLinus Torvalds 
73551da177e4SLinus Torvalds    else {
73561da177e4SLinus Torvalds 
73571da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
73581da177e4SLinus Torvalds 	  }
73591da177e4SLinus Torvalds 
73601da177e4SLinus Torvalds 
73611da177e4SLinus Torvalds    currTar_Info->TarSelQ_Tail = p_SCCB;
73621da177e4SLinus Torvalds    currTar_Info->TarSelQ_Cnt++;
73631da177e4SLinus Torvalds }
73641da177e4SLinus Torvalds 
73651da177e4SLinus Torvalds 
73661da177e4SLinus Torvalds /*---------------------------------------------------------------------
73671da177e4SLinus Torvalds  *
73681da177e4SLinus Torvalds  * Function: Queue Find SCCB
73691da177e4SLinus Torvalds  *
73701da177e4SLinus Torvalds  * Description: Search the target select Queue for this SCCB, and
73711da177e4SLinus Torvalds  *              remove it if found.
73721da177e4SLinus Torvalds  *
73731da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
73741da177e4SLinus Torvalds 
737547b5d69cSJames Bottomley  static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
73761da177e4SLinus Torvalds {
73771da177e4SLinus Torvalds    PSCCB q_ptr;
73781da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
73791da177e4SLinus Torvalds 
738047b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
73811da177e4SLinus Torvalds 
73821da177e4SLinus Torvalds    q_ptr = currTar_Info->TarSelQ_Head;
73831da177e4SLinus Torvalds 
73841da177e4SLinus Torvalds    while(q_ptr != NULL) {
73851da177e4SLinus Torvalds 
73861da177e4SLinus Torvalds 	  if (q_ptr == p_SCCB) {
73871da177e4SLinus Torvalds 
73881da177e4SLinus Torvalds 
73891da177e4SLinus Torvalds 		 if (currTar_Info->TarSelQ_Head == q_ptr) {
73901da177e4SLinus Torvalds 
73911da177e4SLinus Torvalds 			currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
73921da177e4SLinus Torvalds 			}
73931da177e4SLinus Torvalds 
73941da177e4SLinus Torvalds 		 if (currTar_Info->TarSelQ_Tail == q_ptr) {
73951da177e4SLinus Torvalds 
73961da177e4SLinus Torvalds 			currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
73971da177e4SLinus Torvalds 			}
73981da177e4SLinus Torvalds 
73991da177e4SLinus Torvalds 		 if (q_ptr->Sccb_forwardlink != NULL) {
74001da177e4SLinus Torvalds 			q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
74011da177e4SLinus Torvalds 			}
74021da177e4SLinus Torvalds 
74031da177e4SLinus Torvalds 		 if (q_ptr->Sccb_backlink != NULL) {
74041da177e4SLinus Torvalds 			q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
74051da177e4SLinus Torvalds 			}
74061da177e4SLinus Torvalds 
74071da177e4SLinus Torvalds 		 currTar_Info->TarSelQ_Cnt--;
74081da177e4SLinus Torvalds 
740947b5d69cSJames Bottomley  		 return(1);
74101da177e4SLinus Torvalds 		 }
74111da177e4SLinus Torvalds 
74121da177e4SLinus Torvalds 	  else {
74131da177e4SLinus Torvalds 		 q_ptr = q_ptr->Sccb_forwardlink;
74141da177e4SLinus Torvalds 		 }
74151da177e4SLinus Torvalds 	  }
74161da177e4SLinus Torvalds 
74171da177e4SLinus Torvalds 
741847b5d69cSJames Bottomley     return(0);
74191da177e4SLinus Torvalds 
74201da177e4SLinus Torvalds }
74211da177e4SLinus Torvalds 
74221da177e4SLinus Torvalds 
74231da177e4SLinus Torvalds /*---------------------------------------------------------------------
74241da177e4SLinus Torvalds  *
74251da177e4SLinus Torvalds  * Function: Utility Update Residual Count
74261da177e4SLinus Torvalds  *
74271da177e4SLinus Torvalds  * Description: Update the XferCnt to the remaining byte count.
74281da177e4SLinus Torvalds  *              If we transferred all the data then just write zero.
74291da177e4SLinus Torvalds  *              If Non-SG transfer then report Total Cnt - Actual Transfer
74301da177e4SLinus Torvalds  *              Cnt.  For SG transfers add the count fields of all
74311da177e4SLinus Torvalds  *              remaining SG elements, as well as any partial remaining
74321da177e4SLinus Torvalds  *              element.
74331da177e4SLinus Torvalds  *
74341da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
74351da177e4SLinus Torvalds 
743647b5d69cSJames Bottomley  static void  FPT_utilUpdateResidual(PSCCB p_SCCB)
74371da177e4SLinus Torvalds {
74381da177e4SLinus Torvalds    ULONG partial_cnt;
74391da177e4SLinus Torvalds    UINT  sg_index;
74401da177e4SLinus Torvalds    ULONG *sg_ptr;
74411da177e4SLinus Torvalds 
74421da177e4SLinus Torvalds    if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
74431da177e4SLinus Torvalds 
74441da177e4SLinus Torvalds 	  p_SCCB->DataLength = 0x0000;
74451da177e4SLinus Torvalds 	  }
74461da177e4SLinus Torvalds 
74471da177e4SLinus Torvalds    else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
74481da177e4SLinus Torvalds 
74491da177e4SLinus Torvalds 		 partial_cnt = 0x0000;
74501da177e4SLinus Torvalds 
74511da177e4SLinus Torvalds 		 sg_index = p_SCCB->Sccb_sgseg;
74521da177e4SLinus Torvalds 
74531da177e4SLinus Torvalds 		 sg_ptr = (ULONG *)p_SCCB->DataPointer;
74541da177e4SLinus Torvalds 
74551da177e4SLinus Torvalds 		 if (p_SCCB->Sccb_SGoffset) {
74561da177e4SLinus Torvalds 
74571da177e4SLinus Torvalds 			partial_cnt = p_SCCB->Sccb_SGoffset;
74581da177e4SLinus Torvalds 			sg_index++;
74591da177e4SLinus Torvalds 			}
74601da177e4SLinus Torvalds 
74611da177e4SLinus Torvalds 		 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
74621da177e4SLinus Torvalds 			p_SCCB->DataLength ) {
74631da177e4SLinus Torvalds 
74641da177e4SLinus Torvalds 			partial_cnt += *(sg_ptr+(sg_index * 2));
74651da177e4SLinus Torvalds 			sg_index++;
74661da177e4SLinus Torvalds 			}
74671da177e4SLinus Torvalds 
74681da177e4SLinus Torvalds 		 p_SCCB->DataLength = partial_cnt;
74691da177e4SLinus Torvalds 		 }
74701da177e4SLinus Torvalds 
74711da177e4SLinus Torvalds 	  else {
74721da177e4SLinus Torvalds 
74731da177e4SLinus Torvalds 		 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
74741da177e4SLinus Torvalds 		 }
74751da177e4SLinus Torvalds }
74761da177e4SLinus Torvalds 
74771da177e4SLinus Torvalds 
74781da177e4SLinus Torvalds /*---------------------------------------------------------------------
74791da177e4SLinus Torvalds  *
74801da177e4SLinus Torvalds  * Function: Wait 1 Second
74811da177e4SLinus Torvalds  *
74821da177e4SLinus Torvalds  * Description: Wait for 1 second.
74831da177e4SLinus Torvalds  *
74841da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
74851da177e4SLinus Torvalds 
748647b5d69cSJames Bottomley  static void FPT_Wait1Second(ULONG p_port)
74871da177e4SLinus Torvalds {
74881da177e4SLinus Torvalds    UCHAR i;
74891da177e4SLinus Torvalds 
74901da177e4SLinus Torvalds    for(i=0; i < 4; i++) {
74911da177e4SLinus Torvalds 
749247b5d69cSJames Bottomley  	  FPT_Wait(p_port, TO_250ms);
74931da177e4SLinus Torvalds 
74941da177e4SLinus Torvalds 	  if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
74951da177e4SLinus Torvalds 		 break;
74961da177e4SLinus Torvalds 
74971da177e4SLinus Torvalds 	  if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
74981da177e4SLinus Torvalds 		 break;
74991da177e4SLinus Torvalds 	  }
75001da177e4SLinus Torvalds }
75011da177e4SLinus Torvalds 
75021da177e4SLinus Torvalds 
75031da177e4SLinus Torvalds /*---------------------------------------------------------------------
75041da177e4SLinus Torvalds  *
750547b5d69cSJames Bottomley   * Function: FPT_Wait
75061da177e4SLinus Torvalds  *
75071da177e4SLinus Torvalds  * Description: Wait the desired delay.
75081da177e4SLinus Torvalds  *
75091da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
75101da177e4SLinus Torvalds 
751147b5d69cSJames Bottomley  static void FPT_Wait(ULONG p_port, UCHAR p_delay)
75121da177e4SLinus Torvalds {
75131da177e4SLinus Torvalds    UCHAR old_timer;
75141da177e4SLinus Torvalds    UCHAR green_flag;
75151da177e4SLinus Torvalds 
75161da177e4SLinus Torvalds    old_timer = RD_HARPOON(p_port+hp_seltimeout);
75171da177e4SLinus Torvalds 
75181da177e4SLinus Torvalds    green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
75191da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
75201da177e4SLinus Torvalds 
75211da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,p_delay);
75221da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
752347b5d69cSJames Bottomley     WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
75241da177e4SLinus Torvalds 
75251da177e4SLinus Torvalds 
75261da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0,
75271da177e4SLinus Torvalds 	  (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
75281da177e4SLinus Torvalds 
75291da177e4SLinus Torvalds    while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
75301da177e4SLinus Torvalds 
75311da177e4SLinus Torvalds 	  if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
75321da177e4SLinus Torvalds 		 break;
75331da177e4SLinus Torvalds 
75341da177e4SLinus Torvalds 	  if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
75351da177e4SLinus Torvalds 		 break;
75361da177e4SLinus Torvalds 	  }
75371da177e4SLinus Torvalds 
75381da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0,
75391da177e4SLinus Torvalds 	  (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
75401da177e4SLinus Torvalds 
75411da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
754247b5d69cSJames Bottomley     WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
75431da177e4SLinus Torvalds 
75441da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
75451da177e4SLinus Torvalds 
75461da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,old_timer);
75471da177e4SLinus Torvalds }
75481da177e4SLinus Torvalds 
75491da177e4SLinus Torvalds 
75501da177e4SLinus Torvalds /*---------------------------------------------------------------------
75511da177e4SLinus Torvalds  *
75521da177e4SLinus Torvalds  * Function: Enable/Disable Write to EEPROM
75531da177e4SLinus Torvalds  *
75541da177e4SLinus Torvalds  * Description: The EEPROM must first be enabled for writes
75551da177e4SLinus Torvalds  *              A total of 9 clocks are needed.
75561da177e4SLinus Torvalds  *
75571da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
75581da177e4SLinus Torvalds 
755947b5d69cSJames Bottomley  static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
75601da177e4SLinus Torvalds {
75611da177e4SLinus Torvalds    UCHAR ee_value;
75621da177e4SLinus Torvalds 
75631da177e4SLinus Torvalds    ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
75641da177e4SLinus Torvalds 
75651da177e4SLinus Torvalds    if (p_mode)
75661da177e4SLinus Torvalds 
756747b5d69cSJames Bottomley  	  FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
75681da177e4SLinus Torvalds 
75691da177e4SLinus Torvalds    else
75701da177e4SLinus Torvalds 
75711da177e4SLinus Torvalds 
757247b5d69cSJames Bottomley  	  FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
75731da177e4SLinus Torvalds 
75741da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
75751da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /*Turn off Master Select */
75761da177e4SLinus Torvalds }
75771da177e4SLinus Torvalds 
75781da177e4SLinus Torvalds 
75791da177e4SLinus Torvalds /*---------------------------------------------------------------------
75801da177e4SLinus Torvalds  *
75811da177e4SLinus Torvalds  * Function: Write EEPROM
75821da177e4SLinus Torvalds  *
75831da177e4SLinus Torvalds  * Description: Write a word to the EEPROM at the specified
75841da177e4SLinus Torvalds  *              address.
75851da177e4SLinus Torvalds  *
75861da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
75871da177e4SLinus Torvalds 
758847b5d69cSJames Bottomley  static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
75891da177e4SLinus Torvalds {
75901da177e4SLinus Torvalds 
75911da177e4SLinus Torvalds    UCHAR ee_value;
75921da177e4SLinus Torvalds    USHORT i;
75931da177e4SLinus Torvalds 
75941da177e4SLinus Torvalds    ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
75951da177e4SLinus Torvalds 		   (SEE_MS | SEE_CS));
75961da177e4SLinus Torvalds 
75971da177e4SLinus Torvalds 
75981da177e4SLinus Torvalds 
759947b5d69cSJames Bottomley     FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
76001da177e4SLinus Torvalds 
76011da177e4SLinus Torvalds 
76021da177e4SLinus Torvalds    ee_value |= (SEE_MS + SEE_CS);
76031da177e4SLinus Torvalds 
76041da177e4SLinus Torvalds    for(i = 0x8000; i != 0; i>>=1) {
76051da177e4SLinus Torvalds 
76061da177e4SLinus Torvalds 	  if (i & ee_data)
76071da177e4SLinus Torvalds 	 ee_value |= SEE_DO;
76081da177e4SLinus Torvalds 	  else
76091da177e4SLinus Torvalds 	 ee_value &= ~SEE_DO;
76101da177e4SLinus Torvalds 
76111da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76121da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76131da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;          /* Clock  data! */
76141da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76151da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76161da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
76171da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76181da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76191da177e4SLinus Torvalds 	  }
76201da177e4SLinus Torvalds    ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
76211da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
76221da177e4SLinus Torvalds 
762347b5d69cSJames Bottomley     FPT_Wait(p_port, TO_10ms);
76241da177e4SLinus Torvalds 
76251da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
76261da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));       /* Turn off CS */
76271da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /* Turn off Master Select */
76281da177e4SLinus Torvalds }
76291da177e4SLinus Torvalds 
76301da177e4SLinus Torvalds /*---------------------------------------------------------------------
76311da177e4SLinus Torvalds  *
76321da177e4SLinus Torvalds  * Function: Read EEPROM
76331da177e4SLinus Torvalds  *
76341da177e4SLinus Torvalds  * Description: Read a word from the EEPROM at the desired
76351da177e4SLinus Torvalds  *              address.
76361da177e4SLinus Torvalds  *
76371da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
76381da177e4SLinus Torvalds 
763947b5d69cSJames Bottomley  static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
76401da177e4SLinus Torvalds {
76411da177e4SLinus Torvalds    USHORT i, ee_data1, ee_data2;
76421da177e4SLinus Torvalds 
76431da177e4SLinus Torvalds 	i = 0;
764447b5d69cSJames Bottomley  	ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
76451da177e4SLinus Torvalds 	do
76461da177e4SLinus Torvalds 	{
764747b5d69cSJames Bottomley  		ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
76481da177e4SLinus Torvalds 
76491da177e4SLinus Torvalds 		if(ee_data1 == ee_data2)
76501da177e4SLinus Torvalds 			return(ee_data1);
76511da177e4SLinus Torvalds 
76521da177e4SLinus Torvalds 		ee_data1 = ee_data2;
76531da177e4SLinus Torvalds 		i++;
76541da177e4SLinus Torvalds 
76551da177e4SLinus Torvalds 	}while(i < 4);
76561da177e4SLinus Torvalds 
76571da177e4SLinus Torvalds 	return(ee_data1);
76581da177e4SLinus Torvalds }
76591da177e4SLinus Torvalds 
76601da177e4SLinus Torvalds /*---------------------------------------------------------------------
76611da177e4SLinus Torvalds  *
76621da177e4SLinus Torvalds  * Function: Read EEPROM Original
76631da177e4SLinus Torvalds  *
76641da177e4SLinus Torvalds  * Description: Read a word from the EEPROM at the desired
76651da177e4SLinus Torvalds  *              address.
76661da177e4SLinus Torvalds  *
76671da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
76681da177e4SLinus Torvalds 
766947b5d69cSJames Bottomley  static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
76701da177e4SLinus Torvalds {
76711da177e4SLinus Torvalds 
76721da177e4SLinus Torvalds    UCHAR ee_value;
76731da177e4SLinus Torvalds    USHORT i, ee_data;
76741da177e4SLinus Torvalds 
76751da177e4SLinus Torvalds    ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
76761da177e4SLinus Torvalds 		   (SEE_MS | SEE_CS));
76771da177e4SLinus Torvalds 
76781da177e4SLinus Torvalds 
767947b5d69cSJames Bottomley     FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
76801da177e4SLinus Torvalds 
76811da177e4SLinus Torvalds 
76821da177e4SLinus Torvalds    ee_value |= (SEE_MS + SEE_CS);
76831da177e4SLinus Torvalds    ee_data = 0;
76841da177e4SLinus Torvalds 
76851da177e4SLinus Torvalds    for(i = 1; i <= 16; i++) {
76861da177e4SLinus Torvalds 
76871da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;          /* Clock  data! */
76881da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76891da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76901da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
76911da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76921da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
76931da177e4SLinus Torvalds 
76941da177e4SLinus Torvalds 	  ee_data <<= 1;
76951da177e4SLinus Torvalds 
76961da177e4SLinus Torvalds 	  if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
76971da177e4SLinus Torvalds 		 ee_data |= 1;
76981da177e4SLinus Torvalds 	  }
76991da177e4SLinus Torvalds 
77001da177e4SLinus Torvalds    ee_value &= ~(SEE_MS + SEE_CS);
77011da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
77021da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);   /*Turn off Master Select */
77031da177e4SLinus Torvalds 
77041da177e4SLinus Torvalds    return(ee_data);
77051da177e4SLinus Torvalds }
77061da177e4SLinus Torvalds 
77071da177e4SLinus Torvalds 
77081da177e4SLinus Torvalds /*---------------------------------------------------------------------
77091da177e4SLinus Torvalds  *
77101da177e4SLinus Torvalds  * Function: Send EE command and Address to the EEPROM
77111da177e4SLinus Torvalds  *
77121da177e4SLinus Torvalds  * Description: Transfers the correct command and sends the address
77131da177e4SLinus Torvalds  *              to the eeprom.
77141da177e4SLinus Torvalds  *
77151da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
77161da177e4SLinus Torvalds 
771747b5d69cSJames Bottomley  static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
77181da177e4SLinus Torvalds {
77191da177e4SLinus Torvalds    UCHAR ee_value;
77201da177e4SLinus Torvalds    UCHAR narrow_flg;
77211da177e4SLinus Torvalds 
77221da177e4SLinus Torvalds    USHORT i;
77231da177e4SLinus Torvalds 
77241da177e4SLinus Torvalds 
77251da177e4SLinus Torvalds    narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
77261da177e4SLinus Torvalds 
77271da177e4SLinus Torvalds 
77281da177e4SLinus Torvalds    ee_value = SEE_MS;
77291da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77301da177e4SLinus Torvalds 
77311da177e4SLinus Torvalds    ee_value |= SEE_CS;                             /* Set CS to EEPROM */
77321da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77331da177e4SLinus Torvalds 
77341da177e4SLinus Torvalds 
77351da177e4SLinus Torvalds    for(i = 0x04; i != 0; i>>=1) {
77361da177e4SLinus Torvalds 
77371da177e4SLinus Torvalds 	  if (i & ee_cmd)
77381da177e4SLinus Torvalds 		 ee_value |= SEE_DO;
77391da177e4SLinus Torvalds 	  else
77401da177e4SLinus Torvalds 		 ee_value &= ~SEE_DO;
77411da177e4SLinus Torvalds 
77421da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77431da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77441da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;                         /* Clock  data! */
77451da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77461da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77471da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
77481da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77491da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77501da177e4SLinus Torvalds 	  }
77511da177e4SLinus Torvalds 
77521da177e4SLinus Torvalds 
77531da177e4SLinus Torvalds    if (narrow_flg)
77541da177e4SLinus Torvalds 	  i = 0x0080;
77551da177e4SLinus Torvalds 
77561da177e4SLinus Torvalds    else
77571da177e4SLinus Torvalds 	  i = 0x0200;
77581da177e4SLinus Torvalds 
77591da177e4SLinus Torvalds 
77601da177e4SLinus Torvalds    while (i != 0) {
77611da177e4SLinus Torvalds 
77621da177e4SLinus Torvalds 	  if (i & ee_addr)
77631da177e4SLinus Torvalds 		 ee_value |= SEE_DO;
77641da177e4SLinus Torvalds 	  else
77651da177e4SLinus Torvalds 		 ee_value &= ~SEE_DO;
77661da177e4SLinus Torvalds 
77671da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77681da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77691da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;                         /* Clock  data! */
77701da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77711da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77721da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
77731da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77741da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
77751da177e4SLinus Torvalds 
77761da177e4SLinus Torvalds 	  i >>= 1;
77771da177e4SLinus Torvalds 	  }
77781da177e4SLinus Torvalds }
77791da177e4SLinus Torvalds 
778047b5d69cSJames Bottomley  static USHORT FPT_CalcCrc16(UCHAR buffer[])
77811da177e4SLinus Torvalds {
77821da177e4SLinus Torvalds    USHORT crc=0;
77831da177e4SLinus Torvalds 	int i,j;
77841da177e4SLinus Torvalds    USHORT ch;
77851da177e4SLinus Torvalds    for (i=0; i < ID_STRING_LENGTH; i++)
77861da177e4SLinus Torvalds    {
77871da177e4SLinus Torvalds       ch = (USHORT) buffer[i];
77881da177e4SLinus Torvalds 	   for(j=0; j < 8; j++)
77891da177e4SLinus Torvalds 	   {
77901da177e4SLinus Torvalds 		   if ((crc ^ ch) & 1)
77911da177e4SLinus Torvalds             crc = (crc >> 1) ^ CRCMASK;
77921da177e4SLinus Torvalds 		   else
77931da177e4SLinus Torvalds             crc >>= 1;
77941da177e4SLinus Torvalds 		   ch >>= 1;
77951da177e4SLinus Torvalds 	   }
77961da177e4SLinus Torvalds    }
77971da177e4SLinus Torvalds 	return(crc);
77981da177e4SLinus Torvalds }
77991da177e4SLinus Torvalds 
780047b5d69cSJames Bottomley  static UCHAR FPT_CalcLrc(UCHAR buffer[])
78011da177e4SLinus Torvalds {
78021da177e4SLinus Torvalds 	int i;
78031da177e4SLinus Torvalds 	UCHAR lrc;
78041da177e4SLinus Torvalds 	lrc = 0;
78051da177e4SLinus Torvalds 	for(i = 0; i < ID_STRING_LENGTH; i++)
78061da177e4SLinus Torvalds 		lrc ^= buffer[i];
78071da177e4SLinus Torvalds 	return(lrc);
78081da177e4SLinus Torvalds }
78091da177e4SLinus Torvalds 
78101da177e4SLinus Torvalds 
78111da177e4SLinus Torvalds 
78121da177e4SLinus Torvalds /*
78131da177e4SLinus Torvalds   The following inline definitions avoid type conflicts.
78141da177e4SLinus Torvalds */
78151da177e4SLinus Torvalds 
78161da177e4SLinus Torvalds static inline unsigned char
78171da177e4SLinus Torvalds FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
78181da177e4SLinus Torvalds {
78191da177e4SLinus Torvalds   return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
78201da177e4SLinus Torvalds }
78211da177e4SLinus Torvalds 
78221da177e4SLinus Torvalds 
78231da177e4SLinus Torvalds static inline FlashPoint_CardHandle_T
78241da177e4SLinus Torvalds FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
78251da177e4SLinus Torvalds {
78261da177e4SLinus Torvalds   return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
78271da177e4SLinus Torvalds }
78281da177e4SLinus Torvalds 
78291da177e4SLinus Torvalds static inline void
78301da177e4SLinus Torvalds FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
78311da177e4SLinus Torvalds {
78321da177e4SLinus Torvalds   FlashPoint_ReleaseHostAdapter(CardHandle);
78331da177e4SLinus Torvalds }
78341da177e4SLinus Torvalds 
78351da177e4SLinus Torvalds 
78361da177e4SLinus Torvalds static inline void
78371da177e4SLinus Torvalds FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
78381da177e4SLinus Torvalds {
78391da177e4SLinus Torvalds   FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
78401da177e4SLinus Torvalds }
78411da177e4SLinus Torvalds 
78421da177e4SLinus Torvalds 
78431da177e4SLinus Torvalds static inline void
78441da177e4SLinus Torvalds FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
78451da177e4SLinus Torvalds {
78461da177e4SLinus Torvalds   FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
78471da177e4SLinus Torvalds }
78481da177e4SLinus Torvalds 
78491da177e4SLinus Torvalds 
78501da177e4SLinus Torvalds static inline boolean
78511da177e4SLinus Torvalds FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
78521da177e4SLinus Torvalds {
78531da177e4SLinus Torvalds   return FlashPoint_InterruptPending(CardHandle);
78541da177e4SLinus Torvalds }
78551da177e4SLinus Torvalds 
78561da177e4SLinus Torvalds 
78571da177e4SLinus Torvalds static inline int
78581da177e4SLinus Torvalds FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
78591da177e4SLinus Torvalds {
78601da177e4SLinus Torvalds   return FlashPoint_HandleInterrupt(CardHandle);
78611da177e4SLinus Torvalds }
78621da177e4SLinus Torvalds 
78631da177e4SLinus Torvalds 
78641da177e4SLinus Torvalds #define FlashPoint_ProbeHostAdapter	    FlashPoint__ProbeHostAdapter
78651da177e4SLinus Torvalds #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
78661da177e4SLinus Torvalds #define FlashPoint_ReleaseHostAdapter	    FlashPoint__ReleaseHostAdapter
78671da177e4SLinus Torvalds #define FlashPoint_StartCCB		    FlashPoint__StartCCB
78681da177e4SLinus Torvalds #define FlashPoint_AbortCCB		    FlashPoint__AbortCCB
78691da177e4SLinus Torvalds #define FlashPoint_InterruptPending	    FlashPoint__InterruptPending
78701da177e4SLinus Torvalds #define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
78711da177e4SLinus Torvalds 
78721da177e4SLinus Torvalds 
78731da177e4SLinus Torvalds #else  /* CONFIG_SCSI_OMIT_FLASHPOINT */
78741da177e4SLinus Torvalds 
78751da177e4SLinus Torvalds 
78761da177e4SLinus Torvalds /*
78771da177e4SLinus Torvalds   Define prototypes for the FlashPoint SCCB Manager Functions.
78781da177e4SLinus Torvalds */
78791da177e4SLinus Torvalds 
78801da177e4SLinus Torvalds extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
78811da177e4SLinus Torvalds extern FlashPoint_CardHandle_T
78821da177e4SLinus Torvalds        FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
78831da177e4SLinus Torvalds extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
78841da177e4SLinus Torvalds extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
78851da177e4SLinus Torvalds extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
78861da177e4SLinus Torvalds extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
78871da177e4SLinus Torvalds extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
78881da177e4SLinus Torvalds 
78891da177e4SLinus Torvalds 
78901da177e4SLinus Torvalds #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */
7891