xref: /openbmc/linux/drivers/scsi/FlashPoint.c (revision 47b5d69c4aa753fcfc9b2b8d28c0660a1e25c129)
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 #define MAX_CDBLEN  12
511da177e4SLinus Torvalds 
521da177e4SLinus Torvalds #define SCAM_LEV_2	1
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds #define CRCMASK	0xA001
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds #define     BL_VENDOR_ID      0x104B
571da177e4SLinus Torvalds #define     FP_DEVICE_ID      0x8130
581da177e4SLinus Torvalds #define     MM_DEVICE_ID      0x1040
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds #define FAILURE         0xFFFFFFFFL
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds typedef unsigned char   UCHAR;
651da177e4SLinus Torvalds typedef unsigned short  USHORT;
661da177e4SLinus Torvalds typedef unsigned int    UINT;
671da177e4SLinus Torvalds typedef unsigned long   ULONG;
681da177e4SLinus Torvalds typedef unsigned char * PUCHAR;
691da177e4SLinus Torvalds typedef unsigned short* PUSHORT;
701da177e4SLinus Torvalds typedef unsigned long * PULONG;
711da177e4SLinus Torvalds typedef void *          PVOID;
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds 
741da177e4SLinus Torvalds typedef unsigned char           * uchar_ptr;
751da177e4SLinus Torvalds typedef unsigned short          * ushort_ptr;
761da177e4SLinus Torvalds typedef unsigned long           * ulong_ptr;
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds #define s08bits	char
801da177e4SLinus Torvalds #define s16bits 	short
811da177e4SLinus Torvalds #define s32bits	long
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds #define u08bits	unsigned s08bits
841da177e4SLinus Torvalds #define u16bits	unsigned s16bits
851da177e4SLinus Torvalds #define u32bits	unsigned s32bits
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds typedef u08bits 	* pu08bits;
881da177e4SLinus Torvalds typedef u16bits 	* pu16bits;
891da177e4SLinus Torvalds typedef u32bits 	* pu32bits;
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds #define BIT(x)          ((UCHAR)(1<<(x)))    /* single-bit mask in bit position x */
931da177e4SLinus Torvalds #define BITW(x)          ((USHORT)(1<<(x)))  /* single-bit mask in bit position x */
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds 
981da177e4SLinus Torvalds typedef struct _SCCB *PSCCB;
991da177e4SLinus Torvalds typedef void (*CALL_BK_FN)(PSCCB);
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds typedef struct SCCBMgr_info {
1031da177e4SLinus Torvalds    ULONG    si_baseaddr;
1041da177e4SLinus Torvalds    UCHAR    si_present;
1051da177e4SLinus Torvalds    UCHAR    si_intvect;
1061da177e4SLinus Torvalds    UCHAR    si_id;
1071da177e4SLinus Torvalds    UCHAR    si_lun;
1081da177e4SLinus Torvalds    USHORT   si_fw_revision;
1091da177e4SLinus Torvalds    USHORT   si_per_targ_init_sync;
1101da177e4SLinus Torvalds    USHORT   si_per_targ_fast_nego;
1111da177e4SLinus Torvalds    USHORT   si_per_targ_ultra_nego;
1121da177e4SLinus Torvalds    USHORT   si_per_targ_no_disc;
1131da177e4SLinus Torvalds    USHORT   si_per_targ_wide_nego;
1141da177e4SLinus Torvalds    USHORT   si_flags;
1151da177e4SLinus Torvalds    UCHAR    si_card_family;
1161da177e4SLinus Torvalds    UCHAR    si_bustype;
1171da177e4SLinus Torvalds    UCHAR    si_card_model[3];
1181da177e4SLinus Torvalds    UCHAR    si_relative_cardnum;
1191da177e4SLinus Torvalds    UCHAR    si_reserved[4];
1201da177e4SLinus Torvalds    ULONG    si_OS_reserved;
1211da177e4SLinus Torvalds    UCHAR    si_XlatInfo[4];
1221da177e4SLinus Torvalds    ULONG    si_reserved2[5];
1231da177e4SLinus Torvalds    ULONG    si_secondary_range;
1241da177e4SLinus Torvalds } SCCBMGR_INFO;
1251da177e4SLinus Torvalds 
1261da177e4SLinus Torvalds typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds 
1291da177e4SLinus Torvalds #define SCSI_PARITY_ENA		  0x0001
1301da177e4SLinus Torvalds #define LOW_BYTE_TERM		  0x0010
1311da177e4SLinus Torvalds #define HIGH_BYTE_TERM		  0x0020
1321da177e4SLinus Torvalds #define BUSTYPE_PCI	  0x3
1331da177e4SLinus Torvalds 
1341da177e4SLinus Torvalds #define SUPPORT_16TAR_32LUN	  0x0002
1351da177e4SLinus Torvalds #define SOFT_RESET		  0x0004
1361da177e4SLinus Torvalds #define EXTENDED_TRANSLATION	  0x0008
1371da177e4SLinus Torvalds #define POST_ALL_UNDERRRUNS	  0x0040
1381da177e4SLinus Torvalds #define FLAG_SCAM_ENABLED	  0x0080
1391da177e4SLinus Torvalds #define FLAG_SCAM_LEVEL2	  0x0100
1401da177e4SLinus Torvalds 
1411da177e4SLinus Torvalds 
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds #define HARPOON_FAMILY        0x02
1451da177e4SLinus Torvalds 
1461da177e4SLinus Torvalds 
1471da177e4SLinus Torvalds #define ISA_BUS_CARD          0x01
1481da177e4SLinus Torvalds #define EISA_BUS_CARD         0x02
1491da177e4SLinus Torvalds #define PCI_BUS_CARD          0x03
1501da177e4SLinus Torvalds #define VESA_BUS_CARD         0x04
1511da177e4SLinus Torvalds 
1521da177e4SLinus Torvalds /* SCCB struc used for both SCCB and UCB manager compiles!
1531da177e4SLinus Torvalds  * The UCB Manager treats the SCCB as it's 'native hardware structure'
1541da177e4SLinus Torvalds  */
1551da177e4SLinus Torvalds 
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds #pragma pack(1)
1581da177e4SLinus Torvalds typedef struct _SCCB {
1591da177e4SLinus Torvalds    UCHAR OperationCode;
1601da177e4SLinus Torvalds    UCHAR ControlByte;
1611da177e4SLinus Torvalds    UCHAR CdbLength;
1621da177e4SLinus Torvalds    UCHAR RequestSenseLength;
1631da177e4SLinus Torvalds    ULONG DataLength;
1641da177e4SLinus Torvalds    ULONG DataPointer;
1651da177e4SLinus Torvalds    UCHAR CcbRes[2];
1661da177e4SLinus Torvalds    UCHAR HostStatus;
1671da177e4SLinus Torvalds    UCHAR TargetStatus;
1681da177e4SLinus Torvalds    UCHAR TargID;
1691da177e4SLinus Torvalds    UCHAR Lun;
1701da177e4SLinus Torvalds    UCHAR Cdb[12];
1711da177e4SLinus Torvalds    UCHAR CcbRes1;
1721da177e4SLinus Torvalds    UCHAR Reserved1;
1731da177e4SLinus Torvalds    ULONG Reserved2;
1741da177e4SLinus Torvalds    ULONG SensePointer;
1751da177e4SLinus Torvalds 
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds    CALL_BK_FN SccbCallback;                  /* VOID (*SccbCallback)(); */
1781da177e4SLinus Torvalds    ULONG  SccbIOPort;                        /* Identifies board base port */
1791da177e4SLinus Torvalds    UCHAR  SccbStatus;
1801da177e4SLinus Torvalds    UCHAR  SCCBRes2;
1811da177e4SLinus Torvalds    USHORT SccbOSFlags;
1821da177e4SLinus Torvalds 
1831da177e4SLinus Torvalds 
1841da177e4SLinus Torvalds    ULONG   Sccb_XferCnt;            /* actual transfer count */
1851da177e4SLinus Torvalds    ULONG   Sccb_ATC;
1861da177e4SLinus Torvalds    ULONG   SccbVirtDataPtr;         /* virtual addr for OS/2 */
1871da177e4SLinus Torvalds    ULONG   Sccb_res1;
1881da177e4SLinus Torvalds    USHORT  Sccb_MGRFlags;
1891da177e4SLinus Torvalds    USHORT  Sccb_sgseg;
1901da177e4SLinus Torvalds    UCHAR   Sccb_scsimsg;            /* identify msg for selection */
1911da177e4SLinus Torvalds    UCHAR   Sccb_tag;
1921da177e4SLinus Torvalds    UCHAR   Sccb_scsistat;
1931da177e4SLinus Torvalds    UCHAR   Sccb_idmsg;              /* image of last msg in */
1941da177e4SLinus Torvalds    PSCCB   Sccb_forwardlink;
1951da177e4SLinus Torvalds    PSCCB   Sccb_backlink;
1961da177e4SLinus Torvalds    ULONG   Sccb_savedATC;
1971da177e4SLinus Torvalds    UCHAR   Save_Cdb[6];
1981da177e4SLinus Torvalds    UCHAR   Save_CdbLen;
1991da177e4SLinus Torvalds    UCHAR   Sccb_XferState;
2001da177e4SLinus Torvalds    ULONG   Sccb_SGoffset;
2011da177e4SLinus Torvalds    } SCCB;
2021da177e4SLinus Torvalds 
2031da177e4SLinus Torvalds #define SCCB_SIZE sizeof(SCCB)
2041da177e4SLinus Torvalds 
2051da177e4SLinus Torvalds #pragma pack()
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds #define SCSI_INITIATOR_COMMAND    0x00
2101da177e4SLinus Torvalds #define TARGET_MODE_COMMAND       0x01
2111da177e4SLinus Torvalds #define SCATTER_GATHER_COMMAND    0x02
2121da177e4SLinus Torvalds #define RESIDUAL_COMMAND          0x03
2131da177e4SLinus Torvalds #define RESIDUAL_SG_COMMAND       0x04
2141da177e4SLinus Torvalds #define RESET_COMMAND             0x81
2151da177e4SLinus Torvalds 
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds #define F_USE_CMD_Q              0x20     /*Inidcates TAGGED command. */
2181da177e4SLinus Torvalds #define TAG_TYPE_MASK            0xC0     /*Type of tag msg to send. */
2191da177e4SLinus Torvalds #define TAG_Q_MASK               0xE0
2201da177e4SLinus Torvalds #define SCCB_DATA_XFER_OUT       0x10     /* Write */
2211da177e4SLinus Torvalds #define SCCB_DATA_XFER_IN        0x08     /* Read */
2221da177e4SLinus Torvalds 
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds #define FOURTEEN_BYTES           0x00     /* Request Sense Buffer size */
2251da177e4SLinus Torvalds #define NO_AUTO_REQUEST_SENSE    0x01     /* No Request Sense Buffer */
2261da177e4SLinus Torvalds 
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds #define BUS_FREE_ST     0
2291da177e4SLinus Torvalds #define SELECT_ST       1
2301da177e4SLinus Torvalds #define SELECT_BDR_ST   2     /* Select w\ Bus Device Reset */
2311da177e4SLinus Torvalds #define SELECT_SN_ST    3     /* Select w\ Sync Nego */
2321da177e4SLinus Torvalds #define SELECT_WN_ST    4     /* Select w\ Wide Data Nego */
2331da177e4SLinus Torvalds #define SELECT_Q_ST     5     /* Select w\ Tagged Q'ing */
2341da177e4SLinus Torvalds #define COMMAND_ST      6
2351da177e4SLinus Torvalds #define DATA_OUT_ST     7
2361da177e4SLinus Torvalds #define DATA_IN_ST      8
2371da177e4SLinus Torvalds #define DISCONNECT_ST   9
2381da177e4SLinus Torvalds #define STATUS_ST       10
2391da177e4SLinus Torvalds #define ABORT_ST        11
2401da177e4SLinus Torvalds #define MESSAGE_ST      12
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds 
2431da177e4SLinus Torvalds #define F_HOST_XFER_DIR                0x01
2441da177e4SLinus Torvalds #define F_ALL_XFERRED                  0x02
2451da177e4SLinus Torvalds #define F_SG_XFER                      0x04
2461da177e4SLinus Torvalds #define F_AUTO_SENSE                   0x08
2471da177e4SLinus Torvalds #define F_ODD_BALL_CNT                 0x10
2481da177e4SLinus Torvalds #define F_NO_DATA_YET                  0x80
2491da177e4SLinus Torvalds 
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds #define F_STATUSLOADED                 0x01
2521da177e4SLinus Torvalds #define F_MSGLOADED                    0x02
2531da177e4SLinus Torvalds #define F_DEV_SELECTED                 0x04
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds 
2561da177e4SLinus Torvalds #define SCCB_COMPLETE               0x00  /* SCCB completed without error */
2571da177e4SLinus Torvalds #define SCCB_DATA_UNDER_RUN         0x0C
2581da177e4SLinus Torvalds #define SCCB_SELECTION_TIMEOUT      0x11  /* Set SCSI selection timed out */
2591da177e4SLinus Torvalds #define SCCB_DATA_OVER_RUN          0x12
2601da177e4SLinus Torvalds #define SCCB_UNEXPECTED_BUS_FREE    0x13  /* Target dropped SCSI BSY */
2611da177e4SLinus Torvalds #define SCCB_PHASE_SEQUENCE_FAIL    0x14  /* Target bus phase sequence failure */
2621da177e4SLinus Torvalds 
2631da177e4SLinus Torvalds #define SCCB_INVALID_OP_CODE        0x16  /* SCCB invalid operation code */
2641da177e4SLinus Torvalds #define SCCB_INVALID_SCCB           0x1A  /* Invalid SCCB - bad parameter */
2651da177e4SLinus Torvalds #define SCCB_GROSS_FW_ERR           0x27  /* Major problem! */
2661da177e4SLinus Torvalds #define SCCB_BM_ERR                 0x30  /* BusMaster error. */
2671da177e4SLinus Torvalds #define SCCB_PARITY_ERR             0x34  /* SCSI parity error */
2681da177e4SLinus Torvalds 
2691da177e4SLinus Torvalds 
2701da177e4SLinus Torvalds 
2711da177e4SLinus Torvalds #define SCCB_INVALID_DIRECTION      0x18  /* Invalid target direction */
2721da177e4SLinus Torvalds #define SCCB_DUPLICATE_SCCB         0x19  /* Duplicate SCCB */
2731da177e4SLinus Torvalds #define SCCB_SCSI_RST               0x35  /* SCSI RESET detected. */
2741da177e4SLinus Torvalds 
2751da177e4SLinus Torvalds 
2761da177e4SLinus Torvalds #define SCCB_IN_PROCESS            0x00
2771da177e4SLinus Torvalds #define SCCB_SUCCESS               0x01
2781da177e4SLinus Torvalds #define SCCB_ABORT                 0x02
2791da177e4SLinus Torvalds #define SCCB_NOT_FOUND             0x03
2801da177e4SLinus Torvalds #define SCCB_ERROR                 0x04
2811da177e4SLinus Torvalds #define SCCB_INVALID               0x05
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds #define SCCB_SIZE sizeof(SCCB)
2841da177e4SLinus Torvalds 
2851da177e4SLinus Torvalds 
2861da177e4SLinus Torvalds #define  ORION_FW_REV      3110
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds #define HARP_REVD    1
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds #define QUEUE_DEPTH     254+1            /*1 for Normal disconnect 32 for Q'ing. */
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds #define	MAX_MB_CARDS	4					/* Max. no of cards suppoerted on Mother Board */
2941da177e4SLinus Torvalds 
2951da177e4SLinus Torvalds #define WIDE_SCSI       1
2961da177e4SLinus Torvalds 
2971da177e4SLinus Torvalds #define MAX_SCSI_TAR    16
2981da177e4SLinus Torvalds #define MAX_LUN         32
2991da177e4SLinus Torvalds #define LUN_MASK			0x1f
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds #if defined(HARP_REVA)
3021da177e4SLinus Torvalds #define SG_BUF_CNT      15             /*Number of prefetched elements. */
3031da177e4SLinus Torvalds #else
3041da177e4SLinus Torvalds #define SG_BUF_CNT      16             /*Number of prefetched elements. */
3051da177e4SLinus Torvalds #endif
3061da177e4SLinus Torvalds 
3071da177e4SLinus Torvalds #define SG_ELEMENT_SIZE 8              /*Eight byte per element. */
3081da177e4SLinus Torvalds #define SG_LOCAL_MASK   0x00000000L
3091da177e4SLinus Torvalds #define SG_ELEMENT_MASK 0xFFFFFFFFL
3101da177e4SLinus Torvalds 
3111da177e4SLinus Torvalds 
3121da177e4SLinus Torvalds #define RD_HARPOON(ioport)          OS_InPortByte((u32bits)ioport)
3131da177e4SLinus Torvalds #define RDW_HARPOON(ioport)         OS_InPortWord((u32bits)ioport)
3141da177e4SLinus Torvalds #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
3151da177e4SLinus Torvalds #define WR_HARPOON(ioport,val)      OS_OutPortByte((u32bits)ioport,(u08bits) val)
3161da177e4SLinus Torvalds #define WRW_HARPOON(ioport,val)       OS_OutPortWord((u32bits)ioport,(u16bits)val)
3171da177e4SLinus Torvalds #define WR_HARP32(ioport,offset,data)  OS_OutPortLong((u32bits)(ioport + offset), data)
3181da177e4SLinus Torvalds 
3191da177e4SLinus Torvalds 
3201da177e4SLinus Torvalds #define  TAR_SYNC_MASK     (BIT(7)+BIT(6))
3211da177e4SLinus Torvalds #define  SYNC_UNKNOWN      0x00
3221da177e4SLinus Torvalds #define  SYNC_TRYING               BIT(6)
3231da177e4SLinus Torvalds #define  SYNC_SUPPORTED    (BIT(7)+BIT(6))
3241da177e4SLinus Torvalds 
3251da177e4SLinus Torvalds #define  TAR_WIDE_MASK     (BIT(5)+BIT(4))
3261da177e4SLinus Torvalds #define  WIDE_DISABLED     0x00
3271da177e4SLinus Torvalds #define  WIDE_ENABLED              BIT(4)
3281da177e4SLinus Torvalds #define  WIDE_NEGOCIATED   BIT(5)
3291da177e4SLinus Torvalds 
3301da177e4SLinus Torvalds #define  TAR_TAG_Q_MASK    (BIT(3)+BIT(2))
3311da177e4SLinus Torvalds #define  TAG_Q_UNKNOWN     0x00
3321da177e4SLinus Torvalds #define  TAG_Q_TRYING              BIT(2)
3331da177e4SLinus Torvalds #define  TAG_Q_REJECT      BIT(3)
3341da177e4SLinus Torvalds #define  TAG_Q_SUPPORTED   (BIT(3)+BIT(2))
3351da177e4SLinus Torvalds 
3361da177e4SLinus Torvalds #define  TAR_ALLOW_DISC    BIT(0)
3371da177e4SLinus Torvalds 
3381da177e4SLinus Torvalds 
3391da177e4SLinus Torvalds #define  EE_SYNC_MASK      (BIT(0)+BIT(1))
3401da177e4SLinus Torvalds #define  EE_SYNC_ASYNC     0x00
3411da177e4SLinus Torvalds #define  EE_SYNC_5MB       BIT(0)
3421da177e4SLinus Torvalds #define  EE_SYNC_10MB      BIT(1)
3431da177e4SLinus Torvalds #define  EE_SYNC_20MB      (BIT(0)+BIT(1))
3441da177e4SLinus Torvalds 
3451da177e4SLinus Torvalds #define  EE_ALLOW_DISC     BIT(6)
3461da177e4SLinus Torvalds #define  EE_WIDE_SCSI      BIT(7)
3471da177e4SLinus Torvalds 
3481da177e4SLinus Torvalds 
3491da177e4SLinus Torvalds typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
3501da177e4SLinus Torvalds 
3511da177e4SLinus Torvalds 
3521da177e4SLinus Torvalds typedef struct SCCBMgr_tar_info {
3531da177e4SLinus Torvalds 
3541da177e4SLinus Torvalds    PSCCB    TarSelQ_Head;
3551da177e4SLinus Torvalds    PSCCB    TarSelQ_Tail;
3561da177e4SLinus Torvalds    UCHAR    TarLUN_CA;        /*Contingent Allgiance */
3571da177e4SLinus Torvalds    UCHAR    TarTagQ_Cnt;
3581da177e4SLinus Torvalds    UCHAR    TarSelQ_Cnt;
3591da177e4SLinus Torvalds    UCHAR    TarStatus;
3601da177e4SLinus Torvalds    UCHAR    TarEEValue;
3611da177e4SLinus Torvalds    UCHAR 	TarSyncCtrl;
3621da177e4SLinus Torvalds    UCHAR 	TarReserved[2];			/* for alignment */
3631da177e4SLinus Torvalds    UCHAR 	LunDiscQ_Idx[MAX_LUN];
3641da177e4SLinus Torvalds    UCHAR    TarLUNBusy[MAX_LUN];
3651da177e4SLinus Torvalds } SCCBMGR_TAR_INFO;
3661da177e4SLinus Torvalds 
3671da177e4SLinus Torvalds typedef struct NVRAMInfo {
3681da177e4SLinus Torvalds 	UCHAR		niModel;								/* Model No. of card */
3691da177e4SLinus Torvalds 	UCHAR		niCardNo;							/* Card no. */
3701da177e4SLinus Torvalds 	ULONG		niBaseAddr;							/* Port Address of card */
3711da177e4SLinus Torvalds 	UCHAR		niSysConf;							/* Adapter Configuration byte - Byte 16 of eeprom map */
3721da177e4SLinus Torvalds 	UCHAR		niScsiConf;							/* SCSI Configuration byte - Byte 17 of eeprom map */
3731da177e4SLinus Torvalds 	UCHAR		niScamConf;							/* SCAM Configuration byte - Byte 20 of eeprom map */
3741da177e4SLinus Torvalds 	UCHAR		niAdapId;							/* Host Adapter ID - Byte 24 of eerpom map */
3751da177e4SLinus Torvalds 	UCHAR		niSyncTbl[MAX_SCSI_TAR / 2];	/* Sync/Wide byte of targets */
3761da177e4SLinus Torvalds 	UCHAR		niScamTbl[MAX_SCSI_TAR][4];	/* Compressed Scam name string of Targets */
3771da177e4SLinus Torvalds }NVRAMINFO;
3781da177e4SLinus Torvalds 
3791da177e4SLinus Torvalds typedef NVRAMINFO *PNVRamInfo;
3801da177e4SLinus Torvalds 
3811da177e4SLinus Torvalds #define	MODEL_LT		1
3821da177e4SLinus Torvalds #define	MODEL_DL		2
3831da177e4SLinus Torvalds #define	MODEL_LW		3
3841da177e4SLinus Torvalds #define	MODEL_DW		4
3851da177e4SLinus Torvalds 
3861da177e4SLinus Torvalds 
3871da177e4SLinus Torvalds typedef struct SCCBcard {
3881da177e4SLinus Torvalds    PSCCB currentSCCB;
3891da177e4SLinus Torvalds    PSCCBMGR_INFO cardInfo;
3901da177e4SLinus Torvalds 
3911da177e4SLinus Torvalds    ULONG ioPort;
3921da177e4SLinus Torvalds 
3931da177e4SLinus Torvalds    USHORT cmdCounter;
3941da177e4SLinus Torvalds    UCHAR  discQCount;
3951da177e4SLinus Torvalds    UCHAR  tagQ_Lst;
3961da177e4SLinus Torvalds    UCHAR cardIndex;
3971da177e4SLinus Torvalds    UCHAR scanIndex;
3981da177e4SLinus Torvalds    UCHAR globalFlags;
3991da177e4SLinus Torvalds    UCHAR ourId;
4001da177e4SLinus Torvalds    PNVRamInfo pNvRamInfo;
4011da177e4SLinus Torvalds    PSCCB discQ_Tbl[QUEUE_DEPTH];
4021da177e4SLinus Torvalds 
4031da177e4SLinus Torvalds }SCCBCARD;
4041da177e4SLinus Torvalds 
4051da177e4SLinus Torvalds typedef struct SCCBcard *PSCCBcard;
4061da177e4SLinus Torvalds 
4071da177e4SLinus Torvalds 
4081da177e4SLinus Torvalds #define F_TAG_STARTED		0x01
4091da177e4SLinus Torvalds #define F_CONLUN_IO			0x02
4101da177e4SLinus Torvalds #define F_DO_RENEGO			0x04
4111da177e4SLinus Torvalds #define F_NO_FILTER			0x08
4121da177e4SLinus Torvalds #define F_GREEN_PC			0x10
4131da177e4SLinus Torvalds #define F_HOST_XFER_ACT		0x20
4141da177e4SLinus Torvalds #define F_NEW_SCCB_CMD		0x40
4151da177e4SLinus Torvalds #define F_UPDATE_EEPROM		0x80
4161da177e4SLinus Torvalds 
4171da177e4SLinus Torvalds 
4181da177e4SLinus Torvalds #define  ID_STRING_LENGTH  32
4191da177e4SLinus Torvalds #define  TYPE_CODE0        0x63           /*Level2 Mstr (bits 7-6),  */
4201da177e4SLinus Torvalds 
4211da177e4SLinus Torvalds #define  TYPE_CODE1        00             /*No ID yet */
4221da177e4SLinus Torvalds 
4231da177e4SLinus Torvalds #define  SLV_TYPE_CODE0    0xA3           /*Priority Bit set (bits 7-6),  */
4241da177e4SLinus Torvalds 
4251da177e4SLinus Torvalds #define  ASSIGN_ID   0x00
4261da177e4SLinus Torvalds #define  SET_P_FLAG  0x01
4271da177e4SLinus Torvalds #define  CFG_CMPLT   0x03
4281da177e4SLinus Torvalds #define  DOM_MSTR    0x0F
4291da177e4SLinus Torvalds #define  SYNC_PTRN   0x1F
4301da177e4SLinus Torvalds 
4311da177e4SLinus Torvalds #define  ID_0_7      0x18
4321da177e4SLinus Torvalds #define  ID_8_F      0x11
4331da177e4SLinus Torvalds #define  ID_10_17    0x12
4341da177e4SLinus Torvalds #define  ID_18_1F    0x0B
4351da177e4SLinus Torvalds #define  MISC_CODE   0x14
4361da177e4SLinus Torvalds #define  CLR_P_FLAG  0x18
4371da177e4SLinus Torvalds #define  LOCATE_ON   0x12
4381da177e4SLinus Torvalds #define  LOCATE_OFF  0x0B
4391da177e4SLinus Torvalds 
4401da177e4SLinus Torvalds #define  LVL_1_MST   0x00
4411da177e4SLinus Torvalds #define  LVL_2_MST   0x40
4421da177e4SLinus Torvalds #define  DOM_LVL_2   0xC0
4431da177e4SLinus Torvalds 
4441da177e4SLinus Torvalds 
4451da177e4SLinus Torvalds #define  INIT_SELTD  0x01
4461da177e4SLinus Torvalds #define  LEVEL2_TAR  0x02
4471da177e4SLinus Torvalds 
4481da177e4SLinus Torvalds 
4491da177e4SLinus Torvalds enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
4501da177e4SLinus Torvalds                   ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
4511da177e4SLinus Torvalds                   CLR_PRIORITY,NO_ID_AVAIL };
4521da177e4SLinus Torvalds 
4531da177e4SLinus Torvalds typedef struct SCCBscam_info {
4541da177e4SLinus Torvalds 
4551da177e4SLinus Torvalds    UCHAR    id_string[ID_STRING_LENGTH];
4561da177e4SLinus Torvalds    enum scam_id_st state;
4571da177e4SLinus Torvalds 
4581da177e4SLinus Torvalds } SCCBSCAM_INFO, *PSCCBSCAM_INFO;
4591da177e4SLinus Torvalds 
4601da177e4SLinus Torvalds 
4611da177e4SLinus Torvalds #define  SCSI_TEST_UNIT_READY    0x00
4621da177e4SLinus Torvalds #define  SCSI_REZERO_UNIT        0x01
4631da177e4SLinus Torvalds #define  SCSI_REQUEST_SENSE      0x03
4641da177e4SLinus Torvalds #define  SCSI_FORMAT_UNIT        0x04
4651da177e4SLinus Torvalds #define  SCSI_REASSIGN           0x07
4661da177e4SLinus Torvalds #define  SCSI_READ               0x08
4671da177e4SLinus Torvalds #define  SCSI_WRITE              0x0A
4681da177e4SLinus Torvalds #define  SCSI_SEEK               0x0B
4691da177e4SLinus Torvalds #define  SCSI_INQUIRY            0x12
4701da177e4SLinus Torvalds #define  SCSI_MODE_SELECT        0x15
4711da177e4SLinus Torvalds #define  SCSI_RESERVE_UNIT       0x16
4721da177e4SLinus Torvalds #define  SCSI_RELEASE_UNIT       0x17
4731da177e4SLinus Torvalds #define  SCSI_MODE_SENSE         0x1A
4741da177e4SLinus Torvalds #define  SCSI_START_STOP_UNIT    0x1B
4751da177e4SLinus Torvalds #define  SCSI_SEND_DIAGNOSTIC    0x1D
4761da177e4SLinus Torvalds #define  SCSI_READ_CAPACITY      0x25
4771da177e4SLinus Torvalds #define  SCSI_READ_EXTENDED      0x28
4781da177e4SLinus Torvalds #define  SCSI_WRITE_EXTENDED     0x2A
4791da177e4SLinus Torvalds #define  SCSI_SEEK_EXTENDED      0x2B
4801da177e4SLinus Torvalds #define  SCSI_WRITE_AND_VERIFY   0x2E
4811da177e4SLinus Torvalds #define  SCSI_VERIFY             0x2F
4821da177e4SLinus Torvalds #define  SCSI_READ_DEFECT_DATA   0x37
4831da177e4SLinus Torvalds #define  SCSI_WRITE_BUFFER       0x3B
4841da177e4SLinus Torvalds #define  SCSI_READ_BUFFER        0x3C
4851da177e4SLinus Torvalds #define  SCSI_RECV_DIAGNOSTIC    0x1C
4861da177e4SLinus Torvalds #define  SCSI_READ_LONG          0x3E
4871da177e4SLinus Torvalds #define  SCSI_WRITE_LONG         0x3F
4881da177e4SLinus Torvalds #define  SCSI_LAST_SCSI_CMND     SCSI_WRITE_LONG
4891da177e4SLinus Torvalds #define  SCSI_INVALID_CMND       0xFF
4901da177e4SLinus Torvalds 
4911da177e4SLinus Torvalds 
4921da177e4SLinus Torvalds 
4931da177e4SLinus Torvalds #define  SSGOOD                  0x00
4941da177e4SLinus Torvalds #define  SSCHECK                 0x02
4951da177e4SLinus Torvalds #define  SSCOND_MET              0x04
4961da177e4SLinus Torvalds #define  SSBUSY                  0x08
4971da177e4SLinus Torvalds #define  SSRESERVATION_CONFLICT  0x18
4981da177e4SLinus Torvalds #define  SSCMD_TERM              0x22
4991da177e4SLinus Torvalds #define  SSQ_FULL                0x28
5001da177e4SLinus Torvalds 
5011da177e4SLinus Torvalds 
5021da177e4SLinus Torvalds #define  SKNO_SEN                0x00
5031da177e4SLinus Torvalds #define  SKRECOV_ERR             0x01
5041da177e4SLinus Torvalds #define  SKNOT_RDY               0x02
5051da177e4SLinus Torvalds #define  SKMED_ERR               0x03
5061da177e4SLinus Torvalds #define  SKHW_ERR                0x04
5071da177e4SLinus Torvalds #define  SKILL_REQ               0x05
5081da177e4SLinus Torvalds #define  SKUNIT_ATTN             0x06
5091da177e4SLinus Torvalds #define  SKDATA_PROTECT          0x07
5101da177e4SLinus Torvalds #define  SKBLNK_CHK              0x08
5111da177e4SLinus Torvalds #define  SKCPY_ABORT             0x0A
5121da177e4SLinus Torvalds #define  SKABORT_CMD             0x0B
5131da177e4SLinus Torvalds #define  SKEQUAL                 0x0C
5141da177e4SLinus Torvalds #define  SKVOL_OVF               0x0D
5151da177e4SLinus Torvalds #define  SKMIS_CMP               0x0E
5161da177e4SLinus Torvalds 
5171da177e4SLinus Torvalds 
5181da177e4SLinus Torvalds #define  SMCMD_COMP              0x00
5191da177e4SLinus Torvalds #define  SMEXT                   0x01
5201da177e4SLinus Torvalds #define  SMSAVE_DATA_PTR         0x02
5211da177e4SLinus Torvalds #define  SMREST_DATA_PTR         0x03
5221da177e4SLinus Torvalds #define  SMDISC                  0x04
5231da177e4SLinus Torvalds #define  SMINIT_DETEC_ERR        0x05
5241da177e4SLinus Torvalds #define  SMABORT                 0x06
5251da177e4SLinus Torvalds #define  SMREJECT                0x07
5261da177e4SLinus Torvalds #define  SMNO_OP                 0x08
5271da177e4SLinus Torvalds #define  SMPARITY                0x09
5281da177e4SLinus Torvalds #define  SMDEV_RESET             0x0C
5291da177e4SLinus Torvalds #define	SMABORT_TAG					0x0D
5301da177e4SLinus Torvalds #define	SMINIT_RECOVERY			0x0F
5311da177e4SLinus Torvalds #define	SMREL_RECOVERY				0x10
5321da177e4SLinus Torvalds 
5331da177e4SLinus Torvalds #define  SMIDENT                 0x80
5341da177e4SLinus Torvalds #define  DISC_PRIV               0x40
5351da177e4SLinus Torvalds 
5361da177e4SLinus Torvalds 
5371da177e4SLinus Torvalds #define  SMSYNC                  0x01
5381da177e4SLinus Torvalds #define  SM10MBS                 0x19     /* 100ns           */
5391da177e4SLinus Torvalds #define  SM5MBS                  0x32     /* 200ns           */
5401da177e4SLinus Torvalds #define  SMOFFSET                0x0F     /* Maxoffset value */
5411da177e4SLinus Torvalds #define  SMWDTR                  0x03
5421da177e4SLinus Torvalds #define  SM8BIT                  0x00
5431da177e4SLinus Torvalds #define  SM16BIT                 0x01
5441da177e4SLinus Torvalds #define  SM32BIT                 0x02
5451da177e4SLinus Torvalds #define  SMIGNORWR               0x23     /* Ignore Wide Residue */
5461da177e4SLinus Torvalds 
5471da177e4SLinus Torvalds 
5481da177e4SLinus Torvalds #define  ARBITRATION_DELAY       0x01     /* 2.4us using a 40Mhz clock */
5491da177e4SLinus Torvalds #define  BUS_SETTLE_DELAY        0x01     /* 400ns */
5501da177e4SLinus Torvalds #define  BUS_CLEAR_DELAY         0x01     /* 800ns */
5511da177e4SLinus Torvalds 
5521da177e4SLinus Torvalds 
5531da177e4SLinus Torvalds 
5541da177e4SLinus Torvalds #define  SPHASE_TO               0x0A  /* 10 second timeout waiting for */
5551da177e4SLinus Torvalds #define  SCMD_TO                 0x0F  /* Overall command timeout */
5561da177e4SLinus Torvalds 
5571da177e4SLinus Torvalds 
5581da177e4SLinus Torvalds 
5591da177e4SLinus Torvalds #define  SIX_BYTE_CMD            0x06
5601da177e4SLinus Torvalds #define  TEN_BYTE_CMD            0x0A
5611da177e4SLinus Torvalds #define  TWELVE_BYTE_CMD         0x0C
5621da177e4SLinus Torvalds 
5631da177e4SLinus Torvalds #define  ASYNC                   0x00
5641da177e4SLinus Torvalds #define  PERI25NS                0x06  /* 25/4ns to next clock for xbow. */
5651da177e4SLinus Torvalds #define  SYNC10MBS               0x19
5661da177e4SLinus Torvalds #define  SYNC5MBS                0x32
5671da177e4SLinus Torvalds #define  MAX_OFFSET              0x0F  /* Maxbyteoffset for Sync Xfers */
5681da177e4SLinus Torvalds 
5691da177e4SLinus Torvalds 
5701da177e4SLinus Torvalds #define  EEPROM_WD_CNT     256
5711da177e4SLinus Torvalds 
5721da177e4SLinus Torvalds #define  EEPROM_CHECK_SUM  0
5731da177e4SLinus Torvalds #define  FW_SIGNATURE      2
5741da177e4SLinus Torvalds #define  MODEL_NUMB_0      4
5751da177e4SLinus Torvalds #define  MODEL_NUMB_1      5
5761da177e4SLinus Torvalds #define  MODEL_NUMB_2      6
5771da177e4SLinus Torvalds #define  MODEL_NUMB_3      7
5781da177e4SLinus Torvalds #define  MODEL_NUMB_4      8
5791da177e4SLinus Torvalds #define  MODEL_NUMB_5      9
5801da177e4SLinus Torvalds #define  IO_BASE_ADDR      10
5811da177e4SLinus Torvalds #define  IRQ_NUMBER        12
5821da177e4SLinus Torvalds #define  PCI_INT_PIN       13
5831da177e4SLinus Torvalds #define  BUS_DELAY         14       /*On time in byte 14 off delay in 15 */
5841da177e4SLinus Torvalds #define  SYSTEM_CONFIG     16
5851da177e4SLinus Torvalds #define  SCSI_CONFIG       17
5861da177e4SLinus Torvalds #define  BIOS_CONFIG       18
5871da177e4SLinus Torvalds #define  SPIN_UP_DELAY     19
5881da177e4SLinus Torvalds #define  SCAM_CONFIG       20
5891da177e4SLinus Torvalds #define  ADAPTER_SCSI_ID   24
5901da177e4SLinus Torvalds 
5911da177e4SLinus Torvalds 
5921da177e4SLinus Torvalds #define  IGNORE_B_SCAN     32
5931da177e4SLinus Torvalds #define  SEND_START_ENA    34
5941da177e4SLinus Torvalds #define  DEVICE_ENABLE     36
5951da177e4SLinus Torvalds 
5961da177e4SLinus Torvalds #define  SYNC_RATE_TBL     38
5971da177e4SLinus Torvalds #define  SYNC_RATE_TBL01   38
5981da177e4SLinus Torvalds #define  SYNC_RATE_TBL23   40
5991da177e4SLinus Torvalds #define  SYNC_RATE_TBL45   42
6001da177e4SLinus Torvalds #define  SYNC_RATE_TBL67   44
6011da177e4SLinus Torvalds #define  SYNC_RATE_TBL89   46
6021da177e4SLinus Torvalds #define  SYNC_RATE_TBLab   48
6031da177e4SLinus Torvalds #define  SYNC_RATE_TBLcd   50
6041da177e4SLinus Torvalds #define  SYNC_RATE_TBLef   52
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 
6081da177e4SLinus Torvalds #define  EE_SCAMBASE      256
6091da177e4SLinus Torvalds 
6101da177e4SLinus Torvalds 
6111da177e4SLinus Torvalds 
6121da177e4SLinus Torvalds    #define  DOM_MASTER     (BIT(0) + BIT(1))
6131da177e4SLinus Torvalds    #define  SCAM_ENABLED   BIT(2)
6141da177e4SLinus Torvalds    #define  SCAM_LEVEL2    BIT(3)
6151da177e4SLinus Torvalds 
6161da177e4SLinus Torvalds 
6171da177e4SLinus Torvalds 	#define	RENEGO_ENA		BITW(10)
6181da177e4SLinus Torvalds 	#define	CONNIO_ENA		BITW(11)
6191da177e4SLinus Torvalds    #define  GREEN_PC_ENA   BITW(12)
6201da177e4SLinus Torvalds 
6211da177e4SLinus Torvalds 
6221da177e4SLinus Torvalds    #define  AUTO_RATE_00   00
6231da177e4SLinus Torvalds    #define  AUTO_RATE_05   01
6241da177e4SLinus Torvalds    #define  AUTO_RATE_10   02
6251da177e4SLinus Torvalds    #define  AUTO_RATE_20   03
6261da177e4SLinus Torvalds 
6271da177e4SLinus Torvalds    #define  WIDE_NEGO_BIT     BIT(7)
6281da177e4SLinus Torvalds    #define  DISC_ENABLE_BIT   BIT(6)
6291da177e4SLinus Torvalds 
6301da177e4SLinus Torvalds 
6311da177e4SLinus Torvalds 
6321da177e4SLinus Torvalds    #define  hp_vendor_id_0       0x00		/* LSB */
6331da177e4SLinus Torvalds       #define  ORION_VEND_0   0x4B
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds    #define  hp_vendor_id_1       0x01		/* MSB */
6361da177e4SLinus Torvalds       #define  ORION_VEND_1   0x10
6371da177e4SLinus Torvalds 
6381da177e4SLinus Torvalds    #define  hp_device_id_0       0x02		/* LSB */
6391da177e4SLinus Torvalds       #define  ORION_DEV_0    0x30
6401da177e4SLinus Torvalds 
6411da177e4SLinus Torvalds    #define  hp_device_id_1       0x03		/* MSB */
6421da177e4SLinus Torvalds       #define  ORION_DEV_1    0x81
6431da177e4SLinus Torvalds 
6441da177e4SLinus Torvalds 	/* Sub Vendor ID and Sub Device ID only available in
6451da177e4SLinus Torvalds 		Harpoon Version 2 and higher */
6461da177e4SLinus Torvalds 
6471da177e4SLinus Torvalds    #define  hp_sub_vendor_id_0   0x04		/* LSB */
6481da177e4SLinus Torvalds    #define  hp_sub_vendor_id_1   0x05		/* MSB */
6491da177e4SLinus Torvalds    #define  hp_sub_device_id_0   0x06		/* LSB */
6501da177e4SLinus Torvalds    #define  hp_sub_device_id_1   0x07		/* MSB */
6511da177e4SLinus Torvalds 
6521da177e4SLinus Torvalds 
6531da177e4SLinus Torvalds    #define  hp_dual_addr_lo      0x08
6541da177e4SLinus Torvalds    #define  hp_dual_addr_lmi     0x09
6551da177e4SLinus Torvalds    #define  hp_dual_addr_hmi     0x0A
6561da177e4SLinus Torvalds    #define  hp_dual_addr_hi      0x0B
6571da177e4SLinus Torvalds 
6581da177e4SLinus Torvalds    #define  hp_semaphore         0x0C
6591da177e4SLinus Torvalds       #define SCCB_MGR_ACTIVE    BIT(0)
6601da177e4SLinus Torvalds       #define TICKLE_ME          BIT(1)
6611da177e4SLinus Torvalds       #define SCCB_MGR_PRESENT   BIT(3)
6621da177e4SLinus Torvalds       #define BIOS_IN_USE        BIT(4)
6631da177e4SLinus Torvalds 
6641da177e4SLinus Torvalds    #define  hp_user_defined_D    0x0D
6651da177e4SLinus Torvalds 
6661da177e4SLinus Torvalds    #define  hp_reserved_E        0x0E
6671da177e4SLinus Torvalds 
6681da177e4SLinus Torvalds    #define  hp_sys_ctrl          0x0F
6691da177e4SLinus Torvalds 
6701da177e4SLinus Torvalds       #define  STOP_CLK          BIT(0)      /*Turn off BusMaster Clock */
6711da177e4SLinus Torvalds       #define  DRVR_RST          BIT(1)      /*Firmware Reset to 80C15 chip */
6721da177e4SLinus Torvalds       #define  HALT_MACH         BIT(3)      /*Halt State Machine      */
6731da177e4SLinus Torvalds       #define  HARD_ABORT        BIT(4)      /*Hard Abort              */
6741da177e4SLinus Torvalds       #define  DIAG_MODE         BIT(5)      /*Diagnostic Mode         */
6751da177e4SLinus Torvalds 
6761da177e4SLinus Torvalds       #define  BM_ABORT_TMOUT    0x50        /*Halt State machine time out */
6771da177e4SLinus Torvalds 
6781da177e4SLinus Torvalds    #define  hp_sys_cfg           0x10
6791da177e4SLinus Torvalds 
6801da177e4SLinus Torvalds       #define  DONT_RST_FIFO     BIT(7)      /*Don't reset FIFO      */
6811da177e4SLinus Torvalds 
6821da177e4SLinus Torvalds 
6831da177e4SLinus Torvalds    #define  hp_host_ctrl0        0x11
6841da177e4SLinus Torvalds 
6851da177e4SLinus Torvalds       #define  DUAL_ADDR_MODE    BIT(0)   /*Enable 64-bit addresses */
6861da177e4SLinus Torvalds       #define  IO_MEM_SPACE      BIT(1)   /*I/O Memory Space    */
6871da177e4SLinus Torvalds       #define  RESOURCE_LOCK     BIT(2)   /*Enable Resource Lock */
6881da177e4SLinus Torvalds       #define  IGNOR_ACCESS_ERR  BIT(3)   /*Ignore Access Error */
6891da177e4SLinus Torvalds       #define  HOST_INT_EDGE     BIT(4)   /*Host interrupt level/edge mode sel */
6901da177e4SLinus Torvalds       #define  SIX_CLOCKS        BIT(5)   /*6 Clocks between Strobe   */
6911da177e4SLinus Torvalds       #define  DMA_EVEN_PARITY   BIT(6)   /*Enable DMA Enen Parity */
6921da177e4SLinus Torvalds 
6931da177e4SLinus Torvalds /*
6941da177e4SLinus Torvalds       #define  BURST_MODE        BIT(0)
6951da177e4SLinus Torvalds */
6961da177e4SLinus Torvalds 
6971da177e4SLinus Torvalds    #define  hp_reserved_12       0x12
6981da177e4SLinus Torvalds 
6991da177e4SLinus Torvalds    #define  hp_host_blk_cnt      0x13
7001da177e4SLinus Torvalds 
7011da177e4SLinus Torvalds       #define  XFER_BLK1         0x00     /*     0 0 0  1 byte per block*/
7021da177e4SLinus Torvalds       #define  XFER_BLK2         0x01     /*     0 0 1  2 byte per block*/
7031da177e4SLinus Torvalds       #define  XFER_BLK4         0x02     /*     0 1 0  4 byte per block*/
7041da177e4SLinus Torvalds       #define  XFER_BLK8         0x03     /*     0 1 1  8 byte per block*/
7051da177e4SLinus Torvalds       #define  XFER_BLK16        0x04     /*     1 0 0 16 byte per block*/
7061da177e4SLinus Torvalds       #define  XFER_BLK32        0x05     /*     1 0 1 32 byte per block*/
7071da177e4SLinus Torvalds       #define  XFER_BLK64        0x06     /*     1 1 0 64 byte per block*/
7081da177e4SLinus Torvalds 
7091da177e4SLinus Torvalds       #define  BM_THRESHOLD      0x40     /* PCI mode can only xfer 16 bytes*/
7101da177e4SLinus Torvalds 
7111da177e4SLinus Torvalds 
7121da177e4SLinus Torvalds    #define  hp_reserved_14       0x14
7131da177e4SLinus Torvalds    #define  hp_reserved_15       0x15
7141da177e4SLinus Torvalds    #define  hp_reserved_16       0x16
7151da177e4SLinus Torvalds 
7161da177e4SLinus Torvalds    #define  hp_int_mask          0x17
7171da177e4SLinus Torvalds 
7181da177e4SLinus Torvalds       #define  INT_CMD_COMPL     BIT(0)   /* DMA command complete   */
7191da177e4SLinus Torvalds       #define  INT_EXT_STATUS    BIT(1)   /* Extended Status Set    */
7201da177e4SLinus Torvalds       #define  INT_SCSI          BIT(2)   /* Scsi block interrupt   */
7211da177e4SLinus Torvalds       #define  INT_FIFO_RDY      BIT(4)   /* FIFO data ready        */
7221da177e4SLinus Torvalds 
7231da177e4SLinus Torvalds 
7241da177e4SLinus Torvalds    #define  hp_xfer_cnt_lo       0x18
7251da177e4SLinus Torvalds    #define  hp_xfer_cnt_mi       0x19
7261da177e4SLinus Torvalds    #define  hp_xfer_cnt_hi       0x1A
7271da177e4SLinus Torvalds    #define  hp_xfer_cmd          0x1B
7281da177e4SLinus Torvalds 
7291da177e4SLinus Torvalds       #define  XFER_HOST_DMA     0x00     /*     0 0 0 Transfer Host -> DMA */
7301da177e4SLinus Torvalds       #define  XFER_DMA_HOST     0x01     /*     0 0 1 Transfer DMA  -> Host */
7311da177e4SLinus Torvalds       #define  XFER_HOST_MPU     0x02     /*     0 1 0 Transfer Host -> MPU  */
7321da177e4SLinus Torvalds       #define  XFER_MPU_HOST     0x03     /*     0 1 1 Transfer MPU  -> Host */
7331da177e4SLinus Torvalds       #define  XFER_DMA_MPU      0x04     /*     1 0 0 Transfer DMA  -> MPU  */
7341da177e4SLinus Torvalds       #define  XFER_MPU_DMA      0x05     /*     1 0 1 Transfer MPU  -> DMA  */
7351da177e4SLinus Torvalds       #define  SET_SEMAPHORE     0x06     /*     1 1 0 Set Semaphore         */
7361da177e4SLinus Torvalds       #define  XFER_NOP          0x07     /*     1 1 1 Transfer NOP          */
7371da177e4SLinus Torvalds       #define  XFER_MB_MPU       0x06     /*     1 1 0 Transfer MB -> MPU */
7381da177e4SLinus Torvalds       #define  XFER_MB_DMA       0x07     /*     1 1 1 Transfer MB -> DMA */
7391da177e4SLinus Torvalds 
7401da177e4SLinus Torvalds 
7411da177e4SLinus Torvalds       #define  XFER_HOST_AUTO    0x00     /*     0 0 Auto Transfer Size   */
7421da177e4SLinus Torvalds       #define  XFER_HOST_8BIT    0x08     /*     0 1 8 BIT Transfer Size  */
7431da177e4SLinus Torvalds       #define  XFER_HOST_16BIT   0x10     /*     1 0 16 BIT Transfer Size */
7441da177e4SLinus Torvalds       #define  XFER_HOST_32BIT   0x18     /*     1 1 32 BIT Transfer Size */
7451da177e4SLinus Torvalds 
7461da177e4SLinus Torvalds       #define  XFER_DMA_8BIT     0x20     /*     0 1 8 BIT  Transfer Size */
7471da177e4SLinus Torvalds       #define  XFER_DMA_16BIT    0x40     /*     1 0 16 BIT Transfer Size */
7481da177e4SLinus Torvalds 
7491da177e4SLinus Torvalds       #define  DISABLE_INT       BIT(7)   /*Do not interrupt at end of cmd. */
7501da177e4SLinus Torvalds 
7511da177e4SLinus Torvalds       #define  HOST_WRT_CMD      ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
7521da177e4SLinus Torvalds       #define  HOST_RD_CMD       ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
7531da177e4SLinus Torvalds       #define  WIDE_HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_16BIT))
7541da177e4SLinus Torvalds       #define  WIDE_HOST_RD_CMD  ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_16BIT))
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds    #define  hp_host_addr_lo      0x1C
7571da177e4SLinus Torvalds    #define  hp_host_addr_lmi     0x1D
7581da177e4SLinus Torvalds    #define  hp_host_addr_hmi     0x1E
7591da177e4SLinus Torvalds    #define  hp_host_addr_hi      0x1F
7601da177e4SLinus Torvalds 
7611da177e4SLinus Torvalds    #define  hp_pio_data          0x20
7621da177e4SLinus Torvalds    #define  hp_reserved_21       0x21
7631da177e4SLinus Torvalds    #define  hp_ee_ctrl           0x22
7641da177e4SLinus Torvalds 
7651da177e4SLinus Torvalds       #define  EXT_ARB_ACK       BIT(7)
7661da177e4SLinus Torvalds       #define  SCSI_TERM_ENA_H   BIT(6)   /* SCSI high byte terminator */
7671da177e4SLinus Torvalds       #define  SEE_MS            BIT(5)
7681da177e4SLinus Torvalds       #define  SEE_CS            BIT(3)
7691da177e4SLinus Torvalds       #define  SEE_CLK           BIT(2)
7701da177e4SLinus Torvalds       #define  SEE_DO            BIT(1)
7711da177e4SLinus Torvalds       #define  SEE_DI            BIT(0)
7721da177e4SLinus Torvalds 
7731da177e4SLinus Torvalds       #define  EE_READ           0x06
7741da177e4SLinus Torvalds       #define  EE_WRITE          0x05
7751da177e4SLinus Torvalds       #define  EWEN              0x04
7761da177e4SLinus Torvalds       #define  EWEN_ADDR         0x03C0
7771da177e4SLinus Torvalds       #define  EWDS              0x04
7781da177e4SLinus Torvalds       #define  EWDS_ADDR         0x0000
7791da177e4SLinus Torvalds 
7801da177e4SLinus Torvalds    #define  hp_brdctl            0x23
7811da177e4SLinus Torvalds 
7821da177e4SLinus Torvalds       #define  DAT_7             BIT(7)
7831da177e4SLinus Torvalds       #define  DAT_6             BIT(6)
7841da177e4SLinus Torvalds       #define  DAT_5             BIT(5)
7851da177e4SLinus Torvalds       #define  BRD_STB           BIT(4)
7861da177e4SLinus Torvalds       #define  BRD_CS            BIT(3)
7871da177e4SLinus Torvalds       #define  BRD_WR            BIT(2)
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds    #define  hp_reserved_24       0x24
7901da177e4SLinus Torvalds    #define  hp_reserved_25       0x25
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds 
7951da177e4SLinus Torvalds    #define  hp_bm_ctrl           0x26
7961da177e4SLinus Torvalds 
7971da177e4SLinus Torvalds       #define  SCSI_TERM_ENA_L   BIT(0)   /*Enable/Disable external terminators */
7981da177e4SLinus Torvalds       #define  FLUSH_XFER_CNTR   BIT(1)   /*Flush transfer counter */
7991da177e4SLinus Torvalds       #define  BM_XFER_MIN_8     BIT(2)   /*Enable bus master transfer of 9 */
8001da177e4SLinus Torvalds       #define  BIOS_ENA          BIT(3)   /*Enable BIOS/FLASH Enable */
8011da177e4SLinus Torvalds       #define  FORCE1_XFER       BIT(5)   /*Always xfer one byte in byte mode */
8021da177e4SLinus Torvalds       #define  FAST_SINGLE       BIT(6)   /*?? */
8031da177e4SLinus Torvalds 
8041da177e4SLinus Torvalds       #define  BMCTRL_DEFAULT    (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
8051da177e4SLinus Torvalds 
8061da177e4SLinus Torvalds    #define  hp_reserved_27       0x27
8071da177e4SLinus Torvalds 
8081da177e4SLinus Torvalds    #define  hp_sg_addr           0x28
8091da177e4SLinus Torvalds    #define  hp_page_ctrl         0x29
8101da177e4SLinus Torvalds 
8111da177e4SLinus Torvalds       #define  SCATTER_EN        BIT(0)
8121da177e4SLinus Torvalds       #define  SGRAM_ARAM        BIT(1)
8131da177e4SLinus Torvalds       #define  BIOS_SHADOW       BIT(2)
8141da177e4SLinus Torvalds       #define  G_INT_DISABLE     BIT(3)   /* Enable/Disable all Interrupts */
8151da177e4SLinus Torvalds       #define  NARROW_SCSI_CARD  BIT(4)   /* NARROW/WIDE SCSI config pin */
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds    #define  hp_reserved_2A       0x2A
8181da177e4SLinus Torvalds    #define  hp_pci_cmd_cfg       0x2B
8191da177e4SLinus Torvalds 
8201da177e4SLinus Torvalds       #define  IO_SPACE_ENA      BIT(0)   /*enable I/O space */
8211da177e4SLinus Torvalds       #define  MEM_SPACE_ENA     BIT(1)   /*enable memory space */
8221da177e4SLinus Torvalds       #define  BUS_MSTR_ENA      BIT(2)   /*enable bus master operation */
8231da177e4SLinus Torvalds       #define  MEM_WI_ENA        BIT(4)   /*enable Write and Invalidate */
8241da177e4SLinus Torvalds       #define  PAR_ERR_RESP      BIT(6)   /*enable parity error responce. */
8251da177e4SLinus Torvalds 
8261da177e4SLinus Torvalds    #define  hp_reserved_2C       0x2C
8271da177e4SLinus Torvalds 
8281da177e4SLinus Torvalds    #define  hp_pci_stat_cfg      0x2D
8291da177e4SLinus Torvalds 
8301da177e4SLinus Torvalds       #define  DATA_PARITY_ERR   BIT(0)
8311da177e4SLinus Torvalds       #define  REC_TARGET_ABORT  BIT(4)   /*received Target abort */
8321da177e4SLinus Torvalds       #define  REC_MASTER_ABORT  BIT(5)   /*received Master abort */
8331da177e4SLinus Torvalds       #define  SIG_SYSTEM_ERR    BIT(6)
8341da177e4SLinus Torvalds       #define  DETECTED_PAR_ERR  BIT(7)
8351da177e4SLinus Torvalds 
8361da177e4SLinus Torvalds    #define  hp_reserved_2E       0x2E
8371da177e4SLinus Torvalds 
8381da177e4SLinus Torvalds    #define  hp_sys_status        0x2F
8391da177e4SLinus Torvalds 
8401da177e4SLinus Torvalds       #define  SLV_DATA_RDY      BIT(0)   /*Slave data ready */
8411da177e4SLinus Torvalds       #define  XFER_CNT_ZERO     BIT(1)   /*Transfer counter = 0 */
8421da177e4SLinus Torvalds       #define  BM_FIFO_EMPTY     BIT(2)   /*FIFO empty */
8431da177e4SLinus Torvalds       #define  BM_FIFO_FULL      BIT(3)   /*FIFO full */
8441da177e4SLinus Torvalds       #define  HOST_OP_DONE      BIT(4)   /*host operation done */
8451da177e4SLinus Torvalds       #define  DMA_OP_DONE       BIT(5)   /*DMA operation done */
8461da177e4SLinus Torvalds       #define  SLV_OP_DONE       BIT(6)   /*Slave operation done */
8471da177e4SLinus Torvalds       #define  PWR_ON_FLAG       BIT(7)   /*Power on flag */
8481da177e4SLinus Torvalds 
8491da177e4SLinus Torvalds    #define  hp_reserved_30       0x30
8501da177e4SLinus Torvalds 
8511da177e4SLinus Torvalds    #define  hp_host_status0      0x31
8521da177e4SLinus Torvalds 
8531da177e4SLinus Torvalds       #define  HOST_TERM         BIT(5)   /*Host Terminal Count */
8541da177e4SLinus Torvalds       #define  HOST_TRSHLD       BIT(6)   /*Host Threshold      */
8551da177e4SLinus Torvalds       #define  CONNECTED_2_HOST  BIT(7)   /*Connected to Host   */
8561da177e4SLinus Torvalds 
8571da177e4SLinus Torvalds    #define  hp_reserved_32       0x32
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds    #define  hp_rev_num           0x33
8601da177e4SLinus Torvalds 
8611da177e4SLinus Torvalds       #define  REV_A_CONST       0x0E
8621da177e4SLinus Torvalds       #define  REV_B_CONST       0x0E
8631da177e4SLinus Torvalds 
8641da177e4SLinus Torvalds    #define  hp_stack_data        0x34
8651da177e4SLinus Torvalds    #define  hp_stack_addr        0x35
8661da177e4SLinus Torvalds 
8671da177e4SLinus Torvalds    #define  hp_ext_status        0x36
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds       #define  BM_FORCE_OFF      BIT(0)   /*Bus Master is forced to get off */
8701da177e4SLinus Torvalds       #define  PCI_TGT_ABORT     BIT(0)   /*PCI bus master transaction aborted */
8711da177e4SLinus Torvalds       #define  PCI_DEV_TMOUT     BIT(1)   /*PCI Device Time out */
8721da177e4SLinus Torvalds       #define  FIFO_TC_NOT_ZERO  BIT(2)   /*FIFO or transfer counter not zero */
8731da177e4SLinus Torvalds       #define  CHIP_RST_OCCUR    BIT(3)   /*Chip reset occurs */
8741da177e4SLinus Torvalds       #define  CMD_ABORTED       BIT(4)   /*Command aborted */
8751da177e4SLinus Torvalds       #define  BM_PARITY_ERR     BIT(5)   /*parity error on data received   */
8761da177e4SLinus Torvalds       #define  PIO_OVERRUN       BIT(6)   /*Slave data overrun */
8771da177e4SLinus Torvalds       #define  BM_CMD_BUSY       BIT(7)   /*Bus master transfer command busy */
8781da177e4SLinus Torvalds       #define  BAD_EXT_STATUS    (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
8791da177e4SLinus Torvalds                                   BM_PARITY_ERR | PIO_OVERRUN)
8801da177e4SLinus Torvalds 
8811da177e4SLinus Torvalds    #define  hp_int_status        0x37
8821da177e4SLinus Torvalds 
8831da177e4SLinus Torvalds       #define  BM_CMD_CMPL       BIT(0)   /*Bus Master command complete */
8841da177e4SLinus Torvalds       #define  EXT_STATUS_ON     BIT(1)   /*Extended status is valid */
8851da177e4SLinus Torvalds       #define  SCSI_INTERRUPT    BIT(2)   /*Global indication of a SCSI int. */
8861da177e4SLinus Torvalds       #define  BM_FIFO_RDY       BIT(4)
8871da177e4SLinus Torvalds       #define  INT_ASSERTED      BIT(5)   /* */
8881da177e4SLinus Torvalds       #define  SRAM_BUSY         BIT(6)   /*Scatter/Gather RAM busy */
8891da177e4SLinus Torvalds       #define  CMD_REG_BUSY      BIT(7)
8901da177e4SLinus Torvalds 
8911da177e4SLinus Torvalds 
8921da177e4SLinus Torvalds    #define  hp_fifo_cnt          0x38
8931da177e4SLinus Torvalds    #define  hp_curr_host_cnt     0x39
8941da177e4SLinus Torvalds    #define  hp_reserved_3A       0x3A
8951da177e4SLinus Torvalds    #define  hp_fifo_in_addr      0x3B
8961da177e4SLinus Torvalds 
8971da177e4SLinus Torvalds    #define  hp_fifo_out_addr     0x3C
8981da177e4SLinus Torvalds    #define  hp_reserved_3D       0x3D
8991da177e4SLinus Torvalds    #define  hp_reserved_3E       0x3E
9001da177e4SLinus Torvalds    #define  hp_reserved_3F       0x3F
9011da177e4SLinus Torvalds 
9021da177e4SLinus Torvalds 
9031da177e4SLinus Torvalds 
9041da177e4SLinus Torvalds    #define  hp_intena		 0x40
9051da177e4SLinus Torvalds 
9061da177e4SLinus Torvalds       #define  RESET		 BITW(7)
9071da177e4SLinus Torvalds       #define  PROG_HLT		 BITW(6)
9081da177e4SLinus Torvalds       #define  PARITY		 BITW(5)
9091da177e4SLinus Torvalds       #define  FIFO		 BITW(4)
9101da177e4SLinus Torvalds       #define  SEL		 BITW(3)
9111da177e4SLinus Torvalds       #define  SCAM_SEL		 BITW(2)
9121da177e4SLinus Torvalds       #define  RSEL		 BITW(1)
9131da177e4SLinus Torvalds       #define  TIMEOUT		 BITW(0)
9141da177e4SLinus Torvalds       #define  BUS_FREE		 BITW(15)
9151da177e4SLinus Torvalds       #define  XFER_CNT_0	 BITW(14)
9161da177e4SLinus Torvalds       #define  PHASE		 BITW(13)
9171da177e4SLinus Torvalds       #define  IUNKWN		 BITW(12)
9181da177e4SLinus Torvalds       #define  ICMD_COMP	 BITW(11)
9191da177e4SLinus Torvalds       #define  ITICKLE		 BITW(10)
9201da177e4SLinus Torvalds       #define  IDO_STRT		 BITW(9)
9211da177e4SLinus Torvalds       #define  ITAR_DISC	 BITW(8)
9221da177e4SLinus Torvalds       #define  AUTO_INT		 (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
9231da177e4SLinus Torvalds       #define  CLR_ALL_INT	 0xFFFF
9241da177e4SLinus Torvalds       #define  CLR_ALL_INT_1	 0xFF00
9251da177e4SLinus Torvalds 
9261da177e4SLinus Torvalds    #define  hp_intstat		 0x42
9271da177e4SLinus Torvalds 
9281da177e4SLinus Torvalds    #define  hp_scsisig           0x44
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds       #define  SCSI_SEL          BIT(7)
9311da177e4SLinus Torvalds       #define  SCSI_BSY          BIT(6)
9321da177e4SLinus Torvalds       #define  SCSI_REQ          BIT(5)
9331da177e4SLinus Torvalds       #define  SCSI_ACK          BIT(4)
9341da177e4SLinus Torvalds       #define  SCSI_ATN          BIT(3)
9351da177e4SLinus Torvalds       #define  SCSI_CD           BIT(2)
9361da177e4SLinus Torvalds       #define  SCSI_MSG          BIT(1)
9371da177e4SLinus Torvalds       #define  SCSI_IOBIT        BIT(0)
9381da177e4SLinus Torvalds 
9391da177e4SLinus Torvalds       #define  S_SCSI_PHZ        (BIT(2)+BIT(1)+BIT(0))
9401da177e4SLinus Torvalds       #define  S_CMD_PH          (BIT(2)              )
9411da177e4SLinus Torvalds       #define  S_MSGO_PH         (BIT(2)+BIT(1)       )
9421da177e4SLinus Torvalds       #define  S_STAT_PH         (BIT(2)       +BIT(0))
9431da177e4SLinus Torvalds       #define  S_MSGI_PH         (BIT(2)+BIT(1)+BIT(0))
9441da177e4SLinus Torvalds       #define  S_DATAI_PH        (              BIT(0))
9451da177e4SLinus Torvalds       #define  S_DATAO_PH        0x00
9461da177e4SLinus Torvalds       #define  S_ILL_PH          (       BIT(1)       )
9471da177e4SLinus Torvalds 
9481da177e4SLinus Torvalds    #define  hp_scsictrl_0        0x45
9491da177e4SLinus Torvalds 
9501da177e4SLinus Torvalds       #define  NO_ARB            BIT(7)
9511da177e4SLinus Torvalds       #define  SEL_TAR           BIT(6)
9521da177e4SLinus Torvalds       #define  ENA_ATN           BIT(4)
9531da177e4SLinus Torvalds       #define  ENA_RESEL         BIT(2)
9541da177e4SLinus Torvalds       #define  SCSI_RST          BIT(1)
9551da177e4SLinus Torvalds       #define  ENA_SCAM_SEL      BIT(0)
9561da177e4SLinus Torvalds 
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds 
9591da177e4SLinus Torvalds    #define  hp_portctrl_0        0x46
9601da177e4SLinus Torvalds 
9611da177e4SLinus Torvalds       #define  SCSI_PORT         BIT(7)
9621da177e4SLinus Torvalds       #define  SCSI_INBIT        BIT(6)
9631da177e4SLinus Torvalds       #define  DMA_PORT          BIT(5)
9641da177e4SLinus Torvalds       #define  DMA_RD            BIT(4)
9651da177e4SLinus Torvalds       #define  HOST_PORT         BIT(3)
9661da177e4SLinus Torvalds       #define  HOST_WRT          BIT(2)
9671da177e4SLinus Torvalds       #define  SCSI_BUS_EN       BIT(1)
9681da177e4SLinus Torvalds       #define  START_TO          BIT(0)
9691da177e4SLinus Torvalds 
9701da177e4SLinus Torvalds    #define  hp_scsireset         0x47
9711da177e4SLinus Torvalds 
9721da177e4SLinus Torvalds       #define  SCSI_TAR          BIT(7)
9731da177e4SLinus Torvalds       #define  SCSI_INI          BIT(6)
9741da177e4SLinus Torvalds       #define  SCAM_EN           BIT(5)
9751da177e4SLinus Torvalds       #define  ACK_HOLD          BIT(4)
9761da177e4SLinus Torvalds       #define  DMA_RESET         BIT(3)
9771da177e4SLinus Torvalds       #define  HPSCSI_RESET      BIT(2)
9781da177e4SLinus Torvalds       #define  PROG_RESET        BIT(1)
9791da177e4SLinus Torvalds       #define  FIFO_CLR          BIT(0)
9801da177e4SLinus Torvalds 
9811da177e4SLinus Torvalds    #define  hp_xfercnt_0         0x48
9821da177e4SLinus Torvalds    #define  hp_xfercnt_1         0x49
9831da177e4SLinus Torvalds    #define  hp_xfercnt_2         0x4A
9841da177e4SLinus Torvalds    #define  hp_xfercnt_3         0x4B
9851da177e4SLinus Torvalds 
9861da177e4SLinus Torvalds    #define  hp_fifodata_0        0x4C
9871da177e4SLinus Torvalds    #define  hp_fifodata_1        0x4D
9881da177e4SLinus Torvalds    #define  hp_addstat           0x4E
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds       #define  SCAM_TIMER        BIT(7)
9911da177e4SLinus Torvalds       #define  AUTO_RUNNING      BIT(6)
9921da177e4SLinus Torvalds       #define  FAST_SYNC         BIT(5)
9931da177e4SLinus Torvalds       #define  SCSI_MODE8        BIT(3)
9941da177e4SLinus Torvalds       #define  SCSI_PAR_ERR      BIT(0)
9951da177e4SLinus Torvalds 
9961da177e4SLinus Torvalds    #define  hp_prgmcnt_0         0x4F
9971da177e4SLinus Torvalds 
9981da177e4SLinus Torvalds       #define  AUTO_PC_MASK      0x3F
9991da177e4SLinus Torvalds 
10001da177e4SLinus Torvalds    #define  hp_selfid_0          0x50
10011da177e4SLinus Torvalds    #define  hp_selfid_1          0x51
10021da177e4SLinus Torvalds    #define  hp_arb_id            0x52
10031da177e4SLinus Torvalds 
10041da177e4SLinus Torvalds       #define  ARB_ID            (BIT(3) + BIT(2) + BIT(1) + BIT(0))
10051da177e4SLinus Torvalds 
10061da177e4SLinus Torvalds    #define  hp_select_id         0x53
10071da177e4SLinus Torvalds 
10081da177e4SLinus Torvalds       #define  RESEL_ID          (BIT(7) + BIT(6) + BIT(5) + BIT(4))
10091da177e4SLinus Torvalds       #define  SELECT_ID         (BIT(3) + BIT(2) + BIT(1) + BIT(0))
10101da177e4SLinus Torvalds 
10111da177e4SLinus Torvalds    #define  hp_synctarg_base     0x54
10121da177e4SLinus Torvalds    #define  hp_synctarg_12       0x54
10131da177e4SLinus Torvalds    #define  hp_synctarg_13       0x55
10141da177e4SLinus Torvalds    #define  hp_synctarg_14       0x56
10151da177e4SLinus Torvalds    #define  hp_synctarg_15       0x57
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds    #define  hp_synctarg_8        0x58
10181da177e4SLinus Torvalds    #define  hp_synctarg_9        0x59
10191da177e4SLinus Torvalds    #define  hp_synctarg_10       0x5A
10201da177e4SLinus Torvalds    #define  hp_synctarg_11       0x5B
10211da177e4SLinus Torvalds 
10221da177e4SLinus Torvalds    #define  hp_synctarg_4        0x5C
10231da177e4SLinus Torvalds    #define  hp_synctarg_5        0x5D
10241da177e4SLinus Torvalds    #define  hp_synctarg_6        0x5E
10251da177e4SLinus Torvalds    #define  hp_synctarg_7        0x5F
10261da177e4SLinus Torvalds 
10271da177e4SLinus Torvalds    #define  hp_synctarg_0        0x60
10281da177e4SLinus Torvalds    #define  hp_synctarg_1        0x61
10291da177e4SLinus Torvalds    #define  hp_synctarg_2        0x62
10301da177e4SLinus Torvalds    #define  hp_synctarg_3        0x63
10311da177e4SLinus Torvalds 
10321da177e4SLinus Torvalds       #define  RATE_20MB         0x00
10331da177e4SLinus Torvalds       #define  RATE_10MB         (              BIT(5))
10341da177e4SLinus Torvalds       #define  RATE_6_6MB        (       BIT(6)       )
10351da177e4SLinus Torvalds       #define  RATE_5MB          (       BIT(6)+BIT(5))
10361da177e4SLinus Torvalds       #define  RATE_4MB          (BIT(7)              )
10371da177e4SLinus Torvalds       #define  RATE_3_33MB       (BIT(7)       +BIT(5))
10381da177e4SLinus Torvalds       #define  RATE_2_85MB       (BIT(7)+BIT(6)       )
10391da177e4SLinus Torvalds       #define  RATE_2_5MB        (BIT(7)+BIT(5)+BIT(6))
10401da177e4SLinus Torvalds       #define  NEXT_CLK          BIT(5)
10411da177e4SLinus Torvalds       #define  SLOWEST_SYNC      (BIT(7)+BIT(6)+BIT(5))
10421da177e4SLinus Torvalds       #define  NARROW_SCSI       BIT(4)
10431da177e4SLinus Torvalds       #define  SYNC_OFFSET       (BIT(3) + BIT(2) + BIT(1) + BIT(0))
10441da177e4SLinus Torvalds       #define  DEFAULT_ASYNC     0x00
10451da177e4SLinus Torvalds       #define  DEFAULT_OFFSET    0x0F
10461da177e4SLinus Torvalds 
10471da177e4SLinus Torvalds    #define  hp_autostart_0       0x64
10481da177e4SLinus Torvalds    #define  hp_autostart_1       0x65
10491da177e4SLinus Torvalds    #define  hp_autostart_2       0x66
10501da177e4SLinus Torvalds    #define  hp_autostart_3       0x67
10511da177e4SLinus Torvalds 
10521da177e4SLinus Torvalds 
10531da177e4SLinus Torvalds 
10541da177e4SLinus Torvalds       #define  DISABLE  0x00
10551da177e4SLinus Torvalds       #define  AUTO_IMMED    BIT(5)
10561da177e4SLinus Torvalds       #define  SELECT   BIT(6)
10571da177e4SLinus Torvalds       #define  RESELECT (BIT(6)+BIT(5))
10581da177e4SLinus Torvalds       #define  BUSFREE  BIT(7)
10591da177e4SLinus Torvalds       #define  XFER_0   (BIT(7)+BIT(5))
10601da177e4SLinus Torvalds       #define  END_DATA (BIT(7)+BIT(6))
10611da177e4SLinus Torvalds       #define  MSG_PHZ  (BIT(7)+BIT(6)+BIT(5))
10621da177e4SLinus Torvalds 
10631da177e4SLinus Torvalds    #define  hp_gp_reg_0          0x68
10641da177e4SLinus Torvalds    #define  hp_gp_reg_1          0x69
10651da177e4SLinus Torvalds    #define  hp_gp_reg_2          0x6A
10661da177e4SLinus Torvalds    #define  hp_gp_reg_3          0x6B
10671da177e4SLinus Torvalds 
10681da177e4SLinus Torvalds    #define  hp_seltimeout        0x6C
10691da177e4SLinus Torvalds 
10701da177e4SLinus Torvalds 
10711da177e4SLinus Torvalds       #define  TO_2ms            0x54      /* 2.0503ms */
10721da177e4SLinus Torvalds       #define  TO_4ms            0x67      /* 3.9959ms */
10731da177e4SLinus Torvalds 
10741da177e4SLinus Torvalds       #define  TO_5ms            0x03      /* 4.9152ms */
10751da177e4SLinus Torvalds       #define  TO_10ms           0x07      /* 11.xxxms */
10761da177e4SLinus Torvalds       #define  TO_250ms          0x99      /* 250.68ms */
10771da177e4SLinus Torvalds       #define  TO_290ms          0xB1      /* 289.99ms */
10781da177e4SLinus Torvalds       #define  TO_350ms          0xD6      /* 350.62ms */
10791da177e4SLinus Torvalds       #define  TO_417ms          0xFF      /* 417.79ms */
10801da177e4SLinus Torvalds 
10811da177e4SLinus Torvalds    #define  hp_clkctrl_0         0x6D
10821da177e4SLinus Torvalds 
10831da177e4SLinus Torvalds       #define  PWR_DWN           BIT(6)
10841da177e4SLinus Torvalds       #define  ACTdeassert       BIT(4)
10851da177e4SLinus Torvalds       #define  ATNonErr          BIT(3)
10861da177e4SLinus Torvalds       #define  CLK_30MHZ         BIT(1)
10871da177e4SLinus Torvalds       #define  CLK_40MHZ         (BIT(1) + BIT(0))
10881da177e4SLinus Torvalds       #define  CLK_50MHZ         BIT(2)
10891da177e4SLinus Torvalds 
10901da177e4SLinus Torvalds       #define  CLKCTRL_DEFAULT   (ACTdeassert | CLK_40MHZ)
10911da177e4SLinus Torvalds 
10921da177e4SLinus Torvalds    #define  hp_fiforead          0x6E
10931da177e4SLinus Torvalds    #define  hp_fifowrite         0x6F
10941da177e4SLinus Torvalds 
10951da177e4SLinus Torvalds    #define  hp_offsetctr         0x70
10961da177e4SLinus Torvalds    #define  hp_xferstat          0x71
10971da177e4SLinus Torvalds 
10981da177e4SLinus Torvalds       #define  FIFO_FULL         BIT(7)
10991da177e4SLinus Torvalds       #define  FIFO_EMPTY        BIT(6)
11001da177e4SLinus Torvalds       #define  FIFO_MASK         0x3F   /* Mask for the FIFO count value. */
11011da177e4SLinus Torvalds       #define  FIFO_LEN          0x20
11021da177e4SLinus Torvalds 
11031da177e4SLinus Torvalds    #define  hp_portctrl_1        0x72
11041da177e4SLinus Torvalds 
11051da177e4SLinus Torvalds       #define  EVEN_HOST_P       BIT(5)
11061da177e4SLinus Torvalds       #define  INVT_SCSI         BIT(4)
11071da177e4SLinus Torvalds       #define  CHK_SCSI_P        BIT(3)
11081da177e4SLinus Torvalds       #define  HOST_MODE8        BIT(0)
11091da177e4SLinus Torvalds       #define  HOST_MODE16       0x00
11101da177e4SLinus Torvalds 
11111da177e4SLinus Torvalds    #define  hp_xfer_pad          0x73
11121da177e4SLinus Torvalds 
11131da177e4SLinus Torvalds       #define  ID_UNLOCK         BIT(3)
11141da177e4SLinus Torvalds       #define  XFER_PAD          BIT(2)
11151da177e4SLinus Torvalds 
11161da177e4SLinus Torvalds    #define  hp_scsidata_0        0x74
11171da177e4SLinus Torvalds    #define  hp_scsidata_1        0x75
11181da177e4SLinus Torvalds    #define  hp_timer_0           0x76
11191da177e4SLinus Torvalds    #define  hp_timer_1           0x77
11201da177e4SLinus Torvalds 
11211da177e4SLinus Torvalds    #define  hp_reserved_78       0x78
11221da177e4SLinus Torvalds    #define  hp_reserved_79       0x79
11231da177e4SLinus Torvalds    #define  hp_reserved_7A       0x7A
11241da177e4SLinus Torvalds    #define  hp_reserved_7B       0x7B
11251da177e4SLinus Torvalds 
11261da177e4SLinus Torvalds    #define  hp_reserved_7C       0x7C
11271da177e4SLinus Torvalds    #define  hp_reserved_7D       0x7D
11281da177e4SLinus Torvalds    #define  hp_reserved_7E       0x7E
11291da177e4SLinus Torvalds    #define  hp_reserved_7F       0x7F
11301da177e4SLinus Torvalds 
11311da177e4SLinus Torvalds    #define  hp_aramBase          0x80
11321da177e4SLinus Torvalds    #define  BIOS_DATA_OFFSET     0x60
11331da177e4SLinus Torvalds    #define  BIOS_RELATIVE_CARD   0x64
11341da177e4SLinus Torvalds 
11351da177e4SLinus Torvalds 
11361da177e4SLinus Torvalds 
11371da177e4SLinus Torvalds 
11381da177e4SLinus Torvalds       #define  AUTO_LEN 0x80
11391da177e4SLinus Torvalds       #define  AR0      0x00
11401da177e4SLinus Torvalds       #define  AR1      BITW(8)
11411da177e4SLinus Torvalds       #define  AR2      BITW(9)
11421da177e4SLinus Torvalds       #define  AR3      (BITW(9) + BITW(8))
11431da177e4SLinus Torvalds       #define  SDATA    BITW(10)
11441da177e4SLinus Torvalds 
11451da177e4SLinus Torvalds       #define  NOP_OP   0x00        /* Nop command */
11461da177e4SLinus Torvalds 
11471da177e4SLinus Torvalds       #define  CRD_OP   BITW(11)     /* Cmp Reg. w/ Data */
11481da177e4SLinus Torvalds 
11491da177e4SLinus Torvalds       #define  CRR_OP   BITW(12)     /* Cmp Reg. w. Reg. */
11501da177e4SLinus Torvalds 
11511da177e4SLinus Torvalds       #define  CBE_OP   (BITW(14)+BITW(12)+BITW(11)) /* Cmp SCSI cmd class & Branch EQ */
11521da177e4SLinus Torvalds 
11531da177e4SLinus Torvalds       #define  CBN_OP   (BITW(14)+BITW(13))  /* Cmp SCSI cmd class & Branch NOT EQ */
11541da177e4SLinus Torvalds 
11551da177e4SLinus Torvalds       #define  CPE_OP   (BITW(14)+BITW(11))  /* Cmp SCSI phs & Branch EQ */
11561da177e4SLinus Torvalds 
11571da177e4SLinus Torvalds       #define  CPN_OP   (BITW(14)+BITW(12))  /* Cmp SCSI phs & Branch NOT EQ */
11581da177e4SLinus Torvalds 
11591da177e4SLinus Torvalds 
11601da177e4SLinus Torvalds       #define  ADATA_OUT   0x00
11611da177e4SLinus Torvalds       #define  ADATA_IN    BITW(8)
11621da177e4SLinus Torvalds       #define  ACOMMAND    BITW(10)
11631da177e4SLinus Torvalds       #define  ASTATUS     (BITW(10)+BITW(8))
11641da177e4SLinus Torvalds       #define  AMSG_OUT    (BITW(10)+BITW(9))
11651da177e4SLinus Torvalds       #define  AMSG_IN     (BITW(10)+BITW(9)+BITW(8))
11661da177e4SLinus Torvalds       #define  AILLEGAL    (BITW(9)+BITW(8))
11671da177e4SLinus Torvalds 
11681da177e4SLinus Torvalds 
11691da177e4SLinus Torvalds       #define  BRH_OP   BITW(13)   /* Branch */
11701da177e4SLinus Torvalds 
11711da177e4SLinus Torvalds 
11721da177e4SLinus Torvalds       #define  ALWAYS   0x00
11731da177e4SLinus Torvalds       #define  EQUAL    BITW(8)
11741da177e4SLinus Torvalds       #define  NOT_EQ   BITW(9)
11751da177e4SLinus Torvalds 
11761da177e4SLinus Torvalds       #define  TCB_OP   (BITW(13)+BITW(11))    /* Test condition & branch */
11771da177e4SLinus Torvalds 
11781da177e4SLinus Torvalds 
11791da177e4SLinus Torvalds       #define  ATN_SET     BITW(8)
11801da177e4SLinus Torvalds       #define  ATN_RESET   BITW(9)
11811da177e4SLinus Torvalds       #define  XFER_CNT    (BITW(9)+BITW(8))
11821da177e4SLinus Torvalds       #define  FIFO_0      BITW(10)
11831da177e4SLinus Torvalds       #define  FIFO_NOT0   (BITW(10)+BITW(8))
11841da177e4SLinus Torvalds       #define  T_USE_SYNC0 (BITW(10)+BITW(9))
11851da177e4SLinus Torvalds 
11861da177e4SLinus Torvalds 
11871da177e4SLinus Torvalds       #define  MPM_OP   BITW(15)        /* Match phase and move data */
11881da177e4SLinus Torvalds 
11891da177e4SLinus Torvalds       #define  MDR_OP   (BITW(12)+BITW(11)) /* Move data to Reg. */
11901da177e4SLinus Torvalds 
11911da177e4SLinus Torvalds       #define  MRR_OP   BITW(14)        /* Move DReg. to Reg. */
11921da177e4SLinus Torvalds 
11931da177e4SLinus Torvalds 
11941da177e4SLinus Torvalds       #define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
11951da177e4SLinus Torvalds 
11961da177e4SLinus Torvalds 
11971da177e4SLinus Torvalds       #define  D_AR0    0x00
11981da177e4SLinus Torvalds       #define  D_AR1    BIT(0)
11991da177e4SLinus Torvalds       #define  D_AR2    BIT(1)
12001da177e4SLinus Torvalds       #define  D_AR3    (BIT(1) + BIT(0))
12011da177e4SLinus Torvalds       #define  D_SDATA  BIT(2)
12021da177e4SLinus Torvalds       #define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
12031da177e4SLinus Torvalds 
12041da177e4SLinus Torvalds 
12051da177e4SLinus Torvalds       #define  ADR_OP   (BITW(13)+BITW(12)) /* Logical AND Reg. w. Data */
12061da177e4SLinus Torvalds 
12071da177e4SLinus Torvalds       #define  ADS_OP   (BITW(14)+BITW(13)+BITW(12))
12081da177e4SLinus Torvalds 
12091da177e4SLinus Torvalds       #define  ODR_OP   (BITW(13)+BITW(12)+BITW(11))
12101da177e4SLinus Torvalds 
12111da177e4SLinus Torvalds       #define  ODS_OP   (BITW(14)+BITW(13)+BITW(12)+BITW(11))
12121da177e4SLinus Torvalds 
12131da177e4SLinus Torvalds       #define  STR_OP   (BITW(15)+BITW(14)) /* Store to A_Reg. */
12141da177e4SLinus Torvalds 
12151da177e4SLinus Torvalds       #define  AINT_ENA1   0x00
12161da177e4SLinus Torvalds       #define  AINT_STAT1  BITW(8)
12171da177e4SLinus Torvalds       #define  ASCSI_SIG   BITW(9)
12181da177e4SLinus Torvalds       #define  ASCSI_CNTL  (BITW(9)+BITW(8))
12191da177e4SLinus Torvalds       #define  APORT_CNTL  BITW(10)
12201da177e4SLinus Torvalds       #define  ARST_CNTL   (BITW(10)+BITW(8))
12211da177e4SLinus Torvalds       #define  AXFERCNT0   (BITW(10)+BITW(9))
12221da177e4SLinus Torvalds       #define  AXFERCNT1   (BITW(10)+BITW(9)+BITW(8))
12231da177e4SLinus Torvalds       #define  AXFERCNT2   BITW(11)
12241da177e4SLinus Torvalds       #define  AFIFO_DATA  (BITW(11)+BITW(8))
12251da177e4SLinus Torvalds       #define  ASCSISELID  (BITW(11)+BITW(9))
12261da177e4SLinus Torvalds       #define  ASCSISYNC0  (BITW(11)+BITW(9)+BITW(8))
12271da177e4SLinus Torvalds 
12281da177e4SLinus Torvalds 
12291da177e4SLinus Torvalds       #define  RAT_OP      (BITW(14)+BITW(13)+BITW(11))
12301da177e4SLinus Torvalds 
12311da177e4SLinus Torvalds       #define  SSI_OP      (BITW(15)+BITW(11))
12321da177e4SLinus Torvalds 
12331da177e4SLinus Torvalds 
12341da177e4SLinus Torvalds       #define  SSI_ITAR_DISC	(ITAR_DISC >> 8)
12351da177e4SLinus Torvalds       #define  SSI_IDO_STRT	(IDO_STRT >> 8)
12361da177e4SLinus Torvalds       #define  SSI_IDI_STRT	(IDO_STRT >> 8)
12371da177e4SLinus Torvalds 
12381da177e4SLinus Torvalds       #define  SSI_ICMD_COMP	(ICMD_COMP >> 8)
12391da177e4SLinus Torvalds       #define  SSI_ITICKLE	(ITICKLE >> 8)
12401da177e4SLinus Torvalds 
12411da177e4SLinus Torvalds       #define  SSI_IUNKWN	(IUNKWN >> 8)
12421da177e4SLinus Torvalds       #define  SSI_INO_CC	(IUNKWN >> 8)
12431da177e4SLinus Torvalds       #define  SSI_IRFAIL	(IUNKWN >> 8)
12441da177e4SLinus Torvalds 
12451da177e4SLinus Torvalds 
12461da177e4SLinus Torvalds       #define  NP    0x10     /*Next Phase */
12471da177e4SLinus Torvalds       #define  NTCMD 0x02     /*Non- Tagged Command start */
12481da177e4SLinus Torvalds       #define  CMDPZ 0x04     /*Command phase */
12491da177e4SLinus Torvalds       #define  DINT  0x12     /*Data Out/In interrupt */
12501da177e4SLinus Torvalds       #define  DI    0x13     /*Data Out */
12511da177e4SLinus Torvalds       #define  MI    0x14     /*Message In */
12521da177e4SLinus Torvalds       #define  DC    0x19     /*Disconnect Message */
12531da177e4SLinus Torvalds       #define  ST    0x1D     /*Status Phase */
12541da177e4SLinus Torvalds       #define  UNKNWN 0x24    /*Unknown bus action */
12551da177e4SLinus Torvalds       #define  CC    0x25     /*Command Completion failure */
12561da177e4SLinus Torvalds       #define  TICK  0x26     /*New target reselected us. */
12571da177e4SLinus Torvalds       #define  RFAIL 0x27     /*Reselection failed */
12581da177e4SLinus Torvalds       #define  SELCHK 0x28     /*Select & Check SCSI ID latch reg */
12591da177e4SLinus Torvalds 
12601da177e4SLinus Torvalds 
12611da177e4SLinus Torvalds       #define  ID_MSG_STRT    hp_aramBase + 0x00
12621da177e4SLinus Torvalds       #define  NON_TAG_ID_MSG hp_aramBase + 0x06
12631da177e4SLinus Torvalds       #define  CMD_STRT       hp_aramBase + 0x08
12641da177e4SLinus Torvalds       #define  SYNC_MSGS      hp_aramBase + 0x08
12651da177e4SLinus Torvalds 
12661da177e4SLinus Torvalds 
12671da177e4SLinus Torvalds 
12681da177e4SLinus Torvalds 
12691da177e4SLinus Torvalds 
12701da177e4SLinus Torvalds       #define  TAG_STRT          0x00
12711da177e4SLinus Torvalds       #define  SELECTION_START   0x00
12721da177e4SLinus Torvalds       #define  DISCONNECT_START  0x10/2
12731da177e4SLinus Torvalds       #define  END_DATA_START    0x14/2
12741da177e4SLinus Torvalds       #define  NONTAG_STRT       0x02/2
12751da177e4SLinus Torvalds       #define  CMD_ONLY_STRT     CMDPZ/2
12761da177e4SLinus Torvalds       #define  TICKLE_STRT     TICK/2
12771da177e4SLinus Torvalds       #define  SELCHK_STRT     SELCHK/2
12781da177e4SLinus Torvalds 
12791da177e4SLinus Torvalds 
12801da177e4SLinus Torvalds 
12811da177e4SLinus Torvalds 
12821da177e4SLinus Torvalds #define mEEPROM_CLK_DELAY(port) (RD_HARPOON(port+hp_intstat_1))
12831da177e4SLinus Torvalds 
12841da177e4SLinus Torvalds #define mWAIT_10MS(port) (RD_HARPOON(port+hp_intstat_1))
12851da177e4SLinus Torvalds 
12861da177e4SLinus Torvalds 
12871da177e4SLinus Torvalds #define CLR_XFER_CNT(port) (WR_HARPOON(port+hp_xfercnt_0, 0x00))
12881da177e4SLinus Torvalds 
12891da177e4SLinus Torvalds #define SET_XFER_CNT(port, data) (WR_HARP32(port,hp_xfercnt_0,data))
12901da177e4SLinus Torvalds 
12911da177e4SLinus Torvalds #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
12921da177e4SLinus Torvalds /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
12931da177e4SLinus Torvalds                                  xfercnt <<= 16,\
12941da177e4SLinus Torvalds                                  xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
12951da177e4SLinus Torvalds  */
12961da177e4SLinus Torvalds #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
12971da177e4SLinus Torvalds          addr >>= 16,\
12981da177e4SLinus Torvalds          WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
12991da177e4SLinus Torvalds          WR_HARP32(port,hp_xfercnt_0,count),\
13001da177e4SLinus Torvalds          WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
13011da177e4SLinus Torvalds          count >>= 16,\
13021da177e4SLinus Torvalds          WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
13051da177e4SLinus Torvalds                           WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
13061da177e4SLinus Torvalds 
13071da177e4SLinus Torvalds 
13081da177e4SLinus Torvalds #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
13091da177e4SLinus Torvalds                           WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
13101da177e4SLinus Torvalds 
13111da177e4SLinus Torvalds #define ACCEPT_STAT(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
13121da177e4SLinus Torvalds                           WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
13131da177e4SLinus Torvalds 
13141da177e4SLinus Torvalds #define ACCEPT_STAT_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
13151da177e4SLinus Torvalds                           WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
13161da177e4SLinus Torvalds 
13171da177e4SLinus Torvalds #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
13181da177e4SLinus Torvalds                         WR_HARPOON(port+hp_scsireset, 0x00))
13191da177e4SLinus Torvalds 
13201da177e4SLinus Torvalds #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
13211da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
13221da177e4SLinus Torvalds 
13231da177e4SLinus Torvalds #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
13241da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
13251da177e4SLinus Torvalds 
13261da177e4SLinus Torvalds #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
13271da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
13281da177e4SLinus Torvalds 
13291da177e4SLinus Torvalds #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
13301da177e4SLinus Torvalds                              (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
13311da177e4SLinus Torvalds 
13321da177e4SLinus Torvalds 
13331da177e4SLinus Torvalds 
13341da177e4SLinus Torvalds 
13351da177e4SLinus Torvalds void  scsiStartAuto(ULONG port);
1336*47b5d69cSJames Bottomley  static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
1337*47b5d69cSJames Bottomley  static void  FPT_ssel(ULONG port, UCHAR p_card);
1338*47b5d69cSJames Bottomley  static void  FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
1339*47b5d69cSJames Bottomley  static void  FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
1340*47b5d69cSJames Bottomley  static void  FPT_stsyncn(ULONG port, UCHAR p_card);
1341*47b5d69cSJames Bottomley  static void  FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
1342*47b5d69cSJames Bottomley  static void  FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
1343*47b5d69cSJames Bottomley  			 PSCCBMgr_tar_info currTar_Info);
1344*47b5d69cSJames Bottomley  static void  FPT_sresb(ULONG port, UCHAR p_card);
1345*47b5d69cSJames Bottomley  static void  FPT_sxfrp(ULONG p_port, UCHAR p_card);
1346*47b5d69cSJames Bottomley  static void  FPT_schkdd(ULONG port, UCHAR p_card);
1347*47b5d69cSJames Bottomley  static UCHAR FPT_RdStack(ULONG port, UCHAR index);
1348*47b5d69cSJames Bottomley  static void  FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
1349*47b5d69cSJames Bottomley  static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
13501da177e4SLinus Torvalds 
1351*47b5d69cSJames Bottomley  static void FPT_SendMsg(ULONG port, UCHAR message);
1352*47b5d69cSJames Bottomley  static void  FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1353*47b5d69cSJames Bottomley  				    UCHAR error_code);
13541da177e4SLinus Torvalds 
1355*47b5d69cSJames Bottomley  static void  FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1356*47b5d69cSJames Bottomley  static void  FPT_RNVRamData(PNVRamInfo pNvRamInfo);
13571da177e4SLinus Torvalds 
1358*47b5d69cSJames Bottomley  static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1359*47b5d69cSJames Bottomley  static void  FPT_stwidn(ULONG port, UCHAR p_card);
1360*47b5d69cSJames Bottomley  static void  FPT_siwidr(ULONG port, UCHAR width);
13611da177e4SLinus Torvalds 
13621da177e4SLinus Torvalds 
1363*47b5d69cSJames Bottomley  static void  FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1364*47b5d69cSJames Bottomley  static void  FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1365*47b5d69cSJames Bottomley  static void  FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1366*47b5d69cSJames Bottomley  				  UCHAR p_card);
1367*47b5d69cSJames Bottomley  static void  FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1368*47b5d69cSJames Bottomley  static void  FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1369*47b5d69cSJames Bottomley  static void  FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1370*47b5d69cSJames Bottomley  static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1371*47b5d69cSJames Bottomley  static void  FPT_utilUpdateResidual(PSCCB p_SCCB);
1372*47b5d69cSJames Bottomley  static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1373*47b5d69cSJames Bottomley  static UCHAR  FPT_CalcLrc(UCHAR buffer[]);
13741da177e4SLinus Torvalds 
13751da177e4SLinus Torvalds 
1376*47b5d69cSJames Bottomley  static void  FPT_Wait1Second(ULONG p_port);
1377*47b5d69cSJames Bottomley  static void  FPT_Wait(ULONG p_port, UCHAR p_delay);
1378*47b5d69cSJames Bottomley  static void  FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1379*47b5d69cSJames Bottomley  static void  FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1380*47b5d69cSJames Bottomley  static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1381*47b5d69cSJames Bottomley  static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1382*47b5d69cSJames Bottomley  static void  FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
13831da177e4SLinus Torvalds 
13841da177e4SLinus Torvalds 
13851da177e4SLinus Torvalds 
1386*47b5d69cSJames Bottomley  static void  FPT_phaseDataOut(ULONG port, UCHAR p_card);
1387*47b5d69cSJames Bottomley  static void  FPT_phaseDataIn(ULONG port, UCHAR p_card);
1388*47b5d69cSJames Bottomley  static void  FPT_phaseCommand(ULONG port, UCHAR p_card);
1389*47b5d69cSJames Bottomley  static void  FPT_phaseStatus(ULONG port, UCHAR p_card);
1390*47b5d69cSJames Bottomley  static void  FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1391*47b5d69cSJames Bottomley  static void  FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1392*47b5d69cSJames Bottomley  static void  FPT_phaseIllegal(ULONG port, UCHAR p_card);
13931da177e4SLinus Torvalds 
1394*47b5d69cSJames Bottomley  static void  FPT_phaseDecode(ULONG port, UCHAR p_card);
1395*47b5d69cSJames Bottomley  static void  FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1396*47b5d69cSJames Bottomley  static void  FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
13971da177e4SLinus Torvalds 
13981da177e4SLinus Torvalds 
13991da177e4SLinus Torvalds 
14001da177e4SLinus Torvalds 
1401*47b5d69cSJames Bottomley  static void  FPT_XbowInit(ULONG port, UCHAR scamFlg);
1402*47b5d69cSJames Bottomley  static void  FPT_BusMasterInit(ULONG p_port);
1403*47b5d69cSJames Bottomley  static void  FPT_DiagEEPROM(ULONG p_port);
14041da177e4SLinus Torvalds 
14051da177e4SLinus Torvalds 
14061da177e4SLinus Torvalds 
14071da177e4SLinus Torvalds 
14081da177e4SLinus Torvalds void  busMstrAbort(ULONG port);
1409*47b5d69cSJames Bottomley  static void  FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1410*47b5d69cSJames Bottomley  static void  FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1411*47b5d69cSJames Bottomley  static void  FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1412*47b5d69cSJames Bottomley  static void  FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1413*47b5d69cSJames Bottomley  static void  FPT_hostDataXferRestart(PSCCB currSCCB);
14141da177e4SLinus Torvalds 
14151da177e4SLinus Torvalds 
1416*47b5d69cSJames Bottomley  static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1417*47b5d69cSJames Bottomley  				 PSCCBcard pCurrCard, USHORT p_int);
14181da177e4SLinus Torvalds 
1419*47b5d69cSJames Bottomley  static void  FPT_SccbMgrTableInitAll(void);
1420*47b5d69cSJames Bottomley  static void  FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1421*47b5d69cSJames Bottomley  static void  FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
14221da177e4SLinus Torvalds 
14231da177e4SLinus Torvalds 
14241da177e4SLinus Torvalds 
1425*47b5d69cSJames Bottomley  static void  FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
14261da177e4SLinus Torvalds 
1427*47b5d69cSJames Bottomley  static int   FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1428*47b5d69cSJames Bottomley  static void  FPT_scbusf(ULONG p_port);
1429*47b5d69cSJames Bottomley  static void  FPT_scsel(ULONG p_port);
1430*47b5d69cSJames Bottomley  static void  FPT_scasid(UCHAR p_card, ULONG p_port);
1431*47b5d69cSJames Bottomley  static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1432*47b5d69cSJames Bottomley  static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1433*47b5d69cSJames Bottomley  static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1434*47b5d69cSJames Bottomley  static void  FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1435*47b5d69cSJames Bottomley  static void  FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1436*47b5d69cSJames Bottomley  static UCHAR FPT_scvalq(UCHAR p_quintet);
1437*47b5d69cSJames Bottomley  static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1438*47b5d69cSJames Bottomley  static void  FPT_scwtsel(ULONG p_port);
1439*47b5d69cSJames Bottomley  static void  FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1440*47b5d69cSJames Bottomley  static void  FPT_scsavdi(UCHAR p_card, ULONG p_port);
1441*47b5d69cSJames Bottomley  static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
14421da177e4SLinus Torvalds 
14431da177e4SLinus Torvalds 
1444*47b5d69cSJames Bottomley  static void  FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1445*47b5d69cSJames Bottomley  static void  FPT_autoLoadDefaultMap(ULONG p_port);
14461da177e4SLinus Torvalds 
14471da177e4SLinus Torvalds 
14481da177e4SLinus Torvalds 
14491da177e4SLinus Torvalds void  OS_start_timer(unsigned long ioport, unsigned long timeout);
14501da177e4SLinus Torvalds void  OS_stop_timer(unsigned long ioport, unsigned long timeout);
14511da177e4SLinus Torvalds void  OS_disable_int(unsigned char intvec);
14521da177e4SLinus Torvalds void  OS_enable_int(unsigned char intvec);
14531da177e4SLinus Torvalds void  OS_delay(unsigned long count);
14541da177e4SLinus Torvalds int   OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr);
14551da177e4SLinus Torvalds 
1456*47b5d69cSJames Bottomley  static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1457*47b5d69cSJames Bottomley  static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1458*47b5d69cSJames Bottomley  static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1459*47b5d69cSJames Bottomley  static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
14601da177e4SLinus Torvalds 
14611da177e4SLinus Torvalds 
1462*47b5d69cSJames Bottomley  static UCHAR FPT_mbCards = 0;
1463*47b5d69cSJames Bottomley  static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1464*47b5d69cSJames Bottomley  				   ' ', 'B', 'T', '-', '9', '3', '0', \
1465*47b5d69cSJames Bottomley  				   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1466*47b5d69cSJames Bottomley  				   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
14671da177e4SLinus Torvalds 
1468*47b5d69cSJames Bottomley  static USHORT FPT_default_intena = 0;
14691da177e4SLinus Torvalds 
14701da177e4SLinus Torvalds 
1471*47b5d69cSJames Bottomley  static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
14721da177e4SLinus Torvalds 
14731da177e4SLinus Torvalds 
14741da177e4SLinus Torvalds /*---------------------------------------------------------------------
14751da177e4SLinus Torvalds  *
14761da177e4SLinus Torvalds  * Function: SccbMgr_sense_adapter
14771da177e4SLinus Torvalds  *
14781da177e4SLinus Torvalds  * Description: Setup and/or Search for cards and return info to caller.
14791da177e4SLinus Torvalds  *
14801da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
14811da177e4SLinus Torvalds 
1482*47b5d69cSJames Bottomley  static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
14831da177e4SLinus Torvalds {
14841da177e4SLinus Torvalds    static UCHAR first_time = 1;
14851da177e4SLinus Torvalds 
14861da177e4SLinus Torvalds    UCHAR i,j,id,ScamFlg;
14871da177e4SLinus Torvalds    USHORT temp,temp2,temp3,temp4,temp5,temp6;
14881da177e4SLinus Torvalds    ULONG ioport;
14891da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
14901da177e4SLinus Torvalds 
14911da177e4SLinus Torvalds    ioport = pCardInfo->si_baseaddr;
14921da177e4SLinus Torvalds 
14931da177e4SLinus Torvalds 
14941da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
14951da177e4SLinus Torvalds       return((int)FAILURE);
14961da177e4SLinus Torvalds 
14971da177e4SLinus Torvalds    if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
14981da177e4SLinus Torvalds       return((int)FAILURE);
14991da177e4SLinus Torvalds 
15001da177e4SLinus Torvalds    if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
15011da177e4SLinus Torvalds       return((int)FAILURE);
15021da177e4SLinus Torvalds 
15031da177e4SLinus Torvalds    if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
15041da177e4SLinus Torvalds       return((int)FAILURE);
15051da177e4SLinus Torvalds 
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
15081da177e4SLinus Torvalds 
15091da177e4SLinus Torvalds /* For new Harpoon then check for sub_device ID LSB
15101da177e4SLinus Torvalds    the bits(0-3) must be all ZERO for compatible with
15111da177e4SLinus Torvalds    current version of SCCBMgr, else skip this Harpoon
15121da177e4SLinus Torvalds 	device. */
15131da177e4SLinus Torvalds 
15141da177e4SLinus Torvalds 	   if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
15151da177e4SLinus Torvalds 	      return((int)FAILURE);
15161da177e4SLinus Torvalds 	}
15171da177e4SLinus Torvalds 
15181da177e4SLinus Torvalds    if (first_time)
15191da177e4SLinus Torvalds       {
1520*47b5d69cSJames Bottomley        FPT_SccbMgrTableInitAll();
15211da177e4SLinus Torvalds       first_time = 0;
1522*47b5d69cSJames Bottomley  		FPT_mbCards = 0;
15231da177e4SLinus Torvalds       }
15241da177e4SLinus Torvalds 
1525*47b5d69cSJames Bottomley  	if(FPT_RdStack(ioport, 0) != 0x00) {
1526*47b5d69cSJames Bottomley  		if(FPT_ChkIfChipInitialized(ioport) == 0)
15271da177e4SLinus Torvalds 		{
15281da177e4SLinus Torvalds 			pCurrNvRam = NULL;
15291da177e4SLinus Torvalds 		   WR_HARPOON(ioport+hp_semaphore, 0x00);
1530*47b5d69cSJames Bottomley  			FPT_XbowInit(ioport, 0);             /*Must Init the SCSI before attempting */
1531*47b5d69cSJames Bottomley  			FPT_DiagEEPROM(ioport);
15321da177e4SLinus Torvalds 		}
15331da177e4SLinus Torvalds 		else
15341da177e4SLinus Torvalds 		{
1535*47b5d69cSJames Bottomley  			if(FPT_mbCards < MAX_MB_CARDS) {
1536*47b5d69cSJames Bottomley  				pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1537*47b5d69cSJames Bottomley  				FPT_mbCards++;
15381da177e4SLinus Torvalds 				pCurrNvRam->niBaseAddr = ioport;
1539*47b5d69cSJames Bottomley  				FPT_RNVRamData(pCurrNvRam);
15401da177e4SLinus Torvalds 			}else
15411da177e4SLinus Torvalds 				return((int) FAILURE);
15421da177e4SLinus Torvalds 		}
15431da177e4SLinus Torvalds 	}else
15441da177e4SLinus Torvalds 		pCurrNvRam = NULL;
15451da177e4SLinus Torvalds 
15461da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
15471da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
15481da177e4SLinus Torvalds 
15491da177e4SLinus Torvalds 	if(pCurrNvRam)
15501da177e4SLinus Torvalds 		pCardInfo->si_id = pCurrNvRam->niAdapId;
15511da177e4SLinus Torvalds 	else
1552*47b5d69cSJames Bottomley  	   pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
15531da177e4SLinus Torvalds    	   (UCHAR)0x0FF);
15541da177e4SLinus Torvalds 
15551da177e4SLinus Torvalds    pCardInfo->si_lun = 0x00;
15561da177e4SLinus Torvalds    pCardInfo->si_fw_revision = ORION_FW_REV;
15571da177e4SLinus Torvalds    temp2 = 0x0000;
15581da177e4SLinus Torvalds    temp3 = 0x0000;
15591da177e4SLinus Torvalds    temp4 = 0x0000;
15601da177e4SLinus Torvalds    temp5 = 0x0000;
15611da177e4SLinus Torvalds    temp6 = 0x0000;
15621da177e4SLinus Torvalds 
15631da177e4SLinus Torvalds    for (id = 0; id < (16/2); id++) {
15641da177e4SLinus Torvalds 
15651da177e4SLinus Torvalds 		if(pCurrNvRam){
15661da177e4SLinus Torvalds 			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
15671da177e4SLinus Torvalds 			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
15681da177e4SLinus Torvalds 					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
15691da177e4SLinus Torvalds 		}else
1570*47b5d69cSJames Bottomley  	      temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
15711da177e4SLinus Torvalds 
15721da177e4SLinus Torvalds       for (i = 0; i < 2; temp >>=8,i++) {
15731da177e4SLinus Torvalds 
15741da177e4SLinus Torvalds          temp2 >>= 1;
15751da177e4SLinus Torvalds          temp3 >>= 1;
15761da177e4SLinus Torvalds          temp4 >>= 1;
15771da177e4SLinus Torvalds          temp5 >>= 1;
15781da177e4SLinus Torvalds          temp6 >>= 1;
15791da177e4SLinus Torvalds 	 switch (temp & 0x3)
15801da177e4SLinus Torvalds 	   {
15811da177e4SLinus Torvalds 	   case AUTO_RATE_20:	/* Synchronous, 20 mega-transfers/second */
15821da177e4SLinus Torvalds 	     temp6 |= 0x8000;	/* Fall through */
15831da177e4SLinus Torvalds 	   case AUTO_RATE_10:	/* Synchronous, 10 mega-transfers/second */
15841da177e4SLinus Torvalds 	     temp5 |= 0x8000;	/* Fall through */
15851da177e4SLinus Torvalds 	   case AUTO_RATE_05:	/* Synchronous, 5 mega-transfers/second */
15861da177e4SLinus Torvalds 	     temp2 |= 0x8000;	/* Fall through */
15871da177e4SLinus Torvalds 	   case AUTO_RATE_00:	/* Asynchronous */
15881da177e4SLinus Torvalds 	     break;
15891da177e4SLinus Torvalds 	   }
15901da177e4SLinus Torvalds 
15911da177e4SLinus Torvalds          if (temp & DISC_ENABLE_BIT)
15921da177e4SLinus Torvalds 	   temp3 |= 0x8000;
15931da177e4SLinus Torvalds 
15941da177e4SLinus Torvalds          if (temp & WIDE_NEGO_BIT)
15951da177e4SLinus Torvalds 	   temp4 |= 0x8000;
15961da177e4SLinus Torvalds 
15971da177e4SLinus Torvalds          }
15981da177e4SLinus Torvalds       }
15991da177e4SLinus Torvalds 
16001da177e4SLinus Torvalds    pCardInfo->si_per_targ_init_sync = temp2;
16011da177e4SLinus Torvalds    pCardInfo->si_per_targ_no_disc = temp3;
16021da177e4SLinus Torvalds    pCardInfo->si_per_targ_wide_nego = temp4;
16031da177e4SLinus Torvalds    pCardInfo->si_per_targ_fast_nego = temp5;
16041da177e4SLinus Torvalds    pCardInfo->si_per_targ_ultra_nego = temp6;
16051da177e4SLinus Torvalds 
16061da177e4SLinus Torvalds 	if(pCurrNvRam)
16071da177e4SLinus Torvalds 		i = pCurrNvRam->niSysConf;
16081da177e4SLinus Torvalds 	else
1609*47b5d69cSJames Bottomley  	   i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
16101da177e4SLinus Torvalds 
16111da177e4SLinus Torvalds 	if(pCurrNvRam)
16121da177e4SLinus Torvalds 		ScamFlg = pCurrNvRam->niScamConf;
16131da177e4SLinus Torvalds 	else
1614*47b5d69cSJames Bottomley  	   ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
16151da177e4SLinus Torvalds 
16161da177e4SLinus Torvalds    pCardInfo->si_flags = 0x0000;
16171da177e4SLinus Torvalds 
16181da177e4SLinus Torvalds    if (i & 0x01)
16191da177e4SLinus Torvalds       pCardInfo->si_flags |= SCSI_PARITY_ENA;
16201da177e4SLinus Torvalds 
16211da177e4SLinus Torvalds    if (!(i & 0x02))
16221da177e4SLinus Torvalds       pCardInfo->si_flags |= SOFT_RESET;
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds    if (i & 0x10)
16251da177e4SLinus Torvalds       pCardInfo->si_flags |= EXTENDED_TRANSLATION;
16261da177e4SLinus Torvalds 
16271da177e4SLinus Torvalds    if (ScamFlg & SCAM_ENABLED)
16281da177e4SLinus Torvalds      pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
16291da177e4SLinus Torvalds 
16301da177e4SLinus Torvalds    if (ScamFlg & SCAM_LEVEL2)
16311da177e4SLinus Torvalds      pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
16321da177e4SLinus Torvalds 
16331da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
16341da177e4SLinus Torvalds    if (i & 0x04) {
16351da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_L;
16361da177e4SLinus Torvalds       }
16371da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_bm_ctrl, j );
16381da177e4SLinus Torvalds 
16391da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
16401da177e4SLinus Torvalds    if (i & 0x08) {
16411da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_H;
16421da177e4SLinus Torvalds       }
16431da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_ee_ctrl, j );
16441da177e4SLinus Torvalds 
16451da177e4SLinus Torvalds    if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
16461da177e4SLinus Torvalds 
16471da177e4SLinus Torvalds       pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
16481da177e4SLinus Torvalds 
16491da177e4SLinus Torvalds    pCardInfo->si_card_family = HARPOON_FAMILY;
16501da177e4SLinus Torvalds    pCardInfo->si_bustype = BUSTYPE_PCI;
16511da177e4SLinus Torvalds 
16521da177e4SLinus Torvalds 	if(pCurrNvRam){
16531da177e4SLinus Torvalds    	pCardInfo->si_card_model[0] = '9';
16541da177e4SLinus Torvalds 		switch(pCurrNvRam->niModel & 0x0f){
16551da177e4SLinus Torvalds 			case MODEL_LT:
16561da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '3';
16571da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '0';
16581da177e4SLinus Torvalds 				break;
16591da177e4SLinus Torvalds 			case MODEL_LW:
16601da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '5';
16611da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '0';
16621da177e4SLinus Torvalds 				break;
16631da177e4SLinus Torvalds 			case MODEL_DL:
16641da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '3';
16651da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '2';
16661da177e4SLinus Torvalds 				break;
16671da177e4SLinus Torvalds 			case MODEL_DW:
16681da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[1] = '5';
16691da177e4SLinus Torvalds 		   	pCardInfo->si_card_model[2] = '2';
16701da177e4SLinus Torvalds 				break;
16711da177e4SLinus Torvalds 		}
16721da177e4SLinus Torvalds 	}else{
1673*47b5d69cSJames Bottomley  	   temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
16741da177e4SLinus Torvalds    	pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
1675*47b5d69cSJames Bottomley  	   temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
16761da177e4SLinus Torvalds 
16771da177e4SLinus Torvalds    	pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
16781da177e4SLinus Torvalds 	   pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
16791da177e4SLinus Torvalds 	}
16801da177e4SLinus Torvalds 
16811da177e4SLinus Torvalds    if (pCardInfo->si_card_model[1] == '3')
16821da177e4SLinus Torvalds      {
16831da177e4SLinus Torvalds        if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
16841da177e4SLinus Torvalds 	 pCardInfo->si_flags |= LOW_BYTE_TERM;
16851da177e4SLinus Torvalds      }
16861da177e4SLinus Torvalds    else if (pCardInfo->si_card_model[2] == '0')
16871da177e4SLinus Torvalds      {
16881da177e4SLinus Torvalds        temp = RD_HARPOON(ioport+hp_xfer_pad);
16891da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
16901da177e4SLinus Torvalds        if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
16911da177e4SLinus Torvalds 	 pCardInfo->si_flags |= LOW_BYTE_TERM;
16921da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
16931da177e4SLinus Torvalds        if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
16941da177e4SLinus Torvalds 	 pCardInfo->si_flags |= HIGH_BYTE_TERM;
16951da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, temp);
16961da177e4SLinus Torvalds      }
16971da177e4SLinus Torvalds    else
16981da177e4SLinus Torvalds      {
16991da177e4SLinus Torvalds        temp = RD_HARPOON(ioport+hp_ee_ctrl);
17001da177e4SLinus Torvalds        temp2 = RD_HARPOON(ioport+hp_xfer_pad);
17011da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
17021da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
17031da177e4SLinus Torvalds        temp3 = 0;
17041da177e4SLinus Torvalds        for (i = 0; i < 8; i++)
17051da177e4SLinus Torvalds 	 {
17061da177e4SLinus Torvalds 	   temp3 <<= 1;
17071da177e4SLinus Torvalds 	   if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
17081da177e4SLinus Torvalds 	     temp3 |= 1;
17091da177e4SLinus Torvalds 	   WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
17101da177e4SLinus Torvalds 	   WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
17111da177e4SLinus Torvalds 	 }
17121da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_ee_ctrl, temp);
17131da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_xfer_pad, temp2);
17141da177e4SLinus Torvalds        if (!(temp3 & BIT(7)))
17151da177e4SLinus Torvalds 	 pCardInfo->si_flags |= LOW_BYTE_TERM;
17161da177e4SLinus Torvalds        if (!(temp3 & BIT(6)))
17171da177e4SLinus Torvalds 	 pCardInfo->si_flags |= HIGH_BYTE_TERM;
17181da177e4SLinus Torvalds      }
17191da177e4SLinus Torvalds 
17201da177e4SLinus Torvalds 
17211da177e4SLinus Torvalds    ARAM_ACCESS(ioport);
17221da177e4SLinus Torvalds 
17231da177e4SLinus Torvalds    for ( i = 0; i < 4; i++ ) {
17241da177e4SLinus Torvalds 
17251da177e4SLinus Torvalds       pCardInfo->si_XlatInfo[i] =
17261da177e4SLinus Torvalds          RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
17271da177e4SLinus Torvalds       }
17281da177e4SLinus Torvalds 
17291da177e4SLinus Torvalds 	/* return with -1 if no sort, else return with
17301da177e4SLinus Torvalds 	   logical card number sorted by BIOS (zero-based) */
17311da177e4SLinus Torvalds 
17321da177e4SLinus Torvalds 	pCardInfo->si_relative_cardnum =
17331da177e4SLinus Torvalds 	(UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
17341da177e4SLinus Torvalds 
17351da177e4SLinus Torvalds    SGRAM_ACCESS(ioport);
17361da177e4SLinus Torvalds 
1737*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1738*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1739*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1740*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1741*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1742*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1743*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1744*47b5d69cSJames Bottomley     FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
17451da177e4SLinus Torvalds 
17461da177e4SLinus Torvalds    pCardInfo->si_present = 0x01;
17471da177e4SLinus Torvalds 
17481da177e4SLinus Torvalds    return(0);
17491da177e4SLinus Torvalds }
17501da177e4SLinus Torvalds 
17511da177e4SLinus Torvalds 
17521da177e4SLinus Torvalds /*---------------------------------------------------------------------
17531da177e4SLinus Torvalds  *
17541da177e4SLinus Torvalds  * Function: SccbMgr_config_adapter
17551da177e4SLinus Torvalds  *
17561da177e4SLinus Torvalds  * Description: Setup adapter for normal operation (hard reset).
17571da177e4SLinus Torvalds  *
17581da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
17591da177e4SLinus Torvalds 
1760*47b5d69cSJames Bottomley  static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
17611da177e4SLinus Torvalds {
17621da177e4SLinus Torvalds    PSCCBcard CurrCard = NULL;
17631da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
17641da177e4SLinus Torvalds    UCHAR i,j,thisCard, ScamFlg;
17651da177e4SLinus Torvalds    USHORT temp,sync_bit_map,id;
17661da177e4SLinus Torvalds    ULONG ioport;
17671da177e4SLinus Torvalds 
17681da177e4SLinus Torvalds    ioport = pCardInfo->si_baseaddr;
17691da177e4SLinus Torvalds 
17701da177e4SLinus Torvalds    for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
17711da177e4SLinus Torvalds 
17721da177e4SLinus Torvalds       if (thisCard == MAX_CARDS) {
17731da177e4SLinus Torvalds 
17741da177e4SLinus Torvalds 	 return(FAILURE);
17751da177e4SLinus Torvalds          }
17761da177e4SLinus Torvalds 
1777*47b5d69cSJames Bottomley        if (FPT_BL_Card[thisCard].ioPort == ioport) {
17781da177e4SLinus Torvalds 
1779*47b5d69cSJames Bottomley           CurrCard = &FPT_BL_Card[thisCard];
1780*47b5d69cSJames Bottomley           FPT_SccbMgrTableInitCard(CurrCard,thisCard);
17811da177e4SLinus Torvalds          break;
17821da177e4SLinus Torvalds          }
17831da177e4SLinus Torvalds 
1784*47b5d69cSJames Bottomley        else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
17851da177e4SLinus Torvalds 
1786*47b5d69cSJames Bottomley           FPT_BL_Card[thisCard].ioPort = ioport;
1787*47b5d69cSJames Bottomley           CurrCard = &FPT_BL_Card[thisCard];
17881da177e4SLinus Torvalds 
1789*47b5d69cSJames Bottomley  			if(FPT_mbCards)
1790*47b5d69cSJames Bottomley  				for(i = 0; i < FPT_mbCards; i++){
1791*47b5d69cSJames Bottomley  					if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1792*47b5d69cSJames Bottomley  						CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
17931da177e4SLinus Torvalds 				}
1794*47b5d69cSJames Bottomley           FPT_SccbMgrTableInitCard(CurrCard,thisCard);
17951da177e4SLinus Torvalds          CurrCard->cardIndex = thisCard;
17961da177e4SLinus Torvalds          CurrCard->cardInfo = pCardInfo;
17971da177e4SLinus Torvalds 
17981da177e4SLinus Torvalds 	 break;
17991da177e4SLinus Torvalds          }
18001da177e4SLinus Torvalds       }
18011da177e4SLinus Torvalds 
18021da177e4SLinus Torvalds 	pCurrNvRam = CurrCard->pNvRamInfo;
18031da177e4SLinus Torvalds 
18041da177e4SLinus Torvalds 	if(pCurrNvRam){
18051da177e4SLinus Torvalds 		ScamFlg = pCurrNvRam->niScamConf;
18061da177e4SLinus Torvalds 	}
18071da177e4SLinus Torvalds 	else{
1808*47b5d69cSJames Bottomley  	   ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
18091da177e4SLinus Torvalds 	}
18101da177e4SLinus Torvalds 
18111da177e4SLinus Torvalds 
1812*47b5d69cSJames Bottomley     FPT_BusMasterInit(ioport);
1813*47b5d69cSJames Bottomley     FPT_XbowInit(ioport, ScamFlg);
18141da177e4SLinus Torvalds 
1815*47b5d69cSJames Bottomley     FPT_autoLoadDefaultMap(ioport);
18161da177e4SLinus Torvalds 
18171da177e4SLinus Torvalds 
18181da177e4SLinus Torvalds    for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
18191da177e4SLinus Torvalds 
18201da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_selfid_0, id);
18211da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_selfid_1, 0x00);
18221da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
18231da177e4SLinus Torvalds    CurrCard->ourId = pCardInfo->si_id;
18241da177e4SLinus Torvalds 
18251da177e4SLinus Torvalds    i = (UCHAR) pCardInfo->si_flags;
18261da177e4SLinus Torvalds    if (i & SCSI_PARITY_ENA)
18271da177e4SLinus Torvalds        WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
18281da177e4SLinus Torvalds 
18291da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
18301da177e4SLinus Torvalds    if (i & LOW_BYTE_TERM)
18311da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_L;
18321da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_bm_ctrl, j);
18331da177e4SLinus Torvalds 
18341da177e4SLinus Torvalds    j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
18351da177e4SLinus Torvalds    if (i & HIGH_BYTE_TERM)
18361da177e4SLinus Torvalds       j |= SCSI_TERM_ENA_H;
18371da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_ee_ctrl, j );
18381da177e4SLinus Torvalds 
18391da177e4SLinus Torvalds 
18401da177e4SLinus Torvalds    if (!(pCardInfo->si_flags & SOFT_RESET)) {
18411da177e4SLinus Torvalds 
1842*47b5d69cSJames Bottomley        FPT_sresb(ioport,thisCard);
18431da177e4SLinus Torvalds 
1844*47b5d69cSJames Bottomley           FPT_scini(thisCard, pCardInfo->si_id, 0);
18451da177e4SLinus Torvalds       }
18461da177e4SLinus Torvalds 
18471da177e4SLinus Torvalds 
18481da177e4SLinus Torvalds 
18491da177e4SLinus Torvalds    if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
18501da177e4SLinus Torvalds       CurrCard->globalFlags |= F_NO_FILTER;
18511da177e4SLinus Torvalds 
18521da177e4SLinus Torvalds 	if(pCurrNvRam){
18531da177e4SLinus Torvalds 		if(pCurrNvRam->niSysConf & 0x10)
18541da177e4SLinus Torvalds 			CurrCard->globalFlags |= F_GREEN_PC;
18551da177e4SLinus Torvalds 	}
18561da177e4SLinus Torvalds 	else{
1857*47b5d69cSJames Bottomley  	   if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
18581da177e4SLinus Torvalds    	   CurrCard->globalFlags |= F_GREEN_PC;
18591da177e4SLinus Torvalds 	}
18601da177e4SLinus Torvalds 
18611da177e4SLinus Torvalds 	/* Set global flag to indicate Re-Negotiation to be done on all
18621da177e4SLinus Torvalds 		ckeck condition */
18631da177e4SLinus Torvalds 	if(pCurrNvRam){
18641da177e4SLinus Torvalds 		if(pCurrNvRam->niScsiConf & 0x04)
18651da177e4SLinus Torvalds 			CurrCard->globalFlags |= F_DO_RENEGO;
18661da177e4SLinus Torvalds 	}
18671da177e4SLinus Torvalds 	else{
1868*47b5d69cSJames Bottomley  	   if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
18691da177e4SLinus Torvalds    	   CurrCard->globalFlags |= F_DO_RENEGO;
18701da177e4SLinus Torvalds 	}
18711da177e4SLinus Torvalds 
18721da177e4SLinus Torvalds 	if(pCurrNvRam){
18731da177e4SLinus Torvalds 		if(pCurrNvRam->niScsiConf & 0x08)
18741da177e4SLinus Torvalds 			CurrCard->globalFlags |= F_CONLUN_IO;
18751da177e4SLinus Torvalds 	}
18761da177e4SLinus Torvalds 	else{
1877*47b5d69cSJames Bottomley  	   if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
18781da177e4SLinus Torvalds    	   CurrCard->globalFlags |= F_CONLUN_IO;
18791da177e4SLinus Torvalds 	}
18801da177e4SLinus Torvalds 
18811da177e4SLinus Torvalds 
18821da177e4SLinus Torvalds    temp = pCardInfo->si_per_targ_no_disc;
18831da177e4SLinus Torvalds 
18841da177e4SLinus Torvalds    for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
18851da177e4SLinus Torvalds 
18861da177e4SLinus Torvalds       if (temp & id)
1887*47b5d69cSJames Bottomley  	 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
18881da177e4SLinus Torvalds       }
18891da177e4SLinus Torvalds 
18901da177e4SLinus Torvalds    sync_bit_map = 0x0001;
18911da177e4SLinus Torvalds 
18921da177e4SLinus Torvalds    for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
18931da177e4SLinus Torvalds 
18941da177e4SLinus Torvalds 		if(pCurrNvRam){
18951da177e4SLinus Torvalds 			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
18961da177e4SLinus Torvalds 			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
18971da177e4SLinus Torvalds 					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
18981da177e4SLinus Torvalds 		}else
1899*47b5d69cSJames Bottomley  	      temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
19001da177e4SLinus Torvalds 
19011da177e4SLinus Torvalds       for (i = 0; i < 2; temp >>=8,i++) {
19021da177e4SLinus Torvalds 
19031da177e4SLinus Torvalds          if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
19041da177e4SLinus Torvalds 
1905*47b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
19061da177e4SLinus Torvalds             }
19071da177e4SLinus Torvalds 
19081da177e4SLinus Torvalds          else {
1909*47b5d69cSJames Bottomley  	    FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1910*47b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
19111da177e4SLinus Torvalds                (UCHAR)(temp & ~EE_SYNC_MASK);
19121da177e4SLinus Torvalds             }
19131da177e4SLinus Torvalds 
19141da177e4SLinus Torvalds /*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
19151da177e4SLinus Torvalds             (id*2+i >= 8)){
19161da177e4SLinus Torvalds */
19171da177e4SLinus Torvalds          if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
19181da177e4SLinus Torvalds 
1919*47b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
19201da177e4SLinus Torvalds 
19211da177e4SLinus Torvalds             }
19221da177e4SLinus Torvalds 
19231da177e4SLinus Torvalds          else { /* NARROW SCSI */
1924*47b5d69cSJames Bottomley              FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
19251da177e4SLinus Torvalds             }
19261da177e4SLinus Torvalds 
19271da177e4SLinus Torvalds 
19281da177e4SLinus Torvalds 	 sync_bit_map <<= 1;
19291da177e4SLinus Torvalds 
19301da177e4SLinus Torvalds 
19311da177e4SLinus Torvalds 
19321da177e4SLinus Torvalds          }
19331da177e4SLinus Torvalds       }
19341da177e4SLinus Torvalds 
19351da177e4SLinus Torvalds    WR_HARPOON((ioport+hp_semaphore),
19361da177e4SLinus Torvalds       (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
19371da177e4SLinus Torvalds 
19381da177e4SLinus Torvalds    return((ULONG)CurrCard);
19391da177e4SLinus Torvalds }
19401da177e4SLinus Torvalds 
1941*47b5d69cSJames Bottomley  static void SccbMgr_unload_card(ULONG pCurrCard)
19421da177e4SLinus Torvalds {
19431da177e4SLinus Torvalds 	UCHAR i;
19441da177e4SLinus Torvalds 	ULONG portBase;
19451da177e4SLinus Torvalds 	ULONG regOffset;
19461da177e4SLinus Torvalds 	ULONG scamData;
19471da177e4SLinus Torvalds 	ULONG *pScamTbl;
19481da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
19491da177e4SLinus Torvalds 
19501da177e4SLinus Torvalds 	pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
19511da177e4SLinus Torvalds 
19521da177e4SLinus Torvalds 	if(pCurrNvRam){
1953*47b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1954*47b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1955*47b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1956*47b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1957*47b5d69cSJames Bottomley  		FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
19581da177e4SLinus Torvalds 
19591da177e4SLinus Torvalds 		for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1960*47b5d69cSJames Bottomley  			FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
19611da177e4SLinus Torvalds 
19621da177e4SLinus Torvalds 		portBase = pCurrNvRam->niBaseAddr;
19631da177e4SLinus Torvalds 
19641da177e4SLinus Torvalds 		for(i = 0; i < MAX_SCSI_TAR; i++){
19651da177e4SLinus Torvalds 			regOffset = hp_aramBase + 64 + i*4;
19661da177e4SLinus Torvalds 			pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
19671da177e4SLinus Torvalds 			scamData = *pScamTbl;
19681da177e4SLinus Torvalds 			WR_HARP32(portBase, regOffset, scamData);
19691da177e4SLinus Torvalds 		}
19701da177e4SLinus Torvalds 
19711da177e4SLinus Torvalds 	}else{
1972*47b5d69cSJames Bottomley  		FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
19731da177e4SLinus Torvalds 	}
19741da177e4SLinus Torvalds }
19751da177e4SLinus Torvalds 
19761da177e4SLinus Torvalds 
1977*47b5d69cSJames Bottomley  static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
19781da177e4SLinus Torvalds {
19791da177e4SLinus Torvalds 	UCHAR i;
19801da177e4SLinus Torvalds 	ULONG portBase;
19811da177e4SLinus Torvalds 	ULONG regOffset;
19821da177e4SLinus Torvalds 	ULONG scamData;
19831da177e4SLinus Torvalds 	ULONG *pScamTbl;
19841da177e4SLinus Torvalds 
1985*47b5d69cSJames Bottomley  	pNvRamInfo->niModel    = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1986*47b5d69cSJames Bottomley  	pNvRamInfo->niSysConf  = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1987*47b5d69cSJames Bottomley  	pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1988*47b5d69cSJames Bottomley  	pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1989*47b5d69cSJames Bottomley  	pNvRamInfo->niAdapId   = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
19901da177e4SLinus Torvalds 
19911da177e4SLinus Torvalds 	for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1992*47b5d69cSJames Bottomley  		pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
19931da177e4SLinus Torvalds 
19941da177e4SLinus Torvalds 	portBase = pNvRamInfo->niBaseAddr;
19951da177e4SLinus Torvalds 
19961da177e4SLinus Torvalds 	for(i = 0; i < MAX_SCSI_TAR; i++){
19971da177e4SLinus Torvalds 		regOffset = hp_aramBase + 64 + i*4;
19981da177e4SLinus Torvalds 		RD_HARP32(portBase, regOffset, scamData);
19991da177e4SLinus Torvalds 		pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
20001da177e4SLinus Torvalds 		*pScamTbl = scamData;
20011da177e4SLinus Torvalds 	}
20021da177e4SLinus Torvalds 
20031da177e4SLinus Torvalds }
20041da177e4SLinus Torvalds 
2005*47b5d69cSJames Bottomley  static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
20061da177e4SLinus Torvalds {
20071da177e4SLinus Torvalds 	WR_HARPOON(portBase + hp_stack_addr, index);
20081da177e4SLinus Torvalds 	return(RD_HARPOON(portBase + hp_stack_data));
20091da177e4SLinus Torvalds }
20101da177e4SLinus Torvalds 
2011*47b5d69cSJames Bottomley  static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
20121da177e4SLinus Torvalds {
20131da177e4SLinus Torvalds 	WR_HARPOON(portBase + hp_stack_addr, index);
20141da177e4SLinus Torvalds 	WR_HARPOON(portBase + hp_stack_data, data);
20151da177e4SLinus Torvalds }
20161da177e4SLinus Torvalds 
20171da177e4SLinus Torvalds 
2018*47b5d69cSJames Bottomley  static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
20191da177e4SLinus Torvalds {
2020*47b5d69cSJames Bottomley  	if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
2021*47b5d69cSJames Bottomley  		return(0);
20221da177e4SLinus Torvalds 	if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
20231da177e4SLinus Torvalds 								!= CLKCTRL_DEFAULT)
2024*47b5d69cSJames Bottomley  		return(0);
20251da177e4SLinus Torvalds 	if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
20261da177e4SLinus Torvalds 		(RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
2027*47b5d69cSJames Bottomley  		return(1);
2028*47b5d69cSJames Bottomley  	return(0);
20291da177e4SLinus Torvalds 
20301da177e4SLinus Torvalds }
20311da177e4SLinus Torvalds /*---------------------------------------------------------------------
20321da177e4SLinus Torvalds  *
20331da177e4SLinus Torvalds  * Function: SccbMgr_start_sccb
20341da177e4SLinus Torvalds  *
20351da177e4SLinus Torvalds  * Description: Start a command pointed to by p_Sccb. When the
20361da177e4SLinus Torvalds  *              command is completed it will be returned via the
20371da177e4SLinus Torvalds  *              callback function.
20381da177e4SLinus Torvalds  *
20391da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
2040*47b5d69cSJames Bottomley  static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
20411da177e4SLinus Torvalds {
20421da177e4SLinus Torvalds    ULONG ioport;
20431da177e4SLinus Torvalds    UCHAR thisCard, lun;
20441da177e4SLinus Torvalds 	PSCCB pSaveSccb;
20451da177e4SLinus Torvalds    CALL_BK_FN callback;
20461da177e4SLinus Torvalds 
20471da177e4SLinus Torvalds    thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
20481da177e4SLinus Torvalds    ioport = ((PSCCBcard) pCurrCard)->ioPort;
20491da177e4SLinus Torvalds 
20501da177e4SLinus Torvalds 	if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
20511da177e4SLinus Torvalds 	{
20521da177e4SLinus Torvalds 
20531da177e4SLinus Torvalds 		p_Sccb->HostStatus = SCCB_COMPLETE;
20541da177e4SLinus Torvalds 		p_Sccb->SccbStatus = SCCB_ERROR;
20551da177e4SLinus Torvalds 		callback = (CALL_BK_FN)p_Sccb->SccbCallback;
20561da177e4SLinus Torvalds 		if (callback)
20571da177e4SLinus Torvalds 			callback(p_Sccb);
20581da177e4SLinus Torvalds 
20591da177e4SLinus Torvalds 		return;
20601da177e4SLinus Torvalds 	}
20611da177e4SLinus Torvalds 
2062*47b5d69cSJames Bottomley     FPT_sinits(p_Sccb,thisCard);
20631da177e4SLinus Torvalds 
20641da177e4SLinus Torvalds 
20651da177e4SLinus Torvalds    if (!((PSCCBcard) pCurrCard)->cmdCounter)
20661da177e4SLinus Torvalds       {
20671da177e4SLinus Torvalds       WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
20681da177e4SLinus Torvalds          | SCCB_MGR_ACTIVE));
20691da177e4SLinus Torvalds 
20701da177e4SLinus Torvalds       if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
20711da177e4SLinus Torvalds          {
20721da177e4SLinus Torvalds 		 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
20731da177e4SLinus Torvalds 		 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
20741da177e4SLinus Torvalds          }
20751da177e4SLinus Torvalds       }
20761da177e4SLinus Torvalds 
20771da177e4SLinus Torvalds    ((PSCCBcard)pCurrCard)->cmdCounter++;
20781da177e4SLinus Torvalds 
20791da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
20801da177e4SLinus Torvalds 
20811da177e4SLinus Torvalds       WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
20821da177e4SLinus Torvalds          | TICKLE_ME));
20831da177e4SLinus Torvalds 		if(p_Sccb->OperationCode == RESET_COMMAND)
20841da177e4SLinus Torvalds 			{
20851da177e4SLinus Torvalds 				pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
20861da177e4SLinus Torvalds 				((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
2087*47b5d69cSJames Bottomley  				FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
20881da177e4SLinus Torvalds 				((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
20891da177e4SLinus Torvalds 			}
20901da177e4SLinus Torvalds 		else
20911da177e4SLinus Torvalds 			{
2092*47b5d69cSJames Bottomley  	      FPT_queueAddSccb(p_Sccb,thisCard);
20931da177e4SLinus Torvalds 			}
20941da177e4SLinus Torvalds       }
20951da177e4SLinus Torvalds 
20961da177e4SLinus Torvalds    else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
20971da177e4SLinus Torvalds 
20981da177e4SLinus Torvalds 			if(p_Sccb->OperationCode == RESET_COMMAND)
20991da177e4SLinus Torvalds 				{
21001da177e4SLinus Torvalds 					pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
21011da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
2102*47b5d69cSJames Bottomley  					FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
21031da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
21041da177e4SLinus Torvalds 				}
21051da177e4SLinus Torvalds 			else
21061da177e4SLinus Torvalds 				{
2107*47b5d69cSJames Bottomley  		      FPT_queueAddSccb(p_Sccb,thisCard);
21081da177e4SLinus Torvalds 				}
21091da177e4SLinus Torvalds       }
21101da177e4SLinus Torvalds 
21111da177e4SLinus Torvalds    else {
21121da177e4SLinus Torvalds 
21131da177e4SLinus Torvalds       MDISABLE_INT(ioport);
21141da177e4SLinus Torvalds 
21151da177e4SLinus Torvalds 		if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
2116*47b5d69cSJames Bottomley  			((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
21171da177e4SLinus Torvalds 			lun = p_Sccb->Lun;
21181da177e4SLinus Torvalds 		else
21191da177e4SLinus Torvalds 			lun = 0;
21201da177e4SLinus Torvalds       if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
2121*47b5d69cSJames Bottomley           (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
2122*47b5d69cSJames Bottomley           (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
2123*47b5d69cSJames Bottomley           == 0)) {
21241da177e4SLinus Torvalds 
21251da177e4SLinus Torvalds             ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
2126*47b5d69cSJames Bottomley  	    FPT_ssel(p_Sccb->SccbIOPort,thisCard);
21271da177e4SLinus Torvalds          }
21281da177e4SLinus Torvalds 
21291da177e4SLinus Torvalds       else {
21301da177e4SLinus Torvalds 
21311da177e4SLinus Torvalds 			if(p_Sccb->OperationCode == RESET_COMMAND)
21321da177e4SLinus Torvalds 				{
21331da177e4SLinus Torvalds 					pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
21341da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
2135*47b5d69cSJames Bottomley  					FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
21361da177e4SLinus Torvalds 					((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
21371da177e4SLinus Torvalds 				}
21381da177e4SLinus Torvalds 			else
21391da177e4SLinus Torvalds 				{
2140*47b5d69cSJames Bottomley  	         	FPT_queueAddSccb(p_Sccb,thisCard);
21411da177e4SLinus Torvalds 				}
21421da177e4SLinus Torvalds          }
21431da177e4SLinus Torvalds 
21441da177e4SLinus Torvalds 
21451da177e4SLinus Torvalds       MENABLE_INT(ioport);
21461da177e4SLinus Torvalds       }
21471da177e4SLinus Torvalds 
21481da177e4SLinus Torvalds }
21491da177e4SLinus Torvalds 
21501da177e4SLinus Torvalds 
21511da177e4SLinus Torvalds /*---------------------------------------------------------------------
21521da177e4SLinus Torvalds  *
21531da177e4SLinus Torvalds  * Function: SccbMgr_abort_sccb
21541da177e4SLinus Torvalds  *
21551da177e4SLinus Torvalds  * Description: Abort the command pointed to by p_Sccb.  When the
21561da177e4SLinus Torvalds  *              command is completed it will be returned via the
21571da177e4SLinus Torvalds  *              callback function.
21581da177e4SLinus Torvalds  *
21591da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
2160*47b5d69cSJames Bottomley  static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
21611da177e4SLinus Torvalds {
21621da177e4SLinus Torvalds 	ULONG ioport;
21631da177e4SLinus Torvalds 
21641da177e4SLinus Torvalds 	UCHAR thisCard;
21651da177e4SLinus Torvalds 	CALL_BK_FN callback;
21661da177e4SLinus Torvalds 	UCHAR TID;
21671da177e4SLinus Torvalds 	PSCCB pSaveSCCB;
21681da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
21691da177e4SLinus Torvalds 
21701da177e4SLinus Torvalds 
21711da177e4SLinus Torvalds 	ioport = ((PSCCBcard) pCurrCard)->ioPort;
21721da177e4SLinus Torvalds 
21731da177e4SLinus Torvalds 	thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
21741da177e4SLinus Torvalds 
2175*47b5d69cSJames Bottomley  	if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
21761da177e4SLinus Torvalds 	{
21771da177e4SLinus Torvalds 
2178*47b5d69cSJames Bottomley  		if (FPT_queueFindSccb(p_Sccb,thisCard))
21791da177e4SLinus Torvalds 		{
21801da177e4SLinus Torvalds 
21811da177e4SLinus Torvalds 			((PSCCBcard)pCurrCard)->cmdCounter--;
21821da177e4SLinus Torvalds 
21831da177e4SLinus Torvalds 			if (!((PSCCBcard)pCurrCard)->cmdCounter)
21841da177e4SLinus Torvalds 				WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
21851da177e4SLinus Torvalds 					& (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
21861da177e4SLinus Torvalds 
21871da177e4SLinus Torvalds 			p_Sccb->SccbStatus = SCCB_ABORT;
21881da177e4SLinus Torvalds 			callback = p_Sccb->SccbCallback;
21891da177e4SLinus Torvalds 			callback(p_Sccb);
21901da177e4SLinus Torvalds 
21911da177e4SLinus Torvalds 			return(0);
21921da177e4SLinus Torvalds 		}
21931da177e4SLinus Torvalds 
21941da177e4SLinus Torvalds 		else
21951da177e4SLinus Torvalds 		{
21961da177e4SLinus Torvalds 			if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
21971da177e4SLinus Torvalds 			{
21981da177e4SLinus Torvalds 				p_Sccb->SccbStatus = SCCB_ABORT;
21991da177e4SLinus Torvalds 				return(0);
22001da177e4SLinus Torvalds 
22011da177e4SLinus Torvalds 			}
22021da177e4SLinus Torvalds 
22031da177e4SLinus Torvalds 			else
22041da177e4SLinus Torvalds 			{
22051da177e4SLinus Torvalds 
22061da177e4SLinus Torvalds 				TID = p_Sccb->TargID;
22071da177e4SLinus Torvalds 
22081da177e4SLinus Torvalds 
22091da177e4SLinus Torvalds 				if(p_Sccb->Sccb_tag)
22101da177e4SLinus Torvalds 				{
22111da177e4SLinus Torvalds 					MDISABLE_INT(ioport);
22121da177e4SLinus Torvalds 					if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
22131da177e4SLinus Torvalds 					{
22141da177e4SLinus Torvalds 						p_Sccb->SccbStatus = SCCB_ABORT;
22151da177e4SLinus Torvalds 						p_Sccb->Sccb_scsistat = ABORT_ST;
22161da177e4SLinus Torvalds 						p_Sccb->Sccb_scsimsg = SMABORT_TAG;
22171da177e4SLinus Torvalds 
22181da177e4SLinus Torvalds 						if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
22191da177e4SLinus Torvalds 						{
22201da177e4SLinus Torvalds 							((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
2221*47b5d69cSJames Bottomley  							FPT_ssel(ioport, thisCard);
22221da177e4SLinus Torvalds 						}
22231da177e4SLinus Torvalds 						else
22241da177e4SLinus Torvalds 						{
22251da177e4SLinus Torvalds 							pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
22261da177e4SLinus Torvalds 							((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
2227*47b5d69cSJames Bottomley  							FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
22281da177e4SLinus Torvalds 							((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
22291da177e4SLinus Torvalds 						}
22301da177e4SLinus Torvalds 					}
22311da177e4SLinus Torvalds 					MENABLE_INT(ioport);
22321da177e4SLinus Torvalds 					return(0);
22331da177e4SLinus Torvalds 				}
22341da177e4SLinus Torvalds 				else
22351da177e4SLinus Torvalds 				{
2236*47b5d69cSJames Bottomley  					currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
22371da177e4SLinus Torvalds 
2238*47b5d69cSJames Bottomley  					if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
22391da177e4SLinus Torvalds 							== p_Sccb)
22401da177e4SLinus Torvalds 					{
22411da177e4SLinus Torvalds 						p_Sccb->SccbStatus = SCCB_ABORT;
22421da177e4SLinus Torvalds 						return(0);
22431da177e4SLinus Torvalds 					}
22441da177e4SLinus Torvalds 				}
22451da177e4SLinus Torvalds 			}
22461da177e4SLinus Torvalds 		}
22471da177e4SLinus Torvalds 	}
22481da177e4SLinus Torvalds 	return(-1);
22491da177e4SLinus Torvalds }
22501da177e4SLinus Torvalds 
22511da177e4SLinus Torvalds 
22521da177e4SLinus Torvalds /*---------------------------------------------------------------------
22531da177e4SLinus Torvalds  *
22541da177e4SLinus Torvalds  * Function: SccbMgr_my_int
22551da177e4SLinus Torvalds  *
22561da177e4SLinus Torvalds  * Description: Do a quick check to determine if there is a pending
22571da177e4SLinus Torvalds  *              interrupt for this card and disable the IRQ Pin if so.
22581da177e4SLinus Torvalds  *
22591da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
2260*47b5d69cSJames Bottomley  static UCHAR SccbMgr_my_int(ULONG pCurrCard)
22611da177e4SLinus Torvalds {
22621da177e4SLinus Torvalds    ULONG ioport;
22631da177e4SLinus Torvalds 
22641da177e4SLinus Torvalds    ioport = ((PSCCBcard)pCurrCard)->ioPort;
22651da177e4SLinus Torvalds 
22661da177e4SLinus Torvalds    if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
22671da177e4SLinus Torvalds    {
2268*47b5d69cSJames Bottomley        return(1);
22691da177e4SLinus Torvalds    }
22701da177e4SLinus Torvalds 
22711da177e4SLinus Torvalds    else
22721da177e4SLinus Torvalds 
2273*47b5d69cSJames Bottomley        return(0);
22741da177e4SLinus Torvalds }
22751da177e4SLinus Torvalds 
22761da177e4SLinus Torvalds 
22771da177e4SLinus Torvalds 
22781da177e4SLinus Torvalds /*---------------------------------------------------------------------
22791da177e4SLinus Torvalds  *
22801da177e4SLinus Torvalds  * Function: SccbMgr_isr
22811da177e4SLinus Torvalds  *
22821da177e4SLinus Torvalds  * Description: This is our entry point when an interrupt is generated
22831da177e4SLinus Torvalds  *              by the card and the upper level driver passes it on to
22841da177e4SLinus Torvalds  *              us.
22851da177e4SLinus Torvalds  *
22861da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
2287*47b5d69cSJames Bottomley  static int SccbMgr_isr(ULONG pCurrCard)
22881da177e4SLinus Torvalds {
22891da177e4SLinus Torvalds    PSCCB currSCCB;
22901da177e4SLinus Torvalds    UCHAR thisCard,result,bm_status, bm_int_st;
22911da177e4SLinus Torvalds    USHORT hp_int;
22921da177e4SLinus Torvalds    UCHAR i, target;
22931da177e4SLinus Torvalds    ULONG ioport;
22941da177e4SLinus Torvalds 
22951da177e4SLinus Torvalds    thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
22961da177e4SLinus Torvalds    ioport = ((PSCCBcard)pCurrCard)->ioPort;
22971da177e4SLinus Torvalds 
22981da177e4SLinus Torvalds    MDISABLE_INT(ioport);
22991da177e4SLinus Torvalds 
23001da177e4SLinus Torvalds    if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
23011da177e4SLinus Torvalds 		bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
23021da177e4SLinus Torvalds    else
23031da177e4SLinus Torvalds       bm_status = 0;
23041da177e4SLinus Torvalds 
23051da177e4SLinus Torvalds    WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
23061da177e4SLinus Torvalds 
2307*47b5d69cSJames Bottomley     while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
23081da177e4SLinus Torvalds 	  bm_status)
23091da177e4SLinus Torvalds      {
23101da177e4SLinus Torvalds 
23111da177e4SLinus Torvalds        currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
23121da177e4SLinus Torvalds 
23131da177e4SLinus Torvalds       if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
2314*47b5d69cSJames Bottomley           result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
23151da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
23161da177e4SLinus Torvalds          bm_status = 0;
23171da177e4SLinus Torvalds 
23181da177e4SLinus Torvalds          if (result) {
23191da177e4SLinus Torvalds 
23201da177e4SLinus Torvalds             MENABLE_INT(ioport);
23211da177e4SLinus Torvalds             return(result);
23221da177e4SLinus Torvalds             }
23231da177e4SLinus Torvalds          }
23241da177e4SLinus Torvalds 
23251da177e4SLinus Torvalds 
23261da177e4SLinus Torvalds       else if (hp_int & ICMD_COMP) {
23271da177e4SLinus Torvalds 
23281da177e4SLinus Torvalds          if ( !(hp_int & BUS_FREE) ) {
23291da177e4SLinus Torvalds             /* Wait for the BusFree before starting a new command.  We
23301da177e4SLinus Torvalds                must also check for being reselected since the BusFree
23311da177e4SLinus Torvalds                may not show up if another device reselects us in 1.5us or
23321da177e4SLinus Torvalds                less.  SRR Wednesday, 3/8/1995.
23331da177e4SLinus Torvalds 	         */
23341da177e4SLinus Torvalds 	   while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
23351da177e4SLinus Torvalds 	 }
23361da177e4SLinus Torvalds 
23371da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
23381da177e4SLinus Torvalds 
2339*47b5d69cSJames Bottomley              FPT_phaseChkFifo(ioport, thisCard);
23401da177e4SLinus Torvalds 
23411da177e4SLinus Torvalds /*         WRW_HARPOON((ioport+hp_intstat),
23421da177e4SLinus Torvalds             (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
23431da177e4SLinus Torvalds          */
23441da177e4SLinus Torvalds 
23451da177e4SLinus Torvalds 		 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
23461da177e4SLinus Torvalds 
2347*47b5d69cSJames Bottomley           FPT_autoCmdCmplt(ioport,thisCard);
23481da177e4SLinus Torvalds 
23491da177e4SLinus Torvalds          }
23501da177e4SLinus Torvalds 
23511da177e4SLinus Torvalds 
23521da177e4SLinus Torvalds       else if (hp_int & ITAR_DISC)
23531da177e4SLinus Torvalds          {
23541da177e4SLinus Torvalds 
23551da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
23561da177e4SLinus Torvalds 
2357*47b5d69cSJames Bottomley              FPT_phaseChkFifo(ioport, thisCard);
23581da177e4SLinus Torvalds 
23591da177e4SLinus Torvalds             }
23601da177e4SLinus Torvalds 
23611da177e4SLinus Torvalds          if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
23621da177e4SLinus Torvalds 
23631da177e4SLinus Torvalds             WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
23641da177e4SLinus Torvalds             currSCCB->Sccb_XferState |= F_NO_DATA_YET;
23651da177e4SLinus Torvalds 
23661da177e4SLinus Torvalds             currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
23671da177e4SLinus Torvalds             }
23681da177e4SLinus Torvalds 
23691da177e4SLinus Torvalds          currSCCB->Sccb_scsistat = DISCONNECT_ST;
2370*47b5d69cSJames Bottomley           FPT_queueDisconnect(currSCCB,thisCard);
23711da177e4SLinus Torvalds 
23721da177e4SLinus Torvalds             /* Wait for the BusFree before starting a new command.  We
23731da177e4SLinus Torvalds                must also check for being reselected since the BusFree
23741da177e4SLinus Torvalds                may not show up if another device reselects us in 1.5us or
23751da177e4SLinus Torvalds                less.  SRR Wednesday, 3/8/1995.
23761da177e4SLinus Torvalds              */
23771da177e4SLinus Torvalds 	   while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
23781da177e4SLinus Torvalds 		  !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
23791da177e4SLinus Torvalds 		    RD_HARPOON((ioport+hp_scsisig)) ==
23801da177e4SLinus Torvalds 		    (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
23811da177e4SLinus Torvalds 
23821da177e4SLinus Torvalds 	   /*
23831da177e4SLinus Torvalds 	     The additional loop exit condition above detects a timing problem
23841da177e4SLinus Torvalds 	     with the revision D/E harpoon chips.  The caller should reset the
23851da177e4SLinus Torvalds 	     host adapter to recover when 0xFE is returned.
23861da177e4SLinus Torvalds 	   */
23871da177e4SLinus Torvalds 	   if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
23881da177e4SLinus Torvalds 	     {
23891da177e4SLinus Torvalds 	       MENABLE_INT(ioport);
23901da177e4SLinus Torvalds 	       return 0xFE;
23911da177e4SLinus Torvalds 	     }
23921da177e4SLinus Torvalds 
23931da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
23941da177e4SLinus Torvalds 
23951da177e4SLinus Torvalds 
23961da177e4SLinus Torvalds          ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
23971da177e4SLinus Torvalds 
23981da177e4SLinus Torvalds       	}
23991da177e4SLinus Torvalds 
24001da177e4SLinus Torvalds 
24011da177e4SLinus Torvalds       else if (hp_int & RSEL) {
24021da177e4SLinus Torvalds 
24031da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
24041da177e4SLinus Torvalds 
24051da177e4SLinus Torvalds          if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
24061da177e4SLinus Torvalds 		      {
24071da177e4SLinus Torvalds             if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
24081da177e4SLinus Torvalds 			      {
2409*47b5d69cSJames Bottomley                 FPT_phaseChkFifo(ioport, thisCard);
24101da177e4SLinus Torvalds                }
24111da177e4SLinus Torvalds 
24121da177e4SLinus Torvalds             if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
24131da177e4SLinus Torvalds 			      {
24141da177e4SLinus Torvalds                WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
24151da177e4SLinus Torvalds                currSCCB->Sccb_XferState |= F_NO_DATA_YET;
24161da177e4SLinus Torvalds                currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
24171da177e4SLinus Torvalds                }
24181da177e4SLinus Torvalds 
24191da177e4SLinus Torvalds             WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
24201da177e4SLinus Torvalds             currSCCB->Sccb_scsistat = DISCONNECT_ST;
2421*47b5d69cSJames Bottomley              FPT_queueDisconnect(currSCCB,thisCard);
24221da177e4SLinus Torvalds             }
24231da177e4SLinus Torvalds 
2424*47b5d69cSJames Bottomley           FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2425*47b5d69cSJames Bottomley           FPT_phaseDecode(ioport,thisCard);
24261da177e4SLinus Torvalds 
24271da177e4SLinus Torvalds          }
24281da177e4SLinus Torvalds 
24291da177e4SLinus Torvalds 
24301da177e4SLinus Torvalds       else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
24311da177e4SLinus Torvalds          {
24321da177e4SLinus Torvalds 
24331da177e4SLinus Torvalds             WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2434*47b5d69cSJames Bottomley              FPT_phaseDecode(ioport,thisCard);
24351da177e4SLinus Torvalds 
24361da177e4SLinus Torvalds          }
24371da177e4SLinus Torvalds 
24381da177e4SLinus Torvalds 
24391da177e4SLinus Torvalds       else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
24401da177e4SLinus Torvalds 		   {
24411da177e4SLinus Torvalds 	 	   WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
24421da177e4SLinus Torvalds 	 	   if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
24431da177e4SLinus Torvalds 	    		{
2444*47b5d69cSJames Bottomley  	    		FPT_phaseDecode(ioport,thisCard);
24451da177e4SLinus Torvalds 	    		}
24461da177e4SLinus Torvalds 	 	   else
24471da177e4SLinus Torvalds 	    		{
24481da177e4SLinus Torvalds    /* Harpoon problem some SCSI target device respond to selection
24491da177e4SLinus Torvalds    with short BUSY pulse (<400ns) this will make the Harpoon is not able
24501da177e4SLinus Torvalds    to latch the correct Target ID into reg. x53.
24511da177e4SLinus Torvalds    The work around require to correct this reg. But when write to this
24521da177e4SLinus Torvalds    reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
24531da177e4SLinus Torvalds    need to read this reg first then restore it later. After update to 0x53 */
24541da177e4SLinus Torvalds 
24551da177e4SLinus Torvalds 	    		i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
24561da177e4SLinus Torvalds 	    		target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
24571da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
24581da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
24591da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
24601da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_fifowrite, i);
24611da177e4SLinus Torvalds 	    		WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
24621da177e4SLinus Torvalds 	    		}
24631da177e4SLinus Torvalds 	 	   }
24641da177e4SLinus Torvalds 
24651da177e4SLinus Torvalds       else if (hp_int & XFER_CNT_0) {
24661da177e4SLinus Torvalds 
24671da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
24681da177e4SLinus Torvalds 
2469*47b5d69cSJames Bottomley           FPT_schkdd(ioport,thisCard);
24701da177e4SLinus Torvalds 
24711da177e4SLinus Torvalds          }
24721da177e4SLinus Torvalds 
24731da177e4SLinus Torvalds 
24741da177e4SLinus Torvalds       else if (hp_int & BUS_FREE) {
24751da177e4SLinus Torvalds 
24761da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
24771da177e4SLinus Torvalds 
24781da177e4SLinus Torvalds         	if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
24791da177e4SLinus Torvalds 
2480*47b5d69cSJames Bottomley             	FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
24811da177e4SLinus Torvalds 				}
24821da177e4SLinus Torvalds 
2483*47b5d69cSJames Bottomley           FPT_phaseBusFree(ioport,thisCard);
24841da177e4SLinus Torvalds 			}
24851da177e4SLinus Torvalds 
24861da177e4SLinus Torvalds 
24871da177e4SLinus Torvalds       else if (hp_int & ITICKLE) {
24881da177e4SLinus Torvalds 
24891da177e4SLinus Torvalds          WRW_HARPOON((ioport+hp_intstat), ITICKLE);
24901da177e4SLinus Torvalds          ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
24911da177e4SLinus Torvalds          }
24921da177e4SLinus Torvalds 
24931da177e4SLinus Torvalds 
24941da177e4SLinus Torvalds 
24951da177e4SLinus Torvalds       if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
24961da177e4SLinus Torvalds 
24971da177e4SLinus Torvalds 
24981da177e4SLinus Torvalds          ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
24991da177e4SLinus Torvalds 
25001da177e4SLinus Torvalds 
25011da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
25021da177e4SLinus Torvalds 
2503*47b5d69cSJames Bottomley              FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
25041da177e4SLinus Torvalds             }
25051da177e4SLinus Torvalds 
25061da177e4SLinus Torvalds          if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
25071da177e4SLinus Torvalds             ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2508*47b5d69cSJames Bottomley              FPT_ssel(ioport,thisCard);
25091da177e4SLinus Torvalds             }
25101da177e4SLinus Torvalds 
25111da177e4SLinus Torvalds          break;
25121da177e4SLinus Torvalds 
25131da177e4SLinus Torvalds          }
25141da177e4SLinus Torvalds 
25151da177e4SLinus Torvalds       }  /*end while */
25161da177e4SLinus Torvalds 
25171da177e4SLinus Torvalds    MENABLE_INT(ioport);
25181da177e4SLinus Torvalds 
25191da177e4SLinus Torvalds    return(0);
25201da177e4SLinus Torvalds }
25211da177e4SLinus Torvalds 
25221da177e4SLinus Torvalds /*---------------------------------------------------------------------
25231da177e4SLinus Torvalds  *
25241da177e4SLinus Torvalds  * Function: Sccb_bad_isr
25251da177e4SLinus Torvalds  *
25261da177e4SLinus Torvalds  * Description: Some type of interrupt has occurred which is slightly
25271da177e4SLinus Torvalds  *              out of the ordinary.  We will now decode it fully, in
25281da177e4SLinus Torvalds  *              this routine.  This is broken up in an attempt to save
25291da177e4SLinus Torvalds  *              processing time.
25301da177e4SLinus Torvalds  *
25311da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
2532*47b5d69cSJames Bottomley  static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2533*47b5d69cSJames Bottomley  				 PSCCBcard pCurrCard, USHORT p_int)
25341da177e4SLinus Torvalds {
25351da177e4SLinus Torvalds    UCHAR temp, ScamFlg;
25361da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
25371da177e4SLinus Torvalds    PNVRamInfo pCurrNvRam;
25381da177e4SLinus Torvalds 
25391da177e4SLinus Torvalds 
25401da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_ext_status) &
25411da177e4SLinus Torvalds          (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
25421da177e4SLinus Torvalds       {
25431da177e4SLinus Torvalds 
25441da177e4SLinus Torvalds       if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
25451da177e4SLinus Torvalds          {
25461da177e4SLinus Torvalds 
2547*47b5d69cSJames Bottomley           FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
25481da177e4SLinus Torvalds          }
25491da177e4SLinus Torvalds 
25501da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
25511da177e4SLinus Torvalds 
25521da177e4SLinus Torvalds          {
25531da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_pci_stat_cfg,
25541da177e4SLinus Torvalds             (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
25551da177e4SLinus Torvalds 
25561da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
25571da177e4SLinus Torvalds 
25581da177e4SLinus Torvalds          }
25591da177e4SLinus Torvalds 
25601da177e4SLinus Torvalds       if (pCurrCard->currentSCCB != NULL)
25611da177e4SLinus Torvalds          {
25621da177e4SLinus Torvalds 
25631da177e4SLinus Torvalds          if (!pCurrCard->currentSCCB->HostStatus)
25641da177e4SLinus Torvalds             pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
25651da177e4SLinus Torvalds 
2566*47b5d69cSJames Bottomley           FPT_sxfrp(p_port,p_card);
25671da177e4SLinus Torvalds 
25681da177e4SLinus Torvalds 	     temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
25691da177e4SLinus Torvalds 							(EXT_ARB_ACK | SCSI_TERM_ENA_H));
25701da177e4SLinus Torvalds       	WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
25711da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_ee_ctrl, temp);
25721da177e4SLinus Torvalds 
25731da177e4SLinus Torvalds          if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
25741da177e4SLinus Torvalds             {
2575*47b5d69cSJames Bottomley              FPT_phaseDecode(p_port,p_card);
25761da177e4SLinus Torvalds             }
25771da177e4SLinus Torvalds          }
25781da177e4SLinus Torvalds       }
25791da177e4SLinus Torvalds 
25801da177e4SLinus Torvalds 
25811da177e4SLinus Torvalds    else if (p_int & RESET)
25821da177e4SLinus Torvalds          {
25831da177e4SLinus Torvalds 
25841da177e4SLinus Torvalds 				WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
25851da177e4SLinus Torvalds 				WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
25861da177e4SLinus Torvalds            if (pCurrCard->currentSCCB != NULL) {
25871da177e4SLinus Torvalds 
25881da177e4SLinus Torvalds                if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
25891da177e4SLinus Torvalds 
2590*47b5d69cSJames Bottomley                 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
25911da177e4SLinus Torvalds                }
25921da177e4SLinus Torvalds 
25931da177e4SLinus Torvalds 
25941da177e4SLinus Torvalds            DISABLE_AUTO(p_port);
25951da177e4SLinus Torvalds 
2596*47b5d69cSJames Bottomley             FPT_sresb(p_port,p_card);
25971da177e4SLinus Torvalds 
25981da177e4SLinus Torvalds            while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
25991da177e4SLinus Torvalds 
26001da177e4SLinus Torvalds 				pCurrNvRam = pCurrCard->pNvRamInfo;
26011da177e4SLinus Torvalds 				if(pCurrNvRam){
26021da177e4SLinus Torvalds 					ScamFlg = pCurrNvRam->niScamConf;
26031da177e4SLinus Torvalds 				}
26041da177e4SLinus Torvalds 				else{
2605*47b5d69cSJames Bottomley  				   ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
26061da177e4SLinus Torvalds 				}
26071da177e4SLinus Torvalds 
2608*47b5d69cSJames Bottomley             FPT_XbowInit(p_port, ScamFlg);
26091da177e4SLinus Torvalds 
2610*47b5d69cSJames Bottomley                 FPT_scini(p_card, pCurrCard->ourId, 0);
26111da177e4SLinus Torvalds 
26121da177e4SLinus Torvalds            return(0xFF);
26131da177e4SLinus Torvalds          }
26141da177e4SLinus Torvalds 
26151da177e4SLinus Torvalds 
26161da177e4SLinus Torvalds    else if (p_int & FIFO) {
26171da177e4SLinus Torvalds 
26181da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat), FIFO);
26191da177e4SLinus Torvalds 
26201da177e4SLinus Torvalds       if (pCurrCard->currentSCCB != NULL)
2621*47b5d69cSJames Bottomley           FPT_sxfrp(p_port,p_card);
26221da177e4SLinus Torvalds       }
26231da177e4SLinus Torvalds 
26241da177e4SLinus Torvalds    else if (p_int & TIMEOUT)
26251da177e4SLinus Torvalds       {
26261da177e4SLinus Torvalds 
26271da177e4SLinus Torvalds       DISABLE_AUTO(p_port);
26281da177e4SLinus Torvalds 
26291da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat),
26301da177e4SLinus Torvalds 		  (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
26311da177e4SLinus Torvalds 
26321da177e4SLinus Torvalds       pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
26331da177e4SLinus Torvalds 
26341da177e4SLinus Torvalds 
2635*47b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
26361da177e4SLinus Torvalds 		if((pCurrCard->globalFlags & F_CONLUN_IO) &&
26371da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2638*47b5d69cSJames Bottomley  	      currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
26391da177e4SLinus Torvalds 		else
2640*47b5d69cSJames Bottomley  	      currTar_Info->TarLUNBusy[0] = 0;
26411da177e4SLinus Torvalds 
26421da177e4SLinus Torvalds 
26431da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
26441da177e4SLinus Torvalds          {
26451da177e4SLinus Torvalds 	       currTar_Info->TarSyncCtrl = 0;
26461da177e4SLinus Torvalds          currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
26471da177e4SLinus Torvalds          }
26481da177e4SLinus Torvalds 
26491da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
26501da177e4SLinus Torvalds          {
26511da177e4SLinus Torvalds          currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
26521da177e4SLinus Torvalds          }
26531da177e4SLinus Torvalds 
2654*47b5d69cSJames Bottomley        FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
26551da177e4SLinus Torvalds 
2656*47b5d69cSJames Bottomley        FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
26571da177e4SLinus Torvalds 
26581da177e4SLinus Torvalds       }
26591da177e4SLinus Torvalds 
26601da177e4SLinus Torvalds    else if (p_int & SCAM_SEL)
26611da177e4SLinus Torvalds       {
26621da177e4SLinus Torvalds 
2663*47b5d69cSJames Bottomley        FPT_scarb(p_port,LEVEL2_TAR);
2664*47b5d69cSJames Bottomley        FPT_scsel(p_port);
2665*47b5d69cSJames Bottomley        FPT_scasid(p_card, p_port);
26661da177e4SLinus Torvalds 
2667*47b5d69cSJames Bottomley        FPT_scbusf(p_port);
26681da177e4SLinus Torvalds 
26691da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
26701da177e4SLinus Torvalds       }
26711da177e4SLinus Torvalds 
26721da177e4SLinus Torvalds    return(0x00);
26731da177e4SLinus Torvalds }
26741da177e4SLinus Torvalds 
26751da177e4SLinus Torvalds 
26761da177e4SLinus Torvalds /*---------------------------------------------------------------------
26771da177e4SLinus Torvalds  *
26781da177e4SLinus Torvalds  * Function: SccbMgrTableInit
26791da177e4SLinus Torvalds  *
26801da177e4SLinus Torvalds  * Description: Initialize all Sccb manager data structures.
26811da177e4SLinus Torvalds  *
26821da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
26831da177e4SLinus Torvalds 
2684*47b5d69cSJames Bottomley  static void FPT_SccbMgrTableInitAll()
26851da177e4SLinus Torvalds {
26861da177e4SLinus Torvalds    UCHAR thisCard;
26871da177e4SLinus Torvalds 
26881da177e4SLinus Torvalds    for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
26891da177e4SLinus Torvalds       {
2690*47b5d69cSJames Bottomley        FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
26911da177e4SLinus Torvalds 
2692*47b5d69cSJames Bottomley        FPT_BL_Card[thisCard].ioPort      = 0x00;
2693*47b5d69cSJames Bottomley        FPT_BL_Card[thisCard].cardInfo    = NULL;
2694*47b5d69cSJames Bottomley        FPT_BL_Card[thisCard].cardIndex   = 0xFF;
2695*47b5d69cSJames Bottomley        FPT_BL_Card[thisCard].ourId       = 0x00;
2696*47b5d69cSJames Bottomley  		FPT_BL_Card[thisCard].pNvRamInfo	= NULL;
26971da177e4SLinus Torvalds       }
26981da177e4SLinus Torvalds }
26991da177e4SLinus Torvalds 
27001da177e4SLinus Torvalds 
27011da177e4SLinus Torvalds /*---------------------------------------------------------------------
27021da177e4SLinus Torvalds  *
27031da177e4SLinus Torvalds  * Function: SccbMgrTableInit
27041da177e4SLinus Torvalds  *
27051da177e4SLinus Torvalds  * Description: Initialize all Sccb manager data structures.
27061da177e4SLinus Torvalds  *
27071da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
27081da177e4SLinus Torvalds 
2709*47b5d69cSJames Bottomley  static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
27101da177e4SLinus Torvalds {
27111da177e4SLinus Torvalds    UCHAR scsiID, qtag;
27121da177e4SLinus Torvalds 
27131da177e4SLinus Torvalds 	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
27141da177e4SLinus Torvalds 	{
2715*47b5d69cSJames Bottomley  		FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
27161da177e4SLinus Torvalds 	}
27171da177e4SLinus Torvalds 
27181da177e4SLinus Torvalds    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
27191da177e4SLinus Torvalds       {
2720*47b5d69cSJames Bottomley        FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2721*47b5d69cSJames Bottomley        FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2722*47b5d69cSJames Bottomley        FPT_SccbMgrTableInitTarget(p_card, scsiID);
27231da177e4SLinus Torvalds       }
27241da177e4SLinus Torvalds 
27251da177e4SLinus Torvalds    pCurrCard->scanIndex = 0x00;
27261da177e4SLinus Torvalds    pCurrCard->currentSCCB = NULL;
27271da177e4SLinus Torvalds    pCurrCard->globalFlags = 0x00;
27281da177e4SLinus Torvalds    pCurrCard->cmdCounter  = 0x00;
27291da177e4SLinus Torvalds 	pCurrCard->tagQ_Lst = 0x01;
27301da177e4SLinus Torvalds 	pCurrCard->discQCount = 0;
27311da177e4SLinus Torvalds 
27321da177e4SLinus Torvalds 
27331da177e4SLinus Torvalds }
27341da177e4SLinus Torvalds 
27351da177e4SLinus Torvalds 
27361da177e4SLinus Torvalds /*---------------------------------------------------------------------
27371da177e4SLinus Torvalds  *
27381da177e4SLinus Torvalds  * Function: SccbMgrTableInit
27391da177e4SLinus Torvalds  *
27401da177e4SLinus Torvalds  * Description: Initialize all Sccb manager data structures.
27411da177e4SLinus Torvalds  *
27421da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
27431da177e4SLinus Torvalds 
2744*47b5d69cSJames Bottomley  static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
27451da177e4SLinus Torvalds {
27461da177e4SLinus Torvalds 
27471da177e4SLinus Torvalds 	UCHAR lun, qtag;
27481da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
27491da177e4SLinus Torvalds 
2750*47b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
27511da177e4SLinus Torvalds 
27521da177e4SLinus Torvalds 	currTar_Info->TarSelQ_Cnt = 0;
27531da177e4SLinus Torvalds 	currTar_Info->TarSyncCtrl = 0;
27541da177e4SLinus Torvalds 
27551da177e4SLinus Torvalds 	currTar_Info->TarSelQ_Head = NULL;
27561da177e4SLinus Torvalds 	currTar_Info->TarSelQ_Tail = NULL;
27571da177e4SLinus Torvalds 	currTar_Info->TarTagQ_Cnt = 0;
2758*47b5d69cSJames Bottomley  	currTar_Info->TarLUN_CA = 0;
27591da177e4SLinus Torvalds 
27601da177e4SLinus Torvalds 
27611da177e4SLinus Torvalds 	for (lun = 0; lun < MAX_LUN; lun++)
27621da177e4SLinus Torvalds 	{
2763*47b5d69cSJames Bottomley  		currTar_Info->TarLUNBusy[lun] = 0;
27641da177e4SLinus Torvalds 		currTar_Info->LunDiscQ_Idx[lun] = 0;
27651da177e4SLinus Torvalds 	}
27661da177e4SLinus Torvalds 
27671da177e4SLinus Torvalds 	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
27681da177e4SLinus Torvalds 	{
2769*47b5d69cSJames Bottomley  		if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
27701da177e4SLinus Torvalds 		{
2771*47b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
27721da177e4SLinus Torvalds 			{
2773*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2774*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQCount--;
27751da177e4SLinus Torvalds 			}
27761da177e4SLinus Torvalds 		}
27771da177e4SLinus Torvalds 	}
27781da177e4SLinus Torvalds }
27791da177e4SLinus Torvalds 
27801da177e4SLinus Torvalds 
27811da177e4SLinus Torvalds /*---------------------------------------------------------------------
27821da177e4SLinus Torvalds  *
27831da177e4SLinus Torvalds  * Function: sfetm
27841da177e4SLinus Torvalds  *
27851da177e4SLinus Torvalds  * Description: Read in a message byte from the SCSI bus, and check
27861da177e4SLinus Torvalds  *              for a parity error.
27871da177e4SLinus Torvalds  *
27881da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
27891da177e4SLinus Torvalds 
2790*47b5d69cSJames Bottomley  static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
27911da177e4SLinus Torvalds {
27921da177e4SLinus Torvalds 	UCHAR message;
27931da177e4SLinus Torvalds 	USHORT TimeOutLoop;
27941da177e4SLinus Torvalds 
27951da177e4SLinus Torvalds 	TimeOutLoop = 0;
27961da177e4SLinus Torvalds 	while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
27971da177e4SLinus Torvalds 			(TimeOutLoop++ < 20000) ){}
27981da177e4SLinus Torvalds 
27991da177e4SLinus Torvalds 
28001da177e4SLinus Torvalds 	WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
28011da177e4SLinus Torvalds 
28021da177e4SLinus Torvalds 	message = RD_HARPOON(port+hp_scsidata_0);
28031da177e4SLinus Torvalds 
28041da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
28051da177e4SLinus Torvalds 
28061da177e4SLinus Torvalds 
28071da177e4SLinus Torvalds 	if (TimeOutLoop > 20000)
28081da177e4SLinus Torvalds 		message = 0x00;   /* force message byte = 0 if Time Out on Req */
28091da177e4SLinus Torvalds 
28101da177e4SLinus Torvalds 	if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
28111da177e4SLinus Torvalds 		(RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
28121da177e4SLinus Torvalds 	{
28131da177e4SLinus Torvalds 		WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
28141da177e4SLinus Torvalds 		WR_HARPOON(port+hp_xferstat, 0);
28151da177e4SLinus Torvalds 		WR_HARPOON(port+hp_fiforead, 0);
28161da177e4SLinus Torvalds 		WR_HARPOON(port+hp_fifowrite, 0);
28171da177e4SLinus Torvalds 		if (pCurrSCCB != NULL)
28181da177e4SLinus Torvalds 		{
28191da177e4SLinus Torvalds 			pCurrSCCB->Sccb_scsimsg = SMPARITY;
28201da177e4SLinus Torvalds 		}
28211da177e4SLinus Torvalds 		message = 0x00;
28221da177e4SLinus Torvalds 		do
28231da177e4SLinus Torvalds 		{
28241da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
28251da177e4SLinus Torvalds 			TimeOutLoop = 0;
28261da177e4SLinus Torvalds 			while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
28271da177e4SLinus Torvalds 				(TimeOutLoop++ < 20000) ){}
28281da177e4SLinus Torvalds 			if (TimeOutLoop > 20000)
28291da177e4SLinus Torvalds 			{
28301da177e4SLinus Torvalds 				WRW_HARPOON((port+hp_intstat), PARITY);
28311da177e4SLinus Torvalds 				return(message);
28321da177e4SLinus Torvalds 			}
28331da177e4SLinus Torvalds 			if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
28341da177e4SLinus Torvalds 			{
28351da177e4SLinus Torvalds 				WRW_HARPOON((port+hp_intstat), PARITY);
28361da177e4SLinus Torvalds 				return(message);
28371da177e4SLinus Torvalds 			}
28381da177e4SLinus Torvalds 			WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
28391da177e4SLinus Torvalds 
28401da177e4SLinus Torvalds 			RD_HARPOON(port+hp_scsidata_0);
28411da177e4SLinus Torvalds 
28421da177e4SLinus Torvalds 			WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
28431da177e4SLinus Torvalds 
28441da177e4SLinus Torvalds 		}while(1);
28451da177e4SLinus Torvalds 
28461da177e4SLinus Torvalds 	}
28471da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
28481da177e4SLinus Torvalds 	WR_HARPOON(port+hp_xferstat, 0);
28491da177e4SLinus Torvalds 	WR_HARPOON(port+hp_fiforead, 0);
28501da177e4SLinus Torvalds 	WR_HARPOON(port+hp_fifowrite, 0);
28511da177e4SLinus Torvalds 	return(message);
28521da177e4SLinus Torvalds }
28531da177e4SLinus Torvalds 
28541da177e4SLinus Torvalds 
28551da177e4SLinus Torvalds /*---------------------------------------------------------------------
28561da177e4SLinus Torvalds  *
2857*47b5d69cSJames Bottomley   * Function: FPT_ssel
28581da177e4SLinus Torvalds  *
28591da177e4SLinus Torvalds  * Description: Load up automation and select target device.
28601da177e4SLinus Torvalds  *
28611da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
28621da177e4SLinus Torvalds 
2863*47b5d69cSJames Bottomley  static void FPT_ssel(ULONG port, UCHAR p_card)
28641da177e4SLinus Torvalds {
28651da177e4SLinus Torvalds 
28661da177e4SLinus Torvalds    UCHAR auto_loaded, i, target, *theCCB;
28671da177e4SLinus Torvalds 
28681da177e4SLinus Torvalds    ULONG cdb_reg;
28691da177e4SLinus Torvalds    PSCCBcard CurrCard;
28701da177e4SLinus Torvalds    PSCCB currSCCB;
28711da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
28721da177e4SLinus Torvalds    UCHAR lastTag, lun;
28731da177e4SLinus Torvalds 
2874*47b5d69cSJames Bottomley     CurrCard = &FPT_BL_Card[p_card];
28751da177e4SLinus Torvalds    currSCCB = CurrCard->currentSCCB;
28761da177e4SLinus Torvalds    target = currSCCB->TargID;
2877*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][target];
28781da177e4SLinus Torvalds    lastTag = CurrCard->tagQ_Lst;
28791da177e4SLinus Torvalds 
28801da177e4SLinus Torvalds    ARAM_ACCESS(port);
28811da177e4SLinus Torvalds 
28821da177e4SLinus Torvalds 
28831da177e4SLinus Torvalds 	if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
28841da177e4SLinus Torvalds 		currSCCB->ControlByte &= ~F_USE_CMD_Q;
28851da177e4SLinus Torvalds 
28861da177e4SLinus Torvalds 	if(((CurrCard->globalFlags & F_CONLUN_IO) &&
28871da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
28881da177e4SLinus Torvalds 
28891da177e4SLinus Torvalds 	   lun = currSCCB->Lun;
28901da177e4SLinus Torvalds 	else
28911da177e4SLinus Torvalds 		lun = 0;
28921da177e4SLinus Torvalds 
28931da177e4SLinus Torvalds 
28941da177e4SLinus Torvalds    if (CurrCard->globalFlags & F_TAG_STARTED)
28951da177e4SLinus Torvalds       {
28961da177e4SLinus Torvalds       if (!(currSCCB->ControlByte & F_USE_CMD_Q))
28971da177e4SLinus Torvalds          {
2898*47b5d69cSJames Bottomley        	if ((currTar_Info->TarLUN_CA == 0)
28991da177e4SLinus Torvalds       	    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
29001da177e4SLinus Torvalds       	    == TAG_Q_TRYING))
29011da177e4SLinus Torvalds             {
29021da177e4SLinus Torvalds 
29031da177e4SLinus Torvalds 	         if (currTar_Info->TarTagQ_Cnt !=0)
29041da177e4SLinus Torvalds                   {
2905*47b5d69cSJames Bottomley           		   currTar_Info->TarLUNBusy[lun] = 1;
2906*47b5d69cSJames Bottomley              		FPT_queueSelectFail(CurrCard,p_card);
29071da177e4SLinus Torvalds 					   SGRAM_ACCESS(port);
29081da177e4SLinus Torvalds          		   return;
29091da177e4SLinus Torvalds          		   }
29101da177e4SLinus Torvalds 
29111da177e4SLinus Torvalds             else {
2912*47b5d69cSJames Bottomley           		  currTar_Info->TarLUNBusy[lun] = 1;
29131da177e4SLinus Torvalds          		  }
29141da177e4SLinus Torvalds 
29151da177e4SLinus Torvalds    	      }  /*End non-tagged */
29161da177e4SLinus Torvalds 
29171da177e4SLinus Torvalds 	      else {
2918*47b5d69cSJames Bottomley  	         currTar_Info->TarLUNBusy[lun] = 1;
29191da177e4SLinus Torvalds 	         }
29201da177e4SLinus Torvalds 
29211da177e4SLinus Torvalds 	      }  /*!Use cmd Q Tagged */
29221da177e4SLinus Torvalds 
29231da177e4SLinus Torvalds 	   else {
2924*47b5d69cSJames Bottomley     	     if (currTar_Info->TarLUN_CA == 1)
29251da177e4SLinus Torvalds                {
2926*47b5d69cSJames Bottomley        	      FPT_queueSelectFail(CurrCard,p_card);
29271da177e4SLinus Torvalds 				   SGRAM_ACCESS(port);
29281da177e4SLinus Torvalds       	      return;
29291da177e4SLinus Torvalds 	            }
29301da177e4SLinus Torvalds 
2931*47b5d69cSJames Bottomley  	        currTar_Info->TarLUNBusy[lun] = 1;
29321da177e4SLinus Torvalds 
29331da177e4SLinus Torvalds    	     }  /*else use cmd Q tagged */
29341da177e4SLinus Torvalds 
29351da177e4SLinus Torvalds       }  /*if glob tagged started */
29361da177e4SLinus Torvalds 
29371da177e4SLinus Torvalds    else {
2938*47b5d69cSJames Bottomley          currTar_Info->TarLUNBusy[lun] = 1;
29391da177e4SLinus Torvalds         }
29401da177e4SLinus Torvalds 
29411da177e4SLinus Torvalds 
29421da177e4SLinus Torvalds 
29431da177e4SLinus Torvalds 	if((((CurrCard->globalFlags & F_CONLUN_IO) &&
29441da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
29451da177e4SLinus Torvalds 		|| (!(currSCCB->ControlByte & F_USE_CMD_Q))))
29461da177e4SLinus Torvalds 	{
29471da177e4SLinus Torvalds 		if(CurrCard->discQCount >= QUEUE_DEPTH)
29481da177e4SLinus Torvalds 		{
2949*47b5d69cSJames Bottomley  			currTar_Info->TarLUNBusy[lun] = 1;
2950*47b5d69cSJames Bottomley  			FPT_queueSelectFail(CurrCard,p_card);
29511da177e4SLinus Torvalds 			SGRAM_ACCESS(port);
29521da177e4SLinus Torvalds 			return;
29531da177e4SLinus Torvalds 		}
29541da177e4SLinus Torvalds 		for (i = 1; i < QUEUE_DEPTH; i++)
29551da177e4SLinus Torvalds 		{
29561da177e4SLinus Torvalds 			if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
29571da177e4SLinus Torvalds 			if (CurrCard->discQ_Tbl[lastTag] == NULL)
29581da177e4SLinus Torvalds 			{
29591da177e4SLinus Torvalds 				CurrCard->tagQ_Lst = lastTag;
29601da177e4SLinus Torvalds 				currTar_Info->LunDiscQ_Idx[lun] = lastTag;
29611da177e4SLinus Torvalds 				CurrCard->discQ_Tbl[lastTag] = currSCCB;
29621da177e4SLinus Torvalds 				CurrCard->discQCount++;
29631da177e4SLinus Torvalds 				break;
29641da177e4SLinus Torvalds 			}
29651da177e4SLinus Torvalds 		}
29661da177e4SLinus Torvalds 		if(i == QUEUE_DEPTH)
29671da177e4SLinus Torvalds 		{
2968*47b5d69cSJames Bottomley  			currTar_Info->TarLUNBusy[lun] = 1;
2969*47b5d69cSJames Bottomley  			FPT_queueSelectFail(CurrCard,p_card);
29701da177e4SLinus Torvalds 			SGRAM_ACCESS(port);
29711da177e4SLinus Torvalds 			return;
29721da177e4SLinus Torvalds 		}
29731da177e4SLinus Torvalds 	}
29741da177e4SLinus Torvalds 
29751da177e4SLinus Torvalds 
29761da177e4SLinus Torvalds 
2977*47b5d69cSJames Bottomley     auto_loaded = 0;
29781da177e4SLinus Torvalds 
29791da177e4SLinus Torvalds    WR_HARPOON(port+hp_select_id, target);
29801da177e4SLinus Torvalds    WR_HARPOON(port+hp_gp_reg_3, target);  /* Use by new automation logic */
29811da177e4SLinus Torvalds 
29821da177e4SLinus Torvalds    if (currSCCB->OperationCode == RESET_COMMAND) {
29831da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
29841da177e4SLinus Torvalds                	 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
29851da177e4SLinus Torvalds 
29861da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
29871da177e4SLinus Torvalds 
29881da177e4SLinus Torvalds       currSCCB->Sccb_scsimsg = SMDEV_RESET;
29891da177e4SLinus Torvalds 
29901da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2991*47b5d69cSJames Bottomley        auto_loaded = 1;
29921da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = SELECT_BDR_ST;
29931da177e4SLinus Torvalds 
29941da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
29951da177e4SLinus Torvalds          {
29961da177e4SLinus Torvalds 	       currTar_Info->TarSyncCtrl = 0;
29971da177e4SLinus Torvalds 	      currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
29981da177e4SLinus Torvalds 	      }
29991da177e4SLinus Torvalds 
30001da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
30011da177e4SLinus Torvalds          {
30021da177e4SLinus Torvalds       	currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
30031da177e4SLinus Torvalds       	}
30041da177e4SLinus Torvalds 
3005*47b5d69cSJames Bottomley        FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
3006*47b5d69cSJames Bottomley        FPT_SccbMgrTableInitTarget(p_card, target);
30071da177e4SLinus Torvalds 
30081da177e4SLinus Torvalds       }
30091da177e4SLinus Torvalds 
30101da177e4SLinus Torvalds 		else if(currSCCB->Sccb_scsistat == ABORT_ST)
30111da177e4SLinus Torvalds 		{
30121da177e4SLinus Torvalds 			WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
30131da177e4SLinus Torvalds 								(currSCCB->Sccb_idmsg & ~DISC_PRIV)));
30141da177e4SLinus Torvalds 
30151da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
30161da177e4SLinus Torvalds 
30171da177e4SLinus Torvalds 			WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
30181da177e4SLinus Torvalds 								(((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
30191da177e4SLinus Torvalds 								>> 6) | (UCHAR)0x20)));
30201da177e4SLinus Torvalds 			WRW_HARPOON((port+SYNC_MSGS+2),
30211da177e4SLinus Torvalds 							(MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
30221da177e4SLinus Torvalds 			WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
30231da177e4SLinus Torvalds 
30241da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3025*47b5d69cSJames Bottomley  			auto_loaded = 1;
30261da177e4SLinus Torvalds 
30271da177e4SLinus Torvalds 		}
30281da177e4SLinus Torvalds 
30291da177e4SLinus Torvalds    else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED))  {
3030*47b5d69cSJames Bottomley        auto_loaded = FPT_siwidn(port,p_card);
30311da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = SELECT_WN_ST;
30321da177e4SLinus Torvalds       }
30331da177e4SLinus Torvalds 
30341da177e4SLinus Torvalds    else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
30351da177e4SLinus Torvalds       == SYNC_SUPPORTED))  {
3036*47b5d69cSJames Bottomley        auto_loaded = FPT_sisyncn(port,p_card, 0);
30371da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = SELECT_SN_ST;
30381da177e4SLinus Torvalds       }
30391da177e4SLinus Torvalds 
30401da177e4SLinus Torvalds 
30411da177e4SLinus Torvalds    if (!auto_loaded)
30421da177e4SLinus Torvalds       {
30431da177e4SLinus Torvalds 
30441da177e4SLinus Torvalds       if (currSCCB->ControlByte & F_USE_CMD_Q)
30451da177e4SLinus Torvalds          {
30461da177e4SLinus Torvalds 
30471da177e4SLinus Torvalds          CurrCard->globalFlags |= F_TAG_STARTED;
30481da177e4SLinus Torvalds 
30491da177e4SLinus Torvalds          if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
30501da177e4SLinus Torvalds             == TAG_Q_REJECT)
30511da177e4SLinus Torvalds             {
30521da177e4SLinus Torvalds             currSCCB->ControlByte &= ~F_USE_CMD_Q;
30531da177e4SLinus Torvalds 
30541da177e4SLinus Torvalds             /* Fix up the start instruction with a jump to
30551da177e4SLinus Torvalds                Non-Tag-CMD handling */
30561da177e4SLinus Torvalds             WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
30571da177e4SLinus Torvalds 
30581da177e4SLinus Torvalds             WRW_HARPOON((port+NON_TAG_ID_MSG),
30591da177e4SLinus Torvalds 	                     (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
30601da177e4SLinus Torvalds 
30611da177e4SLinus Torvalds 	         WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
30621da177e4SLinus Torvalds 
30631da177e4SLinus Torvalds 	         /* Setup our STATE so we know what happend when
30641da177e4SLinus Torvalds                the wheels fall off. */
30651da177e4SLinus Torvalds             currSCCB->Sccb_scsistat = SELECT_ST;
30661da177e4SLinus Torvalds 
3067*47b5d69cSJames Bottomley  	         currTar_Info->TarLUNBusy[lun] = 1;
30681da177e4SLinus Torvalds             }
30691da177e4SLinus Torvalds 
30701da177e4SLinus Torvalds          else
30711da177e4SLinus Torvalds             {
30721da177e4SLinus Torvalds             WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
30731da177e4SLinus Torvalds 
30741da177e4SLinus Torvalds             WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
30751da177e4SLinus Torvalds                         (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
30761da177e4SLinus Torvalds                         >> 6) | (UCHAR)0x20)));
30771da177e4SLinus Torvalds 
30781da177e4SLinus Torvalds 				for (i = 1; i < QUEUE_DEPTH; i++)
30791da177e4SLinus Torvalds 				{
30801da177e4SLinus Torvalds 					if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
30811da177e4SLinus Torvalds 					if (CurrCard->discQ_Tbl[lastTag] == NULL)
30821da177e4SLinus Torvalds 					{
30831da177e4SLinus Torvalds 						WRW_HARPOON((port+ID_MSG_STRT+6),
30841da177e4SLinus Torvalds 							(MPM_OP+AMSG_OUT+lastTag));
30851da177e4SLinus Torvalds 						CurrCard->tagQ_Lst = lastTag;
30861da177e4SLinus Torvalds 						currSCCB->Sccb_tag = lastTag;
30871da177e4SLinus Torvalds 						CurrCard->discQ_Tbl[lastTag] = currSCCB;
30881da177e4SLinus Torvalds 						CurrCard->discQCount++;
30891da177e4SLinus Torvalds 						break;
30901da177e4SLinus Torvalds 					}
30911da177e4SLinus Torvalds 				}
30921da177e4SLinus Torvalds 
30931da177e4SLinus Torvalds 
30941da177e4SLinus Torvalds             if ( i == QUEUE_DEPTH )
30951da177e4SLinus Torvalds                {
3096*47b5d69cSJames Bottomley     	         currTar_Info->TarLUNBusy[lun] = 1;
3097*47b5d69cSJames Bottomley                 FPT_queueSelectFail(CurrCard,p_card);
30981da177e4SLinus Torvalds 				   SGRAM_ACCESS(port);
30991da177e4SLinus Torvalds    	         return;
31001da177e4SLinus Torvalds    	         }
31011da177e4SLinus Torvalds 
31021da177e4SLinus Torvalds             currSCCB->Sccb_scsistat = SELECT_Q_ST;
31031da177e4SLinus Torvalds 
31041da177e4SLinus Torvalds    	      WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
31051da177e4SLinus Torvalds             }
31061da177e4SLinus Torvalds          }
31071da177e4SLinus Torvalds 
31081da177e4SLinus Torvalds       else
31091da177e4SLinus Torvalds          {
31101da177e4SLinus Torvalds 
31111da177e4SLinus Torvalds          WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
31121da177e4SLinus Torvalds 
31131da177e4SLinus Torvalds       	WRW_HARPOON((port+NON_TAG_ID_MSG),
31141da177e4SLinus Torvalds             (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
31151da177e4SLinus Torvalds 
31161da177e4SLinus Torvalds          currSCCB->Sccb_scsistat = SELECT_ST;
31171da177e4SLinus Torvalds 
31181da177e4SLinus Torvalds          WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
31191da177e4SLinus Torvalds          }
31201da177e4SLinus Torvalds 
31211da177e4SLinus Torvalds 
31221da177e4SLinus Torvalds       theCCB = (UCHAR *)&currSCCB->Cdb[0];
31231da177e4SLinus Torvalds 
31241da177e4SLinus Torvalds       cdb_reg = port + CMD_STRT;
31251da177e4SLinus Torvalds 
31261da177e4SLinus Torvalds       for (i=0; i < currSCCB->CdbLength; i++)
31271da177e4SLinus Torvalds          {
31281da177e4SLinus Torvalds          WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
31291da177e4SLinus Torvalds          cdb_reg +=2;
31301da177e4SLinus Torvalds          theCCB++;
31311da177e4SLinus Torvalds          }
31321da177e4SLinus Torvalds 
31331da177e4SLinus Torvalds       if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
31341da177e4SLinus Torvalds          WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+    NP));
31351da177e4SLinus Torvalds 
31361da177e4SLinus Torvalds       }  /* auto_loaded */
31371da177e4SLinus Torvalds 
31381da177e4SLinus Torvalds    WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
31391da177e4SLinus Torvalds    WR_HARPOON(port+hp_xferstat, 0x00);
31401da177e4SLinus Torvalds 
31411da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
31421da177e4SLinus Torvalds 
31431da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
31441da177e4SLinus Torvalds 
31451da177e4SLinus Torvalds 
31461da177e4SLinus Torvalds    if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
31471da177e4SLinus Torvalds       {
31481da177e4SLinus Torvalds       WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
31491da177e4SLinus Torvalds       }
31501da177e4SLinus Torvalds    else
31511da177e4SLinus Torvalds       {
31521da177e4SLinus Torvalds 
31531da177e4SLinus Torvalds /*      auto_loaded =  (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
31541da177e4SLinus Torvalds       auto_loaded |= AUTO_IMMED; */
31551da177e4SLinus Torvalds       auto_loaded = AUTO_IMMED;
31561da177e4SLinus Torvalds 
31571da177e4SLinus Torvalds       DISABLE_AUTO(port);
31581da177e4SLinus Torvalds 
31591da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_3, auto_loaded);
31601da177e4SLinus Torvalds       }
31611da177e4SLinus Torvalds 
31621da177e4SLinus Torvalds    SGRAM_ACCESS(port);
31631da177e4SLinus Torvalds }
31641da177e4SLinus Torvalds 
31651da177e4SLinus Torvalds 
31661da177e4SLinus Torvalds /*---------------------------------------------------------------------
31671da177e4SLinus Torvalds  *
3168*47b5d69cSJames Bottomley   * Function: FPT_sres
31691da177e4SLinus Torvalds  *
31701da177e4SLinus Torvalds  * Description: Hookup the correct CCB and handle the incoming messages.
31711da177e4SLinus Torvalds  *
31721da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
31731da177e4SLinus Torvalds 
3174*47b5d69cSJames Bottomley  static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
31751da177e4SLinus Torvalds {
31761da177e4SLinus Torvalds 
31771da177e4SLinus Torvalds    UCHAR our_target, message, lun = 0, tag, msgRetryCount;
31781da177e4SLinus Torvalds 
31791da177e4SLinus Torvalds 
31801da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
31811da177e4SLinus Torvalds 	PSCCB currSCCB;
31821da177e4SLinus Torvalds 
31831da177e4SLinus Torvalds 
31841da177e4SLinus Torvalds 
31851da177e4SLinus Torvalds 
31861da177e4SLinus Torvalds 	if(pCurrCard->currentSCCB != NULL)
31871da177e4SLinus Torvalds 	{
3188*47b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
31891da177e4SLinus Torvalds 		DISABLE_AUTO(port);
31901da177e4SLinus Torvalds 
31911da177e4SLinus Torvalds 
31921da177e4SLinus Torvalds 		WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
31931da177e4SLinus Torvalds 
31941da177e4SLinus Torvalds 
31951da177e4SLinus Torvalds 		currSCCB = pCurrCard->currentSCCB;
31961da177e4SLinus Torvalds 		if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
31971da177e4SLinus Torvalds 		{
31981da177e4SLinus Torvalds 			currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
31991da177e4SLinus Torvalds 			currSCCB->Sccb_scsistat = BUS_FREE_ST;
32001da177e4SLinus Torvalds 		}
32011da177e4SLinus Torvalds 		if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
32021da177e4SLinus Torvalds 		{
32031da177e4SLinus Torvalds 			currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
32041da177e4SLinus Torvalds 			currSCCB->Sccb_scsistat = BUS_FREE_ST;
32051da177e4SLinus Torvalds 		}
32061da177e4SLinus Torvalds 		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
32071da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
32081da177e4SLinus Torvalds 		{
3209*47b5d69cSJames Bottomley        	currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
32101da177e4SLinus Torvalds 			if(currSCCB->Sccb_scsistat != ABORT_ST)
32111da177e4SLinus Torvalds 			{
32121da177e4SLinus Torvalds 				pCurrCard->discQCount--;
32131da177e4SLinus Torvalds 				pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
32141da177e4SLinus Torvalds 													= NULL;
32151da177e4SLinus Torvalds 			}
32161da177e4SLinus Torvalds 		}
32171da177e4SLinus Torvalds 		else
32181da177e4SLinus Torvalds 		{
3219*47b5d69cSJames Bottomley  	      currTar_Info->TarLUNBusy[0] = 0;
32201da177e4SLinus Torvalds 			if(currSCCB->Sccb_tag)
32211da177e4SLinus Torvalds 			{
32221da177e4SLinus Torvalds 				if(currSCCB->Sccb_scsistat != ABORT_ST)
32231da177e4SLinus Torvalds 				{
32241da177e4SLinus Torvalds 					pCurrCard->discQCount--;
32251da177e4SLinus Torvalds 					pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
32261da177e4SLinus Torvalds 				}
32271da177e4SLinus Torvalds 			}else
32281da177e4SLinus Torvalds 			{
32291da177e4SLinus Torvalds 				if(currSCCB->Sccb_scsistat != ABORT_ST)
32301da177e4SLinus Torvalds 				{
32311da177e4SLinus Torvalds 					pCurrCard->discQCount--;
32321da177e4SLinus Torvalds 					pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
32331da177e4SLinus Torvalds 				}
32341da177e4SLinus Torvalds 			}
32351da177e4SLinus Torvalds 		}
32361da177e4SLinus Torvalds 
3237*47b5d69cSJames Bottomley        FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
32381da177e4SLinus Torvalds 	}
32391da177e4SLinus Torvalds 
32401da177e4SLinus Torvalds 	WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
32411da177e4SLinus Torvalds 
32421da177e4SLinus Torvalds 
32431da177e4SLinus Torvalds 	our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
3244*47b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
32451da177e4SLinus Torvalds 
32461da177e4SLinus Torvalds 
32471da177e4SLinus Torvalds 	msgRetryCount = 0;
32481da177e4SLinus Torvalds 	do
32491da177e4SLinus Torvalds 	{
32501da177e4SLinus Torvalds 
3251*47b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
32521da177e4SLinus Torvalds 		tag = 0;
32531da177e4SLinus Torvalds 
32541da177e4SLinus Torvalds 
32551da177e4SLinus Torvalds 		while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
32561da177e4SLinus Torvalds 		{
32571da177e4SLinus Torvalds 			if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
32581da177e4SLinus Torvalds 			{
32591da177e4SLinus Torvalds 
32601da177e4SLinus Torvalds 				WRW_HARPOON((port+hp_intstat), PHASE);
32611da177e4SLinus Torvalds 				return;
32621da177e4SLinus Torvalds 			}
32631da177e4SLinus Torvalds 		}
32641da177e4SLinus Torvalds 
32651da177e4SLinus Torvalds 		WRW_HARPOON((port+hp_intstat), PHASE);
32661da177e4SLinus Torvalds 		if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
32671da177e4SLinus Torvalds 		{
32681da177e4SLinus Torvalds 
3269*47b5d69cSJames Bottomley  			message = FPT_sfm(port,pCurrCard->currentSCCB);
32701da177e4SLinus Torvalds 			if (message)
32711da177e4SLinus Torvalds 			{
32721da177e4SLinus Torvalds 
32731da177e4SLinus Torvalds 				if (message <= (0x80 | LUN_MASK))
32741da177e4SLinus Torvalds 				{
32751da177e4SLinus Torvalds 					lun = message & (UCHAR)LUN_MASK;
32761da177e4SLinus Torvalds 
32771da177e4SLinus Torvalds 					if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
32781da177e4SLinus Torvalds 					{
32791da177e4SLinus Torvalds 						if (currTar_Info->TarTagQ_Cnt != 0)
32801da177e4SLinus Torvalds 						{
32811da177e4SLinus Torvalds 
32821da177e4SLinus Torvalds 							if (!(currTar_Info->TarLUN_CA))
32831da177e4SLinus Torvalds 							{
32841da177e4SLinus Torvalds 								ACCEPT_MSG(port);    /*Release the ACK for ID msg. */
32851da177e4SLinus Torvalds 
32861da177e4SLinus Torvalds 
3287*47b5d69cSJames Bottomley  								message = FPT_sfm(port,pCurrCard->currentSCCB);
32881da177e4SLinus Torvalds 								if (message)
32891da177e4SLinus Torvalds 								{
32901da177e4SLinus Torvalds 									ACCEPT_MSG(port);
32911da177e4SLinus Torvalds 								}
32921da177e4SLinus Torvalds 
32931da177e4SLinus Torvalds 								else
3294*47b5d69cSJames Bottomley     								message = 0;
32951da177e4SLinus Torvalds 
3296*47b5d69cSJames Bottomley  								if(message != 0)
32971da177e4SLinus Torvalds 								{
3298*47b5d69cSJames Bottomley  									tag = FPT_sfm(port,pCurrCard->currentSCCB);
32991da177e4SLinus Torvalds 
33001da177e4SLinus Torvalds 									if (!(tag))
3301*47b5d69cSJames Bottomley  										message = 0;
33021da177e4SLinus Torvalds 								}
33031da177e4SLinus Torvalds 
33041da177e4SLinus Torvalds 							} /*C.A. exists! */
33051da177e4SLinus Torvalds 
33061da177e4SLinus Torvalds 						} /*End Q cnt != 0 */
33071da177e4SLinus Torvalds 
33081da177e4SLinus Torvalds 					} /*End Tag cmds supported! */
33091da177e4SLinus Torvalds 
33101da177e4SLinus Torvalds 				} /*End valid ID message.  */
33111da177e4SLinus Torvalds 
33121da177e4SLinus Torvalds 				else
33131da177e4SLinus Torvalds 				{
33141da177e4SLinus Torvalds 
33151da177e4SLinus Torvalds 					ACCEPT_MSG_ATN(port);
33161da177e4SLinus Torvalds 				}
33171da177e4SLinus Torvalds 
33181da177e4SLinus Torvalds 			} /* End good id message. */
33191da177e4SLinus Torvalds 
33201da177e4SLinus Torvalds 			else
33211da177e4SLinus Torvalds 			{
33221da177e4SLinus Torvalds 
3323*47b5d69cSJames Bottomley  				message = 0;
33241da177e4SLinus Torvalds 			}
33251da177e4SLinus Torvalds 		}
33261da177e4SLinus Torvalds 		else
33271da177e4SLinus Torvalds 		{
33281da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
33291da177e4SLinus Torvalds 
33301da177e4SLinus Torvalds 		   while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
33311da177e4SLinus Torvalds 			  !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
33321da177e4SLinus Torvalds 			  (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
33331da177e4SLinus Torvalds 
33341da177e4SLinus Torvalds 			return;
33351da177e4SLinus Torvalds 		}
33361da177e4SLinus Torvalds 
3337*47b5d69cSJames Bottomley  		if(message == 0)
33381da177e4SLinus Torvalds 		{
33391da177e4SLinus Torvalds 			msgRetryCount++;
33401da177e4SLinus Torvalds 			if(msgRetryCount == 1)
33411da177e4SLinus Torvalds 			{
3342*47b5d69cSJames Bottomley  				FPT_SendMsg(port, SMPARITY);
33431da177e4SLinus Torvalds 			}
33441da177e4SLinus Torvalds 			else
33451da177e4SLinus Torvalds 			{
3346*47b5d69cSJames Bottomley  				FPT_SendMsg(port, SMDEV_RESET);
33471da177e4SLinus Torvalds 
3348*47b5d69cSJames Bottomley  				FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
33491da177e4SLinus Torvalds 
3350*47b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
33511da177e4SLinus Torvalds 				{
33521da177e4SLinus Torvalds 
3353*47b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
33541da177e4SLinus Torvalds 
33551da177e4SLinus Torvalds 				}
33561da177e4SLinus Torvalds 
3357*47b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
33581da177e4SLinus Torvalds 				{
33591da177e4SLinus Torvalds 
3360*47b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
33611da177e4SLinus Torvalds 				}
33621da177e4SLinus Torvalds 
33631da177e4SLinus Torvalds 
3364*47b5d69cSJames Bottomley  				FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3365*47b5d69cSJames Bottomley  				FPT_SccbMgrTableInitTarget(p_card,our_target);
33661da177e4SLinus Torvalds 				return;
33671da177e4SLinus Torvalds 			}
33681da177e4SLinus Torvalds 		}
3369*47b5d69cSJames Bottomley  	}while(message == 0);
33701da177e4SLinus Torvalds 
33711da177e4SLinus Torvalds 
33721da177e4SLinus Torvalds 
33731da177e4SLinus Torvalds 	if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
33741da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
33751da177e4SLinus Torvalds 	{
3376*47b5d69cSJames Bottomley  		currTar_Info->TarLUNBusy[lun] = 1;
33771da177e4SLinus Torvalds 		pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
33781da177e4SLinus Torvalds 		if(pCurrCard->currentSCCB != NULL)
33791da177e4SLinus Torvalds 		{
33801da177e4SLinus Torvalds 			ACCEPT_MSG(port);
33811da177e4SLinus Torvalds 		}
33821da177e4SLinus Torvalds 		else
33831da177e4SLinus Torvalds 		{
33841da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
33851da177e4SLinus Torvalds 		}
33861da177e4SLinus Torvalds 	}
33871da177e4SLinus Torvalds 	else
33881da177e4SLinus Torvalds 	{
3389*47b5d69cSJames Bottomley  		currTar_Info->TarLUNBusy[0] = 1;
33901da177e4SLinus Torvalds 
33911da177e4SLinus Torvalds 
33921da177e4SLinus Torvalds 		if (tag)
33931da177e4SLinus Torvalds 		{
33941da177e4SLinus Torvalds 			if (pCurrCard->discQ_Tbl[tag] != NULL)
33951da177e4SLinus Torvalds 			{
33961da177e4SLinus Torvalds 				pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
33971da177e4SLinus Torvalds 		 		currTar_Info->TarTagQ_Cnt--;
33981da177e4SLinus Torvalds 				ACCEPT_MSG(port);
33991da177e4SLinus Torvalds 			}
34001da177e4SLinus Torvalds 			else
34011da177e4SLinus Torvalds 			{
34021da177e4SLinus Torvalds 			ACCEPT_MSG_ATN(port);
34031da177e4SLinus Torvalds 			}
34041da177e4SLinus Torvalds 		}else
34051da177e4SLinus Torvalds 		{
34061da177e4SLinus Torvalds 			pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
34071da177e4SLinus Torvalds 			if(pCurrCard->currentSCCB != NULL)
34081da177e4SLinus Torvalds 			{
34091da177e4SLinus Torvalds 				ACCEPT_MSG(port);
34101da177e4SLinus Torvalds 			}
34111da177e4SLinus Torvalds 			else
34121da177e4SLinus Torvalds 			{
34131da177e4SLinus Torvalds 				ACCEPT_MSG_ATN(port);
34141da177e4SLinus Torvalds 			}
34151da177e4SLinus Torvalds 		}
34161da177e4SLinus Torvalds 	}
34171da177e4SLinus Torvalds 
34181da177e4SLinus Torvalds 	if(pCurrCard->currentSCCB != NULL)
34191da177e4SLinus Torvalds 	{
34201da177e4SLinus Torvalds 		if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
34211da177e4SLinus Torvalds 		{
34221da177e4SLinus Torvalds 		/* During Abort Tag command, the target could have got re-selected
34231da177e4SLinus Torvalds 			and completed the command. Check the select Q and remove the CCB
34241da177e4SLinus Torvalds 			if it is in the Select Q */
3425*47b5d69cSJames Bottomley  			FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
34261da177e4SLinus Torvalds 		}
34271da177e4SLinus Torvalds 	}
34281da177e4SLinus Torvalds 
34291da177e4SLinus Torvalds 
34301da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
34311da177e4SLinus Torvalds 	  !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
34321da177e4SLinus Torvalds 	  (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
34331da177e4SLinus Torvalds }
34341da177e4SLinus Torvalds 
3435*47b5d69cSJames Bottomley  static void FPT_SendMsg(ULONG port, UCHAR message)
34361da177e4SLinus Torvalds {
34371da177e4SLinus Torvalds 	while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
34381da177e4SLinus Torvalds 	{
34391da177e4SLinus Torvalds 		if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
34401da177e4SLinus Torvalds 		{
34411da177e4SLinus Torvalds 
34421da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), PHASE);
34431da177e4SLinus Torvalds 			return;
34441da177e4SLinus Torvalds 		}
34451da177e4SLinus Torvalds 	}
34461da177e4SLinus Torvalds 
34471da177e4SLinus Torvalds 	WRW_HARPOON((port+hp_intstat), PHASE);
34481da177e4SLinus Torvalds 	if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
34491da177e4SLinus Torvalds 	{
34501da177e4SLinus Torvalds 		WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
34511da177e4SLinus Torvalds 
34521da177e4SLinus Torvalds 
34531da177e4SLinus Torvalds 		WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
34541da177e4SLinus Torvalds 
34551da177e4SLinus Torvalds 		WR_HARPOON(port+hp_scsidata_0,message);
34561da177e4SLinus Torvalds 
34571da177e4SLinus Torvalds 		WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
34581da177e4SLinus Torvalds 
34591da177e4SLinus Torvalds 		ACCEPT_MSG(port);
34601da177e4SLinus Torvalds 
34611da177e4SLinus Torvalds 		WR_HARPOON(port+hp_portctrl_0, 0x00);
34621da177e4SLinus Torvalds 
34631da177e4SLinus Torvalds 		if ((message == SMABORT) || (message == SMDEV_RESET) ||
34641da177e4SLinus Torvalds 				(message == SMABORT_TAG) )
34651da177e4SLinus Torvalds 		{
34661da177e4SLinus Torvalds 			while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
34671da177e4SLinus Torvalds 
34681da177e4SLinus Torvalds 			if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
34691da177e4SLinus Torvalds 			{
34701da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), BUS_FREE);
34711da177e4SLinus Torvalds 			}
34721da177e4SLinus Torvalds 		}
34731da177e4SLinus Torvalds 	}
34741da177e4SLinus Torvalds }
34751da177e4SLinus Torvalds 
34761da177e4SLinus Torvalds /*---------------------------------------------------------------------
34771da177e4SLinus Torvalds  *
3478*47b5d69cSJames Bottomley   * Function: FPT_sdecm
34791da177e4SLinus Torvalds  *
34801da177e4SLinus Torvalds  * Description: Determine the proper responce to the message from the
34811da177e4SLinus Torvalds  *              target device.
34821da177e4SLinus Torvalds  *
34831da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
3484*47b5d69cSJames Bottomley  static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
34851da177e4SLinus Torvalds {
34861da177e4SLinus Torvalds 	PSCCB currSCCB;
34871da177e4SLinus Torvalds 	PSCCBcard CurrCard;
34881da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
34891da177e4SLinus Torvalds 
3490*47b5d69cSJames Bottomley  	CurrCard = &FPT_BL_Card[p_card];
34911da177e4SLinus Torvalds 	currSCCB = CurrCard->currentSCCB;
34921da177e4SLinus Torvalds 
3493*47b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
34941da177e4SLinus Torvalds 
34951da177e4SLinus Torvalds 	if (message == SMREST_DATA_PTR)
34961da177e4SLinus Torvalds 	{
34971da177e4SLinus Torvalds 		if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
34981da177e4SLinus Torvalds 		{
34991da177e4SLinus Torvalds 			currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
35001da177e4SLinus Torvalds 
3501*47b5d69cSJames Bottomley  			FPT_hostDataXferRestart(currSCCB);
35021da177e4SLinus Torvalds 		}
35031da177e4SLinus Torvalds 
35041da177e4SLinus Torvalds 		ACCEPT_MSG(port);
35051da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
35061da177e4SLinus Torvalds 	}
35071da177e4SLinus Torvalds 
35081da177e4SLinus Torvalds 	else if (message == SMCMD_COMP)
35091da177e4SLinus Torvalds 	{
35101da177e4SLinus Torvalds 
35111da177e4SLinus Torvalds 
35121da177e4SLinus Torvalds 		if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
35131da177e4SLinus Torvalds 		{
35141da177e4SLinus Torvalds 			currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
35151da177e4SLinus Torvalds 			currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
35161da177e4SLinus Torvalds 		}
35171da177e4SLinus Torvalds 
35181da177e4SLinus Torvalds 		ACCEPT_MSG(port);
35191da177e4SLinus Torvalds 
35201da177e4SLinus Torvalds 	}
35211da177e4SLinus Torvalds 
35221da177e4SLinus Torvalds 	else if ((message == SMNO_OP) || (message >= SMIDENT)
35231da177e4SLinus Torvalds 			|| (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
35241da177e4SLinus Torvalds 	{
35251da177e4SLinus Torvalds 
35261da177e4SLinus Torvalds 		ACCEPT_MSG(port);
35271da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
35281da177e4SLinus Torvalds 	}
35291da177e4SLinus Torvalds 
35301da177e4SLinus Torvalds 	else if (message == SMREJECT)
35311da177e4SLinus Torvalds 	{
35321da177e4SLinus Torvalds 
35331da177e4SLinus Torvalds 		if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
35341da177e4SLinus Torvalds 				(currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
35351da177e4SLinus Torvalds 				((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
35361da177e4SLinus Torvalds 				((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
35371da177e4SLinus Torvalds 
35381da177e4SLinus Torvalds 		{
35391da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), BUS_FREE);
35401da177e4SLinus Torvalds 
35411da177e4SLinus Torvalds 			ACCEPT_MSG(port);
35421da177e4SLinus Torvalds 
35431da177e4SLinus Torvalds 
35441da177e4SLinus Torvalds 			while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
35451da177e4SLinus Torvalds 				(!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
35461da177e4SLinus Torvalds 
35471da177e4SLinus Torvalds 			if(currSCCB->Lun == 0x00)
35481da177e4SLinus Torvalds 			{
35491da177e4SLinus Torvalds 				if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
35501da177e4SLinus Torvalds 				{
35511da177e4SLinus Torvalds 
35521da177e4SLinus Torvalds 					currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
35531da177e4SLinus Torvalds 
35541da177e4SLinus Torvalds 					currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
35551da177e4SLinus Torvalds 				}
35561da177e4SLinus Torvalds 
35571da177e4SLinus Torvalds 				else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
35581da177e4SLinus Torvalds 				{
35591da177e4SLinus Torvalds 
35601da177e4SLinus Torvalds 
35611da177e4SLinus Torvalds 					currTar_Info->TarStatus = (currTar_Info->TarStatus &
35621da177e4SLinus Torvalds 													~WIDE_ENABLED) | WIDE_NEGOCIATED;
35631da177e4SLinus Torvalds 
35641da177e4SLinus Torvalds 					currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
35651da177e4SLinus Torvalds 
35661da177e4SLinus Torvalds 				}
35671da177e4SLinus Torvalds 
35681da177e4SLinus Torvalds 				else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
35691da177e4SLinus Torvalds 				{
35701da177e4SLinus Torvalds 					currTar_Info->TarStatus = (currTar_Info->TarStatus &
35711da177e4SLinus Torvalds 													~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
35721da177e4SLinus Torvalds 
35731da177e4SLinus Torvalds 
35741da177e4SLinus Torvalds 					currSCCB->ControlByte &= ~F_USE_CMD_Q;
35751da177e4SLinus Torvalds 					CurrCard->discQCount--;
35761da177e4SLinus Torvalds 					CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
35771da177e4SLinus Torvalds 					currSCCB->Sccb_tag = 0x00;
35781da177e4SLinus Torvalds 
35791da177e4SLinus Torvalds 				}
35801da177e4SLinus Torvalds 			}
35811da177e4SLinus Torvalds 
35821da177e4SLinus Torvalds 			if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
35831da177e4SLinus Torvalds 			{
35841da177e4SLinus Torvalds 
35851da177e4SLinus Torvalds 
35861da177e4SLinus Torvalds 				if(currSCCB->Lun == 0x00)
35871da177e4SLinus Torvalds 				{
35881da177e4SLinus Torvalds 					WRW_HARPOON((port+hp_intstat), BUS_FREE);
35891da177e4SLinus Torvalds 					CurrCard->globalFlags |= F_NEW_SCCB_CMD;
35901da177e4SLinus Torvalds 				}
35911da177e4SLinus Torvalds 			}
35921da177e4SLinus Torvalds 
35931da177e4SLinus Torvalds 			else
35941da177e4SLinus Torvalds 			{
35951da177e4SLinus Torvalds 
35961da177e4SLinus Torvalds 				if((CurrCard->globalFlags & F_CONLUN_IO) &&
35971da177e4SLinus Torvalds 					((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3598*47b5d69cSJames Bottomley  					currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
35991da177e4SLinus Torvalds 				else
3600*47b5d69cSJames Bottomley  					currTar_Info->TarLUNBusy[0] = 1;
36011da177e4SLinus Torvalds 
36021da177e4SLinus Torvalds 
36031da177e4SLinus Torvalds 				currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
36041da177e4SLinus Torvalds 
36051da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
36061da177e4SLinus Torvalds 
36071da177e4SLinus Torvalds 			}
36081da177e4SLinus Torvalds 		}
36091da177e4SLinus Torvalds 
36101da177e4SLinus Torvalds 		else
36111da177e4SLinus Torvalds 		{
36121da177e4SLinus Torvalds 			ACCEPT_MSG(port);
36131da177e4SLinus Torvalds 
36141da177e4SLinus Torvalds 			while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
36151da177e4SLinus Torvalds 				(!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
36161da177e4SLinus Torvalds 
36171da177e4SLinus Torvalds 			if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
36181da177e4SLinus Torvalds 			{
36191da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
36201da177e4SLinus Torvalds 			}
36211da177e4SLinus Torvalds 		}
36221da177e4SLinus Torvalds 	}
36231da177e4SLinus Torvalds 
36241da177e4SLinus Torvalds 	else if (message == SMEXT)
36251da177e4SLinus Torvalds 	{
36261da177e4SLinus Torvalds 
36271da177e4SLinus Torvalds 		ACCEPT_MSG(port);
3628*47b5d69cSJames Bottomley  		FPT_shandem(port,p_card,currSCCB);
36291da177e4SLinus Torvalds 	}
36301da177e4SLinus Torvalds 
36311da177e4SLinus Torvalds 	else if (message == SMIGNORWR)
36321da177e4SLinus Torvalds 	{
36331da177e4SLinus Torvalds 
36341da177e4SLinus Torvalds 		ACCEPT_MSG(port);          /* ACK the RESIDUE MSG */
36351da177e4SLinus Torvalds 
3636*47b5d69cSJames Bottomley  		message = FPT_sfm(port,currSCCB);
36371da177e4SLinus Torvalds 
36381da177e4SLinus Torvalds 		if(currSCCB->Sccb_scsimsg != SMPARITY)
36391da177e4SLinus Torvalds 			ACCEPT_MSG(port);
36401da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
36411da177e4SLinus Torvalds 	}
36421da177e4SLinus Torvalds 
36431da177e4SLinus Torvalds 
36441da177e4SLinus Torvalds 	else
36451da177e4SLinus Torvalds 	{
36461da177e4SLinus Torvalds 
36471da177e4SLinus Torvalds 		currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
36481da177e4SLinus Torvalds 		currSCCB->Sccb_scsimsg = SMREJECT;
36491da177e4SLinus Torvalds 
36501da177e4SLinus Torvalds 		ACCEPT_MSG_ATN(port);
36511da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
36521da177e4SLinus Torvalds 	}
36531da177e4SLinus Torvalds }
36541da177e4SLinus Torvalds 
36551da177e4SLinus Torvalds 
36561da177e4SLinus Torvalds /*---------------------------------------------------------------------
36571da177e4SLinus Torvalds  *
3658*47b5d69cSJames Bottomley   * Function: FPT_shandem
36591da177e4SLinus Torvalds  *
36601da177e4SLinus Torvalds  * Description: Decide what to do with the extended message.
36611da177e4SLinus Torvalds  *
36621da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
3663*47b5d69cSJames Bottomley  static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
36641da177e4SLinus Torvalds {
36651da177e4SLinus Torvalds 	UCHAR length,message;
36661da177e4SLinus Torvalds 
3667*47b5d69cSJames Bottomley  	length = FPT_sfm(port,pCurrSCCB);
36681da177e4SLinus Torvalds 	if (length)
36691da177e4SLinus Torvalds 	{
36701da177e4SLinus Torvalds 
36711da177e4SLinus Torvalds 		ACCEPT_MSG(port);
3672*47b5d69cSJames Bottomley  		message = FPT_sfm(port,pCurrSCCB);
36731da177e4SLinus Torvalds 		if (message)
36741da177e4SLinus Torvalds 		{
36751da177e4SLinus Torvalds 
36761da177e4SLinus Torvalds 			if (message == SMSYNC)
36771da177e4SLinus Torvalds 			{
36781da177e4SLinus Torvalds 
36791da177e4SLinus Torvalds 				if (length == 0x03)
36801da177e4SLinus Torvalds 				{
36811da177e4SLinus Torvalds 
36821da177e4SLinus Torvalds 					ACCEPT_MSG(port);
3683*47b5d69cSJames Bottomley  					FPT_stsyncn(port,p_card);
36841da177e4SLinus Torvalds 				}
36851da177e4SLinus Torvalds 				else
36861da177e4SLinus Torvalds 				{
36871da177e4SLinus Torvalds 
36881da177e4SLinus Torvalds 					pCurrSCCB->Sccb_scsimsg = SMREJECT;
36891da177e4SLinus Torvalds 					ACCEPT_MSG_ATN(port);
36901da177e4SLinus Torvalds 				}
36911da177e4SLinus Torvalds 			}
36921da177e4SLinus Torvalds 			else if (message == SMWDTR)
36931da177e4SLinus Torvalds 			{
36941da177e4SLinus Torvalds 
36951da177e4SLinus Torvalds 				if (length == 0x02)
36961da177e4SLinus Torvalds 				{
36971da177e4SLinus Torvalds 
36981da177e4SLinus Torvalds 					ACCEPT_MSG(port);
3699*47b5d69cSJames Bottomley  					FPT_stwidn(port,p_card);
37001da177e4SLinus Torvalds 				}
37011da177e4SLinus Torvalds 				else
37021da177e4SLinus Torvalds 				{
37031da177e4SLinus Torvalds 
37041da177e4SLinus Torvalds 					pCurrSCCB->Sccb_scsimsg = SMREJECT;
37051da177e4SLinus Torvalds 					ACCEPT_MSG_ATN(port);
37061da177e4SLinus Torvalds 
37071da177e4SLinus Torvalds 					WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
37081da177e4SLinus Torvalds 				}
37091da177e4SLinus Torvalds 			}
37101da177e4SLinus Torvalds 			else
37111da177e4SLinus Torvalds 			{
37121da177e4SLinus Torvalds 
37131da177e4SLinus Torvalds 				pCurrSCCB->Sccb_scsimsg = SMREJECT;
37141da177e4SLinus Torvalds 				ACCEPT_MSG_ATN(port);
37151da177e4SLinus Torvalds 
37161da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
37171da177e4SLinus Torvalds 			}
37181da177e4SLinus Torvalds 		}
37191da177e4SLinus Torvalds 		else
37201da177e4SLinus Torvalds 		{
37211da177e4SLinus Torvalds 			if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
37221da177e4SLinus Torvalds 				ACCEPT_MSG(port);
37231da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
37241da177e4SLinus Torvalds 		}
37251da177e4SLinus Torvalds 	}else
37261da177e4SLinus Torvalds 	{
37271da177e4SLinus Torvalds 			if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
37281da177e4SLinus Torvalds 				WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
37291da177e4SLinus Torvalds 	}
37301da177e4SLinus Torvalds }
37311da177e4SLinus Torvalds 
37321da177e4SLinus Torvalds 
37331da177e4SLinus Torvalds /*---------------------------------------------------------------------
37341da177e4SLinus Torvalds  *
3735*47b5d69cSJames Bottomley   * Function: FPT_sisyncn
37361da177e4SLinus Torvalds  *
37371da177e4SLinus Torvalds  * Description: Read in a message byte from the SCSI bus, and check
37381da177e4SLinus Torvalds  *              for a parity error.
37391da177e4SLinus Torvalds  *
37401da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
37411da177e4SLinus Torvalds 
3742*47b5d69cSJames Bottomley  static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
37431da177e4SLinus Torvalds {
37441da177e4SLinus Torvalds    PSCCB currSCCB;
37451da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
37461da177e4SLinus Torvalds 
3747*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3748*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
37491da177e4SLinus Torvalds 
37501da177e4SLinus Torvalds    if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
37511da177e4SLinus Torvalds 
37521da177e4SLinus Torvalds 
37531da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT),
37541da177e4SLinus Torvalds                  (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
37551da177e4SLinus Torvalds 
37561da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
37571da177e4SLinus Torvalds 
37581da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
37591da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03  ));
37601da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
37611da177e4SLinus Torvalds 
37621da177e4SLinus Torvalds 
37631da177e4SLinus Torvalds       if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
37641da177e4SLinus Torvalds 
37651da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
37661da177e4SLinus Torvalds 
37671da177e4SLinus Torvalds       else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
37681da177e4SLinus Torvalds 
37691da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
37701da177e4SLinus Torvalds 
37711da177e4SLinus Torvalds       else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
37721da177e4SLinus Torvalds 
37731da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
37741da177e4SLinus Torvalds 
37751da177e4SLinus Torvalds       else
37761da177e4SLinus Torvalds 	 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
37771da177e4SLinus Torvalds 
37781da177e4SLinus Torvalds 
37791da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP                ));
37801da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
37811da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
37821da177e4SLinus Torvalds 
37831da177e4SLinus Torvalds 
3784*47b5d69cSJames Bottomley  		if(syncFlag == 0)
37851da177e4SLinus Torvalds 		{
37861da177e4SLinus Torvalds 		   WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
37871da177e4SLinus Torvalds 	      currTar_Info->TarStatus = ((currTar_Info->TarStatus &
37881da177e4SLinus Torvalds    	      ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
37891da177e4SLinus Torvalds 		}
37901da177e4SLinus Torvalds 		else
37911da177e4SLinus Torvalds 		{
37921da177e4SLinus Torvalds 		   WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
37931da177e4SLinus Torvalds 		}
37941da177e4SLinus Torvalds 
37951da177e4SLinus Torvalds 
3796*47b5d69cSJames Bottomley        return(1);
37971da177e4SLinus Torvalds       }
37981da177e4SLinus Torvalds 
37991da177e4SLinus Torvalds    else {
38001da177e4SLinus Torvalds 
38011da177e4SLinus Torvalds       currTar_Info->TarStatus |=	 (UCHAR)SYNC_SUPPORTED;
38021da177e4SLinus Torvalds       currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3803*47b5d69cSJames Bottomley        return(0);
38041da177e4SLinus Torvalds       }
38051da177e4SLinus Torvalds }
38061da177e4SLinus Torvalds 
38071da177e4SLinus Torvalds 
38081da177e4SLinus Torvalds 
38091da177e4SLinus Torvalds /*---------------------------------------------------------------------
38101da177e4SLinus Torvalds  *
3811*47b5d69cSJames Bottomley   * Function: FPT_stsyncn
38121da177e4SLinus Torvalds  *
38131da177e4SLinus Torvalds  * Description: The has sent us a Sync Nego message so handle it as
38141da177e4SLinus Torvalds  *              necessary.
38151da177e4SLinus Torvalds  *
38161da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
3817*47b5d69cSJames Bottomley  static void FPT_stsyncn(ULONG port, UCHAR p_card)
38181da177e4SLinus Torvalds {
38191da177e4SLinus Torvalds    UCHAR sync_msg,offset,sync_reg,our_sync_msg;
38201da177e4SLinus Torvalds    PSCCB currSCCB;
38211da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
38221da177e4SLinus Torvalds 
3823*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3824*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
38251da177e4SLinus Torvalds 
3826*47b5d69cSJames Bottomley     sync_msg = FPT_sfm(port,currSCCB);
38271da177e4SLinus Torvalds 
38281da177e4SLinus Torvalds 	if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
38291da177e4SLinus Torvalds 	{
38301da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
38311da177e4SLinus Torvalds 		return;
38321da177e4SLinus Torvalds 	}
38331da177e4SLinus Torvalds 
38341da177e4SLinus Torvalds    ACCEPT_MSG(port);
38351da177e4SLinus Torvalds 
38361da177e4SLinus Torvalds 
3837*47b5d69cSJames Bottomley     offset = FPT_sfm(port,currSCCB);
38381da177e4SLinus Torvalds 
38391da177e4SLinus Torvalds 	if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
38401da177e4SLinus Torvalds 	{
38411da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
38421da177e4SLinus Torvalds 		return;
38431da177e4SLinus Torvalds 	}
38441da177e4SLinus Torvalds 
38451da177e4SLinus Torvalds    if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
38461da177e4SLinus Torvalds 
38471da177e4SLinus Torvalds       our_sync_msg = 12;              /* Setup our Message to 20mb/s */
38481da177e4SLinus Torvalds 
38491da177e4SLinus Torvalds    else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
38501da177e4SLinus Torvalds 
38511da177e4SLinus Torvalds       our_sync_msg = 25;              /* Setup our Message to 10mb/s */
38521da177e4SLinus Torvalds 
38531da177e4SLinus Torvalds    else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
38541da177e4SLinus Torvalds 
38551da177e4SLinus Torvalds       our_sync_msg = 50;              /* Setup our Message to 5mb/s */
38561da177e4SLinus Torvalds    else
38571da177e4SLinus Torvalds 
38581da177e4SLinus Torvalds       our_sync_msg = 0;               /* Message = Async */
38591da177e4SLinus Torvalds 
38601da177e4SLinus Torvalds    if (sync_msg < our_sync_msg) {
38611da177e4SLinus Torvalds       sync_msg = our_sync_msg;    /*if faster, then set to max. */
38621da177e4SLinus Torvalds       }
38631da177e4SLinus Torvalds 
38641da177e4SLinus Torvalds    if (offset == ASYNC)
38651da177e4SLinus Torvalds       sync_msg = ASYNC;
38661da177e4SLinus Torvalds 
38671da177e4SLinus Torvalds    if (offset > MAX_OFFSET)
38681da177e4SLinus Torvalds       offset = MAX_OFFSET;
38691da177e4SLinus Torvalds 
38701da177e4SLinus Torvalds    sync_reg = 0x00;
38711da177e4SLinus Torvalds 
38721da177e4SLinus Torvalds    if (sync_msg > 12)
38731da177e4SLinus Torvalds 
38741da177e4SLinus Torvalds       sync_reg = 0x20;        /* Use 10MB/s */
38751da177e4SLinus Torvalds 
38761da177e4SLinus Torvalds    if (sync_msg > 25)
38771da177e4SLinus Torvalds 
38781da177e4SLinus Torvalds       sync_reg = 0x40;        /* Use 6.6MB/s */
38791da177e4SLinus Torvalds 
38801da177e4SLinus Torvalds    if (sync_msg > 38)
38811da177e4SLinus Torvalds 
38821da177e4SLinus Torvalds       sync_reg = 0x60;        /* Use 5MB/s */
38831da177e4SLinus Torvalds 
38841da177e4SLinus Torvalds    if (sync_msg > 50)
38851da177e4SLinus Torvalds 
38861da177e4SLinus Torvalds       sync_reg = 0x80;        /* Use 4MB/s */
38871da177e4SLinus Torvalds 
38881da177e4SLinus Torvalds    if (sync_msg > 62)
38891da177e4SLinus Torvalds 
38901da177e4SLinus Torvalds       sync_reg = 0xA0;        /* Use 3.33MB/s */
38911da177e4SLinus Torvalds 
38921da177e4SLinus Torvalds    if (sync_msg > 75)
38931da177e4SLinus Torvalds 
38941da177e4SLinus Torvalds       sync_reg = 0xC0;        /* Use 2.85MB/s */
38951da177e4SLinus Torvalds 
38961da177e4SLinus Torvalds    if (sync_msg > 87)
38971da177e4SLinus Torvalds 
38981da177e4SLinus Torvalds       sync_reg = 0xE0;        /* Use 2.5MB/s */
38991da177e4SLinus Torvalds 
39001da177e4SLinus Torvalds    if (sync_msg > 100) {
39011da177e4SLinus Torvalds 
39021da177e4SLinus Torvalds       sync_reg = 0x00;        /* Use ASYNC */
39031da177e4SLinus Torvalds       offset = 0x00;
39041da177e4SLinus Torvalds       }
39051da177e4SLinus Torvalds 
39061da177e4SLinus Torvalds 
39071da177e4SLinus Torvalds    if (currTar_Info->TarStatus & WIDE_ENABLED)
39081da177e4SLinus Torvalds 
39091da177e4SLinus Torvalds       sync_reg |= offset;
39101da177e4SLinus Torvalds 
39111da177e4SLinus Torvalds    else
39121da177e4SLinus Torvalds 
39131da177e4SLinus Torvalds       sync_reg |= (offset | NARROW_SCSI);
39141da177e4SLinus Torvalds 
3915*47b5d69cSJames Bottomley     FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
39161da177e4SLinus Torvalds 
39171da177e4SLinus Torvalds 
39181da177e4SLinus Torvalds    if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
39191da177e4SLinus Torvalds 
39201da177e4SLinus Torvalds 
39211da177e4SLinus Torvalds       ACCEPT_MSG(port);
39221da177e4SLinus Torvalds 
39231da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
39241da177e4SLinus Torvalds          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
39251da177e4SLinus Torvalds 
39261da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
39271da177e4SLinus Torvalds       }
39281da177e4SLinus Torvalds 
39291da177e4SLinus Torvalds    else {
39301da177e4SLinus Torvalds 
39311da177e4SLinus Torvalds 
39321da177e4SLinus Torvalds       ACCEPT_MSG_ATN(port);
39331da177e4SLinus Torvalds 
3934*47b5d69cSJames Bottomley        FPT_sisyncr(port,sync_msg,offset);
39351da177e4SLinus Torvalds 
39361da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
39371da177e4SLinus Torvalds          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
39381da177e4SLinus Torvalds       }
39391da177e4SLinus Torvalds }
39401da177e4SLinus Torvalds 
39411da177e4SLinus Torvalds 
39421da177e4SLinus Torvalds /*---------------------------------------------------------------------
39431da177e4SLinus Torvalds  *
3944*47b5d69cSJames Bottomley   * Function: FPT_sisyncr
39451da177e4SLinus Torvalds  *
39461da177e4SLinus Torvalds  * Description: Answer the targets sync message.
39471da177e4SLinus Torvalds  *
39481da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
3949*47b5d69cSJames Bottomley  static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
39501da177e4SLinus Torvalds {
39511da177e4SLinus Torvalds    ARAM_ACCESS(port);
39521da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
39531da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03  ));
39541da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
39551da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
39561da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP                ));
39571da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
39581da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
39591da177e4SLinus Torvalds    SGRAM_ACCESS(port);
39601da177e4SLinus Torvalds 
39611da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
39621da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
39631da177e4SLinus Torvalds 
39641da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
39651da177e4SLinus Torvalds 
39661da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
39671da177e4SLinus Torvalds }
39681da177e4SLinus Torvalds 
39691da177e4SLinus Torvalds 
39701da177e4SLinus Torvalds 
39711da177e4SLinus Torvalds /*---------------------------------------------------------------------
39721da177e4SLinus Torvalds  *
3973*47b5d69cSJames Bottomley   * Function: FPT_siwidn
39741da177e4SLinus Torvalds  *
39751da177e4SLinus Torvalds  * Description: Read in a message byte from the SCSI bus, and check
39761da177e4SLinus Torvalds  *              for a parity error.
39771da177e4SLinus Torvalds  *
39781da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
39791da177e4SLinus Torvalds 
3980*47b5d69cSJames Bottomley  static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
39811da177e4SLinus Torvalds {
39821da177e4SLinus Torvalds    PSCCB currSCCB;
39831da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
39841da177e4SLinus Torvalds 
3985*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
3986*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
39871da177e4SLinus Torvalds 
39881da177e4SLinus Torvalds    if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
39891da177e4SLinus Torvalds 
39901da177e4SLinus Torvalds 
39911da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT),
39921da177e4SLinus Torvalds 	              (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
39931da177e4SLinus Torvalds 
39941da177e4SLinus Torvalds       WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
39951da177e4SLinus Torvalds 
39961da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
39971da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02  ));
39981da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
39991da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP                ));
40001da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
40011da177e4SLinus Torvalds       WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP      ));
40021da177e4SLinus Torvalds 
40031da177e4SLinus Torvalds       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
40041da177e4SLinus Torvalds 
40051da177e4SLinus Torvalds 
40061da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
40071da177e4SLinus Torvalds          ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
40081da177e4SLinus Torvalds 
4009*47b5d69cSJames Bottomley        return(1);
40101da177e4SLinus Torvalds       }
40111da177e4SLinus Torvalds 
40121da177e4SLinus Torvalds    else {
40131da177e4SLinus Torvalds 
40141da177e4SLinus Torvalds       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
40151da177e4SLinus Torvalds                ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
40161da177e4SLinus Torvalds 
40171da177e4SLinus Torvalds       currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
4018*47b5d69cSJames Bottomley        return(0);
40191da177e4SLinus Torvalds       }
40201da177e4SLinus Torvalds }
40211da177e4SLinus Torvalds 
40221da177e4SLinus Torvalds 
40231da177e4SLinus Torvalds 
40241da177e4SLinus Torvalds /*---------------------------------------------------------------------
40251da177e4SLinus Torvalds  *
4026*47b5d69cSJames Bottomley   * Function: FPT_stwidn
40271da177e4SLinus Torvalds  *
40281da177e4SLinus Torvalds  * Description: The has sent us a Wide Nego message so handle it as
40291da177e4SLinus Torvalds  *              necessary.
40301da177e4SLinus Torvalds  *
40311da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
4032*47b5d69cSJames Bottomley  static void FPT_stwidn(ULONG port, UCHAR p_card)
40331da177e4SLinus Torvalds {
40341da177e4SLinus Torvalds    UCHAR width;
40351da177e4SLinus Torvalds    PSCCB currSCCB;
40361da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
40371da177e4SLinus Torvalds 
4038*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
4039*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
40401da177e4SLinus Torvalds 
4041*47b5d69cSJames Bottomley     width = FPT_sfm(port,currSCCB);
40421da177e4SLinus Torvalds 
40431da177e4SLinus Torvalds 	if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
40441da177e4SLinus Torvalds 	{
40451da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
40461da177e4SLinus Torvalds 		return;
40471da177e4SLinus Torvalds 	}
40481da177e4SLinus Torvalds 
40491da177e4SLinus Torvalds 
40501da177e4SLinus Torvalds    if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
40511da177e4SLinus Torvalds       width = 0;
40521da177e4SLinus Torvalds 
40531da177e4SLinus Torvalds    if (width) {
40541da177e4SLinus Torvalds       currTar_Info->TarStatus |= WIDE_ENABLED;
40551da177e4SLinus Torvalds       width = 0;
40561da177e4SLinus Torvalds       }
40571da177e4SLinus Torvalds    else {
40581da177e4SLinus Torvalds       width = NARROW_SCSI;
40591da177e4SLinus Torvalds       currTar_Info->TarStatus &= ~WIDE_ENABLED;
40601da177e4SLinus Torvalds       }
40611da177e4SLinus Torvalds 
40621da177e4SLinus Torvalds 
4063*47b5d69cSJames Bottomley     FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
40641da177e4SLinus Torvalds 
40651da177e4SLinus Torvalds 
40661da177e4SLinus Torvalds    if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
40671da177e4SLinus Torvalds 	{
40681da177e4SLinus Torvalds 
40691da177e4SLinus Torvalds 
40701da177e4SLinus Torvalds 
40711da177e4SLinus Torvalds       currTar_Info->TarStatus |=	 WIDE_NEGOCIATED;
40721da177e4SLinus Torvalds 
40731da177e4SLinus Torvalds 	   if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
40741da177e4SLinus Torvalds 		{
40751da177e4SLinus Torvalds 	      ACCEPT_MSG_ATN(port);
40761da177e4SLinus Torvalds 		   ARAM_ACCESS(port);
4077*47b5d69cSJames Bottomley  	     	FPT_sisyncn(port,p_card, 1);
40781da177e4SLinus Torvalds 	      currSCCB->Sccb_scsistat = SELECT_SN_ST;
40791da177e4SLinus Torvalds 		   SGRAM_ACCESS(port);
40801da177e4SLinus Torvalds 		}
40811da177e4SLinus Torvalds 		else
40821da177e4SLinus Torvalds 		{
40831da177e4SLinus Torvalds 	      ACCEPT_MSG(port);
40841da177e4SLinus Torvalds   		   WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
40851da177e4SLinus Torvalds 		}
40861da177e4SLinus Torvalds    }
40871da177e4SLinus Torvalds 
40881da177e4SLinus Torvalds    else {
40891da177e4SLinus Torvalds 
40901da177e4SLinus Torvalds 
40911da177e4SLinus Torvalds       ACCEPT_MSG_ATN(port);
40921da177e4SLinus Torvalds 
40931da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
40941da177e4SLinus Torvalds       	 width = SM16BIT;
40951da177e4SLinus Torvalds       else
40961da177e4SLinus Torvalds       	 width = SM8BIT;
40971da177e4SLinus Torvalds 
4098*47b5d69cSJames Bottomley        FPT_siwidr(port,width);
40991da177e4SLinus Torvalds 
41001da177e4SLinus Torvalds       currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
41011da177e4SLinus Torvalds       }
41021da177e4SLinus Torvalds }
41031da177e4SLinus Torvalds 
41041da177e4SLinus Torvalds 
41051da177e4SLinus Torvalds /*---------------------------------------------------------------------
41061da177e4SLinus Torvalds  *
4107*47b5d69cSJames Bottomley   * Function: FPT_siwidr
41081da177e4SLinus Torvalds  *
41091da177e4SLinus Torvalds  * Description: Answer the targets Wide nego message.
41101da177e4SLinus Torvalds  *
41111da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
4112*47b5d69cSJames Bottomley  static void FPT_siwidr(ULONG port, UCHAR width)
41131da177e4SLinus Torvalds {
41141da177e4SLinus Torvalds    ARAM_ACCESS(port);
41151da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
41161da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02  ));
41171da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
41181da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP                ));
41191da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
41201da177e4SLinus Torvalds    WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP      ));
41211da177e4SLinus Torvalds    SGRAM_ACCESS(port);
41221da177e4SLinus Torvalds 
41231da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
41241da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
41251da177e4SLinus Torvalds 
41261da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
41271da177e4SLinus Torvalds 
41281da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
41291da177e4SLinus Torvalds }
41301da177e4SLinus Torvalds 
41311da177e4SLinus Torvalds 
41321da177e4SLinus Torvalds 
41331da177e4SLinus Torvalds /*---------------------------------------------------------------------
41341da177e4SLinus Torvalds  *
4135*47b5d69cSJames Bottomley   * Function: FPT_sssyncv
41361da177e4SLinus Torvalds  *
41371da177e4SLinus Torvalds  * Description: Write the desired value to the Sync Register for the
41381da177e4SLinus Torvalds  *              ID specified.
41391da177e4SLinus Torvalds  *
41401da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
4141*47b5d69cSJames Bottomley  static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
4142*47b5d69cSJames Bottomley  			PSCCBMgr_tar_info currTar_Info)
41431da177e4SLinus Torvalds {
41441da177e4SLinus Torvalds    UCHAR index;
41451da177e4SLinus Torvalds 
41461da177e4SLinus Torvalds    index = p_id;
41471da177e4SLinus Torvalds 
41481da177e4SLinus Torvalds    switch (index) {
41491da177e4SLinus Torvalds 
41501da177e4SLinus Torvalds       case 0:
41511da177e4SLinus Torvalds 	 index = 12;             /* hp_synctarg_0 */
41521da177e4SLinus Torvalds 	 break;
41531da177e4SLinus Torvalds       case 1:
41541da177e4SLinus Torvalds 	 index = 13;             /* hp_synctarg_1 */
41551da177e4SLinus Torvalds 	 break;
41561da177e4SLinus Torvalds       case 2:
41571da177e4SLinus Torvalds 	 index = 14;             /* hp_synctarg_2 */
41581da177e4SLinus Torvalds 	 break;
41591da177e4SLinus Torvalds       case 3:
41601da177e4SLinus Torvalds 	 index = 15;             /* hp_synctarg_3 */
41611da177e4SLinus Torvalds 	 break;
41621da177e4SLinus Torvalds       case 4:
41631da177e4SLinus Torvalds 	 index = 8;              /* hp_synctarg_4 */
41641da177e4SLinus Torvalds 	 break;
41651da177e4SLinus Torvalds       case 5:
41661da177e4SLinus Torvalds 	 index = 9;              /* hp_synctarg_5 */
41671da177e4SLinus Torvalds 	 break;
41681da177e4SLinus Torvalds       case 6:
41691da177e4SLinus Torvalds 	 index = 10;             /* hp_synctarg_6 */
41701da177e4SLinus Torvalds 	 break;
41711da177e4SLinus Torvalds       case 7:
41721da177e4SLinus Torvalds 	 index = 11;             /* hp_synctarg_7 */
41731da177e4SLinus Torvalds 	 break;
41741da177e4SLinus Torvalds       case 8:
41751da177e4SLinus Torvalds 	 index = 4;              /* hp_synctarg_8 */
41761da177e4SLinus Torvalds 	 break;
41771da177e4SLinus Torvalds       case 9:
41781da177e4SLinus Torvalds 	 index = 5;              /* hp_synctarg_9 */
41791da177e4SLinus Torvalds 	 break;
41801da177e4SLinus Torvalds       case 10:
41811da177e4SLinus Torvalds 	 index = 6;              /* hp_synctarg_10 */
41821da177e4SLinus Torvalds 	 break;
41831da177e4SLinus Torvalds       case 11:
41841da177e4SLinus Torvalds 	 index = 7;              /* hp_synctarg_11 */
41851da177e4SLinus Torvalds 	 break;
41861da177e4SLinus Torvalds       case 12:
41871da177e4SLinus Torvalds 	 index = 0;              /* hp_synctarg_12 */
41881da177e4SLinus Torvalds 	 break;
41891da177e4SLinus Torvalds       case 13:
41901da177e4SLinus Torvalds 	 index = 1;              /* hp_synctarg_13 */
41911da177e4SLinus Torvalds 	 break;
41921da177e4SLinus Torvalds       case 14:
41931da177e4SLinus Torvalds 	 index = 2;              /* hp_synctarg_14 */
41941da177e4SLinus Torvalds 	 break;
41951da177e4SLinus Torvalds       case 15:
41961da177e4SLinus Torvalds 	 index = 3;              /* hp_synctarg_15 */
41971da177e4SLinus Torvalds 
41981da177e4SLinus Torvalds       }
41991da177e4SLinus Torvalds 
42001da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
42011da177e4SLinus Torvalds 
42021da177e4SLinus Torvalds 	currTar_Info->TarSyncCtrl = p_sync_value;
42031da177e4SLinus Torvalds }
42041da177e4SLinus Torvalds 
42051da177e4SLinus Torvalds 
42061da177e4SLinus Torvalds /*---------------------------------------------------------------------
42071da177e4SLinus Torvalds  *
4208*47b5d69cSJames Bottomley   * Function: FPT_sresb
42091da177e4SLinus Torvalds  *
42101da177e4SLinus Torvalds  * Description: Reset the desired card's SCSI bus.
42111da177e4SLinus Torvalds  *
42121da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
4213*47b5d69cSJames Bottomley  static void FPT_sresb(ULONG port, UCHAR p_card)
42141da177e4SLinus Torvalds {
42151da177e4SLinus Torvalds    UCHAR scsiID, i;
42161da177e4SLinus Torvalds 
42171da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
42181da177e4SLinus Torvalds 
42191da177e4SLinus Torvalds    WR_HARPOON(port+hp_page_ctrl,
42201da177e4SLinus Torvalds       (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
42211da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
42221da177e4SLinus Torvalds 
42231da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
42241da177e4SLinus Torvalds 
42251da177e4SLinus Torvalds    scsiID = RD_HARPOON(port+hp_seltimeout);
42261da177e4SLinus Torvalds    WR_HARPOON(port+hp_seltimeout,TO_5ms);
42271da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), TIMEOUT);
42281da177e4SLinus Torvalds 
42291da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
42301da177e4SLinus Torvalds 
42311da177e4SLinus Torvalds    while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
42321da177e4SLinus Torvalds 
42331da177e4SLinus Torvalds    WR_HARPOON(port+hp_seltimeout,scsiID);
42341da177e4SLinus Torvalds 
42351da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
42361da177e4SLinus Torvalds 
4237*47b5d69cSJames Bottomley     FPT_Wait(port, TO_5ms);
42381da177e4SLinus Torvalds 
42391da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
42401da177e4SLinus Torvalds 
42411da177e4SLinus Torvalds    WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
42421da177e4SLinus Torvalds 
42431da177e4SLinus Torvalds    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
42441da177e4SLinus Torvalds       {
4245*47b5d69cSJames Bottomley        currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
42461da177e4SLinus Torvalds 
42471da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
42481da177e4SLinus Torvalds          {
42491da177e4SLinus Torvalds 	      	currTar_Info->TarSyncCtrl = 0;
42501da177e4SLinus Torvalds 	      	currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
42511da177e4SLinus Torvalds 	      }
42521da177e4SLinus Torvalds 
42531da177e4SLinus Torvalds       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
42541da177e4SLinus Torvalds          {
42551da177e4SLinus Torvalds       	currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
42561da177e4SLinus Torvalds       	}
42571da177e4SLinus Torvalds 
4258*47b5d69cSJames Bottomley        FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
42591da177e4SLinus Torvalds 
4260*47b5d69cSJames Bottomley        FPT_SccbMgrTableInitTarget(p_card, scsiID);
42611da177e4SLinus Torvalds       }
42621da177e4SLinus Torvalds 
4263*47b5d69cSJames Bottomley     FPT_BL_Card[p_card].scanIndex = 0x00;
4264*47b5d69cSJames Bottomley     FPT_BL_Card[p_card].currentSCCB = NULL;
4265*47b5d69cSJames Bottomley     FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
42661da177e4SLinus Torvalds 													| F_NEW_SCCB_CMD);
4267*47b5d69cSJames Bottomley     FPT_BL_Card[p_card].cmdCounter  = 0x00;
4268*47b5d69cSJames Bottomley  	FPT_BL_Card[p_card].discQCount = 0x00;
4269*47b5d69cSJames Bottomley     FPT_BL_Card[p_card].tagQ_Lst = 0x01;
42701da177e4SLinus Torvalds 
42711da177e4SLinus Torvalds 	for(i = 0; i < QUEUE_DEPTH; i++)
4272*47b5d69cSJames Bottomley  		FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
42731da177e4SLinus Torvalds 
42741da177e4SLinus Torvalds    WR_HARPOON(port+hp_page_ctrl,
42751da177e4SLinus Torvalds       (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
42761da177e4SLinus Torvalds 
42771da177e4SLinus Torvalds }
42781da177e4SLinus Torvalds 
42791da177e4SLinus Torvalds /*---------------------------------------------------------------------
42801da177e4SLinus Torvalds  *
4281*47b5d69cSJames Bottomley   * Function: FPT_ssenss
42821da177e4SLinus Torvalds  *
42831da177e4SLinus Torvalds  * Description: Setup for the Auto Sense command.
42841da177e4SLinus Torvalds  *
42851da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
4286*47b5d69cSJames Bottomley  static void FPT_ssenss(PSCCBcard pCurrCard)
42871da177e4SLinus Torvalds {
42881da177e4SLinus Torvalds    UCHAR i;
42891da177e4SLinus Torvalds    PSCCB currSCCB;
42901da177e4SLinus Torvalds 
42911da177e4SLinus Torvalds    currSCCB = pCurrCard->currentSCCB;
42921da177e4SLinus Torvalds 
42931da177e4SLinus Torvalds 
42941da177e4SLinus Torvalds    currSCCB->Save_CdbLen = currSCCB->CdbLength;
42951da177e4SLinus Torvalds 
42961da177e4SLinus Torvalds    for (i = 0; i < 6; i++) {
42971da177e4SLinus Torvalds 
42981da177e4SLinus Torvalds       currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
42991da177e4SLinus Torvalds       }
43001da177e4SLinus Torvalds 
43011da177e4SLinus Torvalds    currSCCB->CdbLength = SIX_BYTE_CMD;
43021da177e4SLinus Torvalds    currSCCB->Cdb[0]    = SCSI_REQUEST_SENSE;
43031da177e4SLinus Torvalds    currSCCB->Cdb[1]    = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
43041da177e4SLinus Torvalds    currSCCB->Cdb[2]    = 0x00;
43051da177e4SLinus Torvalds    currSCCB->Cdb[3]    = 0x00;
43061da177e4SLinus Torvalds    currSCCB->Cdb[4]    = currSCCB->RequestSenseLength;
43071da177e4SLinus Torvalds    currSCCB->Cdb[5]    = 0x00;
43081da177e4SLinus Torvalds 
43091da177e4SLinus Torvalds    currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
43101da177e4SLinus Torvalds 
43111da177e4SLinus Torvalds    currSCCB->Sccb_ATC = 0x00;
43121da177e4SLinus Torvalds 
43131da177e4SLinus Torvalds    currSCCB->Sccb_XferState |= F_AUTO_SENSE;
43141da177e4SLinus Torvalds 
43151da177e4SLinus Torvalds    currSCCB->Sccb_XferState &= ~F_SG_XFER;
43161da177e4SLinus Torvalds 
43171da177e4SLinus Torvalds    currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
43181da177e4SLinus Torvalds 
43191da177e4SLinus Torvalds    currSCCB->ControlByte = 0x00;
43201da177e4SLinus Torvalds 
43211da177e4SLinus Torvalds    currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
43221da177e4SLinus Torvalds }
43231da177e4SLinus Torvalds 
43241da177e4SLinus Torvalds 
43251da177e4SLinus Torvalds 
43261da177e4SLinus Torvalds /*---------------------------------------------------------------------
43271da177e4SLinus Torvalds  *
4328*47b5d69cSJames Bottomley   * Function: FPT_sxfrp
43291da177e4SLinus Torvalds  *
43301da177e4SLinus Torvalds  * Description: Transfer data into the bit bucket until the device
43311da177e4SLinus Torvalds  *              decides to switch phase.
43321da177e4SLinus Torvalds  *
43331da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
43341da177e4SLinus Torvalds 
4335*47b5d69cSJames Bottomley  static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
43361da177e4SLinus Torvalds {
43371da177e4SLinus Torvalds    UCHAR curr_phz;
43381da177e4SLinus Torvalds 
43391da177e4SLinus Torvalds 
43401da177e4SLinus Torvalds    DISABLE_AUTO(p_port);
43411da177e4SLinus Torvalds 
4342*47b5d69cSJames Bottomley     if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
43431da177e4SLinus Torvalds 
4344*47b5d69cSJames Bottomley        FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
43451da177e4SLinus Torvalds 
43461da177e4SLinus Torvalds       }
43471da177e4SLinus Torvalds 
43481da177e4SLinus Torvalds    /* If the Automation handled the end of the transfer then do not
43491da177e4SLinus Torvalds       match the phase or we will get out of sync with the ISR.       */
43501da177e4SLinus Torvalds 
43511da177e4SLinus Torvalds    if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
43521da177e4SLinus Torvalds       return;
43531da177e4SLinus Torvalds 
43541da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
43551da177e4SLinus Torvalds 
43561da177e4SLinus Torvalds    curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
43571da177e4SLinus Torvalds 
43581da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
43591da177e4SLinus Torvalds 
43601da177e4SLinus Torvalds 
43611da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, curr_phz);
43621da177e4SLinus Torvalds 
43631da177e4SLinus Torvalds    while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
43641da177e4SLinus Torvalds       (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
43651da177e4SLinus Torvalds       {
43661da177e4SLinus Torvalds       if (curr_phz & (UCHAR)SCSI_IOBIT)
43671da177e4SLinus Torvalds          {
43681da177e4SLinus Torvalds       	WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
43691da177e4SLinus Torvalds 
43701da177e4SLinus Torvalds 	      if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
43711da177e4SLinus Torvalds             {
43721da177e4SLinus Torvalds 	         RD_HARPOON(p_port+hp_fifodata_0);
43731da177e4SLinus Torvalds 	         }
43741da177e4SLinus Torvalds 	      }
43751da177e4SLinus Torvalds       else
43761da177e4SLinus Torvalds          {
43771da177e4SLinus Torvalds       	WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
43781da177e4SLinus Torvalds    	   if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
43791da177e4SLinus Torvalds             {
43801da177e4SLinus Torvalds 	         WR_HARPOON(p_port+hp_fifodata_0,0xFA);
43811da177e4SLinus Torvalds 	         }
43821da177e4SLinus Torvalds 	      }
43831da177e4SLinus Torvalds       } /* End of While loop for padding data I/O phase */
43841da177e4SLinus Torvalds 
43851da177e4SLinus Torvalds       while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
43861da177e4SLinus Torvalds          {
43871da177e4SLinus Torvalds          if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
43881da177e4SLinus Torvalds       	   break;
43891da177e4SLinus Torvalds          }
43901da177e4SLinus Torvalds 
43911da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
43921da177e4SLinus Torvalds       while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
43931da177e4SLinus Torvalds          {
43941da177e4SLinus Torvalds          RD_HARPOON(p_port+hp_fifodata_0);
43951da177e4SLinus Torvalds          }
43961da177e4SLinus Torvalds 
43971da177e4SLinus Torvalds       if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
43981da177e4SLinus Torvalds          {
43991da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
44001da177e4SLinus Torvalds          while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
44011da177e4SLinus Torvalds 
44021da177e4SLinus Torvalds          if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
44031da177e4SLinus Torvalds    	   while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
44041da177e4SLinus Torvalds          }
44051da177e4SLinus Torvalds }
44061da177e4SLinus Torvalds 
44071da177e4SLinus Torvalds 
44081da177e4SLinus Torvalds /*---------------------------------------------------------------------
44091da177e4SLinus Torvalds  *
4410*47b5d69cSJames Bottomley   * Function: FPT_schkdd
44111da177e4SLinus Torvalds  *
44121da177e4SLinus Torvalds  * Description: Make sure data has been flushed from both FIFOs and abort
44131da177e4SLinus Torvalds  *              the operations if necessary.
44141da177e4SLinus Torvalds  *
44151da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
44161da177e4SLinus Torvalds 
4417*47b5d69cSJames Bottomley  static void FPT_schkdd(ULONG port, UCHAR p_card)
44181da177e4SLinus Torvalds {
44191da177e4SLinus Torvalds    USHORT TimeOutLoop;
44201da177e4SLinus Torvalds 	UCHAR sPhase;
44211da177e4SLinus Torvalds 
44221da177e4SLinus Torvalds    PSCCB currSCCB;
44231da177e4SLinus Torvalds 
4424*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
44251da177e4SLinus Torvalds 
44261da177e4SLinus Torvalds 
44271da177e4SLinus Torvalds    if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
44281da177e4SLinus Torvalds        (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
44291da177e4SLinus Torvalds       return;
44301da177e4SLinus Torvalds       }
44311da177e4SLinus Torvalds 
44321da177e4SLinus Torvalds 
44331da177e4SLinus Torvalds 
44341da177e4SLinus Torvalds    if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
44351da177e4SLinus Torvalds       {
44361da177e4SLinus Torvalds 
44371da177e4SLinus Torvalds       currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
44381da177e4SLinus Torvalds 
44391da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = 1;
44401da177e4SLinus Torvalds 
44411da177e4SLinus Torvalds       currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
44421da177e4SLinus Torvalds       WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
44431da177e4SLinus Torvalds       WR_HARPOON(port+hp_xferstat, 0x00);
44441da177e4SLinus Torvalds       }
44451da177e4SLinus Torvalds 
44461da177e4SLinus Torvalds    else
44471da177e4SLinus Torvalds       {
44481da177e4SLinus Torvalds 
44491da177e4SLinus Torvalds       currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
44501da177e4SLinus Torvalds 
44511da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = 0;
44521da177e4SLinus Torvalds       }
44531da177e4SLinus Torvalds 
44541da177e4SLinus Torvalds    if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
44551da177e4SLinus Torvalds       (currSCCB->HostStatus == SCCB_COMPLETE)) {
44561da177e4SLinus Torvalds 
44571da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PARITY_ERR;
44581da177e4SLinus Torvalds       WRW_HARPOON((port+hp_intstat), PARITY);
44591da177e4SLinus Torvalds       }
44601da177e4SLinus Torvalds 
44611da177e4SLinus Torvalds 
4462*47b5d69cSJames Bottomley     FPT_hostDataXferAbort(port,p_card,currSCCB);
44631da177e4SLinus Torvalds 
44641da177e4SLinus Torvalds 
44651da177e4SLinus Torvalds    while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
44661da177e4SLinus Torvalds 
44671da177e4SLinus Torvalds    TimeOutLoop = 0;
44681da177e4SLinus Torvalds 
44691da177e4SLinus Torvalds    while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
44701da177e4SLinus Torvalds       {
44711da177e4SLinus Torvalds       if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
44721da177e4SLinus Torvalds 	      return;
44731da177e4SLinus Torvalds    	   }
44741da177e4SLinus Torvalds       if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
44751da177e4SLinus Torvalds 	      break;
44761da177e4SLinus Torvalds    	   }
44771da177e4SLinus Torvalds       if (RDW_HARPOON((port+hp_intstat)) & RESET) {
44781da177e4SLinus Torvalds 	      return;
44791da177e4SLinus Torvalds    	   }
44801da177e4SLinus Torvalds       if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
44811da177e4SLinus Torvalds    	   break;
44821da177e4SLinus Torvalds       }
44831da177e4SLinus Torvalds 
44841da177e4SLinus Torvalds 	sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
44851da177e4SLinus Torvalds    if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))                     ||
44861da177e4SLinus Torvalds       (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F)                       ||
44871da177e4SLinus Torvalds       (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
44881da177e4SLinus Torvalds       (sPhase == (SCSI_BSY | S_DATAI_PH)))
44891da177e4SLinus Torvalds       {
44901da177e4SLinus Torvalds 
44911da177e4SLinus Torvalds 	   WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
44921da177e4SLinus Torvalds 
44931da177e4SLinus Torvalds 	   if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
44941da177e4SLinus Torvalds          {
44951da177e4SLinus Torvalds 	      if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4496*47b5d69cSJames Bottomley  	         FPT_phaseDataIn(port,p_card);
44971da177e4SLinus Torvalds 	      	}
44981da177e4SLinus Torvalds 
44991da177e4SLinus Torvalds 	   	else {
4500*47b5d69cSJames Bottomley  	       FPT_phaseDataOut(port,p_card);
45011da177e4SLinus Torvalds 	       	}
45021da177e4SLinus Torvalds 	   	}
45031da177e4SLinus Torvalds 		else
45041da177e4SLinus Torvalds       	{
4505*47b5d69cSJames Bottomley  	   	FPT_sxfrp(port,p_card);
45061da177e4SLinus Torvalds 	   	if (!(RDW_HARPOON((port+hp_intstat)) &
45071da177e4SLinus Torvalds 		      (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
45081da177e4SLinus Torvalds          {
45091da177e4SLinus Torvalds    		WRW_HARPOON((port+hp_intstat), AUTO_INT);
4510*47b5d69cSJames Bottomley  		   FPT_phaseDecode(port,p_card);
45111da177e4SLinus Torvalds 		   }
45121da177e4SLinus Torvalds 	   }
45131da177e4SLinus Torvalds 
45141da177e4SLinus Torvalds    }
45151da177e4SLinus Torvalds 
45161da177e4SLinus Torvalds    else {
45171da177e4SLinus Torvalds       WR_HARPOON(port+hp_portctrl_0, 0x00);
45181da177e4SLinus Torvalds       }
45191da177e4SLinus Torvalds }
45201da177e4SLinus Torvalds 
45211da177e4SLinus Torvalds 
45221da177e4SLinus Torvalds /*---------------------------------------------------------------------
45231da177e4SLinus Torvalds  *
4524*47b5d69cSJames Bottomley   * Function: FPT_sinits
45251da177e4SLinus Torvalds  *
45261da177e4SLinus Torvalds  * Description: Setup SCCB manager fields in this SCCB.
45271da177e4SLinus Torvalds  *
45281da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
45291da177e4SLinus Torvalds 
4530*47b5d69cSJames Bottomley  static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
45311da177e4SLinus Torvalds {
45321da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
45331da177e4SLinus Torvalds 
45341da177e4SLinus Torvalds 	if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
45351da177e4SLinus Torvalds 	{
45361da177e4SLinus Torvalds 		return;
45371da177e4SLinus Torvalds 	}
4538*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
45391da177e4SLinus Torvalds 
45401da177e4SLinus Torvalds    p_sccb->Sccb_XferState     = 0x00;
45411da177e4SLinus Torvalds    p_sccb->Sccb_XferCnt       = p_sccb->DataLength;
45421da177e4SLinus Torvalds 
45431da177e4SLinus Torvalds    if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
45441da177e4SLinus Torvalds       (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
45451da177e4SLinus Torvalds 
45461da177e4SLinus Torvalds       p_sccb->Sccb_SGoffset   = 0;
45471da177e4SLinus Torvalds       p_sccb->Sccb_XferState  = F_SG_XFER;
45481da177e4SLinus Torvalds       p_sccb->Sccb_XferCnt    = 0x00;
45491da177e4SLinus Torvalds       }
45501da177e4SLinus Torvalds 
45511da177e4SLinus Torvalds    if (p_sccb->DataLength == 0x00)
45521da177e4SLinus Torvalds 
45531da177e4SLinus Torvalds       p_sccb->Sccb_XferState |= F_ALL_XFERRED;
45541da177e4SLinus Torvalds 
45551da177e4SLinus Torvalds    if (p_sccb->ControlByte & F_USE_CMD_Q)
45561da177e4SLinus Torvalds       {
45571da177e4SLinus Torvalds       if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
45581da177e4SLinus Torvalds          p_sccb->ControlByte &= ~F_USE_CMD_Q;
45591da177e4SLinus Torvalds 
45601da177e4SLinus Torvalds       else
45611da177e4SLinus Torvalds 	      currTar_Info->TarStatus |= TAG_Q_TRYING;
45621da177e4SLinus Torvalds       }
45631da177e4SLinus Torvalds 
45641da177e4SLinus Torvalds /*      For !single SCSI device in system  & device allow Disconnect
45651da177e4SLinus Torvalds 	or command is tag_q type then send Cmd with Disconnect Enable
45661da177e4SLinus Torvalds 	else send Cmd with Disconnect Disable */
45671da177e4SLinus Torvalds 
45681da177e4SLinus Torvalds /*
4569*47b5d69cSJames Bottomley     if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
45701da177e4SLinus Torvalds       (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
45711da177e4SLinus Torvalds       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
45721da177e4SLinus Torvalds */
45731da177e4SLinus Torvalds    if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
45741da177e4SLinus Torvalds       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
45751da177e4SLinus Torvalds       p_sccb->Sccb_idmsg      = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
45761da177e4SLinus Torvalds       }
45771da177e4SLinus Torvalds 
45781da177e4SLinus Torvalds    else {
45791da177e4SLinus Torvalds 
45801da177e4SLinus Torvalds       p_sccb->Sccb_idmsg      = (UCHAR)SMIDENT | p_sccb->Lun;
45811da177e4SLinus Torvalds       }
45821da177e4SLinus Torvalds 
45831da177e4SLinus Torvalds    p_sccb->HostStatus         = 0x00;
45841da177e4SLinus Torvalds    p_sccb->TargetStatus       = 0x00;
45851da177e4SLinus Torvalds    p_sccb->Sccb_tag           = 0x00;
45861da177e4SLinus Torvalds    p_sccb->Sccb_MGRFlags      = 0x00;
45871da177e4SLinus Torvalds    p_sccb->Sccb_sgseg         = 0x00;
45881da177e4SLinus Torvalds    p_sccb->Sccb_ATC           = 0x00;
45891da177e4SLinus Torvalds    p_sccb->Sccb_savedATC      = 0x00;
45901da177e4SLinus Torvalds /*
45911da177e4SLinus Torvalds    p_sccb->SccbVirtDataPtr    = 0x00;
45921da177e4SLinus Torvalds    p_sccb->Sccb_forwardlink   = NULL;
45931da177e4SLinus Torvalds    p_sccb->Sccb_backlink      = NULL;
45941da177e4SLinus Torvalds  */
45951da177e4SLinus Torvalds    p_sccb->Sccb_scsistat      = BUS_FREE_ST;
45961da177e4SLinus Torvalds    p_sccb->SccbStatus         = SCCB_IN_PROCESS;
45971da177e4SLinus Torvalds    p_sccb->Sccb_scsimsg       = SMNO_OP;
45981da177e4SLinus Torvalds 
45991da177e4SLinus Torvalds }
46001da177e4SLinus Torvalds 
46011da177e4SLinus Torvalds 
46021da177e4SLinus Torvalds /*---------------------------------------------------------------------
46031da177e4SLinus Torvalds  *
46041da177e4SLinus Torvalds  * Function: Phase Decode
46051da177e4SLinus Torvalds  *
46061da177e4SLinus Torvalds  * Description: Determine the phase and call the appropriate function.
46071da177e4SLinus Torvalds  *
46081da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
46091da177e4SLinus Torvalds 
4610*47b5d69cSJames Bottomley  static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
46111da177e4SLinus Torvalds {
46121da177e4SLinus Torvalds    unsigned char phase_ref;
46131da177e4SLinus Torvalds    void (*phase) (ULONG, UCHAR);
46141da177e4SLinus Torvalds 
46151da177e4SLinus Torvalds 
46161da177e4SLinus Torvalds    DISABLE_AUTO(p_port);
46171da177e4SLinus Torvalds 
46181da177e4SLinus Torvalds    phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
46191da177e4SLinus Torvalds 
4620*47b5d69cSJames Bottomley     phase = FPT_s_PhaseTbl[phase_ref];
46211da177e4SLinus Torvalds 
46221da177e4SLinus Torvalds    (*phase)(p_port, p_card);           /* Call the correct phase func */
46231da177e4SLinus Torvalds }
46241da177e4SLinus Torvalds 
46251da177e4SLinus Torvalds 
46261da177e4SLinus Torvalds 
46271da177e4SLinus Torvalds /*---------------------------------------------------------------------
46281da177e4SLinus Torvalds  *
46291da177e4SLinus Torvalds  * Function: Data Out Phase
46301da177e4SLinus Torvalds  *
46311da177e4SLinus Torvalds  * Description: Start up both the BusMaster and Xbow.
46321da177e4SLinus Torvalds  *
46331da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
46341da177e4SLinus Torvalds 
4635*47b5d69cSJames Bottomley  static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
46361da177e4SLinus Torvalds {
46371da177e4SLinus Torvalds 
46381da177e4SLinus Torvalds    PSCCB currSCCB;
46391da177e4SLinus Torvalds 
4640*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
46411da177e4SLinus Torvalds    if (currSCCB == NULL)
46421da177e4SLinus Torvalds       {
46431da177e4SLinus Torvalds       return;  /* Exit if No SCCB record */
46441da177e4SLinus Torvalds       }
46451da177e4SLinus Torvalds 
46461da177e4SLinus Torvalds    currSCCB->Sccb_scsistat = DATA_OUT_ST;
46471da177e4SLinus Torvalds    currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
46481da177e4SLinus Torvalds 
46491da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
46501da177e4SLinus Torvalds 
46511da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
46521da177e4SLinus Torvalds 
46531da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
46541da177e4SLinus Torvalds 
4655*47b5d69cSJames Bottomley     FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
46561da177e4SLinus Torvalds 
46571da177e4SLinus Torvalds    if (currSCCB->Sccb_XferCnt == 0) {
46581da177e4SLinus Torvalds 
46591da177e4SLinus Torvalds 
46601da177e4SLinus Torvalds       if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
46611da177e4SLinus Torvalds 	 (currSCCB->HostStatus == SCCB_COMPLETE))
46621da177e4SLinus Torvalds 	 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
46631da177e4SLinus Torvalds 
4664*47b5d69cSJames Bottomley        FPT_sxfrp(port,p_card);
46651da177e4SLinus Torvalds       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4666*47b5d69cSJames Bottomley  	    FPT_phaseDecode(port,p_card);
46671da177e4SLinus Torvalds       }
46681da177e4SLinus Torvalds }
46691da177e4SLinus Torvalds 
46701da177e4SLinus Torvalds 
46711da177e4SLinus Torvalds /*---------------------------------------------------------------------
46721da177e4SLinus Torvalds  *
46731da177e4SLinus Torvalds  * Function: Data In Phase
46741da177e4SLinus Torvalds  *
46751da177e4SLinus Torvalds  * Description: Startup the BusMaster and the XBOW.
46761da177e4SLinus Torvalds  *
46771da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
46781da177e4SLinus Torvalds 
4679*47b5d69cSJames Bottomley  static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
46801da177e4SLinus Torvalds {
46811da177e4SLinus Torvalds 
46821da177e4SLinus Torvalds    PSCCB currSCCB;
46831da177e4SLinus Torvalds 
4684*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
46851da177e4SLinus Torvalds 
46861da177e4SLinus Torvalds    if (currSCCB == NULL)
46871da177e4SLinus Torvalds       {
46881da177e4SLinus Torvalds       return;  /* Exit if No SCCB record */
46891da177e4SLinus Torvalds       }
46901da177e4SLinus Torvalds 
46911da177e4SLinus Torvalds 
46921da177e4SLinus Torvalds    currSCCB->Sccb_scsistat = DATA_IN_ST;
46931da177e4SLinus Torvalds    currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
46941da177e4SLinus Torvalds    currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
46951da177e4SLinus Torvalds 
46961da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
46971da177e4SLinus Torvalds 
46981da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
46991da177e4SLinus Torvalds 
47001da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
47011da177e4SLinus Torvalds 
4702*47b5d69cSJames Bottomley     FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
47031da177e4SLinus Torvalds 
47041da177e4SLinus Torvalds    if (currSCCB->Sccb_XferCnt == 0) {
47051da177e4SLinus Torvalds 
47061da177e4SLinus Torvalds 
47071da177e4SLinus Torvalds       if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
47081da177e4SLinus Torvalds 	 (currSCCB->HostStatus == SCCB_COMPLETE))
47091da177e4SLinus Torvalds 	 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
47101da177e4SLinus Torvalds 
4711*47b5d69cSJames Bottomley        FPT_sxfrp(port,p_card);
47121da177e4SLinus Torvalds       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4713*47b5d69cSJames Bottomley  	    FPT_phaseDecode(port,p_card);
47141da177e4SLinus Torvalds 
47151da177e4SLinus Torvalds       }
47161da177e4SLinus Torvalds }
47171da177e4SLinus Torvalds 
47181da177e4SLinus Torvalds /*---------------------------------------------------------------------
47191da177e4SLinus Torvalds  *
47201da177e4SLinus Torvalds  * Function: Command Phase
47211da177e4SLinus Torvalds  *
47221da177e4SLinus Torvalds  * Description: Load the CDB into the automation and start it up.
47231da177e4SLinus Torvalds  *
47241da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
47251da177e4SLinus Torvalds 
4726*47b5d69cSJames Bottomley  static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
47271da177e4SLinus Torvalds {
47281da177e4SLinus Torvalds    PSCCB currSCCB;
47291da177e4SLinus Torvalds    ULONG cdb_reg;
47301da177e4SLinus Torvalds    UCHAR i;
47311da177e4SLinus Torvalds 
4732*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
47331da177e4SLinus Torvalds 
47341da177e4SLinus Torvalds    if (currSCCB->OperationCode == RESET_COMMAND) {
47351da177e4SLinus Torvalds 
47361da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
47371da177e4SLinus Torvalds       currSCCB->CdbLength = SIX_BYTE_CMD;
47381da177e4SLinus Torvalds       }
47391da177e4SLinus Torvalds 
47401da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, 0x00);
47411da177e4SLinus Torvalds 
47421da177e4SLinus Torvalds    ARAM_ACCESS(p_port);
47431da177e4SLinus Torvalds 
47441da177e4SLinus Torvalds 
47451da177e4SLinus Torvalds    cdb_reg = p_port + CMD_STRT;
47461da177e4SLinus Torvalds 
47471da177e4SLinus Torvalds    for (i=0; i < currSCCB->CdbLength; i++) {
47481da177e4SLinus Torvalds 
47491da177e4SLinus Torvalds       if (currSCCB->OperationCode == RESET_COMMAND)
47501da177e4SLinus Torvalds 
47511da177e4SLinus Torvalds 	 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
47521da177e4SLinus Torvalds 
47531da177e4SLinus Torvalds       else
47541da177e4SLinus Torvalds 	 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
47551da177e4SLinus Torvalds       cdb_reg +=2;
47561da177e4SLinus Torvalds       }
47571da177e4SLinus Torvalds 
47581da177e4SLinus Torvalds    if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
47591da177e4SLinus Torvalds       WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+    NP));
47601da177e4SLinus Torvalds 
47611da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
47621da177e4SLinus Torvalds 
47631da177e4SLinus Torvalds    currSCCB->Sccb_scsistat = COMMAND_ST;
47641da177e4SLinus Torvalds 
47651da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
47661da177e4SLinus Torvalds    SGRAM_ACCESS(p_port);
47671da177e4SLinus Torvalds }
47681da177e4SLinus Torvalds 
47691da177e4SLinus Torvalds 
47701da177e4SLinus Torvalds /*---------------------------------------------------------------------
47711da177e4SLinus Torvalds  *
47721da177e4SLinus Torvalds  * Function: Status phase
47731da177e4SLinus Torvalds  *
47741da177e4SLinus Torvalds  * Description: Bring in the status and command complete message bytes
47751da177e4SLinus Torvalds  *
47761da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
47771da177e4SLinus Torvalds 
4778*47b5d69cSJames Bottomley  static void FPT_phaseStatus(ULONG port, UCHAR p_card)
47791da177e4SLinus Torvalds {
47801da177e4SLinus Torvalds    /* Start-up the automation to finish off this command and let the
47811da177e4SLinus Torvalds       isr handle the interrupt for command complete when it comes in.
47821da177e4SLinus Torvalds       We could wait here for the interrupt to be generated?
47831da177e4SLinus Torvalds     */
47841da177e4SLinus Torvalds 
47851da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsisig, 0x00);
47861da177e4SLinus Torvalds 
47871da177e4SLinus Torvalds    WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
47881da177e4SLinus Torvalds }
47891da177e4SLinus Torvalds 
47901da177e4SLinus Torvalds 
47911da177e4SLinus Torvalds /*---------------------------------------------------------------------
47921da177e4SLinus Torvalds  *
47931da177e4SLinus Torvalds  * Function: Phase Message Out
47941da177e4SLinus Torvalds  *
47951da177e4SLinus Torvalds  * Description: Send out our message (if we have one) and handle whatever
47961da177e4SLinus Torvalds  *              else is involed.
47971da177e4SLinus Torvalds  *
47981da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
47991da177e4SLinus Torvalds 
4800*47b5d69cSJames Bottomley  static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
48011da177e4SLinus Torvalds {
48021da177e4SLinus Torvalds 	UCHAR message,scsiID;
48031da177e4SLinus Torvalds 	PSCCB currSCCB;
48041da177e4SLinus Torvalds 	PSCCBMgr_tar_info currTar_Info;
48051da177e4SLinus Torvalds 
4806*47b5d69cSJames Bottomley  	currSCCB = FPT_BL_Card[p_card].currentSCCB;
48071da177e4SLinus Torvalds 
48081da177e4SLinus Torvalds 	if (currSCCB != NULL) {
48091da177e4SLinus Torvalds 
48101da177e4SLinus Torvalds 		message = currSCCB->Sccb_scsimsg;
48111da177e4SLinus Torvalds 		scsiID = currSCCB->TargID;
48121da177e4SLinus Torvalds 
48131da177e4SLinus Torvalds 		if (message == SMDEV_RESET)
48141da177e4SLinus Torvalds 		{
48151da177e4SLinus Torvalds 
48161da177e4SLinus Torvalds 
4817*47b5d69cSJames Bottomley  			currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
48181da177e4SLinus Torvalds 			currTar_Info->TarSyncCtrl = 0;
4819*47b5d69cSJames Bottomley  			FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
48201da177e4SLinus Torvalds 
4821*47b5d69cSJames Bottomley  			if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
48221da177e4SLinus Torvalds 			{
48231da177e4SLinus Torvalds 
4824*47b5d69cSJames Bottomley  				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
48251da177e4SLinus Torvalds 
48261da177e4SLinus Torvalds 			}
48271da177e4SLinus Torvalds 
4828*47b5d69cSJames Bottomley  			if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
48291da177e4SLinus Torvalds 			{
48301da177e4SLinus Torvalds 
4831*47b5d69cSJames Bottomley  				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
48321da177e4SLinus Torvalds 			}
48331da177e4SLinus Torvalds 
48341da177e4SLinus Torvalds 
4835*47b5d69cSJames Bottomley  			FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4836*47b5d69cSJames Bottomley  			FPT_SccbMgrTableInitTarget(p_card,scsiID);
48371da177e4SLinus Torvalds 		}
48381da177e4SLinus Torvalds 		else if (currSCCB->Sccb_scsistat == ABORT_ST)
48391da177e4SLinus Torvalds 		{
48401da177e4SLinus Torvalds 			currSCCB->HostStatus = SCCB_COMPLETE;
4841*47b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
48421da177e4SLinus Torvalds 			{
4843*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4844*47b5d69cSJames Bottomley  				FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
48451da177e4SLinus Torvalds 			}
48461da177e4SLinus Torvalds 
48471da177e4SLinus Torvalds 		}
48481da177e4SLinus Torvalds 
48491da177e4SLinus Torvalds 		else if (currSCCB->Sccb_scsistat < COMMAND_ST)
48501da177e4SLinus Torvalds 		{
48511da177e4SLinus Torvalds 
48521da177e4SLinus Torvalds 
48531da177e4SLinus Torvalds 			if(message == SMNO_OP)
48541da177e4SLinus Torvalds 			{
48551da177e4SLinus Torvalds 				currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
48561da177e4SLinus Torvalds 
4857*47b5d69cSJames Bottomley  				FPT_ssel(port,p_card);
48581da177e4SLinus Torvalds 				return;
48591da177e4SLinus Torvalds 			}
48601da177e4SLinus Torvalds 		}
48611da177e4SLinus Torvalds 		else
48621da177e4SLinus Torvalds 		{
48631da177e4SLinus Torvalds 
48641da177e4SLinus Torvalds 
48651da177e4SLinus Torvalds 			if (message == SMABORT)
48661da177e4SLinus Torvalds 
4867*47b5d69cSJames Bottomley  				FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
48681da177e4SLinus Torvalds 		}
48691da177e4SLinus Torvalds 
48701da177e4SLinus Torvalds 	}
48711da177e4SLinus Torvalds 	else
48721da177e4SLinus Torvalds 	{
48731da177e4SLinus Torvalds 		message = SMABORT;
48741da177e4SLinus Torvalds 	}
48751da177e4SLinus Torvalds 
48761da177e4SLinus Torvalds 	WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
48771da177e4SLinus Torvalds 
48781da177e4SLinus Torvalds 
48791da177e4SLinus Torvalds 	WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
48801da177e4SLinus Torvalds 
48811da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsidata_0,message);
48821da177e4SLinus Torvalds 
48831da177e4SLinus Torvalds 	WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
48841da177e4SLinus Torvalds 
48851da177e4SLinus Torvalds 	ACCEPT_MSG(port);
48861da177e4SLinus Torvalds 
48871da177e4SLinus Torvalds 	WR_HARPOON(port+hp_portctrl_0, 0x00);
48881da177e4SLinus Torvalds 
48891da177e4SLinus Torvalds 	if ((message == SMABORT) || (message == SMDEV_RESET) ||
48901da177e4SLinus Torvalds 				(message == SMABORT_TAG) )
48911da177e4SLinus Torvalds 	{
48921da177e4SLinus Torvalds 
48931da177e4SLinus Torvalds 		while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
48941da177e4SLinus Torvalds 
48951da177e4SLinus Torvalds 		if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
48961da177e4SLinus Torvalds 		{
48971da177e4SLinus Torvalds 			WRW_HARPOON((port+hp_intstat), BUS_FREE);
48981da177e4SLinus Torvalds 
48991da177e4SLinus Torvalds 			if (currSCCB != NULL)
49001da177e4SLinus Torvalds 			{
49011da177e4SLinus Torvalds 
4902*47b5d69cSJames Bottomley  				if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4903*47b5d69cSJames Bottomley  					((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4904*47b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
49051da177e4SLinus Torvalds 				else
4906*47b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
49071da177e4SLinus Torvalds 
4908*47b5d69cSJames Bottomley  				FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
49091da177e4SLinus Torvalds 			}
49101da177e4SLinus Torvalds 
49111da177e4SLinus Torvalds 			else
49121da177e4SLinus Torvalds 			{
4913*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
49141da177e4SLinus Torvalds 			}
49151da177e4SLinus Torvalds 		}
49161da177e4SLinus Torvalds 
49171da177e4SLinus Torvalds 		else
49181da177e4SLinus Torvalds 		{
49191da177e4SLinus Torvalds 
4920*47b5d69cSJames Bottomley  			FPT_sxfrp(port,p_card);
49211da177e4SLinus Torvalds 		}
49221da177e4SLinus Torvalds 	}
49231da177e4SLinus Torvalds 
49241da177e4SLinus Torvalds 	else
49251da177e4SLinus Torvalds 	{
49261da177e4SLinus Torvalds 
49271da177e4SLinus Torvalds 		if(message == SMPARITY)
49281da177e4SLinus Torvalds 		{
49291da177e4SLinus Torvalds 			currSCCB->Sccb_scsimsg = SMNO_OP;
49301da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
49311da177e4SLinus Torvalds 		}
49321da177e4SLinus Torvalds 		else
49331da177e4SLinus Torvalds 		{
4934*47b5d69cSJames Bottomley  			FPT_sxfrp(port,p_card);
49351da177e4SLinus Torvalds 		}
49361da177e4SLinus Torvalds 	}
49371da177e4SLinus Torvalds }
49381da177e4SLinus Torvalds 
49391da177e4SLinus Torvalds 
49401da177e4SLinus Torvalds /*---------------------------------------------------------------------
49411da177e4SLinus Torvalds  *
49421da177e4SLinus Torvalds  * Function: Message In phase
49431da177e4SLinus Torvalds  *
49441da177e4SLinus Torvalds  * Description: Bring in the message and determine what to do with it.
49451da177e4SLinus Torvalds  *
49461da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
49471da177e4SLinus Torvalds 
4948*47b5d69cSJames Bottomley  static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
49491da177e4SLinus Torvalds {
49501da177e4SLinus Torvalds 	UCHAR message;
49511da177e4SLinus Torvalds 	PSCCB currSCCB;
49521da177e4SLinus Torvalds 
4953*47b5d69cSJames Bottomley  	currSCCB = FPT_BL_Card[p_card].currentSCCB;
49541da177e4SLinus Torvalds 
4955*47b5d69cSJames Bottomley  	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
49561da177e4SLinus Torvalds 	{
49571da177e4SLinus Torvalds 
4958*47b5d69cSJames Bottomley  		FPT_phaseChkFifo(port, p_card);
49591da177e4SLinus Torvalds 	}
49601da177e4SLinus Torvalds 
49611da177e4SLinus Torvalds 	message = RD_HARPOON(port+hp_scsidata_0);
49621da177e4SLinus Torvalds 	if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
49631da177e4SLinus Torvalds 	{
49641da177e4SLinus Torvalds 
49651da177e4SLinus Torvalds 		WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
49661da177e4SLinus Torvalds 
49671da177e4SLinus Torvalds 	}
49681da177e4SLinus Torvalds 
49691da177e4SLinus Torvalds 	else
49701da177e4SLinus Torvalds 	{
49711da177e4SLinus Torvalds 
4972*47b5d69cSJames Bottomley  		message = FPT_sfm(port,currSCCB);
49731da177e4SLinus Torvalds 		if (message)
49741da177e4SLinus Torvalds 		{
49751da177e4SLinus Torvalds 
49761da177e4SLinus Torvalds 
4977*47b5d69cSJames Bottomley  			FPT_sdecm(message,port,p_card);
49781da177e4SLinus Torvalds 
49791da177e4SLinus Torvalds 		}
49801da177e4SLinus Torvalds 		else
49811da177e4SLinus Torvalds 		{
49821da177e4SLinus Torvalds 			if(currSCCB->Sccb_scsimsg != SMPARITY)
49831da177e4SLinus Torvalds 				ACCEPT_MSG(port);
49841da177e4SLinus Torvalds 			WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
49851da177e4SLinus Torvalds 		}
49861da177e4SLinus Torvalds 	}
49871da177e4SLinus Torvalds 
49881da177e4SLinus Torvalds }
49891da177e4SLinus Torvalds 
49901da177e4SLinus Torvalds 
49911da177e4SLinus Torvalds /*---------------------------------------------------------------------
49921da177e4SLinus Torvalds  *
49931da177e4SLinus Torvalds  * Function: Illegal phase
49941da177e4SLinus Torvalds  *
49951da177e4SLinus Torvalds  * Description: Target switched to some illegal phase, so all we can do
49961da177e4SLinus Torvalds  *              is report an error back to the host (if that is possible)
49971da177e4SLinus Torvalds  *              and send an ABORT message to the misbehaving target.
49981da177e4SLinus Torvalds  *
49991da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
50001da177e4SLinus Torvalds 
5001*47b5d69cSJames Bottomley  static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
50021da177e4SLinus Torvalds {
50031da177e4SLinus Torvalds    PSCCB currSCCB;
50041da177e4SLinus Torvalds 
5005*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
50061da177e4SLinus Torvalds 
50071da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
50081da177e4SLinus Torvalds    if (currSCCB != NULL) {
50091da177e4SLinus Torvalds 
50101da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
50111da177e4SLinus Torvalds       currSCCB->Sccb_scsistat = ABORT_ST;
50121da177e4SLinus Torvalds       currSCCB->Sccb_scsimsg = SMABORT;
50131da177e4SLinus Torvalds       }
50141da177e4SLinus Torvalds 
50151da177e4SLinus Torvalds    ACCEPT_MSG_ATN(port);
50161da177e4SLinus Torvalds }
50171da177e4SLinus Torvalds 
50181da177e4SLinus Torvalds 
50191da177e4SLinus Torvalds 
50201da177e4SLinus Torvalds /*---------------------------------------------------------------------
50211da177e4SLinus Torvalds  *
50221da177e4SLinus Torvalds  * Function: Phase Check FIFO
50231da177e4SLinus Torvalds  *
50241da177e4SLinus Torvalds  * Description: Make sure data has been flushed from both FIFOs and abort
50251da177e4SLinus Torvalds  *              the operations if necessary.
50261da177e4SLinus Torvalds  *
50271da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
50281da177e4SLinus Torvalds 
5029*47b5d69cSJames Bottomley  static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
50301da177e4SLinus Torvalds {
50311da177e4SLinus Torvalds    ULONG xfercnt;
50321da177e4SLinus Torvalds    PSCCB currSCCB;
50331da177e4SLinus Torvalds 
5034*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
50351da177e4SLinus Torvalds 
50361da177e4SLinus Torvalds    if (currSCCB->Sccb_scsistat == DATA_IN_ST)
50371da177e4SLinus Torvalds       {
50381da177e4SLinus Torvalds 
50391da177e4SLinus Torvalds       while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
50401da177e4SLinus Torvalds 	      (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
50411da177e4SLinus Torvalds 
50421da177e4SLinus Torvalds 
50431da177e4SLinus Torvalds       if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
50441da177e4SLinus Torvalds          {
50451da177e4SLinus Torvalds 	      currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
50461da177e4SLinus Torvalds 
50471da177e4SLinus Torvalds 	      currSCCB->Sccb_XferCnt = 0;
50481da177e4SLinus Torvalds 
50491da177e4SLinus Torvalds 	      if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
50501da177e4SLinus Torvalds 	            (currSCCB->HostStatus == SCCB_COMPLETE))
50511da177e4SLinus Torvalds             {
50521da177e4SLinus Torvalds 	         currSCCB->HostStatus = SCCB_PARITY_ERR;
50531da177e4SLinus Torvalds 	         WRW_HARPOON((port+hp_intstat), PARITY);
50541da177e4SLinus Torvalds 	         }
50551da177e4SLinus Torvalds 
5056*47b5d69cSJames Bottomley  	      FPT_hostDataXferAbort(port,p_card,currSCCB);
50571da177e4SLinus Torvalds 
5058*47b5d69cSJames Bottomley  	      FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
50591da177e4SLinus Torvalds 
50601da177e4SLinus Torvalds 	      while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
50611da177e4SLinus Torvalds 	         (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
50621da177e4SLinus Torvalds 
50631da177e4SLinus Torvalds 	      }
50641da177e4SLinus Torvalds       }  /*End Data In specific code. */
50651da177e4SLinus Torvalds 
50661da177e4SLinus Torvalds 
50671da177e4SLinus Torvalds 
50681da177e4SLinus Torvalds    GET_XFER_CNT(port,xfercnt);
50691da177e4SLinus Torvalds 
50701da177e4SLinus Torvalds 
50711da177e4SLinus Torvalds    WR_HARPOON(port+hp_xfercnt_0, 0x00);
50721da177e4SLinus Torvalds 
50731da177e4SLinus Torvalds 
50741da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_0, 0x00);
50751da177e4SLinus Torvalds 
50761da177e4SLinus Torvalds    currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
50771da177e4SLinus Torvalds 
50781da177e4SLinus Torvalds    currSCCB->Sccb_XferCnt = xfercnt;
50791da177e4SLinus Torvalds 
50801da177e4SLinus Torvalds    if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
50811da177e4SLinus Torvalds       (currSCCB->HostStatus == SCCB_COMPLETE)) {
50821da177e4SLinus Torvalds 
50831da177e4SLinus Torvalds       currSCCB->HostStatus = SCCB_PARITY_ERR;
50841da177e4SLinus Torvalds       WRW_HARPOON((port+hp_intstat), PARITY);
50851da177e4SLinus Torvalds       }
50861da177e4SLinus Torvalds 
50871da177e4SLinus Torvalds 
5088*47b5d69cSJames Bottomley     FPT_hostDataXferAbort(port,p_card,currSCCB);
50891da177e4SLinus Torvalds 
50901da177e4SLinus Torvalds 
50911da177e4SLinus Torvalds    WR_HARPOON(port+hp_fifowrite, 0x00);
50921da177e4SLinus Torvalds    WR_HARPOON(port+hp_fiforead, 0x00);
50931da177e4SLinus Torvalds    WR_HARPOON(port+hp_xferstat, 0x00);
50941da177e4SLinus Torvalds 
50951da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
50961da177e4SLinus Torvalds }
50971da177e4SLinus Torvalds 
50981da177e4SLinus Torvalds 
50991da177e4SLinus Torvalds /*---------------------------------------------------------------------
51001da177e4SLinus Torvalds  *
51011da177e4SLinus Torvalds  * Function: Phase Bus Free
51021da177e4SLinus Torvalds  *
51031da177e4SLinus Torvalds  * Description: We just went bus free so figure out if it was
51041da177e4SLinus Torvalds  *              because of command complete or from a disconnect.
51051da177e4SLinus Torvalds  *
51061da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
5107*47b5d69cSJames Bottomley  static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
51081da177e4SLinus Torvalds {
51091da177e4SLinus Torvalds    PSCCB currSCCB;
51101da177e4SLinus Torvalds 
5111*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
51121da177e4SLinus Torvalds 
51131da177e4SLinus Torvalds    if (currSCCB != NULL)
51141da177e4SLinus Torvalds       {
51151da177e4SLinus Torvalds 
51161da177e4SLinus Torvalds       DISABLE_AUTO(port);
51171da177e4SLinus Torvalds 
51181da177e4SLinus Torvalds 
51191da177e4SLinus Torvalds       if (currSCCB->OperationCode == RESET_COMMAND)
51201da177e4SLinus Torvalds          {
51211da177e4SLinus Torvalds 
5122*47b5d69cSJames Bottomley  			if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5123*47b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5124*47b5d69cSJames Bottomley  	   		 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
51251da177e4SLinus Torvalds 			else
5126*47b5d69cSJames Bottomley  		   	 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
51271da177e4SLinus Torvalds 
5128*47b5d69cSJames Bottomley  	      FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
51291da177e4SLinus Torvalds 
5130*47b5d69cSJames Bottomley  	      FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
51311da177e4SLinus Torvalds 
51321da177e4SLinus Torvalds 	      }
51331da177e4SLinus Torvalds 
51341da177e4SLinus Torvalds       else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
51351da177e4SLinus Torvalds 	      {
5136*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
51371da177e4SLinus Torvalds 			         (UCHAR)SYNC_SUPPORTED;
5138*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
51391da177e4SLinus Torvalds 	      }
51401da177e4SLinus Torvalds 
51411da177e4SLinus Torvalds       else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
51421da177e4SLinus Torvalds 	      {
5143*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5144*47b5d69cSJames Bottomley  		            (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
51451da177e4SLinus Torvalds 		   TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
51461da177e4SLinus Torvalds 
5147*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
51481da177e4SLinus Torvalds 	      }
51491da177e4SLinus Torvalds 
51501da177e4SLinus Torvalds       else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
51511da177e4SLinus Torvalds 	      {
51521da177e4SLinus Torvalds 	      /* Make sure this is not a phony BUS_FREE.  If we were
51531da177e4SLinus Torvalds 	      reselected or if BUSY is NOT on then this is a
51541da177e4SLinus Torvalds 	      valid BUS FREE.  SRR Wednesday, 5/10/1995.     */
51551da177e4SLinus Torvalds 
51561da177e4SLinus Torvalds 	      if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
51571da177e4SLinus Torvalds 	         (RDW_HARPOON((port+hp_intstat)) & RSEL))
51581da177e4SLinus Torvalds 	         {
5159*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
5160*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
51611da177e4SLinus Torvalds 	         }
51621da177e4SLinus Torvalds 
51631da177e4SLinus Torvalds 	      else
51641da177e4SLinus Torvalds             {
51651da177e4SLinus Torvalds 	         return;
51661da177e4SLinus Torvalds 	         }
51671da177e4SLinus Torvalds          }
51681da177e4SLinus Torvalds 
51691da177e4SLinus Torvalds       else
51701da177e4SLinus Torvalds 	      {
51711da177e4SLinus Torvalds 
51721da177e4SLinus Torvalds 	      currSCCB->Sccb_scsistat = BUS_FREE_ST;
51731da177e4SLinus Torvalds 
51741da177e4SLinus Torvalds          if (!currSCCB->HostStatus)
51751da177e4SLinus Torvalds 	         {
51761da177e4SLinus Torvalds 	         currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
51771da177e4SLinus Torvalds 	         }
51781da177e4SLinus Torvalds 
5179*47b5d69cSJames Bottomley  			if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5180*47b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5181*47b5d69cSJames Bottomley  	   		 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
51821da177e4SLinus Torvalds 			else
5183*47b5d69cSJames Bottomley  		   	 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
51841da177e4SLinus Torvalds 
5185*47b5d69cSJames Bottomley  	      FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
51861da177e4SLinus Torvalds 	      return;
51871da177e4SLinus Torvalds 	      }
51881da177e4SLinus Torvalds 
51891da177e4SLinus Torvalds 
5190*47b5d69cSJames Bottomley        FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
51911da177e4SLinus Torvalds 
51921da177e4SLinus Torvalds       } /*end if !=null */
51931da177e4SLinus Torvalds }
51941da177e4SLinus Torvalds 
51951da177e4SLinus Torvalds 
51961da177e4SLinus Torvalds 
51971da177e4SLinus Torvalds 
51981da177e4SLinus Torvalds /*---------------------------------------------------------------------
51991da177e4SLinus Torvalds  *
52001da177e4SLinus Torvalds  * Function: Auto Load Default Map
52011da177e4SLinus Torvalds  *
52021da177e4SLinus Torvalds  * Description: Load the Automation RAM with the defualt map values.
52031da177e4SLinus Torvalds  *
52041da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
5205*47b5d69cSJames Bottomley  static void FPT_autoLoadDefaultMap(ULONG p_port)
52061da177e4SLinus Torvalds {
52071da177e4SLinus Torvalds    ULONG map_addr;
52081da177e4SLinus Torvalds 
52091da177e4SLinus Torvalds    ARAM_ACCESS(p_port);
52101da177e4SLinus Torvalds    map_addr = p_port + hp_aramBase;
52111da177e4SLinus Torvalds 
52121da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0));  /*ID MESSAGE */
52131da177e4SLinus Torvalds    map_addr +=2;
52141da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20));  /*SIMPLE TAG QUEUEING MSG */
52151da177e4SLinus Torvalds    map_addr +=2;
52161da177e4SLinus Torvalds    WRW_HARPOON(map_addr, RAT_OP);                   /*RESET ATTENTION */
52171da177e4SLinus Torvalds    map_addr +=2;
52181da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00));  /*TAG ID MSG */
52191da177e4SLinus Torvalds    map_addr +=2;
52201da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 0 */
52211da177e4SLinus Torvalds    map_addr +=2;
52221da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 1 */
52231da177e4SLinus Torvalds    map_addr +=2;
52241da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 2 */
52251da177e4SLinus Torvalds    map_addr +=2;
52261da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 3 */
52271da177e4SLinus Torvalds    map_addr +=2;
52281da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 4 */
52291da177e4SLinus Torvalds    map_addr +=2;
52301da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 5 */
52311da177e4SLinus Torvalds    map_addr +=2;
52321da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 6 */
52331da177e4SLinus Torvalds    map_addr +=2;
52341da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 7 */
52351da177e4SLinus Torvalds    map_addr +=2;
52361da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 8 */
52371da177e4SLinus Torvalds    map_addr +=2;
52381da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 9 */
52391da177e4SLinus Torvalds    map_addr +=2;
52401da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 10 */
52411da177e4SLinus Torvalds    map_addr +=2;
52421da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00));  /*CDB BYTE 11 */
52431da177e4SLinus Torvalds    map_addr +=2;
52441da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
52451da177e4SLinus Torvalds    map_addr +=2;
52461da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI));     /*JUMP IF NO DATA IN FIFO */
52471da177e4SLinus Torvalds    map_addr +=2;                                   /*This means AYNC DATA IN */
52481da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+   SSI_IDO_STRT)); /*STOP AND INTERRUPT */
52491da177e4SLinus Torvalds    map_addr +=2;
52501da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT));   /*JUMP IF NOT DATA IN PHZ */
52511da177e4SLinus Torvalds    map_addr +=2;
52521da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  ST));    /*IF NOT MSG IN CHECK 4 DATA IN */
52531da177e4SLinus Torvalds    map_addr +=2;
52541da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x02));  /*SAVE DATA PTR MSG? */
52551da177e4SLinus Torvalds    map_addr +=2;
52561da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   DC));    /*GO CHECK FOR DISCONNECT MSG */
52571da177e4SLinus Torvalds    map_addr +=2;
52581da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+    D_AR1)); /*SAVE DATA PTRS MSG */
52591da177e4SLinus Torvalds    map_addr +=2;
52601da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  ST));    /*IF NOT MSG IN CHECK DATA IN */
52611da177e4SLinus Torvalds    map_addr +=2;
52621da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x04));  /*DISCONNECT MSG? */
52631da177e4SLinus Torvalds    map_addr +=2;
52641da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   UNKNWN));/*UKNKNOWN MSG */
52651da177e4SLinus Torvalds    map_addr +=2;
52661da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+    D_BUCKET));/*XFER DISCONNECT MSG */
52671da177e4SLinus Torvalds    map_addr +=2;
52681da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+          SSI_ITAR_DISC));/*STOP AND INTERRUPT */
52691da177e4SLinus Torvalds    map_addr +=2;
52701da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+  UNKNWN));/*JUMP IF NOT STATUS PHZ. */
52711da177e4SLinus Torvalds    map_addr +=2;
52721da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+  D_AR0));   /*GET STATUS BYTE */
52731da177e4SLinus Torvalds    map_addr +=2;
52741da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+  CC));    /*ERROR IF NOT MSG IN PHZ */
52751da177e4SLinus Torvalds    map_addr +=2;
52761da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRD_OP+SDATA+    0x00));  /*CHECK FOR CMD COMPLETE MSG. */
52771da177e4SLinus Torvalds    map_addr +=2;
52781da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+   CC));    /*ERROR IF NOT CMD COMPLETE MSG. */
52791da177e4SLinus Torvalds    map_addr +=2;
52801da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (MRR_OP+SDATA+  D_BUCKET));/*GET CMD COMPLETE MSG */
52811da177e4SLinus Torvalds    map_addr +=2;
52821da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+       SSI_ICMD_COMP));/*END OF COMMAND */
52831da177e4SLinus Torvalds    map_addr +=2;
52841da177e4SLinus Torvalds 
52851da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN));  /*RECEIVED UNKNOWN MSG BYTE */
52861da177e4SLinus Torvalds    map_addr +=2;
52871da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC));  /*NO COMMAND COMPLETE AFTER STATUS */
52881da177e4SLinus Torvalds    map_addr +=2;
52891da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
52901da177e4SLinus Torvalds    map_addr +=2;
52911da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL));  /*EXPECTED ID/TAG MESSAGES AND */
52921da177e4SLinus Torvalds    map_addr +=2;                             /* DIDN'T GET ONE */
52931da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (CRR_OP+AR3+  S_IDREG)); /* comp SCSI SEL ID & AR3*/
52941da177e4SLinus Torvalds    map_addr +=2;
52951da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (BRH_OP+EQUAL+   0x00));    /*SEL ID OK then Conti. */
52961da177e4SLinus Torvalds    map_addr +=2;
52971da177e4SLinus Torvalds    WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC));  /*NO COMMAND COMPLETE AFTER STATUS */
52981da177e4SLinus Torvalds 
52991da177e4SLinus Torvalds 
53001da177e4SLinus Torvalds 
53011da177e4SLinus Torvalds    SGRAM_ACCESS(p_port);
53021da177e4SLinus Torvalds }
53031da177e4SLinus Torvalds 
53041da177e4SLinus Torvalds /*---------------------------------------------------------------------
53051da177e4SLinus Torvalds  *
53061da177e4SLinus Torvalds  * Function: Auto Command Complete
53071da177e4SLinus Torvalds  *
53081da177e4SLinus Torvalds  * Description: Post command back to host and find another command
53091da177e4SLinus Torvalds  *              to execute.
53101da177e4SLinus Torvalds  *
53111da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
53121da177e4SLinus Torvalds 
5313*47b5d69cSJames Bottomley  static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
53141da177e4SLinus Torvalds {
53151da177e4SLinus Torvalds    PSCCB currSCCB;
53161da177e4SLinus Torvalds    UCHAR status_byte;
53171da177e4SLinus Torvalds 
5318*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
53191da177e4SLinus Torvalds 
53201da177e4SLinus Torvalds    status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
53211da177e4SLinus Torvalds 
5322*47b5d69cSJames Bottomley     FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
53231da177e4SLinus Torvalds 
53241da177e4SLinus Torvalds    if (status_byte != SSGOOD) {
53251da177e4SLinus Torvalds 
53261da177e4SLinus Torvalds       if (status_byte == SSQ_FULL) {
53271da177e4SLinus Torvalds 
53281da177e4SLinus Torvalds 
5329*47b5d69cSJames Bottomley  			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5330*47b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
53311da177e4SLinus Torvalds 			{
5332*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5333*47b5d69cSJames Bottomley  				if(FPT_BL_Card[p_card].discQCount != 0)
5334*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQCount--;
5335*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
53361da177e4SLinus Torvalds 			}
53371da177e4SLinus Torvalds 			else
53381da177e4SLinus Torvalds 			{
5339*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
53401da177e4SLinus Torvalds 				if(currSCCB->Sccb_tag)
53411da177e4SLinus Torvalds 				{
5342*47b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
5343*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
5344*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
53451da177e4SLinus Torvalds 				}else
53461da177e4SLinus Torvalds 				{
5347*47b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
5348*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
5349*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
53501da177e4SLinus Torvalds 				}
53511da177e4SLinus Torvalds 			}
53521da177e4SLinus Torvalds 
53531da177e4SLinus Torvalds          currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
53541da177e4SLinus Torvalds 
5355*47b5d69cSJames Bottomley           FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
53561da177e4SLinus Torvalds 
53571da177e4SLinus Torvalds          return;
53581da177e4SLinus Torvalds          }
53591da177e4SLinus Torvalds 
53601da177e4SLinus Torvalds       if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
53611da177e4SLinus Torvalds          {
5362*47b5d69cSJames Bottomley           FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
53631da177e4SLinus Torvalds             (UCHAR)SYNC_SUPPORTED;
53641da177e4SLinus Torvalds 
5365*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5366*47b5d69cSJames Bottomley           FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
53671da177e4SLinus Torvalds 
5368*47b5d69cSJames Bottomley  			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5369*47b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
53701da177e4SLinus Torvalds 			{
5371*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5372*47b5d69cSJames Bottomley  				if(FPT_BL_Card[p_card].discQCount != 0)
5373*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQCount--;
5374*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
53751da177e4SLinus Torvalds 			}
53761da177e4SLinus Torvalds 			else
53771da177e4SLinus Torvalds 			{
5378*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
53791da177e4SLinus Torvalds 				if(currSCCB->Sccb_tag)
53801da177e4SLinus Torvalds 				{
5381*47b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
5382*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
5383*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
53841da177e4SLinus Torvalds 				}else
53851da177e4SLinus Torvalds 				{
5386*47b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
5387*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
5388*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
53891da177e4SLinus Torvalds 				}
53901da177e4SLinus Torvalds 			}
53911da177e4SLinus Torvalds          return;
53921da177e4SLinus Torvalds 
53931da177e4SLinus Torvalds          }
53941da177e4SLinus Torvalds 
53951da177e4SLinus Torvalds       if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
53961da177e4SLinus Torvalds          {
53971da177e4SLinus Torvalds 
5398*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5399*47b5d69cSJames Bottomley  	         (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
54001da177e4SLinus Torvalds 	         TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
54011da177e4SLinus Torvalds 
5402*47b5d69cSJames Bottomley  	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5403*47b5d69cSJames Bottomley           FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
54041da177e4SLinus Torvalds 
5405*47b5d69cSJames Bottomley  			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5406*47b5d69cSJames Bottomley  				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
54071da177e4SLinus Torvalds 			{
5408*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5409*47b5d69cSJames Bottomley  				if(FPT_BL_Card[p_card].discQCount != 0)
5410*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQCount--;
5411*47b5d69cSJames Bottomley  				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
54121da177e4SLinus Torvalds 			}
54131da177e4SLinus Torvalds 			else
54141da177e4SLinus Torvalds 			{
5415*47b5d69cSJames Bottomley  	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
54161da177e4SLinus Torvalds 				if(currSCCB->Sccb_tag)
54171da177e4SLinus Torvalds 				{
5418*47b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
5419*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
5420*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
54211da177e4SLinus Torvalds 				}else
54221da177e4SLinus Torvalds 				{
5423*47b5d69cSJames Bottomley  					if(FPT_BL_Card[p_card].discQCount != 0)
5424*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQCount--;
5425*47b5d69cSJames Bottomley  					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
54261da177e4SLinus Torvalds 				}
54271da177e4SLinus Torvalds 			}
54281da177e4SLinus Torvalds          return;
54291da177e4SLinus Torvalds 
54301da177e4SLinus Torvalds          }
54311da177e4SLinus Torvalds 
54321da177e4SLinus Torvalds 	   if (status_byte == SSCHECK)
54331da177e4SLinus Torvalds 		{
5434*47b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
54351da177e4SLinus Torvalds 			{
5436*47b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
54371da177e4SLinus Torvalds 				{
5438*47b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
54391da177e4SLinus Torvalds 				}
5440*47b5d69cSJames Bottomley  				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
54411da177e4SLinus Torvalds 				{
5442*47b5d69cSJames Bottomley  					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
54431da177e4SLinus Torvalds 				}
54441da177e4SLinus Torvalds 			}
54451da177e4SLinus Torvalds 		}
54461da177e4SLinus Torvalds 
54471da177e4SLinus Torvalds       if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
54481da177e4SLinus Torvalds 
54491da177e4SLinus Torvalds          currSCCB->SccbStatus = SCCB_ERROR;
54501da177e4SLinus Torvalds          currSCCB->TargetStatus = status_byte;
54511da177e4SLinus Torvalds 
54521da177e4SLinus Torvalds          if (status_byte == SSCHECK) {
54531da177e4SLinus Torvalds 
5454*47b5d69cSJames Bottomley              FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5455*47b5d69cSJames Bottomley                 = 1;
54561da177e4SLinus Torvalds 
54571da177e4SLinus Torvalds 
54581da177e4SLinus Torvalds             if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
54591da177e4SLinus Torvalds 
54601da177e4SLinus Torvalds                if (currSCCB->RequestSenseLength == 0)
54611da177e4SLinus Torvalds                   currSCCB->RequestSenseLength = 14;
54621da177e4SLinus Torvalds 
5463*47b5d69cSJames Bottomley                 FPT_ssenss(&FPT_BL_Card[p_card]);
5464*47b5d69cSJames Bottomley                 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
54651da177e4SLinus Torvalds 
5466*47b5d69cSJames Bottomley   					if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5467*47b5d69cSJames Bottomley  						((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
54681da177e4SLinus Torvalds 					{
5469*47b5d69cSJames Bottomley  			         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5470*47b5d69cSJames Bottomley  						if(FPT_BL_Card[p_card].discQCount != 0)
5471*47b5d69cSJames Bottomley  							FPT_BL_Card[p_card].discQCount--;
5472*47b5d69cSJames Bottomley  						FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
54731da177e4SLinus Torvalds 					}
54741da177e4SLinus Torvalds 					else
54751da177e4SLinus Torvalds 					{
5476*47b5d69cSJames Bottomley  	   		      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
54771da177e4SLinus Torvalds 						if(currSCCB->Sccb_tag)
54781da177e4SLinus Torvalds 						{
5479*47b5d69cSJames Bottomley  							if(FPT_BL_Card[p_card].discQCount != 0)
5480*47b5d69cSJames Bottomley  								FPT_BL_Card[p_card].discQCount--;
5481*47b5d69cSJames Bottomley  							FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
54821da177e4SLinus Torvalds 						}else
54831da177e4SLinus Torvalds 						{
5484*47b5d69cSJames Bottomley  							if(FPT_BL_Card[p_card].discQCount != 0)
5485*47b5d69cSJames Bottomley  								FPT_BL_Card[p_card].discQCount--;
5486*47b5d69cSJames Bottomley  							FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
54871da177e4SLinus Torvalds 						}
54881da177e4SLinus Torvalds 					}
54891da177e4SLinus Torvalds                return;
54901da177e4SLinus Torvalds                }
54911da177e4SLinus Torvalds             }
5492*47b5d69cSJames Bottomley           }
5493*47b5d69cSJames Bottomley        }
5494*47b5d69cSJames Bottomley  
5495*47b5d69cSJames Bottomley  
5496*47b5d69cSJames Bottomley  	if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5497*47b5d69cSJames Bottomley  		((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5498*47b5d69cSJames Bottomley  	   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
54991da177e4SLinus Torvalds 	else
5500*47b5d69cSJames Bottomley  	   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5501*47b5d69cSJames Bottomley  
5502*47b5d69cSJames Bottomley  
5503*47b5d69cSJames Bottomley     FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
55041da177e4SLinus Torvalds }
55051da177e4SLinus Torvalds 
55061da177e4SLinus Torvalds #define SHORT_WAIT   0x0000000F
55071da177e4SLinus Torvalds #define LONG_WAIT    0x0000FFFFL
55081da177e4SLinus Torvalds 
55091da177e4SLinus Torvalds 
55101da177e4SLinus Torvalds /*---------------------------------------------------------------------
55111da177e4SLinus Torvalds  *
55121da177e4SLinus Torvalds  * Function: Data Transfer Processor
55131da177e4SLinus Torvalds  *
55141da177e4SLinus Torvalds  * Description: This routine performs two tasks.
55151da177e4SLinus Torvalds  *              (1) Start data transfer by calling HOST_DATA_XFER_START
55161da177e4SLinus Torvalds  *              function.  Once data transfer is started, (2) Depends
55171da177e4SLinus Torvalds  *              on the type of data transfer mode Scatter/Gather mode
55181da177e4SLinus Torvalds  *              or NON Scatter/Gather mode.  In NON Scatter/Gather mode,
55191da177e4SLinus Torvalds  *              this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
55201da177e4SLinus Torvalds  *              data transfer done.  In Scatter/Gather mode, this routine
55211da177e4SLinus Torvalds  *              checks bus master command complete and dual rank busy
55221da177e4SLinus Torvalds  *              bit to keep chaining SC transfer command.  Similarly,
55231da177e4SLinus Torvalds  *              in Scatter/Gather mode, it checks Sccb_MGRFlag
55241da177e4SLinus Torvalds  *              (F_HOST_XFER_ACT bit) for data transfer done.
55251da177e4SLinus Torvalds  *
55261da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
55271da177e4SLinus Torvalds 
5528*47b5d69cSJames Bottomley  static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
55291da177e4SLinus Torvalds {
55301da177e4SLinus Torvalds    PSCCB currSCCB;
55311da177e4SLinus Torvalds 
55321da177e4SLinus Torvalds    currSCCB = pCurrCard->currentSCCB;
55331da177e4SLinus Torvalds 
55341da177e4SLinus Torvalds       if (currSCCB->Sccb_XferState & F_SG_XFER)
55351da177e4SLinus Torvalds 			{
55361da177e4SLinus Torvalds 			if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
55371da177e4SLinus Torvalds 
55381da177e4SLinus Torvalds 				{
55391da177e4SLinus Torvalds 		   	currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
55401da177e4SLinus Torvalds          	currSCCB->Sccb_SGoffset = 0x00;
55411da177e4SLinus Torvalds  				}
55421da177e4SLinus Torvalds 			pCurrCard->globalFlags |= F_HOST_XFER_ACT;
55431da177e4SLinus Torvalds 
5544*47b5d69cSJames Bottomley           FPT_busMstrSGDataXferStart(port, currSCCB);
55451da177e4SLinus Torvalds 			}
55461da177e4SLinus Torvalds 
55471da177e4SLinus Torvalds       else
55481da177e4SLinus Torvalds 			{
55491da177e4SLinus Torvalds 			if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
55501da177e4SLinus Torvalds 				{
55511da177e4SLinus Torvalds 				pCurrCard->globalFlags |= F_HOST_XFER_ACT;
55521da177e4SLinus Torvalds 
5553*47b5d69cSJames Bottomley           	FPT_busMstrDataXferStart(port, currSCCB);
55541da177e4SLinus Torvalds          	}
55551da177e4SLinus Torvalds 			}
55561da177e4SLinus Torvalds }
55571da177e4SLinus Torvalds 
55581da177e4SLinus Torvalds 
55591da177e4SLinus Torvalds /*---------------------------------------------------------------------
55601da177e4SLinus Torvalds  *
55611da177e4SLinus Torvalds  * Function: BusMaster Scatter Gather Data Transfer Start
55621da177e4SLinus Torvalds  *
55631da177e4SLinus Torvalds  * Description:
55641da177e4SLinus Torvalds  *
55651da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
5566*47b5d69cSJames Bottomley  static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
55671da177e4SLinus Torvalds {
55681da177e4SLinus Torvalds    ULONG count,addr,tmpSGCnt;
55691da177e4SLinus Torvalds    UINT sg_index;
55701da177e4SLinus Torvalds    UCHAR sg_count, i;
55711da177e4SLinus Torvalds    ULONG reg_offset;
55721da177e4SLinus Torvalds 
55731da177e4SLinus Torvalds 
55741da177e4SLinus Torvalds    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
55751da177e4SLinus Torvalds 
55761da177e4SLinus Torvalds       count =  ((ULONG) HOST_RD_CMD)<<24;
55771da177e4SLinus Torvalds       }
55781da177e4SLinus Torvalds 
55791da177e4SLinus Torvalds    else {
55801da177e4SLinus Torvalds       count =  ((ULONG) HOST_WRT_CMD)<<24;
55811da177e4SLinus Torvalds       }
55821da177e4SLinus Torvalds 
55831da177e4SLinus Torvalds    sg_count = 0;
55841da177e4SLinus Torvalds    tmpSGCnt = 0;
55851da177e4SLinus Torvalds    sg_index = pcurrSCCB->Sccb_sgseg;
55861da177e4SLinus Torvalds    reg_offset = hp_aramBase;
55871da177e4SLinus Torvalds 
55881da177e4SLinus Torvalds 
55891da177e4SLinus Torvalds 	i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
55901da177e4SLinus Torvalds 
55911da177e4SLinus Torvalds 
55921da177e4SLinus Torvalds 	WR_HARPOON(p_port+hp_page_ctrl, i);
55931da177e4SLinus Torvalds 
55941da177e4SLinus Torvalds    while ((sg_count < (UCHAR)SG_BUF_CNT) &&
55951da177e4SLinus Torvalds       ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
55961da177e4SLinus Torvalds 
55971da177e4SLinus Torvalds       tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
55981da177e4SLinus Torvalds          (sg_index * 2));
55991da177e4SLinus Torvalds 
56001da177e4SLinus Torvalds       count |= *(((ULONG *)pcurrSCCB->DataPointer)+
56011da177e4SLinus Torvalds          (sg_index * 2));
56021da177e4SLinus Torvalds 
56031da177e4SLinus Torvalds       addr = *(((ULONG *)pcurrSCCB->DataPointer)+
56041da177e4SLinus Torvalds          ((sg_index * 2) + 1));
56051da177e4SLinus Torvalds 
56061da177e4SLinus Torvalds 
56071da177e4SLinus Torvalds       if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
56081da177e4SLinus Torvalds 
56091da177e4SLinus Torvalds          addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
56101da177e4SLinus Torvalds          count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
56111da177e4SLinus Torvalds 
56121da177e4SLinus Torvalds          tmpSGCnt = count & 0x00FFFFFFL;
56131da177e4SLinus Torvalds          }
56141da177e4SLinus Torvalds 
56151da177e4SLinus Torvalds       WR_HARP32(p_port,reg_offset,addr);
56161da177e4SLinus Torvalds       reg_offset +=4;
56171da177e4SLinus Torvalds 
56181da177e4SLinus Torvalds       WR_HARP32(p_port,reg_offset,count);
56191da177e4SLinus Torvalds       reg_offset +=4;
56201da177e4SLinus Torvalds 
56211da177e4SLinus Torvalds       count &= 0xFF000000L;
56221da177e4SLinus Torvalds       sg_index++;
56231da177e4SLinus Torvalds       sg_count++;
56241da177e4SLinus Torvalds 
56251da177e4SLinus Torvalds       } /*End While */
56261da177e4SLinus Torvalds 
56271da177e4SLinus Torvalds    pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
56281da177e4SLinus Torvalds 
56291da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
56301da177e4SLinus Torvalds 
56311da177e4SLinus Torvalds    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
56321da177e4SLinus Torvalds 
56331da177e4SLinus Torvalds       WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
56341da177e4SLinus Torvalds 
56351da177e4SLinus Torvalds 
56361da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
56371da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
56381da177e4SLinus Torvalds       }
56391da177e4SLinus Torvalds 
56401da177e4SLinus Torvalds    else {
56411da177e4SLinus Torvalds 
56421da177e4SLinus Torvalds 
56431da177e4SLinus Torvalds       if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
56441da177e4SLinus Torvalds          (tmpSGCnt & 0x000000001))
56451da177e4SLinus Torvalds          {
56461da177e4SLinus Torvalds 
56471da177e4SLinus Torvalds          pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
56481da177e4SLinus Torvalds          tmpSGCnt--;
56491da177e4SLinus Torvalds          }
56501da177e4SLinus Torvalds 
56511da177e4SLinus Torvalds 
56521da177e4SLinus Torvalds       WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
56531da177e4SLinus Torvalds 
56541da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
56551da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
56561da177e4SLinus Torvalds       }
56571da177e4SLinus Torvalds 
56581da177e4SLinus Torvalds 
56591da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
56601da177e4SLinus Torvalds 
56611da177e4SLinus Torvalds }
56621da177e4SLinus Torvalds 
56631da177e4SLinus Torvalds 
56641da177e4SLinus Torvalds /*---------------------------------------------------------------------
56651da177e4SLinus Torvalds  *
56661da177e4SLinus Torvalds  * Function: BusMaster Data Transfer Start
56671da177e4SLinus Torvalds  *
56681da177e4SLinus Torvalds  * Description:
56691da177e4SLinus Torvalds  *
56701da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
5671*47b5d69cSJames Bottomley  static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
56721da177e4SLinus Torvalds {
56731da177e4SLinus Torvalds    ULONG addr,count;
56741da177e4SLinus Torvalds 
56751da177e4SLinus Torvalds    if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
56761da177e4SLinus Torvalds 
56771da177e4SLinus Torvalds       count = pcurrSCCB->Sccb_XferCnt;
56781da177e4SLinus Torvalds 
56791da177e4SLinus Torvalds       addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
56801da177e4SLinus Torvalds       }
56811da177e4SLinus Torvalds 
56821da177e4SLinus Torvalds    else {
56831da177e4SLinus Torvalds       addr = pcurrSCCB->SensePointer;
56841da177e4SLinus Torvalds       count = pcurrSCCB->RequestSenseLength;
56851da177e4SLinus Torvalds 
56861da177e4SLinus Torvalds       }
56871da177e4SLinus Torvalds 
56881da177e4SLinus Torvalds    HP_SETUP_ADDR_CNT(p_port,addr,count);
56891da177e4SLinus Torvalds 
56901da177e4SLinus Torvalds 
56911da177e4SLinus Torvalds    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
56921da177e4SLinus Torvalds 
56931da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
56941da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
56951da177e4SLinus Torvalds 
56961da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_xfer_cmd,
56971da177e4SLinus Torvalds          (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
56981da177e4SLinus Torvalds       }
56991da177e4SLinus Torvalds 
57001da177e4SLinus Torvalds    else {
57011da177e4SLinus Torvalds 
57021da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
57031da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
57041da177e4SLinus Torvalds 
57051da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_xfer_cmd,
57061da177e4SLinus Torvalds          (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
57071da177e4SLinus Torvalds 
57081da177e4SLinus Torvalds       }
57091da177e4SLinus Torvalds }
57101da177e4SLinus Torvalds 
57111da177e4SLinus Torvalds 
57121da177e4SLinus Torvalds /*---------------------------------------------------------------------
57131da177e4SLinus Torvalds  *
57141da177e4SLinus Torvalds  * Function: BusMaster Timeout Handler
57151da177e4SLinus Torvalds  *
57161da177e4SLinus Torvalds  * Description: This function is called after a bus master command busy time
57171da177e4SLinus Torvalds  *               out is detected.  This routines issue halt state machine
57181da177e4SLinus Torvalds  *               with a software time out for command busy.  If command busy
57191da177e4SLinus Torvalds  *               is still asserted at the end of the time out, it issues
57201da177e4SLinus Torvalds  *               hard abort with another software time out.  It hard abort
57211da177e4SLinus Torvalds  *               command busy is also time out, it'll just give up.
57221da177e4SLinus Torvalds  *
57231da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
5724*47b5d69cSJames Bottomley  static UCHAR FPT_busMstrTimeOut(ULONG p_port)
57251da177e4SLinus Torvalds {
57261da177e4SLinus Torvalds    ULONG timeout;
57271da177e4SLinus Torvalds 
57281da177e4SLinus Torvalds    timeout = LONG_WAIT;
57291da177e4SLinus Torvalds 
57301da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
57311da177e4SLinus Torvalds 
57321da177e4SLinus Torvalds    while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
57331da177e4SLinus Torvalds 
57341da177e4SLinus Torvalds 
57351da177e4SLinus Torvalds 
57361da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
57371da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
57381da177e4SLinus Torvalds 
57391da177e4SLinus Torvalds       timeout = LONG_WAIT;
57401da177e4SLinus Torvalds       while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
57411da177e4SLinus Torvalds       }
57421da177e4SLinus Torvalds 
57431da177e4SLinus Torvalds    RD_HARPOON(p_port+hp_int_status);           /*Clear command complete */
57441da177e4SLinus Torvalds 
57451da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5746*47b5d69cSJames Bottomley        return(1);
57471da177e4SLinus Torvalds       }
57481da177e4SLinus Torvalds 
57491da177e4SLinus Torvalds    else {
5750*47b5d69cSJames Bottomley        return(0);
57511da177e4SLinus Torvalds       }
57521da177e4SLinus Torvalds }
57531da177e4SLinus Torvalds 
57541da177e4SLinus Torvalds 
57551da177e4SLinus Torvalds /*---------------------------------------------------------------------
57561da177e4SLinus Torvalds  *
57571da177e4SLinus Torvalds  * Function: Host Data Transfer Abort
57581da177e4SLinus Torvalds  *
57591da177e4SLinus Torvalds  * Description: Abort any in progress transfer.
57601da177e4SLinus Torvalds  *
57611da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
5762*47b5d69cSJames Bottomley  static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
57631da177e4SLinus Torvalds {
57641da177e4SLinus Torvalds 
57651da177e4SLinus Torvalds    ULONG timeout;
57661da177e4SLinus Torvalds    ULONG remain_cnt;
57671da177e4SLinus Torvalds    UINT sg_ptr;
57681da177e4SLinus Torvalds 
5769*47b5d69cSJames Bottomley     FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
57701da177e4SLinus Torvalds 
57711da177e4SLinus Torvalds    if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
57721da177e4SLinus Torvalds 
57731da177e4SLinus Torvalds 
57741da177e4SLinus Torvalds       if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
57751da177e4SLinus Torvalds 
57761da177e4SLinus Torvalds          WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
57771da177e4SLinus Torvalds          timeout = LONG_WAIT;
57781da177e4SLinus Torvalds 
57791da177e4SLinus Torvalds          while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
57801da177e4SLinus Torvalds 
57811da177e4SLinus Torvalds          WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
57821da177e4SLinus Torvalds 
57831da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
57841da177e4SLinus Torvalds 
5785*47b5d69cSJames Bottomley              if (FPT_busMstrTimeOut(port)) {
57861da177e4SLinus Torvalds 
57871da177e4SLinus Torvalds                if (pCurrSCCB->HostStatus == 0x00)
57881da177e4SLinus Torvalds 
57891da177e4SLinus Torvalds                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
57901da177e4SLinus Torvalds 
57911da177e4SLinus Torvalds                }
57921da177e4SLinus Torvalds 
57931da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
57941da177e4SLinus Torvalds 
57951da177e4SLinus Torvalds                if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
57961da177e4SLinus Torvalds 
57971da177e4SLinus Torvalds                   if (pCurrSCCB->HostStatus == 0x00)
57981da177e4SLinus Torvalds 
57991da177e4SLinus Torvalds                      {
58001da177e4SLinus Torvalds                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
58011da177e4SLinus Torvalds                      }
58021da177e4SLinus Torvalds             }
58031da177e4SLinus Torvalds          }
58041da177e4SLinus Torvalds       }
58051da177e4SLinus Torvalds 
58061da177e4SLinus Torvalds    else if (pCurrSCCB->Sccb_XferCnt) {
58071da177e4SLinus Torvalds 
58081da177e4SLinus Torvalds       if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
58091da177e4SLinus Torvalds 
58101da177e4SLinus Torvalds 
58111da177e4SLinus Torvalds               WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
58121da177e4SLinus Torvalds             ~SCATTER_EN));
58131da177e4SLinus Torvalds 
58141da177e4SLinus Torvalds          WR_HARPOON(port+hp_sg_addr,0x00);
58151da177e4SLinus Torvalds 
58161da177e4SLinus Torvalds          sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
58171da177e4SLinus Torvalds 
58181da177e4SLinus Torvalds          if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
58191da177e4SLinus Torvalds 
58201da177e4SLinus Torvalds             sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
58211da177e4SLinus Torvalds             }
58221da177e4SLinus Torvalds 
58231da177e4SLinus Torvalds          remain_cnt = pCurrSCCB->Sccb_XferCnt;
58241da177e4SLinus Torvalds 
58251da177e4SLinus Torvalds          while (remain_cnt < 0x01000000L) {
58261da177e4SLinus Torvalds 
58271da177e4SLinus Torvalds             sg_ptr--;
58281da177e4SLinus Torvalds 
58291da177e4SLinus Torvalds             if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
58301da177e4SLinus Torvalds                DataPointer) + (sg_ptr * 2)))) {
58311da177e4SLinus Torvalds 
58321da177e4SLinus Torvalds                remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
58331da177e4SLinus Torvalds                   DataPointer) + (sg_ptr * 2)));
58341da177e4SLinus Torvalds                }
58351da177e4SLinus Torvalds 
58361da177e4SLinus Torvalds             else {
58371da177e4SLinus Torvalds 
58381da177e4SLinus Torvalds                break;
58391da177e4SLinus Torvalds                }
58401da177e4SLinus Torvalds             }
58411da177e4SLinus Torvalds 
58421da177e4SLinus Torvalds 
58431da177e4SLinus Torvalds 
58441da177e4SLinus Torvalds          if (remain_cnt < 0x01000000L) {
58451da177e4SLinus Torvalds 
58461da177e4SLinus Torvalds 
58471da177e4SLinus Torvalds             pCurrSCCB->Sccb_SGoffset = remain_cnt;
58481da177e4SLinus Torvalds 
58491da177e4SLinus Torvalds             pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
58501da177e4SLinus Torvalds 
58511da177e4SLinus Torvalds 
58521da177e4SLinus Torvalds             if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
58531da177e4SLinus Torvalds                 && (remain_cnt == 0))
58541da177e4SLinus Torvalds 
58551da177e4SLinus Torvalds                pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
58561da177e4SLinus Torvalds             }
58571da177e4SLinus Torvalds 
58581da177e4SLinus Torvalds          else {
58591da177e4SLinus Torvalds 
58601da177e4SLinus Torvalds 
58611da177e4SLinus Torvalds             if (pCurrSCCB->HostStatus == 0x00) {
58621da177e4SLinus Torvalds 
58631da177e4SLinus Torvalds                pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
58641da177e4SLinus Torvalds                }
58651da177e4SLinus Torvalds             }
58661da177e4SLinus Torvalds          }
58671da177e4SLinus Torvalds 
58681da177e4SLinus Torvalds 
58691da177e4SLinus Torvalds       if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
58701da177e4SLinus Torvalds 
58711da177e4SLinus Torvalds 
58721da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
58731da177e4SLinus Torvalds 
5874*47b5d69cSJames Bottomley              FPT_busMstrTimeOut(port);
58751da177e4SLinus Torvalds             }
58761da177e4SLinus Torvalds 
58771da177e4SLinus Torvalds          else {
58781da177e4SLinus Torvalds 
58791da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
58801da177e4SLinus Torvalds 
58811da177e4SLinus Torvalds                if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
58821da177e4SLinus Torvalds 
58831da177e4SLinus Torvalds                   if (pCurrSCCB->HostStatus == 0x00) {
58841da177e4SLinus Torvalds 
58851da177e4SLinus Torvalds                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
58861da177e4SLinus Torvalds                      }
58871da177e4SLinus Torvalds                   }
58881da177e4SLinus Torvalds                }
58891da177e4SLinus Torvalds 
58901da177e4SLinus Torvalds             }
58911da177e4SLinus Torvalds          }
58921da177e4SLinus Torvalds 
58931da177e4SLinus Torvalds       else {
58941da177e4SLinus Torvalds 
58951da177e4SLinus Torvalds 
58961da177e4SLinus Torvalds          if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
58971da177e4SLinus Torvalds 
58981da177e4SLinus Torvalds             timeout = SHORT_WAIT;
58991da177e4SLinus Torvalds 
59001da177e4SLinus Torvalds             while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
59011da177e4SLinus Torvalds                ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
59021da177e4SLinus Torvalds                timeout--) {}
59031da177e4SLinus Torvalds             }
59041da177e4SLinus Torvalds 
59051da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
59061da177e4SLinus Torvalds 
59071da177e4SLinus Torvalds             WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
59081da177e4SLinus Torvalds                FLUSH_XFER_CNTR));
59091da177e4SLinus Torvalds 
59101da177e4SLinus Torvalds             timeout = LONG_WAIT;
59111da177e4SLinus Torvalds 
59121da177e4SLinus Torvalds             while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
59131da177e4SLinus Torvalds                timeout--) {}
59141da177e4SLinus Torvalds 
59151da177e4SLinus Torvalds             WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
59161da177e4SLinus Torvalds                ~FLUSH_XFER_CNTR));
59171da177e4SLinus Torvalds 
59181da177e4SLinus Torvalds 
59191da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
59201da177e4SLinus Torvalds 
59211da177e4SLinus Torvalds                if (pCurrSCCB->HostStatus == 0x00) {
59221da177e4SLinus Torvalds 
59231da177e4SLinus Torvalds                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
59241da177e4SLinus Torvalds                   }
59251da177e4SLinus Torvalds 
5926*47b5d69cSJames Bottomley                 FPT_busMstrTimeOut(port);
59271da177e4SLinus Torvalds                }
59281da177e4SLinus Torvalds             }
59291da177e4SLinus Torvalds 
59301da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
59311da177e4SLinus Torvalds 
59321da177e4SLinus Torvalds             if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
59331da177e4SLinus Torvalds 
59341da177e4SLinus Torvalds                if (pCurrSCCB->HostStatus == 0x00) {
59351da177e4SLinus Torvalds 
59361da177e4SLinus Torvalds                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
59371da177e4SLinus Torvalds                   }
59381da177e4SLinus Torvalds                }
59391da177e4SLinus Torvalds             }
59401da177e4SLinus Torvalds          }
59411da177e4SLinus Torvalds 
59421da177e4SLinus Torvalds       }
59431da177e4SLinus Torvalds 
59441da177e4SLinus Torvalds    else {
59451da177e4SLinus Torvalds 
59461da177e4SLinus Torvalds 
59471da177e4SLinus Torvalds       if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
59481da177e4SLinus Torvalds 
59491da177e4SLinus Torvalds          timeout = LONG_WAIT;
59501da177e4SLinus Torvalds 
59511da177e4SLinus Torvalds          while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
59521da177e4SLinus Torvalds 
59531da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
59541da177e4SLinus Torvalds 
59551da177e4SLinus Torvalds             if (pCurrSCCB->HostStatus == 0x00) {
59561da177e4SLinus Torvalds 
59571da177e4SLinus Torvalds                pCurrSCCB->HostStatus = SCCB_BM_ERR;
59581da177e4SLinus Torvalds                }
59591da177e4SLinus Torvalds 
5960*47b5d69cSJames Bottomley              FPT_busMstrTimeOut(port);
59611da177e4SLinus Torvalds             }
59621da177e4SLinus Torvalds          }
59631da177e4SLinus Torvalds 
59641da177e4SLinus Torvalds 
59651da177e4SLinus Torvalds       if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
59661da177e4SLinus Torvalds 
59671da177e4SLinus Torvalds          if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
59681da177e4SLinus Torvalds 
59691da177e4SLinus Torvalds             if (pCurrSCCB->HostStatus == 0x00) {
59701da177e4SLinus Torvalds 
59711da177e4SLinus Torvalds                pCurrSCCB->HostStatus = SCCB_BM_ERR;
59721da177e4SLinus Torvalds                }
59731da177e4SLinus Torvalds             }
59741da177e4SLinus Torvalds 
59751da177e4SLinus Torvalds          }
59761da177e4SLinus Torvalds 
59771da177e4SLinus Torvalds       if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
59781da177e4SLinus Torvalds 
59791da177e4SLinus Torvalds          WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
59801da177e4SLinus Torvalds                  ~SCATTER_EN));
59811da177e4SLinus Torvalds 
59821da177e4SLinus Torvalds          WR_HARPOON(port+hp_sg_addr,0x00);
59831da177e4SLinus Torvalds 
59841da177e4SLinus Torvalds          pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
59851da177e4SLinus Torvalds 
59861da177e4SLinus Torvalds          pCurrSCCB->Sccb_SGoffset = 0x00;
59871da177e4SLinus Torvalds 
59881da177e4SLinus Torvalds 
59891da177e4SLinus Torvalds          if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
59901da177e4SLinus Torvalds             pCurrSCCB->DataLength) {
59911da177e4SLinus Torvalds 
59921da177e4SLinus Torvalds             pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
59931da177e4SLinus Torvalds 
59941da177e4SLinus Torvalds             pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
59951da177e4SLinus Torvalds 
59961da177e4SLinus Torvalds             }
59971da177e4SLinus Torvalds          }
59981da177e4SLinus Torvalds 
59991da177e4SLinus Torvalds       else {
60001da177e4SLinus Torvalds 
60011da177e4SLinus Torvalds          if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
60021da177e4SLinus Torvalds 
60031da177e4SLinus Torvalds             pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
60041da177e4SLinus Torvalds          }
60051da177e4SLinus Torvalds       }
60061da177e4SLinus Torvalds 
60071da177e4SLinus Torvalds    WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
60081da177e4SLinus Torvalds }
60091da177e4SLinus Torvalds 
60101da177e4SLinus Torvalds 
60111da177e4SLinus Torvalds 
60121da177e4SLinus Torvalds /*---------------------------------------------------------------------
60131da177e4SLinus Torvalds  *
60141da177e4SLinus Torvalds  * Function: Host Data Transfer Restart
60151da177e4SLinus Torvalds  *
60161da177e4SLinus Torvalds  * Description: Reset the available count due to a restore data
60171da177e4SLinus Torvalds  *              pointers message.
60181da177e4SLinus Torvalds  *
60191da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
6020*47b5d69cSJames Bottomley  static void FPT_hostDataXferRestart(PSCCB currSCCB)
60211da177e4SLinus Torvalds {
60221da177e4SLinus Torvalds    ULONG data_count;
60231da177e4SLinus Torvalds    UINT  sg_index;
60241da177e4SLinus Torvalds    ULONG *sg_ptr;
60251da177e4SLinus Torvalds 
60261da177e4SLinus Torvalds    if (currSCCB->Sccb_XferState & F_SG_XFER) {
60271da177e4SLinus Torvalds 
60281da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = 0;
60291da177e4SLinus Torvalds 
60301da177e4SLinus Torvalds       sg_index = 0xffff;         /*Index by long words into sg list. */
60311da177e4SLinus Torvalds       data_count = 0;            /*Running count of SG xfer counts. */
60321da177e4SLinus Torvalds 
60331da177e4SLinus Torvalds       sg_ptr = (ULONG *)currSCCB->DataPointer;
60341da177e4SLinus Torvalds 
60351da177e4SLinus Torvalds       while (data_count < currSCCB->Sccb_ATC) {
60361da177e4SLinus Torvalds 
60371da177e4SLinus Torvalds          sg_index++;
60381da177e4SLinus Torvalds          data_count += *(sg_ptr+(sg_index * 2));
60391da177e4SLinus Torvalds          }
60401da177e4SLinus Torvalds 
60411da177e4SLinus Torvalds       if (data_count == currSCCB->Sccb_ATC) {
60421da177e4SLinus Torvalds 
60431da177e4SLinus Torvalds          currSCCB->Sccb_SGoffset = 0;
60441da177e4SLinus Torvalds          sg_index++;
60451da177e4SLinus Torvalds          }
60461da177e4SLinus Torvalds 
60471da177e4SLinus Torvalds       else {
60481da177e4SLinus Torvalds          currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
60491da177e4SLinus Torvalds          }
60501da177e4SLinus Torvalds 
60511da177e4SLinus Torvalds       currSCCB->Sccb_sgseg = (USHORT)sg_index;
60521da177e4SLinus Torvalds       }
60531da177e4SLinus Torvalds 
60541da177e4SLinus Torvalds    else {
60551da177e4SLinus Torvalds       currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
60561da177e4SLinus Torvalds       }
60571da177e4SLinus Torvalds }
60581da177e4SLinus Torvalds 
60591da177e4SLinus Torvalds 
60601da177e4SLinus Torvalds 
60611da177e4SLinus Torvalds /*---------------------------------------------------------------------
60621da177e4SLinus Torvalds  *
6063*47b5d69cSJames Bottomley   * Function: FPT_scini
60641da177e4SLinus Torvalds  *
60651da177e4SLinus Torvalds  * Description: Setup all data structures necessary for SCAM selection.
60661da177e4SLinus Torvalds  *
60671da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
60681da177e4SLinus Torvalds 
6069*47b5d69cSJames Bottomley  static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
60701da177e4SLinus Torvalds {
60711da177e4SLinus Torvalds 
60721da177e4SLinus Torvalds    UCHAR loser,assigned_id;
60731da177e4SLinus Torvalds    ULONG p_port;
60741da177e4SLinus Torvalds 
60751da177e4SLinus Torvalds    UCHAR i,k,ScamFlg ;
60761da177e4SLinus Torvalds    PSCCBcard currCard;
60771da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
60781da177e4SLinus Torvalds 
6079*47b5d69cSJames Bottomley     currCard = &FPT_BL_Card[p_card];
60801da177e4SLinus Torvalds    p_port = currCard->ioPort;
60811da177e4SLinus Torvalds 	pCurrNvRam = currCard->pNvRamInfo;
60821da177e4SLinus Torvalds 
60831da177e4SLinus Torvalds 
60841da177e4SLinus Torvalds 	if(pCurrNvRam){
60851da177e4SLinus Torvalds 		ScamFlg = pCurrNvRam->niScamConf;
60861da177e4SLinus Torvalds 		i = pCurrNvRam->niSysConf;
60871da177e4SLinus Torvalds 	}
60881da177e4SLinus Torvalds 	else{
6089*47b5d69cSJames Bottomley  	   ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
6090*47b5d69cSJames Bottomley  	   i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
60911da177e4SLinus Torvalds 	}
60921da177e4SLinus Torvalds 	if(!(i & 0x02))	/* check if reset bus in AutoSCSI parameter set */
60931da177e4SLinus Torvalds 		return;
60941da177e4SLinus Torvalds 
6095*47b5d69cSJames Bottomley     FPT_inisci(p_card,p_port, p_our_id);
60961da177e4SLinus Torvalds 
60971da177e4SLinus Torvalds    /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
60981da177e4SLinus Torvalds       too slow to return to SCAM selection */
60991da177e4SLinus Torvalds 
61001da177e4SLinus Torvalds    /* if (p_power_up)
6101*47b5d69cSJames Bottomley           FPT_Wait1Second(p_port);
61021da177e4SLinus Torvalds       else
6103*47b5d69cSJames Bottomley           FPT_Wait(p_port, TO_250ms); */
61041da177e4SLinus Torvalds 
6105*47b5d69cSJames Bottomley     FPT_Wait1Second(p_port);
61061da177e4SLinus Torvalds 
61071da177e4SLinus Torvalds    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
61081da177e4SLinus Torvalds       {
6109*47b5d69cSJames Bottomley        while (!(FPT_scarb(p_port,INIT_SELTD))) {}
61101da177e4SLinus Torvalds 
6111*47b5d69cSJames Bottomley        FPT_scsel(p_port);
61121da177e4SLinus Torvalds 
61131da177e4SLinus Torvalds       do {
6114*47b5d69cSJames Bottomley           FPT_scxferc(p_port,SYNC_PTRN);
6115*47b5d69cSJames Bottomley           FPT_scxferc(p_port,DOM_MSTR);
6116*47b5d69cSJames Bottomley           loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
61171da177e4SLinus Torvalds          } while ( loser == 0xFF );
61181da177e4SLinus Torvalds 
6119*47b5d69cSJames Bottomley        FPT_scbusf(p_port);
61201da177e4SLinus Torvalds 
61211da177e4SLinus Torvalds       if ((p_power_up) && (!loser))
61221da177e4SLinus Torvalds          {
6123*47b5d69cSJames Bottomley           FPT_sresb(p_port,p_card);
6124*47b5d69cSJames Bottomley           FPT_Wait(p_port, TO_250ms);
61251da177e4SLinus Torvalds 
6126*47b5d69cSJames Bottomley           while (!(FPT_scarb(p_port,INIT_SELTD))) {}
61271da177e4SLinus Torvalds 
6128*47b5d69cSJames Bottomley           FPT_scsel(p_port);
61291da177e4SLinus Torvalds 
61301da177e4SLinus Torvalds          do {
6131*47b5d69cSJames Bottomley              FPT_scxferc(p_port, SYNC_PTRN);
6132*47b5d69cSJames Bottomley              FPT_scxferc(p_port, DOM_MSTR);
6133*47b5d69cSJames Bottomley              loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
61341da177e4SLinus Torvalds                id_string[0]);
61351da177e4SLinus Torvalds             } while ( loser == 0xFF );
61361da177e4SLinus Torvalds 
6137*47b5d69cSJames Bottomley           FPT_scbusf(p_port);
61381da177e4SLinus Torvalds          }
61391da177e4SLinus Torvalds       }
61401da177e4SLinus Torvalds 
61411da177e4SLinus Torvalds    else
61421da177e4SLinus Torvalds       {
6143*47b5d69cSJames Bottomley        loser = 0;
61441da177e4SLinus Torvalds       }
61451da177e4SLinus Torvalds 
61461da177e4SLinus Torvalds 
61471da177e4SLinus Torvalds    if (!loser)
61481da177e4SLinus Torvalds       {
61491da177e4SLinus Torvalds 
6150*47b5d69cSJames Bottomley        FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
61511da177e4SLinus Torvalds 
61521da177e4SLinus Torvalds 
61531da177e4SLinus Torvalds 		if (ScamFlg & SCAM_ENABLED)
61541da177e4SLinus Torvalds 		{
61551da177e4SLinus Torvalds 
61561da177e4SLinus Torvalds 	      for (i=0; i < MAX_SCSI_TAR; i++)
61571da177e4SLinus Torvalds   		   {
6158*47b5d69cSJames Bottomley        	   if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
6159*47b5d69cSJames Bottomley    	      	   (FPT_scamInfo[i].state == ID_UNUSED))
61601da177e4SLinus Torvalds 	  	      {
6161*47b5d69cSJames Bottomley     	     	   if (FPT_scsell(p_port,i))
61621da177e4SLinus Torvalds       	  	   {
6163*47b5d69cSJames Bottomley              	   FPT_scamInfo[i].state = LEGACY;
6164*47b5d69cSJames Bottomley    	            	if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
6165*47b5d69cSJames Bottomley       	            	(FPT_scamInfo[i].id_string[1] != 0xFA))
61661da177e4SLinus Torvalds 	     	         {
61671da177e4SLinus Torvalds 
6168*47b5d69cSJames Bottomley     	        	      FPT_scamInfo[i].id_string[0] = 0xFF;
6169*47b5d69cSJames Bottomley        	        	   FPT_scamInfo[i].id_string[1] = 0xFA;
61701da177e4SLinus Torvalds 							if(pCurrNvRam == NULL)
61711da177e4SLinus Torvalds 	         	         currCard->globalFlags |= F_UPDATE_EEPROM;
61721da177e4SLinus Torvalds                	}
61731da177e4SLinus Torvalds 	  	         }
61741da177e4SLinus Torvalds    	  	   }
61751da177e4SLinus Torvalds       	}
61761da177e4SLinus Torvalds 
6177*47b5d69cSJames Bottomley  	      FPT_sresb(p_port,p_card);
6178*47b5d69cSJames Bottomley        	FPT_Wait1Second(p_port);
6179*47b5d69cSJames Bottomley           while (!(FPT_scarb(p_port,INIT_SELTD))) {}
6180*47b5d69cSJames Bottomley           FPT_scsel(p_port);
6181*47b5d69cSJames Bottomley           FPT_scasid(p_card, p_port);
61821da177e4SLinus Torvalds          }
61831da177e4SLinus Torvalds 
61841da177e4SLinus Torvalds       }
61851da177e4SLinus Torvalds 
61861da177e4SLinus Torvalds    else if ((loser) && (ScamFlg & SCAM_ENABLED))
61871da177e4SLinus Torvalds       {
6188*47b5d69cSJames Bottomley        FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
6189*47b5d69cSJames Bottomley        assigned_id = 0;
6190*47b5d69cSJames Bottomley        FPT_scwtsel(p_port);
61911da177e4SLinus Torvalds 
61921da177e4SLinus Torvalds       do {
6193*47b5d69cSJames Bottomley           while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
61941da177e4SLinus Torvalds 
6195*47b5d69cSJames Bottomley           i = FPT_scxferc(p_port,0x00);
61961da177e4SLinus Torvalds          if (i == ASSIGN_ID)
61971da177e4SLinus Torvalds             {
6198*47b5d69cSJames Bottomley              if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
61991da177e4SLinus Torvalds                   {
6200*47b5d69cSJames Bottomley                    i = FPT_scxferc(p_port,0x00);
6201*47b5d69cSJames Bottomley                    if (FPT_scvalq(i))
62021da177e4SLinus Torvalds                      {
6203*47b5d69cSJames Bottomley                       k = FPT_scxferc(p_port,0x00);
62041da177e4SLinus Torvalds 
6205*47b5d69cSJames Bottomley                       if (FPT_scvalq(k))
62061da177e4SLinus Torvalds                         {
62071da177e4SLinus Torvalds                         currCard->ourId =
62081da177e4SLinus Torvalds                            ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
6209*47b5d69cSJames Bottomley                          FPT_inisci(p_card, p_port, p_our_id);
6210*47b5d69cSJames Bottomley                          FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
6211*47b5d69cSJames Bottomley                          FPT_scamInfo[currCard->ourId].id_string[0]
62121da177e4SLinus Torvalds                            = SLV_TYPE_CODE0;
6213*47b5d69cSJames Bottomley                          assigned_id = 1;
62141da177e4SLinus Torvalds                         }
62151da177e4SLinus Torvalds                      }
62161da177e4SLinus Torvalds                   }
62171da177e4SLinus Torvalds             }
62181da177e4SLinus Torvalds 
62191da177e4SLinus Torvalds          else if (i == SET_P_FLAG)
62201da177e4SLinus Torvalds             {
6221*47b5d69cSJames Bottomley                 if (!(FPT_scsendi(p_port,
6222*47b5d69cSJames Bottomley                          &FPT_scamInfo[p_our_id].id_string[0])))
6223*47b5d69cSJames Bottomley                          FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
62241da177e4SLinus Torvalds             }
62251da177e4SLinus Torvalds          }while (!assigned_id);
62261da177e4SLinus Torvalds 
6227*47b5d69cSJames Bottomley        while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
62281da177e4SLinus Torvalds       }
62291da177e4SLinus Torvalds 
62301da177e4SLinus Torvalds    if (ScamFlg & SCAM_ENABLED)
62311da177e4SLinus Torvalds       {
6232*47b5d69cSJames Bottomley        FPT_scbusf(p_port);
62331da177e4SLinus Torvalds       if (currCard->globalFlags & F_UPDATE_EEPROM)
62341da177e4SLinus Torvalds          {
6235*47b5d69cSJames Bottomley           FPT_scsavdi(p_card, p_port);
62361da177e4SLinus Torvalds          currCard->globalFlags &= ~F_UPDATE_EEPROM;
62371da177e4SLinus Torvalds          }
62381da177e4SLinus Torvalds       }
62391da177e4SLinus Torvalds 
62401da177e4SLinus Torvalds 
62411da177e4SLinus Torvalds /*
62421da177e4SLinus Torvalds    for (i=0,k=0; i < MAX_SCSI_TAR; i++)
62431da177e4SLinus Torvalds       {
6244*47b5d69cSJames Bottomley        if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
6245*47b5d69cSJames Bottomley           (FPT_scamInfo[i].state == LEGACY))
62461da177e4SLinus Torvalds          k++;
62471da177e4SLinus Torvalds       }
62481da177e4SLinus Torvalds 
62491da177e4SLinus Torvalds    if (k==2)
62501da177e4SLinus Torvalds       currCard->globalFlags |= F_SINGLE_DEVICE;
62511da177e4SLinus Torvalds    else
62521da177e4SLinus Torvalds       currCard->globalFlags &= ~F_SINGLE_DEVICE;
62531da177e4SLinus Torvalds */
62541da177e4SLinus Torvalds }
62551da177e4SLinus Torvalds 
62561da177e4SLinus Torvalds 
62571da177e4SLinus Torvalds /*---------------------------------------------------------------------
62581da177e4SLinus Torvalds  *
6259*47b5d69cSJames Bottomley   * Function: FPT_scarb
62601da177e4SLinus Torvalds  *
62611da177e4SLinus Torvalds  * Description: Gain control of the bus and wait SCAM select time (250ms)
62621da177e4SLinus Torvalds  *
62631da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
62641da177e4SLinus Torvalds 
6265*47b5d69cSJames Bottomley  static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
62661da177e4SLinus Torvalds {
62671da177e4SLinus Torvalds    if (p_sel_type == INIT_SELTD)
62681da177e4SLinus Torvalds       {
62691da177e4SLinus Torvalds 
62701da177e4SLinus Torvalds       while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
62711da177e4SLinus Torvalds 
62721da177e4SLinus Torvalds 
62731da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
6274*47b5d69cSJames Bottomley           return(0);
62751da177e4SLinus Torvalds 
62761da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
6277*47b5d69cSJames Bottomley           return(0);
62781da177e4SLinus Torvalds 
62791da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
62801da177e4SLinus Torvalds 
62811da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
62821da177e4SLinus Torvalds 
62831da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
62841da177e4SLinus Torvalds             ~SCSI_BSY));
6285*47b5d69cSJames Bottomley           return(0);
62861da177e4SLinus Torvalds          }
62871da177e4SLinus Torvalds 
62881da177e4SLinus Torvalds 
62891da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
62901da177e4SLinus Torvalds 
62911da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
62921da177e4SLinus Torvalds 
62931da177e4SLinus Torvalds          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
62941da177e4SLinus Torvalds             ~(SCSI_BSY | SCSI_SEL)));
6295*47b5d69cSJames Bottomley           return(0);
62961da177e4SLinus Torvalds          }
62971da177e4SLinus Torvalds       }
62981da177e4SLinus Torvalds 
62991da177e4SLinus Torvalds 
63001da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
63011da177e4SLinus Torvalds       & ~ACTdeassert));
63021da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
63031da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
63041da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_1, 0x00);
63051da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
63061da177e4SLinus Torvalds 
63071da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
63081da177e4SLinus Torvalds 
63091da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
63101da177e4SLinus Torvalds       & ~SCSI_BSY));
63111da177e4SLinus Torvalds 
6312*47b5d69cSJames Bottomley     FPT_Wait(p_port,TO_250ms);
63131da177e4SLinus Torvalds 
6314*47b5d69cSJames Bottomley     return(1);
63151da177e4SLinus Torvalds }
63161da177e4SLinus Torvalds 
63171da177e4SLinus Torvalds 
63181da177e4SLinus Torvalds /*---------------------------------------------------------------------
63191da177e4SLinus Torvalds  *
6320*47b5d69cSJames Bottomley   * Function: FPT_scbusf
63211da177e4SLinus Torvalds  *
63221da177e4SLinus Torvalds  * Description: Release the SCSI bus and disable SCAM selection.
63231da177e4SLinus Torvalds  *
63241da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
63251da177e4SLinus Torvalds 
6326*47b5d69cSJames Bottomley  static void FPT_scbusf(ULONG p_port)
63271da177e4SLinus Torvalds {
63281da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl,
63291da177e4SLinus Torvalds       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
63301da177e4SLinus Torvalds 
63311da177e4SLinus Torvalds 
63321da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
63331da177e4SLinus Torvalds 
63341da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
63351da177e4SLinus Torvalds       & ~SCSI_BUS_EN));
63361da177e4SLinus Torvalds 
63371da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, 0x00);
63381da177e4SLinus Torvalds 
63391da177e4SLinus Torvalds 
63401da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsireset,  (RD_HARPOON(p_port+hp_scsireset)
63411da177e4SLinus Torvalds       & ~SCAM_EN));
63421da177e4SLinus Torvalds 
63431da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
63441da177e4SLinus Torvalds       | ACTdeassert));
63451da177e4SLinus Torvalds 
63461da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
63471da177e4SLinus Torvalds 
63481da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl,
63491da177e4SLinus Torvalds       (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
63501da177e4SLinus Torvalds }
63511da177e4SLinus Torvalds 
63521da177e4SLinus Torvalds 
63531da177e4SLinus Torvalds 
63541da177e4SLinus Torvalds /*---------------------------------------------------------------------
63551da177e4SLinus Torvalds  *
6356*47b5d69cSJames Bottomley   * Function: FPT_scasid
63571da177e4SLinus Torvalds  *
63581da177e4SLinus Torvalds  * Description: Assign an ID to all the SCAM devices.
63591da177e4SLinus Torvalds  *
63601da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
63611da177e4SLinus Torvalds 
6362*47b5d69cSJames Bottomley  static void FPT_scasid(UCHAR p_card, ULONG p_port)
63631da177e4SLinus Torvalds {
63641da177e4SLinus Torvalds    UCHAR temp_id_string[ID_STRING_LENGTH];
63651da177e4SLinus Torvalds 
63661da177e4SLinus Torvalds    UCHAR i,k,scam_id;
63671da177e4SLinus Torvalds 	UCHAR crcBytes[3];
63681da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
63691da177e4SLinus Torvalds 	ushort_ptr pCrcBytes;
63701da177e4SLinus Torvalds 
6371*47b5d69cSJames Bottomley  	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
63721da177e4SLinus Torvalds 
6373*47b5d69cSJames Bottomley     i=0;
63741da177e4SLinus Torvalds 
63751da177e4SLinus Torvalds    while (!i)
63761da177e4SLinus Torvalds       {
63771da177e4SLinus Torvalds 
63781da177e4SLinus Torvalds       for (k=0; k < ID_STRING_LENGTH; k++)
63791da177e4SLinus Torvalds          {
63801da177e4SLinus Torvalds          temp_id_string[k] = (UCHAR) 0x00;
63811da177e4SLinus Torvalds          }
63821da177e4SLinus Torvalds 
6383*47b5d69cSJames Bottomley        FPT_scxferc(p_port,SYNC_PTRN);
6384*47b5d69cSJames Bottomley        FPT_scxferc(p_port,ASSIGN_ID);
63851da177e4SLinus Torvalds 
6386*47b5d69cSJames Bottomley        if (!(FPT_sciso(p_port,&temp_id_string[0])))
63871da177e4SLinus Torvalds          {
63881da177e4SLinus Torvalds 			if(pCurrNvRam){
63891da177e4SLinus Torvalds 				pCrcBytes = (ushort_ptr)&crcBytes[0];
6390*47b5d69cSJames Bottomley  				*pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6391*47b5d69cSJames Bottomley  				crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
63921da177e4SLinus Torvalds 				temp_id_string[1] = crcBytes[2];
63931da177e4SLinus Torvalds 				temp_id_string[2] = crcBytes[0];
63941da177e4SLinus Torvalds 				temp_id_string[3] = crcBytes[1];
63951da177e4SLinus Torvalds 				for(k = 4; k < ID_STRING_LENGTH; k++)
63961da177e4SLinus Torvalds 					temp_id_string[k] = (UCHAR) 0x00;
63971da177e4SLinus Torvalds 			}
6398*47b5d69cSJames Bottomley           i = FPT_scmachid(p_card,temp_id_string);
63991da177e4SLinus Torvalds 
64001da177e4SLinus Torvalds          if (i == CLR_PRIORITY)
64011da177e4SLinus Torvalds             {
6402*47b5d69cSJames Bottomley              FPT_scxferc(p_port,MISC_CODE);
6403*47b5d69cSJames Bottomley              FPT_scxferc(p_port,CLR_P_FLAG);
6404*47b5d69cSJames Bottomley              i = 0;  /*Not the last ID yet. */
64051da177e4SLinus Torvalds             }
64061da177e4SLinus Torvalds 
64071da177e4SLinus Torvalds          else if (i != NO_ID_AVAIL)
64081da177e4SLinus Torvalds             {
64091da177e4SLinus Torvalds             if (i < 8 )
6410*47b5d69cSJames Bottomley                 FPT_scxferc(p_port,ID_0_7);
64111da177e4SLinus Torvalds             else
6412*47b5d69cSJames Bottomley                 FPT_scxferc(p_port,ID_8_F);
64131da177e4SLinus Torvalds 
64141da177e4SLinus Torvalds             scam_id = (i & (UCHAR) 0x07);
64151da177e4SLinus Torvalds 
64161da177e4SLinus Torvalds 
64171da177e4SLinus Torvalds             for (k=1; k < 0x08; k <<= 1)
64181da177e4SLinus Torvalds                if (!( k & i ))
64191da177e4SLinus Torvalds                   scam_id += 0x08;        /*Count number of zeros in DB0-3. */
64201da177e4SLinus Torvalds 
6421*47b5d69cSJames Bottomley              FPT_scxferc(p_port,scam_id);
64221da177e4SLinus Torvalds 
6423*47b5d69cSJames Bottomley              i = 0;  /*Not the last ID yet. */
64241da177e4SLinus Torvalds             }
64251da177e4SLinus Torvalds          }
64261da177e4SLinus Torvalds 
64271da177e4SLinus Torvalds       else
64281da177e4SLinus Torvalds          {
6429*47b5d69cSJames Bottomley           i = 1;
64301da177e4SLinus Torvalds          }
64311da177e4SLinus Torvalds 
64321da177e4SLinus Torvalds       }  /*End while */
64331da177e4SLinus Torvalds 
6434*47b5d69cSJames Bottomley     FPT_scxferc(p_port,SYNC_PTRN);
6435*47b5d69cSJames Bottomley     FPT_scxferc(p_port,CFG_CMPLT);
64361da177e4SLinus Torvalds }
64371da177e4SLinus Torvalds 
64381da177e4SLinus Torvalds 
64391da177e4SLinus Torvalds 
64401da177e4SLinus Torvalds 
64411da177e4SLinus Torvalds 
64421da177e4SLinus Torvalds /*---------------------------------------------------------------------
64431da177e4SLinus Torvalds  *
6444*47b5d69cSJames Bottomley   * Function: FPT_scsel
64451da177e4SLinus Torvalds  *
64461da177e4SLinus Torvalds  * Description: Select all the SCAM devices.
64471da177e4SLinus Torvalds  *
64481da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
64491da177e4SLinus Torvalds 
6450*47b5d69cSJames Bottomley  static void FPT_scsel(ULONG p_port)
64511da177e4SLinus Torvalds {
64521da177e4SLinus Torvalds 
64531da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6454*47b5d69cSJames Bottomley     FPT_scwiros(p_port, SCSI_MSG);
64551da177e4SLinus Torvalds 
64561da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
64571da177e4SLinus Torvalds 
64581da177e4SLinus Torvalds 
64591da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
64601da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
64611da177e4SLinus Torvalds       (UCHAR)(BIT(7)+BIT(6))));
64621da177e4SLinus Torvalds 
64631da177e4SLinus Torvalds 
64641da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6465*47b5d69cSJames Bottomley     FPT_scwiros(p_port, SCSI_SEL);
64661da177e4SLinus Torvalds 
64671da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
64681da177e4SLinus Torvalds       ~(UCHAR)BIT(6)));
6469*47b5d69cSJames Bottomley     FPT_scwirod(p_port, BIT(6));
64701da177e4SLinus Torvalds 
64711da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
64721da177e4SLinus Torvalds }
64731da177e4SLinus Torvalds 
64741da177e4SLinus Torvalds 
64751da177e4SLinus Torvalds 
64761da177e4SLinus Torvalds /*---------------------------------------------------------------------
64771da177e4SLinus Torvalds  *
6478*47b5d69cSJames Bottomley   * Function: FPT_scxferc
64791da177e4SLinus Torvalds  *
64801da177e4SLinus Torvalds  * Description: Handshake the p_data (DB4-0) across the bus.
64811da177e4SLinus Torvalds  *
64821da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
64831da177e4SLinus Torvalds 
6484*47b5d69cSJames Bottomley  static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
64851da177e4SLinus Torvalds {
64861da177e4SLinus Torvalds    UCHAR curr_data, ret_data;
64871da177e4SLinus Torvalds 
64881da177e4SLinus Torvalds    curr_data = p_data | BIT(7) | BIT(5);   /*Start with DB7 & DB5 asserted. */
64891da177e4SLinus Torvalds 
64901da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
64911da177e4SLinus Torvalds 
64921da177e4SLinus Torvalds    curr_data &= ~BIT(7);
64931da177e4SLinus Torvalds 
64941da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
64951da177e4SLinus Torvalds 
6496*47b5d69cSJames Bottomley     FPT_scwirod(p_port,BIT(7));              /*Wait for DB7 to be released. */
64971da177e4SLinus Torvalds 	while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
64981da177e4SLinus Torvalds 
64991da177e4SLinus Torvalds    ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
65001da177e4SLinus Torvalds 
65011da177e4SLinus Torvalds    curr_data |= BIT(6);
65021da177e4SLinus Torvalds 
65031da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
65041da177e4SLinus Torvalds 
65051da177e4SLinus Torvalds    curr_data &= ~BIT(5);
65061da177e4SLinus Torvalds 
65071da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
65081da177e4SLinus Torvalds 
6509*47b5d69cSJames Bottomley     FPT_scwirod(p_port,BIT(5));              /*Wait for DB5 to be released. */
65101da177e4SLinus Torvalds 
65111da177e4SLinus Torvalds    curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
65121da177e4SLinus Torvalds    curr_data |= BIT(7);
65131da177e4SLinus Torvalds 
65141da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
65151da177e4SLinus Torvalds 
65161da177e4SLinus Torvalds    curr_data &= ~BIT(6);
65171da177e4SLinus Torvalds 
65181da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
65191da177e4SLinus Torvalds 
6520*47b5d69cSJames Bottomley     FPT_scwirod(p_port,BIT(6));              /*Wait for DB6 to be released. */
65211da177e4SLinus Torvalds 
65221da177e4SLinus Torvalds    return(ret_data);
65231da177e4SLinus Torvalds }
65241da177e4SLinus Torvalds 
65251da177e4SLinus Torvalds 
65261da177e4SLinus Torvalds /*---------------------------------------------------------------------
65271da177e4SLinus Torvalds  *
6528*47b5d69cSJames Bottomley   * Function: FPT_scsendi
65291da177e4SLinus Torvalds  *
65301da177e4SLinus Torvalds  * Description: Transfer our Identification string to determine if we
65311da177e4SLinus Torvalds  *              will be the dominant master.
65321da177e4SLinus Torvalds  *
65331da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
65341da177e4SLinus Torvalds 
6535*47b5d69cSJames Bottomley  static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
65361da177e4SLinus Torvalds {
65371da177e4SLinus Torvalds    UCHAR ret_data,byte_cnt,bit_cnt,defer;
65381da177e4SLinus Torvalds 
6539*47b5d69cSJames Bottomley     defer = 0;
65401da177e4SLinus Torvalds 
65411da177e4SLinus Torvalds    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
65421da177e4SLinus Torvalds 
65431da177e4SLinus Torvalds       for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
65441da177e4SLinus Torvalds 
65451da177e4SLinus Torvalds          if (defer)
6546*47b5d69cSJames Bottomley              ret_data = FPT_scxferc(p_port,00);
65471da177e4SLinus Torvalds 
65481da177e4SLinus Torvalds          else if (p_id_string[byte_cnt] & bit_cnt)
65491da177e4SLinus Torvalds 
6550*47b5d69cSJames Bottomley                 ret_data = FPT_scxferc(p_port,02);
65511da177e4SLinus Torvalds 
65521da177e4SLinus Torvalds             else {
65531da177e4SLinus Torvalds 
6554*47b5d69cSJames Bottomley                 ret_data = FPT_scxferc(p_port,01);
65551da177e4SLinus Torvalds                if (ret_data & 02)
6556*47b5d69cSJames Bottomley                    defer = 1;
65571da177e4SLinus Torvalds                }
65581da177e4SLinus Torvalds 
65591da177e4SLinus Torvalds          if ((ret_data & 0x1C) == 0x10)
65601da177e4SLinus Torvalds             return(0x00);  /*End of isolation stage, we won! */
65611da177e4SLinus Torvalds 
65621da177e4SLinus Torvalds          if (ret_data & 0x1C)
65631da177e4SLinus Torvalds             return(0xFF);
65641da177e4SLinus Torvalds 
65651da177e4SLinus Torvalds          if ((defer) && (!(ret_data & 0x1F)))
65661da177e4SLinus Torvalds             return(0x01);  /*End of isolation stage, we lost. */
65671da177e4SLinus Torvalds 
65681da177e4SLinus Torvalds          } /*bit loop */
65691da177e4SLinus Torvalds 
65701da177e4SLinus Torvalds       } /*byte loop */
65711da177e4SLinus Torvalds 
65721da177e4SLinus Torvalds    if (defer)
65731da177e4SLinus Torvalds       return(0x01);  /*We lost */
65741da177e4SLinus Torvalds    else
65751da177e4SLinus Torvalds       return(0);  /*We WON! Yeeessss! */
65761da177e4SLinus Torvalds }
65771da177e4SLinus Torvalds 
65781da177e4SLinus Torvalds 
65791da177e4SLinus Torvalds 
65801da177e4SLinus Torvalds /*---------------------------------------------------------------------
65811da177e4SLinus Torvalds  *
6582*47b5d69cSJames Bottomley   * Function: FPT_sciso
65831da177e4SLinus Torvalds  *
65841da177e4SLinus Torvalds  * Description: Transfer the Identification string.
65851da177e4SLinus Torvalds  *
65861da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
65871da177e4SLinus Torvalds 
6588*47b5d69cSJames Bottomley  static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
65891da177e4SLinus Torvalds {
65901da177e4SLinus Torvalds    UCHAR ret_data,the_data,byte_cnt,bit_cnt;
65911da177e4SLinus Torvalds 
65921da177e4SLinus Torvalds    the_data = 0;
65931da177e4SLinus Torvalds 
65941da177e4SLinus Torvalds    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
65951da177e4SLinus Torvalds 
65961da177e4SLinus Torvalds       for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
65971da177e4SLinus Torvalds 
6598*47b5d69cSJames Bottomley           ret_data = FPT_scxferc(p_port,0);
65991da177e4SLinus Torvalds 
66001da177e4SLinus Torvalds          if (ret_data & 0xFC)
66011da177e4SLinus Torvalds             return(0xFF);
66021da177e4SLinus Torvalds 
66031da177e4SLinus Torvalds          else {
66041da177e4SLinus Torvalds 
66051da177e4SLinus Torvalds             the_data <<= 1;
66061da177e4SLinus Torvalds             if (ret_data & BIT(1)) {
66071da177e4SLinus Torvalds                the_data |= 1;
66081da177e4SLinus Torvalds                }
66091da177e4SLinus Torvalds             }
66101da177e4SLinus Torvalds 
66111da177e4SLinus Torvalds          if ((ret_data & 0x1F) == 0)
66121da177e4SLinus Torvalds 	   {
66131da177e4SLinus Torvalds /*
66141da177e4SLinus Torvalds 				if(bit_cnt != 0 || bit_cnt != 8)
66151da177e4SLinus Torvalds 				{
66161da177e4SLinus Torvalds 					byte_cnt = 0;
66171da177e4SLinus Torvalds 					bit_cnt = 0;
6618*47b5d69cSJames Bottomley  					FPT_scxferc(p_port, SYNC_PTRN);
6619*47b5d69cSJames Bottomley  					FPT_scxferc(p_port, ASSIGN_ID);
66201da177e4SLinus Torvalds 					continue;
66211da177e4SLinus Torvalds 				}
66221da177e4SLinus Torvalds */
66231da177e4SLinus Torvalds             if (byte_cnt)
66241da177e4SLinus Torvalds                return(0x00);
66251da177e4SLinus Torvalds             else
66261da177e4SLinus Torvalds                return(0xFF);
66271da177e4SLinus Torvalds 	   }
66281da177e4SLinus Torvalds 
66291da177e4SLinus Torvalds          } /*bit loop */
66301da177e4SLinus Torvalds 
66311da177e4SLinus Torvalds       p_id_string[byte_cnt] = the_data;
66321da177e4SLinus Torvalds 
66331da177e4SLinus Torvalds       } /*byte loop */
66341da177e4SLinus Torvalds 
66351da177e4SLinus Torvalds    return(0);
66361da177e4SLinus Torvalds }
66371da177e4SLinus Torvalds 
66381da177e4SLinus Torvalds 
66391da177e4SLinus Torvalds 
66401da177e4SLinus Torvalds /*---------------------------------------------------------------------
66411da177e4SLinus Torvalds  *
6642*47b5d69cSJames Bottomley   * Function: FPT_scwirod
66431da177e4SLinus Torvalds  *
66441da177e4SLinus Torvalds  * Description: Sample the SCSI data bus making sure the signal has been
66451da177e4SLinus Torvalds  *              deasserted for the correct number of consecutive samples.
66461da177e4SLinus Torvalds  *
66471da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
66481da177e4SLinus Torvalds 
6649*47b5d69cSJames Bottomley  static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
66501da177e4SLinus Torvalds {
66511da177e4SLinus Torvalds    UCHAR i;
66521da177e4SLinus Torvalds 
66531da177e4SLinus Torvalds    i = 0;
66541da177e4SLinus Torvalds    while ( i < MAX_SCSI_TAR ) {
66551da177e4SLinus Torvalds 
66561da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
66571da177e4SLinus Torvalds 
66581da177e4SLinus Torvalds          i = 0;
66591da177e4SLinus Torvalds 
66601da177e4SLinus Torvalds       else
66611da177e4SLinus Torvalds 
66621da177e4SLinus Torvalds          i++;
66631da177e4SLinus Torvalds 
66641da177e4SLinus Torvalds       }
66651da177e4SLinus Torvalds }
66661da177e4SLinus Torvalds 
66671da177e4SLinus Torvalds 
66681da177e4SLinus Torvalds 
66691da177e4SLinus Torvalds /*---------------------------------------------------------------------
66701da177e4SLinus Torvalds  *
6671*47b5d69cSJames Bottomley   * Function: FPT_scwiros
66721da177e4SLinus Torvalds  *
66731da177e4SLinus Torvalds  * Description: Sample the SCSI Signal lines making sure the signal has been
66741da177e4SLinus Torvalds  *              deasserted for the correct number of consecutive samples.
66751da177e4SLinus Torvalds  *
66761da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
66771da177e4SLinus Torvalds 
6678*47b5d69cSJames Bottomley  static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
66791da177e4SLinus Torvalds {
66801da177e4SLinus Torvalds    UCHAR i;
66811da177e4SLinus Torvalds 
66821da177e4SLinus Torvalds    i = 0;
66831da177e4SLinus Torvalds    while ( i < MAX_SCSI_TAR ) {
66841da177e4SLinus Torvalds 
66851da177e4SLinus Torvalds       if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
66861da177e4SLinus Torvalds 
66871da177e4SLinus Torvalds          i = 0;
66881da177e4SLinus Torvalds 
66891da177e4SLinus Torvalds       else
66901da177e4SLinus Torvalds 
66911da177e4SLinus Torvalds          i++;
66921da177e4SLinus Torvalds 
66931da177e4SLinus Torvalds       }
66941da177e4SLinus Torvalds }
66951da177e4SLinus Torvalds 
66961da177e4SLinus Torvalds 
66971da177e4SLinus Torvalds /*---------------------------------------------------------------------
66981da177e4SLinus Torvalds  *
6699*47b5d69cSJames Bottomley   * Function: FPT_scvalq
67001da177e4SLinus Torvalds  *
67011da177e4SLinus Torvalds  * Description: Make sure we received a valid data byte.
67021da177e4SLinus Torvalds  *
67031da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
67041da177e4SLinus Torvalds 
6705*47b5d69cSJames Bottomley  static UCHAR FPT_scvalq(UCHAR p_quintet)
67061da177e4SLinus Torvalds {
67071da177e4SLinus Torvalds    UCHAR count;
67081da177e4SLinus Torvalds 
67091da177e4SLinus Torvalds    for (count=1; count < 0x08; count<<=1) {
67101da177e4SLinus Torvalds       if (!(p_quintet & count))
67111da177e4SLinus Torvalds          p_quintet -= 0x80;
67121da177e4SLinus Torvalds       }
67131da177e4SLinus Torvalds 
67141da177e4SLinus Torvalds    if (p_quintet & 0x18)
6715*47b5d69cSJames Bottomley        return(0);
67161da177e4SLinus Torvalds 
67171da177e4SLinus Torvalds    else
6718*47b5d69cSJames Bottomley        return(1);
67191da177e4SLinus Torvalds }
67201da177e4SLinus Torvalds 
67211da177e4SLinus Torvalds 
67221da177e4SLinus Torvalds /*---------------------------------------------------------------------
67231da177e4SLinus Torvalds  *
6724*47b5d69cSJames Bottomley   * Function: FPT_scsell
67251da177e4SLinus Torvalds  *
67261da177e4SLinus Torvalds  * Description: Select the specified device ID using a selection timeout
67271da177e4SLinus Torvalds  *              less than 4ms.  If somebody responds then it is a legacy
67281da177e4SLinus Torvalds  *              drive and this ID must be marked as such.
67291da177e4SLinus Torvalds  *
67301da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
67311da177e4SLinus Torvalds 
6732*47b5d69cSJames Bottomley  static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
67331da177e4SLinus Torvalds {
67341da177e4SLinus Torvalds    ULONG i;
67351da177e4SLinus Torvalds 
67361da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl,
67371da177e4SLinus Torvalds       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
67381da177e4SLinus Torvalds 
67391da177e4SLinus Torvalds    ARAM_ACCESS(p_port);
67401da177e4SLinus Torvalds 
67411da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
67421da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
67431da177e4SLinus Torvalds 
67441da177e4SLinus Torvalds 
67451da177e4SLinus Torvalds    for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
67461da177e4SLinus Torvalds       WRW_HARPOON(i, (MPM_OP+ACOMMAND));
67471da177e4SLinus Torvalds       }
67481da177e4SLinus Torvalds    WRW_HARPOON(i, (BRH_OP+ALWAYS+    NP));
67491da177e4SLinus Torvalds 
67501da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat),
67511da177e4SLinus Torvalds 	       (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
67521da177e4SLinus Torvalds 
67531da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_select_id, targ_id);
67541da177e4SLinus Torvalds 
67551da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
67561da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
67571da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
67581da177e4SLinus Torvalds 
67591da177e4SLinus Torvalds 
67601da177e4SLinus Torvalds    while (!(RDW_HARPOON((p_port+hp_intstat)) &
67611da177e4SLinus Torvalds 	    (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
67621da177e4SLinus Torvalds 
67631da177e4SLinus Torvalds    if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6764*47b5d69cSJames Bottomley           FPT_Wait(p_port, TO_250ms);
67651da177e4SLinus Torvalds 
67661da177e4SLinus Torvalds    DISABLE_AUTO(p_port);
67671da177e4SLinus Torvalds 
67681da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
67691da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
67701da177e4SLinus Torvalds 
67711da177e4SLinus Torvalds    SGRAM_ACCESS(p_port);
67721da177e4SLinus Torvalds 
67731da177e4SLinus Torvalds    if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
67741da177e4SLinus Torvalds 
67751da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat),
67761da177e4SLinus Torvalds 		  (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
67771da177e4SLinus Torvalds 
67781da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_page_ctrl,
67791da177e4SLinus Torvalds          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
67801da177e4SLinus Torvalds 
6781*47b5d69cSJames Bottomley        return(0);  /*No legacy device */
67821da177e4SLinus Torvalds       }
67831da177e4SLinus Torvalds 
67841da177e4SLinus Torvalds    else {
67851da177e4SLinus Torvalds 
67861da177e4SLinus Torvalds       while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
67871da177e4SLinus Torvalds 				if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
67881da177e4SLinus Torvalds 					{
67891da177e4SLinus Torvalds 					WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
67901da177e4SLinus Torvalds       			ACCEPT_MSG(p_port);
67911da177e4SLinus Torvalds 					}
67921da177e4SLinus Torvalds 		}
67931da177e4SLinus Torvalds 
67941da177e4SLinus Torvalds       WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
67951da177e4SLinus Torvalds 
67961da177e4SLinus Torvalds       WR_HARPOON(p_port+hp_page_ctrl,
67971da177e4SLinus Torvalds          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
67981da177e4SLinus Torvalds 
6799*47b5d69cSJames Bottomley        return(1);  /*Found one of them oldies! */
68001da177e4SLinus Torvalds       }
68011da177e4SLinus Torvalds }
68021da177e4SLinus Torvalds 
68031da177e4SLinus Torvalds /*---------------------------------------------------------------------
68041da177e4SLinus Torvalds  *
6805*47b5d69cSJames Bottomley   * Function: FPT_scwtsel
68061da177e4SLinus Torvalds  *
68071da177e4SLinus Torvalds  * Description: Wait to be selected by another SCAM initiator.
68081da177e4SLinus Torvalds  *
68091da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
68101da177e4SLinus Torvalds 
6811*47b5d69cSJames Bottomley  static void FPT_scwtsel(ULONG p_port)
68121da177e4SLinus Torvalds {
68131da177e4SLinus Torvalds    while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
68141da177e4SLinus Torvalds }
68151da177e4SLinus Torvalds 
68161da177e4SLinus Torvalds 
68171da177e4SLinus Torvalds /*---------------------------------------------------------------------
68181da177e4SLinus Torvalds  *
6819*47b5d69cSJames Bottomley   * Function: FPT_inisci
68201da177e4SLinus Torvalds  *
68211da177e4SLinus Torvalds  * Description: Setup the data Structure with the info from the EEPROM.
68221da177e4SLinus Torvalds  *
68231da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
68241da177e4SLinus Torvalds 
6825*47b5d69cSJames Bottomley  static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
68261da177e4SLinus Torvalds {
68271da177e4SLinus Torvalds    UCHAR i,k,max_id;
68281da177e4SLinus Torvalds    USHORT ee_data;
68291da177e4SLinus Torvalds 	PNVRamInfo pCurrNvRam;
68301da177e4SLinus Torvalds 
6831*47b5d69cSJames Bottomley  	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
68321da177e4SLinus Torvalds 
68331da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
68341da177e4SLinus Torvalds       max_id = 0x08;
68351da177e4SLinus Torvalds 
68361da177e4SLinus Torvalds    else
68371da177e4SLinus Torvalds       max_id = 0x10;
68381da177e4SLinus Torvalds 
68391da177e4SLinus Torvalds 	if(pCurrNvRam){
68401da177e4SLinus Torvalds 		for(i = 0; i < max_id; i++){
68411da177e4SLinus Torvalds 
68421da177e4SLinus Torvalds 			for(k = 0; k < 4; k++)
6843*47b5d69cSJames Bottomley  				FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
68441da177e4SLinus Torvalds 			for(k = 4; k < ID_STRING_LENGTH; k++)
6845*47b5d69cSJames Bottomley  				FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
68461da177e4SLinus Torvalds 
6847*47b5d69cSJames Bottomley  	      if(FPT_scamInfo[i].id_string[0] == 0x00)
6848*47b5d69cSJames Bottomley        	   FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
68491da177e4SLinus Torvalds 	      else
6850*47b5d69cSJames Bottomley     	      FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
68511da177e4SLinus Torvalds 
68521da177e4SLinus Torvalds 		}
68531da177e4SLinus Torvalds 	}else {
68541da177e4SLinus Torvalds 	   for (i=0; i < max_id; i++)
68551da177e4SLinus Torvalds    	   {
68561da177e4SLinus Torvalds       	for (k=0; k < ID_STRING_LENGTH; k+=2)
68571da177e4SLinus Torvalds 	         {
6858*47b5d69cSJames Bottomley     	      ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
68591da177e4SLinus Torvalds       	     (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6860*47b5d69cSJames Bottomley           	FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
68611da177e4SLinus Torvalds 	         ee_data >>= 8;
6862*47b5d69cSJames Bottomley     	      FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
68631da177e4SLinus Torvalds       	   }
68641da177e4SLinus Torvalds 
6865*47b5d69cSJames Bottomley  	      if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6866*47b5d69cSJames Bottomley     	       (FPT_scamInfo[i].id_string[0] == 0xFF))
68671da177e4SLinus Torvalds 
6868*47b5d69cSJames Bottomley        	   FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
68691da177e4SLinus Torvalds 
68701da177e4SLinus Torvalds 	      else
6871*47b5d69cSJames Bottomley     	      FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
68721da177e4SLinus Torvalds 
68731da177e4SLinus Torvalds       	}
68741da177e4SLinus Torvalds 	}
68751da177e4SLinus Torvalds 	for(k = 0; k < ID_STRING_LENGTH; k++)
6876*47b5d69cSJames Bottomley  		FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
68771da177e4SLinus Torvalds 
68781da177e4SLinus Torvalds }
68791da177e4SLinus Torvalds 
68801da177e4SLinus Torvalds /*---------------------------------------------------------------------
68811da177e4SLinus Torvalds  *
6882*47b5d69cSJames Bottomley   * Function: FPT_scmachid
68831da177e4SLinus Torvalds  *
68841da177e4SLinus Torvalds  * Description: Match the Device ID string with our values stored in
68851da177e4SLinus Torvalds  *              the EEPROM.
68861da177e4SLinus Torvalds  *
68871da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
68881da177e4SLinus Torvalds 
6889*47b5d69cSJames Bottomley  static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
68901da177e4SLinus Torvalds {
68911da177e4SLinus Torvalds 
68921da177e4SLinus Torvalds    UCHAR i,k,match;
68931da177e4SLinus Torvalds 
68941da177e4SLinus Torvalds 
68951da177e4SLinus Torvalds    for (i=0; i < MAX_SCSI_TAR; i++) {
68961da177e4SLinus Torvalds 
6897*47b5d69cSJames Bottomley           match = 1;
68981da177e4SLinus Torvalds 
68991da177e4SLinus Torvalds          for (k=0; k < ID_STRING_LENGTH; k++)
69001da177e4SLinus Torvalds             {
6901*47b5d69cSJames Bottomley              if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6902*47b5d69cSJames Bottomley                 match = 0;
69031da177e4SLinus Torvalds             }
69041da177e4SLinus Torvalds 
69051da177e4SLinus Torvalds          if (match)
69061da177e4SLinus Torvalds             {
6907*47b5d69cSJames Bottomley              FPT_scamInfo[i].state = ID_ASSIGNED;
69081da177e4SLinus Torvalds             return(i);
69091da177e4SLinus Torvalds             }
69101da177e4SLinus Torvalds 
69111da177e4SLinus Torvalds       }
69121da177e4SLinus Torvalds 
69131da177e4SLinus Torvalds 
69141da177e4SLinus Torvalds 
69151da177e4SLinus Torvalds    if (p_id_string[0] & BIT(5))
69161da177e4SLinus Torvalds       i = 8;
69171da177e4SLinus Torvalds    else
69181da177e4SLinus Torvalds       i = MAX_SCSI_TAR;
69191da177e4SLinus Torvalds 
69201da177e4SLinus Torvalds    if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
69211da177e4SLinus Torvalds       match = p_id_string[1] & (UCHAR) 0x1F;
69221da177e4SLinus Torvalds    else
69231da177e4SLinus Torvalds       match = 7;
69241da177e4SLinus Torvalds 
69251da177e4SLinus Torvalds    while (i > 0)
69261da177e4SLinus Torvalds       {
69271da177e4SLinus Torvalds       i--;
69281da177e4SLinus Torvalds 
6929*47b5d69cSJames Bottomley        if (FPT_scamInfo[match].state == ID_UNUSED)
69301da177e4SLinus Torvalds          {
69311da177e4SLinus Torvalds          for (k=0; k < ID_STRING_LENGTH; k++)
69321da177e4SLinus Torvalds             {
6933*47b5d69cSJames Bottomley              FPT_scamInfo[match].id_string[k] = p_id_string[k];
69341da177e4SLinus Torvalds             }
69351da177e4SLinus Torvalds 
6936*47b5d69cSJames Bottomley           FPT_scamInfo[match].state = ID_ASSIGNED;
69371da177e4SLinus Torvalds 
6938*47b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6939*47b5d69cSJames Bottomley  	         FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
69401da177e4SLinus Torvalds          return(match);
69411da177e4SLinus Torvalds 
69421da177e4SLinus Torvalds          }
69431da177e4SLinus Torvalds 
69441da177e4SLinus Torvalds 
69451da177e4SLinus Torvalds       match--;
69461da177e4SLinus Torvalds 
69471da177e4SLinus Torvalds       if (match == 0xFF)
69481da177e4SLinus Torvalds 	{
69491da177e4SLinus Torvalds          if (p_id_string[0] & BIT(5))
69501da177e4SLinus Torvalds             match = 7;
69511da177e4SLinus Torvalds          else
69521da177e4SLinus Torvalds             match = MAX_SCSI_TAR-1;
69531da177e4SLinus Torvalds 	}
69541da177e4SLinus Torvalds       }
69551da177e4SLinus Torvalds 
69561da177e4SLinus Torvalds 
69571da177e4SLinus Torvalds 
69581da177e4SLinus Torvalds    if (p_id_string[0] & BIT(7))
69591da177e4SLinus Torvalds       {
69601da177e4SLinus Torvalds       return(CLR_PRIORITY);
69611da177e4SLinus Torvalds       }
69621da177e4SLinus Torvalds 
69631da177e4SLinus Torvalds 
69641da177e4SLinus Torvalds    if (p_id_string[0] & BIT(5))
69651da177e4SLinus Torvalds       i = 8;
69661da177e4SLinus Torvalds    else
69671da177e4SLinus Torvalds       i = MAX_SCSI_TAR;
69681da177e4SLinus Torvalds 
69691da177e4SLinus Torvalds    if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
69701da177e4SLinus Torvalds       match = p_id_string[1] & (UCHAR) 0x1F;
69711da177e4SLinus Torvalds    else
69721da177e4SLinus Torvalds       match = 7;
69731da177e4SLinus Torvalds 
69741da177e4SLinus Torvalds    while (i > 0)
69751da177e4SLinus Torvalds       {
69761da177e4SLinus Torvalds 
69771da177e4SLinus Torvalds       i--;
69781da177e4SLinus Torvalds 
6979*47b5d69cSJames Bottomley        if (FPT_scamInfo[match].state == ID_UNASSIGNED)
69801da177e4SLinus Torvalds          {
69811da177e4SLinus Torvalds          for (k=0; k < ID_STRING_LENGTH; k++)
69821da177e4SLinus Torvalds             {
6983*47b5d69cSJames Bottomley              FPT_scamInfo[match].id_string[k] = p_id_string[k];
69841da177e4SLinus Torvalds             }
69851da177e4SLinus Torvalds 
6986*47b5d69cSJames Bottomley           FPT_scamInfo[match].id_string[0] |= BIT(7);
6987*47b5d69cSJames Bottomley           FPT_scamInfo[match].state = ID_ASSIGNED;
6988*47b5d69cSJames Bottomley  			if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6989*47b5d69cSJames Bottomley  	         FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
69901da177e4SLinus Torvalds          return(match);
69911da177e4SLinus Torvalds 
69921da177e4SLinus Torvalds          }
69931da177e4SLinus Torvalds 
69941da177e4SLinus Torvalds 
69951da177e4SLinus Torvalds       match--;
69961da177e4SLinus Torvalds 
69971da177e4SLinus Torvalds       if (match == 0xFF)
69981da177e4SLinus Torvalds 	{
69991da177e4SLinus Torvalds          if (p_id_string[0] & BIT(5))
70001da177e4SLinus Torvalds             match = 7;
70011da177e4SLinus Torvalds          else
70021da177e4SLinus Torvalds             match = MAX_SCSI_TAR-1;
70031da177e4SLinus Torvalds 	}
70041da177e4SLinus Torvalds       }
70051da177e4SLinus Torvalds 
70061da177e4SLinus Torvalds    return(NO_ID_AVAIL);
70071da177e4SLinus Torvalds }
70081da177e4SLinus Torvalds 
70091da177e4SLinus Torvalds 
70101da177e4SLinus Torvalds /*---------------------------------------------------------------------
70111da177e4SLinus Torvalds  *
7012*47b5d69cSJames Bottomley   * Function: FPT_scsavdi
70131da177e4SLinus Torvalds  *
70141da177e4SLinus Torvalds  * Description: Save off the device SCAM ID strings.
70151da177e4SLinus Torvalds  *
70161da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
70171da177e4SLinus Torvalds 
7018*47b5d69cSJames Bottomley  static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
70191da177e4SLinus Torvalds {
70201da177e4SLinus Torvalds    UCHAR i,k,max_id;
70211da177e4SLinus Torvalds    USHORT ee_data,sum_data;
70221da177e4SLinus Torvalds 
70231da177e4SLinus Torvalds 
70241da177e4SLinus Torvalds    sum_data = 0x0000;
70251da177e4SLinus Torvalds 
70261da177e4SLinus Torvalds    for (i = 1; i < EE_SCAMBASE/2; i++)
70271da177e4SLinus Torvalds       {
7028*47b5d69cSJames Bottomley        sum_data += FPT_utilEERead(p_port, i);
70291da177e4SLinus Torvalds       }
70301da177e4SLinus Torvalds 
70311da177e4SLinus Torvalds 
7032*47b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,1);   /* Enable write access to the EEPROM */
70331da177e4SLinus Torvalds 
70341da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
70351da177e4SLinus Torvalds       max_id = 0x08;
70361da177e4SLinus Torvalds 
70371da177e4SLinus Torvalds    else
70381da177e4SLinus Torvalds       max_id = 0x10;
70391da177e4SLinus Torvalds 
70401da177e4SLinus Torvalds    for (i=0; i < max_id; i++)
70411da177e4SLinus Torvalds       {
70421da177e4SLinus Torvalds 
70431da177e4SLinus Torvalds       for (k=0; k < ID_STRING_LENGTH; k+=2)
70441da177e4SLinus Torvalds          {
7045*47b5d69cSJames Bottomley           ee_data = FPT_scamInfo[i].id_string[k+1];
70461da177e4SLinus Torvalds          ee_data <<= 8;
7047*47b5d69cSJames Bottomley           ee_data |= FPT_scamInfo[i].id_string[k];
70481da177e4SLinus Torvalds          sum_data += ee_data;
7049*47b5d69cSJames Bottomley           FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
70501da177e4SLinus Torvalds             (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
70511da177e4SLinus Torvalds          }
70521da177e4SLinus Torvalds       }
70531da177e4SLinus Torvalds 
70541da177e4SLinus Torvalds 
7055*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
7056*47b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,0);   /* Turn off write access */
70571da177e4SLinus Torvalds }
70581da177e4SLinus Torvalds 
70591da177e4SLinus Torvalds /*---------------------------------------------------------------------
70601da177e4SLinus Torvalds  *
7061*47b5d69cSJames Bottomley   * Function: FPT_XbowInit
70621da177e4SLinus Torvalds  *
70631da177e4SLinus Torvalds  * Description: Setup the Xbow for normal operation.
70641da177e4SLinus Torvalds  *
70651da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
70661da177e4SLinus Torvalds 
7067*47b5d69cSJames Bottomley  static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
70681da177e4SLinus Torvalds {
70691da177e4SLinus Torvalds UCHAR i;
70701da177e4SLinus Torvalds 
70711da177e4SLinus Torvalds 	i = RD_HARPOON(port+hp_page_ctrl);
70721da177e4SLinus Torvalds 	WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
70731da177e4SLinus Torvalds 
70741da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsireset,0x00);
70751da177e4SLinus Torvalds    WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
70761da177e4SLinus Torvalds 
70771da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
70781da177e4SLinus Torvalds 				 FIFO_CLR));
70791da177e4SLinus Torvalds 
70801da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsireset,SCSI_INI);
70811da177e4SLinus Torvalds 
70821da177e4SLinus Torvalds    WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
70831da177e4SLinus Torvalds 
70841da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsisig,0x00);         /*  Clear any signals we might */
70851da177e4SLinus Torvalds    WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
70861da177e4SLinus Torvalds 
70871da177e4SLinus Torvalds    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
70881da177e4SLinus Torvalds 
7089*47b5d69cSJames Bottomley     FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
70901da177e4SLinus Torvalds 		    BUS_FREE | XFER_CNT_0 | AUTO_INT;
70911da177e4SLinus Torvalds 
70921da177e4SLinus Torvalds    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
7093*47b5d69cSJames Bottomley  		FPT_default_intena |= SCAM_SEL;
70941da177e4SLinus Torvalds 
7095*47b5d69cSJames Bottomley     WRW_HARPOON((port+hp_intena), FPT_default_intena);
70961da177e4SLinus Torvalds 
70971da177e4SLinus Torvalds    WR_HARPOON(port+hp_seltimeout,TO_290ms);
70981da177e4SLinus Torvalds 
70991da177e4SLinus Torvalds    /* Turn on SCSI_MODE8 for narrow cards to fix the
71001da177e4SLinus Torvalds       strapping issue with the DUAL CHANNEL card */
71011da177e4SLinus Torvalds    if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
71021da177e4SLinus Torvalds       WR_HARPOON(port+hp_addstat,SCSI_MODE8);
71031da177e4SLinus Torvalds 
71041da177e4SLinus Torvalds 	WR_HARPOON(port+hp_page_ctrl, i);
71051da177e4SLinus Torvalds 
71061da177e4SLinus Torvalds }
71071da177e4SLinus Torvalds 
71081da177e4SLinus Torvalds 
71091da177e4SLinus Torvalds /*---------------------------------------------------------------------
71101da177e4SLinus Torvalds  *
7111*47b5d69cSJames Bottomley   * Function: FPT_BusMasterInit
71121da177e4SLinus Torvalds  *
71131da177e4SLinus Torvalds  * Description: Initialize the BusMaster for normal operations.
71141da177e4SLinus Torvalds  *
71151da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
71161da177e4SLinus Torvalds 
7117*47b5d69cSJames Bottomley  static void FPT_BusMasterInit(ULONG p_port)
71181da177e4SLinus Torvalds {
71191da177e4SLinus Torvalds 
71201da177e4SLinus Torvalds 
71211da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
71221da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
71231da177e4SLinus Torvalds 
71241da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
71251da177e4SLinus Torvalds 
71261da177e4SLinus Torvalds 
71271da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
71281da177e4SLinus Torvalds 
71291da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
71301da177e4SLinus Torvalds 
71311da177e4SLinus Torvalds 
71321da177e4SLinus Torvalds    RD_HARPOON(p_port+hp_int_status);        /*Clear interrupts. */
71331da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
71341da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
71351da177e4SLinus Torvalds       ~SCATTER_EN));
71361da177e4SLinus Torvalds }
71371da177e4SLinus Torvalds 
71381da177e4SLinus Torvalds 
71391da177e4SLinus Torvalds /*---------------------------------------------------------------------
71401da177e4SLinus Torvalds  *
7141*47b5d69cSJames Bottomley   * Function: FPT_DiagEEPROM
71421da177e4SLinus Torvalds  *
71431da177e4SLinus Torvalds  * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
71441da177e4SLinus Torvalds  *              necessary.
71451da177e4SLinus Torvalds  *
71461da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
71471da177e4SLinus Torvalds 
7148*47b5d69cSJames Bottomley  static void FPT_DiagEEPROM(ULONG p_port)
71491da177e4SLinus Torvalds {
71501da177e4SLinus Torvalds    USHORT index,temp,max_wd_cnt;
71511da177e4SLinus Torvalds 
71521da177e4SLinus Torvalds    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
71531da177e4SLinus Torvalds       max_wd_cnt = EEPROM_WD_CNT;
71541da177e4SLinus Torvalds    else
71551da177e4SLinus Torvalds       max_wd_cnt = EEPROM_WD_CNT * 2;
71561da177e4SLinus Torvalds 
7157*47b5d69cSJames Bottomley     temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
71581da177e4SLinus Torvalds 
71591da177e4SLinus Torvalds    if (temp == 0x4641) {
71601da177e4SLinus Torvalds 
71611da177e4SLinus Torvalds       for (index = 2; index < max_wd_cnt; index++) {
71621da177e4SLinus Torvalds 
7163*47b5d69cSJames Bottomley           temp += FPT_utilEERead(p_port, index);
71641da177e4SLinus Torvalds 
71651da177e4SLinus Torvalds          }
71661da177e4SLinus Torvalds 
7167*47b5d69cSJames Bottomley        if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
71681da177e4SLinus Torvalds 
71691da177e4SLinus Torvalds          return;          /*EEPROM is Okay so return now! */
71701da177e4SLinus Torvalds          }
71711da177e4SLinus Torvalds       }
71721da177e4SLinus Torvalds 
71731da177e4SLinus Torvalds 
7174*47b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
71751da177e4SLinus Torvalds 
71761da177e4SLinus Torvalds    for (index = 0; index < max_wd_cnt; index++) {
71771da177e4SLinus Torvalds 
7178*47b5d69cSJames Bottomley        FPT_utilEEWrite(p_port, 0x0000, index);
71791da177e4SLinus Torvalds       }
71801da177e4SLinus Torvalds 
71811da177e4SLinus Torvalds    temp = 0;
71821da177e4SLinus Torvalds 
7183*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
71841da177e4SLinus Torvalds    temp += 0x4641;
7185*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
71861da177e4SLinus Torvalds    temp += 0x3920;
7187*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
71881da177e4SLinus Torvalds    temp += 0x3033;
7189*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
71901da177e4SLinus Torvalds    temp += 0x2020;
7191*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
71921da177e4SLinus Torvalds    temp += 0x70D3;
7193*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
71941da177e4SLinus Torvalds    temp += 0x0010;
7195*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
71961da177e4SLinus Torvalds    temp += 0x0003;
7197*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
71981da177e4SLinus Torvalds    temp += 0x0007;
71991da177e4SLinus Torvalds 
7200*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
72011da177e4SLinus Torvalds    temp += 0x0000;
7202*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
72031da177e4SLinus Torvalds    temp += 0x0000;
7204*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
72051da177e4SLinus Torvalds    temp += 0x0000;
72061da177e4SLinus Torvalds 
7207*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
72081da177e4SLinus Torvalds    temp += 0x4242;
7209*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
72101da177e4SLinus Torvalds    temp += 0x4242;
7211*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
72121da177e4SLinus Torvalds    temp += 0x4242;
7213*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
72141da177e4SLinus Torvalds    temp += 0x4242;
7215*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
72161da177e4SLinus Torvalds    temp += 0x4242;
7217*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
72181da177e4SLinus Torvalds    temp += 0x4242;
7219*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
72201da177e4SLinus Torvalds    temp += 0x4242;
7221*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
72221da177e4SLinus Torvalds    temp += 0x4242;
72231da177e4SLinus Torvalds 
72241da177e4SLinus Torvalds 
7225*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x6C46, 64/2);  /*PRODUCT ID */
72261da177e4SLinus Torvalds    temp += 0x6C46;
7227*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x7361, 66/2);  /* FlashPoint LT   */
72281da177e4SLinus Torvalds    temp += 0x7361;
7229*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5068, 68/2);
72301da177e4SLinus Torvalds    temp += 0x5068;
7231*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x696F, 70/2);
72321da177e4SLinus Torvalds    temp += 0x696F;
7233*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x746E, 72/2);
72341da177e4SLinus Torvalds    temp += 0x746E;
7235*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4C20, 74/2);
72361da177e4SLinus Torvalds    temp += 0x4C20;
7237*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2054, 76/2);
72381da177e4SLinus Torvalds    temp += 0x2054;
7239*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2020, 78/2);
72401da177e4SLinus Torvalds    temp += 0x2020;
72411da177e4SLinus Torvalds 
72421da177e4SLinus Torvalds    index = ((EE_SCAMBASE/2)+(7*16));
7243*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
72441da177e4SLinus Torvalds    temp += (0x0700+TYPE_CODE0);
72451da177e4SLinus Torvalds    index++;
7246*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5542, index);            /*Vendor ID code */
72471da177e4SLinus Torvalds    temp += 0x5542;                                /* BUSLOGIC      */
72481da177e4SLinus Torvalds    index++;
7249*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4C53, index);
72501da177e4SLinus Torvalds    temp += 0x4C53;
72511da177e4SLinus Torvalds    index++;
7252*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x474F, index);
72531da177e4SLinus Torvalds    temp += 0x474F;
72541da177e4SLinus Torvalds    index++;
7255*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4349, index);
72561da177e4SLinus Torvalds    temp += 0x4349;
72571da177e4SLinus Torvalds    index++;
7258*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5442, index);            /*Vendor unique code */
72591da177e4SLinus Torvalds    temp += 0x5442;                         /* BT- 930           */
72601da177e4SLinus Torvalds    index++;
7261*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x202D, index);
72621da177e4SLinus Torvalds    temp += 0x202D;
72631da177e4SLinus Torvalds    index++;
7264*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3339, index);
72651da177e4SLinus Torvalds    temp += 0x3339;
72661da177e4SLinus Torvalds    index++;                                 /*Serial #          */
7267*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2030, index);             /* 01234567         */
72681da177e4SLinus Torvalds    temp += 0x2030;
72691da177e4SLinus Torvalds    index++;
7270*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5453, index);
72711da177e4SLinus Torvalds    temp += 0x5453;
72721da177e4SLinus Torvalds    index++;
7273*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x5645, index);
72741da177e4SLinus Torvalds    temp += 0x5645;
72751da177e4SLinus Torvalds    index++;
7276*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x2045, index);
72771da177e4SLinus Torvalds    temp += 0x2045;
72781da177e4SLinus Torvalds    index++;
7279*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x202F, index);
72801da177e4SLinus Torvalds    temp += 0x202F;
72811da177e4SLinus Torvalds    index++;
7282*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x4F4A, index);
72831da177e4SLinus Torvalds    temp += 0x4F4A;
72841da177e4SLinus Torvalds    index++;
7285*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x204E, index);
72861da177e4SLinus Torvalds    temp += 0x204E;
72871da177e4SLinus Torvalds    index++;
7288*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, 0x3539, index);
72891da177e4SLinus Torvalds    temp += 0x3539;
72901da177e4SLinus Torvalds 
72911da177e4SLinus Torvalds 
72921da177e4SLinus Torvalds 
7293*47b5d69cSJames Bottomley     FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
72941da177e4SLinus Torvalds 
7295*47b5d69cSJames Bottomley     FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
72961da177e4SLinus Torvalds 
72971da177e4SLinus Torvalds }
72981da177e4SLinus Torvalds 
72991da177e4SLinus Torvalds 
73001da177e4SLinus Torvalds /*---------------------------------------------------------------------
73011da177e4SLinus Torvalds  *
73021da177e4SLinus Torvalds  * Function: Queue Search Select
73031da177e4SLinus Torvalds  *
73041da177e4SLinus Torvalds  * Description: Try to find a new command to execute.
73051da177e4SLinus Torvalds  *
73061da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
73071da177e4SLinus Torvalds 
7308*47b5d69cSJames Bottomley  static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
73091da177e4SLinus Torvalds {
73101da177e4SLinus Torvalds    UCHAR scan_ptr, lun;
73111da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
73121da177e4SLinus Torvalds 	PSCCB pOldSccb;
73131da177e4SLinus Torvalds 
73141da177e4SLinus Torvalds    scan_ptr = pCurrCard->scanIndex;
73151da177e4SLinus Torvalds 	do
73161da177e4SLinus Torvalds 	{
7317*47b5d69cSJames Bottomley  		currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
73181da177e4SLinus Torvalds 		if((pCurrCard->globalFlags & F_CONLUN_IO) &&
73191da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
73201da177e4SLinus Torvalds 		{
73211da177e4SLinus Torvalds 			if (currTar_Info->TarSelQ_Cnt != 0)
73221da177e4SLinus Torvalds 			{
73231da177e4SLinus Torvalds 
73241da177e4SLinus Torvalds 				scan_ptr++;
73251da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR)
73261da177e4SLinus Torvalds 					scan_ptr = 0;
73271da177e4SLinus Torvalds 
73281da177e4SLinus Torvalds 				for(lun=0; lun < MAX_LUN; lun++)
73291da177e4SLinus Torvalds 				{
7330*47b5d69cSJames Bottomley  					if(currTar_Info->TarLUNBusy[lun] == 0)
73311da177e4SLinus Torvalds 					{
73321da177e4SLinus Torvalds 
73331da177e4SLinus Torvalds 						pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
73341da177e4SLinus Torvalds 						pOldSccb = NULL;
73351da177e4SLinus Torvalds 
73361da177e4SLinus Torvalds 						while((pCurrCard->currentSCCB != NULL) &&
73371da177e4SLinus Torvalds 								 (lun != pCurrCard->currentSCCB->Lun))
73381da177e4SLinus Torvalds 						{
73391da177e4SLinus Torvalds 							pOldSccb = pCurrCard->currentSCCB;
73401da177e4SLinus Torvalds 							pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
73411da177e4SLinus Torvalds 																	Sccb_forwardlink;
73421da177e4SLinus Torvalds 						}
73431da177e4SLinus Torvalds 						if(pCurrCard->currentSCCB == NULL)
73441da177e4SLinus Torvalds 							continue;
73451da177e4SLinus Torvalds 						if(pOldSccb != NULL)
73461da177e4SLinus Torvalds 						{
73471da177e4SLinus Torvalds 							pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
73481da177e4SLinus Torvalds 																	Sccb_forwardlink;
73491da177e4SLinus Torvalds 							pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
73501da177e4SLinus Torvalds 																	Sccb_backlink;
73511da177e4SLinus Torvalds 							currTar_Info->TarSelQ_Cnt--;
73521da177e4SLinus Torvalds 						}
73531da177e4SLinus Torvalds 						else
73541da177e4SLinus Torvalds 						{
73551da177e4SLinus Torvalds 							currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
73561da177e4SLinus Torvalds 
73571da177e4SLinus Torvalds 							if (currTar_Info->TarSelQ_Head == NULL)
73581da177e4SLinus Torvalds 							{
73591da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Tail = NULL;
73601da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Cnt = 0;
73611da177e4SLinus Torvalds 							}
73621da177e4SLinus Torvalds 							else
73631da177e4SLinus Torvalds 							{
73641da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Cnt--;
73651da177e4SLinus Torvalds 								currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
73661da177e4SLinus Torvalds 							}
73671da177e4SLinus Torvalds 						}
73681da177e4SLinus Torvalds 					pCurrCard->scanIndex = scan_ptr;
73691da177e4SLinus Torvalds 
73701da177e4SLinus Torvalds 					pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
73711da177e4SLinus Torvalds 
73721da177e4SLinus Torvalds 					break;
73731da177e4SLinus Torvalds 					}
73741da177e4SLinus Torvalds 				}
73751da177e4SLinus Torvalds 			}
73761da177e4SLinus Torvalds 
73771da177e4SLinus Torvalds 			else
73781da177e4SLinus Torvalds 			{
73791da177e4SLinus Torvalds 				scan_ptr++;
73801da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR) {
73811da177e4SLinus Torvalds 					scan_ptr = 0;
73821da177e4SLinus Torvalds 				}
73831da177e4SLinus Torvalds 			}
73841da177e4SLinus Torvalds 
73851da177e4SLinus Torvalds 		}
73861da177e4SLinus Torvalds 		else
73871da177e4SLinus Torvalds 		{
73881da177e4SLinus Torvalds 			if ((currTar_Info->TarSelQ_Cnt != 0) &&
7389*47b5d69cSJames Bottomley  				(currTar_Info->TarLUNBusy[0] == 0))
73901da177e4SLinus Torvalds 			{
73911da177e4SLinus Torvalds 
73921da177e4SLinus Torvalds 				pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
73931da177e4SLinus Torvalds 
73941da177e4SLinus Torvalds 				currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
73951da177e4SLinus Torvalds 
73961da177e4SLinus Torvalds 				if (currTar_Info->TarSelQ_Head == NULL)
73971da177e4SLinus Torvalds 				{
73981da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Tail = NULL;
73991da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Cnt = 0;
74001da177e4SLinus Torvalds 				}
74011da177e4SLinus Torvalds 				else
74021da177e4SLinus Torvalds 				{
74031da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Cnt--;
74041da177e4SLinus Torvalds 					currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
74051da177e4SLinus Torvalds 				}
74061da177e4SLinus Torvalds 
74071da177e4SLinus Torvalds 				scan_ptr++;
74081da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR)
74091da177e4SLinus Torvalds 					scan_ptr = 0;
74101da177e4SLinus Torvalds 
74111da177e4SLinus Torvalds 				pCurrCard->scanIndex = scan_ptr;
74121da177e4SLinus Torvalds 
74131da177e4SLinus Torvalds 				pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
74141da177e4SLinus Torvalds 
74151da177e4SLinus Torvalds 				break;
74161da177e4SLinus Torvalds 			}
74171da177e4SLinus Torvalds 
74181da177e4SLinus Torvalds 			else
74191da177e4SLinus Torvalds 			{
74201da177e4SLinus Torvalds 				scan_ptr++;
74211da177e4SLinus Torvalds 				if (scan_ptr == MAX_SCSI_TAR)
74221da177e4SLinus Torvalds 				{
74231da177e4SLinus Torvalds 					scan_ptr = 0;
74241da177e4SLinus Torvalds 				}
74251da177e4SLinus Torvalds 			}
74261da177e4SLinus Torvalds 		}
74271da177e4SLinus Torvalds 	} while (scan_ptr != pCurrCard->scanIndex);
74281da177e4SLinus Torvalds }
74291da177e4SLinus Torvalds 
74301da177e4SLinus Torvalds 
74311da177e4SLinus Torvalds /*---------------------------------------------------------------------
74321da177e4SLinus Torvalds  *
74331da177e4SLinus Torvalds  * Function: Queue Select Fail
74341da177e4SLinus Torvalds  *
74351da177e4SLinus Torvalds  * Description: Add the current SCCB to the head of the Queue.
74361da177e4SLinus Torvalds  *
74371da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
74381da177e4SLinus Torvalds 
7439*47b5d69cSJames Bottomley  static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
74401da177e4SLinus Torvalds {
74411da177e4SLinus Torvalds    UCHAR thisTarg;
74421da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
74431da177e4SLinus Torvalds 
74441da177e4SLinus Torvalds    if (pCurrCard->currentSCCB != NULL)
74451da177e4SLinus Torvalds 	  {
74461da177e4SLinus Torvalds 	  thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7447*47b5d69cSJames Bottomley        currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
74481da177e4SLinus Torvalds 
74491da177e4SLinus Torvalds       pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
74501da177e4SLinus Torvalds 
74511da177e4SLinus Torvalds       pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
74521da177e4SLinus Torvalds 
74531da177e4SLinus Torvalds 	  if (currTar_Info->TarSelQ_Cnt == 0)
74541da177e4SLinus Torvalds 		 {
74551da177e4SLinus Torvalds 		 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
74561da177e4SLinus Torvalds 		 }
74571da177e4SLinus Torvalds 
74581da177e4SLinus Torvalds 	  else
74591da177e4SLinus Torvalds 		 {
74601da177e4SLinus Torvalds 		 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
74611da177e4SLinus Torvalds 		 }
74621da177e4SLinus Torvalds 
74631da177e4SLinus Torvalds 
74641da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
74651da177e4SLinus Torvalds 
74661da177e4SLinus Torvalds 	  pCurrCard->currentSCCB = NULL;
74671da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Cnt++;
74681da177e4SLinus Torvalds 	  }
74691da177e4SLinus Torvalds }
74701da177e4SLinus Torvalds /*---------------------------------------------------------------------
74711da177e4SLinus Torvalds  *
74721da177e4SLinus Torvalds  * Function: Queue Command Complete
74731da177e4SLinus Torvalds  *
74741da177e4SLinus Torvalds  * Description: Call the callback function with the current SCCB.
74751da177e4SLinus Torvalds  *
74761da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
74771da177e4SLinus Torvalds 
7478*47b5d69cSJames Bottomley  static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7479*47b5d69cSJames Bottomley  				 UCHAR p_card)
74801da177e4SLinus Torvalds {
74811da177e4SLinus Torvalds 
74821da177e4SLinus Torvalds    UCHAR i, SCSIcmd;
74831da177e4SLinus Torvalds    CALL_BK_FN callback;
74841da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
74851da177e4SLinus Torvalds 
74861da177e4SLinus Torvalds    SCSIcmd = p_sccb->Cdb[0];
74871da177e4SLinus Torvalds 
74881da177e4SLinus Torvalds 
74891da177e4SLinus Torvalds    if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
74901da177e4SLinus Torvalds 
74911da177e4SLinus Torvalds 	  if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
74921da177e4SLinus Torvalds 		 (p_sccb->HostStatus == SCCB_COMPLETE)                             &&
74931da177e4SLinus Torvalds 		 (p_sccb->TargetStatus != SSCHECK))
74941da177e4SLinus Torvalds 
74951da177e4SLinus Torvalds 		 if ((SCSIcmd == SCSI_READ)             ||
74961da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_WRITE)            ||
74971da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_READ_EXTENDED)    ||
74981da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_WRITE_EXTENDED)   ||
74991da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
75001da177e4SLinus Torvalds 			 (SCSIcmd == SCSI_START_STOP_UNIT)  ||
75011da177e4SLinus Torvalds 			 (pCurrCard->globalFlags & F_NO_FILTER)
75021da177e4SLinus Torvalds 			)
75031da177e4SLinus Torvalds 			   p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
75041da177e4SLinus Torvalds 	  }
75051da177e4SLinus Torvalds 
75061da177e4SLinus Torvalds 
75071da177e4SLinus Torvalds 	if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
75081da177e4SLinus Torvalds 	{
75091da177e4SLinus Torvalds 	   if (p_sccb->HostStatus || p_sccb->TargetStatus)
75101da177e4SLinus Torvalds 		  p_sccb->SccbStatus = SCCB_ERROR;
75111da177e4SLinus Torvalds 	   else
75121da177e4SLinus Torvalds 		  p_sccb->SccbStatus = SCCB_SUCCESS;
75131da177e4SLinus Torvalds 	}
75141da177e4SLinus Torvalds 
75151da177e4SLinus Torvalds    if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
75161da177e4SLinus Torvalds 
75171da177e4SLinus Torvalds 	  p_sccb->CdbLength = p_sccb->Save_CdbLen;
75181da177e4SLinus Torvalds 	  for (i=0; i < 6; i++) {
75191da177e4SLinus Torvalds 		 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
75201da177e4SLinus Torvalds 		 }
75211da177e4SLinus Torvalds 	  }
75221da177e4SLinus Torvalds 
75231da177e4SLinus Torvalds    if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
75241da177e4SLinus Torvalds 	  (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
75251da177e4SLinus Torvalds 
7526*47b5d69cSJames Bottomley  		 FPT_utilUpdateResidual(p_sccb);
75271da177e4SLinus Torvalds 		 }
75281da177e4SLinus Torvalds 
75291da177e4SLinus Torvalds    pCurrCard->cmdCounter--;
75301da177e4SLinus Torvalds    if (!pCurrCard->cmdCounter) {
75311da177e4SLinus Torvalds 
75321da177e4SLinus Torvalds 	  if (pCurrCard->globalFlags & F_GREEN_PC) {
75331da177e4SLinus Torvalds 		 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
75341da177e4SLinus Torvalds 		 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
75351da177e4SLinus Torvalds 		 }
75361da177e4SLinus Torvalds 
75371da177e4SLinus Torvalds 	  WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
75381da177e4SLinus Torvalds 	  (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
75391da177e4SLinus Torvalds 
75401da177e4SLinus Torvalds 	  }
75411da177e4SLinus Torvalds 
75421da177e4SLinus Torvalds 	if(pCurrCard->discQCount != 0)
75431da177e4SLinus Torvalds 	{
7544*47b5d69cSJames Bottomley        currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
75451da177e4SLinus Torvalds 		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
75461da177e4SLinus Torvalds 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
75471da177e4SLinus Torvalds 		{
75481da177e4SLinus Torvalds 			pCurrCard->discQCount--;
75491da177e4SLinus Torvalds 			pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
75501da177e4SLinus Torvalds 		}
75511da177e4SLinus Torvalds 		else
75521da177e4SLinus Torvalds 		{
75531da177e4SLinus Torvalds 			if(p_sccb->Sccb_tag)
75541da177e4SLinus Torvalds 			{
75551da177e4SLinus Torvalds 				pCurrCard->discQCount--;
75561da177e4SLinus Torvalds 				pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
75571da177e4SLinus Torvalds 			}else
75581da177e4SLinus Torvalds 			{
75591da177e4SLinus Torvalds 				pCurrCard->discQCount--;
75601da177e4SLinus Torvalds 				pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
75611da177e4SLinus Torvalds 			}
75621da177e4SLinus Torvalds 		}
75631da177e4SLinus Torvalds 
75641da177e4SLinus Torvalds 	}
75651da177e4SLinus Torvalds 
75661da177e4SLinus Torvalds 	callback = (CALL_BK_FN)p_sccb->SccbCallback;
75671da177e4SLinus Torvalds    callback(p_sccb);
75681da177e4SLinus Torvalds    pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
75691da177e4SLinus Torvalds    pCurrCard->currentSCCB = NULL;
75701da177e4SLinus Torvalds }
75711da177e4SLinus Torvalds 
75721da177e4SLinus Torvalds 
75731da177e4SLinus Torvalds /*---------------------------------------------------------------------
75741da177e4SLinus Torvalds  *
75751da177e4SLinus Torvalds  * Function: Queue Disconnect
75761da177e4SLinus Torvalds  *
75771da177e4SLinus Torvalds  * Description: Add SCCB to our disconnect array.
75781da177e4SLinus Torvalds  *
75791da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
7580*47b5d69cSJames Bottomley  static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
75811da177e4SLinus Torvalds {
75821da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
75831da177e4SLinus Torvalds 
7584*47b5d69cSJames Bottomley  	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
75851da177e4SLinus Torvalds 
7586*47b5d69cSJames Bottomley  	if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
75871da177e4SLinus Torvalds 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
75881da177e4SLinus Torvalds 	{
7589*47b5d69cSJames Bottomley  		FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
75901da177e4SLinus Torvalds 	}
75911da177e4SLinus Torvalds 	else
75921da177e4SLinus Torvalds 	{
75931da177e4SLinus Torvalds 		if (p_sccb->Sccb_tag)
75941da177e4SLinus Torvalds 		{
7595*47b5d69cSJames Bottomley  			FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7596*47b5d69cSJames Bottomley  			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7597*47b5d69cSJames Bottomley  			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
75981da177e4SLinus Torvalds 		}else
75991da177e4SLinus Torvalds 		{
7600*47b5d69cSJames Bottomley  			FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
76011da177e4SLinus Torvalds 		}
76021da177e4SLinus Torvalds 	}
7603*47b5d69cSJames Bottomley  	FPT_BL_Card[p_card].currentSCCB = NULL;
76041da177e4SLinus Torvalds }
76051da177e4SLinus Torvalds 
76061da177e4SLinus Torvalds 
76071da177e4SLinus Torvalds /*---------------------------------------------------------------------
76081da177e4SLinus Torvalds  *
76091da177e4SLinus Torvalds  * Function: Queue Flush SCCB
76101da177e4SLinus Torvalds  *
76111da177e4SLinus Torvalds  * Description: Flush all SCCB's back to the host driver for this target.
76121da177e4SLinus Torvalds  *
76131da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
76141da177e4SLinus Torvalds 
7615*47b5d69cSJames Bottomley  static void  FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
76161da177e4SLinus Torvalds {
76171da177e4SLinus Torvalds    UCHAR qtag,thisTarg;
76181da177e4SLinus Torvalds    PSCCB currSCCB;
76191da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
76201da177e4SLinus Torvalds 
7621*47b5d69cSJames Bottomley     currSCCB = FPT_BL_Card[p_card].currentSCCB;
76221da177e4SLinus Torvalds 	if(currSCCB != NULL)
76231da177e4SLinus Torvalds 	{
76241da177e4SLinus Torvalds 	   thisTarg = (UCHAR)currSCCB->TargID;
7625*47b5d69cSJames Bottomley     	currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
76261da177e4SLinus Torvalds 
76271da177e4SLinus Torvalds 	   for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
76281da177e4SLinus Torvalds 
7629*47b5d69cSJames Bottomley  		  if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7630*47b5d69cSJames Bottomley  					(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
76311da177e4SLinus Torvalds 			 {
76321da177e4SLinus Torvalds 
7633*47b5d69cSJames Bottomley  			 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
76341da177e4SLinus Torvalds 
7635*47b5d69cSJames Bottomley  			 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
76361da177e4SLinus Torvalds 
7637*47b5d69cSJames Bottomley  			 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
76381da177e4SLinus Torvalds 			 currTar_Info->TarTagQ_Cnt--;
76391da177e4SLinus Torvalds 
76401da177e4SLinus Torvalds 			 }
76411da177e4SLinus Torvalds 		  }
76421da177e4SLinus Torvalds 	}
76431da177e4SLinus Torvalds 
76441da177e4SLinus Torvalds }
76451da177e4SLinus Torvalds 
76461da177e4SLinus Torvalds /*---------------------------------------------------------------------
76471da177e4SLinus Torvalds  *
76481da177e4SLinus Torvalds  * Function: Queue Flush Target SCCB
76491da177e4SLinus Torvalds  *
76501da177e4SLinus Torvalds  * Description: Flush all SCCB's back to the host driver for this target.
76511da177e4SLinus Torvalds  *
76521da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
76531da177e4SLinus Torvalds 
7654*47b5d69cSJames Bottomley  static void  FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7655*47b5d69cSJames Bottomley  				    UCHAR error_code)
76561da177e4SLinus Torvalds {
76571da177e4SLinus Torvalds    UCHAR qtag;
76581da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
76591da177e4SLinus Torvalds 
7660*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
76611da177e4SLinus Torvalds 
76621da177e4SLinus Torvalds    for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
76631da177e4SLinus Torvalds 
7664*47b5d69cSJames Bottomley  	  if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7665*47b5d69cSJames Bottomley  				(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
76661da177e4SLinus Torvalds 		 {
76671da177e4SLinus Torvalds 
7668*47b5d69cSJames Bottomley  		 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
76691da177e4SLinus Torvalds 
7670*47b5d69cSJames Bottomley  		 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
76711da177e4SLinus Torvalds 
7672*47b5d69cSJames Bottomley  		 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
76731da177e4SLinus Torvalds 		 currTar_Info->TarTagQ_Cnt--;
76741da177e4SLinus Torvalds 
76751da177e4SLinus Torvalds 		 }
76761da177e4SLinus Torvalds 	  }
76771da177e4SLinus Torvalds 
76781da177e4SLinus Torvalds }
76791da177e4SLinus Torvalds 
76801da177e4SLinus Torvalds 
76811da177e4SLinus Torvalds 
76821da177e4SLinus Torvalds 
76831da177e4SLinus Torvalds 
7684*47b5d69cSJames Bottomley  static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
76851da177e4SLinus Torvalds {
76861da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
7687*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
76881da177e4SLinus Torvalds 
76891da177e4SLinus Torvalds    p_SCCB->Sccb_forwardlink = NULL;
76901da177e4SLinus Torvalds 
76911da177e4SLinus Torvalds    p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
76921da177e4SLinus Torvalds 
76931da177e4SLinus Torvalds    if (currTar_Info->TarSelQ_Cnt == 0) {
76941da177e4SLinus Torvalds 
76951da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Head = p_SCCB;
76961da177e4SLinus Torvalds 	  }
76971da177e4SLinus Torvalds 
76981da177e4SLinus Torvalds    else {
76991da177e4SLinus Torvalds 
77001da177e4SLinus Torvalds 	  currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
77011da177e4SLinus Torvalds 	  }
77021da177e4SLinus Torvalds 
77031da177e4SLinus Torvalds 
77041da177e4SLinus Torvalds    currTar_Info->TarSelQ_Tail = p_SCCB;
77051da177e4SLinus Torvalds    currTar_Info->TarSelQ_Cnt++;
77061da177e4SLinus Torvalds }
77071da177e4SLinus Torvalds 
77081da177e4SLinus Torvalds 
77091da177e4SLinus Torvalds /*---------------------------------------------------------------------
77101da177e4SLinus Torvalds  *
77111da177e4SLinus Torvalds  * Function: Queue Find SCCB
77121da177e4SLinus Torvalds  *
77131da177e4SLinus Torvalds  * Description: Search the target select Queue for this SCCB, and
77141da177e4SLinus Torvalds  *              remove it if found.
77151da177e4SLinus Torvalds  *
77161da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
77171da177e4SLinus Torvalds 
7718*47b5d69cSJames Bottomley  static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
77191da177e4SLinus Torvalds {
77201da177e4SLinus Torvalds    PSCCB q_ptr;
77211da177e4SLinus Torvalds    PSCCBMgr_tar_info currTar_Info;
77221da177e4SLinus Torvalds 
7723*47b5d69cSJames Bottomley     currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
77241da177e4SLinus Torvalds 
77251da177e4SLinus Torvalds    q_ptr = currTar_Info->TarSelQ_Head;
77261da177e4SLinus Torvalds 
77271da177e4SLinus Torvalds    while(q_ptr != NULL) {
77281da177e4SLinus Torvalds 
77291da177e4SLinus Torvalds 	  if (q_ptr == p_SCCB) {
77301da177e4SLinus Torvalds 
77311da177e4SLinus Torvalds 
77321da177e4SLinus Torvalds 		 if (currTar_Info->TarSelQ_Head == q_ptr) {
77331da177e4SLinus Torvalds 
77341da177e4SLinus Torvalds 			currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
77351da177e4SLinus Torvalds 			}
77361da177e4SLinus Torvalds 
77371da177e4SLinus Torvalds 		 if (currTar_Info->TarSelQ_Tail == q_ptr) {
77381da177e4SLinus Torvalds 
77391da177e4SLinus Torvalds 			currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
77401da177e4SLinus Torvalds 			}
77411da177e4SLinus Torvalds 
77421da177e4SLinus Torvalds 		 if (q_ptr->Sccb_forwardlink != NULL) {
77431da177e4SLinus Torvalds 			q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
77441da177e4SLinus Torvalds 			}
77451da177e4SLinus Torvalds 
77461da177e4SLinus Torvalds 		 if (q_ptr->Sccb_backlink != NULL) {
77471da177e4SLinus Torvalds 			q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
77481da177e4SLinus Torvalds 			}
77491da177e4SLinus Torvalds 
77501da177e4SLinus Torvalds 		 currTar_Info->TarSelQ_Cnt--;
77511da177e4SLinus Torvalds 
7752*47b5d69cSJames Bottomley  		 return(1);
77531da177e4SLinus Torvalds 		 }
77541da177e4SLinus Torvalds 
77551da177e4SLinus Torvalds 	  else {
77561da177e4SLinus Torvalds 		 q_ptr = q_ptr->Sccb_forwardlink;
77571da177e4SLinus Torvalds 		 }
77581da177e4SLinus Torvalds 	  }
77591da177e4SLinus Torvalds 
77601da177e4SLinus Torvalds 
7761*47b5d69cSJames Bottomley     return(0);
77621da177e4SLinus Torvalds 
77631da177e4SLinus Torvalds }
77641da177e4SLinus Torvalds 
77651da177e4SLinus Torvalds 
77661da177e4SLinus Torvalds /*---------------------------------------------------------------------
77671da177e4SLinus Torvalds  *
77681da177e4SLinus Torvalds  * Function: Utility Update Residual Count
77691da177e4SLinus Torvalds  *
77701da177e4SLinus Torvalds  * Description: Update the XferCnt to the remaining byte count.
77711da177e4SLinus Torvalds  *              If we transferred all the data then just write zero.
77721da177e4SLinus Torvalds  *              If Non-SG transfer then report Total Cnt - Actual Transfer
77731da177e4SLinus Torvalds  *              Cnt.  For SG transfers add the count fields of all
77741da177e4SLinus Torvalds  *              remaining SG elements, as well as any partial remaining
77751da177e4SLinus Torvalds  *              element.
77761da177e4SLinus Torvalds  *
77771da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
77781da177e4SLinus Torvalds 
7779*47b5d69cSJames Bottomley  static void  FPT_utilUpdateResidual(PSCCB p_SCCB)
77801da177e4SLinus Torvalds {
77811da177e4SLinus Torvalds    ULONG partial_cnt;
77821da177e4SLinus Torvalds    UINT  sg_index;
77831da177e4SLinus Torvalds    ULONG *sg_ptr;
77841da177e4SLinus Torvalds 
77851da177e4SLinus Torvalds    if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
77861da177e4SLinus Torvalds 
77871da177e4SLinus Torvalds 	  p_SCCB->DataLength = 0x0000;
77881da177e4SLinus Torvalds 	  }
77891da177e4SLinus Torvalds 
77901da177e4SLinus Torvalds    else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
77911da177e4SLinus Torvalds 
77921da177e4SLinus Torvalds 		 partial_cnt = 0x0000;
77931da177e4SLinus Torvalds 
77941da177e4SLinus Torvalds 		 sg_index = p_SCCB->Sccb_sgseg;
77951da177e4SLinus Torvalds 
77961da177e4SLinus Torvalds 		 sg_ptr = (ULONG *)p_SCCB->DataPointer;
77971da177e4SLinus Torvalds 
77981da177e4SLinus Torvalds 		 if (p_SCCB->Sccb_SGoffset) {
77991da177e4SLinus Torvalds 
78001da177e4SLinus Torvalds 			partial_cnt = p_SCCB->Sccb_SGoffset;
78011da177e4SLinus Torvalds 			sg_index++;
78021da177e4SLinus Torvalds 			}
78031da177e4SLinus Torvalds 
78041da177e4SLinus Torvalds 		 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
78051da177e4SLinus Torvalds 			p_SCCB->DataLength ) {
78061da177e4SLinus Torvalds 
78071da177e4SLinus Torvalds 			partial_cnt += *(sg_ptr+(sg_index * 2));
78081da177e4SLinus Torvalds 			sg_index++;
78091da177e4SLinus Torvalds 			}
78101da177e4SLinus Torvalds 
78111da177e4SLinus Torvalds 		 p_SCCB->DataLength = partial_cnt;
78121da177e4SLinus Torvalds 		 }
78131da177e4SLinus Torvalds 
78141da177e4SLinus Torvalds 	  else {
78151da177e4SLinus Torvalds 
78161da177e4SLinus Torvalds 		 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
78171da177e4SLinus Torvalds 		 }
78181da177e4SLinus Torvalds }
78191da177e4SLinus Torvalds 
78201da177e4SLinus Torvalds 
78211da177e4SLinus Torvalds /*---------------------------------------------------------------------
78221da177e4SLinus Torvalds  *
78231da177e4SLinus Torvalds  * Function: Wait 1 Second
78241da177e4SLinus Torvalds  *
78251da177e4SLinus Torvalds  * Description: Wait for 1 second.
78261da177e4SLinus Torvalds  *
78271da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
78281da177e4SLinus Torvalds 
7829*47b5d69cSJames Bottomley  static void FPT_Wait1Second(ULONG p_port)
78301da177e4SLinus Torvalds {
78311da177e4SLinus Torvalds    UCHAR i;
78321da177e4SLinus Torvalds 
78331da177e4SLinus Torvalds    for(i=0; i < 4; i++) {
78341da177e4SLinus Torvalds 
7835*47b5d69cSJames Bottomley  	  FPT_Wait(p_port, TO_250ms);
78361da177e4SLinus Torvalds 
78371da177e4SLinus Torvalds 	  if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
78381da177e4SLinus Torvalds 		 break;
78391da177e4SLinus Torvalds 
78401da177e4SLinus Torvalds 	  if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
78411da177e4SLinus Torvalds 		 break;
78421da177e4SLinus Torvalds 	  }
78431da177e4SLinus Torvalds }
78441da177e4SLinus Torvalds 
78451da177e4SLinus Torvalds 
78461da177e4SLinus Torvalds /*---------------------------------------------------------------------
78471da177e4SLinus Torvalds  *
7848*47b5d69cSJames Bottomley   * Function: FPT_Wait
78491da177e4SLinus Torvalds  *
78501da177e4SLinus Torvalds  * Description: Wait the desired delay.
78511da177e4SLinus Torvalds  *
78521da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
78531da177e4SLinus Torvalds 
7854*47b5d69cSJames Bottomley  static void FPT_Wait(ULONG p_port, UCHAR p_delay)
78551da177e4SLinus Torvalds {
78561da177e4SLinus Torvalds    UCHAR old_timer;
78571da177e4SLinus Torvalds    UCHAR green_flag;
78581da177e4SLinus Torvalds 
78591da177e4SLinus Torvalds    old_timer = RD_HARPOON(p_port+hp_seltimeout);
78601da177e4SLinus Torvalds 
78611da177e4SLinus Torvalds    green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
78621da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
78631da177e4SLinus Torvalds 
78641da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,p_delay);
78651da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7866*47b5d69cSJames Bottomley     WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
78671da177e4SLinus Torvalds 
78681da177e4SLinus Torvalds 
78691da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0,
78701da177e4SLinus Torvalds 	  (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
78711da177e4SLinus Torvalds 
78721da177e4SLinus Torvalds    while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
78731da177e4SLinus Torvalds 
78741da177e4SLinus Torvalds 	  if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
78751da177e4SLinus Torvalds 		 break;
78761da177e4SLinus Torvalds 
78771da177e4SLinus Torvalds 	  if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
78781da177e4SLinus Torvalds 		 break;
78791da177e4SLinus Torvalds 	  }
78801da177e4SLinus Torvalds 
78811da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_portctrl_0,
78821da177e4SLinus Torvalds 	  (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
78831da177e4SLinus Torvalds 
78841da177e4SLinus Torvalds    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7885*47b5d69cSJames Bottomley     WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
78861da177e4SLinus Torvalds 
78871da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
78881da177e4SLinus Torvalds 
78891da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_seltimeout,old_timer);
78901da177e4SLinus Torvalds }
78911da177e4SLinus Torvalds 
78921da177e4SLinus Torvalds 
78931da177e4SLinus Torvalds /*---------------------------------------------------------------------
78941da177e4SLinus Torvalds  *
78951da177e4SLinus Torvalds  * Function: Enable/Disable Write to EEPROM
78961da177e4SLinus Torvalds  *
78971da177e4SLinus Torvalds  * Description: The EEPROM must first be enabled for writes
78981da177e4SLinus Torvalds  *              A total of 9 clocks are needed.
78991da177e4SLinus Torvalds  *
79001da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
79011da177e4SLinus Torvalds 
7902*47b5d69cSJames Bottomley  static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
79031da177e4SLinus Torvalds {
79041da177e4SLinus Torvalds    UCHAR ee_value;
79051da177e4SLinus Torvalds 
79061da177e4SLinus Torvalds    ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
79071da177e4SLinus Torvalds 
79081da177e4SLinus Torvalds    if (p_mode)
79091da177e4SLinus Torvalds 
7910*47b5d69cSJames Bottomley  	  FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
79111da177e4SLinus Torvalds 
79121da177e4SLinus Torvalds    else
79131da177e4SLinus Torvalds 
79141da177e4SLinus Torvalds 
7915*47b5d69cSJames Bottomley  	  FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
79161da177e4SLinus Torvalds 
79171da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
79181da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /*Turn off Master Select */
79191da177e4SLinus Torvalds }
79201da177e4SLinus Torvalds 
79211da177e4SLinus Torvalds 
79221da177e4SLinus Torvalds /*---------------------------------------------------------------------
79231da177e4SLinus Torvalds  *
79241da177e4SLinus Torvalds  * Function: Write EEPROM
79251da177e4SLinus Torvalds  *
79261da177e4SLinus Torvalds  * Description: Write a word to the EEPROM at the specified
79271da177e4SLinus Torvalds  *              address.
79281da177e4SLinus Torvalds  *
79291da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
79301da177e4SLinus Torvalds 
7931*47b5d69cSJames Bottomley  static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
79321da177e4SLinus Torvalds {
79331da177e4SLinus Torvalds 
79341da177e4SLinus Torvalds    UCHAR ee_value;
79351da177e4SLinus Torvalds    USHORT i;
79361da177e4SLinus Torvalds 
79371da177e4SLinus Torvalds    ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
79381da177e4SLinus Torvalds 		   (SEE_MS | SEE_CS));
79391da177e4SLinus Torvalds 
79401da177e4SLinus Torvalds 
79411da177e4SLinus Torvalds 
7942*47b5d69cSJames Bottomley     FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
79431da177e4SLinus Torvalds 
79441da177e4SLinus Torvalds 
79451da177e4SLinus Torvalds    ee_value |= (SEE_MS + SEE_CS);
79461da177e4SLinus Torvalds 
79471da177e4SLinus Torvalds    for(i = 0x8000; i != 0; i>>=1) {
79481da177e4SLinus Torvalds 
79491da177e4SLinus Torvalds 	  if (i & ee_data)
79501da177e4SLinus Torvalds 	 ee_value |= SEE_DO;
79511da177e4SLinus Torvalds 	  else
79521da177e4SLinus Torvalds 	 ee_value &= ~SEE_DO;
79531da177e4SLinus Torvalds 
79541da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
79551da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
79561da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;          /* Clock  data! */
79571da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
79581da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
79591da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
79601da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
79611da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
79621da177e4SLinus Torvalds 	  }
79631da177e4SLinus Torvalds    ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
79641da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
79651da177e4SLinus Torvalds 
7966*47b5d69cSJames Bottomley     FPT_Wait(p_port, TO_10ms);
79671da177e4SLinus Torvalds 
79681da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
79691da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));       /* Turn off CS */
79701da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /* Turn off Master Select */
79711da177e4SLinus Torvalds }
79721da177e4SLinus Torvalds 
79731da177e4SLinus Torvalds /*---------------------------------------------------------------------
79741da177e4SLinus Torvalds  *
79751da177e4SLinus Torvalds  * Function: Read EEPROM
79761da177e4SLinus Torvalds  *
79771da177e4SLinus Torvalds  * Description: Read a word from the EEPROM at the desired
79781da177e4SLinus Torvalds  *              address.
79791da177e4SLinus Torvalds  *
79801da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
79811da177e4SLinus Torvalds 
7982*47b5d69cSJames Bottomley  static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
79831da177e4SLinus Torvalds {
79841da177e4SLinus Torvalds    USHORT i, ee_data1, ee_data2;
79851da177e4SLinus Torvalds 
79861da177e4SLinus Torvalds 	i = 0;
7987*47b5d69cSJames Bottomley  	ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
79881da177e4SLinus Torvalds 	do
79891da177e4SLinus Torvalds 	{
7990*47b5d69cSJames Bottomley  		ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
79911da177e4SLinus Torvalds 
79921da177e4SLinus Torvalds 		if(ee_data1 == ee_data2)
79931da177e4SLinus Torvalds 			return(ee_data1);
79941da177e4SLinus Torvalds 
79951da177e4SLinus Torvalds 		ee_data1 = ee_data2;
79961da177e4SLinus Torvalds 		i++;
79971da177e4SLinus Torvalds 
79981da177e4SLinus Torvalds 	}while(i < 4);
79991da177e4SLinus Torvalds 
80001da177e4SLinus Torvalds 	return(ee_data1);
80011da177e4SLinus Torvalds }
80021da177e4SLinus Torvalds 
80031da177e4SLinus Torvalds /*---------------------------------------------------------------------
80041da177e4SLinus Torvalds  *
80051da177e4SLinus Torvalds  * Function: Read EEPROM Original
80061da177e4SLinus Torvalds  *
80071da177e4SLinus Torvalds  * Description: Read a word from the EEPROM at the desired
80081da177e4SLinus Torvalds  *              address.
80091da177e4SLinus Torvalds  *
80101da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
80111da177e4SLinus Torvalds 
8012*47b5d69cSJames Bottomley  static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
80131da177e4SLinus Torvalds {
80141da177e4SLinus Torvalds 
80151da177e4SLinus Torvalds    UCHAR ee_value;
80161da177e4SLinus Torvalds    USHORT i, ee_data;
80171da177e4SLinus Torvalds 
80181da177e4SLinus Torvalds    ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
80191da177e4SLinus Torvalds 		   (SEE_MS | SEE_CS));
80201da177e4SLinus Torvalds 
80211da177e4SLinus Torvalds 
8022*47b5d69cSJames Bottomley     FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
80231da177e4SLinus Torvalds 
80241da177e4SLinus Torvalds 
80251da177e4SLinus Torvalds    ee_value |= (SEE_MS + SEE_CS);
80261da177e4SLinus Torvalds    ee_data = 0;
80271da177e4SLinus Torvalds 
80281da177e4SLinus Torvalds    for(i = 1; i <= 16; i++) {
80291da177e4SLinus Torvalds 
80301da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;          /* Clock  data! */
80311da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80321da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80331da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
80341da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80351da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80361da177e4SLinus Torvalds 
80371da177e4SLinus Torvalds 	  ee_data <<= 1;
80381da177e4SLinus Torvalds 
80391da177e4SLinus Torvalds 	  if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
80401da177e4SLinus Torvalds 		 ee_data |= 1;
80411da177e4SLinus Torvalds 	  }
80421da177e4SLinus Torvalds 
80431da177e4SLinus Torvalds    ee_value &= ~(SEE_MS + SEE_CS);
80441da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
80451da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);   /*Turn off Master Select */
80461da177e4SLinus Torvalds 
80471da177e4SLinus Torvalds    return(ee_data);
80481da177e4SLinus Torvalds }
80491da177e4SLinus Torvalds 
80501da177e4SLinus Torvalds 
80511da177e4SLinus Torvalds /*---------------------------------------------------------------------
80521da177e4SLinus Torvalds  *
80531da177e4SLinus Torvalds  * Function: Send EE command and Address to the EEPROM
80541da177e4SLinus Torvalds  *
80551da177e4SLinus Torvalds  * Description: Transfers the correct command and sends the address
80561da177e4SLinus Torvalds  *              to the eeprom.
80571da177e4SLinus Torvalds  *
80581da177e4SLinus Torvalds  *---------------------------------------------------------------------*/
80591da177e4SLinus Torvalds 
8060*47b5d69cSJames Bottomley  static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
80611da177e4SLinus Torvalds {
80621da177e4SLinus Torvalds    UCHAR ee_value;
80631da177e4SLinus Torvalds    UCHAR narrow_flg;
80641da177e4SLinus Torvalds 
80651da177e4SLinus Torvalds    USHORT i;
80661da177e4SLinus Torvalds 
80671da177e4SLinus Torvalds 
80681da177e4SLinus Torvalds    narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
80691da177e4SLinus Torvalds 
80701da177e4SLinus Torvalds 
80711da177e4SLinus Torvalds    ee_value = SEE_MS;
80721da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80731da177e4SLinus Torvalds 
80741da177e4SLinus Torvalds    ee_value |= SEE_CS;                             /* Set CS to EEPROM */
80751da177e4SLinus Torvalds    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80761da177e4SLinus Torvalds 
80771da177e4SLinus Torvalds 
80781da177e4SLinus Torvalds    for(i = 0x04; i != 0; i>>=1) {
80791da177e4SLinus Torvalds 
80801da177e4SLinus Torvalds 	  if (i & ee_cmd)
80811da177e4SLinus Torvalds 		 ee_value |= SEE_DO;
80821da177e4SLinus Torvalds 	  else
80831da177e4SLinus Torvalds 		 ee_value &= ~SEE_DO;
80841da177e4SLinus Torvalds 
80851da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80861da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80871da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;                         /* Clock  data! */
80881da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80891da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80901da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
80911da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80921da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
80931da177e4SLinus Torvalds 	  }
80941da177e4SLinus Torvalds 
80951da177e4SLinus Torvalds 
80961da177e4SLinus Torvalds    if (narrow_flg)
80971da177e4SLinus Torvalds 	  i = 0x0080;
80981da177e4SLinus Torvalds 
80991da177e4SLinus Torvalds    else
81001da177e4SLinus Torvalds 	  i = 0x0200;
81011da177e4SLinus Torvalds 
81021da177e4SLinus Torvalds 
81031da177e4SLinus Torvalds    while (i != 0) {
81041da177e4SLinus Torvalds 
81051da177e4SLinus Torvalds 	  if (i & ee_addr)
81061da177e4SLinus Torvalds 		 ee_value |= SEE_DO;
81071da177e4SLinus Torvalds 	  else
81081da177e4SLinus Torvalds 		 ee_value &= ~SEE_DO;
81091da177e4SLinus Torvalds 
81101da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
81111da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
81121da177e4SLinus Torvalds 	  ee_value |= SEE_CLK;                         /* Clock  data! */
81131da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
81141da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
81151da177e4SLinus Torvalds 	  ee_value &= ~SEE_CLK;
81161da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
81171da177e4SLinus Torvalds 	  WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
81181da177e4SLinus Torvalds 
81191da177e4SLinus Torvalds 	  i >>= 1;
81201da177e4SLinus Torvalds 	  }
81211da177e4SLinus Torvalds }
81221da177e4SLinus Torvalds 
8123*47b5d69cSJames Bottomley  static USHORT FPT_CalcCrc16(UCHAR buffer[])
81241da177e4SLinus Torvalds {
81251da177e4SLinus Torvalds    USHORT crc=0;
81261da177e4SLinus Torvalds 	int i,j;
81271da177e4SLinus Torvalds    USHORT ch;
81281da177e4SLinus Torvalds    for (i=0; i < ID_STRING_LENGTH; i++)
81291da177e4SLinus Torvalds    {
81301da177e4SLinus Torvalds       ch = (USHORT) buffer[i];
81311da177e4SLinus Torvalds 	   for(j=0; j < 8; j++)
81321da177e4SLinus Torvalds 	   {
81331da177e4SLinus Torvalds 		   if ((crc ^ ch) & 1)
81341da177e4SLinus Torvalds             crc = (crc >> 1) ^ CRCMASK;
81351da177e4SLinus Torvalds 		   else
81361da177e4SLinus Torvalds             crc >>= 1;
81371da177e4SLinus Torvalds 		   ch >>= 1;
81381da177e4SLinus Torvalds 	   }
81391da177e4SLinus Torvalds    }
81401da177e4SLinus Torvalds 	return(crc);
81411da177e4SLinus Torvalds }
81421da177e4SLinus Torvalds 
8143*47b5d69cSJames Bottomley  static UCHAR FPT_CalcLrc(UCHAR buffer[])
81441da177e4SLinus Torvalds {
81451da177e4SLinus Torvalds 	int i;
81461da177e4SLinus Torvalds 	UCHAR lrc;
81471da177e4SLinus Torvalds 	lrc = 0;
81481da177e4SLinus Torvalds 	for(i = 0; i < ID_STRING_LENGTH; i++)
81491da177e4SLinus Torvalds 		lrc ^= buffer[i];
81501da177e4SLinus Torvalds 	return(lrc);
81511da177e4SLinus Torvalds }
81521da177e4SLinus Torvalds 
81531da177e4SLinus Torvalds 
81541da177e4SLinus Torvalds 
81551da177e4SLinus Torvalds /*
81561da177e4SLinus Torvalds   The following inline definitions avoid type conflicts.
81571da177e4SLinus Torvalds */
81581da177e4SLinus Torvalds 
81591da177e4SLinus Torvalds static inline unsigned char
81601da177e4SLinus Torvalds FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
81611da177e4SLinus Torvalds {
81621da177e4SLinus Torvalds   return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
81631da177e4SLinus Torvalds }
81641da177e4SLinus Torvalds 
81651da177e4SLinus Torvalds 
81661da177e4SLinus Torvalds static inline FlashPoint_CardHandle_T
81671da177e4SLinus Torvalds FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
81681da177e4SLinus Torvalds {
81691da177e4SLinus Torvalds   return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
81701da177e4SLinus Torvalds }
81711da177e4SLinus Torvalds 
81721da177e4SLinus Torvalds static inline void
81731da177e4SLinus Torvalds FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
81741da177e4SLinus Torvalds {
81751da177e4SLinus Torvalds   FlashPoint_ReleaseHostAdapter(CardHandle);
81761da177e4SLinus Torvalds }
81771da177e4SLinus Torvalds 
81781da177e4SLinus Torvalds 
81791da177e4SLinus Torvalds static inline void
81801da177e4SLinus Torvalds FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
81811da177e4SLinus Torvalds {
81821da177e4SLinus Torvalds   FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
81831da177e4SLinus Torvalds }
81841da177e4SLinus Torvalds 
81851da177e4SLinus Torvalds 
81861da177e4SLinus Torvalds static inline void
81871da177e4SLinus Torvalds FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
81881da177e4SLinus Torvalds {
81891da177e4SLinus Torvalds   FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
81901da177e4SLinus Torvalds }
81911da177e4SLinus Torvalds 
81921da177e4SLinus Torvalds 
81931da177e4SLinus Torvalds static inline boolean
81941da177e4SLinus Torvalds FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
81951da177e4SLinus Torvalds {
81961da177e4SLinus Torvalds   return FlashPoint_InterruptPending(CardHandle);
81971da177e4SLinus Torvalds }
81981da177e4SLinus Torvalds 
81991da177e4SLinus Torvalds 
82001da177e4SLinus Torvalds static inline int
82011da177e4SLinus Torvalds FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
82021da177e4SLinus Torvalds {
82031da177e4SLinus Torvalds   return FlashPoint_HandleInterrupt(CardHandle);
82041da177e4SLinus Torvalds }
82051da177e4SLinus Torvalds 
82061da177e4SLinus Torvalds 
82071da177e4SLinus Torvalds #define FlashPoint_ProbeHostAdapter	    FlashPoint__ProbeHostAdapter
82081da177e4SLinus Torvalds #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
82091da177e4SLinus Torvalds #define FlashPoint_ReleaseHostAdapter	    FlashPoint__ReleaseHostAdapter
82101da177e4SLinus Torvalds #define FlashPoint_StartCCB		    FlashPoint__StartCCB
82111da177e4SLinus Torvalds #define FlashPoint_AbortCCB		    FlashPoint__AbortCCB
82121da177e4SLinus Torvalds #define FlashPoint_InterruptPending	    FlashPoint__InterruptPending
82131da177e4SLinus Torvalds #define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
82141da177e4SLinus Torvalds 
82151da177e4SLinus Torvalds 
82161da177e4SLinus Torvalds #else  /* CONFIG_SCSI_OMIT_FLASHPOINT */
82171da177e4SLinus Torvalds 
82181da177e4SLinus Torvalds 
82191da177e4SLinus Torvalds /*
82201da177e4SLinus Torvalds   Define prototypes for the FlashPoint SCCB Manager Functions.
82211da177e4SLinus Torvalds */
82221da177e4SLinus Torvalds 
82231da177e4SLinus Torvalds extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
82241da177e4SLinus Torvalds extern FlashPoint_CardHandle_T
82251da177e4SLinus Torvalds        FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
82261da177e4SLinus Torvalds extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
82271da177e4SLinus Torvalds extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
82281da177e4SLinus Torvalds extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
82291da177e4SLinus Torvalds extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
82301da177e4SLinus Torvalds extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
82311da177e4SLinus Torvalds 
82321da177e4SLinus Torvalds 
82331da177e4SLinus Torvalds #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */
8234