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