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