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 1978b4b05dSMatthew Wilcox #ifdef CONFIG_SCSI_FLASHPOINT 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds #define MAX_CARDS 8 221da177e4SLinus Torvalds #undef BUSTYPE_PCI 231da177e4SLinus Torvalds 241da177e4SLinus Torvalds #define CRCMASK 0xA001 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds #define FAILURE 0xFFFFFFFFL 271da177e4SLinus Torvalds 2869eb2ea4SAlexey Dobriyan struct sccb; 2969eb2ea4SAlexey Dobriyan typedef void (*CALL_BK_FN) (struct sccb *); 301da177e4SLinus Torvalds 317f101662SAlexey Dobriyan struct sccb_mgr_info { 32391e2f25SKhalid Aziz u32 si_baseaddr; 33db038cf8SAlexey Dobriyan unsigned char si_present; 34db038cf8SAlexey Dobriyan unsigned char si_intvect; 35db038cf8SAlexey Dobriyan unsigned char si_id; 36db038cf8SAlexey Dobriyan unsigned char si_lun; 37391e2f25SKhalid Aziz u16 si_fw_revision; 38391e2f25SKhalid Aziz u16 si_per_targ_init_sync; 39391e2f25SKhalid Aziz u16 si_per_targ_fast_nego; 40391e2f25SKhalid Aziz u16 si_per_targ_ultra_nego; 41391e2f25SKhalid Aziz u16 si_per_targ_no_disc; 42391e2f25SKhalid Aziz u16 si_per_targ_wide_nego; 43391e2f25SKhalid Aziz u16 si_flags; 44db038cf8SAlexey Dobriyan unsigned char si_card_family; 45db038cf8SAlexey Dobriyan unsigned char si_bustype; 46db038cf8SAlexey Dobriyan unsigned char si_card_model[3]; 47db038cf8SAlexey Dobriyan unsigned char si_relative_cardnum; 48db038cf8SAlexey Dobriyan unsigned char si_reserved[4]; 49391e2f25SKhalid Aziz u32 si_OS_reserved; 50db038cf8SAlexey Dobriyan unsigned char si_XlatInfo[4]; 51391e2f25SKhalid Aziz u32 si_reserved2[5]; 52391e2f25SKhalid Aziz u32 si_secondary_range; 537f101662SAlexey Dobriyan }; 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds #define SCSI_PARITY_ENA 0x0001 561da177e4SLinus Torvalds #define LOW_BYTE_TERM 0x0010 571da177e4SLinus Torvalds #define HIGH_BYTE_TERM 0x0020 581da177e4SLinus Torvalds #define BUSTYPE_PCI 0x3 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds #define SUPPORT_16TAR_32LUN 0x0002 611da177e4SLinus Torvalds #define SOFT_RESET 0x0004 621da177e4SLinus Torvalds #define EXTENDED_TRANSLATION 0x0008 631da177e4SLinus Torvalds #define POST_ALL_UNDERRRUNS 0x0040 641da177e4SLinus Torvalds #define FLAG_SCAM_ENABLED 0x0080 651da177e4SLinus Torvalds #define FLAG_SCAM_LEVEL2 0x0100 661da177e4SLinus Torvalds 671da177e4SLinus Torvalds #define HARPOON_FAMILY 0x02 681da177e4SLinus Torvalds 6932357988SAlexey Dobriyan /* SCCB struct used for both SCCB and UCB manager compiles! 701da177e4SLinus Torvalds * The UCB Manager treats the SCCB as it's 'native hardware structure' 711da177e4SLinus Torvalds */ 721da177e4SLinus Torvalds 73391e2f25SKhalid Aziz /*#pragma pack(1)*/ 7469eb2ea4SAlexey Dobriyan struct sccb { 75db038cf8SAlexey Dobriyan unsigned char OperationCode; 76db038cf8SAlexey Dobriyan unsigned char ControlByte; 77db038cf8SAlexey Dobriyan unsigned char CdbLength; 78db038cf8SAlexey Dobriyan unsigned char RequestSenseLength; 79391e2f25SKhalid Aziz u32 DataLength; 80391e2f25SKhalid Aziz void *DataPointer; 81db038cf8SAlexey Dobriyan unsigned char CcbRes[2]; 82db038cf8SAlexey Dobriyan unsigned char HostStatus; 83db038cf8SAlexey Dobriyan unsigned char TargetStatus; 84db038cf8SAlexey Dobriyan unsigned char TargID; 85db038cf8SAlexey Dobriyan unsigned char Lun; 86db038cf8SAlexey Dobriyan unsigned char Cdb[12]; 87db038cf8SAlexey Dobriyan unsigned char CcbRes1; 88db038cf8SAlexey Dobriyan unsigned char Reserved1; 89391e2f25SKhalid Aziz u32 Reserved2; 90391e2f25SKhalid Aziz u32 SensePointer; 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */ 93391e2f25SKhalid Aziz u32 SccbIOPort; /* Identifies board base port */ 94db038cf8SAlexey Dobriyan unsigned char SccbStatus; 95db038cf8SAlexey Dobriyan unsigned char SCCBRes2; 96391e2f25SKhalid Aziz u16 SccbOSFlags; 971da177e4SLinus Torvalds 98391e2f25SKhalid Aziz u32 Sccb_XferCnt; /* actual transfer count */ 99391e2f25SKhalid Aziz u32 Sccb_ATC; 100391e2f25SKhalid Aziz u32 SccbVirtDataPtr; /* virtual addr for OS/2 */ 101391e2f25SKhalid Aziz u32 Sccb_res1; 102391e2f25SKhalid Aziz u16 Sccb_MGRFlags; 103391e2f25SKhalid Aziz u16 Sccb_sgseg; 104db038cf8SAlexey Dobriyan unsigned char Sccb_scsimsg; /* identify msg for selection */ 105db038cf8SAlexey Dobriyan unsigned char Sccb_tag; 106db038cf8SAlexey Dobriyan unsigned char Sccb_scsistat; 107db038cf8SAlexey Dobriyan unsigned char Sccb_idmsg; /* image of last msg in */ 10869eb2ea4SAlexey Dobriyan struct sccb *Sccb_forwardlink; 10969eb2ea4SAlexey Dobriyan struct sccb *Sccb_backlink; 110391e2f25SKhalid Aziz u32 Sccb_savedATC; 111db038cf8SAlexey Dobriyan unsigned char Save_Cdb[6]; 112db038cf8SAlexey Dobriyan unsigned char Save_CdbLen; 113db038cf8SAlexey Dobriyan unsigned char Sccb_XferState; 114391e2f25SKhalid Aziz u32 Sccb_SGoffset; 11569eb2ea4SAlexey Dobriyan }; 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds #pragma pack() 1181da177e4SLinus Torvalds 1191da177e4SLinus Torvalds #define SCATTER_GATHER_COMMAND 0x02 1201da177e4SLinus Torvalds #define RESIDUAL_COMMAND 0x03 1211da177e4SLinus Torvalds #define RESIDUAL_SG_COMMAND 0x04 1221da177e4SLinus Torvalds #define RESET_COMMAND 0x81 1231da177e4SLinus Torvalds 1241da177e4SLinus Torvalds #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */ 1251da177e4SLinus Torvalds #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */ 1261da177e4SLinus Torvalds #define SCCB_DATA_XFER_OUT 0x10 /* Write */ 1271da177e4SLinus Torvalds #define SCCB_DATA_XFER_IN 0x08 /* Read */ 1281da177e4SLinus Torvalds 1291da177e4SLinus Torvalds #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ 1301da177e4SLinus Torvalds 1311da177e4SLinus Torvalds #define BUS_FREE_ST 0 1321da177e4SLinus Torvalds #define SELECT_ST 1 1331da177e4SLinus Torvalds #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */ 1341da177e4SLinus Torvalds #define SELECT_SN_ST 3 /* Select w\ Sync Nego */ 1351da177e4SLinus Torvalds #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */ 1361da177e4SLinus Torvalds #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */ 1371da177e4SLinus Torvalds #define COMMAND_ST 6 1381da177e4SLinus Torvalds #define DATA_OUT_ST 7 1391da177e4SLinus Torvalds #define DATA_IN_ST 8 1401da177e4SLinus Torvalds #define DISCONNECT_ST 9 1411da177e4SLinus Torvalds #define ABORT_ST 11 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds #define F_HOST_XFER_DIR 0x01 1441da177e4SLinus Torvalds #define F_ALL_XFERRED 0x02 1451da177e4SLinus Torvalds #define F_SG_XFER 0x04 1461da177e4SLinus Torvalds #define F_AUTO_SENSE 0x08 1471da177e4SLinus Torvalds #define F_ODD_BALL_CNT 0x10 1481da177e4SLinus Torvalds #define F_NO_DATA_YET 0x80 1491da177e4SLinus Torvalds 1501da177e4SLinus Torvalds #define F_STATUSLOADED 0x01 1511da177e4SLinus Torvalds #define F_DEV_SELECTED 0x04 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds #define SCCB_COMPLETE 0x00 /* SCCB completed without error */ 1541da177e4SLinus Torvalds #define SCCB_DATA_UNDER_RUN 0x0C 1551da177e4SLinus Torvalds #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ 1561da177e4SLinus Torvalds #define SCCB_DATA_OVER_RUN 0x12 1571da177e4SLinus Torvalds #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */ 1581da177e4SLinus Torvalds 1591da177e4SLinus Torvalds #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */ 1601da177e4SLinus Torvalds #define SCCB_BM_ERR 0x30 /* BusMaster error. */ 1611da177e4SLinus Torvalds #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */ 1621da177e4SLinus Torvalds 1631da177e4SLinus Torvalds #define SCCB_IN_PROCESS 0x00 1641da177e4SLinus Torvalds #define SCCB_SUCCESS 0x01 1651da177e4SLinus Torvalds #define SCCB_ABORT 0x02 1661da177e4SLinus Torvalds #define SCCB_ERROR 0x04 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds #define ORION_FW_REV 3110 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */ 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */ 1731da177e4SLinus Torvalds 1741da177e4SLinus Torvalds #define MAX_SCSI_TAR 16 1751da177e4SLinus Torvalds #define MAX_LUN 32 1761da177e4SLinus Torvalds #define LUN_MASK 0x1f 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds #define SG_BUF_CNT 16 /*Number of prefetched elements. */ 1791da177e4SLinus Torvalds 1801da177e4SLinus Torvalds #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */ 1811da177e4SLinus Torvalds 182ad0e1d9fSAlexey Dobriyan #define RD_HARPOON(ioport) inb((u32)ioport) 183ad0e1d9fSAlexey Dobriyan #define RDW_HARPOON(ioport) inw((u32)ioport) 184ad0e1d9fSAlexey Dobriyan #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset))) 185ad0e1d9fSAlexey Dobriyan #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport) 186ad0e1d9fSAlexey Dobriyan #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport) 187ad0e1d9fSAlexey Dobriyan #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset)) 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds #define TAR_SYNC_MASK (BIT(7)+BIT(6)) 1901da177e4SLinus Torvalds #define SYNC_TRYING BIT(6) 1911da177e4SLinus Torvalds #define SYNC_SUPPORTED (BIT(7)+BIT(6)) 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds #define TAR_WIDE_MASK (BIT(5)+BIT(4)) 1941da177e4SLinus Torvalds #define WIDE_ENABLED BIT(4) 1951da177e4SLinus Torvalds #define WIDE_NEGOCIATED BIT(5) 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds #define TAR_TAG_Q_MASK (BIT(3)+BIT(2)) 1981da177e4SLinus Torvalds #define TAG_Q_TRYING BIT(2) 1991da177e4SLinus Torvalds #define TAG_Q_REJECT BIT(3) 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds #define TAR_ALLOW_DISC BIT(0) 2021da177e4SLinus Torvalds 2031da177e4SLinus Torvalds #define EE_SYNC_MASK (BIT(0)+BIT(1)) 2041da177e4SLinus Torvalds #define EE_SYNC_5MB BIT(0) 2051da177e4SLinus Torvalds #define EE_SYNC_10MB BIT(1) 2061da177e4SLinus Torvalds #define EE_SYNC_20MB (BIT(0)+BIT(1)) 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds #define EE_WIDE_SCSI BIT(7) 2091da177e4SLinus Torvalds 210f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info { 2111da177e4SLinus Torvalds 21269eb2ea4SAlexey Dobriyan struct sccb *TarSelQ_Head; 21369eb2ea4SAlexey Dobriyan struct sccb *TarSelQ_Tail; 214db038cf8SAlexey Dobriyan unsigned char TarLUN_CA; /*Contingent Allgiance */ 215db038cf8SAlexey Dobriyan unsigned char TarTagQ_Cnt; 216db038cf8SAlexey Dobriyan unsigned char TarSelQ_Cnt; 217db038cf8SAlexey Dobriyan unsigned char TarStatus; 218db038cf8SAlexey Dobriyan unsigned char TarEEValue; 219db038cf8SAlexey Dobriyan unsigned char TarSyncCtrl; 220db038cf8SAlexey Dobriyan unsigned char TarReserved[2]; /* for alignment */ 221db038cf8SAlexey Dobriyan unsigned char LunDiscQ_Idx[MAX_LUN]; 222db038cf8SAlexey Dobriyan unsigned char TarLUNBusy[MAX_LUN]; 223f31dc0cdSAlexey Dobriyan }; 2241da177e4SLinus Torvalds 22568d0c1aeSAlexey Dobriyan struct nvram_info { 226db038cf8SAlexey Dobriyan unsigned char niModel; /* Model No. of card */ 227db038cf8SAlexey Dobriyan unsigned char niCardNo; /* Card no. */ 228391e2f25SKhalid Aziz u32 niBaseAddr; /* Port Address of card */ 229391e2f25SKhalid Aziz unsigned char niSysConf; /* Adapter Configuration byte - 230391e2f25SKhalid Aziz Byte 16 of eeprom map */ 231391e2f25SKhalid Aziz unsigned char niScsiConf; /* SCSI Configuration byte - 232391e2f25SKhalid Aziz Byte 17 of eeprom map */ 233391e2f25SKhalid Aziz unsigned char niScamConf; /* SCAM Configuration byte - 234391e2f25SKhalid Aziz Byte 20 of eeprom map */ 235391e2f25SKhalid Aziz unsigned char niAdapId; /* Host Adapter ID - 236391e2f25SKhalid Aziz Byte 24 of eerpom map */ 237391e2f25SKhalid Aziz unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte 238391e2f25SKhalid Aziz of targets */ 239391e2f25SKhalid Aziz unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name 240391e2f25SKhalid Aziz string of Targets */ 24168d0c1aeSAlexey Dobriyan }; 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds #define MODEL_LT 1 2441da177e4SLinus Torvalds #define MODEL_DL 2 2451da177e4SLinus Torvalds #define MODEL_LW 3 2461da177e4SLinus Torvalds #define MODEL_DW 4 2471da177e4SLinus Torvalds 24813e6851aSAlexey Dobriyan struct sccb_card { 24969eb2ea4SAlexey Dobriyan struct sccb *currentSCCB; 2507f101662SAlexey Dobriyan struct sccb_mgr_info *cardInfo; 2511da177e4SLinus Torvalds 252391e2f25SKhalid Aziz u32 ioPort; 2531da177e4SLinus Torvalds 254c823feebSAlexey Dobriyan unsigned short cmdCounter; 255db038cf8SAlexey Dobriyan unsigned char discQCount; 256db038cf8SAlexey Dobriyan unsigned char tagQ_Lst; 257db038cf8SAlexey Dobriyan unsigned char cardIndex; 258db038cf8SAlexey Dobriyan unsigned char scanIndex; 259db038cf8SAlexey Dobriyan unsigned char globalFlags; 260db038cf8SAlexey Dobriyan unsigned char ourId; 26168d0c1aeSAlexey Dobriyan struct nvram_info *pNvRamInfo; 26269eb2ea4SAlexey Dobriyan struct sccb *discQ_Tbl[QUEUE_DEPTH]; 2631da177e4SLinus Torvalds 26413e6851aSAlexey Dobriyan }; 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds #define F_TAG_STARTED 0x01 2671da177e4SLinus Torvalds #define F_CONLUN_IO 0x02 2681da177e4SLinus Torvalds #define F_DO_RENEGO 0x04 2691da177e4SLinus Torvalds #define F_NO_FILTER 0x08 2701da177e4SLinus Torvalds #define F_GREEN_PC 0x10 2711da177e4SLinus Torvalds #define F_HOST_XFER_ACT 0x20 2721da177e4SLinus Torvalds #define F_NEW_SCCB_CMD 0x40 2731da177e4SLinus Torvalds #define F_UPDATE_EEPROM 0x80 2741da177e4SLinus Torvalds 2751da177e4SLinus Torvalds #define ID_STRING_LENGTH 32 2761da177e4SLinus Torvalds #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */ 2771da177e4SLinus Torvalds 2781da177e4SLinus Torvalds #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */ 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds #define ASSIGN_ID 0x00 2811da177e4SLinus Torvalds #define SET_P_FLAG 0x01 2821da177e4SLinus Torvalds #define CFG_CMPLT 0x03 2831da177e4SLinus Torvalds #define DOM_MSTR 0x0F 2841da177e4SLinus Torvalds #define SYNC_PTRN 0x1F 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds #define ID_0_7 0x18 2871da177e4SLinus Torvalds #define ID_8_F 0x11 2881da177e4SLinus Torvalds #define MISC_CODE 0x14 2891da177e4SLinus Torvalds #define CLR_P_FLAG 0x18 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds #define INIT_SELTD 0x01 2921da177e4SLinus Torvalds #define LEVEL2_TAR 0x02 2931da177e4SLinus Torvalds 2945c04a7b8SAlexey Dobriyan enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11, 2955c04a7b8SAlexey Dobriyan ID12, 2961da177e4SLinus Torvalds ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY, 2975c04a7b8SAlexey Dobriyan CLR_PRIORITY, NO_ID_AVAIL 2985c04a7b8SAlexey Dobriyan }; 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds typedef struct SCCBscam_info { 3011da177e4SLinus Torvalds 302db038cf8SAlexey Dobriyan unsigned char id_string[ID_STRING_LENGTH]; 3031da177e4SLinus Torvalds enum scam_id_st state; 3041da177e4SLinus Torvalds 30585ae97d8SAlexey Dobriyan } SCCBSCAM_INFO; 3061da177e4SLinus Torvalds 3071da177e4SLinus Torvalds #define SCSI_REQUEST_SENSE 0x03 3081da177e4SLinus Torvalds #define SCSI_READ 0x08 3091da177e4SLinus Torvalds #define SCSI_WRITE 0x0A 3101da177e4SLinus Torvalds #define SCSI_START_STOP_UNIT 0x1B 3111da177e4SLinus Torvalds #define SCSI_READ_EXTENDED 0x28 3121da177e4SLinus Torvalds #define SCSI_WRITE_EXTENDED 0x2A 3131da177e4SLinus Torvalds #define SCSI_WRITE_AND_VERIFY 0x2E 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds #define SSGOOD 0x00 3161da177e4SLinus Torvalds #define SSCHECK 0x02 3171da177e4SLinus Torvalds #define SSQ_FULL 0x28 3181da177e4SLinus Torvalds 3191da177e4SLinus Torvalds #define SMCMD_COMP 0x00 3201da177e4SLinus Torvalds #define SMEXT 0x01 3211da177e4SLinus Torvalds #define SMSAVE_DATA_PTR 0x02 3221da177e4SLinus Torvalds #define SMREST_DATA_PTR 0x03 3231da177e4SLinus Torvalds #define SMDISC 0x04 3241da177e4SLinus Torvalds #define SMABORT 0x06 3251da177e4SLinus Torvalds #define SMREJECT 0x07 3261da177e4SLinus Torvalds #define SMNO_OP 0x08 3271da177e4SLinus Torvalds #define SMPARITY 0x09 3281da177e4SLinus Torvalds #define SMDEV_RESET 0x0C 3291da177e4SLinus Torvalds #define SMABORT_TAG 0x0D 3301da177e4SLinus Torvalds #define SMINIT_RECOVERY 0x0F 3311da177e4SLinus Torvalds #define SMREL_RECOVERY 0x10 3321da177e4SLinus Torvalds 3331da177e4SLinus Torvalds #define SMIDENT 0x80 3341da177e4SLinus Torvalds #define DISC_PRIV 0x40 3351da177e4SLinus Torvalds 3361da177e4SLinus Torvalds #define SMSYNC 0x01 3371da177e4SLinus Torvalds #define SMWDTR 0x03 3381da177e4SLinus Torvalds #define SM8BIT 0x00 3391da177e4SLinus Torvalds #define SM16BIT 0x01 3401da177e4SLinus Torvalds #define SMIGNORWR 0x23 /* Ignore Wide Residue */ 3411da177e4SLinus Torvalds 3421da177e4SLinus Torvalds #define SIX_BYTE_CMD 0x06 3431da177e4SLinus Torvalds #define TWELVE_BYTE_CMD 0x0C 3441da177e4SLinus Torvalds 3451da177e4SLinus Torvalds #define ASYNC 0x00 3461da177e4SLinus Torvalds #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */ 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds #define EEPROM_WD_CNT 256 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds #define EEPROM_CHECK_SUM 0 3511da177e4SLinus Torvalds #define FW_SIGNATURE 2 3521da177e4SLinus Torvalds #define MODEL_NUMB_0 4 3531da177e4SLinus Torvalds #define MODEL_NUMB_2 6 3541da177e4SLinus Torvalds #define MODEL_NUMB_4 8 3551da177e4SLinus Torvalds #define SYSTEM_CONFIG 16 3561da177e4SLinus Torvalds #define SCSI_CONFIG 17 3571da177e4SLinus Torvalds #define BIOS_CONFIG 18 3581da177e4SLinus Torvalds #define SCAM_CONFIG 20 3591da177e4SLinus Torvalds #define ADAPTER_SCSI_ID 24 3601da177e4SLinus Torvalds 3611da177e4SLinus Torvalds #define IGNORE_B_SCAN 32 3621da177e4SLinus Torvalds #define SEND_START_ENA 34 3631da177e4SLinus Torvalds #define DEVICE_ENABLE 36 3641da177e4SLinus Torvalds 3651da177e4SLinus Torvalds #define SYNC_RATE_TBL 38 3661da177e4SLinus Torvalds #define SYNC_RATE_TBL01 38 3671da177e4SLinus Torvalds #define SYNC_RATE_TBL23 40 3681da177e4SLinus Torvalds #define SYNC_RATE_TBL45 42 3691da177e4SLinus Torvalds #define SYNC_RATE_TBL67 44 3701da177e4SLinus Torvalds #define SYNC_RATE_TBL89 46 3711da177e4SLinus Torvalds #define SYNC_RATE_TBLab 48 3721da177e4SLinus Torvalds #define SYNC_RATE_TBLcd 50 3731da177e4SLinus Torvalds #define SYNC_RATE_TBLef 52 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds #define EE_SCAMBASE 256 3761da177e4SLinus Torvalds 3771da177e4SLinus Torvalds #define SCAM_ENABLED BIT(2) 3781da177e4SLinus Torvalds #define SCAM_LEVEL2 BIT(3) 3791da177e4SLinus Torvalds 3801cafc30fSJiri Slaby #define RENEGO_ENA BIT(10) 3811cafc30fSJiri Slaby #define CONNIO_ENA BIT(11) 3821cafc30fSJiri Slaby #define GREEN_PC_ENA BIT(12) 3831da177e4SLinus Torvalds 3841da177e4SLinus Torvalds #define AUTO_RATE_00 00 3851da177e4SLinus Torvalds #define AUTO_RATE_05 01 3861da177e4SLinus Torvalds #define AUTO_RATE_10 02 3871da177e4SLinus Torvalds #define AUTO_RATE_20 03 3881da177e4SLinus Torvalds 3891da177e4SLinus Torvalds #define WIDE_NEGO_BIT BIT(7) 3901da177e4SLinus Torvalds #define DISC_ENABLE_BIT BIT(6) 3911da177e4SLinus Torvalds 3921da177e4SLinus Torvalds #define hp_vendor_id_0 0x00 /* LSB */ 3931da177e4SLinus Torvalds #define ORION_VEND_0 0x4B 3941da177e4SLinus Torvalds 3951da177e4SLinus Torvalds #define hp_vendor_id_1 0x01 /* MSB */ 3961da177e4SLinus Torvalds #define ORION_VEND_1 0x10 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds #define hp_device_id_0 0x02 /* LSB */ 3991da177e4SLinus Torvalds #define ORION_DEV_0 0x30 4001da177e4SLinus Torvalds 4011da177e4SLinus Torvalds #define hp_device_id_1 0x03 /* MSB */ 4021da177e4SLinus Torvalds #define ORION_DEV_1 0x81 4031da177e4SLinus Torvalds 4041da177e4SLinus Torvalds /* Sub Vendor ID and Sub Device ID only available in 4051da177e4SLinus Torvalds Harpoon Version 2 and higher */ 4061da177e4SLinus Torvalds 4071da177e4SLinus Torvalds #define hp_sub_device_id_0 0x06 /* LSB */ 4081da177e4SLinus Torvalds 4091da177e4SLinus Torvalds #define hp_semaphore 0x0C 4101da177e4SLinus Torvalds #define SCCB_MGR_ACTIVE BIT(0) 4111da177e4SLinus Torvalds #define TICKLE_ME BIT(1) 4121da177e4SLinus Torvalds #define SCCB_MGR_PRESENT BIT(3) 4131da177e4SLinus Torvalds #define BIOS_IN_USE BIT(4) 4141da177e4SLinus Torvalds 4151da177e4SLinus Torvalds #define hp_sys_ctrl 0x0F 4161da177e4SLinus Torvalds 4171da177e4SLinus Torvalds #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */ 4181da177e4SLinus Torvalds #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */ 4191da177e4SLinus Torvalds #define HALT_MACH BIT(3) /*Halt State Machine */ 4201da177e4SLinus Torvalds #define HARD_ABORT BIT(4) /*Hard Abort */ 4211da177e4SLinus Torvalds 4221da177e4SLinus Torvalds #define hp_host_blk_cnt 0x13 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */ 4251da177e4SLinus Torvalds 4261da177e4SLinus Torvalds #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */ 4271da177e4SLinus Torvalds 4281da177e4SLinus Torvalds #define hp_int_mask 0x17 4291da177e4SLinus Torvalds 4301da177e4SLinus Torvalds #define INT_CMD_COMPL BIT(0) /* DMA command complete */ 4311da177e4SLinus Torvalds #define INT_EXT_STATUS BIT(1) /* Extended Status Set */ 4321da177e4SLinus Torvalds 4331da177e4SLinus Torvalds #define hp_xfer_cnt_lo 0x18 4341da177e4SLinus Torvalds #define hp_xfer_cnt_hi 0x1A 4351da177e4SLinus Torvalds #define hp_xfer_cmd 0x1B 4361da177e4SLinus Torvalds 4371da177e4SLinus Torvalds #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */ 4381da177e4SLinus Torvalds #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */ 4391da177e4SLinus Torvalds 4401da177e4SLinus Torvalds #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */ 4411da177e4SLinus Torvalds 4421da177e4SLinus Torvalds #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */ 4431da177e4SLinus Torvalds 4441da177e4SLinus Torvalds #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */ 4451da177e4SLinus Torvalds 4461da177e4SLinus Torvalds #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT)) 4471da177e4SLinus Torvalds #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT)) 4481da177e4SLinus Torvalds 4491da177e4SLinus Torvalds #define hp_host_addr_lo 0x1C 4501da177e4SLinus Torvalds #define hp_host_addr_hmi 0x1E 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvalds #define hp_ee_ctrl 0x22 4531da177e4SLinus Torvalds 4541da177e4SLinus Torvalds #define EXT_ARB_ACK BIT(7) 4551da177e4SLinus Torvalds #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */ 4561da177e4SLinus Torvalds #define SEE_MS BIT(5) 4571da177e4SLinus Torvalds #define SEE_CS BIT(3) 4581da177e4SLinus Torvalds #define SEE_CLK BIT(2) 4591da177e4SLinus Torvalds #define SEE_DO BIT(1) 4601da177e4SLinus Torvalds #define SEE_DI BIT(0) 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds #define EE_READ 0x06 4631da177e4SLinus Torvalds #define EE_WRITE 0x05 4641da177e4SLinus Torvalds #define EWEN 0x04 4651da177e4SLinus Torvalds #define EWEN_ADDR 0x03C0 4661da177e4SLinus Torvalds #define EWDS 0x04 4671da177e4SLinus Torvalds #define EWDS_ADDR 0x0000 4681da177e4SLinus Torvalds 4691da177e4SLinus Torvalds #define hp_bm_ctrl 0x26 4701da177e4SLinus Torvalds 4711da177e4SLinus Torvalds #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */ 4721da177e4SLinus Torvalds #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */ 4731da177e4SLinus Torvalds #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */ 4741da177e4SLinus Torvalds #define FAST_SINGLE BIT(6) /*?? */ 4751da177e4SLinus Torvalds 4761da177e4SLinus Torvalds #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L) 4771da177e4SLinus Torvalds 4781da177e4SLinus Torvalds #define hp_sg_addr 0x28 4791da177e4SLinus Torvalds #define hp_page_ctrl 0x29 4801da177e4SLinus Torvalds 4811da177e4SLinus Torvalds #define SCATTER_EN BIT(0) 4821da177e4SLinus Torvalds #define SGRAM_ARAM BIT(1) 4831da177e4SLinus Torvalds #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */ 4841da177e4SLinus Torvalds #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */ 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds #define hp_pci_stat_cfg 0x2D 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds #define REC_MASTER_ABORT BIT(5) /*received Master abort */ 4891da177e4SLinus Torvalds 4901da177e4SLinus Torvalds #define hp_rev_num 0x33 4911da177e4SLinus Torvalds 4921da177e4SLinus Torvalds #define hp_stack_data 0x34 4931da177e4SLinus Torvalds #define hp_stack_addr 0x35 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds #define hp_ext_status 0x36 4961da177e4SLinus Torvalds 4971da177e4SLinus Torvalds #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */ 4981da177e4SLinus Torvalds #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */ 4991da177e4SLinus Torvalds #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */ 5001da177e4SLinus Torvalds #define CMD_ABORTED BIT(4) /*Command aborted */ 5011da177e4SLinus Torvalds #define BM_PARITY_ERR BIT(5) /*parity error on data received */ 5021da177e4SLinus Torvalds #define PIO_OVERRUN BIT(6) /*Slave data overrun */ 5031da177e4SLinus Torvalds #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */ 5041da177e4SLinus Torvalds #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \ 5051da177e4SLinus Torvalds BM_PARITY_ERR | PIO_OVERRUN) 5061da177e4SLinus Torvalds 5071da177e4SLinus Torvalds #define hp_int_status 0x37 5081da177e4SLinus Torvalds 5091da177e4SLinus Torvalds #define EXT_STATUS_ON BIT(1) /*Extended status is valid */ 5101da177e4SLinus Torvalds #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */ 5111da177e4SLinus Torvalds #define INT_ASSERTED BIT(5) /* */ 5121da177e4SLinus Torvalds 5131da177e4SLinus Torvalds #define hp_fifo_cnt 0x38 5141da177e4SLinus Torvalds 5151da177e4SLinus Torvalds #define hp_intena 0x40 5161da177e4SLinus Torvalds 5171cafc30fSJiri Slaby #define RESET BIT(7) 5181cafc30fSJiri Slaby #define PROG_HLT BIT(6) 5191cafc30fSJiri Slaby #define PARITY BIT(5) 5201cafc30fSJiri Slaby #define FIFO BIT(4) 5211cafc30fSJiri Slaby #define SEL BIT(3) 5221cafc30fSJiri Slaby #define SCAM_SEL BIT(2) 5231cafc30fSJiri Slaby #define RSEL BIT(1) 5241cafc30fSJiri Slaby #define TIMEOUT BIT(0) 5251cafc30fSJiri Slaby #define BUS_FREE BIT(15) 5261cafc30fSJiri Slaby #define XFER_CNT_0 BIT(14) 5271cafc30fSJiri Slaby #define PHASE BIT(13) 5281cafc30fSJiri Slaby #define IUNKWN BIT(12) 5291cafc30fSJiri Slaby #define ICMD_COMP BIT(11) 5301cafc30fSJiri Slaby #define ITICKLE BIT(10) 5311cafc30fSJiri Slaby #define IDO_STRT BIT(9) 5321cafc30fSJiri Slaby #define ITAR_DISC BIT(8) 5331cafc30fSJiri Slaby #define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8)) 5341da177e4SLinus Torvalds #define CLR_ALL_INT 0xFFFF 5351da177e4SLinus Torvalds #define CLR_ALL_INT_1 0xFF00 5361da177e4SLinus Torvalds 5371da177e4SLinus Torvalds #define hp_intstat 0x42 5381da177e4SLinus Torvalds 5391da177e4SLinus Torvalds #define hp_scsisig 0x44 5401da177e4SLinus Torvalds 5411da177e4SLinus Torvalds #define SCSI_SEL BIT(7) 5421da177e4SLinus Torvalds #define SCSI_BSY BIT(6) 5431da177e4SLinus Torvalds #define SCSI_REQ BIT(5) 5441da177e4SLinus Torvalds #define SCSI_ACK BIT(4) 5451da177e4SLinus Torvalds #define SCSI_ATN BIT(3) 5461da177e4SLinus Torvalds #define SCSI_CD BIT(2) 5471da177e4SLinus Torvalds #define SCSI_MSG BIT(1) 5481da177e4SLinus Torvalds #define SCSI_IOBIT BIT(0) 5491da177e4SLinus Torvalds 5501da177e4SLinus Torvalds #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0)) 5511da177e4SLinus Torvalds #define S_MSGO_PH (BIT(2)+BIT(1) ) 5521da177e4SLinus Torvalds #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0)) 5531da177e4SLinus Torvalds #define S_DATAI_PH ( BIT(0)) 5541da177e4SLinus Torvalds #define S_DATAO_PH 0x00 5551da177e4SLinus Torvalds #define S_ILL_PH ( BIT(1) ) 5561da177e4SLinus Torvalds 5571da177e4SLinus Torvalds #define hp_scsictrl_0 0x45 5581da177e4SLinus Torvalds 5591da177e4SLinus Torvalds #define SEL_TAR BIT(6) 5601da177e4SLinus Torvalds #define ENA_ATN BIT(4) 5611da177e4SLinus Torvalds #define ENA_RESEL BIT(2) 5621da177e4SLinus Torvalds #define SCSI_RST BIT(1) 5631da177e4SLinus Torvalds #define ENA_SCAM_SEL BIT(0) 5641da177e4SLinus Torvalds 5651da177e4SLinus Torvalds #define hp_portctrl_0 0x46 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds #define SCSI_PORT BIT(7) 5681da177e4SLinus Torvalds #define SCSI_INBIT BIT(6) 5691da177e4SLinus Torvalds #define DMA_PORT BIT(5) 5701da177e4SLinus Torvalds #define DMA_RD BIT(4) 5711da177e4SLinus Torvalds #define HOST_PORT BIT(3) 5721da177e4SLinus Torvalds #define HOST_WRT BIT(2) 5731da177e4SLinus Torvalds #define SCSI_BUS_EN BIT(1) 5741da177e4SLinus Torvalds #define START_TO BIT(0) 5751da177e4SLinus Torvalds 5761da177e4SLinus Torvalds #define hp_scsireset 0x47 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds #define SCSI_INI BIT(6) 5791da177e4SLinus Torvalds #define SCAM_EN BIT(5) 5801da177e4SLinus Torvalds #define DMA_RESET BIT(3) 5811da177e4SLinus Torvalds #define HPSCSI_RESET BIT(2) 5821da177e4SLinus Torvalds #define PROG_RESET BIT(1) 5831da177e4SLinus Torvalds #define FIFO_CLR BIT(0) 5841da177e4SLinus Torvalds 5851da177e4SLinus Torvalds #define hp_xfercnt_0 0x48 5861da177e4SLinus Torvalds #define hp_xfercnt_2 0x4A 5871da177e4SLinus Torvalds 5881da177e4SLinus Torvalds #define hp_fifodata_0 0x4C 5891da177e4SLinus Torvalds #define hp_addstat 0x4E 5901da177e4SLinus Torvalds 5911da177e4SLinus Torvalds #define SCAM_TIMER BIT(7) 5921da177e4SLinus Torvalds #define SCSI_MODE8 BIT(3) 5931da177e4SLinus Torvalds #define SCSI_PAR_ERR BIT(0) 5941da177e4SLinus Torvalds 5951da177e4SLinus Torvalds #define hp_prgmcnt_0 0x4F 5961da177e4SLinus Torvalds 5971da177e4SLinus Torvalds #define hp_selfid_0 0x50 5981da177e4SLinus Torvalds #define hp_selfid_1 0x51 5991da177e4SLinus Torvalds #define hp_arb_id 0x52 6001da177e4SLinus Torvalds 6011da177e4SLinus Torvalds #define hp_select_id 0x53 6021da177e4SLinus Torvalds 6031da177e4SLinus Torvalds #define hp_synctarg_base 0x54 6041da177e4SLinus Torvalds #define hp_synctarg_12 0x54 6051da177e4SLinus Torvalds #define hp_synctarg_13 0x55 6061da177e4SLinus Torvalds #define hp_synctarg_14 0x56 6071da177e4SLinus Torvalds #define hp_synctarg_15 0x57 6081da177e4SLinus Torvalds 6091da177e4SLinus Torvalds #define hp_synctarg_8 0x58 6101da177e4SLinus Torvalds #define hp_synctarg_9 0x59 6111da177e4SLinus Torvalds #define hp_synctarg_10 0x5A 6121da177e4SLinus Torvalds #define hp_synctarg_11 0x5B 6131da177e4SLinus Torvalds 6141da177e4SLinus Torvalds #define hp_synctarg_4 0x5C 6151da177e4SLinus Torvalds #define hp_synctarg_5 0x5D 6161da177e4SLinus Torvalds #define hp_synctarg_6 0x5E 6171da177e4SLinus Torvalds #define hp_synctarg_7 0x5F 6181da177e4SLinus Torvalds 6191da177e4SLinus Torvalds #define hp_synctarg_0 0x60 6201da177e4SLinus Torvalds #define hp_synctarg_1 0x61 6211da177e4SLinus Torvalds #define hp_synctarg_2 0x62 6221da177e4SLinus Torvalds #define hp_synctarg_3 0x63 6231da177e4SLinus Torvalds 6241da177e4SLinus Torvalds #define NARROW_SCSI BIT(4) 6251da177e4SLinus Torvalds #define DEFAULT_OFFSET 0x0F 6261da177e4SLinus Torvalds 6271da177e4SLinus Torvalds #define hp_autostart_0 0x64 6281da177e4SLinus Torvalds #define hp_autostart_1 0x65 6291da177e4SLinus Torvalds #define hp_autostart_3 0x67 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds #define AUTO_IMMED BIT(5) 6321da177e4SLinus Torvalds #define SELECT BIT(6) 6331da177e4SLinus Torvalds #define END_DATA (BIT(7)+BIT(6)) 6341da177e4SLinus Torvalds 6351da177e4SLinus Torvalds #define hp_gp_reg_0 0x68 6361da177e4SLinus Torvalds #define hp_gp_reg_1 0x69 6371da177e4SLinus Torvalds #define hp_gp_reg_3 0x6B 6381da177e4SLinus Torvalds 6391da177e4SLinus Torvalds #define hp_seltimeout 0x6C 6401da177e4SLinus Torvalds 6411da177e4SLinus Torvalds #define TO_4ms 0x67 /* 3.9959ms */ 6421da177e4SLinus Torvalds 6431da177e4SLinus Torvalds #define TO_5ms 0x03 /* 4.9152ms */ 6441da177e4SLinus Torvalds #define TO_10ms 0x07 /* 11.xxxms */ 6451da177e4SLinus Torvalds #define TO_250ms 0x99 /* 250.68ms */ 6461da177e4SLinus Torvalds #define TO_290ms 0xB1 /* 289.99ms */ 6471da177e4SLinus Torvalds 6481da177e4SLinus Torvalds #define hp_clkctrl_0 0x6D 6491da177e4SLinus Torvalds 6501da177e4SLinus Torvalds #define PWR_DWN BIT(6) 6511da177e4SLinus Torvalds #define ACTdeassert BIT(4) 6521da177e4SLinus Torvalds #define CLK_40MHZ (BIT(1) + BIT(0)) 6531da177e4SLinus Torvalds 6541da177e4SLinus Torvalds #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ) 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds #define hp_fiforead 0x6E 6571da177e4SLinus Torvalds #define hp_fifowrite 0x6F 6581da177e4SLinus Torvalds 6591da177e4SLinus Torvalds #define hp_offsetctr 0x70 6601da177e4SLinus Torvalds #define hp_xferstat 0x71 6611da177e4SLinus Torvalds 6621da177e4SLinus Torvalds #define FIFO_EMPTY BIT(6) 6631da177e4SLinus Torvalds 6641da177e4SLinus Torvalds #define hp_portctrl_1 0x72 6651da177e4SLinus Torvalds 6661da177e4SLinus Torvalds #define CHK_SCSI_P BIT(3) 6671da177e4SLinus Torvalds #define HOST_MODE8 BIT(0) 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds #define hp_xfer_pad 0x73 6701da177e4SLinus Torvalds 6711da177e4SLinus Torvalds #define ID_UNLOCK BIT(3) 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds #define hp_scsidata_0 0x74 6741da177e4SLinus Torvalds #define hp_scsidata_1 0x75 6751da177e4SLinus Torvalds 6761da177e4SLinus Torvalds #define hp_aramBase 0x80 6771da177e4SLinus Torvalds #define BIOS_DATA_OFFSET 0x60 6781da177e4SLinus Torvalds #define BIOS_RELATIVE_CARD 0x64 6791da177e4SLinus Torvalds 6801cafc30fSJiri Slaby #define AR3 (BIT(9) + BIT(8)) 6811cafc30fSJiri Slaby #define SDATA BIT(10) 6821da177e4SLinus Torvalds 6831cafc30fSJiri Slaby #define CRD_OP BIT(11) /* Cmp Reg. w/ Data */ 6841da177e4SLinus Torvalds 6851cafc30fSJiri Slaby #define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */ 6861da177e4SLinus Torvalds 6871cafc30fSJiri Slaby #define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */ 6881da177e4SLinus Torvalds 6891cafc30fSJiri Slaby #define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */ 6901da177e4SLinus Torvalds 6911da177e4SLinus Torvalds #define ADATA_OUT 0x00 6921cafc30fSJiri Slaby #define ADATA_IN BIT(8) 6931cafc30fSJiri Slaby #define ACOMMAND BIT(10) 6941cafc30fSJiri Slaby #define ASTATUS (BIT(10)+BIT(8)) 6951cafc30fSJiri Slaby #define AMSG_OUT (BIT(10)+BIT(9)) 6961cafc30fSJiri Slaby #define AMSG_IN (BIT(10)+BIT(9)+BIT(8)) 6971da177e4SLinus Torvalds 6981cafc30fSJiri Slaby #define BRH_OP BIT(13) /* Branch */ 6991da177e4SLinus Torvalds 7001da177e4SLinus Torvalds #define ALWAYS 0x00 7011cafc30fSJiri Slaby #define EQUAL BIT(8) 7021cafc30fSJiri Slaby #define NOT_EQ BIT(9) 7031da177e4SLinus Torvalds 7041cafc30fSJiri Slaby #define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */ 7051da177e4SLinus Torvalds 7061cafc30fSJiri Slaby #define FIFO_0 BIT(10) 7071da177e4SLinus Torvalds 7081cafc30fSJiri Slaby #define MPM_OP BIT(15) /* Match phase and move data */ 7091da177e4SLinus Torvalds 7101cafc30fSJiri Slaby #define MRR_OP BIT(14) /* Move DReg. to Reg. */ 7111da177e4SLinus Torvalds 7121da177e4SLinus Torvalds #define S_IDREG (BIT(2)+BIT(1)+BIT(0)) 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds #define D_AR0 0x00 7151da177e4SLinus Torvalds #define D_AR1 BIT(0) 7161da177e4SLinus Torvalds #define D_BUCKET (BIT(2) + BIT(1) + BIT(0)) 7171da177e4SLinus Torvalds 7181cafc30fSJiri Slaby #define RAT_OP (BIT(14)+BIT(13)+BIT(11)) 7191da177e4SLinus Torvalds 7201cafc30fSJiri Slaby #define SSI_OP (BIT(15)+BIT(11)) 7211da177e4SLinus Torvalds 7221da177e4SLinus Torvalds #define SSI_ITAR_DISC (ITAR_DISC >> 8) 7231da177e4SLinus Torvalds #define SSI_IDO_STRT (IDO_STRT >> 8) 7241da177e4SLinus Torvalds 7251da177e4SLinus Torvalds #define SSI_ICMD_COMP (ICMD_COMP >> 8) 7261da177e4SLinus Torvalds #define SSI_ITICKLE (ITICKLE >> 8) 7271da177e4SLinus Torvalds 7281da177e4SLinus Torvalds #define SSI_IUNKWN (IUNKWN >> 8) 7291da177e4SLinus Torvalds #define SSI_INO_CC (IUNKWN >> 8) 7301da177e4SLinus Torvalds #define SSI_IRFAIL (IUNKWN >> 8) 7311da177e4SLinus Torvalds 7321da177e4SLinus Torvalds #define NP 0x10 /*Next Phase */ 7331da177e4SLinus Torvalds #define NTCMD 0x02 /*Non- Tagged Command start */ 7341da177e4SLinus Torvalds #define CMDPZ 0x04 /*Command phase */ 7351da177e4SLinus Torvalds #define DINT 0x12 /*Data Out/In interrupt */ 7361da177e4SLinus Torvalds #define DI 0x13 /*Data Out */ 7371da177e4SLinus Torvalds #define DC 0x19 /*Disconnect Message */ 7381da177e4SLinus Torvalds #define ST 0x1D /*Status Phase */ 7391da177e4SLinus Torvalds #define UNKNWN 0x24 /*Unknown bus action */ 7401da177e4SLinus Torvalds #define CC 0x25 /*Command Completion failure */ 7411da177e4SLinus Torvalds #define TICK 0x26 /*New target reselected us. */ 7421da177e4SLinus Torvalds #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */ 7431da177e4SLinus Torvalds 7441da177e4SLinus Torvalds #define ID_MSG_STRT hp_aramBase + 0x00 7451da177e4SLinus Torvalds #define NON_TAG_ID_MSG hp_aramBase + 0x06 7461da177e4SLinus Torvalds #define CMD_STRT hp_aramBase + 0x08 7471da177e4SLinus Torvalds #define SYNC_MSGS hp_aramBase + 0x08 7481da177e4SLinus Torvalds 7491da177e4SLinus Torvalds #define TAG_STRT 0x00 7501da177e4SLinus Torvalds #define DISCONNECT_START 0x10/2 7511da177e4SLinus Torvalds #define END_DATA_START 0x14/2 7521da177e4SLinus Torvalds #define CMD_ONLY_STRT CMDPZ/2 7531da177e4SLinus Torvalds #define SELCHK_STRT SELCHK/2 7541da177e4SLinus Torvalds 7551da177e4SLinus Torvalds #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;} 7561da177e4SLinus Torvalds /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \ 7571da177e4SLinus Torvalds xfercnt <<= 16,\ 758c823feebSAlexey Dobriyan xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0))) 7591da177e4SLinus Torvalds */ 760c823feebSAlexey Dobriyan #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\ 7611da177e4SLinus Torvalds addr >>= 16,\ 762c823feebSAlexey Dobriyan WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\ 7631da177e4SLinus Torvalds WR_HARP32(port,hp_xfercnt_0,count),\ 764c823feebSAlexey Dobriyan WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\ 7651da177e4SLinus Torvalds count >>= 16,\ 7661da177e4SLinus Torvalds WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF))) 7671da177e4SLinus Torvalds 7681da177e4SLinus Torvalds #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ 7691da177e4SLinus Torvalds WR_HARPOON(port+hp_scsisig, S_ILL_PH);} 7701da177e4SLinus Torvalds 7711da177e4SLinus Torvalds #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ 7721da177e4SLinus Torvalds WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));} 7731da177e4SLinus Torvalds 7741da177e4SLinus Torvalds #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\ 7751da177e4SLinus Torvalds WR_HARPOON(port+hp_scsireset, 0x00)) 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \ 7781da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM))) 7791da177e4SLinus Torvalds 7801da177e4SLinus Torvalds #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \ 7811da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM))) 7821da177e4SLinus Torvalds 7831da177e4SLinus Torvalds #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \ 7841da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE))) 7851da177e4SLinus Torvalds 7861da177e4SLinus Torvalds #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \ 7871da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE))) 7881da177e4SLinus Torvalds 789391e2f25SKhalid Aziz static unsigned char FPT_sisyncn(u32 port, unsigned char p_card, 7905c04a7b8SAlexey Dobriyan unsigned char syncFlag); 791391e2f25SKhalid Aziz static void FPT_ssel(u32 port, unsigned char p_card); 792391e2f25SKhalid Aziz static void FPT_sres(u32 port, unsigned char p_card, 7935c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard); 794391e2f25SKhalid Aziz static void FPT_shandem(u32 port, unsigned char p_card, 7955c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB); 796391e2f25SKhalid Aziz static void FPT_stsyncn(u32 port, unsigned char p_card); 797391e2f25SKhalid Aziz static void FPT_sisyncr(u32 port, unsigned char sync_pulse, 7985c04a7b8SAlexey Dobriyan unsigned char offset); 799391e2f25SKhalid Aziz static void FPT_sssyncv(u32 p_port, unsigned char p_id, 8005c04a7b8SAlexey Dobriyan unsigned char p_sync_value, 801f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info); 802391e2f25SKhalid Aziz static void FPT_sresb(u32 port, unsigned char p_card); 803391e2f25SKhalid Aziz static void FPT_sxfrp(u32 p_port, unsigned char p_card); 804391e2f25SKhalid Aziz static void FPT_schkdd(u32 port, unsigned char p_card); 805391e2f25SKhalid Aziz static unsigned char FPT_RdStack(u32 port, unsigned char index); 806391e2f25SKhalid Aziz static void FPT_WrStack(u32 portBase, unsigned char index, 8075c04a7b8SAlexey Dobriyan unsigned char data); 808391e2f25SKhalid Aziz static unsigned char FPT_ChkIfChipInitialized(u32 ioPort); 8091da177e4SLinus Torvalds 810391e2f25SKhalid Aziz static void FPT_SendMsg(u32 port, unsigned char message); 811db038cf8SAlexey Dobriyan static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg, 812db038cf8SAlexey Dobriyan unsigned char error_code); 8131da177e4SLinus Torvalds 81469eb2ea4SAlexey Dobriyan static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card); 81568d0c1aeSAlexey Dobriyan static void FPT_RNVRamData(struct nvram_info *pNvRamInfo); 8161da177e4SLinus Torvalds 817391e2f25SKhalid Aziz static unsigned char FPT_siwidn(u32 port, unsigned char p_card); 818391e2f25SKhalid Aziz static void FPT_stwidn(u32 port, unsigned char p_card); 819391e2f25SKhalid Aziz static void FPT_siwidr(u32 port, unsigned char width); 8201da177e4SLinus Torvalds 8215c04a7b8SAlexey Dobriyan static void FPT_queueSelectFail(struct sccb_card *pCurrCard, 822db038cf8SAlexey Dobriyan unsigned char p_card); 8235c04a7b8SAlexey Dobriyan static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card); 8245c04a7b8SAlexey Dobriyan static void FPT_queueCmdComplete(struct sccb_card *pCurrCard, 8255c04a7b8SAlexey Dobriyan struct sccb *p_SCCB, unsigned char p_card); 8265c04a7b8SAlexey Dobriyan static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, 8275c04a7b8SAlexey Dobriyan unsigned char p_card); 828db038cf8SAlexey Dobriyan static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code); 82969eb2ea4SAlexey Dobriyan static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card); 8305c04a7b8SAlexey Dobriyan static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB, 8315c04a7b8SAlexey Dobriyan unsigned char p_card); 83269eb2ea4SAlexey Dobriyan static void FPT_utilUpdateResidual(struct sccb *p_SCCB); 833c823feebSAlexey Dobriyan static unsigned short FPT_CalcCrc16(unsigned char buffer[]); 834db038cf8SAlexey Dobriyan static unsigned char FPT_CalcLrc(unsigned char buffer[]); 8351da177e4SLinus Torvalds 836391e2f25SKhalid Aziz static void FPT_Wait1Second(u32 p_port); 837391e2f25SKhalid Aziz static void FPT_Wait(u32 p_port, unsigned char p_delay); 838391e2f25SKhalid Aziz static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode); 839391e2f25SKhalid Aziz static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data, 8405c04a7b8SAlexey Dobriyan unsigned short ee_addr); 841391e2f25SKhalid Aziz static unsigned short FPT_utilEERead(u32 p_port, 8425c04a7b8SAlexey Dobriyan unsigned short ee_addr); 843391e2f25SKhalid Aziz static unsigned short FPT_utilEEReadOrg(u32 p_port, 8445c04a7b8SAlexey Dobriyan unsigned short ee_addr); 845391e2f25SKhalid Aziz static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd, 8465c04a7b8SAlexey Dobriyan unsigned short ee_addr); 8471da177e4SLinus Torvalds 848391e2f25SKhalid Aziz static void FPT_phaseDataOut(u32 port, unsigned char p_card); 849391e2f25SKhalid Aziz static void FPT_phaseDataIn(u32 port, unsigned char p_card); 850391e2f25SKhalid Aziz static void FPT_phaseCommand(u32 port, unsigned char p_card); 851391e2f25SKhalid Aziz static void FPT_phaseStatus(u32 port, unsigned char p_card); 852391e2f25SKhalid Aziz static void FPT_phaseMsgOut(u32 port, unsigned char p_card); 853391e2f25SKhalid Aziz static void FPT_phaseMsgIn(u32 port, unsigned char p_card); 854391e2f25SKhalid Aziz static void FPT_phaseIllegal(u32 port, unsigned char p_card); 8551da177e4SLinus Torvalds 856391e2f25SKhalid Aziz static void FPT_phaseDecode(u32 port, unsigned char p_card); 857391e2f25SKhalid Aziz static void FPT_phaseChkFifo(u32 port, unsigned char p_card); 858391e2f25SKhalid Aziz static void FPT_phaseBusFree(u32 p_port, unsigned char p_card); 8591da177e4SLinus Torvalds 860391e2f25SKhalid Aziz static void FPT_XbowInit(u32 port, unsigned char scamFlg); 861391e2f25SKhalid Aziz static void FPT_BusMasterInit(u32 p_port); 862391e2f25SKhalid Aziz static void FPT_DiagEEPROM(u32 p_port); 8631da177e4SLinus Torvalds 864391e2f25SKhalid Aziz static void FPT_dataXferProcessor(u32 port, 8655c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard); 866391e2f25SKhalid Aziz static void FPT_busMstrSGDataXferStart(u32 port, 8675c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB); 868391e2f25SKhalid Aziz static void FPT_busMstrDataXferStart(u32 port, 8695c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB); 870391e2f25SKhalid Aziz static void FPT_hostDataXferAbort(u32 port, unsigned char p_card, 8715c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB); 87269eb2ea4SAlexey Dobriyan static void FPT_hostDataXferRestart(struct sccb *currSCCB); 8731da177e4SLinus Torvalds 874391e2f25SKhalid Aziz static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, 8755c04a7b8SAlexey Dobriyan unsigned char p_card, 8765c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard, 8775c04a7b8SAlexey Dobriyan unsigned short p_int); 8781da177e4SLinus Torvalds 87947b5d69cSJames Bottomley static void FPT_SccbMgrTableInitAll(void); 8805c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard, 8815c04a7b8SAlexey Dobriyan unsigned char p_card); 8825c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitTarget(unsigned char p_card, 8835c04a7b8SAlexey Dobriyan unsigned char target); 8841da177e4SLinus Torvalds 8855c04a7b8SAlexey Dobriyan static void FPT_scini(unsigned char p_card, unsigned char p_our_id, 8865c04a7b8SAlexey Dobriyan unsigned char p_power_up); 8871da177e4SLinus Torvalds 888391e2f25SKhalid Aziz static int FPT_scarb(u32 p_port, unsigned char p_sel_type); 889391e2f25SKhalid Aziz static void FPT_scbusf(u32 p_port); 890391e2f25SKhalid Aziz static void FPT_scsel(u32 p_port); 891391e2f25SKhalid Aziz static void FPT_scasid(unsigned char p_card, u32 p_port); 892391e2f25SKhalid Aziz static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data); 893391e2f25SKhalid Aziz static unsigned char FPT_scsendi(u32 p_port, 8945c04a7b8SAlexey Dobriyan unsigned char p_id_string[]); 895391e2f25SKhalid Aziz static unsigned char FPT_sciso(u32 p_port, 8965c04a7b8SAlexey Dobriyan unsigned char p_id_string[]); 897391e2f25SKhalid Aziz static void FPT_scwirod(u32 p_port, unsigned char p_data_bit); 898391e2f25SKhalid Aziz static void FPT_scwiros(u32 p_port, unsigned char p_data_bit); 899db038cf8SAlexey Dobriyan static unsigned char FPT_scvalq(unsigned char p_quintet); 900391e2f25SKhalid Aziz static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id); 901391e2f25SKhalid Aziz static void FPT_scwtsel(u32 p_port); 902391e2f25SKhalid Aziz static void FPT_inisci(unsigned char p_card, u32 p_port, 9035c04a7b8SAlexey Dobriyan unsigned char p_our_id); 904391e2f25SKhalid Aziz static void FPT_scsavdi(unsigned char p_card, u32 p_port); 9055c04a7b8SAlexey Dobriyan static unsigned char FPT_scmachid(unsigned char p_card, 9065c04a7b8SAlexey Dobriyan unsigned char p_id_string[]); 9071da177e4SLinus Torvalds 908391e2f25SKhalid Aziz static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card); 909391e2f25SKhalid Aziz static void FPT_autoLoadDefaultMap(u32 p_port); 9101da177e4SLinus Torvalds 9115c04a7b8SAlexey Dobriyan static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = 9125c04a7b8SAlexey Dobriyan { {{0}} }; 91313e6851aSAlexey Dobriyan static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} }; 91447b5d69cSJames Bottomley static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} }; 91568d0c1aeSAlexey Dobriyan static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} }; 9161da177e4SLinus Torvalds 917db038cf8SAlexey Dobriyan static unsigned char FPT_mbCards = 0; 9185c04a7b8SAlexey Dobriyan static unsigned char FPT_scamHAString[] = 9195c04a7b8SAlexey Dobriyan { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', 9205c04a7b8SAlexey Dobriyan ' ', 'B', 'T', '-', '9', '3', '0', 9215c04a7b8SAlexey Dobriyan 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 9225c04a7b8SAlexey Dobriyan 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 9235c04a7b8SAlexey Dobriyan }; 9241da177e4SLinus Torvalds 925c823feebSAlexey Dobriyan static unsigned short FPT_default_intena = 0; 9261da177e4SLinus Torvalds 927391e2f25SKhalid Aziz static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = { 9285c04a7b8SAlexey Dobriyan 0}; 9291da177e4SLinus Torvalds 9301da177e4SLinus Torvalds /*--------------------------------------------------------------------- 9311da177e4SLinus Torvalds * 932d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_ProbeHostAdapter 9331da177e4SLinus Torvalds * 9341da177e4SLinus Torvalds * Description: Setup and/or Search for cards and return info to caller. 9351da177e4SLinus Torvalds * 9361da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 9371da177e4SLinus Torvalds 9387f101662SAlexey Dobriyan static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) 9391da177e4SLinus Torvalds { 940db038cf8SAlexey Dobriyan static unsigned char first_time = 1; 9411da177e4SLinus Torvalds 942db038cf8SAlexey Dobriyan unsigned char i, j, id, ScamFlg; 943c823feebSAlexey Dobriyan unsigned short temp, temp2, temp3, temp4, temp5, temp6; 944391e2f25SKhalid Aziz u32 ioport; 94568d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 9461da177e4SLinus Torvalds 9471da177e4SLinus Torvalds ioport = pCardInfo->si_baseaddr; 9481da177e4SLinus Torvalds 9491da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0) 9505c1b85e2SAlexey Dobriyan return (int)FAILURE; 9511da177e4SLinus Torvalds 9521da177e4SLinus Torvalds if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1)) 9535c1b85e2SAlexey Dobriyan return (int)FAILURE; 9541da177e4SLinus Torvalds 9551da177e4SLinus Torvalds if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0)) 9565c1b85e2SAlexey Dobriyan return (int)FAILURE; 9571da177e4SLinus Torvalds 9581da177e4SLinus Torvalds if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1)) 9595c1b85e2SAlexey Dobriyan return (int)FAILURE; 9601da177e4SLinus Torvalds 9611da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) { 9621da177e4SLinus Torvalds 9631da177e4SLinus Torvalds /* For new Harpoon then check for sub_device ID LSB 9641da177e4SLinus Torvalds the bits(0-3) must be all ZERO for compatible with 9651da177e4SLinus Torvalds current version of SCCBMgr, else skip this Harpoon 9661da177e4SLinus Torvalds device. */ 9671da177e4SLinus Torvalds 9681da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f) 9695c1b85e2SAlexey Dobriyan return (int)FAILURE; 9701da177e4SLinus Torvalds } 9711da177e4SLinus Torvalds 9725c04a7b8SAlexey Dobriyan if (first_time) { 97347b5d69cSJames Bottomley FPT_SccbMgrTableInitAll(); 9741da177e4SLinus Torvalds first_time = 0; 97547b5d69cSJames Bottomley FPT_mbCards = 0; 9761da177e4SLinus Torvalds } 9771da177e4SLinus Torvalds 97847b5d69cSJames Bottomley if (FPT_RdStack(ioport, 0) != 0x00) { 9795c04a7b8SAlexey Dobriyan if (FPT_ChkIfChipInitialized(ioport) == 0) { 9801da177e4SLinus Torvalds pCurrNvRam = NULL; 9811da177e4SLinus Torvalds WR_HARPOON(ioport + hp_semaphore, 0x00); 98247b5d69cSJames Bottomley FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ 98347b5d69cSJames Bottomley FPT_DiagEEPROM(ioport); 9845c04a7b8SAlexey Dobriyan } else { 98547b5d69cSJames Bottomley if (FPT_mbCards < MAX_MB_CARDS) { 98647b5d69cSJames Bottomley pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards]; 98747b5d69cSJames Bottomley FPT_mbCards++; 9881da177e4SLinus Torvalds pCurrNvRam->niBaseAddr = ioport; 98947b5d69cSJames Bottomley FPT_RNVRamData(pCurrNvRam); 9901da177e4SLinus Torvalds } else 9915c1b85e2SAlexey Dobriyan return (int)FAILURE; 9921da177e4SLinus Torvalds } 9931da177e4SLinus Torvalds } else 9941da177e4SLinus Torvalds pCurrNvRam = NULL; 9951da177e4SLinus Torvalds 9961da177e4SLinus Torvalds WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT); 9971da177e4SLinus Torvalds WR_HARPOON(ioport + hp_sys_ctrl, 0x00); 9981da177e4SLinus Torvalds 9991da177e4SLinus Torvalds if (pCurrNvRam) 10001da177e4SLinus Torvalds pCardInfo->si_id = pCurrNvRam->niAdapId; 10011da177e4SLinus Torvalds else 10025c04a7b8SAlexey Dobriyan pCardInfo->si_id = 10035c04a7b8SAlexey Dobriyan (unsigned 10045c04a7b8SAlexey Dobriyan char)(FPT_utilEERead(ioport, 10055c04a7b8SAlexey Dobriyan (ADAPTER_SCSI_ID / 10065c04a7b8SAlexey Dobriyan 2)) & (unsigned char)0x0FF); 10071da177e4SLinus Torvalds 10081da177e4SLinus Torvalds pCardInfo->si_lun = 0x00; 10091da177e4SLinus Torvalds pCardInfo->si_fw_revision = ORION_FW_REV; 10101da177e4SLinus Torvalds temp2 = 0x0000; 10111da177e4SLinus Torvalds temp3 = 0x0000; 10121da177e4SLinus Torvalds temp4 = 0x0000; 10131da177e4SLinus Torvalds temp5 = 0x0000; 10141da177e4SLinus Torvalds temp6 = 0x0000; 10151da177e4SLinus Torvalds 10161da177e4SLinus Torvalds for (id = 0; id < (16 / 2); id++) { 10171da177e4SLinus Torvalds 10181da177e4SLinus Torvalds if (pCurrNvRam) { 1019c823feebSAlexey Dobriyan temp = (unsigned short)pCurrNvRam->niSyncTbl[id]; 10201da177e4SLinus Torvalds temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + 10211da177e4SLinus Torvalds (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); 10221da177e4SLinus Torvalds } else 10235c04a7b8SAlexey Dobriyan temp = 10245c04a7b8SAlexey Dobriyan FPT_utilEERead(ioport, 10255c04a7b8SAlexey Dobriyan (unsigned short)((SYNC_RATE_TBL / 2) 10265c04a7b8SAlexey Dobriyan + id)); 10271da177e4SLinus Torvalds 10281da177e4SLinus Torvalds for (i = 0; i < 2; temp >>= 8, i++) { 10291da177e4SLinus Torvalds 10301da177e4SLinus Torvalds temp2 >>= 1; 10311da177e4SLinus Torvalds temp3 >>= 1; 10321da177e4SLinus Torvalds temp4 >>= 1; 10331da177e4SLinus Torvalds temp5 >>= 1; 10341da177e4SLinus Torvalds temp6 >>= 1; 10355c04a7b8SAlexey Dobriyan switch (temp & 0x3) { 10361da177e4SLinus Torvalds case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */ 1037*df561f66SGustavo A. R. Silva temp6 |= 0x8000; 1038*df561f66SGustavo A. R. Silva fallthrough; 10391da177e4SLinus Torvalds case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */ 1040*df561f66SGustavo A. R. Silva temp5 |= 0x8000; 1041*df561f66SGustavo A. R. Silva fallthrough; 10421da177e4SLinus Torvalds case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */ 1043*df561f66SGustavo A. R. Silva temp2 |= 0x8000; 1044*df561f66SGustavo A. R. Silva fallthrough; 10451da177e4SLinus Torvalds case AUTO_RATE_00: /* Asynchronous */ 10461da177e4SLinus Torvalds break; 10471da177e4SLinus Torvalds } 10481da177e4SLinus Torvalds 10491da177e4SLinus Torvalds if (temp & DISC_ENABLE_BIT) 10501da177e4SLinus Torvalds temp3 |= 0x8000; 10511da177e4SLinus Torvalds 10521da177e4SLinus Torvalds if (temp & WIDE_NEGO_BIT) 10531da177e4SLinus Torvalds temp4 |= 0x8000; 10541da177e4SLinus Torvalds 10551da177e4SLinus Torvalds } 10561da177e4SLinus Torvalds } 10571da177e4SLinus Torvalds 10581da177e4SLinus Torvalds pCardInfo->si_per_targ_init_sync = temp2; 10591da177e4SLinus Torvalds pCardInfo->si_per_targ_no_disc = temp3; 10601da177e4SLinus Torvalds pCardInfo->si_per_targ_wide_nego = temp4; 10611da177e4SLinus Torvalds pCardInfo->si_per_targ_fast_nego = temp5; 10621da177e4SLinus Torvalds pCardInfo->si_per_targ_ultra_nego = temp6; 10631da177e4SLinus Torvalds 10641da177e4SLinus Torvalds if (pCurrNvRam) 10651da177e4SLinus Torvalds i = pCurrNvRam->niSysConf; 10661da177e4SLinus Torvalds else 10675c04a7b8SAlexey Dobriyan i = (unsigned 10685c04a7b8SAlexey Dobriyan char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2))); 10691da177e4SLinus Torvalds 10701da177e4SLinus Torvalds if (pCurrNvRam) 10711da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf; 10721da177e4SLinus Torvalds else 10735c04a7b8SAlexey Dobriyan ScamFlg = 10745c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); 10751da177e4SLinus Torvalds 10761da177e4SLinus Torvalds pCardInfo->si_flags = 0x0000; 10771da177e4SLinus Torvalds 10781da177e4SLinus Torvalds if (i & 0x01) 10791da177e4SLinus Torvalds pCardInfo->si_flags |= SCSI_PARITY_ENA; 10801da177e4SLinus Torvalds 10811da177e4SLinus Torvalds if (!(i & 0x02)) 10821da177e4SLinus Torvalds pCardInfo->si_flags |= SOFT_RESET; 10831da177e4SLinus Torvalds 10841da177e4SLinus Torvalds if (i & 0x10) 10851da177e4SLinus Torvalds pCardInfo->si_flags |= EXTENDED_TRANSLATION; 10861da177e4SLinus Torvalds 10871da177e4SLinus Torvalds if (ScamFlg & SCAM_ENABLED) 10881da177e4SLinus Torvalds pCardInfo->si_flags |= FLAG_SCAM_ENABLED; 10891da177e4SLinus Torvalds 10901da177e4SLinus Torvalds if (ScamFlg & SCAM_LEVEL2) 10911da177e4SLinus Torvalds pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; 10921da177e4SLinus Torvalds 10931da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); 10941da177e4SLinus Torvalds if (i & 0x04) { 10951da177e4SLinus Torvalds j |= SCSI_TERM_ENA_L; 10961da177e4SLinus Torvalds } 10971da177e4SLinus Torvalds WR_HARPOON(ioport + hp_bm_ctrl, j); 10981da177e4SLinus Torvalds 10991da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H); 11001da177e4SLinus Torvalds if (i & 0x08) { 11011da177e4SLinus Torvalds j |= SCSI_TERM_ENA_H; 11021da177e4SLinus Torvalds } 11031da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, j); 11041da177e4SLinus Torvalds 11051da177e4SLinus Torvalds if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD)) 11061da177e4SLinus Torvalds 11071da177e4SLinus Torvalds pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; 11081da177e4SLinus Torvalds 11091da177e4SLinus Torvalds pCardInfo->si_card_family = HARPOON_FAMILY; 11101da177e4SLinus Torvalds pCardInfo->si_bustype = BUSTYPE_PCI; 11111da177e4SLinus Torvalds 11121da177e4SLinus Torvalds if (pCurrNvRam) { 11131da177e4SLinus Torvalds pCardInfo->si_card_model[0] = '9'; 11141da177e4SLinus Torvalds switch (pCurrNvRam->niModel & 0x0f) { 11151da177e4SLinus Torvalds case MODEL_LT: 11161da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '3'; 11171da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '0'; 11181da177e4SLinus Torvalds break; 11191da177e4SLinus Torvalds case MODEL_LW: 11201da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '5'; 11211da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '0'; 11221da177e4SLinus Torvalds break; 11231da177e4SLinus Torvalds case MODEL_DL: 11241da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '3'; 11251da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '2'; 11261da177e4SLinus Torvalds break; 11271da177e4SLinus Torvalds case MODEL_DW: 11281da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '5'; 11291da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '2'; 11301da177e4SLinus Torvalds break; 11311da177e4SLinus Torvalds } 11321da177e4SLinus Torvalds } else { 113347b5d69cSJames Bottomley temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2)); 1134db038cf8SAlexey Dobriyan pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8); 113547b5d69cSJames Bottomley temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2)); 11361da177e4SLinus Torvalds 1137db038cf8SAlexey Dobriyan pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF); 1138db038cf8SAlexey Dobriyan pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8); 11391da177e4SLinus Torvalds } 11401da177e4SLinus Torvalds 11415c04a7b8SAlexey Dobriyan if (pCardInfo->si_card_model[1] == '3') { 11421da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) 11431da177e4SLinus Torvalds pCardInfo->si_flags |= LOW_BYTE_TERM; 11445c04a7b8SAlexey Dobriyan } else if (pCardInfo->si_card_model[2] == '0') { 11451da177e4SLinus Torvalds temp = RD_HARPOON(ioport + hp_xfer_pad); 11461da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4))); 11471da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) 11481da177e4SLinus Torvalds pCardInfo->si_flags |= LOW_BYTE_TERM; 11491da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4))); 11501da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) 11511da177e4SLinus Torvalds pCardInfo->si_flags |= HIGH_BYTE_TERM; 11521da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, temp); 11535c04a7b8SAlexey Dobriyan } else { 11541da177e4SLinus Torvalds temp = RD_HARPOON(ioport + hp_ee_ctrl); 11551da177e4SLinus Torvalds temp2 = RD_HARPOON(ioport + hp_xfer_pad); 11561da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS)); 11571da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4))); 11581da177e4SLinus Torvalds temp3 = 0; 11595c04a7b8SAlexey Dobriyan for (i = 0; i < 8; i++) { 11601da177e4SLinus Torvalds temp3 <<= 1; 11611da177e4SLinus Torvalds if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))) 11621da177e4SLinus Torvalds temp3 |= 1; 11631da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4))); 11641da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4))); 11651da177e4SLinus Torvalds } 11661da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, temp); 11671da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, temp2); 11681da177e4SLinus Torvalds if (!(temp3 & BIT(7))) 11691da177e4SLinus Torvalds pCardInfo->si_flags |= LOW_BYTE_TERM; 11701da177e4SLinus Torvalds if (!(temp3 & BIT(6))) 11711da177e4SLinus Torvalds pCardInfo->si_flags |= HIGH_BYTE_TERM; 11721da177e4SLinus Torvalds } 11731da177e4SLinus Torvalds 11741da177e4SLinus Torvalds ARAM_ACCESS(ioport); 11751da177e4SLinus Torvalds 11761da177e4SLinus Torvalds for (i = 0; i < 4; i++) { 11771da177e4SLinus Torvalds 11781da177e4SLinus Torvalds pCardInfo->si_XlatInfo[i] = 11791da177e4SLinus Torvalds RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i); 11801da177e4SLinus Torvalds } 11811da177e4SLinus Torvalds 11821da177e4SLinus Torvalds /* return with -1 if no sort, else return with 11831da177e4SLinus Torvalds logical card number sorted by BIOS (zero-based) */ 11841da177e4SLinus Torvalds 11851da177e4SLinus Torvalds pCardInfo->si_relative_cardnum = 11865c04a7b8SAlexey Dobriyan (unsigned 11875c04a7b8SAlexey Dobriyan char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1); 11881da177e4SLinus Torvalds 11891da177e4SLinus Torvalds SGRAM_ACCESS(ioport); 11901da177e4SLinus Torvalds 119147b5d69cSJames Bottomley FPT_s_PhaseTbl[0] = FPT_phaseDataOut; 119247b5d69cSJames Bottomley FPT_s_PhaseTbl[1] = FPT_phaseDataIn; 119347b5d69cSJames Bottomley FPT_s_PhaseTbl[2] = FPT_phaseIllegal; 119447b5d69cSJames Bottomley FPT_s_PhaseTbl[3] = FPT_phaseIllegal; 119547b5d69cSJames Bottomley FPT_s_PhaseTbl[4] = FPT_phaseCommand; 119647b5d69cSJames Bottomley FPT_s_PhaseTbl[5] = FPT_phaseStatus; 119747b5d69cSJames Bottomley FPT_s_PhaseTbl[6] = FPT_phaseMsgOut; 119847b5d69cSJames Bottomley FPT_s_PhaseTbl[7] = FPT_phaseMsgIn; 11991da177e4SLinus Torvalds 12001da177e4SLinus Torvalds pCardInfo->si_present = 0x01; 12011da177e4SLinus Torvalds 12025c1b85e2SAlexey Dobriyan return 0; 12031da177e4SLinus Torvalds } 12041da177e4SLinus Torvalds 12051da177e4SLinus Torvalds /*--------------------------------------------------------------------- 12061da177e4SLinus Torvalds * 1207d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_HardwareResetHostAdapter 12081da177e4SLinus Torvalds * 12091da177e4SLinus Torvalds * Description: Setup adapter for normal operation (hard reset). 12101da177e4SLinus Torvalds * 12111da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 12121da177e4SLinus Torvalds 1213391e2f25SKhalid Aziz static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info 12145c04a7b8SAlexey Dobriyan *pCardInfo) 12151da177e4SLinus Torvalds { 121613e6851aSAlexey Dobriyan struct sccb_card *CurrCard = NULL; 121768d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 1218db038cf8SAlexey Dobriyan unsigned char i, j, thisCard, ScamFlg; 1219c823feebSAlexey Dobriyan unsigned short temp, sync_bit_map, id; 1220391e2f25SKhalid Aziz u32 ioport; 12211da177e4SLinus Torvalds 12221da177e4SLinus Torvalds ioport = pCardInfo->si_baseaddr; 12231da177e4SLinus Torvalds 12241da177e4SLinus Torvalds for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) { 12251da177e4SLinus Torvalds 1226391e2f25SKhalid Aziz if (thisCard == MAX_CARDS) 1227391e2f25SKhalid Aziz return (void *)FAILURE; 12281da177e4SLinus Torvalds 122947b5d69cSJames Bottomley if (FPT_BL_Card[thisCard].ioPort == ioport) { 12301da177e4SLinus Torvalds 123147b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[thisCard]; 123247b5d69cSJames Bottomley FPT_SccbMgrTableInitCard(CurrCard, thisCard); 12331da177e4SLinus Torvalds break; 12341da177e4SLinus Torvalds } 12351da177e4SLinus Torvalds 123647b5d69cSJames Bottomley else if (FPT_BL_Card[thisCard].ioPort == 0x00) { 12371da177e4SLinus Torvalds 123847b5d69cSJames Bottomley FPT_BL_Card[thisCard].ioPort = ioport; 123947b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[thisCard]; 12401da177e4SLinus Torvalds 124147b5d69cSJames Bottomley if (FPT_mbCards) 124247b5d69cSJames Bottomley for (i = 0; i < FPT_mbCards; i++) { 12435c04a7b8SAlexey Dobriyan if (CurrCard->ioPort == 12445c04a7b8SAlexey Dobriyan FPT_nvRamInfo[i].niBaseAddr) 12455c04a7b8SAlexey Dobriyan CurrCard->pNvRamInfo = 12465c04a7b8SAlexey Dobriyan &FPT_nvRamInfo[i]; 12471da177e4SLinus Torvalds } 124847b5d69cSJames Bottomley FPT_SccbMgrTableInitCard(CurrCard, thisCard); 12491da177e4SLinus Torvalds CurrCard->cardIndex = thisCard; 12501da177e4SLinus Torvalds CurrCard->cardInfo = pCardInfo; 12511da177e4SLinus Torvalds 12521da177e4SLinus Torvalds break; 12531da177e4SLinus Torvalds } 12541da177e4SLinus Torvalds } 12551da177e4SLinus Torvalds 12561da177e4SLinus Torvalds pCurrNvRam = CurrCard->pNvRamInfo; 12571da177e4SLinus Torvalds 12581da177e4SLinus Torvalds if (pCurrNvRam) { 12591da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf; 12605c04a7b8SAlexey Dobriyan } else { 12615c04a7b8SAlexey Dobriyan ScamFlg = 12625c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); 12631da177e4SLinus Torvalds } 12641da177e4SLinus Torvalds 126547b5d69cSJames Bottomley FPT_BusMasterInit(ioport); 126647b5d69cSJames Bottomley FPT_XbowInit(ioport, ScamFlg); 12671da177e4SLinus Torvalds 126847b5d69cSJames Bottomley FPT_autoLoadDefaultMap(ioport); 12691da177e4SLinus Torvalds 12705c04a7b8SAlexey Dobriyan for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) { 12715c04a7b8SAlexey Dobriyan } 12721da177e4SLinus Torvalds 12731da177e4SLinus Torvalds WR_HARPOON(ioport + hp_selfid_0, id); 12741da177e4SLinus Torvalds WR_HARPOON(ioport + hp_selfid_1, 0x00); 12751da177e4SLinus Torvalds WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id); 12761da177e4SLinus Torvalds CurrCard->ourId = pCardInfo->si_id; 12771da177e4SLinus Torvalds 1278db038cf8SAlexey Dobriyan i = (unsigned char)pCardInfo->si_flags; 12791da177e4SLinus Torvalds if (i & SCSI_PARITY_ENA) 12801da177e4SLinus Torvalds WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P)); 12811da177e4SLinus Torvalds 12821da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); 12831da177e4SLinus Torvalds if (i & LOW_BYTE_TERM) 12841da177e4SLinus Torvalds j |= SCSI_TERM_ENA_L; 12851da177e4SLinus Torvalds WR_HARPOON(ioport + hp_bm_ctrl, j); 12861da177e4SLinus Torvalds 12871da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H); 12881da177e4SLinus Torvalds if (i & HIGH_BYTE_TERM) 12891da177e4SLinus Torvalds j |= SCSI_TERM_ENA_H; 12901da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, j); 12911da177e4SLinus Torvalds 12921da177e4SLinus Torvalds if (!(pCardInfo->si_flags & SOFT_RESET)) { 12931da177e4SLinus Torvalds 129447b5d69cSJames Bottomley FPT_sresb(ioport, thisCard); 12951da177e4SLinus Torvalds 129647b5d69cSJames Bottomley FPT_scini(thisCard, pCardInfo->si_id, 0); 12971da177e4SLinus Torvalds } 12981da177e4SLinus Torvalds 12991da177e4SLinus Torvalds if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) 13001da177e4SLinus Torvalds CurrCard->globalFlags |= F_NO_FILTER; 13011da177e4SLinus Torvalds 13021da177e4SLinus Torvalds if (pCurrNvRam) { 13031da177e4SLinus Torvalds if (pCurrNvRam->niSysConf & 0x10) 13041da177e4SLinus Torvalds CurrCard->globalFlags |= F_GREEN_PC; 13055c04a7b8SAlexey Dobriyan } else { 130647b5d69cSJames Bottomley if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA) 13071da177e4SLinus Torvalds CurrCard->globalFlags |= F_GREEN_PC; 13081da177e4SLinus Torvalds } 13091da177e4SLinus Torvalds 13101da177e4SLinus Torvalds /* Set global flag to indicate Re-Negotiation to be done on all 13111da177e4SLinus Torvalds ckeck condition */ 13121da177e4SLinus Torvalds if (pCurrNvRam) { 13131da177e4SLinus Torvalds if (pCurrNvRam->niScsiConf & 0x04) 13141da177e4SLinus Torvalds CurrCard->globalFlags |= F_DO_RENEGO; 13155c04a7b8SAlexey Dobriyan } else { 131647b5d69cSJames Bottomley if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA) 13171da177e4SLinus Torvalds CurrCard->globalFlags |= F_DO_RENEGO; 13181da177e4SLinus Torvalds } 13191da177e4SLinus Torvalds 13201da177e4SLinus Torvalds if (pCurrNvRam) { 13211da177e4SLinus Torvalds if (pCurrNvRam->niScsiConf & 0x08) 13221da177e4SLinus Torvalds CurrCard->globalFlags |= F_CONLUN_IO; 13235c04a7b8SAlexey Dobriyan } else { 132447b5d69cSJames Bottomley if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA) 13251da177e4SLinus Torvalds CurrCard->globalFlags |= F_CONLUN_IO; 13261da177e4SLinus Torvalds } 13271da177e4SLinus Torvalds 13281da177e4SLinus Torvalds temp = pCardInfo->si_per_targ_no_disc; 13291da177e4SLinus Torvalds 13301da177e4SLinus Torvalds for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) { 13311da177e4SLinus Torvalds 13321da177e4SLinus Torvalds if (temp & id) 133347b5d69cSJames Bottomley FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC; 13341da177e4SLinus Torvalds } 13351da177e4SLinus Torvalds 13361da177e4SLinus Torvalds sync_bit_map = 0x0001; 13371da177e4SLinus Torvalds 13381da177e4SLinus Torvalds for (id = 0; id < (MAX_SCSI_TAR / 2); id++) { 13391da177e4SLinus Torvalds 13401da177e4SLinus Torvalds if (pCurrNvRam) { 1341c823feebSAlexey Dobriyan temp = (unsigned short)pCurrNvRam->niSyncTbl[id]; 13421da177e4SLinus Torvalds temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + 13431da177e4SLinus Torvalds (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); 13441da177e4SLinus Torvalds } else 13455c04a7b8SAlexey Dobriyan temp = 13465c04a7b8SAlexey Dobriyan FPT_utilEERead(ioport, 13475c04a7b8SAlexey Dobriyan (unsigned short)((SYNC_RATE_TBL / 2) 13485c04a7b8SAlexey Dobriyan + id)); 13491da177e4SLinus Torvalds 13501da177e4SLinus Torvalds for (i = 0; i < 2; temp >>= 8, i++) { 13511da177e4SLinus Torvalds 13521da177e4SLinus Torvalds if (pCardInfo->si_per_targ_init_sync & sync_bit_map) { 13531da177e4SLinus Torvalds 13545c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 + 13555c04a7b8SAlexey Dobriyan i].TarEEValue = 13565c04a7b8SAlexey Dobriyan (unsigned char)temp; 13571da177e4SLinus Torvalds } 13581da177e4SLinus Torvalds 13591da177e4SLinus Torvalds else { 13605c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 + 13615c04a7b8SAlexey Dobriyan i].TarStatus |= 13625c04a7b8SAlexey Dobriyan SYNC_SUPPORTED; 13635c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 + 13645c04a7b8SAlexey Dobriyan i].TarEEValue = 1365db038cf8SAlexey Dobriyan (unsigned char)(temp & ~EE_SYNC_MASK); 13661da177e4SLinus Torvalds } 13671da177e4SLinus Torvalds 13681da177e4SLinus Torvalds /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) || 13691da177e4SLinus Torvalds (id*2+i >= 8)){ 13701da177e4SLinus Torvalds */ 13711da177e4SLinus Torvalds if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) { 13721da177e4SLinus Torvalds 13735c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 + 13745c04a7b8SAlexey Dobriyan i].TarEEValue |= 13755c04a7b8SAlexey Dobriyan EE_WIDE_SCSI; 13761da177e4SLinus Torvalds 13771da177e4SLinus Torvalds } 13781da177e4SLinus Torvalds 13791da177e4SLinus Torvalds else { /* NARROW SCSI */ 13805c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 + 13815c04a7b8SAlexey Dobriyan i].TarStatus |= 13825c04a7b8SAlexey Dobriyan WIDE_NEGOCIATED; 13831da177e4SLinus Torvalds } 13841da177e4SLinus Torvalds 13851da177e4SLinus Torvalds sync_bit_map <<= 1; 13861da177e4SLinus Torvalds 13871da177e4SLinus Torvalds } 13881da177e4SLinus Torvalds } 13891da177e4SLinus Torvalds 13901da177e4SLinus Torvalds WR_HARPOON((ioport + hp_semaphore), 13915c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) | 13925c04a7b8SAlexey Dobriyan SCCB_MGR_PRESENT)); 13931da177e4SLinus Torvalds 1394391e2f25SKhalid Aziz return (void *)CurrCard; 13951da177e4SLinus Torvalds } 13961da177e4SLinus Torvalds 1397391e2f25SKhalid Aziz static void FlashPoint_ReleaseHostAdapter(void *pCurrCard) 13981da177e4SLinus Torvalds { 1399db038cf8SAlexey Dobriyan unsigned char i; 1400391e2f25SKhalid Aziz u32 portBase; 1401391e2f25SKhalid Aziz u32 regOffset; 1402391e2f25SKhalid Aziz u32 scamData; 1403391e2f25SKhalid Aziz u32 *pScamTbl; 140468d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 14051da177e4SLinus Torvalds 140613e6851aSAlexey Dobriyan pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo; 14071da177e4SLinus Torvalds 14081da177e4SLinus Torvalds if (pCurrNvRam) { 140947b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel); 141047b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf); 141147b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf); 141247b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf); 141347b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId); 14141da177e4SLinus Torvalds 14151da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR / 2; i++) 14165c04a7b8SAlexey Dobriyan FPT_WrStack(pCurrNvRam->niBaseAddr, 14175c04a7b8SAlexey Dobriyan (unsigned char)(i + 5), 14185c04a7b8SAlexey Dobriyan pCurrNvRam->niSyncTbl[i]); 14191da177e4SLinus Torvalds 14201da177e4SLinus Torvalds portBase = pCurrNvRam->niBaseAddr; 14211da177e4SLinus Torvalds 14221da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR; i++) { 14231da177e4SLinus Torvalds regOffset = hp_aramBase + 64 + i * 4; 1424391e2f25SKhalid Aziz pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i]; 14251da177e4SLinus Torvalds scamData = *pScamTbl; 14261da177e4SLinus Torvalds WR_HARP32(portBase, regOffset, scamData); 14271da177e4SLinus Torvalds } 14281da177e4SLinus Torvalds 14291da177e4SLinus Torvalds } else { 143013e6851aSAlexey Dobriyan FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0); 14311da177e4SLinus Torvalds } 14321da177e4SLinus Torvalds } 14331da177e4SLinus Torvalds 143468d0c1aeSAlexey Dobriyan static void FPT_RNVRamData(struct nvram_info *pNvRamInfo) 14351da177e4SLinus Torvalds { 1436db038cf8SAlexey Dobriyan unsigned char i; 1437391e2f25SKhalid Aziz u32 portBase; 1438391e2f25SKhalid Aziz u32 regOffset; 1439391e2f25SKhalid Aziz u32 scamData; 1440391e2f25SKhalid Aziz u32 *pScamTbl; 14411da177e4SLinus Torvalds 144247b5d69cSJames Bottomley pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0); 144347b5d69cSJames Bottomley pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1); 144447b5d69cSJames Bottomley pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2); 144547b5d69cSJames Bottomley pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3); 144647b5d69cSJames Bottomley pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4); 14471da177e4SLinus Torvalds 14481da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR / 2; i++) 14495c04a7b8SAlexey Dobriyan pNvRamInfo->niSyncTbl[i] = 14505c04a7b8SAlexey Dobriyan FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5)); 14511da177e4SLinus Torvalds 14521da177e4SLinus Torvalds portBase = pNvRamInfo->niBaseAddr; 14531da177e4SLinus Torvalds 14541da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR; i++) { 14551da177e4SLinus Torvalds regOffset = hp_aramBase + 64 + i * 4; 14561da177e4SLinus Torvalds RD_HARP32(portBase, regOffset, scamData); 1457391e2f25SKhalid Aziz pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i]; 14581da177e4SLinus Torvalds *pScamTbl = scamData; 14591da177e4SLinus Torvalds } 14601da177e4SLinus Torvalds 14611da177e4SLinus Torvalds } 14621da177e4SLinus Torvalds 1463391e2f25SKhalid Aziz static unsigned char FPT_RdStack(u32 portBase, unsigned char index) 14641da177e4SLinus Torvalds { 14651da177e4SLinus Torvalds WR_HARPOON(portBase + hp_stack_addr, index); 14665c1b85e2SAlexey Dobriyan return RD_HARPOON(portBase + hp_stack_data); 14671da177e4SLinus Torvalds } 14681da177e4SLinus Torvalds 1469391e2f25SKhalid Aziz static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data) 14701da177e4SLinus Torvalds { 14711da177e4SLinus Torvalds WR_HARPOON(portBase + hp_stack_addr, index); 14721da177e4SLinus Torvalds WR_HARPOON(portBase + hp_stack_data, data); 14731da177e4SLinus Torvalds } 14741da177e4SLinus Torvalds 1475391e2f25SKhalid Aziz static unsigned char FPT_ChkIfChipInitialized(u32 ioPort) 14761da177e4SLinus Torvalds { 147747b5d69cSJames Bottomley if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4)) 14785c1b85e2SAlexey Dobriyan return 0; 14791da177e4SLinus Torvalds if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT) 14801da177e4SLinus Torvalds != CLKCTRL_DEFAULT) 14815c1b85e2SAlexey Dobriyan return 0; 14821da177e4SLinus Torvalds if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) || 14831da177e4SLinus Torvalds (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms)) 14845c1b85e2SAlexey Dobriyan return 1; 14855c1b85e2SAlexey Dobriyan return 0; 14861da177e4SLinus Torvalds 14871da177e4SLinus Torvalds } 14885c04a7b8SAlexey Dobriyan 14891da177e4SLinus Torvalds /*--------------------------------------------------------------------- 14901da177e4SLinus Torvalds * 1491d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_StartCCB 14921da177e4SLinus Torvalds * 14931da177e4SLinus Torvalds * Description: Start a command pointed to by p_Sccb. When the 14941da177e4SLinus Torvalds * command is completed it will be returned via the 14951da177e4SLinus Torvalds * callback function. 14961da177e4SLinus Torvalds * 14971da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 1498391e2f25SKhalid Aziz static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb) 14991da177e4SLinus Torvalds { 1500391e2f25SKhalid Aziz u32 ioport; 1501db038cf8SAlexey Dobriyan unsigned char thisCard, lun; 150269eb2ea4SAlexey Dobriyan struct sccb *pSaveSccb; 15031da177e4SLinus Torvalds CALL_BK_FN callback; 1504391e2f25SKhalid Aziz struct sccb_card *pCurrCard = curr_card; 15051da177e4SLinus Torvalds 1506391e2f25SKhalid Aziz thisCard = pCurrCard->cardIndex; 1507391e2f25SKhalid Aziz ioport = pCurrCard->ioPort; 15081da177e4SLinus Torvalds 15091377d8ddSAdrian Bunk if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) { 15101da177e4SLinus Torvalds 15111da177e4SLinus Torvalds p_Sccb->HostStatus = SCCB_COMPLETE; 15121da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ERROR; 15131da177e4SLinus Torvalds callback = (CALL_BK_FN) p_Sccb->SccbCallback; 15141da177e4SLinus Torvalds if (callback) 15151da177e4SLinus Torvalds callback(p_Sccb); 15161da177e4SLinus Torvalds 15171da177e4SLinus Torvalds return; 15181da177e4SLinus Torvalds } 15191da177e4SLinus Torvalds 152047b5d69cSJames Bottomley FPT_sinits(p_Sccb, thisCard); 15211da177e4SLinus Torvalds 1522391e2f25SKhalid Aziz if (!pCurrCard->cmdCounter) { 15235c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_semaphore, 15245c04a7b8SAlexey Dobriyan (RD_HARPOON(ioport + hp_semaphore) 15251da177e4SLinus Torvalds | SCCB_MGR_ACTIVE)); 15261da177e4SLinus Torvalds 1527391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_GREEN_PC) { 15281da177e4SLinus Torvalds WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT); 15291da177e4SLinus Torvalds WR_HARPOON(ioport + hp_sys_ctrl, 0x00); 15301da177e4SLinus Torvalds } 15311da177e4SLinus Torvalds } 15321da177e4SLinus Torvalds 1533391e2f25SKhalid Aziz pCurrCard->cmdCounter++; 15341da177e4SLinus Torvalds 15351da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) { 15361da177e4SLinus Torvalds 15375c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_semaphore, 15385c04a7b8SAlexey Dobriyan (RD_HARPOON(ioport + hp_semaphore) 15391da177e4SLinus Torvalds | TICKLE_ME)); 15405c04a7b8SAlexey Dobriyan if (p_Sccb->OperationCode == RESET_COMMAND) { 15415c04a7b8SAlexey Dobriyan pSaveSccb = 1542391e2f25SKhalid Aziz pCurrCard->currentSCCB; 1543391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb; 154447b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); 1545391e2f25SKhalid Aziz pCurrCard->currentSCCB = 15465c04a7b8SAlexey Dobriyan pSaveSccb; 15475c04a7b8SAlexey Dobriyan } else { 154847b5d69cSJames Bottomley FPT_queueAddSccb(p_Sccb, thisCard); 15491da177e4SLinus Torvalds } 15501da177e4SLinus Torvalds } 15511da177e4SLinus Torvalds 15521da177e4SLinus Torvalds else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) { 15531da177e4SLinus Torvalds 15545c04a7b8SAlexey Dobriyan if (p_Sccb->OperationCode == RESET_COMMAND) { 15555c04a7b8SAlexey Dobriyan pSaveSccb = 1556391e2f25SKhalid Aziz pCurrCard->currentSCCB; 1557391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb; 155847b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard); 1559391e2f25SKhalid Aziz pCurrCard->currentSCCB = 15605c04a7b8SAlexey Dobriyan pSaveSccb; 15615c04a7b8SAlexey Dobriyan } else { 156247b5d69cSJames Bottomley FPT_queueAddSccb(p_Sccb, thisCard); 15631da177e4SLinus Torvalds } 15641da177e4SLinus Torvalds } 15651da177e4SLinus Torvalds 15661da177e4SLinus Torvalds else { 15671da177e4SLinus Torvalds 15681da177e4SLinus Torvalds MDISABLE_INT(ioport); 15691da177e4SLinus Torvalds 1570391e2f25SKhalid Aziz if ((pCurrCard->globalFlags & F_CONLUN_IO) && 15715c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID]. 15725c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) 15731da177e4SLinus Torvalds lun = p_Sccb->Lun; 15741da177e4SLinus Torvalds else 15751da177e4SLinus Torvalds lun = 0; 1576391e2f25SKhalid Aziz if ((pCurrCard->currentSCCB == NULL) && 15775c04a7b8SAlexey Dobriyan (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) 15785c04a7b8SAlexey Dobriyan && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun] 157947b5d69cSJames Bottomley == 0)) { 15801da177e4SLinus Torvalds 1581391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb; 158247b5d69cSJames Bottomley FPT_ssel(p_Sccb->SccbIOPort, thisCard); 15831da177e4SLinus Torvalds } 15841da177e4SLinus Torvalds 15851da177e4SLinus Torvalds else { 15861da177e4SLinus Torvalds 15875c04a7b8SAlexey Dobriyan if (p_Sccb->OperationCode == RESET_COMMAND) { 1588391e2f25SKhalid Aziz pSaveSccb = pCurrCard->currentSCCB; 1589391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb; 15905c04a7b8SAlexey Dobriyan FPT_queueSelectFail(&FPT_BL_Card[thisCard], 15915c04a7b8SAlexey Dobriyan thisCard); 1592391e2f25SKhalid Aziz pCurrCard->currentSCCB = pSaveSccb; 15935c04a7b8SAlexey Dobriyan } else { 159447b5d69cSJames Bottomley FPT_queueAddSccb(p_Sccb, thisCard); 15951da177e4SLinus Torvalds } 15961da177e4SLinus Torvalds } 15971da177e4SLinus Torvalds 15981da177e4SLinus Torvalds MENABLE_INT(ioport); 15991da177e4SLinus Torvalds } 16001da177e4SLinus Torvalds 16011da177e4SLinus Torvalds } 16021da177e4SLinus Torvalds 16031da177e4SLinus Torvalds /*--------------------------------------------------------------------- 16041da177e4SLinus Torvalds * 1605d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_AbortCCB 16061da177e4SLinus Torvalds * 16071da177e4SLinus Torvalds * Description: Abort the command pointed to by p_Sccb. When the 16081da177e4SLinus Torvalds * command is completed it will be returned via the 16091da177e4SLinus Torvalds * callback function. 16101da177e4SLinus Torvalds * 16111da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 1612391e2f25SKhalid Aziz static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb) 16131da177e4SLinus Torvalds { 1614391e2f25SKhalid Aziz u32 ioport; 16151da177e4SLinus Torvalds 1616db038cf8SAlexey Dobriyan unsigned char thisCard; 16171da177e4SLinus Torvalds CALL_BK_FN callback; 1618db038cf8SAlexey Dobriyan unsigned char TID; 161969eb2ea4SAlexey Dobriyan struct sccb *pSaveSCCB; 1620f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 16211da177e4SLinus Torvalds 162213e6851aSAlexey Dobriyan ioport = ((struct sccb_card *)pCurrCard)->ioPort; 16231da177e4SLinus Torvalds 162413e6851aSAlexey Dobriyan thisCard = ((struct sccb_card *)pCurrCard)->cardIndex; 16251da177e4SLinus Torvalds 16265c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) { 16271da177e4SLinus Torvalds 16285c04a7b8SAlexey Dobriyan if (FPT_queueFindSccb(p_Sccb, thisCard)) { 16291da177e4SLinus Torvalds 163013e6851aSAlexey Dobriyan ((struct sccb_card *)pCurrCard)->cmdCounter--; 16311da177e4SLinus Torvalds 163213e6851aSAlexey Dobriyan if (!((struct sccb_card *)pCurrCard)->cmdCounter) 16335c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_semaphore, 16345c04a7b8SAlexey Dobriyan (RD_HARPOON(ioport + hp_semaphore) 16355c04a7b8SAlexey Dobriyan & (unsigned 16365c04a7b8SAlexey Dobriyan char)(~(SCCB_MGR_ACTIVE | 16375c04a7b8SAlexey Dobriyan TICKLE_ME)))); 16381da177e4SLinus Torvalds 16391da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT; 16401da177e4SLinus Torvalds callback = p_Sccb->SccbCallback; 16411da177e4SLinus Torvalds callback(p_Sccb); 16421da177e4SLinus Torvalds 16435c1b85e2SAlexey Dobriyan return 0; 16441da177e4SLinus Torvalds } 16451da177e4SLinus Torvalds 16465c04a7b8SAlexey Dobriyan else { 16475c04a7b8SAlexey Dobriyan if (((struct sccb_card *)pCurrCard)->currentSCCB == 16485c04a7b8SAlexey Dobriyan p_Sccb) { 16491da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT; 16505c1b85e2SAlexey Dobriyan return 0; 16511da177e4SLinus Torvalds 16521da177e4SLinus Torvalds } 16531da177e4SLinus Torvalds 16545c04a7b8SAlexey Dobriyan else { 16551da177e4SLinus Torvalds 16561da177e4SLinus Torvalds TID = p_Sccb->TargID; 16571da177e4SLinus Torvalds 16585c04a7b8SAlexey Dobriyan if (p_Sccb->Sccb_tag) { 16591da177e4SLinus Torvalds MDISABLE_INT(ioport); 16605c04a7b8SAlexey Dobriyan if (((struct sccb_card *)pCurrCard)-> 16615c04a7b8SAlexey Dobriyan discQ_Tbl[p_Sccb->Sccb_tag] == 16625c04a7b8SAlexey Dobriyan p_Sccb) { 16631da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT; 16645c04a7b8SAlexey Dobriyan p_Sccb->Sccb_scsistat = 16655c04a7b8SAlexey Dobriyan ABORT_ST; 16665c04a7b8SAlexey Dobriyan p_Sccb->Sccb_scsimsg = 16675c04a7b8SAlexey Dobriyan SMABORT_TAG; 16681da177e4SLinus Torvalds 16695c04a7b8SAlexey Dobriyan if (((struct sccb_card *) 16705c04a7b8SAlexey Dobriyan pCurrCard)->currentSCCB == 16715c04a7b8SAlexey Dobriyan NULL) { 16725c04a7b8SAlexey Dobriyan ((struct sccb_card *) 16735c04a7b8SAlexey Dobriyan pCurrCard)-> 16745c04a7b8SAlexey Dobriyan currentSCCB = p_Sccb; 16755c04a7b8SAlexey Dobriyan FPT_ssel(ioport, 16765c04a7b8SAlexey Dobriyan thisCard); 16775c04a7b8SAlexey Dobriyan } else { 16785c04a7b8SAlexey Dobriyan pSaveSCCB = 16795c04a7b8SAlexey Dobriyan ((struct sccb_card 16805c04a7b8SAlexey Dobriyan *)pCurrCard)-> 16815c04a7b8SAlexey Dobriyan currentSCCB; 16825c04a7b8SAlexey Dobriyan ((struct sccb_card *) 16835c04a7b8SAlexey Dobriyan pCurrCard)-> 16845c04a7b8SAlexey Dobriyan currentSCCB = p_Sccb; 168513e6851aSAlexey Dobriyan FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard); 16865c04a7b8SAlexey Dobriyan ((struct sccb_card *) 16875c04a7b8SAlexey Dobriyan pCurrCard)-> 16885c04a7b8SAlexey Dobriyan currentSCCB = pSaveSCCB; 16891da177e4SLinus Torvalds } 16901da177e4SLinus Torvalds } 16911da177e4SLinus Torvalds MENABLE_INT(ioport); 16925c1b85e2SAlexey Dobriyan return 0; 16935c04a7b8SAlexey Dobriyan } else { 16945c04a7b8SAlexey Dobriyan currTar_Info = 16955c04a7b8SAlexey Dobriyan &FPT_sccbMgrTbl[thisCard][p_Sccb-> 16965c04a7b8SAlexey Dobriyan TargID]; 16971da177e4SLinus Torvalds 16985c04a7b8SAlexey Dobriyan if (FPT_BL_Card[thisCard]. 16995c04a7b8SAlexey Dobriyan discQ_Tbl[currTar_Info-> 17005c04a7b8SAlexey Dobriyan LunDiscQ_Idx[p_Sccb->Lun]] 17015c04a7b8SAlexey Dobriyan == p_Sccb) { 17021da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT; 17035c1b85e2SAlexey Dobriyan return 0; 17041da177e4SLinus Torvalds } 17051da177e4SLinus Torvalds } 17061da177e4SLinus Torvalds } 17071da177e4SLinus Torvalds } 17081da177e4SLinus Torvalds } 17095c1b85e2SAlexey Dobriyan return -1; 17101da177e4SLinus Torvalds } 17111da177e4SLinus Torvalds 17121da177e4SLinus Torvalds /*--------------------------------------------------------------------- 17131da177e4SLinus Torvalds * 1714d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_InterruptPending 17151da177e4SLinus Torvalds * 17161da177e4SLinus Torvalds * Description: Do a quick check to determine if there is a pending 17171da177e4SLinus Torvalds * interrupt for this card and disable the IRQ Pin if so. 17181da177e4SLinus Torvalds * 17191da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 1720391e2f25SKhalid Aziz static unsigned char FlashPoint_InterruptPending(void *pCurrCard) 17211da177e4SLinus Torvalds { 1722391e2f25SKhalid Aziz u32 ioport; 17231da177e4SLinus Torvalds 172413e6851aSAlexey Dobriyan ioport = ((struct sccb_card *)pCurrCard)->ioPort; 17251da177e4SLinus Torvalds 17265c04a7b8SAlexey Dobriyan if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) { 17275c1b85e2SAlexey Dobriyan return 1; 17281da177e4SLinus Torvalds } 17291da177e4SLinus Torvalds 17301da177e4SLinus Torvalds else 17311da177e4SLinus Torvalds 17325c1b85e2SAlexey Dobriyan return 0; 17331da177e4SLinus Torvalds } 17341da177e4SLinus Torvalds 17351da177e4SLinus Torvalds /*--------------------------------------------------------------------- 17361da177e4SLinus Torvalds * 1737d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_HandleInterrupt 17381da177e4SLinus Torvalds * 17391da177e4SLinus Torvalds * Description: This is our entry point when an interrupt is generated 17401da177e4SLinus Torvalds * by the card and the upper level driver passes it on to 17411da177e4SLinus Torvalds * us. 17421da177e4SLinus Torvalds * 17431da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 1744391e2f25SKhalid Aziz static int FlashPoint_HandleInterrupt(void *pcard) 17451da177e4SLinus Torvalds { 174669eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 1747db038cf8SAlexey Dobriyan unsigned char thisCard, result, bm_status, bm_int_st; 1748c823feebSAlexey Dobriyan unsigned short hp_int; 1749db038cf8SAlexey Dobriyan unsigned char i, target; 1750391e2f25SKhalid Aziz struct sccb_card *pCurrCard = pcard; 1751391e2f25SKhalid Aziz u32 ioport; 17521da177e4SLinus Torvalds 1753391e2f25SKhalid Aziz thisCard = pCurrCard->cardIndex; 1754391e2f25SKhalid Aziz ioport = pCurrCard->ioPort; 17551da177e4SLinus Torvalds 17561da177e4SLinus Torvalds MDISABLE_INT(ioport); 17571da177e4SLinus Torvalds 17581da177e4SLinus Torvalds if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON) 1759391e2f25SKhalid Aziz bm_status = RD_HARPOON(ioport + hp_ext_status) & 1760391e2f25SKhalid Aziz (unsigned char)BAD_EXT_STATUS; 17611da177e4SLinus Torvalds else 17621da177e4SLinus Torvalds bm_status = 0; 17631da177e4SLinus Torvalds 17641da177e4SLinus Torvalds WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); 17651da177e4SLinus Torvalds 1766391e2f25SKhalid Aziz while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) & 1767391e2f25SKhalid Aziz FPT_default_intena) | bm_status) { 17681da177e4SLinus Torvalds 1769391e2f25SKhalid Aziz currSCCB = pCurrCard->currentSCCB; 17701da177e4SLinus Torvalds 17711da177e4SLinus Torvalds if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) { 17725c04a7b8SAlexey Dobriyan result = 1773391e2f25SKhalid Aziz FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard, 17745c04a7b8SAlexey Dobriyan hp_int); 17755c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat), 17765c04a7b8SAlexey Dobriyan (FIFO | TIMEOUT | RESET | SCAM_SEL)); 17771da177e4SLinus Torvalds bm_status = 0; 17781da177e4SLinus Torvalds 17791da177e4SLinus Torvalds if (result) { 17801da177e4SLinus Torvalds 17811da177e4SLinus Torvalds MENABLE_INT(ioport); 17825c1b85e2SAlexey Dobriyan return result; 17831da177e4SLinus Torvalds } 17841da177e4SLinus Torvalds } 17851da177e4SLinus Torvalds 17861da177e4SLinus Torvalds else if (hp_int & ICMD_COMP) { 17871da177e4SLinus Torvalds 17881da177e4SLinus Torvalds if (!(hp_int & BUS_FREE)) { 17891da177e4SLinus Torvalds /* Wait for the BusFree before starting a new command. We 17901da177e4SLinus Torvalds must also check for being reselected since the BusFree 17911da177e4SLinus Torvalds may not show up if another device reselects us in 1.5us or 17921da177e4SLinus Torvalds less. SRR Wednesday, 3/8/1995. 17931da177e4SLinus Torvalds */ 17945c04a7b8SAlexey Dobriyan while (! 17955c04a7b8SAlexey Dobriyan (RDW_HARPOON((ioport + hp_intstat)) & 17965c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))) ; 17971da177e4SLinus Torvalds } 17981da177e4SLinus Torvalds 1799391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT) 18001da177e4SLinus Torvalds 180147b5d69cSJames Bottomley FPT_phaseChkFifo(ioport, thisCard); 18021da177e4SLinus Torvalds 18031da177e4SLinus Torvalds /* WRW_HARPOON((ioport+hp_intstat), 18041da177e4SLinus Torvalds (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0)); 18051da177e4SLinus Torvalds */ 18061da177e4SLinus Torvalds 18071da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1); 18081da177e4SLinus Torvalds 180947b5d69cSJames Bottomley FPT_autoCmdCmplt(ioport, thisCard); 18101da177e4SLinus Torvalds 18111da177e4SLinus Torvalds } 18121da177e4SLinus Torvalds 18135c04a7b8SAlexey Dobriyan else if (hp_int & ITAR_DISC) { 18141da177e4SLinus Torvalds 1815391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT) 181647b5d69cSJames Bottomley FPT_phaseChkFifo(ioport, thisCard); 18171da177e4SLinus Torvalds 1818391e2f25SKhalid Aziz if (RD_HARPOON(ioport + hp_gp_reg_1) == 1819391e2f25SKhalid Aziz SMSAVE_DATA_PTR) { 18201da177e4SLinus Torvalds 18211da177e4SLinus Torvalds WR_HARPOON(ioport + hp_gp_reg_1, 0x00); 18221da177e4SLinus Torvalds currSCCB->Sccb_XferState |= F_NO_DATA_YET; 18231da177e4SLinus Torvalds 18241da177e4SLinus Torvalds currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC; 18251da177e4SLinus Torvalds } 18261da177e4SLinus Torvalds 18271da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DISCONNECT_ST; 182847b5d69cSJames Bottomley FPT_queueDisconnect(currSCCB, thisCard); 18291da177e4SLinus Torvalds 18301da177e4SLinus Torvalds /* Wait for the BusFree before starting a new command. We 18311da177e4SLinus Torvalds must also check for being reselected since the BusFree 18321da177e4SLinus Torvalds may not show up if another device reselects us in 1.5us or 18331da177e4SLinus Torvalds less. SRR Wednesday, 3/8/1995. 18341da177e4SLinus Torvalds */ 18355c04a7b8SAlexey Dobriyan while (! 18365c04a7b8SAlexey Dobriyan (RDW_HARPOON((ioport + hp_intstat)) & 18375c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL)) 18385c04a7b8SAlexey Dobriyan && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE) 18395c04a7b8SAlexey Dobriyan && RD_HARPOON((ioport + hp_scsisig)) == 18405c04a7b8SAlexey Dobriyan (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | 18415c04a7b8SAlexey Dobriyan SCSI_IOBIT))) ; 18421da177e4SLinus Torvalds 18431da177e4SLinus Torvalds /* 18441da177e4SLinus Torvalds The additional loop exit condition above detects a timing problem 18451da177e4SLinus Torvalds with the revision D/E harpoon chips. The caller should reset the 18461da177e4SLinus Torvalds host adapter to recover when 0xFE is returned. 18471da177e4SLinus Torvalds */ 18485c04a7b8SAlexey Dobriyan if (! 18495c04a7b8SAlexey Dobriyan (RDW_HARPOON((ioport + hp_intstat)) & 18505c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))) { 18511da177e4SLinus Torvalds MENABLE_INT(ioport); 18521da177e4SLinus Torvalds return 0xFE; 18531da177e4SLinus Torvalds } 18541da177e4SLinus Torvalds 18555c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat), 18565c04a7b8SAlexey Dobriyan (BUS_FREE | ITAR_DISC)); 18571da177e4SLinus Torvalds 1858391e2f25SKhalid Aziz pCurrCard->globalFlags |= F_NEW_SCCB_CMD; 18591da177e4SLinus Torvalds 18601da177e4SLinus Torvalds } 18611da177e4SLinus Torvalds 18621da177e4SLinus Torvalds else if (hp_int & RSEL) { 18631da177e4SLinus Torvalds 18645c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat), 18655c04a7b8SAlexey Dobriyan (PROG_HLT | RSEL | PHASE | BUS_FREE)); 18661da177e4SLinus Torvalds 18675c04a7b8SAlexey Dobriyan if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) { 1868391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT) 186947b5d69cSJames Bottomley FPT_phaseChkFifo(ioport, thisCard); 18701da177e4SLinus Torvalds 18715c04a7b8SAlexey Dobriyan if (RD_HARPOON(ioport + hp_gp_reg_1) == 18725c04a7b8SAlexey Dobriyan SMSAVE_DATA_PTR) { 18731da177e4SLinus Torvalds WR_HARPOON(ioport + hp_gp_reg_1, 0x00); 18745c04a7b8SAlexey Dobriyan currSCCB->Sccb_XferState |= 18755c04a7b8SAlexey Dobriyan F_NO_DATA_YET; 18765c04a7b8SAlexey Dobriyan currSCCB->Sccb_savedATC = 18775c04a7b8SAlexey Dobriyan currSCCB->Sccb_ATC; 18781da177e4SLinus Torvalds } 18791da177e4SLinus Torvalds 18805c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat), 18815c04a7b8SAlexey Dobriyan (BUS_FREE | ITAR_DISC)); 18821da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DISCONNECT_ST; 188347b5d69cSJames Bottomley FPT_queueDisconnect(currSCCB, thisCard); 18841da177e4SLinus Torvalds } 18851da177e4SLinus Torvalds 1886391e2f25SKhalid Aziz FPT_sres(ioport, thisCard, pCurrCard); 188747b5d69cSJames Bottomley FPT_phaseDecode(ioport, thisCard); 18881da177e4SLinus Torvalds 18891da177e4SLinus Torvalds } 18901da177e4SLinus Torvalds 18915c04a7b8SAlexey Dobriyan else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) { 18921da177e4SLinus Torvalds 18935c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat), 18945c04a7b8SAlexey Dobriyan (IDO_STRT | XFER_CNT_0)); 189547b5d69cSJames Bottomley FPT_phaseDecode(ioport, thisCard); 18961da177e4SLinus Torvalds 18971da177e4SLinus Torvalds } 18981da177e4SLinus Torvalds 18995c04a7b8SAlexey Dobriyan else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) { 19005c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat), 19015c04a7b8SAlexey Dobriyan (PHASE | IUNKWN | PROG_HLT)); 19025c04a7b8SAlexey Dobriyan if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char) 19035c04a7b8SAlexey Dobriyan 0x3f) < (unsigned char)SELCHK) { 190447b5d69cSJames Bottomley FPT_phaseDecode(ioport, thisCard); 19055c04a7b8SAlexey Dobriyan } else { 19061da177e4SLinus Torvalds /* Harpoon problem some SCSI target device respond to selection 19071da177e4SLinus Torvalds with short BUSY pulse (<400ns) this will make the Harpoon is not able 19081da177e4SLinus Torvalds to latch the correct Target ID into reg. x53. 19091da177e4SLinus Torvalds The work around require to correct this reg. But when write to this 19101da177e4SLinus Torvalds reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we 19111da177e4SLinus Torvalds need to read this reg first then restore it later. After update to 0x53 */ 19121da177e4SLinus Torvalds 19135c04a7b8SAlexey Dobriyan i = (unsigned 19145c04a7b8SAlexey Dobriyan char)(RD_HARPOON(ioport + hp_fifowrite)); 19155c04a7b8SAlexey Dobriyan target = 19165c04a7b8SAlexey Dobriyan (unsigned 19175c04a7b8SAlexey Dobriyan char)(RD_HARPOON(ioport + hp_gp_reg_3)); 19185c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_xfer_pad, 19195c04a7b8SAlexey Dobriyan (unsigned char)ID_UNLOCK); 19205c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_select_id, 19215c04a7b8SAlexey Dobriyan (unsigned char)(target | target << 19225c04a7b8SAlexey Dobriyan 4)); 19235c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_xfer_pad, 19245c04a7b8SAlexey Dobriyan (unsigned char)0x00); 19251da177e4SLinus Torvalds WR_HARPOON(ioport + hp_fifowrite, i); 19265c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_autostart_3, 19275c04a7b8SAlexey Dobriyan (AUTO_IMMED + TAG_STRT)); 19281da177e4SLinus Torvalds } 19291da177e4SLinus Torvalds } 19301da177e4SLinus Torvalds 19311da177e4SLinus Torvalds else if (hp_int & XFER_CNT_0) { 19321da177e4SLinus Torvalds 19331da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0); 19341da177e4SLinus Torvalds 193547b5d69cSJames Bottomley FPT_schkdd(ioport, thisCard); 19361da177e4SLinus Torvalds 19371da177e4SLinus Torvalds } 19381da177e4SLinus Torvalds 19391da177e4SLinus Torvalds else if (hp_int & BUS_FREE) { 19401da177e4SLinus Torvalds 19411da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), BUS_FREE); 19421da177e4SLinus Torvalds 1943391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT) { 19441da177e4SLinus Torvalds 19455c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(ioport, thisCard, 19465c04a7b8SAlexey Dobriyan currSCCB); 19471da177e4SLinus Torvalds } 19481da177e4SLinus Torvalds 194947b5d69cSJames Bottomley FPT_phaseBusFree(ioport, thisCard); 19501da177e4SLinus Torvalds } 19511da177e4SLinus Torvalds 19521da177e4SLinus Torvalds else if (hp_int & ITICKLE) { 19531da177e4SLinus Torvalds 19541da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), ITICKLE); 1955391e2f25SKhalid Aziz pCurrCard->globalFlags |= F_NEW_SCCB_CMD; 19561da177e4SLinus Torvalds } 19571da177e4SLinus Torvalds 19585c04a7b8SAlexey Dobriyan if (((struct sccb_card *)pCurrCard)-> 19595c04a7b8SAlexey Dobriyan globalFlags & F_NEW_SCCB_CMD) { 19601da177e4SLinus Torvalds 1961391e2f25SKhalid Aziz pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD; 19621da177e4SLinus Torvalds 1963391e2f25SKhalid Aziz if (pCurrCard->currentSCCB == NULL) 1964391e2f25SKhalid Aziz FPT_queueSearchSelect(pCurrCard, thisCard); 19651da177e4SLinus Torvalds 1966391e2f25SKhalid Aziz if (pCurrCard->currentSCCB != NULL) { 1967391e2f25SKhalid Aziz pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD; 196847b5d69cSJames Bottomley FPT_ssel(ioport, thisCard); 19691da177e4SLinus Torvalds } 19701da177e4SLinus Torvalds 19711da177e4SLinus Torvalds break; 19721da177e4SLinus Torvalds 19731da177e4SLinus Torvalds } 19741da177e4SLinus Torvalds 19751da177e4SLinus Torvalds } /*end while */ 19761da177e4SLinus Torvalds 19771da177e4SLinus Torvalds MENABLE_INT(ioport); 19781da177e4SLinus Torvalds 19795c1b85e2SAlexey Dobriyan return 0; 19801da177e4SLinus Torvalds } 19811da177e4SLinus Torvalds 19821da177e4SLinus Torvalds /*--------------------------------------------------------------------- 19831da177e4SLinus Torvalds * 19841da177e4SLinus Torvalds * Function: Sccb_bad_isr 19851da177e4SLinus Torvalds * 19861da177e4SLinus Torvalds * Description: Some type of interrupt has occurred which is slightly 19871da177e4SLinus Torvalds * out of the ordinary. We will now decode it fully, in 19881da177e4SLinus Torvalds * this routine. This is broken up in an attempt to save 19891da177e4SLinus Torvalds * processing time. 19901da177e4SLinus Torvalds * 19911da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 1992391e2f25SKhalid Aziz static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card, 19935c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard, 19945c04a7b8SAlexey Dobriyan unsigned short p_int) 19951da177e4SLinus Torvalds { 1996db038cf8SAlexey Dobriyan unsigned char temp, ScamFlg; 1997f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 199868d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 19991da177e4SLinus Torvalds 20001da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ext_status) & 20015c04a7b8SAlexey Dobriyan (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) { 20021da177e4SLinus Torvalds 20035c04a7b8SAlexey Dobriyan if (pCurrCard->globalFlags & F_HOST_XFER_ACT) { 20041da177e4SLinus Torvalds 20055c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(p_port, p_card, 20065c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB); 20071da177e4SLinus Torvalds } 20081da177e4SLinus Torvalds 20091da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT) 20101da177e4SLinus Torvalds { 20111da177e4SLinus Torvalds WR_HARPOON(p_port + hp_pci_stat_cfg, 20125c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_pci_stat_cfg) & 20135c04a7b8SAlexey Dobriyan ~REC_MASTER_ABORT)); 20141da177e4SLinus Torvalds 20151da177e4SLinus Torvalds WR_HARPOON(p_port + hp_host_blk_cnt, 0x00); 20161da177e4SLinus Torvalds 20171da177e4SLinus Torvalds } 20181da177e4SLinus Torvalds 20195c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) { 20201da177e4SLinus Torvalds 20211da177e4SLinus Torvalds if (!pCurrCard->currentSCCB->HostStatus) 20225c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB->HostStatus = 20235c04a7b8SAlexey Dobriyan SCCB_BM_ERR; 20241da177e4SLinus Torvalds 202547b5d69cSJames Bottomley FPT_sxfrp(p_port, p_card); 20261da177e4SLinus Torvalds 2027db038cf8SAlexey Dobriyan temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) & 20281da177e4SLinus Torvalds (EXT_ARB_ACK | SCSI_TERM_ENA_H)); 20295c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_ee_ctrl, 20305c04a7b8SAlexey Dobriyan ((unsigned char)temp | SEE_MS | SEE_CS)); 20311da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, temp); 20321da177e4SLinus Torvalds 20335c04a7b8SAlexey Dobriyan if (! 20345c04a7b8SAlexey Dobriyan (RDW_HARPOON((p_port + hp_intstat)) & 20355c04a7b8SAlexey Dobriyan (BUS_FREE | RESET))) { 203647b5d69cSJames Bottomley FPT_phaseDecode(p_port, p_card); 20371da177e4SLinus Torvalds } 20381da177e4SLinus Torvalds } 20391da177e4SLinus Torvalds } 20401da177e4SLinus Torvalds 20415c04a7b8SAlexey Dobriyan else if (p_int & RESET) { 20421da177e4SLinus Torvalds 20431da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT); 20441da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, 0x00); 20451da177e4SLinus Torvalds if (pCurrCard->currentSCCB != NULL) { 20461da177e4SLinus Torvalds 20471da177e4SLinus Torvalds if (pCurrCard->globalFlags & F_HOST_XFER_ACT) 20481da177e4SLinus Torvalds 20495c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(p_port, p_card, 20505c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB); 20511da177e4SLinus Torvalds } 20521da177e4SLinus Torvalds 20531da177e4SLinus Torvalds DISABLE_AUTO(p_port); 20541da177e4SLinus Torvalds 205547b5d69cSJames Bottomley FPT_sresb(p_port, p_card); 20561da177e4SLinus Torvalds 20575c04a7b8SAlexey Dobriyan while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) { 20585c04a7b8SAlexey Dobriyan } 20591da177e4SLinus Torvalds 20601da177e4SLinus Torvalds pCurrNvRam = pCurrCard->pNvRamInfo; 20611da177e4SLinus Torvalds if (pCurrNvRam) { 20621da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf; 20635c04a7b8SAlexey Dobriyan } else { 20645c04a7b8SAlexey Dobriyan ScamFlg = 20655c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(p_port, 20665c04a7b8SAlexey Dobriyan SCAM_CONFIG / 2); 20671da177e4SLinus Torvalds } 20681da177e4SLinus Torvalds 206947b5d69cSJames Bottomley FPT_XbowInit(p_port, ScamFlg); 20701da177e4SLinus Torvalds 207147b5d69cSJames Bottomley FPT_scini(p_card, pCurrCard->ourId, 0); 20721da177e4SLinus Torvalds 20735c1b85e2SAlexey Dobriyan return 0xFF; 20741da177e4SLinus Torvalds } 20751da177e4SLinus Torvalds 20761da177e4SLinus Torvalds else if (p_int & FIFO) { 20771da177e4SLinus Torvalds 20781da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), FIFO); 20791da177e4SLinus Torvalds 20801da177e4SLinus Torvalds if (pCurrCard->currentSCCB != NULL) 208147b5d69cSJames Bottomley FPT_sxfrp(p_port, p_card); 20821da177e4SLinus Torvalds } 20831da177e4SLinus Torvalds 20845c04a7b8SAlexey Dobriyan else if (p_int & TIMEOUT) { 20851da177e4SLinus Torvalds 20861da177e4SLinus Torvalds DISABLE_AUTO(p_port); 20871da177e4SLinus Torvalds 20881da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), 20895c04a7b8SAlexey Dobriyan (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE | 20905c04a7b8SAlexey Dobriyan IUNKWN)); 20911da177e4SLinus Torvalds 20921da177e4SLinus Torvalds pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT; 20931da177e4SLinus Torvalds 20945c04a7b8SAlexey Dobriyan currTar_Info = 20955c04a7b8SAlexey Dobriyan &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; 20965c04a7b8SAlexey Dobriyan if ((pCurrCard->globalFlags & F_CONLUN_IO) 20975c04a7b8SAlexey Dobriyan && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != 20985c04a7b8SAlexey Dobriyan TAG_Q_TRYING)) 20995c04a7b8SAlexey Dobriyan currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 21005c04a7b8SAlexey Dobriyan 0; 21011da177e4SLinus Torvalds else 210247b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 0; 21031da177e4SLinus Torvalds 21045c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_SYNC_MASK) { 21051da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0; 21061da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK; 21071da177e4SLinus Torvalds } 21081da177e4SLinus Torvalds 21095c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_WIDE_SCSI) { 21101da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK; 21111da177e4SLinus Torvalds } 21121da177e4SLinus Torvalds 21135c04a7b8SAlexey Dobriyan FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI, 21145c04a7b8SAlexey Dobriyan currTar_Info); 21151da177e4SLinus Torvalds 211647b5d69cSJames Bottomley FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card); 21171da177e4SLinus Torvalds 21181da177e4SLinus Torvalds } 21191da177e4SLinus Torvalds 21205c04a7b8SAlexey Dobriyan else if (p_int & SCAM_SEL) { 21211da177e4SLinus Torvalds 212247b5d69cSJames Bottomley FPT_scarb(p_port, LEVEL2_TAR); 212347b5d69cSJames Bottomley FPT_scsel(p_port); 212447b5d69cSJames Bottomley FPT_scasid(p_card, p_port); 21251da177e4SLinus Torvalds 212647b5d69cSJames Bottomley FPT_scbusf(p_port); 21271da177e4SLinus Torvalds 21281da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), SCAM_SEL); 21291da177e4SLinus Torvalds } 21301da177e4SLinus Torvalds 21315c1b85e2SAlexey Dobriyan return 0x00; 21321da177e4SLinus Torvalds } 21331da177e4SLinus Torvalds 21341da177e4SLinus Torvalds /*--------------------------------------------------------------------- 21351da177e4SLinus Torvalds * 21361da177e4SLinus Torvalds * Function: SccbMgrTableInit 21371da177e4SLinus Torvalds * 21381da177e4SLinus Torvalds * Description: Initialize all Sccb manager data structures. 21391da177e4SLinus Torvalds * 21401da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 21411da177e4SLinus Torvalds 2142cd9d715cSSudip Mukherjee static void FPT_SccbMgrTableInitAll(void) 21431da177e4SLinus Torvalds { 2144db038cf8SAlexey Dobriyan unsigned char thisCard; 21451da177e4SLinus Torvalds 21465c04a7b8SAlexey Dobriyan for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) { 214747b5d69cSJames Bottomley FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard); 21481da177e4SLinus Torvalds 214947b5d69cSJames Bottomley FPT_BL_Card[thisCard].ioPort = 0x00; 215047b5d69cSJames Bottomley FPT_BL_Card[thisCard].cardInfo = NULL; 215147b5d69cSJames Bottomley FPT_BL_Card[thisCard].cardIndex = 0xFF; 215247b5d69cSJames Bottomley FPT_BL_Card[thisCard].ourId = 0x00; 215347b5d69cSJames Bottomley FPT_BL_Card[thisCard].pNvRamInfo = NULL; 21541da177e4SLinus Torvalds } 21551da177e4SLinus Torvalds } 21561da177e4SLinus Torvalds 21571da177e4SLinus Torvalds /*--------------------------------------------------------------------- 21581da177e4SLinus Torvalds * 21591da177e4SLinus Torvalds * Function: SccbMgrTableInit 21601da177e4SLinus Torvalds * 21611da177e4SLinus Torvalds * Description: Initialize all Sccb manager data structures. 21621da177e4SLinus Torvalds * 21631da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 21641da177e4SLinus Torvalds 21655c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard, 21665c04a7b8SAlexey Dobriyan unsigned char p_card) 21671da177e4SLinus Torvalds { 2168db038cf8SAlexey Dobriyan unsigned char scsiID, qtag; 21691da177e4SLinus Torvalds 21705c04a7b8SAlexey Dobriyan for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { 217147b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; 21721da177e4SLinus Torvalds } 21731da177e4SLinus Torvalds 21745c04a7b8SAlexey Dobriyan for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) { 217547b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0; 217647b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0; 217747b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, scsiID); 21781da177e4SLinus Torvalds } 21791da177e4SLinus Torvalds 21801da177e4SLinus Torvalds pCurrCard->scanIndex = 0x00; 21811da177e4SLinus Torvalds pCurrCard->currentSCCB = NULL; 21821da177e4SLinus Torvalds pCurrCard->globalFlags = 0x00; 21831da177e4SLinus Torvalds pCurrCard->cmdCounter = 0x00; 21841da177e4SLinus Torvalds pCurrCard->tagQ_Lst = 0x01; 21851da177e4SLinus Torvalds pCurrCard->discQCount = 0; 21861da177e4SLinus Torvalds 21871da177e4SLinus Torvalds } 21881da177e4SLinus Torvalds 21891da177e4SLinus Torvalds /*--------------------------------------------------------------------- 21901da177e4SLinus Torvalds * 21911da177e4SLinus Torvalds * Function: SccbMgrTableInit 21921da177e4SLinus Torvalds * 21931da177e4SLinus Torvalds * Description: Initialize all Sccb manager data structures. 21941da177e4SLinus Torvalds * 21951da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 21961da177e4SLinus Torvalds 21975c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitTarget(unsigned char p_card, 21985c04a7b8SAlexey Dobriyan unsigned char target) 21991da177e4SLinus Torvalds { 22001da177e4SLinus Torvalds 2201db038cf8SAlexey Dobriyan unsigned char lun, qtag; 2202f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 22031da177e4SLinus Torvalds 220447b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][target]; 22051da177e4SLinus Torvalds 22061da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt = 0; 22071da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0; 22081da177e4SLinus Torvalds 22091da177e4SLinus Torvalds currTar_Info->TarSelQ_Head = NULL; 22101da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = NULL; 22111da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt = 0; 221247b5d69cSJames Bottomley currTar_Info->TarLUN_CA = 0; 22131da177e4SLinus Torvalds 22145c04a7b8SAlexey Dobriyan for (lun = 0; lun < MAX_LUN; lun++) { 221547b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 0; 22161da177e4SLinus Torvalds currTar_Info->LunDiscQ_Idx[lun] = 0; 22171da177e4SLinus Torvalds } 22181da177e4SLinus Torvalds 22195c04a7b8SAlexey Dobriyan for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { 22205c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) { 22215c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == 22225c04a7b8SAlexey Dobriyan target) { 222347b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; 222447b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--; 22251da177e4SLinus Torvalds } 22261da177e4SLinus Torvalds } 22271da177e4SLinus Torvalds } 22281da177e4SLinus Torvalds } 22291da177e4SLinus Torvalds 22301da177e4SLinus Torvalds /*--------------------------------------------------------------------- 22311da177e4SLinus Torvalds * 22321da177e4SLinus Torvalds * Function: sfetm 22331da177e4SLinus Torvalds * 22341da177e4SLinus Torvalds * Description: Read in a message byte from the SCSI bus, and check 22351da177e4SLinus Torvalds * for a parity error. 22361da177e4SLinus Torvalds * 22371da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 22381da177e4SLinus Torvalds 2239391e2f25SKhalid Aziz static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB) 22401da177e4SLinus Torvalds { 2241db038cf8SAlexey Dobriyan unsigned char message; 2242c823feebSAlexey Dobriyan unsigned short TimeOutLoop; 22431da177e4SLinus Torvalds 22441da177e4SLinus Torvalds TimeOutLoop = 0; 22451da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && 22465c04a7b8SAlexey Dobriyan (TimeOutLoop++ < 20000)) { 22475c04a7b8SAlexey Dobriyan } 22481da177e4SLinus Torvalds 22491da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 22501da177e4SLinus Torvalds 22511da177e4SLinus Torvalds message = RD_HARPOON(port + hp_scsidata_0); 22521da177e4SLinus Torvalds 22531da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH); 22541da177e4SLinus Torvalds 22551da177e4SLinus Torvalds if (TimeOutLoop > 20000) 22561da177e4SLinus Torvalds message = 0x00; /* force message byte = 0 if Time Out on Req */ 22571da177e4SLinus Torvalds 22581da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && 22595c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) { 22601da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); 22611da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0); 22621da177e4SLinus Torvalds WR_HARPOON(port + hp_fiforead, 0); 22631da177e4SLinus Torvalds WR_HARPOON(port + hp_fifowrite, 0); 22645c04a7b8SAlexey Dobriyan if (pCurrSCCB != NULL) { 22651da177e4SLinus Torvalds pCurrSCCB->Sccb_scsimsg = SMPARITY; 22661da177e4SLinus Torvalds } 22671da177e4SLinus Torvalds message = 0x00; 22685c04a7b8SAlexey Dobriyan do { 22691da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 22701da177e4SLinus Torvalds TimeOutLoop = 0; 22711da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && 22725c04a7b8SAlexey Dobriyan (TimeOutLoop++ < 20000)) { 22735c04a7b8SAlexey Dobriyan } 22745c04a7b8SAlexey Dobriyan if (TimeOutLoop > 20000) { 22751da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY); 22765c1b85e2SAlexey Dobriyan return message; 22771da177e4SLinus Torvalds } 22785c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) != 22795c04a7b8SAlexey Dobriyan S_MSGI_PH) { 22801da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY); 22815c1b85e2SAlexey Dobriyan return message; 22821da177e4SLinus Torvalds } 22831da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 22841da177e4SLinus Torvalds 22851da177e4SLinus Torvalds RD_HARPOON(port + hp_scsidata_0); 22861da177e4SLinus Torvalds 22871da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); 22881da177e4SLinus Torvalds 22891da177e4SLinus Torvalds } while (1); 22901da177e4SLinus Torvalds 22911da177e4SLinus Torvalds } 22921da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); 22931da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0); 22941da177e4SLinus Torvalds WR_HARPOON(port + hp_fiforead, 0); 22951da177e4SLinus Torvalds WR_HARPOON(port + hp_fifowrite, 0); 22965c1b85e2SAlexey Dobriyan return message; 22971da177e4SLinus Torvalds } 22981da177e4SLinus Torvalds 22991da177e4SLinus Torvalds /*--------------------------------------------------------------------- 23001da177e4SLinus Torvalds * 230147b5d69cSJames Bottomley * Function: FPT_ssel 23021da177e4SLinus Torvalds * 23031da177e4SLinus Torvalds * Description: Load up automation and select target device. 23041da177e4SLinus Torvalds * 23051da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 23061da177e4SLinus Torvalds 2307391e2f25SKhalid Aziz static void FPT_ssel(u32 port, unsigned char p_card) 23081da177e4SLinus Torvalds { 23091da177e4SLinus Torvalds 2310db038cf8SAlexey Dobriyan unsigned char auto_loaded, i, target, *theCCB; 23111da177e4SLinus Torvalds 2312391e2f25SKhalid Aziz u32 cdb_reg; 231313e6851aSAlexey Dobriyan struct sccb_card *CurrCard; 231469eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 2315f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 2316db038cf8SAlexey Dobriyan unsigned char lastTag, lun; 23171da177e4SLinus Torvalds 231847b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[p_card]; 23191da177e4SLinus Torvalds currSCCB = CurrCard->currentSCCB; 23201da177e4SLinus Torvalds target = currSCCB->TargID; 232147b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][target]; 23221da177e4SLinus Torvalds lastTag = CurrCard->tagQ_Lst; 23231da177e4SLinus Torvalds 23241da177e4SLinus Torvalds ARAM_ACCESS(port); 23251da177e4SLinus Torvalds 23261da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT) 23271da177e4SLinus Torvalds currSCCB->ControlByte &= ~F_USE_CMD_Q; 23281da177e4SLinus Torvalds 23291da177e4SLinus Torvalds if (((CurrCard->globalFlags & F_CONLUN_IO) && 23301da177e4SLinus Torvalds ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) 23311da177e4SLinus Torvalds 23321da177e4SLinus Torvalds lun = currSCCB->Lun; 23331da177e4SLinus Torvalds else 23341da177e4SLinus Torvalds lun = 0; 23351da177e4SLinus Torvalds 23365c04a7b8SAlexey Dobriyan if (CurrCard->globalFlags & F_TAG_STARTED) { 23375c04a7b8SAlexey Dobriyan if (!(currSCCB->ControlByte & F_USE_CMD_Q)) { 233847b5d69cSJames Bottomley if ((currTar_Info->TarLUN_CA == 0) 23391da177e4SLinus Torvalds && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) 23405c04a7b8SAlexey Dobriyan == TAG_Q_TRYING)) { 23411da177e4SLinus Torvalds 23425c04a7b8SAlexey Dobriyan if (currTar_Info->TarTagQ_Cnt != 0) { 234347b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 234447b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card); 23451da177e4SLinus Torvalds SGRAM_ACCESS(port); 23461da177e4SLinus Torvalds return; 23471da177e4SLinus Torvalds } 23481da177e4SLinus Torvalds 23491da177e4SLinus Torvalds else { 235047b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 23511da177e4SLinus Torvalds } 23521da177e4SLinus Torvalds 23535c04a7b8SAlexey Dobriyan } 23545c04a7b8SAlexey Dobriyan /*End non-tagged */ 23551da177e4SLinus Torvalds else { 235647b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 23571da177e4SLinus Torvalds } 23581da177e4SLinus Torvalds 23595c04a7b8SAlexey Dobriyan } 23605c04a7b8SAlexey Dobriyan /*!Use cmd Q Tagged */ 23611da177e4SLinus Torvalds else { 23625c04a7b8SAlexey Dobriyan if (currTar_Info->TarLUN_CA == 1) { 236347b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card); 23641da177e4SLinus Torvalds SGRAM_ACCESS(port); 23651da177e4SLinus Torvalds return; 23661da177e4SLinus Torvalds } 23671da177e4SLinus Torvalds 236847b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 23691da177e4SLinus Torvalds 23701da177e4SLinus Torvalds } /*else use cmd Q tagged */ 23711da177e4SLinus Torvalds 23725c04a7b8SAlexey Dobriyan } 23735c04a7b8SAlexey Dobriyan /*if glob tagged started */ 23741da177e4SLinus Torvalds else { 237547b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 23761da177e4SLinus Torvalds } 23771da177e4SLinus Torvalds 23781da177e4SLinus Torvalds if ((((CurrCard->globalFlags & F_CONLUN_IO) && 23791da177e4SLinus Torvalds ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) 23805c04a7b8SAlexey Dobriyan || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) { 23815c04a7b8SAlexey Dobriyan if (CurrCard->discQCount >= QUEUE_DEPTH) { 238247b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 238347b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card); 23841da177e4SLinus Torvalds SGRAM_ACCESS(port); 23851da177e4SLinus Torvalds return; 23861da177e4SLinus Torvalds } 23875c04a7b8SAlexey Dobriyan for (i = 1; i < QUEUE_DEPTH; i++) { 23885c04a7b8SAlexey Dobriyan if (++lastTag >= QUEUE_DEPTH) 23895c04a7b8SAlexey Dobriyan lastTag = 1; 23905c04a7b8SAlexey Dobriyan if (CurrCard->discQ_Tbl[lastTag] == NULL) { 23911da177e4SLinus Torvalds CurrCard->tagQ_Lst = lastTag; 23921da177e4SLinus Torvalds currTar_Info->LunDiscQ_Idx[lun] = lastTag; 23931da177e4SLinus Torvalds CurrCard->discQ_Tbl[lastTag] = currSCCB; 23941da177e4SLinus Torvalds CurrCard->discQCount++; 23951da177e4SLinus Torvalds break; 23961da177e4SLinus Torvalds } 23971da177e4SLinus Torvalds } 23985c04a7b8SAlexey Dobriyan if (i == QUEUE_DEPTH) { 239947b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 240047b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card); 24011da177e4SLinus Torvalds SGRAM_ACCESS(port); 24021da177e4SLinus Torvalds return; 24031da177e4SLinus Torvalds } 24041da177e4SLinus Torvalds } 24051da177e4SLinus Torvalds 240647b5d69cSJames Bottomley auto_loaded = 0; 24071da177e4SLinus Torvalds 24081da177e4SLinus Torvalds WR_HARPOON(port + hp_select_id, target); 24091da177e4SLinus Torvalds WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */ 24101da177e4SLinus Torvalds 24111da177e4SLinus Torvalds if (currSCCB->OperationCode == RESET_COMMAND) { 24121da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT + 24135c04a7b8SAlexey Dobriyan (currSCCB-> 24145c04a7b8SAlexey Dobriyan Sccb_idmsg & ~DISC_PRIV))); 24151da177e4SLinus Torvalds 24161da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP); 24171da177e4SLinus Torvalds 24181da177e4SLinus Torvalds currSCCB->Sccb_scsimsg = SMDEV_RESET; 24191da177e4SLinus Torvalds 24201da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); 242147b5d69cSJames Bottomley auto_loaded = 1; 24221da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_BDR_ST; 24231da177e4SLinus Torvalds 24245c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_SYNC_MASK) { 24251da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0; 24261da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK; 24271da177e4SLinus Torvalds } 24281da177e4SLinus Torvalds 24295c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_WIDE_SCSI) { 24301da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK; 24311da177e4SLinus Torvalds } 24321da177e4SLinus Torvalds 243347b5d69cSJames Bottomley FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info); 243447b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, target); 24351da177e4SLinus Torvalds 24361da177e4SLinus Torvalds } 24371da177e4SLinus Torvalds 24385c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == ABORT_ST) { 24391da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT + 24405c04a7b8SAlexey Dobriyan (currSCCB-> 24415c04a7b8SAlexey Dobriyan Sccb_idmsg & ~DISC_PRIV))); 24421da177e4SLinus Torvalds 24431da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); 24441da177e4SLinus Torvalds 24451da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + 24465c04a7b8SAlexey Dobriyan (((unsigned 24475c04a7b8SAlexey Dobriyan char)(currSCCB-> 24485c04a7b8SAlexey Dobriyan ControlByte & 24495c04a7b8SAlexey Dobriyan TAG_TYPE_MASK) 24505c04a7b8SAlexey Dobriyan >> 6) | (unsigned char) 24515c04a7b8SAlexey Dobriyan 0x20))); 24521da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), 24531da177e4SLinus Torvalds (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag)); 24541da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP)); 24551da177e4SLinus Torvalds 24561da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); 245747b5d69cSJames Bottomley auto_loaded = 1; 24581da177e4SLinus Torvalds 24591da177e4SLinus Torvalds } 24601da177e4SLinus Torvalds 24611da177e4SLinus Torvalds else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) { 246247b5d69cSJames Bottomley auto_loaded = FPT_siwidn(port, p_card); 24631da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_WN_ST; 24641da177e4SLinus Torvalds } 24651da177e4SLinus Torvalds 24661da177e4SLinus Torvalds else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) 24671da177e4SLinus Torvalds == SYNC_SUPPORTED)) { 246847b5d69cSJames Bottomley auto_loaded = FPT_sisyncn(port, p_card, 0); 24691da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_SN_ST; 24701da177e4SLinus Torvalds } 24711da177e4SLinus Torvalds 24725c04a7b8SAlexey Dobriyan if (!auto_loaded) { 24731da177e4SLinus Torvalds 24745c04a7b8SAlexey Dobriyan if (currSCCB->ControlByte & F_USE_CMD_Q) { 24751da177e4SLinus Torvalds 24761da177e4SLinus Torvalds CurrCard->globalFlags |= F_TAG_STARTED; 24771da177e4SLinus Torvalds 24781da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) 24795c04a7b8SAlexey Dobriyan == TAG_Q_REJECT) { 24801da177e4SLinus Torvalds currSCCB->ControlByte &= ~F_USE_CMD_Q; 24811da177e4SLinus Torvalds 24821da177e4SLinus Torvalds /* Fix up the start instruction with a jump to 24831da177e4SLinus Torvalds Non-Tag-CMD handling */ 24845c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT), 24855c04a7b8SAlexey Dobriyan BRH_OP + ALWAYS + NTCMD); 24861da177e4SLinus Torvalds 24871da177e4SLinus Torvalds WRW_HARPOON((port + NON_TAG_ID_MSG), 24885c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 24895c04a7b8SAlexey Dobriyan currSCCB->Sccb_idmsg)); 24901da177e4SLinus Torvalds 24915c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3, 24925c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT)); 24931da177e4SLinus Torvalds 249425985edcSLucas De Marchi /* Setup our STATE so we know what happened when 24951da177e4SLinus Torvalds the wheels fall off. */ 24961da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_ST; 24971da177e4SLinus Torvalds 249847b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 24991da177e4SLinus Torvalds } 25001da177e4SLinus Torvalds 25015c04a7b8SAlexey Dobriyan else { 25025c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT), 25035c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 25045c04a7b8SAlexey Dobriyan currSCCB->Sccb_idmsg)); 25051da177e4SLinus Torvalds 25065c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT + 2), 25075c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 25085c04a7b8SAlexey Dobriyan (((unsigned char)(currSCCB-> 25095c04a7b8SAlexey Dobriyan ControlByte & 25105c04a7b8SAlexey Dobriyan TAG_TYPE_MASK) 2511db038cf8SAlexey Dobriyan >> 6) | (unsigned char)0x20))); 25121da177e4SLinus Torvalds 25135c04a7b8SAlexey Dobriyan for (i = 1; i < QUEUE_DEPTH; i++) { 25145c04a7b8SAlexey Dobriyan if (++lastTag >= QUEUE_DEPTH) 25155c04a7b8SAlexey Dobriyan lastTag = 1; 25165c04a7b8SAlexey Dobriyan if (CurrCard->discQ_Tbl[lastTag] == 25175c04a7b8SAlexey Dobriyan NULL) { 25185c04a7b8SAlexey Dobriyan WRW_HARPOON((port + 25195c04a7b8SAlexey Dobriyan ID_MSG_STRT + 6), 25205c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 25215c04a7b8SAlexey Dobriyan lastTag)); 25221da177e4SLinus Torvalds CurrCard->tagQ_Lst = lastTag; 25231da177e4SLinus Torvalds currSCCB->Sccb_tag = lastTag; 25245c04a7b8SAlexey Dobriyan CurrCard->discQ_Tbl[lastTag] = 25255c04a7b8SAlexey Dobriyan currSCCB; 25261da177e4SLinus Torvalds CurrCard->discQCount++; 25271da177e4SLinus Torvalds break; 25281da177e4SLinus Torvalds } 25291da177e4SLinus Torvalds } 25301da177e4SLinus Torvalds 25315c04a7b8SAlexey Dobriyan if (i == QUEUE_DEPTH) { 253247b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 253347b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card); 25341da177e4SLinus Torvalds SGRAM_ACCESS(port); 25351da177e4SLinus Torvalds return; 25361da177e4SLinus Torvalds } 25371da177e4SLinus Torvalds 25381da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_Q_ST; 25391da177e4SLinus Torvalds 25405c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3, 25415c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT)); 25421da177e4SLinus Torvalds } 25431da177e4SLinus Torvalds } 25441da177e4SLinus Torvalds 25455c04a7b8SAlexey Dobriyan else { 25461da177e4SLinus Torvalds 25475c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT), 25485c04a7b8SAlexey Dobriyan BRH_OP + ALWAYS + NTCMD); 25491da177e4SLinus Torvalds 25501da177e4SLinus Torvalds WRW_HARPOON((port + NON_TAG_ID_MSG), 25511da177e4SLinus Torvalds (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg)); 25521da177e4SLinus Torvalds 25531da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_ST; 25541da177e4SLinus Torvalds 25555c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3, 25565c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT)); 25571da177e4SLinus Torvalds } 25581da177e4SLinus Torvalds 2559db038cf8SAlexey Dobriyan theCCB = (unsigned char *)&currSCCB->Cdb[0]; 25601da177e4SLinus Torvalds 25611da177e4SLinus Torvalds cdb_reg = port + CMD_STRT; 25621da177e4SLinus Torvalds 25635c04a7b8SAlexey Dobriyan for (i = 0; i < currSCCB->CdbLength; i++) { 25641da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB)); 25651da177e4SLinus Torvalds cdb_reg += 2; 25661da177e4SLinus Torvalds theCCB++; 25671da177e4SLinus Torvalds } 25681da177e4SLinus Torvalds 25691da177e4SLinus Torvalds if (currSCCB->CdbLength != TWELVE_BYTE_CMD) 25701da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP)); 25711da177e4SLinus Torvalds 25725c04a7b8SAlexey Dobriyan } 25735c04a7b8SAlexey Dobriyan /* auto_loaded */ 2574c823feebSAlexey Dobriyan WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); 25751da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0x00); 25761da177e4SLinus Torvalds 25771da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE)); 25781da177e4SLinus Torvalds 25791da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT)); 25801da177e4SLinus Torvalds 25815c04a7b8SAlexey Dobriyan if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) { 25825c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_scsictrl_0, 25835c04a7b8SAlexey Dobriyan (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL)); 25845c04a7b8SAlexey Dobriyan } else { 25851da177e4SLinus Torvalds 2586db038cf8SAlexey Dobriyan /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F); 25871da177e4SLinus Torvalds auto_loaded |= AUTO_IMMED; */ 25881da177e4SLinus Torvalds auto_loaded = AUTO_IMMED; 25891da177e4SLinus Torvalds 25901da177e4SLinus Torvalds DISABLE_AUTO(port); 25911da177e4SLinus Torvalds 25921da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, auto_loaded); 25931da177e4SLinus Torvalds } 25941da177e4SLinus Torvalds 25951da177e4SLinus Torvalds SGRAM_ACCESS(port); 25961da177e4SLinus Torvalds } 25971da177e4SLinus Torvalds 25981da177e4SLinus Torvalds /*--------------------------------------------------------------------- 25991da177e4SLinus Torvalds * 260047b5d69cSJames Bottomley * Function: FPT_sres 26011da177e4SLinus Torvalds * 26021da177e4SLinus Torvalds * Description: Hookup the correct CCB and handle the incoming messages. 26031da177e4SLinus Torvalds * 26041da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 26051da177e4SLinus Torvalds 2606391e2f25SKhalid Aziz static void FPT_sres(u32 port, unsigned char p_card, 26075c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard) 26081da177e4SLinus Torvalds { 26091da177e4SLinus Torvalds 2610db038cf8SAlexey Dobriyan unsigned char our_target, message, lun = 0, tag, msgRetryCount; 26111da177e4SLinus Torvalds 2612f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 261369eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 26141da177e4SLinus Torvalds 26155c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) { 26165c04a7b8SAlexey Dobriyan currTar_Info = 26175c04a7b8SAlexey Dobriyan &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; 26181da177e4SLinus Torvalds DISABLE_AUTO(port); 26191da177e4SLinus Torvalds 26201da177e4SLinus Torvalds WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL)); 26211da177e4SLinus Torvalds 26221da177e4SLinus Torvalds currSCCB = pCurrCard->currentSCCB; 26235c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { 26241da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK; 26251da177e4SLinus Torvalds currSCCB->Sccb_scsistat = BUS_FREE_ST; 26261da177e4SLinus Torvalds } 26275c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { 26281da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK; 26291da177e4SLinus Torvalds currSCCB->Sccb_scsistat = BUS_FREE_ST; 26301da177e4SLinus Torvalds } 26311da177e4SLinus Torvalds if (((pCurrCard->globalFlags & F_CONLUN_IO) && 26325c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != 26335c04a7b8SAlexey Dobriyan TAG_Q_TRYING))) { 263447b5d69cSJames Bottomley currTar_Info->TarLUNBusy[currSCCB->Lun] = 0; 26355c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat != ABORT_ST) { 26361da177e4SLinus Torvalds pCurrCard->discQCount--; 26375c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info-> 26385c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB-> 26395c04a7b8SAlexey Dobriyan Lun]] 26401da177e4SLinus Torvalds = NULL; 26411da177e4SLinus Torvalds } 26425c04a7b8SAlexey Dobriyan } else { 264347b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 0; 26445c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) { 26455c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat != ABORT_ST) { 26461da177e4SLinus Torvalds pCurrCard->discQCount--; 26475c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currSCCB-> 26485c04a7b8SAlexey Dobriyan Sccb_tag] = NULL; 26491da177e4SLinus Torvalds } 26505c04a7b8SAlexey Dobriyan } else { 26515c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat != ABORT_ST) { 26521da177e4SLinus Torvalds pCurrCard->discQCount--; 26535c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info-> 26545c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = 26555c04a7b8SAlexey Dobriyan NULL; 26561da177e4SLinus Torvalds } 26571da177e4SLinus Torvalds } 26581da177e4SLinus Torvalds } 26591da177e4SLinus Torvalds 266047b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card); 26611da177e4SLinus Torvalds } 26621da177e4SLinus Torvalds 2663c823feebSAlexey Dobriyan WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); 26641da177e4SLinus Torvalds 2665db038cf8SAlexey Dobriyan our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4); 266647b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][our_target]; 26671da177e4SLinus Torvalds 26681da177e4SLinus Torvalds msgRetryCount = 0; 26695c04a7b8SAlexey Dobriyan do { 26701da177e4SLinus Torvalds 267147b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][our_target]; 26721da177e4SLinus Torvalds tag = 0; 26731da177e4SLinus Torvalds 26745c04a7b8SAlexey Dobriyan while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) { 26755c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) { 26761da177e4SLinus Torvalds 26771da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE); 26781da177e4SLinus Torvalds return; 26791da177e4SLinus Torvalds } 26801da177e4SLinus Torvalds } 26811da177e4SLinus Torvalds 26821da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE); 26835c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) { 26841da177e4SLinus Torvalds 268547b5d69cSJames Bottomley message = FPT_sfm(port, pCurrCard->currentSCCB); 26865c04a7b8SAlexey Dobriyan if (message) { 26871da177e4SLinus Torvalds 26885c04a7b8SAlexey Dobriyan if (message <= (0x80 | LUN_MASK)) { 2689db038cf8SAlexey Dobriyan lun = message & (unsigned char)LUN_MASK; 26901da177e4SLinus Torvalds 26915c04a7b8SAlexey Dobriyan if ((currTar_Info-> 26925c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) == 26935c04a7b8SAlexey Dobriyan TAG_Q_TRYING) { 26945c04a7b8SAlexey Dobriyan if (currTar_Info->TarTagQ_Cnt != 26955c04a7b8SAlexey Dobriyan 0) { 26961da177e4SLinus Torvalds 26975c04a7b8SAlexey Dobriyan if (! 26985c04a7b8SAlexey Dobriyan (currTar_Info-> 26995c04a7b8SAlexey Dobriyan TarLUN_CA)) { 27001da177e4SLinus Torvalds ACCEPT_MSG(port); /*Release the ACK for ID msg. */ 27011da177e4SLinus Torvalds 27025c04a7b8SAlexey Dobriyan message = 27035c04a7b8SAlexey Dobriyan FPT_sfm 27045c04a7b8SAlexey Dobriyan (port, 27055c04a7b8SAlexey Dobriyan pCurrCard-> 27065c04a7b8SAlexey Dobriyan currentSCCB); 27075c04a7b8SAlexey Dobriyan if (message) { 27085c04a7b8SAlexey Dobriyan ACCEPT_MSG 27095c04a7b8SAlexey Dobriyan (port); 27101da177e4SLinus Torvalds } 27111da177e4SLinus Torvalds 27121da177e4SLinus Torvalds else 27135c04a7b8SAlexey Dobriyan message 27145c04a7b8SAlexey Dobriyan = 0; 27151da177e4SLinus Torvalds 27165c04a7b8SAlexey Dobriyan if (message != 27175c04a7b8SAlexey Dobriyan 0) { 27185c04a7b8SAlexey Dobriyan tag = 27195c04a7b8SAlexey Dobriyan FPT_sfm 27205c04a7b8SAlexey Dobriyan (port, 27215c04a7b8SAlexey Dobriyan pCurrCard-> 27225c04a7b8SAlexey Dobriyan currentSCCB); 27231da177e4SLinus Torvalds 27245c04a7b8SAlexey Dobriyan if (! 27255c04a7b8SAlexey Dobriyan (tag)) 27265c04a7b8SAlexey Dobriyan message 27275c04a7b8SAlexey Dobriyan = 27285c04a7b8SAlexey Dobriyan 0; 27291da177e4SLinus Torvalds } 27301da177e4SLinus Torvalds 27315c04a7b8SAlexey Dobriyan } 27325c04a7b8SAlexey Dobriyan /*C.A. exists! */ 27335c04a7b8SAlexey Dobriyan } 27345c04a7b8SAlexey Dobriyan /*End Q cnt != 0 */ 27355c04a7b8SAlexey Dobriyan } 27365c04a7b8SAlexey Dobriyan /*End Tag cmds supported! */ 27375c04a7b8SAlexey Dobriyan } 27385c04a7b8SAlexey Dobriyan /*End valid ID message. */ 27395c04a7b8SAlexey Dobriyan else { 27401da177e4SLinus Torvalds 27411da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 27421da177e4SLinus Torvalds } 27431da177e4SLinus Torvalds 27445c04a7b8SAlexey Dobriyan } 27455c04a7b8SAlexey Dobriyan /* End good id message. */ 27465c04a7b8SAlexey Dobriyan else { 27471da177e4SLinus Torvalds 274847b5d69cSJames Bottomley message = 0; 27491da177e4SLinus Torvalds } 27505c04a7b8SAlexey Dobriyan } else { 27511da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 27521da177e4SLinus Torvalds 27535c04a7b8SAlexey Dobriyan while (! 27545c04a7b8SAlexey Dobriyan (RDW_HARPOON((port + hp_intstat)) & 27555c04a7b8SAlexey Dobriyan (PHASE | RESET)) 27565c04a7b8SAlexey Dobriyan && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) 27575c04a7b8SAlexey Dobriyan && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ; 27581da177e4SLinus Torvalds 27591da177e4SLinus Torvalds return; 27601da177e4SLinus Torvalds } 27611da177e4SLinus Torvalds 27625c04a7b8SAlexey Dobriyan if (message == 0) { 27631da177e4SLinus Torvalds msgRetryCount++; 27645c04a7b8SAlexey Dobriyan if (msgRetryCount == 1) { 276547b5d69cSJames Bottomley FPT_SendMsg(port, SMPARITY); 27665c04a7b8SAlexey Dobriyan } else { 276747b5d69cSJames Bottomley FPT_SendMsg(port, SMDEV_RESET); 27681da177e4SLinus Torvalds 27695c04a7b8SAlexey Dobriyan FPT_sssyncv(port, our_target, NARROW_SCSI, 27705c04a7b8SAlexey Dobriyan currTar_Info); 27711da177e4SLinus Torvalds 27725c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][our_target]. 27735c04a7b8SAlexey Dobriyan TarEEValue & EE_SYNC_MASK) { 27741da177e4SLinus Torvalds 27755c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][our_target]. 27765c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_SYNC_MASK; 27771da177e4SLinus Torvalds 27781da177e4SLinus Torvalds } 27791da177e4SLinus Torvalds 27805c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][our_target]. 27815c04a7b8SAlexey Dobriyan TarEEValue & EE_WIDE_SCSI) { 27821da177e4SLinus Torvalds 27835c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][our_target]. 27845c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_WIDE_MASK; 27851da177e4SLinus Torvalds } 27861da177e4SLinus Torvalds 27875c04a7b8SAlexey Dobriyan FPT_queueFlushTargSccb(p_card, our_target, 27885c04a7b8SAlexey Dobriyan SCCB_COMPLETE); 278947b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, our_target); 27901da177e4SLinus Torvalds return; 27911da177e4SLinus Torvalds } 27921da177e4SLinus Torvalds } 279347b5d69cSJames Bottomley } while (message == 0); 27941da177e4SLinus Torvalds 27951da177e4SLinus Torvalds if (((pCurrCard->globalFlags & F_CONLUN_IO) && 27965c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { 279747b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1; 27985c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB = 27995c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]]; 28005c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) { 28011da177e4SLinus Torvalds ACCEPT_MSG(port); 28025c04a7b8SAlexey Dobriyan } else { 28031da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 28041da177e4SLinus Torvalds } 28055c04a7b8SAlexey Dobriyan } else { 280647b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 1; 28071da177e4SLinus Torvalds 28085c04a7b8SAlexey Dobriyan if (tag) { 28095c04a7b8SAlexey Dobriyan if (pCurrCard->discQ_Tbl[tag] != NULL) { 28105c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB = 28115c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[tag]; 28121da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt--; 28131da177e4SLinus Torvalds ACCEPT_MSG(port); 28145c04a7b8SAlexey Dobriyan } else { 28151da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 28161da177e4SLinus Torvalds } 28175c04a7b8SAlexey Dobriyan } else { 28185c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB = 28195c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]]; 28205c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) { 28211da177e4SLinus Torvalds ACCEPT_MSG(port); 28225c04a7b8SAlexey Dobriyan } else { 28231da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 28241da177e4SLinus Torvalds } 28251da177e4SLinus Torvalds } 28261da177e4SLinus Torvalds } 28271da177e4SLinus Torvalds 28285c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) { 28295c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) { 28301da177e4SLinus Torvalds /* During Abort Tag command, the target could have got re-selected 28311da177e4SLinus Torvalds and completed the command. Check the select Q and remove the CCB 28321da177e4SLinus Torvalds if it is in the Select Q */ 283347b5d69cSJames Bottomley FPT_queueFindSccb(pCurrCard->currentSCCB, p_card); 28341da177e4SLinus Torvalds } 28351da177e4SLinus Torvalds } 28361da177e4SLinus Torvalds 28371da177e4SLinus Torvalds while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) && 28381da177e4SLinus Torvalds !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) && 28391da177e4SLinus Torvalds (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ; 28401da177e4SLinus Torvalds } 28411da177e4SLinus Torvalds 2842391e2f25SKhalid Aziz static void FPT_SendMsg(u32 port, unsigned char message) 28431da177e4SLinus Torvalds { 28445c04a7b8SAlexey Dobriyan while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) { 28455c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) { 28461da177e4SLinus Torvalds 28471da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE); 28481da177e4SLinus Torvalds return; 28491da177e4SLinus Torvalds } 28501da177e4SLinus Torvalds } 28511da177e4SLinus Torvalds 28521da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE); 28535c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) { 28545c04a7b8SAlexey Dobriyan WRW_HARPOON((port + hp_intstat), 28555c04a7b8SAlexey Dobriyan (BUS_FREE | PHASE | XFER_CNT_0)); 28561da177e4SLinus Torvalds 28571da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN); 28581da177e4SLinus Torvalds 28591da177e4SLinus Torvalds WR_HARPOON(port + hp_scsidata_0, message); 28601da177e4SLinus Torvalds 28611da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); 28621da177e4SLinus Torvalds 28631da177e4SLinus Torvalds ACCEPT_MSG(port); 28641da177e4SLinus Torvalds 28651da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00); 28661da177e4SLinus Torvalds 28671da177e4SLinus Torvalds if ((message == SMABORT) || (message == SMDEV_RESET) || 28685c04a7b8SAlexey Dobriyan (message == SMABORT_TAG)) { 28695c04a7b8SAlexey Dobriyan while (! 28705c04a7b8SAlexey Dobriyan (RDW_HARPOON((port + hp_intstat)) & 28715c04a7b8SAlexey Dobriyan (BUS_FREE | PHASE))) { 28725c04a7b8SAlexey Dobriyan } 28731da177e4SLinus Torvalds 28745c04a7b8SAlexey Dobriyan if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { 28751da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), BUS_FREE); 28761da177e4SLinus Torvalds } 28771da177e4SLinus Torvalds } 28781da177e4SLinus Torvalds } 28791da177e4SLinus Torvalds } 28801da177e4SLinus Torvalds 28811da177e4SLinus Torvalds /*--------------------------------------------------------------------- 28821da177e4SLinus Torvalds * 288347b5d69cSJames Bottomley * Function: FPT_sdecm 28841da177e4SLinus Torvalds * 288525985edcSLucas De Marchi * Description: Determine the proper response to the message from the 28861da177e4SLinus Torvalds * target device. 28871da177e4SLinus Torvalds * 28881da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 2889391e2f25SKhalid Aziz static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card) 28901da177e4SLinus Torvalds { 289169eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 289213e6851aSAlexey Dobriyan struct sccb_card *CurrCard; 2893f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 28941da177e4SLinus Torvalds 289547b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[p_card]; 28961da177e4SLinus Torvalds currSCCB = CurrCard->currentSCCB; 28971da177e4SLinus Torvalds 289847b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; 28991da177e4SLinus Torvalds 29005c04a7b8SAlexey Dobriyan if (message == SMREST_DATA_PTR) { 29015c04a7b8SAlexey Dobriyan if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) { 29021da177e4SLinus Torvalds currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC; 29031da177e4SLinus Torvalds 290447b5d69cSJames Bottomley FPT_hostDataXferRestart(currSCCB); 29051da177e4SLinus Torvalds } 29061da177e4SLinus Torvalds 29071da177e4SLinus Torvalds ACCEPT_MSG(port); 29085c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 29095c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 29101da177e4SLinus Torvalds } 29111da177e4SLinus Torvalds 29125c04a7b8SAlexey Dobriyan else if (message == SMCMD_COMP) { 29131da177e4SLinus Torvalds 29145c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_Q_ST) { 29155c04a7b8SAlexey Dobriyan currTar_Info->TarStatus &= 29165c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_TAG_Q_MASK; 2917db038cf8SAlexey Dobriyan currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT; 29181da177e4SLinus Torvalds } 29191da177e4SLinus Torvalds 29201da177e4SLinus Torvalds ACCEPT_MSG(port); 29211da177e4SLinus Torvalds 29221da177e4SLinus Torvalds } 29231da177e4SLinus Torvalds 29241da177e4SLinus Torvalds else if ((message == SMNO_OP) || (message >= SMIDENT) 29255c04a7b8SAlexey Dobriyan || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) { 29261da177e4SLinus Torvalds 29271da177e4SLinus Torvalds ACCEPT_MSG(port); 29285c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 29295c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 29301da177e4SLinus Torvalds } 29311da177e4SLinus Torvalds 29325c04a7b8SAlexey Dobriyan else if (message == SMREJECT) { 29331da177e4SLinus Torvalds 29341da177e4SLinus Torvalds if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) || 29351da177e4SLinus Torvalds (currSCCB->Sccb_scsistat == SELECT_WN_ST) || 29365c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING) 29375c04a7b8SAlexey Dobriyan || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == 29385c04a7b8SAlexey Dobriyan TAG_Q_TRYING)) 29391da177e4SLinus Torvalds { 29401da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), BUS_FREE); 29411da177e4SLinus Torvalds 29421da177e4SLinus Torvalds ACCEPT_MSG(port); 29431da177e4SLinus Torvalds 29441da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && 29455c04a7b8SAlexey Dobriyan (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE))) 29461da177e4SLinus Torvalds { 29471da177e4SLinus Torvalds } 29481da177e4SLinus Torvalds 29495c04a7b8SAlexey Dobriyan if (currSCCB->Lun == 0x00) { 2950adb11023SNathan Chancellor if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { 29511da177e4SLinus Torvalds 29525c04a7b8SAlexey Dobriyan currTar_Info->TarStatus |= 29535c04a7b8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED; 29541da177e4SLinus Torvalds 29555c04a7b8SAlexey Dobriyan currTar_Info->TarEEValue &= 29565c04a7b8SAlexey Dobriyan ~EE_SYNC_MASK; 29575c04a7b8SAlexey Dobriyan } 29581da177e4SLinus Torvalds 2959adb11023SNathan Chancellor else if (currSCCB->Sccb_scsistat == 2960adb11023SNathan Chancellor SELECT_WN_ST) { 29615c04a7b8SAlexey Dobriyan 29625c04a7b8SAlexey Dobriyan currTar_Info->TarStatus = 29635c04a7b8SAlexey Dobriyan (currTar_Info-> 29645c04a7b8SAlexey Dobriyan TarStatus & ~WIDE_ENABLED) | 29655c04a7b8SAlexey Dobriyan WIDE_NEGOCIATED; 29665c04a7b8SAlexey Dobriyan 29675c04a7b8SAlexey Dobriyan currTar_Info->TarEEValue &= 29685c04a7b8SAlexey Dobriyan ~EE_WIDE_SCSI; 29691da177e4SLinus Torvalds 29701da177e4SLinus Torvalds } 29711da177e4SLinus Torvalds 29725c04a7b8SAlexey Dobriyan else if ((currTar_Info-> 29735c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) == 29745c04a7b8SAlexey Dobriyan TAG_Q_TRYING) { 29755c04a7b8SAlexey Dobriyan currTar_Info->TarStatus = 29765c04a7b8SAlexey Dobriyan (currTar_Info-> 29775c04a7b8SAlexey Dobriyan TarStatus & ~(unsigned char) 29785c04a7b8SAlexey Dobriyan TAR_TAG_Q_MASK) | TAG_Q_REJECT; 29791da177e4SLinus Torvalds 29801da177e4SLinus Torvalds currSCCB->ControlByte &= ~F_USE_CMD_Q; 29811da177e4SLinus Torvalds CurrCard->discQCount--; 29825c04a7b8SAlexey Dobriyan CurrCard->discQ_Tbl[currSCCB-> 29835c04a7b8SAlexey Dobriyan Sccb_tag] = NULL; 29841da177e4SLinus Torvalds currSCCB->Sccb_tag = 0x00; 29851da177e4SLinus Torvalds 29861da177e4SLinus Torvalds } 29871da177e4SLinus Torvalds } 29881da177e4SLinus Torvalds 29895c04a7b8SAlexey Dobriyan if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { 29901da177e4SLinus Torvalds 29915c04a7b8SAlexey Dobriyan if (currSCCB->Lun == 0x00) { 29925c04a7b8SAlexey Dobriyan WRW_HARPOON((port + hp_intstat), 29935c04a7b8SAlexey Dobriyan BUS_FREE); 29941da177e4SLinus Torvalds CurrCard->globalFlags |= F_NEW_SCCB_CMD; 29951da177e4SLinus Torvalds } 29961da177e4SLinus Torvalds } 29971da177e4SLinus Torvalds 29985c04a7b8SAlexey Dobriyan else { 29991da177e4SLinus Torvalds 30001da177e4SLinus Torvalds if ((CurrCard->globalFlags & F_CONLUN_IO) && 30015c04a7b8SAlexey Dobriyan ((currTar_Info-> 30025c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != 30035c04a7b8SAlexey Dobriyan TAG_Q_TRYING)) 30045c04a7b8SAlexey Dobriyan currTar_Info->TarLUNBusy[currSCCB-> 30055c04a7b8SAlexey Dobriyan Lun] = 1; 30061da177e4SLinus Torvalds else 300747b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 1; 30081da177e4SLinus Torvalds 30095c04a7b8SAlexey Dobriyan currSCCB->ControlByte &= 30105c04a7b8SAlexey Dobriyan ~(unsigned char)F_USE_CMD_Q; 30111da177e4SLinus Torvalds 30125c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 30135c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 30141da177e4SLinus Torvalds 30151da177e4SLinus Torvalds } 30161da177e4SLinus Torvalds } 30171da177e4SLinus Torvalds 30185c04a7b8SAlexey Dobriyan else { 30191da177e4SLinus Torvalds ACCEPT_MSG(port); 30201da177e4SLinus Torvalds 30211da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) && 30225c04a7b8SAlexey Dobriyan (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE))) 30231da177e4SLinus Torvalds { 30245c04a7b8SAlexey Dobriyan } 30255c04a7b8SAlexey Dobriyan 30265c04a7b8SAlexey Dobriyan if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) { 30275c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 30285c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 30291da177e4SLinus Torvalds } 30301da177e4SLinus Torvalds } 30311da177e4SLinus Torvalds } 30321da177e4SLinus Torvalds 30335c04a7b8SAlexey Dobriyan else if (message == SMEXT) { 30341da177e4SLinus Torvalds 30351da177e4SLinus Torvalds ACCEPT_MSG(port); 303647b5d69cSJames Bottomley FPT_shandem(port, p_card, currSCCB); 30371da177e4SLinus Torvalds } 30381da177e4SLinus Torvalds 30395c04a7b8SAlexey Dobriyan else if (message == SMIGNORWR) { 30401da177e4SLinus Torvalds 30411da177e4SLinus Torvalds ACCEPT_MSG(port); /* ACK the RESIDUE MSG */ 30421da177e4SLinus Torvalds 304347b5d69cSJames Bottomley message = FPT_sfm(port, currSCCB); 30441da177e4SLinus Torvalds 30451da177e4SLinus Torvalds if (currSCCB->Sccb_scsimsg != SMPARITY) 30461da177e4SLinus Torvalds ACCEPT_MSG(port); 30475c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 30485c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 30491da177e4SLinus Torvalds } 30501da177e4SLinus Torvalds 30515c04a7b8SAlexey Dobriyan else { 30521da177e4SLinus Torvalds 30531da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; 30541da177e4SLinus Torvalds currSCCB->Sccb_scsimsg = SMREJECT; 30551da177e4SLinus Torvalds 30561da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 30575c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 30585c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 30591da177e4SLinus Torvalds } 30601da177e4SLinus Torvalds } 30611da177e4SLinus Torvalds 30621da177e4SLinus Torvalds /*--------------------------------------------------------------------- 30631da177e4SLinus Torvalds * 306447b5d69cSJames Bottomley * Function: FPT_shandem 30651da177e4SLinus Torvalds * 30661da177e4SLinus Torvalds * Description: Decide what to do with the extended message. 30671da177e4SLinus Torvalds * 30681da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3069391e2f25SKhalid Aziz static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB) 30701da177e4SLinus Torvalds { 3071db038cf8SAlexey Dobriyan unsigned char length, message; 30721da177e4SLinus Torvalds 307347b5d69cSJames Bottomley length = FPT_sfm(port, pCurrSCCB); 30745c04a7b8SAlexey Dobriyan if (length) { 30751da177e4SLinus Torvalds 30761da177e4SLinus Torvalds ACCEPT_MSG(port); 307747b5d69cSJames Bottomley message = FPT_sfm(port, pCurrSCCB); 30785c04a7b8SAlexey Dobriyan if (message) { 30791da177e4SLinus Torvalds 30805c04a7b8SAlexey Dobriyan if (message == SMSYNC) { 30811da177e4SLinus Torvalds 30825c04a7b8SAlexey Dobriyan if (length == 0x03) { 30831da177e4SLinus Torvalds 30841da177e4SLinus Torvalds ACCEPT_MSG(port); 308547b5d69cSJames Bottomley FPT_stsyncn(port, p_card); 30865c04a7b8SAlexey Dobriyan } else { 30871da177e4SLinus Torvalds 30881da177e4SLinus Torvalds pCurrSCCB->Sccb_scsimsg = SMREJECT; 30891da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 30901da177e4SLinus Torvalds } 30915c04a7b8SAlexey Dobriyan } else if (message == SMWDTR) { 30921da177e4SLinus Torvalds 30935c04a7b8SAlexey Dobriyan if (length == 0x02) { 30941da177e4SLinus Torvalds 30951da177e4SLinus Torvalds ACCEPT_MSG(port); 309647b5d69cSJames Bottomley FPT_stwidn(port, p_card); 30975c04a7b8SAlexey Dobriyan } else { 30981da177e4SLinus Torvalds 30991da177e4SLinus Torvalds pCurrSCCB->Sccb_scsimsg = SMREJECT; 31001da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 31011da177e4SLinus Torvalds 31025c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 31035c04a7b8SAlexey Dobriyan (AUTO_IMMED + 31045c04a7b8SAlexey Dobriyan DISCONNECT_START)); 31051da177e4SLinus Torvalds } 31065c04a7b8SAlexey Dobriyan } else { 31071da177e4SLinus Torvalds 31081da177e4SLinus Torvalds pCurrSCCB->Sccb_scsimsg = SMREJECT; 31091da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 31101da177e4SLinus Torvalds 31115c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 31125c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 31131da177e4SLinus Torvalds } 31145c04a7b8SAlexey Dobriyan } else { 31151da177e4SLinus Torvalds if (pCurrSCCB->Sccb_scsimsg != SMPARITY) 31161da177e4SLinus Torvalds ACCEPT_MSG(port); 31175c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 31185c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 31191da177e4SLinus Torvalds } 31205c04a7b8SAlexey Dobriyan } else { 31211da177e4SLinus Torvalds if (pCurrSCCB->Sccb_scsimsg == SMPARITY) 31225c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 31235c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 31241da177e4SLinus Torvalds } 31251da177e4SLinus Torvalds } 31261da177e4SLinus Torvalds 31271da177e4SLinus Torvalds /*--------------------------------------------------------------------- 31281da177e4SLinus Torvalds * 312947b5d69cSJames Bottomley * Function: FPT_sisyncn 31301da177e4SLinus Torvalds * 31311da177e4SLinus Torvalds * Description: Read in a message byte from the SCSI bus, and check 31321da177e4SLinus Torvalds * for a parity error. 31331da177e4SLinus Torvalds * 31341da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 31351da177e4SLinus Torvalds 3136391e2f25SKhalid Aziz static unsigned char FPT_sisyncn(u32 port, unsigned char p_card, 31375c04a7b8SAlexey Dobriyan unsigned char syncFlag) 31381da177e4SLinus Torvalds { 313969eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 3140f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 31411da177e4SLinus Torvalds 314247b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 314347b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; 31441da177e4SLinus Torvalds 31451da177e4SLinus Torvalds if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) { 31461da177e4SLinus Torvalds 31471da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT), 31485c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 31495c04a7b8SAlexey Dobriyan (currSCCB-> 31505c04a7b8SAlexey Dobriyan Sccb_idmsg & ~(unsigned char)DISC_PRIV))); 31511da177e4SLinus Torvalds 31521da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); 31531da177e4SLinus Torvalds 31545c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 0), 31555c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + SMEXT)); 31561da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03)); 31575c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 4), 31585c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + SMSYNC)); 31591da177e4SLinus Torvalds 31601da177e4SLinus Torvalds if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) 31611da177e4SLinus Torvalds 31625c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6), 31635c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 12)); 31641da177e4SLinus Torvalds 31655c04a7b8SAlexey Dobriyan else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == 31665c04a7b8SAlexey Dobriyan EE_SYNC_10MB) 31671da177e4SLinus Torvalds 31685c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6), 31695c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 25)); 31701da177e4SLinus Torvalds 31715c04a7b8SAlexey Dobriyan else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == 31725c04a7b8SAlexey Dobriyan EE_SYNC_5MB) 31731da177e4SLinus Torvalds 31745c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6), 31755c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 50)); 31761da177e4SLinus Torvalds 31771da177e4SLinus Torvalds else 31785c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6), 31795c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 00)); 31801da177e4SLinus Torvalds 31811da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP)); 31825c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 10), 31835c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + DEFAULT_OFFSET)); 31841da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP)); 31851da177e4SLinus Torvalds 31865c04a7b8SAlexey Dobriyan if (syncFlag == 0) { 31875c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3, 31885c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT)); 31895c04a7b8SAlexey Dobriyan currTar_Info->TarStatus = 31905c04a7b8SAlexey Dobriyan ((currTar_Info-> 31915c04a7b8SAlexey Dobriyan TarStatus & ~(unsigned char)TAR_SYNC_MASK) | 31925c04a7b8SAlexey Dobriyan (unsigned char)SYNC_TRYING); 31935c04a7b8SAlexey Dobriyan } else { 31945c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3, 31955c04a7b8SAlexey Dobriyan (AUTO_IMMED + CMD_ONLY_STRT)); 31961da177e4SLinus Torvalds } 31971da177e4SLinus Torvalds 31985c1b85e2SAlexey Dobriyan return 1; 31991da177e4SLinus Torvalds } 32001da177e4SLinus Torvalds 32011da177e4SLinus Torvalds else { 32021da177e4SLinus Torvalds 3203db038cf8SAlexey Dobriyan currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED; 32041da177e4SLinus Torvalds currTar_Info->TarEEValue &= ~EE_SYNC_MASK; 32055c1b85e2SAlexey Dobriyan return 0; 32061da177e4SLinus Torvalds } 32071da177e4SLinus Torvalds } 32081da177e4SLinus Torvalds 32091da177e4SLinus Torvalds /*--------------------------------------------------------------------- 32101da177e4SLinus Torvalds * 321147b5d69cSJames Bottomley * Function: FPT_stsyncn 32121da177e4SLinus Torvalds * 32131da177e4SLinus Torvalds * Description: The has sent us a Sync Nego message so handle it as 32141da177e4SLinus Torvalds * necessary. 32151da177e4SLinus Torvalds * 32161da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3217391e2f25SKhalid Aziz static void FPT_stsyncn(u32 port, unsigned char p_card) 32181da177e4SLinus Torvalds { 3219db038cf8SAlexey Dobriyan unsigned char sync_msg, offset, sync_reg, our_sync_msg; 322069eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 3221f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 32221da177e4SLinus Torvalds 322347b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 322447b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; 32251da177e4SLinus Torvalds 322647b5d69cSJames Bottomley sync_msg = FPT_sfm(port, currSCCB); 32271da177e4SLinus Torvalds 32285c04a7b8SAlexey Dobriyan if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { 32295c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 32305c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 32311da177e4SLinus Torvalds return; 32321da177e4SLinus Torvalds } 32331da177e4SLinus Torvalds 32341da177e4SLinus Torvalds ACCEPT_MSG(port); 32351da177e4SLinus Torvalds 323647b5d69cSJames Bottomley offset = FPT_sfm(port, currSCCB); 32371da177e4SLinus Torvalds 32385c04a7b8SAlexey Dobriyan if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { 32395c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 32405c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 32411da177e4SLinus Torvalds return; 32421da177e4SLinus Torvalds } 32431da177e4SLinus Torvalds 32441da177e4SLinus Torvalds if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) 32451da177e4SLinus Torvalds 32461da177e4SLinus Torvalds our_sync_msg = 12; /* Setup our Message to 20mb/s */ 32471da177e4SLinus Torvalds 32481da177e4SLinus Torvalds else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB) 32491da177e4SLinus Torvalds 32501da177e4SLinus Torvalds our_sync_msg = 25; /* Setup our Message to 10mb/s */ 32511da177e4SLinus Torvalds 32521da177e4SLinus Torvalds else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB) 32531da177e4SLinus Torvalds 32541da177e4SLinus Torvalds our_sync_msg = 50; /* Setup our Message to 5mb/s */ 32551da177e4SLinus Torvalds else 32561da177e4SLinus Torvalds 32571da177e4SLinus Torvalds our_sync_msg = 0; /* Message = Async */ 32581da177e4SLinus Torvalds 32591da177e4SLinus Torvalds if (sync_msg < our_sync_msg) { 32601da177e4SLinus Torvalds sync_msg = our_sync_msg; /*if faster, then set to max. */ 32611da177e4SLinus Torvalds } 32621da177e4SLinus Torvalds 32631da177e4SLinus Torvalds if (offset == ASYNC) 32641da177e4SLinus Torvalds sync_msg = ASYNC; 32651da177e4SLinus Torvalds 32661da177e4SLinus Torvalds if (offset > MAX_OFFSET) 32671da177e4SLinus Torvalds offset = MAX_OFFSET; 32681da177e4SLinus Torvalds 32691da177e4SLinus Torvalds sync_reg = 0x00; 32701da177e4SLinus Torvalds 32711da177e4SLinus Torvalds if (sync_msg > 12) 32721da177e4SLinus Torvalds 32731da177e4SLinus Torvalds sync_reg = 0x20; /* Use 10MB/s */ 32741da177e4SLinus Torvalds 32751da177e4SLinus Torvalds if (sync_msg > 25) 32761da177e4SLinus Torvalds 32771da177e4SLinus Torvalds sync_reg = 0x40; /* Use 6.6MB/s */ 32781da177e4SLinus Torvalds 32791da177e4SLinus Torvalds if (sync_msg > 38) 32801da177e4SLinus Torvalds 32811da177e4SLinus Torvalds sync_reg = 0x60; /* Use 5MB/s */ 32821da177e4SLinus Torvalds 32831da177e4SLinus Torvalds if (sync_msg > 50) 32841da177e4SLinus Torvalds 32851da177e4SLinus Torvalds sync_reg = 0x80; /* Use 4MB/s */ 32861da177e4SLinus Torvalds 32871da177e4SLinus Torvalds if (sync_msg > 62) 32881da177e4SLinus Torvalds 32891da177e4SLinus Torvalds sync_reg = 0xA0; /* Use 3.33MB/s */ 32901da177e4SLinus Torvalds 32911da177e4SLinus Torvalds if (sync_msg > 75) 32921da177e4SLinus Torvalds 32931da177e4SLinus Torvalds sync_reg = 0xC0; /* Use 2.85MB/s */ 32941da177e4SLinus Torvalds 32951da177e4SLinus Torvalds if (sync_msg > 87) 32961da177e4SLinus Torvalds 32971da177e4SLinus Torvalds sync_reg = 0xE0; /* Use 2.5MB/s */ 32981da177e4SLinus Torvalds 32991da177e4SLinus Torvalds if (sync_msg > 100) { 33001da177e4SLinus Torvalds 33011da177e4SLinus Torvalds sync_reg = 0x00; /* Use ASYNC */ 33021da177e4SLinus Torvalds offset = 0x00; 33031da177e4SLinus Torvalds } 33041da177e4SLinus Torvalds 33051da177e4SLinus Torvalds if (currTar_Info->TarStatus & WIDE_ENABLED) 33061da177e4SLinus Torvalds 33071da177e4SLinus Torvalds sync_reg |= offset; 33081da177e4SLinus Torvalds 33091da177e4SLinus Torvalds else 33101da177e4SLinus Torvalds 33111da177e4SLinus Torvalds sync_reg |= (offset | NARROW_SCSI); 33121da177e4SLinus Torvalds 331347b5d69cSJames Bottomley FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info); 33141da177e4SLinus Torvalds 33151da177e4SLinus Torvalds if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { 33161da177e4SLinus Torvalds 33171da177e4SLinus Torvalds ACCEPT_MSG(port); 33181da177e4SLinus Torvalds 33191da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus & 33205c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_SYNC_MASK) | 33215c04a7b8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED); 33221da177e4SLinus Torvalds 33235c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 33245c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 33251da177e4SLinus Torvalds } 33261da177e4SLinus Torvalds 33271da177e4SLinus Torvalds else { 33281da177e4SLinus Torvalds 33291da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 33301da177e4SLinus Torvalds 333147b5d69cSJames Bottomley FPT_sisyncr(port, sync_msg, offset); 33321da177e4SLinus Torvalds 33331da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus & 33345c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_SYNC_MASK) | 33355c04a7b8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED); 33361da177e4SLinus Torvalds } 33371da177e4SLinus Torvalds } 33381da177e4SLinus Torvalds 33391da177e4SLinus Torvalds /*--------------------------------------------------------------------- 33401da177e4SLinus Torvalds * 334147b5d69cSJames Bottomley * Function: FPT_sisyncr 33421da177e4SLinus Torvalds * 33431da177e4SLinus Torvalds * Description: Answer the targets sync message. 33441da177e4SLinus Torvalds * 33451da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3346391e2f25SKhalid Aziz static void FPT_sisyncr(u32 port, unsigned char sync_pulse, 33475c04a7b8SAlexey Dobriyan unsigned char offset) 33481da177e4SLinus Torvalds { 33491da177e4SLinus Torvalds ARAM_ACCESS(port); 33501da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); 33511da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03)); 33521da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC)); 33531da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse)); 33541da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP)); 33551da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset)); 33561da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP)); 33571da177e4SLinus Torvalds SGRAM_ACCESS(port); 33581da177e4SLinus Torvalds 33591da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 33601da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1); 33611da177e4SLinus Torvalds 33621da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT)); 33631da177e4SLinus Torvalds 33645c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) { 33651da177e4SLinus Torvalds } 33665c04a7b8SAlexey Dobriyan } 33671da177e4SLinus Torvalds 33681da177e4SLinus Torvalds /*--------------------------------------------------------------------- 33691da177e4SLinus Torvalds * 337047b5d69cSJames Bottomley * Function: FPT_siwidn 33711da177e4SLinus Torvalds * 33721da177e4SLinus Torvalds * Description: Read in a message byte from the SCSI bus, and check 33731da177e4SLinus Torvalds * for a parity error. 33741da177e4SLinus Torvalds * 33751da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 33761da177e4SLinus Torvalds 3377391e2f25SKhalid Aziz static unsigned char FPT_siwidn(u32 port, unsigned char p_card) 33781da177e4SLinus Torvalds { 337969eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 3380f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 33811da177e4SLinus Torvalds 338247b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 338347b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; 33841da177e4SLinus Torvalds 33851da177e4SLinus Torvalds if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) { 33861da177e4SLinus Torvalds 33871da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT), 33885c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 33895c04a7b8SAlexey Dobriyan (currSCCB-> 33905c04a7b8SAlexey Dobriyan Sccb_idmsg & ~(unsigned char)DISC_PRIV))); 33911da177e4SLinus Torvalds 33921da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); 33931da177e4SLinus Torvalds 33945c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 0), 33955c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + SMEXT)); 33961da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02)); 33975c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 4), 33985c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + SMWDTR)); 33991da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP)); 34005c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 8), 34015c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + SM16BIT)); 34021da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP)); 34031da177e4SLinus Torvalds 34041da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); 34051da177e4SLinus Torvalds 34061da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus & 34075c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_WIDE_MASK) | 34085c04a7b8SAlexey Dobriyan (unsigned char)WIDE_ENABLED); 34091da177e4SLinus Torvalds 34105c1b85e2SAlexey Dobriyan return 1; 34111da177e4SLinus Torvalds } 34121da177e4SLinus Torvalds 34131da177e4SLinus Torvalds else { 34141da177e4SLinus Torvalds 34151da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus & 34165c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_WIDE_MASK) | 34175c04a7b8SAlexey Dobriyan WIDE_NEGOCIATED); 34181da177e4SLinus Torvalds 34191da177e4SLinus Torvalds currTar_Info->TarEEValue &= ~EE_WIDE_SCSI; 34205c1b85e2SAlexey Dobriyan return 0; 34211da177e4SLinus Torvalds } 34221da177e4SLinus Torvalds } 34231da177e4SLinus Torvalds 34241da177e4SLinus Torvalds /*--------------------------------------------------------------------- 34251da177e4SLinus Torvalds * 342647b5d69cSJames Bottomley * Function: FPT_stwidn 34271da177e4SLinus Torvalds * 34281da177e4SLinus Torvalds * Description: The has sent us a Wide Nego message so handle it as 34291da177e4SLinus Torvalds * necessary. 34301da177e4SLinus Torvalds * 34311da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3432391e2f25SKhalid Aziz static void FPT_stwidn(u32 port, unsigned char p_card) 34331da177e4SLinus Torvalds { 3434db038cf8SAlexey Dobriyan unsigned char width; 343569eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 3436f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 34371da177e4SLinus Torvalds 343847b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 343947b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; 34401da177e4SLinus Torvalds 344147b5d69cSJames Bottomley width = FPT_sfm(port, currSCCB); 34421da177e4SLinus Torvalds 34435c04a7b8SAlexey Dobriyan if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { 34445c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 34455c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 34461da177e4SLinus Torvalds return; 34471da177e4SLinus Torvalds } 34481da177e4SLinus Torvalds 34491da177e4SLinus Torvalds if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI)) 34501da177e4SLinus Torvalds width = 0; 34511da177e4SLinus Torvalds 34521da177e4SLinus Torvalds if (width) { 34531da177e4SLinus Torvalds currTar_Info->TarStatus |= WIDE_ENABLED; 34541da177e4SLinus Torvalds width = 0; 34555c04a7b8SAlexey Dobriyan } else { 34561da177e4SLinus Torvalds width = NARROW_SCSI; 34571da177e4SLinus Torvalds currTar_Info->TarStatus &= ~WIDE_ENABLED; 34581da177e4SLinus Torvalds } 34591da177e4SLinus Torvalds 346047b5d69cSJames Bottomley FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info); 34611da177e4SLinus Torvalds 34625c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { 34631da177e4SLinus Torvalds 34641da177e4SLinus Torvalds currTar_Info->TarStatus |= WIDE_NEGOCIATED; 34651da177e4SLinus Torvalds 34665c04a7b8SAlexey Dobriyan if (! 34675c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_SYNC_MASK) == 34685c04a7b8SAlexey Dobriyan SYNC_SUPPORTED)) { 34691da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 34701da177e4SLinus Torvalds ARAM_ACCESS(port); 347147b5d69cSJames Bottomley FPT_sisyncn(port, p_card, 1); 34721da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_SN_ST; 34731da177e4SLinus Torvalds SGRAM_ACCESS(port); 34745c04a7b8SAlexey Dobriyan } else { 34751da177e4SLinus Torvalds ACCEPT_MSG(port); 34765c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 34775c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 34781da177e4SLinus Torvalds } 34791da177e4SLinus Torvalds } 34801da177e4SLinus Torvalds 34811da177e4SLinus Torvalds else { 34821da177e4SLinus Torvalds 34831da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 34841da177e4SLinus Torvalds 34851da177e4SLinus Torvalds if (currTar_Info->TarEEValue & EE_WIDE_SCSI) 34861da177e4SLinus Torvalds width = SM16BIT; 34871da177e4SLinus Torvalds else 34881da177e4SLinus Torvalds width = SM8BIT; 34891da177e4SLinus Torvalds 349047b5d69cSJames Bottomley FPT_siwidr(port, width); 34911da177e4SLinus Torvalds 34921da177e4SLinus Torvalds currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED); 34931da177e4SLinus Torvalds } 34941da177e4SLinus Torvalds } 34951da177e4SLinus Torvalds 34961da177e4SLinus Torvalds /*--------------------------------------------------------------------- 34971da177e4SLinus Torvalds * 349847b5d69cSJames Bottomley * Function: FPT_siwidr 34991da177e4SLinus Torvalds * 35001da177e4SLinus Torvalds * Description: Answer the targets Wide nego message. 35011da177e4SLinus Torvalds * 35021da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3503391e2f25SKhalid Aziz static void FPT_siwidr(u32 port, unsigned char width) 35041da177e4SLinus Torvalds { 35051da177e4SLinus Torvalds ARAM_ACCESS(port); 35061da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); 35071da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02)); 35081da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR)); 35091da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP)); 35101da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width)); 35111da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP)); 35121da177e4SLinus Torvalds SGRAM_ACCESS(port); 35131da177e4SLinus Torvalds 35141da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 35151da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1); 35161da177e4SLinus Torvalds 35171da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT)); 35181da177e4SLinus Torvalds 35195c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) { 35201da177e4SLinus Torvalds } 35215c04a7b8SAlexey Dobriyan } 35221da177e4SLinus Torvalds 35231da177e4SLinus Torvalds /*--------------------------------------------------------------------- 35241da177e4SLinus Torvalds * 352547b5d69cSJames Bottomley * Function: FPT_sssyncv 35261da177e4SLinus Torvalds * 35271da177e4SLinus Torvalds * Description: Write the desired value to the Sync Register for the 35281da177e4SLinus Torvalds * ID specified. 35291da177e4SLinus Torvalds * 35301da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3531391e2f25SKhalid Aziz static void FPT_sssyncv(u32 p_port, unsigned char p_id, 35325c04a7b8SAlexey Dobriyan unsigned char p_sync_value, 3533f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info) 35341da177e4SLinus Torvalds { 3535db038cf8SAlexey Dobriyan unsigned char index; 35361da177e4SLinus Torvalds 35371da177e4SLinus Torvalds index = p_id; 35381da177e4SLinus Torvalds 35391da177e4SLinus Torvalds switch (index) { 35401da177e4SLinus Torvalds 35411da177e4SLinus Torvalds case 0: 35421da177e4SLinus Torvalds index = 12; /* hp_synctarg_0 */ 35431da177e4SLinus Torvalds break; 35441da177e4SLinus Torvalds case 1: 35451da177e4SLinus Torvalds index = 13; /* hp_synctarg_1 */ 35461da177e4SLinus Torvalds break; 35471da177e4SLinus Torvalds case 2: 35481da177e4SLinus Torvalds index = 14; /* hp_synctarg_2 */ 35491da177e4SLinus Torvalds break; 35501da177e4SLinus Torvalds case 3: 35511da177e4SLinus Torvalds index = 15; /* hp_synctarg_3 */ 35521da177e4SLinus Torvalds break; 35531da177e4SLinus Torvalds case 4: 35541da177e4SLinus Torvalds index = 8; /* hp_synctarg_4 */ 35551da177e4SLinus Torvalds break; 35561da177e4SLinus Torvalds case 5: 35571da177e4SLinus Torvalds index = 9; /* hp_synctarg_5 */ 35581da177e4SLinus Torvalds break; 35591da177e4SLinus Torvalds case 6: 35601da177e4SLinus Torvalds index = 10; /* hp_synctarg_6 */ 35611da177e4SLinus Torvalds break; 35621da177e4SLinus Torvalds case 7: 35631da177e4SLinus Torvalds index = 11; /* hp_synctarg_7 */ 35641da177e4SLinus Torvalds break; 35651da177e4SLinus Torvalds case 8: 35661da177e4SLinus Torvalds index = 4; /* hp_synctarg_8 */ 35671da177e4SLinus Torvalds break; 35681da177e4SLinus Torvalds case 9: 35691da177e4SLinus Torvalds index = 5; /* hp_synctarg_9 */ 35701da177e4SLinus Torvalds break; 35711da177e4SLinus Torvalds case 10: 35721da177e4SLinus Torvalds index = 6; /* hp_synctarg_10 */ 35731da177e4SLinus Torvalds break; 35741da177e4SLinus Torvalds case 11: 35751da177e4SLinus Torvalds index = 7; /* hp_synctarg_11 */ 35761da177e4SLinus Torvalds break; 35771da177e4SLinus Torvalds case 12: 35781da177e4SLinus Torvalds index = 0; /* hp_synctarg_12 */ 35791da177e4SLinus Torvalds break; 35801da177e4SLinus Torvalds case 13: 35811da177e4SLinus Torvalds index = 1; /* hp_synctarg_13 */ 35821da177e4SLinus Torvalds break; 35831da177e4SLinus Torvalds case 14: 35841da177e4SLinus Torvalds index = 2; /* hp_synctarg_14 */ 35851da177e4SLinus Torvalds break; 35861da177e4SLinus Torvalds case 15: 35871da177e4SLinus Torvalds index = 3; /* hp_synctarg_15 */ 35881da177e4SLinus Torvalds 35891da177e4SLinus Torvalds } 35901da177e4SLinus Torvalds 35911da177e4SLinus Torvalds WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value); 35921da177e4SLinus Torvalds 35931da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = p_sync_value; 35941da177e4SLinus Torvalds } 35951da177e4SLinus Torvalds 35961da177e4SLinus Torvalds /*--------------------------------------------------------------------- 35971da177e4SLinus Torvalds * 359847b5d69cSJames Bottomley * Function: FPT_sresb 35991da177e4SLinus Torvalds * 36001da177e4SLinus Torvalds * Description: Reset the desired card's SCSI bus. 36011da177e4SLinus Torvalds * 36021da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 3603391e2f25SKhalid Aziz static void FPT_sresb(u32 port, unsigned char p_card) 36041da177e4SLinus Torvalds { 3605db038cf8SAlexey Dobriyan unsigned char scsiID, i; 36061da177e4SLinus Torvalds 3607f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 36081da177e4SLinus Torvalds 36091da177e4SLinus Torvalds WR_HARPOON(port + hp_page_ctrl, 36101da177e4SLinus Torvalds (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE)); 36111da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT); 36121da177e4SLinus Torvalds 36131da177e4SLinus Torvalds WR_HARPOON(port + hp_scsictrl_0, SCSI_RST); 36141da177e4SLinus Torvalds 36151da177e4SLinus Torvalds scsiID = RD_HARPOON(port + hp_seltimeout); 36161da177e4SLinus Torvalds WR_HARPOON(port + hp_seltimeout, TO_5ms); 36171da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), TIMEOUT); 36181da177e4SLinus Torvalds 36191da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO)); 36201da177e4SLinus Torvalds 36215c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) { 36225c04a7b8SAlexey Dobriyan } 36231da177e4SLinus Torvalds 36241da177e4SLinus Torvalds WR_HARPOON(port + hp_seltimeout, scsiID); 36251da177e4SLinus Torvalds 36261da177e4SLinus Torvalds WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL); 36271da177e4SLinus Torvalds 362847b5d69cSJames Bottomley FPT_Wait(port, TO_5ms); 36291da177e4SLinus Torvalds 36301da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT); 36311da177e4SLinus Torvalds 36321da177e4SLinus Torvalds WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00)); 36331da177e4SLinus Torvalds 36345c04a7b8SAlexey Dobriyan for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) { 363547b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID]; 36361da177e4SLinus Torvalds 36375c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_SYNC_MASK) { 36381da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0; 36391da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK; 36401da177e4SLinus Torvalds } 36411da177e4SLinus Torvalds 36425c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_WIDE_SCSI) { 36431da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK; 36441da177e4SLinus Torvalds } 36451da177e4SLinus Torvalds 364647b5d69cSJames Bottomley FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info); 36471da177e4SLinus Torvalds 364847b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, scsiID); 36491da177e4SLinus Torvalds } 36501da177e4SLinus Torvalds 365147b5d69cSJames Bottomley FPT_BL_Card[p_card].scanIndex = 0x00; 365247b5d69cSJames Bottomley FPT_BL_Card[p_card].currentSCCB = NULL; 365347b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT 36541da177e4SLinus Torvalds | F_NEW_SCCB_CMD); 365547b5d69cSJames Bottomley FPT_BL_Card[p_card].cmdCounter = 0x00; 365647b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount = 0x00; 365747b5d69cSJames Bottomley FPT_BL_Card[p_card].tagQ_Lst = 0x01; 36581da177e4SLinus Torvalds 36591da177e4SLinus Torvalds for (i = 0; i < QUEUE_DEPTH; i++) 366047b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[i] = NULL; 36611da177e4SLinus Torvalds 36621da177e4SLinus Torvalds WR_HARPOON(port + hp_page_ctrl, 36631da177e4SLinus Torvalds (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE)); 36641da177e4SLinus Torvalds 36651da177e4SLinus Torvalds } 36661da177e4SLinus Torvalds 36671da177e4SLinus Torvalds /*--------------------------------------------------------------------- 36681da177e4SLinus Torvalds * 366947b5d69cSJames Bottomley * Function: FPT_ssenss 36701da177e4SLinus Torvalds * 36711da177e4SLinus Torvalds * Description: Setup for the Auto Sense command. 36721da177e4SLinus Torvalds * 36731da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 367413e6851aSAlexey Dobriyan static void FPT_ssenss(struct sccb_card *pCurrCard) 36751da177e4SLinus Torvalds { 3676db038cf8SAlexey Dobriyan unsigned char i; 367769eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 36781da177e4SLinus Torvalds 36791da177e4SLinus Torvalds currSCCB = pCurrCard->currentSCCB; 36801da177e4SLinus Torvalds 36811da177e4SLinus Torvalds currSCCB->Save_CdbLen = currSCCB->CdbLength; 36821da177e4SLinus Torvalds 36831da177e4SLinus Torvalds for (i = 0; i < 6; i++) { 36841da177e4SLinus Torvalds 36851da177e4SLinus Torvalds currSCCB->Save_Cdb[i] = currSCCB->Cdb[i]; 36861da177e4SLinus Torvalds } 36871da177e4SLinus Torvalds 36881da177e4SLinus Torvalds currSCCB->CdbLength = SIX_BYTE_CMD; 36891da177e4SLinus Torvalds currSCCB->Cdb[0] = SCSI_REQUEST_SENSE; 3690db038cf8SAlexey Dobriyan currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */ 36911da177e4SLinus Torvalds currSCCB->Cdb[2] = 0x00; 36921da177e4SLinus Torvalds currSCCB->Cdb[3] = 0x00; 36931da177e4SLinus Torvalds currSCCB->Cdb[4] = currSCCB->RequestSenseLength; 36941da177e4SLinus Torvalds currSCCB->Cdb[5] = 0x00; 36951da177e4SLinus Torvalds 3696391e2f25SKhalid Aziz currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength; 36971da177e4SLinus Torvalds 36981da177e4SLinus Torvalds currSCCB->Sccb_ATC = 0x00; 36991da177e4SLinus Torvalds 37001da177e4SLinus Torvalds currSCCB->Sccb_XferState |= F_AUTO_SENSE; 37011da177e4SLinus Torvalds 37021da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~F_SG_XFER; 37031da177e4SLinus Torvalds 3704db038cf8SAlexey Dobriyan currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV; 37051da177e4SLinus Torvalds 37061da177e4SLinus Torvalds currSCCB->ControlByte = 0x00; 37071da177e4SLinus Torvalds 37081da177e4SLinus Torvalds currSCCB->Sccb_MGRFlags &= F_STATUSLOADED; 37091da177e4SLinus Torvalds } 37101da177e4SLinus Torvalds 37111da177e4SLinus Torvalds /*--------------------------------------------------------------------- 37121da177e4SLinus Torvalds * 371347b5d69cSJames Bottomley * Function: FPT_sxfrp 37141da177e4SLinus Torvalds * 37151da177e4SLinus Torvalds * Description: Transfer data into the bit bucket until the device 37161da177e4SLinus Torvalds * decides to switch phase. 37171da177e4SLinus Torvalds * 37181da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 37191da177e4SLinus Torvalds 3720391e2f25SKhalid Aziz static void FPT_sxfrp(u32 p_port, unsigned char p_card) 37211da177e4SLinus Torvalds { 3722db038cf8SAlexey Dobriyan unsigned char curr_phz; 37231da177e4SLinus Torvalds 37241da177e4SLinus Torvalds DISABLE_AUTO(p_port); 37251da177e4SLinus Torvalds 372647b5d69cSJames Bottomley if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) { 37271da177e4SLinus Torvalds 37285c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(p_port, p_card, 37295c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].currentSCCB); 37301da177e4SLinus Torvalds 37311da177e4SLinus Torvalds } 37321da177e4SLinus Torvalds 37331da177e4SLinus Torvalds /* If the Automation handled the end of the transfer then do not 37341da177e4SLinus Torvalds match the phase or we will get out of sync with the ISR. */ 37351da177e4SLinus Torvalds 37365c04a7b8SAlexey Dobriyan if (RDW_HARPOON((p_port + hp_intstat)) & 37375c04a7b8SAlexey Dobriyan (BUS_FREE | XFER_CNT_0 | AUTO_INT)) 37381da177e4SLinus Torvalds return; 37391da177e4SLinus Torvalds 37401da177e4SLinus Torvalds WR_HARPOON(p_port + hp_xfercnt_0, 0x00); 37411da177e4SLinus Torvalds 3742db038cf8SAlexey Dobriyan curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ; 37431da177e4SLinus Torvalds 37441da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0); 37451da177e4SLinus Torvalds 37461da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, curr_phz); 37471da177e4SLinus Torvalds 37481da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) && 37495c04a7b8SAlexey Dobriyan (curr_phz == 37505c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ))) 37511da177e4SLinus Torvalds { 37525c04a7b8SAlexey Dobriyan if (curr_phz & (unsigned char)SCSI_IOBIT) { 37535c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 37545c04a7b8SAlexey Dobriyan (SCSI_PORT | HOST_PORT | SCSI_INBIT)); 37551da177e4SLinus Torvalds 37565c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) { 37571da177e4SLinus Torvalds RD_HARPOON(p_port + hp_fifodata_0); 37581da177e4SLinus Torvalds } 37595c04a7b8SAlexey Dobriyan } else { 37605c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 37615c04a7b8SAlexey Dobriyan (SCSI_PORT | HOST_PORT | HOST_WRT)); 37625c04a7b8SAlexey Dobriyan if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) { 37631da177e4SLinus Torvalds WR_HARPOON(p_port + hp_fifodata_0, 0xFA); 37641da177e4SLinus Torvalds } 37651da177e4SLinus Torvalds } 37661da177e4SLinus Torvalds } /* End of While loop for padding data I/O phase */ 37671da177e4SLinus Torvalds 37685c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) { 37691da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) 37701da177e4SLinus Torvalds break; 37711da177e4SLinus Torvalds } 37721da177e4SLinus Torvalds 37735c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 37745c04a7b8SAlexey Dobriyan (SCSI_PORT | HOST_PORT | SCSI_INBIT)); 37755c04a7b8SAlexey Dobriyan while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) { 37761da177e4SLinus Torvalds RD_HARPOON(p_port + hp_fifodata_0); 37771da177e4SLinus Torvalds } 37781da177e4SLinus Torvalds 37795c04a7b8SAlexey Dobriyan if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) { 37805c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_autostart_0, 37815c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 37825c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) { 37831da177e4SLinus Torvalds } 37841da177e4SLinus Torvalds 37855c04a7b8SAlexey Dobriyan if (RDW_HARPOON((p_port + hp_intstat)) & 37865c04a7b8SAlexey Dobriyan (ICMD_COMP | ITAR_DISC)) 37875c04a7b8SAlexey Dobriyan while (! 37885c04a7b8SAlexey Dobriyan (RDW_HARPOON((p_port + hp_intstat)) & 37895c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))) ; 37905c04a7b8SAlexey Dobriyan } 37915c04a7b8SAlexey Dobriyan } 37921da177e4SLinus Torvalds 37931da177e4SLinus Torvalds /*--------------------------------------------------------------------- 37941da177e4SLinus Torvalds * 379547b5d69cSJames Bottomley * Function: FPT_schkdd 37961da177e4SLinus Torvalds * 37971da177e4SLinus Torvalds * Description: Make sure data has been flushed from both FIFOs and abort 37981da177e4SLinus Torvalds * the operations if necessary. 37991da177e4SLinus Torvalds * 38001da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 38011da177e4SLinus Torvalds 3802391e2f25SKhalid Aziz static void FPT_schkdd(u32 port, unsigned char p_card) 38031da177e4SLinus Torvalds { 3804c823feebSAlexey Dobriyan unsigned short TimeOutLoop; 3805db038cf8SAlexey Dobriyan unsigned char sPhase; 38061da177e4SLinus Torvalds 380769eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 38081da177e4SLinus Torvalds 380947b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 38101da177e4SLinus Torvalds 38111da177e4SLinus Torvalds if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) && 38121da177e4SLinus Torvalds (currSCCB->Sccb_scsistat != DATA_IN_ST)) { 38131da177e4SLinus Torvalds return; 38141da177e4SLinus Torvalds } 38151da177e4SLinus Torvalds 38165c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) { 38171da177e4SLinus Torvalds 38181da177e4SLinus Torvalds currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1); 38191da177e4SLinus Torvalds 38201da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 1; 38211da177e4SLinus Torvalds 38221da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT; 3823c823feebSAlexey Dobriyan WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00); 38241da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0x00); 38251da177e4SLinus Torvalds } 38261da177e4SLinus Torvalds 38275c04a7b8SAlexey Dobriyan else { 38281da177e4SLinus Torvalds 38291da177e4SLinus Torvalds currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt; 38301da177e4SLinus Torvalds 38311da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 0; 38321da177e4SLinus Torvalds } 38331da177e4SLinus Torvalds 38341da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && 38351da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE)) { 38361da177e4SLinus Torvalds 38371da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PARITY_ERR; 38381da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY); 38391da177e4SLinus Torvalds } 38401da177e4SLinus Torvalds 384147b5d69cSJames Bottomley FPT_hostDataXferAbort(port, p_card, currSCCB); 38421da177e4SLinus Torvalds 38435c04a7b8SAlexey Dobriyan while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) { 38445c04a7b8SAlexey Dobriyan } 38451da177e4SLinus Torvalds 38461da177e4SLinus Torvalds TimeOutLoop = 0; 38471da177e4SLinus Torvalds 38485c04a7b8SAlexey Dobriyan while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) { 38491da177e4SLinus Torvalds if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { 38501da177e4SLinus Torvalds return; 38511da177e4SLinus Torvalds } 3852db038cf8SAlexey Dobriyan if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) { 38531da177e4SLinus Torvalds break; 38541da177e4SLinus Torvalds } 38551da177e4SLinus Torvalds if (RDW_HARPOON((port + hp_intstat)) & RESET) { 38561da177e4SLinus Torvalds return; 38571da177e4SLinus Torvalds } 38585c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ) 38595c04a7b8SAlexey Dobriyan || (TimeOutLoop++ > 0x3000)) 38601da177e4SLinus Torvalds break; 38611da177e4SLinus Torvalds } 38621da177e4SLinus Torvalds 38631da177e4SLinus Torvalds sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ); 38641da177e4SLinus Torvalds if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) || 3865db038cf8SAlexey Dobriyan (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) || 38661da177e4SLinus Torvalds (sPhase == (SCSI_BSY | S_DATAO_PH)) || 38675c04a7b8SAlexey Dobriyan (sPhase == (SCSI_BSY | S_DATAI_PH))) { 38681da177e4SLinus Torvalds 38691da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 38701da177e4SLinus Torvalds 38715c04a7b8SAlexey Dobriyan if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) { 38721da177e4SLinus Torvalds if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) { 387347b5d69cSJames Bottomley FPT_phaseDataIn(port, p_card); 38741da177e4SLinus Torvalds } 38751da177e4SLinus Torvalds 38761da177e4SLinus Torvalds else { 387747b5d69cSJames Bottomley FPT_phaseDataOut(port, p_card); 38781da177e4SLinus Torvalds } 38795c04a7b8SAlexey Dobriyan } else { 388047b5d69cSJames Bottomley FPT_sxfrp(port, p_card); 38811da177e4SLinus Torvalds if (!(RDW_HARPOON((port + hp_intstat)) & 38825c04a7b8SAlexey Dobriyan (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) { 38831da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), AUTO_INT); 388447b5d69cSJames Bottomley FPT_phaseDecode(port, p_card); 38851da177e4SLinus Torvalds } 38861da177e4SLinus Torvalds } 38871da177e4SLinus Torvalds 38881da177e4SLinus Torvalds } 38891da177e4SLinus Torvalds 38901da177e4SLinus Torvalds else { 38911da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00); 38921da177e4SLinus Torvalds } 38931da177e4SLinus Torvalds } 38941da177e4SLinus Torvalds 38951da177e4SLinus Torvalds /*--------------------------------------------------------------------- 38961da177e4SLinus Torvalds * 389747b5d69cSJames Bottomley * Function: FPT_sinits 38981da177e4SLinus Torvalds * 38991da177e4SLinus Torvalds * Description: Setup SCCB manager fields in this SCCB. 39001da177e4SLinus Torvalds * 39011da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 39021da177e4SLinus Torvalds 390369eb2ea4SAlexey Dobriyan static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card) 39041da177e4SLinus Torvalds { 3905f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 39061da177e4SLinus Torvalds 39075d7ebb9cSDan Carpenter if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) { 39081da177e4SLinus Torvalds return; 39091da177e4SLinus Torvalds } 391047b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; 39111da177e4SLinus Torvalds 39121da177e4SLinus Torvalds p_sccb->Sccb_XferState = 0x00; 39131da177e4SLinus Torvalds p_sccb->Sccb_XferCnt = p_sccb->DataLength; 39141da177e4SLinus Torvalds 39151da177e4SLinus Torvalds if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) || 39161da177e4SLinus Torvalds (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) { 39171da177e4SLinus Torvalds 39181da177e4SLinus Torvalds p_sccb->Sccb_SGoffset = 0; 39191da177e4SLinus Torvalds p_sccb->Sccb_XferState = F_SG_XFER; 39201da177e4SLinus Torvalds p_sccb->Sccb_XferCnt = 0x00; 39211da177e4SLinus Torvalds } 39221da177e4SLinus Torvalds 39231da177e4SLinus Torvalds if (p_sccb->DataLength == 0x00) 39241da177e4SLinus Torvalds 39251da177e4SLinus Torvalds p_sccb->Sccb_XferState |= F_ALL_XFERRED; 39261da177e4SLinus Torvalds 39275c04a7b8SAlexey Dobriyan if (p_sccb->ControlByte & F_USE_CMD_Q) { 39281da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT) 39291da177e4SLinus Torvalds p_sccb->ControlByte &= ~F_USE_CMD_Q; 39301da177e4SLinus Torvalds 39311da177e4SLinus Torvalds else 39321da177e4SLinus Torvalds currTar_Info->TarStatus |= TAG_Q_TRYING; 39331da177e4SLinus Torvalds } 39341da177e4SLinus Torvalds 39351da177e4SLinus Torvalds /* For !single SCSI device in system & device allow Disconnect 39361da177e4SLinus Torvalds or command is tag_q type then send Cmd with Disconnect Enable 39371da177e4SLinus Torvalds else send Cmd with Disconnect Disable */ 39381da177e4SLinus Torvalds 39391da177e4SLinus Torvalds /* 394047b5d69cSJames Bottomley if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) && 39411da177e4SLinus Torvalds (currTar_Info->TarStatus & TAR_ALLOW_DISC)) || 39421da177e4SLinus Torvalds (currTar_Info->TarStatus & TAG_Q_TRYING)) { 39431da177e4SLinus Torvalds */ 39441da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) || 39451da177e4SLinus Torvalds (currTar_Info->TarStatus & TAG_Q_TRYING)) { 39465c04a7b8SAlexey Dobriyan p_sccb->Sccb_idmsg = 39475c04a7b8SAlexey Dobriyan (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun; 39481da177e4SLinus Torvalds } 39491da177e4SLinus Torvalds 39501da177e4SLinus Torvalds else { 39511da177e4SLinus Torvalds 3952db038cf8SAlexey Dobriyan p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun; 39531da177e4SLinus Torvalds } 39541da177e4SLinus Torvalds 39551da177e4SLinus Torvalds p_sccb->HostStatus = 0x00; 39561da177e4SLinus Torvalds p_sccb->TargetStatus = 0x00; 39571da177e4SLinus Torvalds p_sccb->Sccb_tag = 0x00; 39581da177e4SLinus Torvalds p_sccb->Sccb_MGRFlags = 0x00; 39591da177e4SLinus Torvalds p_sccb->Sccb_sgseg = 0x00; 39601da177e4SLinus Torvalds p_sccb->Sccb_ATC = 0x00; 39611da177e4SLinus Torvalds p_sccb->Sccb_savedATC = 0x00; 39621da177e4SLinus Torvalds /* 39631da177e4SLinus Torvalds p_sccb->SccbVirtDataPtr = 0x00; 39641da177e4SLinus Torvalds p_sccb->Sccb_forwardlink = NULL; 39651da177e4SLinus Torvalds p_sccb->Sccb_backlink = NULL; 39661da177e4SLinus Torvalds */ 39671da177e4SLinus Torvalds p_sccb->Sccb_scsistat = BUS_FREE_ST; 39681da177e4SLinus Torvalds p_sccb->SccbStatus = SCCB_IN_PROCESS; 39691da177e4SLinus Torvalds p_sccb->Sccb_scsimsg = SMNO_OP; 39701da177e4SLinus Torvalds 39711da177e4SLinus Torvalds } 39721da177e4SLinus Torvalds 39731da177e4SLinus Torvalds /*--------------------------------------------------------------------- 39741da177e4SLinus Torvalds * 39751da177e4SLinus Torvalds * Function: Phase Decode 39761da177e4SLinus Torvalds * 39771da177e4SLinus Torvalds * Description: Determine the phase and call the appropriate function. 39781da177e4SLinus Torvalds * 39791da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 39801da177e4SLinus Torvalds 3981391e2f25SKhalid Aziz static void FPT_phaseDecode(u32 p_port, unsigned char p_card) 39821da177e4SLinus Torvalds { 39831da177e4SLinus Torvalds unsigned char phase_ref; 3984391e2f25SKhalid Aziz void (*phase) (u32, unsigned char); 39851da177e4SLinus Torvalds 39861da177e4SLinus Torvalds DISABLE_AUTO(p_port); 39871da177e4SLinus Torvalds 39885c04a7b8SAlexey Dobriyan phase_ref = 39895c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ); 39901da177e4SLinus Torvalds 399147b5d69cSJames Bottomley phase = FPT_s_PhaseTbl[phase_ref]; 39921da177e4SLinus Torvalds 39931da177e4SLinus Torvalds (*phase) (p_port, p_card); /* Call the correct phase func */ 39941da177e4SLinus Torvalds } 39951da177e4SLinus Torvalds 39961da177e4SLinus Torvalds /*--------------------------------------------------------------------- 39971da177e4SLinus Torvalds * 39981da177e4SLinus Torvalds * Function: Data Out Phase 39991da177e4SLinus Torvalds * 40001da177e4SLinus Torvalds * Description: Start up both the BusMaster and Xbow. 40011da177e4SLinus Torvalds * 40021da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 40031da177e4SLinus Torvalds 4004391e2f25SKhalid Aziz static void FPT_phaseDataOut(u32 port, unsigned char p_card) 40051da177e4SLinus Torvalds { 40061da177e4SLinus Torvalds 400769eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 40081da177e4SLinus Torvalds 400947b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 40105c04a7b8SAlexey Dobriyan if (currSCCB == NULL) { 40111da177e4SLinus Torvalds return; /* Exit if No SCCB record */ 40121da177e4SLinus Torvalds } 40131da177e4SLinus Torvalds 40141da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DATA_OUT_ST; 40151da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET); 40161da177e4SLinus Torvalds 40171da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 40181da177e4SLinus Torvalds 40191da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), XFER_CNT_0); 40201da177e4SLinus Torvalds 40211da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START)); 40221da177e4SLinus Torvalds 402347b5d69cSJames Bottomley FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); 40241da177e4SLinus Torvalds 40251da177e4SLinus Torvalds if (currSCCB->Sccb_XferCnt == 0) { 40261da177e4SLinus Torvalds 40271da177e4SLinus Torvalds if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) && 40281da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE)) 40291da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_DATA_OVER_RUN; 40301da177e4SLinus Torvalds 403147b5d69cSJames Bottomley FPT_sxfrp(port, p_card); 40321da177e4SLinus Torvalds if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET))) 403347b5d69cSJames Bottomley FPT_phaseDecode(port, p_card); 40341da177e4SLinus Torvalds } 40351da177e4SLinus Torvalds } 40361da177e4SLinus Torvalds 40371da177e4SLinus Torvalds /*--------------------------------------------------------------------- 40381da177e4SLinus Torvalds * 40391da177e4SLinus Torvalds * Function: Data In Phase 40401da177e4SLinus Torvalds * 40411da177e4SLinus Torvalds * Description: Startup the BusMaster and the XBOW. 40421da177e4SLinus Torvalds * 40431da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 40441da177e4SLinus Torvalds 4045391e2f25SKhalid Aziz static void FPT_phaseDataIn(u32 port, unsigned char p_card) 40461da177e4SLinus Torvalds { 40471da177e4SLinus Torvalds 404869eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 40491da177e4SLinus Torvalds 405047b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 40511da177e4SLinus Torvalds 40525c04a7b8SAlexey Dobriyan if (currSCCB == NULL) { 40531da177e4SLinus Torvalds return; /* Exit if No SCCB record */ 40541da177e4SLinus Torvalds } 40551da177e4SLinus Torvalds 40561da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DATA_IN_ST; 40571da177e4SLinus Torvalds currSCCB->Sccb_XferState |= F_HOST_XFER_DIR; 40581da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~F_NO_DATA_YET; 40591da177e4SLinus Torvalds 40601da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT); 40611da177e4SLinus Torvalds 40621da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), XFER_CNT_0); 40631da177e4SLinus Torvalds 40641da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START)); 40651da177e4SLinus Torvalds 406647b5d69cSJames Bottomley FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); 40671da177e4SLinus Torvalds 40681da177e4SLinus Torvalds if (currSCCB->Sccb_XferCnt == 0) { 40691da177e4SLinus Torvalds 40701da177e4SLinus Torvalds if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) && 40711da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE)) 40721da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_DATA_OVER_RUN; 40731da177e4SLinus Torvalds 407447b5d69cSJames Bottomley FPT_sxfrp(port, p_card); 40751da177e4SLinus Torvalds if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET))) 407647b5d69cSJames Bottomley FPT_phaseDecode(port, p_card); 40771da177e4SLinus Torvalds 40781da177e4SLinus Torvalds } 40791da177e4SLinus Torvalds } 40801da177e4SLinus Torvalds 40811da177e4SLinus Torvalds /*--------------------------------------------------------------------- 40821da177e4SLinus Torvalds * 40831da177e4SLinus Torvalds * Function: Command Phase 40841da177e4SLinus Torvalds * 40851da177e4SLinus Torvalds * Description: Load the CDB into the automation and start it up. 40861da177e4SLinus Torvalds * 40871da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 40881da177e4SLinus Torvalds 4089391e2f25SKhalid Aziz static void FPT_phaseCommand(u32 p_port, unsigned char p_card) 40901da177e4SLinus Torvalds { 409169eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 4092391e2f25SKhalid Aziz u32 cdb_reg; 4093db038cf8SAlexey Dobriyan unsigned char i; 40941da177e4SLinus Torvalds 409547b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 40961da177e4SLinus Torvalds 40971da177e4SLinus Torvalds if (currSCCB->OperationCode == RESET_COMMAND) { 40981da177e4SLinus Torvalds 40991da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; 41001da177e4SLinus Torvalds currSCCB->CdbLength = SIX_BYTE_CMD; 41011da177e4SLinus Torvalds } 41021da177e4SLinus Torvalds 41031da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, 0x00); 41041da177e4SLinus Torvalds 41051da177e4SLinus Torvalds ARAM_ACCESS(p_port); 41061da177e4SLinus Torvalds 41071da177e4SLinus Torvalds cdb_reg = p_port + CMD_STRT; 41081da177e4SLinus Torvalds 41091da177e4SLinus Torvalds for (i = 0; i < currSCCB->CdbLength; i++) { 41101da177e4SLinus Torvalds 41111da177e4SLinus Torvalds if (currSCCB->OperationCode == RESET_COMMAND) 41121da177e4SLinus Torvalds 41131da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00)); 41141da177e4SLinus Torvalds 41151da177e4SLinus Torvalds else 41165c04a7b8SAlexey Dobriyan WRW_HARPOON(cdb_reg, 41175c04a7b8SAlexey Dobriyan (MPM_OP + ACOMMAND + currSCCB->Cdb[i])); 41181da177e4SLinus Torvalds cdb_reg += 2; 41191da177e4SLinus Torvalds } 41201da177e4SLinus Torvalds 41211da177e4SLinus Torvalds if (currSCCB->CdbLength != TWELVE_BYTE_CMD) 41221da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP)); 41231da177e4SLinus Torvalds 41241da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT)); 41251da177e4SLinus Torvalds 41261da177e4SLinus Torvalds currSCCB->Sccb_scsistat = COMMAND_ST; 41271da177e4SLinus Torvalds 41281da177e4SLinus Torvalds WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT)); 41291da177e4SLinus Torvalds SGRAM_ACCESS(p_port); 41301da177e4SLinus Torvalds } 41311da177e4SLinus Torvalds 41321da177e4SLinus Torvalds /*--------------------------------------------------------------------- 41331da177e4SLinus Torvalds * 41341da177e4SLinus Torvalds * Function: Status phase 41351da177e4SLinus Torvalds * 41361da177e4SLinus Torvalds * Description: Bring in the status and command complete message bytes 41371da177e4SLinus Torvalds * 41381da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 41391da177e4SLinus Torvalds 4140391e2f25SKhalid Aziz static void FPT_phaseStatus(u32 port, unsigned char p_card) 41411da177e4SLinus Torvalds { 41421da177e4SLinus Torvalds /* Start-up the automation to finish off this command and let the 41431da177e4SLinus Torvalds isr handle the interrupt for command complete when it comes in. 41441da177e4SLinus Torvalds We could wait here for the interrupt to be generated? 41451da177e4SLinus Torvalds */ 41461da177e4SLinus Torvalds 41471da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, 0x00); 41481da177e4SLinus Torvalds 41491da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START)); 41501da177e4SLinus Torvalds } 41511da177e4SLinus Torvalds 41521da177e4SLinus Torvalds /*--------------------------------------------------------------------- 41531da177e4SLinus Torvalds * 41541da177e4SLinus Torvalds * Function: Phase Message Out 41551da177e4SLinus Torvalds * 41561da177e4SLinus Torvalds * Description: Send out our message (if we have one) and handle whatever 41571da177e4SLinus Torvalds * else is involed. 41581da177e4SLinus Torvalds * 41591da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 41601da177e4SLinus Torvalds 4161391e2f25SKhalid Aziz static void FPT_phaseMsgOut(u32 port, unsigned char p_card) 41621da177e4SLinus Torvalds { 4163db038cf8SAlexey Dobriyan unsigned char message, scsiID; 416469eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 4165f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 41661da177e4SLinus Torvalds 416747b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 41681da177e4SLinus Torvalds 41691da177e4SLinus Torvalds if (currSCCB != NULL) { 41701da177e4SLinus Torvalds 41711da177e4SLinus Torvalds message = currSCCB->Sccb_scsimsg; 41721da177e4SLinus Torvalds scsiID = currSCCB->TargID; 41731da177e4SLinus Torvalds 41745c04a7b8SAlexey Dobriyan if (message == SMDEV_RESET) { 41751da177e4SLinus Torvalds 417647b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID]; 41771da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0; 417847b5d69cSJames Bottomley FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info); 41791da177e4SLinus Torvalds 41805c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][scsiID]. 41815c04a7b8SAlexey Dobriyan TarEEValue & EE_SYNC_MASK) { 41821da177e4SLinus Torvalds 41835c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= 41845c04a7b8SAlexey Dobriyan ~TAR_SYNC_MASK; 41851da177e4SLinus Torvalds 41861da177e4SLinus Torvalds } 41871da177e4SLinus Torvalds 41885c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][scsiID]. 41895c04a7b8SAlexey Dobriyan TarEEValue & EE_WIDE_SCSI) { 41901da177e4SLinus Torvalds 41915c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= 41925c04a7b8SAlexey Dobriyan ~TAR_WIDE_MASK; 41931da177e4SLinus Torvalds } 41941da177e4SLinus Torvalds 419547b5d69cSJames Bottomley FPT_queueFlushSccb(p_card, SCCB_COMPLETE); 419647b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, scsiID); 41975c04a7b8SAlexey Dobriyan } else if (currSCCB->Sccb_scsistat == ABORT_ST) { 41981da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_COMPLETE; 41995c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != 42005c04a7b8SAlexey Dobriyan NULL) { 42015c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> 42025c04a7b8SAlexey Dobriyan Sccb_tag] = NULL; 420347b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--; 42041da177e4SLinus Torvalds } 42051da177e4SLinus Torvalds 42061da177e4SLinus Torvalds } 42071da177e4SLinus Torvalds 42085c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat < COMMAND_ST) { 42091da177e4SLinus Torvalds 42105c04a7b8SAlexey Dobriyan if (message == SMNO_OP) { 42111da177e4SLinus Torvalds currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED; 42121da177e4SLinus Torvalds 421347b5d69cSJames Bottomley FPT_ssel(port, p_card); 42141da177e4SLinus Torvalds return; 42151da177e4SLinus Torvalds } 42165c04a7b8SAlexey Dobriyan } else { 42171da177e4SLinus Torvalds 42181da177e4SLinus Torvalds if (message == SMABORT) 42191da177e4SLinus Torvalds 422047b5d69cSJames Bottomley FPT_queueFlushSccb(p_card, SCCB_COMPLETE); 42211da177e4SLinus Torvalds } 42221da177e4SLinus Torvalds 42235c04a7b8SAlexey Dobriyan } else { 42241da177e4SLinus Torvalds message = SMABORT; 42251da177e4SLinus Torvalds } 42261da177e4SLinus Torvalds 42271da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0)); 42281da177e4SLinus Torvalds 42291da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN); 42301da177e4SLinus Torvalds 42311da177e4SLinus Torvalds WR_HARPOON(port + hp_scsidata_0, message); 42321da177e4SLinus Torvalds 42331da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH)); 42341da177e4SLinus Torvalds 42351da177e4SLinus Torvalds ACCEPT_MSG(port); 42361da177e4SLinus Torvalds 42371da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00); 42381da177e4SLinus Torvalds 42391da177e4SLinus Torvalds if ((message == SMABORT) || (message == SMDEV_RESET) || 42405c04a7b8SAlexey Dobriyan (message == SMABORT_TAG)) { 42411da177e4SLinus Torvalds 42425c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) { 42435c04a7b8SAlexey Dobriyan } 42441da177e4SLinus Torvalds 42455c04a7b8SAlexey Dobriyan if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) { 42461da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), BUS_FREE); 42471da177e4SLinus Torvalds 42485c04a7b8SAlexey Dobriyan if (currSCCB != NULL) { 42491da177e4SLinus Torvalds 42505c04a7b8SAlexey Dobriyan if ((FPT_BL_Card[p_card]. 42515c04a7b8SAlexey Dobriyan globalFlags & F_CONLUN_IO) 42525c04a7b8SAlexey Dobriyan && 42535c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 42545c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != 42555c04a7b8SAlexey Dobriyan TAG_Q_TRYING)) 42565c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB-> 42575c04a7b8SAlexey Dobriyan TargID]. 42585c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 0; 42591da177e4SLinus Torvalds else 42605c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB-> 42615c04a7b8SAlexey Dobriyan TargID]. 42625c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 0; 42631da177e4SLinus Torvalds 42645c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], 42655c04a7b8SAlexey Dobriyan currSCCB, p_card); 42661da177e4SLinus Torvalds } 42671da177e4SLinus Torvalds 42685c04a7b8SAlexey Dobriyan else { 42695c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |= 42705c04a7b8SAlexey Dobriyan F_NEW_SCCB_CMD; 42711da177e4SLinus Torvalds } 42721da177e4SLinus Torvalds } 42731da177e4SLinus Torvalds 42745c04a7b8SAlexey Dobriyan else { 42751da177e4SLinus Torvalds 427647b5d69cSJames Bottomley FPT_sxfrp(port, p_card); 42771da177e4SLinus Torvalds } 42781da177e4SLinus Torvalds } 42791da177e4SLinus Torvalds 42805c04a7b8SAlexey Dobriyan else { 42811da177e4SLinus Torvalds 42825c04a7b8SAlexey Dobriyan if (message == SMPARITY) { 42831da177e4SLinus Torvalds currSCCB->Sccb_scsimsg = SMNO_OP; 42845c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 42855c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 42865c04a7b8SAlexey Dobriyan } else { 428747b5d69cSJames Bottomley FPT_sxfrp(port, p_card); 42881da177e4SLinus Torvalds } 42891da177e4SLinus Torvalds } 42901da177e4SLinus Torvalds } 42911da177e4SLinus Torvalds 42921da177e4SLinus Torvalds /*--------------------------------------------------------------------- 42931da177e4SLinus Torvalds * 42941da177e4SLinus Torvalds * Function: Message In phase 42951da177e4SLinus Torvalds * 42961da177e4SLinus Torvalds * Description: Bring in the message and determine what to do with it. 42971da177e4SLinus Torvalds * 42981da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 42991da177e4SLinus Torvalds 4300391e2f25SKhalid Aziz static void FPT_phaseMsgIn(u32 port, unsigned char p_card) 43011da177e4SLinus Torvalds { 4302db038cf8SAlexey Dobriyan unsigned char message; 430369eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 43041da177e4SLinus Torvalds 430547b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 43061da177e4SLinus Torvalds 43075c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) { 43081da177e4SLinus Torvalds 430947b5d69cSJames Bottomley FPT_phaseChkFifo(port, p_card); 43101da177e4SLinus Torvalds } 43111da177e4SLinus Torvalds 43121da177e4SLinus Torvalds message = RD_HARPOON(port + hp_scsidata_0); 43135c04a7b8SAlexey Dobriyan if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) { 43141da177e4SLinus Torvalds 43155c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 43165c04a7b8SAlexey Dobriyan (AUTO_IMMED + END_DATA_START)); 43171da177e4SLinus Torvalds 43181da177e4SLinus Torvalds } 43191da177e4SLinus Torvalds 43205c04a7b8SAlexey Dobriyan else { 43211da177e4SLinus Torvalds 432247b5d69cSJames Bottomley message = FPT_sfm(port, currSCCB); 43235c04a7b8SAlexey Dobriyan if (message) { 43241da177e4SLinus Torvalds 432547b5d69cSJames Bottomley FPT_sdecm(message, port, p_card); 43261da177e4SLinus Torvalds 43275c04a7b8SAlexey Dobriyan } else { 43281da177e4SLinus Torvalds if (currSCCB->Sccb_scsimsg != SMPARITY) 43291da177e4SLinus Torvalds ACCEPT_MSG(port); 43305c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1, 43315c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START)); 43321da177e4SLinus Torvalds } 43331da177e4SLinus Torvalds } 43341da177e4SLinus Torvalds 43351da177e4SLinus Torvalds } 43361da177e4SLinus Torvalds 43371da177e4SLinus Torvalds /*--------------------------------------------------------------------- 43381da177e4SLinus Torvalds * 43391da177e4SLinus Torvalds * Function: Illegal phase 43401da177e4SLinus Torvalds * 43411da177e4SLinus Torvalds * Description: Target switched to some illegal phase, so all we can do 43421da177e4SLinus Torvalds * is report an error back to the host (if that is possible) 43431da177e4SLinus Torvalds * and send an ABORT message to the misbehaving target. 43441da177e4SLinus Torvalds * 43451da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 43461da177e4SLinus Torvalds 4347391e2f25SKhalid Aziz static void FPT_phaseIllegal(u32 port, unsigned char p_card) 43481da177e4SLinus Torvalds { 434969eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 43501da177e4SLinus Torvalds 435147b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 43521da177e4SLinus Torvalds 43531da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig)); 43541da177e4SLinus Torvalds if (currSCCB != NULL) { 43551da177e4SLinus Torvalds 43561da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; 43571da177e4SLinus Torvalds currSCCB->Sccb_scsistat = ABORT_ST; 43581da177e4SLinus Torvalds currSCCB->Sccb_scsimsg = SMABORT; 43591da177e4SLinus Torvalds } 43601da177e4SLinus Torvalds 43611da177e4SLinus Torvalds ACCEPT_MSG_ATN(port); 43621da177e4SLinus Torvalds } 43631da177e4SLinus Torvalds 43641da177e4SLinus Torvalds /*--------------------------------------------------------------------- 43651da177e4SLinus Torvalds * 43661da177e4SLinus Torvalds * Function: Phase Check FIFO 43671da177e4SLinus Torvalds * 43681da177e4SLinus Torvalds * Description: Make sure data has been flushed from both FIFOs and abort 43691da177e4SLinus Torvalds * the operations if necessary. 43701da177e4SLinus Torvalds * 43711da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 43721da177e4SLinus Torvalds 4373391e2f25SKhalid Aziz static void FPT_phaseChkFifo(u32 port, unsigned char p_card) 43741da177e4SLinus Torvalds { 4375391e2f25SKhalid Aziz u32 xfercnt; 437669eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 43771da177e4SLinus Torvalds 437847b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 43791da177e4SLinus Torvalds 43805c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == DATA_IN_ST) { 43811da177e4SLinus Torvalds 43821da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) && 43835c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) { 43845c04a7b8SAlexey Dobriyan } 43851da177e4SLinus Torvalds 43865c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) { 43871da177e4SLinus Torvalds currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt; 43881da177e4SLinus Torvalds 43891da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 0; 43901da177e4SLinus Torvalds 43911da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && 43925c04a7b8SAlexey Dobriyan (currSCCB->HostStatus == SCCB_COMPLETE)) { 43931da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PARITY_ERR; 43941da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY); 43951da177e4SLinus Torvalds } 43961da177e4SLinus Torvalds 439747b5d69cSJames Bottomley FPT_hostDataXferAbort(port, p_card, currSCCB); 43981da177e4SLinus Torvalds 439947b5d69cSJames Bottomley FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]); 44001da177e4SLinus Torvalds 44015c04a7b8SAlexey Dobriyan while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) 44025c04a7b8SAlexey Dobriyan && (RD_HARPOON(port + hp_ext_status) & 44035c04a7b8SAlexey Dobriyan BM_CMD_BUSY)) { 44045c04a7b8SAlexey Dobriyan } 44051da177e4SLinus Torvalds 44061da177e4SLinus Torvalds } 44075c04a7b8SAlexey Dobriyan } 44081da177e4SLinus Torvalds 44095c04a7b8SAlexey Dobriyan /*End Data In specific code. */ 44101da177e4SLinus Torvalds GET_XFER_CNT(port, xfercnt); 44111da177e4SLinus Torvalds 44121da177e4SLinus Torvalds WR_HARPOON(port + hp_xfercnt_0, 0x00); 44131da177e4SLinus Torvalds 44141da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00); 44151da177e4SLinus Torvalds 44161da177e4SLinus Torvalds currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt); 44171da177e4SLinus Torvalds 44181da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = xfercnt; 44191da177e4SLinus Torvalds 44201da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) && 44211da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE)) { 44221da177e4SLinus Torvalds 44231da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PARITY_ERR; 44241da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY); 44251da177e4SLinus Torvalds } 44261da177e4SLinus Torvalds 442747b5d69cSJames Bottomley FPT_hostDataXferAbort(port, p_card, currSCCB); 44281da177e4SLinus Torvalds 44291da177e4SLinus Torvalds WR_HARPOON(port + hp_fifowrite, 0x00); 44301da177e4SLinus Torvalds WR_HARPOON(port + hp_fiforead, 0x00); 44311da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0x00); 44321da177e4SLinus Torvalds 44331da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), XFER_CNT_0); 44341da177e4SLinus Torvalds } 44351da177e4SLinus Torvalds 44361da177e4SLinus Torvalds /*--------------------------------------------------------------------- 44371da177e4SLinus Torvalds * 44381da177e4SLinus Torvalds * Function: Phase Bus Free 44391da177e4SLinus Torvalds * 44401da177e4SLinus Torvalds * Description: We just went bus free so figure out if it was 44411da177e4SLinus Torvalds * because of command complete or from a disconnect. 44421da177e4SLinus Torvalds * 44431da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 4444391e2f25SKhalid Aziz static void FPT_phaseBusFree(u32 port, unsigned char p_card) 44451da177e4SLinus Torvalds { 444669eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 44471da177e4SLinus Torvalds 444847b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 44491da177e4SLinus Torvalds 44505c04a7b8SAlexey Dobriyan if (currSCCB != NULL) { 44511da177e4SLinus Torvalds 44521da177e4SLinus Torvalds DISABLE_AUTO(port); 44531da177e4SLinus Torvalds 44545c04a7b8SAlexey Dobriyan if (currSCCB->OperationCode == RESET_COMMAND) { 44551da177e4SLinus Torvalds 445647b5d69cSJames Bottomley if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 44575c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 44585c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) 44595c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 44605c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 0; 44611da177e4SLinus Torvalds else 44625c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 44635c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 0; 44641da177e4SLinus Torvalds 44655c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, 44665c04a7b8SAlexey Dobriyan p_card); 44671da177e4SLinus Torvalds 446847b5d69cSJames Bottomley FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card); 44691da177e4SLinus Torvalds 44701da177e4SLinus Torvalds } 44711da177e4SLinus Torvalds 44725c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { 447347b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= 4474db038cf8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED; 44755c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= 44765c04a7b8SAlexey Dobriyan ~EE_SYNC_MASK; 44771da177e4SLinus Torvalds } 44781da177e4SLinus Torvalds 44795c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { 448047b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = 448147b5d69cSJames Bottomley (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 44821da177e4SLinus Torvalds TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; 44831da177e4SLinus Torvalds 44845c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= 44855c04a7b8SAlexey Dobriyan ~EE_WIDE_SCSI; 44861da177e4SLinus Torvalds } 44871da177e4SLinus Torvalds 44885c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) { 44891da177e4SLinus Torvalds /* Make sure this is not a phony BUS_FREE. If we were 44901da177e4SLinus Torvalds reselected or if BUSY is NOT on then this is a 44911da177e4SLinus Torvalds valid BUS FREE. SRR Wednesday, 5/10/1995. */ 44921da177e4SLinus Torvalds 44931da177e4SLinus Torvalds if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) || 44945c04a7b8SAlexey Dobriyan (RDW_HARPOON((port + hp_intstat)) & RSEL)) { 44955c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 44965c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_TAG_Q_MASK; 44975c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 44985c04a7b8SAlexey Dobriyan TarStatus |= TAG_Q_REJECT; 44991da177e4SLinus Torvalds } 45001da177e4SLinus Torvalds 45015c04a7b8SAlexey Dobriyan else { 45021da177e4SLinus Torvalds return; 45031da177e4SLinus Torvalds } 45041da177e4SLinus Torvalds } 45051da177e4SLinus Torvalds 45065c04a7b8SAlexey Dobriyan else { 45071da177e4SLinus Torvalds 45081da177e4SLinus Torvalds currSCCB->Sccb_scsistat = BUS_FREE_ST; 45091da177e4SLinus Torvalds 45105c04a7b8SAlexey Dobriyan if (!currSCCB->HostStatus) { 45111da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; 45121da177e4SLinus Torvalds } 45131da177e4SLinus Torvalds 451447b5d69cSJames Bottomley if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 45155c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 45165c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) 45175c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 45185c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 0; 45191da177e4SLinus Torvalds else 45205c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 45215c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 0; 45221da177e4SLinus Torvalds 45235c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, 45245c04a7b8SAlexey Dobriyan p_card); 45251da177e4SLinus Torvalds return; 45261da177e4SLinus Torvalds } 45271da177e4SLinus Torvalds 452847b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; 45291da177e4SLinus Torvalds 45301da177e4SLinus Torvalds } /*end if !=null */ 45311da177e4SLinus Torvalds } 45321da177e4SLinus Torvalds 45331da177e4SLinus Torvalds /*--------------------------------------------------------------------- 45341da177e4SLinus Torvalds * 45351da177e4SLinus Torvalds * Function: Auto Load Default Map 45361da177e4SLinus Torvalds * 45371da177e4SLinus Torvalds * Description: Load the Automation RAM with the defualt map values. 45381da177e4SLinus Torvalds * 45391da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 4540391e2f25SKhalid Aziz static void FPT_autoLoadDefaultMap(u32 p_port) 45411da177e4SLinus Torvalds { 4542391e2f25SKhalid Aziz u32 map_addr; 45431da177e4SLinus Torvalds 45441da177e4SLinus Torvalds ARAM_ACCESS(p_port); 45451da177e4SLinus Torvalds map_addr = p_port + hp_aramBase; 45461da177e4SLinus Torvalds 45471da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */ 45481da177e4SLinus Torvalds map_addr += 2; 45491da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */ 45501da177e4SLinus Torvalds map_addr += 2; 45511da177e4SLinus Torvalds WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */ 45521da177e4SLinus Torvalds map_addr += 2; 45531da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */ 45541da177e4SLinus Torvalds map_addr += 2; 45551da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */ 45561da177e4SLinus Torvalds map_addr += 2; 45571da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */ 45581da177e4SLinus Torvalds map_addr += 2; 45591da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */ 45601da177e4SLinus Torvalds map_addr += 2; 45611da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */ 45621da177e4SLinus Torvalds map_addr += 2; 45631da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */ 45641da177e4SLinus Torvalds map_addr += 2; 45651da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */ 45661da177e4SLinus Torvalds map_addr += 2; 45671da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */ 45681da177e4SLinus Torvalds map_addr += 2; 45691da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */ 45701da177e4SLinus Torvalds map_addr += 2; 45711da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */ 45721da177e4SLinus Torvalds map_addr += 2; 45731da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */ 45741da177e4SLinus Torvalds map_addr += 2; 45751da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */ 45761da177e4SLinus Torvalds map_addr += 2; 45771da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */ 45781da177e4SLinus Torvalds map_addr += 2; 45791da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */ 45801da177e4SLinus Torvalds map_addr += 2; 45811da177e4SLinus Torvalds WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */ 45821da177e4SLinus Torvalds map_addr += 2; /*This means AYNC DATA IN */ 45831da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */ 45841da177e4SLinus Torvalds map_addr += 2; 45851da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */ 45861da177e4SLinus Torvalds map_addr += 2; 45871da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */ 45881da177e4SLinus Torvalds map_addr += 2; 45891da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */ 45901da177e4SLinus Torvalds map_addr += 2; 45911da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */ 45921da177e4SLinus Torvalds map_addr += 2; 45931da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */ 45941da177e4SLinus Torvalds map_addr += 2; 45951da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */ 45961da177e4SLinus Torvalds map_addr += 2; 45971da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */ 45981da177e4SLinus Torvalds map_addr += 2; 45991da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */ 46001da177e4SLinus Torvalds map_addr += 2; 46011da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */ 46021da177e4SLinus Torvalds map_addr += 2; 46031da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */ 46041da177e4SLinus Torvalds map_addr += 2; 46051da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */ 46061da177e4SLinus Torvalds map_addr += 2; 46071da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */ 46081da177e4SLinus Torvalds map_addr += 2; 46091da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */ 46101da177e4SLinus Torvalds map_addr += 2; 46111da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */ 46121da177e4SLinus Torvalds map_addr += 2; 46131da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */ 46141da177e4SLinus Torvalds map_addr += 2; 46151da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */ 46161da177e4SLinus Torvalds map_addr += 2; 46171da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */ 46181da177e4SLinus Torvalds map_addr += 2; 46191da177e4SLinus Torvalds 46201da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */ 46211da177e4SLinus Torvalds map_addr += 2; 46221da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */ 46231da177e4SLinus Torvalds map_addr += 2; 46241da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */ 46251da177e4SLinus Torvalds map_addr += 2; 46261da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */ 46271da177e4SLinus Torvalds map_addr += 2; /* DIDN'T GET ONE */ 46281da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */ 46291da177e4SLinus Torvalds map_addr += 2; 46301da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */ 46311da177e4SLinus Torvalds map_addr += 2; 46321da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */ 46331da177e4SLinus Torvalds 46341da177e4SLinus Torvalds SGRAM_ACCESS(p_port); 46351da177e4SLinus Torvalds } 46361da177e4SLinus Torvalds 46371da177e4SLinus Torvalds /*--------------------------------------------------------------------- 46381da177e4SLinus Torvalds * 46391da177e4SLinus Torvalds * Function: Auto Command Complete 46401da177e4SLinus Torvalds * 46411da177e4SLinus Torvalds * Description: Post command back to host and find another command 46421da177e4SLinus Torvalds * to execute. 46431da177e4SLinus Torvalds * 46441da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 46451da177e4SLinus Torvalds 4646391e2f25SKhalid Aziz static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card) 46471da177e4SLinus Torvalds { 464869eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 4649db038cf8SAlexey Dobriyan unsigned char status_byte; 46501da177e4SLinus Torvalds 465147b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 46521da177e4SLinus Torvalds 46531da177e4SLinus Torvalds status_byte = RD_HARPOON(p_port + hp_gp_reg_0); 46541da177e4SLinus Torvalds 465547b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0; 46561da177e4SLinus Torvalds 46571da177e4SLinus Torvalds if (status_byte != SSGOOD) { 46581da177e4SLinus Torvalds 46591da177e4SLinus Torvalds if (status_byte == SSQ_FULL) { 46601da177e4SLinus Torvalds 466147b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 46625c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 46635c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { 46645c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 46655c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 1; 466647b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 466747b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--; 46685c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 46695c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card] 46705c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 46715c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->Lun]] = 46725c04a7b8SAlexey Dobriyan NULL; 46735c04a7b8SAlexey Dobriyan } else { 46745c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 46755c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1; 46765c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) { 467747b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 46785c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 46795c04a7b8SAlexey Dobriyan discQCount--; 46805c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> 46815c04a7b8SAlexey Dobriyan Sccb_tag] 46825c04a7b8SAlexey Dobriyan = NULL; 46835c04a7b8SAlexey Dobriyan } else { 468447b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 46855c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 46865c04a7b8SAlexey Dobriyan discQCount--; 46875c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 46885c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card] 46895c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 46905c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL; 46911da177e4SLinus Torvalds } 46921da177e4SLinus Torvalds } 46931da177e4SLinus Torvalds 46941da177e4SLinus Torvalds currSCCB->Sccb_MGRFlags |= F_STATUSLOADED; 46951da177e4SLinus Torvalds 469647b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card); 46971da177e4SLinus Torvalds 46981da177e4SLinus Torvalds return; 46991da177e4SLinus Torvalds } 47001da177e4SLinus Torvalds 47015c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { 470247b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= 4703db038cf8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED; 47041da177e4SLinus Torvalds 47055c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= 47065c04a7b8SAlexey Dobriyan ~EE_SYNC_MASK; 470747b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; 47081da177e4SLinus Torvalds 470947b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 47105c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47115c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { 47125c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47135c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 1; 471447b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 471547b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--; 47165c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47175c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card] 47185c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 47195c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->Lun]] = 47205c04a7b8SAlexey Dobriyan NULL; 47215c04a7b8SAlexey Dobriyan } else { 47225c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47235c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1; 47245c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) { 472547b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 47265c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47275c04a7b8SAlexey Dobriyan discQCount--; 47285c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> 47295c04a7b8SAlexey Dobriyan Sccb_tag] 47305c04a7b8SAlexey Dobriyan = NULL; 47315c04a7b8SAlexey Dobriyan } else { 473247b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 47335c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47345c04a7b8SAlexey Dobriyan discQCount--; 47355c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47365c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card] 47375c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 47385c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL; 47391da177e4SLinus Torvalds } 47401da177e4SLinus Torvalds } 47411da177e4SLinus Torvalds return; 47421da177e4SLinus Torvalds 47431da177e4SLinus Torvalds } 47441da177e4SLinus Torvalds 47455c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_WN_ST) { 47461da177e4SLinus Torvalds 474747b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = 474847b5d69cSJames Bottomley (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47491da177e4SLinus Torvalds TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; 47501da177e4SLinus Torvalds 47515c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= 47525c04a7b8SAlexey Dobriyan ~EE_WIDE_SCSI; 475347b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; 47541da177e4SLinus Torvalds 475547b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 47565c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47575c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { 47585c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47595c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 1; 476047b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 476147b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--; 47625c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47635c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card] 47645c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 47655c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->Lun]] = 47665c04a7b8SAlexey Dobriyan NULL; 47675c04a7b8SAlexey Dobriyan } else { 47685c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47695c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1; 47705c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) { 477147b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 47725c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47735c04a7b8SAlexey Dobriyan discQCount--; 47745c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB-> 47755c04a7b8SAlexey Dobriyan Sccb_tag] 47765c04a7b8SAlexey Dobriyan = NULL; 47775c04a7b8SAlexey Dobriyan } else { 477847b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0) 47795c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47805c04a7b8SAlexey Dobriyan discQCount--; 47815c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 47825c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card] 47835c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 47845c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL; 47851da177e4SLinus Torvalds } 47861da177e4SLinus Torvalds } 47871da177e4SLinus Torvalds return; 47881da177e4SLinus Torvalds 47891da177e4SLinus Torvalds } 47901da177e4SLinus Torvalds 47915c04a7b8SAlexey Dobriyan if (status_byte == SSCHECK) { 47925c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) { 47935c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 47945c04a7b8SAlexey Dobriyan TarEEValue & EE_SYNC_MASK) { 47955c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB-> 47965c04a7b8SAlexey Dobriyan TargID]. 47975c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_SYNC_MASK; 47981da177e4SLinus Torvalds } 47995c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 48005c04a7b8SAlexey Dobriyan TarEEValue & EE_WIDE_SCSI) { 48015c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB-> 48025c04a7b8SAlexey Dobriyan TargID]. 48035c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_WIDE_MASK; 48041da177e4SLinus Torvalds } 48051da177e4SLinus Torvalds } 48061da177e4SLinus Torvalds } 48071da177e4SLinus Torvalds 48081da177e4SLinus Torvalds if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) { 48091da177e4SLinus Torvalds 48101da177e4SLinus Torvalds currSCCB->SccbStatus = SCCB_ERROR; 48111da177e4SLinus Torvalds currSCCB->TargetStatus = status_byte; 48121da177e4SLinus Torvalds 48131da177e4SLinus Torvalds if (status_byte == SSCHECK) { 48141da177e4SLinus Torvalds 48155c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 48165c04a7b8SAlexey Dobriyan TarLUN_CA = 1; 48171da177e4SLinus Torvalds 48185c04a7b8SAlexey Dobriyan if (currSCCB->RequestSenseLength != 48195c04a7b8SAlexey Dobriyan NO_AUTO_REQUEST_SENSE) { 48201da177e4SLinus Torvalds 48211da177e4SLinus Torvalds if (currSCCB->RequestSenseLength == 0) 48225c04a7b8SAlexey Dobriyan currSCCB->RequestSenseLength = 48235c04a7b8SAlexey Dobriyan 14; 48241da177e4SLinus Torvalds 482547b5d69cSJames Bottomley FPT_ssenss(&FPT_BL_Card[p_card]); 48265c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |= 48275c04a7b8SAlexey Dobriyan F_NEW_SCCB_CMD; 48281da177e4SLinus Torvalds 48295c04a7b8SAlexey Dobriyan if (((FPT_BL_Card[p_card]. 48305c04a7b8SAlexey Dobriyan globalFlags & F_CONLUN_IO) 48315c04a7b8SAlexey Dobriyan && 48325c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card] 48335c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 48345c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != 48355c04a7b8SAlexey Dobriyan TAG_Q_TRYING))) { 48365c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card] 48375c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 48385c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 48395c04a7b8SAlexey Dobriyan 1; 48405c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card]. 48415c04a7b8SAlexey Dobriyan discQCount != 0) 48425c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 48435c04a7b8SAlexey Dobriyan discQCount--; 48445c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 48455c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl 48465c04a7b8SAlexey Dobriyan [p_card] 48475c04a7b8SAlexey Dobriyan [currSCCB-> 48485c04a7b8SAlexey Dobriyan TargID]. 48495c04a7b8SAlexey Dobriyan LunDiscQ_Idx 48505c04a7b8SAlexey Dobriyan [currSCCB->Lun]] = 48515c04a7b8SAlexey Dobriyan NULL; 48525c04a7b8SAlexey Dobriyan } else { 48535c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card] 48545c04a7b8SAlexey Dobriyan [currSCCB->TargID]. 48555c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1; 48565c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) { 48575c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card]. 48585c04a7b8SAlexey Dobriyan discQCount != 0) 48595c04a7b8SAlexey Dobriyan FPT_BL_Card 48605c04a7b8SAlexey Dobriyan [p_card]. 48615c04a7b8SAlexey Dobriyan discQCount--; 48625c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 48635c04a7b8SAlexey Dobriyan discQ_Tbl[currSCCB-> 48645c04a7b8SAlexey Dobriyan Sccb_tag] 48655c04a7b8SAlexey Dobriyan = NULL; 48665c04a7b8SAlexey Dobriyan } else { 48675c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card]. 48685c04a7b8SAlexey Dobriyan discQCount != 0) 48695c04a7b8SAlexey Dobriyan FPT_BL_Card 48705c04a7b8SAlexey Dobriyan [p_card]. 48715c04a7b8SAlexey Dobriyan discQCount--; 48725c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 48735c04a7b8SAlexey Dobriyan discQ_Tbl 48745c04a7b8SAlexey Dobriyan [FPT_sccbMgrTbl 48755c04a7b8SAlexey Dobriyan [p_card][currSCCB-> 48765c04a7b8SAlexey Dobriyan TargID]. 48775c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = 48785c04a7b8SAlexey Dobriyan NULL; 48791da177e4SLinus Torvalds } 48801da177e4SLinus Torvalds } 48811da177e4SLinus Torvalds return; 48821da177e4SLinus Torvalds } 48831da177e4SLinus Torvalds } 488447b5d69cSJames Bottomley } 488547b5d69cSJames Bottomley } 488647b5d69cSJames Bottomley 488747b5d69cSJames Bottomley if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 48885c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. 48895c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) 48905c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB-> 48915c04a7b8SAlexey Dobriyan Lun] = 0; 48921da177e4SLinus Torvalds else 489347b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0; 489447b5d69cSJames Bottomley 489547b5d69cSJames Bottomley FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card); 48961da177e4SLinus Torvalds } 48971da177e4SLinus Torvalds 48981da177e4SLinus Torvalds #define SHORT_WAIT 0x0000000F 48991da177e4SLinus Torvalds #define LONG_WAIT 0x0000FFFFL 49001da177e4SLinus Torvalds 49011da177e4SLinus Torvalds /*--------------------------------------------------------------------- 49021da177e4SLinus Torvalds * 49031da177e4SLinus Torvalds * Function: Data Transfer Processor 49041da177e4SLinus Torvalds * 49051da177e4SLinus Torvalds * Description: This routine performs two tasks. 49061da177e4SLinus Torvalds * (1) Start data transfer by calling HOST_DATA_XFER_START 49071da177e4SLinus Torvalds * function. Once data transfer is started, (2) Depends 49081da177e4SLinus Torvalds * on the type of data transfer mode Scatter/Gather mode 49091da177e4SLinus Torvalds * or NON Scatter/Gather mode. In NON Scatter/Gather mode, 49101da177e4SLinus Torvalds * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for 49111da177e4SLinus Torvalds * data transfer done. In Scatter/Gather mode, this routine 49121da177e4SLinus Torvalds * checks bus master command complete and dual rank busy 49131da177e4SLinus Torvalds * bit to keep chaining SC transfer command. Similarly, 49141da177e4SLinus Torvalds * in Scatter/Gather mode, it checks Sccb_MGRFlag 49151da177e4SLinus Torvalds * (F_HOST_XFER_ACT bit) for data transfer done. 49161da177e4SLinus Torvalds * 49171da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 49181da177e4SLinus Torvalds 4919391e2f25SKhalid Aziz static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard) 49201da177e4SLinus Torvalds { 492169eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 49221da177e4SLinus Torvalds 49231da177e4SLinus Torvalds currSCCB = pCurrCard->currentSCCB; 49241da177e4SLinus Torvalds 49255c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_XferState & F_SG_XFER) { 49261da177e4SLinus Torvalds if (pCurrCard->globalFlags & F_HOST_XFER_ACT) 49271da177e4SLinus Torvalds { 4928db038cf8SAlexey Dobriyan currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT; 49291da177e4SLinus Torvalds currSCCB->Sccb_SGoffset = 0x00; 49301da177e4SLinus Torvalds } 49311da177e4SLinus Torvalds pCurrCard->globalFlags |= F_HOST_XFER_ACT; 49321da177e4SLinus Torvalds 493347b5d69cSJames Bottomley FPT_busMstrSGDataXferStart(port, currSCCB); 49341da177e4SLinus Torvalds } 49351da177e4SLinus Torvalds 49365c04a7b8SAlexey Dobriyan else { 49375c04a7b8SAlexey Dobriyan if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) { 49381da177e4SLinus Torvalds pCurrCard->globalFlags |= F_HOST_XFER_ACT; 49391da177e4SLinus Torvalds 494047b5d69cSJames Bottomley FPT_busMstrDataXferStart(port, currSCCB); 49411da177e4SLinus Torvalds } 49421da177e4SLinus Torvalds } 49431da177e4SLinus Torvalds } 49441da177e4SLinus Torvalds 49451da177e4SLinus Torvalds /*--------------------------------------------------------------------- 49461da177e4SLinus Torvalds * 49471da177e4SLinus Torvalds * Function: BusMaster Scatter Gather Data Transfer Start 49481da177e4SLinus Torvalds * 49491da177e4SLinus Torvalds * Description: 49501da177e4SLinus Torvalds * 49511da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 4952391e2f25SKhalid Aziz static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB) 49531da177e4SLinus Torvalds { 4954391e2f25SKhalid Aziz u32 count, addr, tmpSGCnt; 4955ce793215SAlexey Dobriyan unsigned int sg_index; 4956db038cf8SAlexey Dobriyan unsigned char sg_count, i; 4957391e2f25SKhalid Aziz u32 reg_offset; 4958391e2f25SKhalid Aziz struct blogic_sg_seg *segp; 49591da177e4SLinus Torvalds 4960391e2f25SKhalid Aziz if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) 4961391e2f25SKhalid Aziz count = ((u32)HOST_RD_CMD) << 24; 4962391e2f25SKhalid Aziz else 4963391e2f25SKhalid Aziz count = ((u32)HOST_WRT_CMD) << 24; 49641da177e4SLinus Torvalds 49651da177e4SLinus Torvalds sg_count = 0; 49661da177e4SLinus Torvalds tmpSGCnt = 0; 49671da177e4SLinus Torvalds sg_index = pcurrSCCB->Sccb_sgseg; 49681da177e4SLinus Torvalds reg_offset = hp_aramBase; 49691da177e4SLinus Torvalds 49705c04a7b8SAlexey Dobriyan i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) & 49715c04a7b8SAlexey Dobriyan ~(SGRAM_ARAM | SCATTER_EN)); 49721da177e4SLinus Torvalds 49731da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, i); 49741da177e4SLinus Torvalds 4975db038cf8SAlexey Dobriyan while ((sg_count < (unsigned char)SG_BUF_CNT) && 4976391e2f25SKhalid Aziz ((sg_index * (unsigned int)SG_ELEMENT_SIZE) < 49775c04a7b8SAlexey Dobriyan pcurrSCCB->DataLength)) { 49781da177e4SLinus Torvalds 4979391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) + 4980391e2f25SKhalid Aziz sg_index; 4981391e2f25SKhalid Aziz tmpSGCnt += segp->segbytes; 4982391e2f25SKhalid Aziz count |= segp->segbytes; 4983391e2f25SKhalid Aziz addr = segp->segdata; 49841da177e4SLinus Torvalds 49851da177e4SLinus Torvalds if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) { 49865c04a7b8SAlexey Dobriyan addr += 49875c04a7b8SAlexey Dobriyan ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset); 49885c04a7b8SAlexey Dobriyan count = 49895c04a7b8SAlexey Dobriyan (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset; 49901da177e4SLinus Torvalds tmpSGCnt = count & 0x00FFFFFFL; 49911da177e4SLinus Torvalds } 49921da177e4SLinus Torvalds 49931da177e4SLinus Torvalds WR_HARP32(p_port, reg_offset, addr); 49941da177e4SLinus Torvalds reg_offset += 4; 49951da177e4SLinus Torvalds 49961da177e4SLinus Torvalds WR_HARP32(p_port, reg_offset, count); 49971da177e4SLinus Torvalds reg_offset += 4; 49981da177e4SLinus Torvalds 49991da177e4SLinus Torvalds count &= 0xFF000000L; 50001da177e4SLinus Torvalds sg_index++; 50011da177e4SLinus Torvalds sg_count++; 50021da177e4SLinus Torvalds 50031da177e4SLinus Torvalds } /*End While */ 50041da177e4SLinus Torvalds 50051da177e4SLinus Torvalds pcurrSCCB->Sccb_XferCnt = tmpSGCnt; 50061da177e4SLinus Torvalds 50071da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4)); 50081da177e4SLinus Torvalds 50091da177e4SLinus Torvalds if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { 50101da177e4SLinus Torvalds 50111da177e4SLinus Torvalds WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt); 50121da177e4SLinus Torvalds 50135c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 50145c04a7b8SAlexey Dobriyan (DMA_PORT | SCSI_PORT | SCSI_INBIT)); 50151da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH); 50161da177e4SLinus Torvalds } 50171da177e4SLinus Torvalds 50181da177e4SLinus Torvalds else { 50191da177e4SLinus Torvalds 50201da177e4SLinus Torvalds if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) && 50215c04a7b8SAlexey Dobriyan (tmpSGCnt & 0x000000001)) { 50221da177e4SLinus Torvalds 50231da177e4SLinus Torvalds pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT; 50241da177e4SLinus Torvalds tmpSGCnt--; 50251da177e4SLinus Torvalds } 50261da177e4SLinus Torvalds 50271da177e4SLinus Torvalds WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt); 50281da177e4SLinus Torvalds 50295c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 50305c04a7b8SAlexey Dobriyan (SCSI_PORT | DMA_PORT | DMA_RD)); 50311da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH); 50321da177e4SLinus Torvalds } 50331da177e4SLinus Torvalds 5034db038cf8SAlexey Dobriyan WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN)); 50351da177e4SLinus Torvalds 50361da177e4SLinus Torvalds } 50371da177e4SLinus Torvalds 50381da177e4SLinus Torvalds /*--------------------------------------------------------------------- 50391da177e4SLinus Torvalds * 50401da177e4SLinus Torvalds * Function: BusMaster Data Transfer Start 50411da177e4SLinus Torvalds * 50421da177e4SLinus Torvalds * Description: 50431da177e4SLinus Torvalds * 50441da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 5045391e2f25SKhalid Aziz static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB) 50461da177e4SLinus Torvalds { 5047391e2f25SKhalid Aziz u32 addr, count; 50481da177e4SLinus Torvalds 50491da177e4SLinus Torvalds if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) { 50501da177e4SLinus Torvalds 50511da177e4SLinus Torvalds count = pcurrSCCB->Sccb_XferCnt; 50521da177e4SLinus Torvalds 5053391e2f25SKhalid Aziz addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC; 50541da177e4SLinus Torvalds } 50551da177e4SLinus Torvalds 50561da177e4SLinus Torvalds else { 50571da177e4SLinus Torvalds addr = pcurrSCCB->SensePointer; 50581da177e4SLinus Torvalds count = pcurrSCCB->RequestSenseLength; 50591da177e4SLinus Torvalds 50601da177e4SLinus Torvalds } 50611da177e4SLinus Torvalds 50621da177e4SLinus Torvalds HP_SETUP_ADDR_CNT(p_port, addr, count); 50631da177e4SLinus Torvalds 50641da177e4SLinus Torvalds if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { 50651da177e4SLinus Torvalds 50665c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 50675c04a7b8SAlexey Dobriyan (DMA_PORT | SCSI_PORT | SCSI_INBIT)); 50681da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH); 50691da177e4SLinus Torvalds 50701da177e4SLinus Torvalds WR_HARPOON(p_port + hp_xfer_cmd, 50711da177e4SLinus Torvalds (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT)); 50721da177e4SLinus Torvalds } 50731da177e4SLinus Torvalds 50741da177e4SLinus Torvalds else { 50751da177e4SLinus Torvalds 50765c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0, 50775c04a7b8SAlexey Dobriyan (SCSI_PORT | DMA_PORT | DMA_RD)); 50781da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH); 50791da177e4SLinus Torvalds 50801da177e4SLinus Torvalds WR_HARPOON(p_port + hp_xfer_cmd, 50811da177e4SLinus Torvalds (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT)); 50821da177e4SLinus Torvalds 50831da177e4SLinus Torvalds } 50841da177e4SLinus Torvalds } 50851da177e4SLinus Torvalds 50861da177e4SLinus Torvalds /*--------------------------------------------------------------------- 50871da177e4SLinus Torvalds * 50881da177e4SLinus Torvalds * Function: BusMaster Timeout Handler 50891da177e4SLinus Torvalds * 50901da177e4SLinus Torvalds * Description: This function is called after a bus master command busy time 50911da177e4SLinus Torvalds * out is detected. This routines issue halt state machine 50921da177e4SLinus Torvalds * with a software time out for command busy. If command busy 50931da177e4SLinus Torvalds * is still asserted at the end of the time out, it issues 50941da177e4SLinus Torvalds * hard abort with another software time out. It hard abort 50951da177e4SLinus Torvalds * command busy is also time out, it'll just give up. 50961da177e4SLinus Torvalds * 50971da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 5098391e2f25SKhalid Aziz static unsigned char FPT_busMstrTimeOut(u32 p_port) 50991da177e4SLinus Torvalds { 5100d63a4cccSAlexey Dobriyan unsigned long timeout; 51011da177e4SLinus Torvalds 51021da177e4SLinus Torvalds timeout = LONG_WAIT; 51031da177e4SLinus Torvalds 51041da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH); 51051da177e4SLinus Torvalds 51065c04a7b8SAlexey Dobriyan while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED)) 51075c04a7b8SAlexey Dobriyan && timeout--) { 51085c04a7b8SAlexey Dobriyan } 51091da177e4SLinus Torvalds 51101da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) { 51111da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT); 51121da177e4SLinus Torvalds 51131da177e4SLinus Torvalds timeout = LONG_WAIT; 51145c04a7b8SAlexey Dobriyan while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) 51155c04a7b8SAlexey Dobriyan && timeout--) { 51165c04a7b8SAlexey Dobriyan } 51171da177e4SLinus Torvalds } 51181da177e4SLinus Torvalds 51191da177e4SLinus Torvalds RD_HARPOON(p_port + hp_int_status); /*Clear command complete */ 51201da177e4SLinus Torvalds 51211da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) { 51225c1b85e2SAlexey Dobriyan return 1; 51231da177e4SLinus Torvalds } 51241da177e4SLinus Torvalds 51251da177e4SLinus Torvalds else { 51265c1b85e2SAlexey Dobriyan return 0; 51271da177e4SLinus Torvalds } 51281da177e4SLinus Torvalds } 51291da177e4SLinus Torvalds 51301da177e4SLinus Torvalds /*--------------------------------------------------------------------- 51311da177e4SLinus Torvalds * 51321da177e4SLinus Torvalds * Function: Host Data Transfer Abort 51331da177e4SLinus Torvalds * 51341da177e4SLinus Torvalds * Description: Abort any in progress transfer. 51351da177e4SLinus Torvalds * 51361da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 5137391e2f25SKhalid Aziz static void FPT_hostDataXferAbort(u32 port, unsigned char p_card, 51385c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB) 51391da177e4SLinus Torvalds { 51401da177e4SLinus Torvalds 5141d63a4cccSAlexey Dobriyan unsigned long timeout; 5142d63a4cccSAlexey Dobriyan unsigned long remain_cnt; 5143391e2f25SKhalid Aziz u32 sg_ptr; 5144391e2f25SKhalid Aziz struct blogic_sg_seg *segp; 51451da177e4SLinus Torvalds 514647b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT; 51471da177e4SLinus Torvalds 51481da177e4SLinus Torvalds if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) { 51491da177e4SLinus Torvalds 51501da177e4SLinus Torvalds if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) { 51511da177e4SLinus Torvalds 51525c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl, 51535c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) | 51545c04a7b8SAlexey Dobriyan FLUSH_XFER_CNTR)); 51551da177e4SLinus Torvalds timeout = LONG_WAIT; 51561da177e4SLinus Torvalds 51575c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) 51585c04a7b8SAlexey Dobriyan && timeout--) { 51595c04a7b8SAlexey Dobriyan } 51601da177e4SLinus Torvalds 51615c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl, 51625c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) & 51635c04a7b8SAlexey Dobriyan ~FLUSH_XFER_CNTR)); 51641da177e4SLinus Torvalds 51651da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { 51661da177e4SLinus Torvalds 516747b5d69cSJames Bottomley if (FPT_busMstrTimeOut(port)) { 51681da177e4SLinus Torvalds 51691da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) 51701da177e4SLinus Torvalds 51715c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus = 51725c04a7b8SAlexey Dobriyan SCCB_BM_ERR; 51731da177e4SLinus Torvalds 51741da177e4SLinus Torvalds } 51751da177e4SLinus Torvalds 51765c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_int_status) & 51775c04a7b8SAlexey Dobriyan INT_EXT_STATUS) 51781da177e4SLinus Torvalds 51795c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) & 51805c04a7b8SAlexey Dobriyan BAD_EXT_STATUS) 51811da177e4SLinus Torvalds 51825c04a7b8SAlexey Dobriyan if (pCurrSCCB->HostStatus == 51835c04a7b8SAlexey Dobriyan 0x00) 51841da177e4SLinus Torvalds { 51855c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus = 51865c04a7b8SAlexey Dobriyan SCCB_BM_ERR; 51871da177e4SLinus Torvalds } 51881da177e4SLinus Torvalds } 51891da177e4SLinus Torvalds } 51901da177e4SLinus Torvalds } 51911da177e4SLinus Torvalds 51921da177e4SLinus Torvalds else if (pCurrSCCB->Sccb_XferCnt) { 51931da177e4SLinus Torvalds 51941da177e4SLinus Torvalds if (pCurrSCCB->Sccb_XferState & F_SG_XFER) { 51951da177e4SLinus Torvalds 51965c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_page_ctrl, 51975c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_page_ctrl) & 51981da177e4SLinus Torvalds ~SCATTER_EN)); 51991da177e4SLinus Torvalds 52001da177e4SLinus Torvalds WR_HARPOON(port + hp_sg_addr, 0x00); 52011da177e4SLinus Torvalds 52021da177e4SLinus Torvalds sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT; 52031da177e4SLinus Torvalds 52045c04a7b8SAlexey Dobriyan if (sg_ptr > 52055c04a7b8SAlexey Dobriyan (unsigned int)(pCurrSCCB->DataLength / 52065c04a7b8SAlexey Dobriyan SG_ELEMENT_SIZE)) { 52071da177e4SLinus Torvalds 5208391e2f25SKhalid Aziz sg_ptr = (u32)(pCurrSCCB->DataLength / 52095c04a7b8SAlexey Dobriyan SG_ELEMENT_SIZE); 52101da177e4SLinus Torvalds } 52111da177e4SLinus Torvalds 52121da177e4SLinus Torvalds remain_cnt = pCurrSCCB->Sccb_XferCnt; 52131da177e4SLinus Torvalds 52141da177e4SLinus Torvalds while (remain_cnt < 0x01000000L) { 52151da177e4SLinus Torvalds 52161da177e4SLinus Torvalds sg_ptr--; 5217391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(pCurrSCCB-> 5218391e2f25SKhalid Aziz DataPointer) + (sg_ptr * 2); 5219391e2f25SKhalid Aziz if (remain_cnt > (unsigned long)segp->segbytes) 52205c04a7b8SAlexey Dobriyan remain_cnt -= 5221391e2f25SKhalid Aziz (unsigned long)segp->segbytes; 5222391e2f25SKhalid Aziz else 52231da177e4SLinus Torvalds break; 52241da177e4SLinus Torvalds } 52251da177e4SLinus Torvalds 52261da177e4SLinus Torvalds if (remain_cnt < 0x01000000L) { 52271da177e4SLinus Torvalds 52281da177e4SLinus Torvalds pCurrSCCB->Sccb_SGoffset = remain_cnt; 52291da177e4SLinus Torvalds 5230c823feebSAlexey Dobriyan pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr; 52311da177e4SLinus Torvalds 52325c04a7b8SAlexey Dobriyan if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == 52335c04a7b8SAlexey Dobriyan pCurrSCCB->DataLength && (remain_cnt == 0)) 52341da177e4SLinus Torvalds 52355c04a7b8SAlexey Dobriyan pCurrSCCB->Sccb_XferState |= 52365c04a7b8SAlexey Dobriyan F_ALL_XFERRED; 52371da177e4SLinus Torvalds } 52381da177e4SLinus Torvalds 52391da177e4SLinus Torvalds else { 52401da177e4SLinus Torvalds 52411da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) { 52421da177e4SLinus Torvalds 52435c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus = 52445c04a7b8SAlexey Dobriyan SCCB_GROSS_FW_ERR; 52451da177e4SLinus Torvalds } 52461da177e4SLinus Torvalds } 52471da177e4SLinus Torvalds } 52481da177e4SLinus Torvalds 52491da177e4SLinus Torvalds if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) { 52501da177e4SLinus Torvalds 52511da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { 52521da177e4SLinus Torvalds 525347b5d69cSJames Bottomley FPT_busMstrTimeOut(port); 52541da177e4SLinus Torvalds } 52551da177e4SLinus Torvalds 52561da177e4SLinus Torvalds else { 52571da177e4SLinus Torvalds 52585c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_int_status) & 52595c04a7b8SAlexey Dobriyan INT_EXT_STATUS) { 52601da177e4SLinus Torvalds 52615c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) & 52625c04a7b8SAlexey Dobriyan BAD_EXT_STATUS) { 52631da177e4SLinus Torvalds 52645c04a7b8SAlexey Dobriyan if (pCurrSCCB->HostStatus == 52655c04a7b8SAlexey Dobriyan 0x00) { 52661da177e4SLinus Torvalds 52675c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus = 52685c04a7b8SAlexey Dobriyan SCCB_BM_ERR; 52691da177e4SLinus Torvalds } 52701da177e4SLinus Torvalds } 52711da177e4SLinus Torvalds } 52721da177e4SLinus Torvalds 52731da177e4SLinus Torvalds } 52741da177e4SLinus Torvalds } 52751da177e4SLinus Torvalds 52761da177e4SLinus Torvalds else { 52771da177e4SLinus Torvalds 52781da177e4SLinus Torvalds if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) { 52791da177e4SLinus Torvalds 52801da177e4SLinus Torvalds timeout = SHORT_WAIT; 52811da177e4SLinus Torvalds 52825c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) & 52835c04a7b8SAlexey Dobriyan BM_CMD_BUSY) 52845c04a7b8SAlexey Dobriyan && ((RD_HARPOON(port + hp_fifo_cnt)) >= 52855c04a7b8SAlexey Dobriyan BM_THRESHOLD) && timeout--) { 52865c04a7b8SAlexey Dobriyan } 52871da177e4SLinus Torvalds } 52881da177e4SLinus Torvalds 52891da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { 52901da177e4SLinus Torvalds 52915c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl, 52925c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) | 52931da177e4SLinus Torvalds FLUSH_XFER_CNTR)); 52941da177e4SLinus Torvalds 52951da177e4SLinus Torvalds timeout = LONG_WAIT; 52961da177e4SLinus Torvalds 52975c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) & 52985c04a7b8SAlexey Dobriyan BM_CMD_BUSY) && timeout--) { 52995c04a7b8SAlexey Dobriyan } 53001da177e4SLinus Torvalds 53015c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl, 53025c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) & 53031da177e4SLinus Torvalds ~FLUSH_XFER_CNTR)); 53041da177e4SLinus Torvalds 53055c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) & 53065c04a7b8SAlexey Dobriyan BM_CMD_BUSY) { 53071da177e4SLinus Torvalds 53081da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) { 53091da177e4SLinus Torvalds 53105c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus = 53115c04a7b8SAlexey Dobriyan SCCB_BM_ERR; 53121da177e4SLinus Torvalds } 53131da177e4SLinus Torvalds 531447b5d69cSJames Bottomley FPT_busMstrTimeOut(port); 53151da177e4SLinus Torvalds } 53161da177e4SLinus Torvalds } 53171da177e4SLinus Torvalds 53181da177e4SLinus Torvalds if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) { 53191da177e4SLinus Torvalds 53205c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) & 53215c04a7b8SAlexey Dobriyan BAD_EXT_STATUS) { 53221da177e4SLinus Torvalds 53231da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) { 53241da177e4SLinus Torvalds 53255c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus = 53265c04a7b8SAlexey Dobriyan SCCB_BM_ERR; 53271da177e4SLinus Torvalds } 53281da177e4SLinus Torvalds } 53291da177e4SLinus Torvalds } 53301da177e4SLinus Torvalds } 53311da177e4SLinus Torvalds 53321da177e4SLinus Torvalds } 53331da177e4SLinus Torvalds 53341da177e4SLinus Torvalds else { 53351da177e4SLinus Torvalds 53361da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { 53371da177e4SLinus Torvalds 53381da177e4SLinus Torvalds timeout = LONG_WAIT; 53391da177e4SLinus Torvalds 53405c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) 53415c04a7b8SAlexey Dobriyan && timeout--) { 53425c04a7b8SAlexey Dobriyan } 53431da177e4SLinus Torvalds 53441da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) { 53451da177e4SLinus Torvalds 53461da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) { 53471da177e4SLinus Torvalds 53481da177e4SLinus Torvalds pCurrSCCB->HostStatus = SCCB_BM_ERR; 53491da177e4SLinus Torvalds } 53501da177e4SLinus Torvalds 535147b5d69cSJames Bottomley FPT_busMstrTimeOut(port); 53521da177e4SLinus Torvalds } 53531da177e4SLinus Torvalds } 53541da177e4SLinus Torvalds 53551da177e4SLinus Torvalds if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) { 53561da177e4SLinus Torvalds 53571da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) { 53581da177e4SLinus Torvalds 53591da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) { 53601da177e4SLinus Torvalds 53611da177e4SLinus Torvalds pCurrSCCB->HostStatus = SCCB_BM_ERR; 53621da177e4SLinus Torvalds } 53631da177e4SLinus Torvalds } 53641da177e4SLinus Torvalds 53651da177e4SLinus Torvalds } 53661da177e4SLinus Torvalds 53671da177e4SLinus Torvalds if (pCurrSCCB->Sccb_XferState & F_SG_XFER) { 53681da177e4SLinus Torvalds 53695c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_page_ctrl, 53705c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_page_ctrl) & 53711da177e4SLinus Torvalds ~SCATTER_EN)); 53721da177e4SLinus Torvalds 53731da177e4SLinus Torvalds WR_HARPOON(port + hp_sg_addr, 0x00); 53741da177e4SLinus Torvalds 53751da177e4SLinus Torvalds pCurrSCCB->Sccb_sgseg += SG_BUF_CNT; 53761da177e4SLinus Torvalds 53771da177e4SLinus Torvalds pCurrSCCB->Sccb_SGoffset = 0x00; 53781da177e4SLinus Torvalds 5379391e2f25SKhalid Aziz if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >= 53801da177e4SLinus Torvalds pCurrSCCB->DataLength) { 53811da177e4SLinus Torvalds 53821da177e4SLinus Torvalds pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; 53835c04a7b8SAlexey Dobriyan pCurrSCCB->Sccb_sgseg = 53845c04a7b8SAlexey Dobriyan (unsigned short)(pCurrSCCB->DataLength / 53855c04a7b8SAlexey Dobriyan SG_ELEMENT_SIZE); 53861da177e4SLinus Torvalds } 53871da177e4SLinus Torvalds } 53881da177e4SLinus Torvalds 53891da177e4SLinus Torvalds else { 53901da177e4SLinus Torvalds if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE)) 53911da177e4SLinus Torvalds pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; 53921da177e4SLinus Torvalds } 53931da177e4SLinus Torvalds } 53941da177e4SLinus Torvalds 53951da177e4SLinus Torvalds WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); 53961da177e4SLinus Torvalds } 53971da177e4SLinus Torvalds 53981da177e4SLinus Torvalds /*--------------------------------------------------------------------- 53991da177e4SLinus Torvalds * 54001da177e4SLinus Torvalds * Function: Host Data Transfer Restart 54011da177e4SLinus Torvalds * 54021da177e4SLinus Torvalds * Description: Reset the available count due to a restore data 54031da177e4SLinus Torvalds * pointers message. 54041da177e4SLinus Torvalds * 54051da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 540669eb2ea4SAlexey Dobriyan static void FPT_hostDataXferRestart(struct sccb *currSCCB) 54071da177e4SLinus Torvalds { 5408d63a4cccSAlexey Dobriyan unsigned long data_count; 5409ce793215SAlexey Dobriyan unsigned int sg_index; 5410391e2f25SKhalid Aziz struct blogic_sg_seg *segp; 54111da177e4SLinus Torvalds 54121da177e4SLinus Torvalds if (currSCCB->Sccb_XferState & F_SG_XFER) { 54131da177e4SLinus Torvalds 54141da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 0; 54151da177e4SLinus Torvalds 54161da177e4SLinus Torvalds sg_index = 0xffff; /*Index by long words into sg list. */ 54171da177e4SLinus Torvalds data_count = 0; /*Running count of SG xfer counts. */ 54181da177e4SLinus Torvalds 54191da177e4SLinus Torvalds 54201da177e4SLinus Torvalds while (data_count < currSCCB->Sccb_ATC) { 54211da177e4SLinus Torvalds 54221da177e4SLinus Torvalds sg_index++; 5423391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) + 5424391e2f25SKhalid Aziz (sg_index * 2); 5425391e2f25SKhalid Aziz data_count += segp->segbytes; 54261da177e4SLinus Torvalds } 54271da177e4SLinus Torvalds 54281da177e4SLinus Torvalds if (data_count == currSCCB->Sccb_ATC) { 54291da177e4SLinus Torvalds 54301da177e4SLinus Torvalds currSCCB->Sccb_SGoffset = 0; 54311da177e4SLinus Torvalds sg_index++; 54321da177e4SLinus Torvalds } 54331da177e4SLinus Torvalds 54341da177e4SLinus Torvalds else { 54355c04a7b8SAlexey Dobriyan currSCCB->Sccb_SGoffset = 54365c04a7b8SAlexey Dobriyan data_count - currSCCB->Sccb_ATC; 54371da177e4SLinus Torvalds } 54381da177e4SLinus Torvalds 5439c823feebSAlexey Dobriyan currSCCB->Sccb_sgseg = (unsigned short)sg_index; 54401da177e4SLinus Torvalds } 54411da177e4SLinus Torvalds 54421da177e4SLinus Torvalds else { 54435c04a7b8SAlexey Dobriyan currSCCB->Sccb_XferCnt = 54445c04a7b8SAlexey Dobriyan currSCCB->DataLength - currSCCB->Sccb_ATC; 54451da177e4SLinus Torvalds } 54461da177e4SLinus Torvalds } 54471da177e4SLinus Torvalds 54481da177e4SLinus Torvalds /*--------------------------------------------------------------------- 54491da177e4SLinus Torvalds * 545047b5d69cSJames Bottomley * Function: FPT_scini 54511da177e4SLinus Torvalds * 54521da177e4SLinus Torvalds * Description: Setup all data structures necessary for SCAM selection. 54531da177e4SLinus Torvalds * 54541da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 54551da177e4SLinus Torvalds 54565c04a7b8SAlexey Dobriyan static void FPT_scini(unsigned char p_card, unsigned char p_our_id, 54575c04a7b8SAlexey Dobriyan unsigned char p_power_up) 54581da177e4SLinus Torvalds { 54591da177e4SLinus Torvalds 5460db038cf8SAlexey Dobriyan unsigned char loser, assigned_id; 5461391e2f25SKhalid Aziz u32 p_port; 54621da177e4SLinus Torvalds 5463db038cf8SAlexey Dobriyan unsigned char i, k, ScamFlg; 546413e6851aSAlexey Dobriyan struct sccb_card *currCard; 546568d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 54661da177e4SLinus Torvalds 546747b5d69cSJames Bottomley currCard = &FPT_BL_Card[p_card]; 54681da177e4SLinus Torvalds p_port = currCard->ioPort; 54691da177e4SLinus Torvalds pCurrNvRam = currCard->pNvRamInfo; 54701da177e4SLinus Torvalds 54711da177e4SLinus Torvalds if (pCurrNvRam) { 54721da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf; 54731da177e4SLinus Torvalds i = pCurrNvRam->niSysConf; 54745c04a7b8SAlexey Dobriyan } else { 54755c04a7b8SAlexey Dobriyan ScamFlg = 54765c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2); 54775c04a7b8SAlexey Dobriyan i = (unsigned 54785c04a7b8SAlexey Dobriyan char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2))); 54791da177e4SLinus Torvalds } 54801da177e4SLinus Torvalds if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */ 54811da177e4SLinus Torvalds return; 54821da177e4SLinus Torvalds 548347b5d69cSJames Bottomley FPT_inisci(p_card, p_port, p_our_id); 54841da177e4SLinus Torvalds 54851da177e4SLinus Torvalds /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW 54861da177e4SLinus Torvalds too slow to return to SCAM selection */ 54871da177e4SLinus Torvalds 54881da177e4SLinus Torvalds /* if (p_power_up) 548947b5d69cSJames Bottomley FPT_Wait1Second(p_port); 54901da177e4SLinus Torvalds else 549147b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms); */ 54921da177e4SLinus Torvalds 549347b5d69cSJames Bottomley FPT_Wait1Second(p_port); 54941da177e4SLinus Torvalds 54955c04a7b8SAlexey Dobriyan if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) { 54965c04a7b8SAlexey Dobriyan while (!(FPT_scarb(p_port, INIT_SELTD))) { 54975c04a7b8SAlexey Dobriyan } 54981da177e4SLinus Torvalds 549947b5d69cSJames Bottomley FPT_scsel(p_port); 55001da177e4SLinus Torvalds 55011da177e4SLinus Torvalds do { 550247b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN); 550347b5d69cSJames Bottomley FPT_scxferc(p_port, DOM_MSTR); 55045c04a7b8SAlexey Dobriyan loser = 55055c04a7b8SAlexey Dobriyan FPT_scsendi(p_port, 55065c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id].id_string[0]); 55071da177e4SLinus Torvalds } while (loser == 0xFF); 55081da177e4SLinus Torvalds 550947b5d69cSJames Bottomley FPT_scbusf(p_port); 55101da177e4SLinus Torvalds 55115c04a7b8SAlexey Dobriyan if ((p_power_up) && (!loser)) { 551247b5d69cSJames Bottomley FPT_sresb(p_port, p_card); 551347b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms); 55141da177e4SLinus Torvalds 55155c04a7b8SAlexey Dobriyan while (!(FPT_scarb(p_port, INIT_SELTD))) { 55165c04a7b8SAlexey Dobriyan } 55171da177e4SLinus Torvalds 551847b5d69cSJames Bottomley FPT_scsel(p_port); 55191da177e4SLinus Torvalds 55201da177e4SLinus Torvalds do { 552147b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN); 552247b5d69cSJames Bottomley FPT_scxferc(p_port, DOM_MSTR); 55235c04a7b8SAlexey Dobriyan loser = 55245c04a7b8SAlexey Dobriyan FPT_scsendi(p_port, 55255c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id]. 55261da177e4SLinus Torvalds id_string[0]); 55271da177e4SLinus Torvalds } while (loser == 0xFF); 55281da177e4SLinus Torvalds 552947b5d69cSJames Bottomley FPT_scbusf(p_port); 55301da177e4SLinus Torvalds } 55311da177e4SLinus Torvalds } 55321da177e4SLinus Torvalds 55335c04a7b8SAlexey Dobriyan else { 553447b5d69cSJames Bottomley loser = 0; 55351da177e4SLinus Torvalds } 55361da177e4SLinus Torvalds 55375c04a7b8SAlexey Dobriyan if (!loser) { 55381da177e4SLinus Torvalds 553947b5d69cSJames Bottomley FPT_scamInfo[p_our_id].state = ID_ASSIGNED; 55401da177e4SLinus Torvalds 55415c04a7b8SAlexey Dobriyan if (ScamFlg & SCAM_ENABLED) { 55421da177e4SLinus Torvalds 55435c04a7b8SAlexey Dobriyan for (i = 0; i < MAX_SCSI_TAR; i++) { 554447b5d69cSJames Bottomley if ((FPT_scamInfo[i].state == ID_UNASSIGNED) || 55455c04a7b8SAlexey Dobriyan (FPT_scamInfo[i].state == ID_UNUSED)) { 55465c04a7b8SAlexey Dobriyan if (FPT_scsell(p_port, i)) { 554747b5d69cSJames Bottomley FPT_scamInfo[i].state = LEGACY; 55485c04a7b8SAlexey Dobriyan if ((FPT_scamInfo[i]. 55495c04a7b8SAlexey Dobriyan id_string[0] != 0xFF) 55505c04a7b8SAlexey Dobriyan || (FPT_scamInfo[i]. 55515c04a7b8SAlexey Dobriyan id_string[1] != 0xFA)) { 55521da177e4SLinus Torvalds 55535c04a7b8SAlexey Dobriyan FPT_scamInfo[i]. 55545c04a7b8SAlexey Dobriyan id_string[0] = 0xFF; 55555c04a7b8SAlexey Dobriyan FPT_scamInfo[i]. 55565c04a7b8SAlexey Dobriyan id_string[1] = 0xFA; 55571da177e4SLinus Torvalds if (pCurrNvRam == NULL) 55585c04a7b8SAlexey Dobriyan currCard-> 55595c04a7b8SAlexey Dobriyan globalFlags 55605c04a7b8SAlexey Dobriyan |= 55615c04a7b8SAlexey Dobriyan F_UPDATE_EEPROM; 55621da177e4SLinus Torvalds } 55631da177e4SLinus Torvalds } 55641da177e4SLinus Torvalds } 55651da177e4SLinus Torvalds } 55661da177e4SLinus Torvalds 556747b5d69cSJames Bottomley FPT_sresb(p_port, p_card); 556847b5d69cSJames Bottomley FPT_Wait1Second(p_port); 55695c04a7b8SAlexey Dobriyan while (!(FPT_scarb(p_port, INIT_SELTD))) { 55705c04a7b8SAlexey Dobriyan } 557147b5d69cSJames Bottomley FPT_scsel(p_port); 557247b5d69cSJames Bottomley FPT_scasid(p_card, p_port); 55731da177e4SLinus Torvalds } 55741da177e4SLinus Torvalds 55751da177e4SLinus Torvalds } 55761da177e4SLinus Torvalds 55775c04a7b8SAlexey Dobriyan else if ((loser) && (ScamFlg & SCAM_ENABLED)) { 557847b5d69cSJames Bottomley FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0; 557947b5d69cSJames Bottomley assigned_id = 0; 558047b5d69cSJames Bottomley FPT_scwtsel(p_port); 55811da177e4SLinus Torvalds 55821da177e4SLinus Torvalds do { 55835c04a7b8SAlexey Dobriyan while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) { 55845c04a7b8SAlexey Dobriyan } 55851da177e4SLinus Torvalds 558647b5d69cSJames Bottomley i = FPT_scxferc(p_port, 0x00); 55875c04a7b8SAlexey Dobriyan if (i == ASSIGN_ID) { 55885c04a7b8SAlexey Dobriyan if (! 55895c04a7b8SAlexey Dobriyan (FPT_scsendi 55905c04a7b8SAlexey Dobriyan (p_port, 55915c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id].id_string[0]))) { 559247b5d69cSJames Bottomley i = FPT_scxferc(p_port, 0x00); 55935c04a7b8SAlexey Dobriyan if (FPT_scvalq(i)) { 559447b5d69cSJames Bottomley k = FPT_scxferc(p_port, 0x00); 55951da177e4SLinus Torvalds 55965c04a7b8SAlexey Dobriyan if (FPT_scvalq(k)) { 55971da177e4SLinus Torvalds currCard->ourId = 55985c04a7b8SAlexey Dobriyan ((unsigned char)(i 55995c04a7b8SAlexey Dobriyan << 56005c04a7b8SAlexey Dobriyan 3) 56015c04a7b8SAlexey Dobriyan + 56025c04a7b8SAlexey Dobriyan (k & 56035c04a7b8SAlexey Dobriyan (unsigned char)7)) 56045c04a7b8SAlexey Dobriyan & (unsigned char) 56055c04a7b8SAlexey Dobriyan 0x3F; 56065c04a7b8SAlexey Dobriyan FPT_inisci(p_card, 56075c04a7b8SAlexey Dobriyan p_port, 56085c04a7b8SAlexey Dobriyan p_our_id); 56095c04a7b8SAlexey Dobriyan FPT_scamInfo[currCard-> 56105c04a7b8SAlexey Dobriyan ourId]. 56115c04a7b8SAlexey Dobriyan state = ID_ASSIGNED; 56125c04a7b8SAlexey Dobriyan FPT_scamInfo[currCard-> 56135c04a7b8SAlexey Dobriyan ourId]. 56145c04a7b8SAlexey Dobriyan id_string[0] 56151da177e4SLinus Torvalds = SLV_TYPE_CODE0; 561647b5d69cSJames Bottomley assigned_id = 1; 56171da177e4SLinus Torvalds } 56181da177e4SLinus Torvalds } 56191da177e4SLinus Torvalds } 56201da177e4SLinus Torvalds } 56211da177e4SLinus Torvalds 56225c04a7b8SAlexey Dobriyan else if (i == SET_P_FLAG) { 562347b5d69cSJames Bottomley if (!(FPT_scsendi(p_port, 56245c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id]. 56255c04a7b8SAlexey Dobriyan id_string[0]))) 56265c04a7b8SAlexey Dobriyan FPT_scamInfo[p_our_id].id_string[0] |= 56275c04a7b8SAlexey Dobriyan 0x80; 56281da177e4SLinus Torvalds } 56291da177e4SLinus Torvalds } while (!assigned_id); 56301da177e4SLinus Torvalds 56315c04a7b8SAlexey Dobriyan while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) { 56325c04a7b8SAlexey Dobriyan } 56331da177e4SLinus Torvalds } 56341da177e4SLinus Torvalds 56355c04a7b8SAlexey Dobriyan if (ScamFlg & SCAM_ENABLED) { 563647b5d69cSJames Bottomley FPT_scbusf(p_port); 56375c04a7b8SAlexey Dobriyan if (currCard->globalFlags & F_UPDATE_EEPROM) { 563847b5d69cSJames Bottomley FPT_scsavdi(p_card, p_port); 56391da177e4SLinus Torvalds currCard->globalFlags &= ~F_UPDATE_EEPROM; 56401da177e4SLinus Torvalds } 56411da177e4SLinus Torvalds } 56421da177e4SLinus Torvalds 56431da177e4SLinus Torvalds /* 56441da177e4SLinus Torvalds for (i=0,k=0; i < MAX_SCSI_TAR; i++) 56451da177e4SLinus Torvalds { 564647b5d69cSJames Bottomley if ((FPT_scamInfo[i].state == ID_ASSIGNED) || 564747b5d69cSJames Bottomley (FPT_scamInfo[i].state == LEGACY)) 56481da177e4SLinus Torvalds k++; 56491da177e4SLinus Torvalds } 56501da177e4SLinus Torvalds 56511da177e4SLinus Torvalds if (k==2) 56521da177e4SLinus Torvalds currCard->globalFlags |= F_SINGLE_DEVICE; 56531da177e4SLinus Torvalds else 56541da177e4SLinus Torvalds currCard->globalFlags &= ~F_SINGLE_DEVICE; 56551da177e4SLinus Torvalds */ 56561da177e4SLinus Torvalds } 56571da177e4SLinus Torvalds 56581da177e4SLinus Torvalds /*--------------------------------------------------------------------- 56591da177e4SLinus Torvalds * 566047b5d69cSJames Bottomley * Function: FPT_scarb 56611da177e4SLinus Torvalds * 56621da177e4SLinus Torvalds * Description: Gain control of the bus and wait SCAM select time (250ms) 56631da177e4SLinus Torvalds * 56641da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 56651da177e4SLinus Torvalds 5666391e2f25SKhalid Aziz static int FPT_scarb(u32 p_port, unsigned char p_sel_type) 56671da177e4SLinus Torvalds { 56685c04a7b8SAlexey Dobriyan if (p_sel_type == INIT_SELTD) { 56691da177e4SLinus Torvalds 56705c04a7b8SAlexey Dobriyan while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) { 56715c04a7b8SAlexey Dobriyan } 56721da177e4SLinus Torvalds 56731da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) 56745c1b85e2SAlexey Dobriyan return 0; 56751da177e4SLinus Torvalds 56761da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsidata_0) != 00) 56775c1b85e2SAlexey Dobriyan return 0; 56781da177e4SLinus Torvalds 56795c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 56805c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY)); 56811da177e4SLinus Torvalds 56821da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) { 56831da177e4SLinus Torvalds 56845c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 56855c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) & 56861da177e4SLinus Torvalds ~SCSI_BSY)); 56875c1b85e2SAlexey Dobriyan return 0; 56881da177e4SLinus Torvalds } 56891da177e4SLinus Torvalds 56905c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 56915c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL)); 56921da177e4SLinus Torvalds 56931da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsidata_0) != 00) { 56941da177e4SLinus Torvalds 56955c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 56965c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) & 56971da177e4SLinus Torvalds ~(SCSI_BSY | SCSI_SEL))); 56985c1b85e2SAlexey Dobriyan return 0; 56991da177e4SLinus Torvalds } 57001da177e4SLinus Torvalds } 57011da177e4SLinus Torvalds 57021da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0) 57031da177e4SLinus Torvalds & ~ACTdeassert)); 57041da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsireset, SCAM_EN); 57051da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, 0x00); 57061da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_1, 0x00); 57071da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN); 57081da177e4SLinus Torvalds 57095c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 57105c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG)); 57111da177e4SLinus Torvalds 57121da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig) 57131da177e4SLinus Torvalds & ~SCSI_BSY)); 57141da177e4SLinus Torvalds 571547b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms); 57161da177e4SLinus Torvalds 57175c1b85e2SAlexey Dobriyan return 1; 57181da177e4SLinus Torvalds } 57191da177e4SLinus Torvalds 57201da177e4SLinus Torvalds /*--------------------------------------------------------------------- 57211da177e4SLinus Torvalds * 572247b5d69cSJames Bottomley * Function: FPT_scbusf 57231da177e4SLinus Torvalds * 57241da177e4SLinus Torvalds * Description: Release the SCSI bus and disable SCAM selection. 57251da177e4SLinus Torvalds * 57261da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 57271da177e4SLinus Torvalds 5728391e2f25SKhalid Aziz static void FPT_scbusf(u32 p_port) 57291da177e4SLinus Torvalds { 57301da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, 57311da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE)); 57321da177e4SLinus Torvalds 57331da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, 0x00); 57341da177e4SLinus Torvalds 57351da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0) 57361da177e4SLinus Torvalds & ~SCSI_BUS_EN)); 57371da177e4SLinus Torvalds 57381da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, 0x00); 57391da177e4SLinus Torvalds 57401da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset) 57411da177e4SLinus Torvalds & ~SCAM_EN)); 57421da177e4SLinus Torvalds 57431da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0) 57441da177e4SLinus Torvalds | ACTdeassert)); 57451da177e4SLinus Torvalds 57461da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL)); 57471da177e4SLinus Torvalds 57481da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, 57491da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE)); 57501da177e4SLinus Torvalds } 57511da177e4SLinus Torvalds 57521da177e4SLinus Torvalds /*--------------------------------------------------------------------- 57531da177e4SLinus Torvalds * 575447b5d69cSJames Bottomley * Function: FPT_scasid 57551da177e4SLinus Torvalds * 57561da177e4SLinus Torvalds * Description: Assign an ID to all the SCAM devices. 57571da177e4SLinus Torvalds * 57581da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 57591da177e4SLinus Torvalds 5760391e2f25SKhalid Aziz static void FPT_scasid(unsigned char p_card, u32 p_port) 57611da177e4SLinus Torvalds { 5762db038cf8SAlexey Dobriyan unsigned char temp_id_string[ID_STRING_LENGTH]; 57631da177e4SLinus Torvalds 5764db038cf8SAlexey Dobriyan unsigned char i, k, scam_id; 5765db038cf8SAlexey Dobriyan unsigned char crcBytes[3]; 576668d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 5767fd1e29edSAlexey Dobriyan unsigned short *pCrcBytes; 57681da177e4SLinus Torvalds 576947b5d69cSJames Bottomley pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo; 57701da177e4SLinus Torvalds 577147b5d69cSJames Bottomley i = 0; 57721da177e4SLinus Torvalds 57735c04a7b8SAlexey Dobriyan while (!i) { 57741da177e4SLinus Torvalds 57755c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) { 5776db038cf8SAlexey Dobriyan temp_id_string[k] = (unsigned char)0x00; 57771da177e4SLinus Torvalds } 57781da177e4SLinus Torvalds 577947b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN); 578047b5d69cSJames Bottomley FPT_scxferc(p_port, ASSIGN_ID); 57811da177e4SLinus Torvalds 57825c04a7b8SAlexey Dobriyan if (!(FPT_sciso(p_port, &temp_id_string[0]))) { 57831da177e4SLinus Torvalds if (pCurrNvRam) { 5784fd1e29edSAlexey Dobriyan pCrcBytes = (unsigned short *)&crcBytes[0]; 578547b5d69cSJames Bottomley *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]); 578647b5d69cSJames Bottomley crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]); 57871da177e4SLinus Torvalds temp_id_string[1] = crcBytes[2]; 57881da177e4SLinus Torvalds temp_id_string[2] = crcBytes[0]; 57891da177e4SLinus Torvalds temp_id_string[3] = crcBytes[1]; 57901da177e4SLinus Torvalds for (k = 4; k < ID_STRING_LENGTH; k++) 5791db038cf8SAlexey Dobriyan temp_id_string[k] = (unsigned char)0x00; 57921da177e4SLinus Torvalds } 579347b5d69cSJames Bottomley i = FPT_scmachid(p_card, temp_id_string); 57941da177e4SLinus Torvalds 57955c04a7b8SAlexey Dobriyan if (i == CLR_PRIORITY) { 579647b5d69cSJames Bottomley FPT_scxferc(p_port, MISC_CODE); 579747b5d69cSJames Bottomley FPT_scxferc(p_port, CLR_P_FLAG); 579847b5d69cSJames Bottomley i = 0; /*Not the last ID yet. */ 57991da177e4SLinus Torvalds } 58001da177e4SLinus Torvalds 58015c04a7b8SAlexey Dobriyan else if (i != NO_ID_AVAIL) { 58021da177e4SLinus Torvalds if (i < 8) 580347b5d69cSJames Bottomley FPT_scxferc(p_port, ID_0_7); 58041da177e4SLinus Torvalds else 580547b5d69cSJames Bottomley FPT_scxferc(p_port, ID_8_F); 58061da177e4SLinus Torvalds 5807db038cf8SAlexey Dobriyan scam_id = (i & (unsigned char)0x07); 58081da177e4SLinus Torvalds 58091da177e4SLinus Torvalds for (k = 1; k < 0x08; k <<= 1) 58101da177e4SLinus Torvalds if (!(k & i)) 58111da177e4SLinus Torvalds scam_id += 0x08; /*Count number of zeros in DB0-3. */ 58121da177e4SLinus Torvalds 581347b5d69cSJames Bottomley FPT_scxferc(p_port, scam_id); 58141da177e4SLinus Torvalds 581547b5d69cSJames Bottomley i = 0; /*Not the last ID yet. */ 58161da177e4SLinus Torvalds } 58171da177e4SLinus Torvalds } 58181da177e4SLinus Torvalds 58195c04a7b8SAlexey Dobriyan else { 582047b5d69cSJames Bottomley i = 1; 58211da177e4SLinus Torvalds } 58221da177e4SLinus Torvalds 58231da177e4SLinus Torvalds } /*End while */ 58241da177e4SLinus Torvalds 582547b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN); 582647b5d69cSJames Bottomley FPT_scxferc(p_port, CFG_CMPLT); 58271da177e4SLinus Torvalds } 58281da177e4SLinus Torvalds 58291da177e4SLinus Torvalds /*--------------------------------------------------------------------- 58301da177e4SLinus Torvalds * 583147b5d69cSJames Bottomley * Function: FPT_scsel 58321da177e4SLinus Torvalds * 58331da177e4SLinus Torvalds * Description: Select all the SCAM devices. 58341da177e4SLinus Torvalds * 58351da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 58361da177e4SLinus Torvalds 5837391e2f25SKhalid Aziz static void FPT_scsel(u32 p_port) 58381da177e4SLinus Torvalds { 58391da177e4SLinus Torvalds 58401da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, SCSI_SEL); 584147b5d69cSJames Bottomley FPT_scwiros(p_port, SCSI_MSG); 58421da177e4SLinus Torvalds 58431da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY)); 58441da177e4SLinus Torvalds 58455c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 58465c04a7b8SAlexey Dobriyan (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); 58475c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsidata_0, 58485c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) | 5849db038cf8SAlexey Dobriyan (unsigned char)(BIT(7) + BIT(6)))); 58501da177e4SLinus Torvalds 58511da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD)); 585247b5d69cSJames Bottomley FPT_scwiros(p_port, SCSI_SEL); 58531da177e4SLinus Torvalds 58545c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsidata_0, 58555c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) & 5856db038cf8SAlexey Dobriyan ~(unsigned char)BIT(6))); 585747b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(6)); 58581da177e4SLinus Torvalds 58595c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 58605c04a7b8SAlexey Dobriyan (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); 58611da177e4SLinus Torvalds } 58621da177e4SLinus Torvalds 58631da177e4SLinus Torvalds /*--------------------------------------------------------------------- 58641da177e4SLinus Torvalds * 586547b5d69cSJames Bottomley * Function: FPT_scxferc 58661da177e4SLinus Torvalds * 58671da177e4SLinus Torvalds * Description: Handshake the p_data (DB4-0) across the bus. 58681da177e4SLinus Torvalds * 58691da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 58701da177e4SLinus Torvalds 5871391e2f25SKhalid Aziz static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data) 58721da177e4SLinus Torvalds { 5873db038cf8SAlexey Dobriyan unsigned char curr_data, ret_data; 58741da177e4SLinus Torvalds 58751da177e4SLinus Torvalds curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */ 58761da177e4SLinus Torvalds 58771da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data); 58781da177e4SLinus Torvalds 58791da177e4SLinus Torvalds curr_data &= ~BIT(7); 58801da177e4SLinus Torvalds 58811da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data); 58821da177e4SLinus Torvalds 588347b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */ 58841da177e4SLinus Torvalds while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ; 58851da177e4SLinus Torvalds 5886db038cf8SAlexey Dobriyan ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F); 58871da177e4SLinus Torvalds 58881da177e4SLinus Torvalds curr_data |= BIT(6); 58891da177e4SLinus Torvalds 58901da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data); 58911da177e4SLinus Torvalds 58921da177e4SLinus Torvalds curr_data &= ~BIT(5); 58931da177e4SLinus Torvalds 58941da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data); 58951da177e4SLinus Torvalds 589647b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */ 58971da177e4SLinus Torvalds 58981da177e4SLinus Torvalds curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */ 58991da177e4SLinus Torvalds curr_data |= BIT(7); 59001da177e4SLinus Torvalds 59011da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data); 59021da177e4SLinus Torvalds 59031da177e4SLinus Torvalds curr_data &= ~BIT(6); 59041da177e4SLinus Torvalds 59051da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data); 59061da177e4SLinus Torvalds 590747b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */ 59081da177e4SLinus Torvalds 59095c1b85e2SAlexey Dobriyan return ret_data; 59101da177e4SLinus Torvalds } 59111da177e4SLinus Torvalds 59121da177e4SLinus Torvalds /*--------------------------------------------------------------------- 59131da177e4SLinus Torvalds * 591447b5d69cSJames Bottomley * Function: FPT_scsendi 59151da177e4SLinus Torvalds * 59161da177e4SLinus Torvalds * Description: Transfer our Identification string to determine if we 59171da177e4SLinus Torvalds * will be the dominant master. 59181da177e4SLinus Torvalds * 59191da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 59201da177e4SLinus Torvalds 5921391e2f25SKhalid Aziz static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[]) 59221da177e4SLinus Torvalds { 5923db038cf8SAlexey Dobriyan unsigned char ret_data, byte_cnt, bit_cnt, defer; 59241da177e4SLinus Torvalds 592547b5d69cSJames Bottomley defer = 0; 59261da177e4SLinus Torvalds 59271da177e4SLinus Torvalds for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { 59281da177e4SLinus Torvalds 59291da177e4SLinus Torvalds for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) { 59301da177e4SLinus Torvalds 59311da177e4SLinus Torvalds if (defer) 593247b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 00); 59331da177e4SLinus Torvalds 59341da177e4SLinus Torvalds else if (p_id_string[byte_cnt] & bit_cnt) 59351da177e4SLinus Torvalds 593647b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 02); 59371da177e4SLinus Torvalds 59381da177e4SLinus Torvalds else { 59391da177e4SLinus Torvalds 594047b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 01); 59411da177e4SLinus Torvalds if (ret_data & 02) 594247b5d69cSJames Bottomley defer = 1; 59431da177e4SLinus Torvalds } 59441da177e4SLinus Torvalds 59451da177e4SLinus Torvalds if ((ret_data & 0x1C) == 0x10) 59465c1b85e2SAlexey Dobriyan return 0x00; /*End of isolation stage, we won! */ 59471da177e4SLinus Torvalds 59481da177e4SLinus Torvalds if (ret_data & 0x1C) 59495c1b85e2SAlexey Dobriyan return 0xFF; 59501da177e4SLinus Torvalds 59511da177e4SLinus Torvalds if ((defer) && (!(ret_data & 0x1F))) 59525c1b85e2SAlexey Dobriyan return 0x01; /*End of isolation stage, we lost. */ 59531da177e4SLinus Torvalds 59541da177e4SLinus Torvalds } /*bit loop */ 59551da177e4SLinus Torvalds 59561da177e4SLinus Torvalds } /*byte loop */ 59571da177e4SLinus Torvalds 59581da177e4SLinus Torvalds if (defer) 59595c1b85e2SAlexey Dobriyan return 0x01; /*We lost */ 59601da177e4SLinus Torvalds else 59615c1b85e2SAlexey Dobriyan return 0; /*We WON! Yeeessss! */ 59621da177e4SLinus Torvalds } 59631da177e4SLinus Torvalds 59641da177e4SLinus Torvalds /*--------------------------------------------------------------------- 59651da177e4SLinus Torvalds * 596647b5d69cSJames Bottomley * Function: FPT_sciso 59671da177e4SLinus Torvalds * 59681da177e4SLinus Torvalds * Description: Transfer the Identification string. 59691da177e4SLinus Torvalds * 59701da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 59711da177e4SLinus Torvalds 5972391e2f25SKhalid Aziz static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[]) 59731da177e4SLinus Torvalds { 5974db038cf8SAlexey Dobriyan unsigned char ret_data, the_data, byte_cnt, bit_cnt; 59751da177e4SLinus Torvalds 59761da177e4SLinus Torvalds the_data = 0; 59771da177e4SLinus Torvalds 59781da177e4SLinus Torvalds for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { 59791da177e4SLinus Torvalds 59801da177e4SLinus Torvalds for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) { 59811da177e4SLinus Torvalds 598247b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 0); 59831da177e4SLinus Torvalds 59841da177e4SLinus Torvalds if (ret_data & 0xFC) 59855c1b85e2SAlexey Dobriyan return 0xFF; 59861da177e4SLinus Torvalds 59871da177e4SLinus Torvalds else { 59881da177e4SLinus Torvalds 59891da177e4SLinus Torvalds the_data <<= 1; 59901da177e4SLinus Torvalds if (ret_data & BIT(1)) { 59911da177e4SLinus Torvalds the_data |= 1; 59921da177e4SLinus Torvalds } 59931da177e4SLinus Torvalds } 59941da177e4SLinus Torvalds 59955c04a7b8SAlexey Dobriyan if ((ret_data & 0x1F) == 0) { 59961da177e4SLinus Torvalds /* 59971da177e4SLinus Torvalds if(bit_cnt != 0 || bit_cnt != 8) 59981da177e4SLinus Torvalds { 59991da177e4SLinus Torvalds byte_cnt = 0; 60001da177e4SLinus Torvalds bit_cnt = 0; 600147b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN); 600247b5d69cSJames Bottomley FPT_scxferc(p_port, ASSIGN_ID); 60031da177e4SLinus Torvalds continue; 60041da177e4SLinus Torvalds } 60051da177e4SLinus Torvalds */ 60061da177e4SLinus Torvalds if (byte_cnt) 60075c1b85e2SAlexey Dobriyan return 0x00; 60081da177e4SLinus Torvalds else 60095c1b85e2SAlexey Dobriyan return 0xFF; 60101da177e4SLinus Torvalds } 60111da177e4SLinus Torvalds 60121da177e4SLinus Torvalds } /*bit loop */ 60131da177e4SLinus Torvalds 60141da177e4SLinus Torvalds p_id_string[byte_cnt] = the_data; 60151da177e4SLinus Torvalds 60161da177e4SLinus Torvalds } /*byte loop */ 60171da177e4SLinus Torvalds 60185c1b85e2SAlexey Dobriyan return 0; 60191da177e4SLinus Torvalds } 60201da177e4SLinus Torvalds 60211da177e4SLinus Torvalds /*--------------------------------------------------------------------- 60221da177e4SLinus Torvalds * 602347b5d69cSJames Bottomley * Function: FPT_scwirod 60241da177e4SLinus Torvalds * 60251da177e4SLinus Torvalds * Description: Sample the SCSI data bus making sure the signal has been 60261da177e4SLinus Torvalds * deasserted for the correct number of consecutive samples. 60271da177e4SLinus Torvalds * 60281da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 60291da177e4SLinus Torvalds 6030391e2f25SKhalid Aziz static void FPT_scwirod(u32 p_port, unsigned char p_data_bit) 60311da177e4SLinus Torvalds { 6032db038cf8SAlexey Dobriyan unsigned char i; 60331da177e4SLinus Torvalds 60341da177e4SLinus Torvalds i = 0; 60351da177e4SLinus Torvalds while (i < MAX_SCSI_TAR) { 60361da177e4SLinus Torvalds 60371da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit) 60381da177e4SLinus Torvalds 60391da177e4SLinus Torvalds i = 0; 60401da177e4SLinus Torvalds 60411da177e4SLinus Torvalds else 60421da177e4SLinus Torvalds 60431da177e4SLinus Torvalds i++; 60441da177e4SLinus Torvalds 60451da177e4SLinus Torvalds } 60461da177e4SLinus Torvalds } 60471da177e4SLinus Torvalds 60481da177e4SLinus Torvalds /*--------------------------------------------------------------------- 60491da177e4SLinus Torvalds * 605047b5d69cSJames Bottomley * Function: FPT_scwiros 60511da177e4SLinus Torvalds * 60521da177e4SLinus Torvalds * Description: Sample the SCSI Signal lines making sure the signal has been 60531da177e4SLinus Torvalds * deasserted for the correct number of consecutive samples. 60541da177e4SLinus Torvalds * 60551da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 60561da177e4SLinus Torvalds 6057391e2f25SKhalid Aziz static void FPT_scwiros(u32 p_port, unsigned char p_data_bit) 60581da177e4SLinus Torvalds { 6059db038cf8SAlexey Dobriyan unsigned char i; 60601da177e4SLinus Torvalds 60611da177e4SLinus Torvalds i = 0; 60621da177e4SLinus Torvalds while (i < MAX_SCSI_TAR) { 60631da177e4SLinus Torvalds 60641da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit) 60651da177e4SLinus Torvalds 60661da177e4SLinus Torvalds i = 0; 60671da177e4SLinus Torvalds 60681da177e4SLinus Torvalds else 60691da177e4SLinus Torvalds 60701da177e4SLinus Torvalds i++; 60711da177e4SLinus Torvalds 60721da177e4SLinus Torvalds } 60731da177e4SLinus Torvalds } 60741da177e4SLinus Torvalds 60751da177e4SLinus Torvalds /*--------------------------------------------------------------------- 60761da177e4SLinus Torvalds * 607747b5d69cSJames Bottomley * Function: FPT_scvalq 60781da177e4SLinus Torvalds * 60791da177e4SLinus Torvalds * Description: Make sure we received a valid data byte. 60801da177e4SLinus Torvalds * 60811da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 60821da177e4SLinus Torvalds 6083db038cf8SAlexey Dobriyan static unsigned char FPT_scvalq(unsigned char p_quintet) 60841da177e4SLinus Torvalds { 6085db038cf8SAlexey Dobriyan unsigned char count; 60861da177e4SLinus Torvalds 60871da177e4SLinus Torvalds for (count = 1; count < 0x08; count <<= 1) { 60881da177e4SLinus Torvalds if (!(p_quintet & count)) 60891da177e4SLinus Torvalds p_quintet -= 0x80; 60901da177e4SLinus Torvalds } 60911da177e4SLinus Torvalds 60921da177e4SLinus Torvalds if (p_quintet & 0x18) 60935c1b85e2SAlexey Dobriyan return 0; 60941da177e4SLinus Torvalds 60951da177e4SLinus Torvalds else 60965c1b85e2SAlexey Dobriyan return 1; 60971da177e4SLinus Torvalds } 60981da177e4SLinus Torvalds 60991da177e4SLinus Torvalds /*--------------------------------------------------------------------- 61001da177e4SLinus Torvalds * 610147b5d69cSJames Bottomley * Function: FPT_scsell 61021da177e4SLinus Torvalds * 61031da177e4SLinus Torvalds * Description: Select the specified device ID using a selection timeout 61041da177e4SLinus Torvalds * less than 4ms. If somebody responds then it is a legacy 61051da177e4SLinus Torvalds * drive and this ID must be marked as such. 61061da177e4SLinus Torvalds * 61071da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 61081da177e4SLinus Torvalds 6109391e2f25SKhalid Aziz static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id) 61101da177e4SLinus Torvalds { 6111d63a4cccSAlexey Dobriyan unsigned long i; 61121da177e4SLinus Torvalds 61131da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, 61141da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE)); 61151da177e4SLinus Torvalds 61161da177e4SLinus Torvalds ARAM_ACCESS(p_port); 61171da177e4SLinus Torvalds 61185c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_addstat, 61195c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER)); 61201da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, TO_4ms); 61211da177e4SLinus Torvalds 61221da177e4SLinus Torvalds for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) { 61231da177e4SLinus Torvalds WRW_HARPOON(i, (MPM_OP + ACOMMAND)); 61241da177e4SLinus Torvalds } 61251da177e4SLinus Torvalds WRW_HARPOON(i, (BRH_OP + ALWAYS + NP)); 61261da177e4SLinus Torvalds 61271da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), 61281da177e4SLinus Torvalds (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT)); 61291da177e4SLinus Torvalds 61301da177e4SLinus Torvalds WR_HARPOON(p_port + hp_select_id, targ_id); 61311da177e4SLinus Torvalds 61321da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT); 61331da177e4SLinus Torvalds WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT)); 61341da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL)); 61351da177e4SLinus Torvalds 61361da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & 61375c04a7b8SAlexey Dobriyan (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) { 61385c04a7b8SAlexey Dobriyan } 61391da177e4SLinus Torvalds 61401da177e4SLinus Torvalds if (RDW_HARPOON((p_port + hp_intstat)) & RESET) 614147b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms); 61421da177e4SLinus Torvalds 61431da177e4SLinus Torvalds DISABLE_AUTO(p_port); 61441da177e4SLinus Torvalds 61455c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_addstat, 61465c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER)); 61471da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, TO_290ms); 61481da177e4SLinus Torvalds 61491da177e4SLinus Torvalds SGRAM_ACCESS(p_port); 61501da177e4SLinus Torvalds 61511da177e4SLinus Torvalds if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) { 61521da177e4SLinus Torvalds 61531da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), 61541da177e4SLinus Torvalds (RESET | TIMEOUT | SEL | BUS_FREE | PHASE)); 61551da177e4SLinus Torvalds 61561da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, 61575c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_page_ctrl) & 61585c04a7b8SAlexey Dobriyan ~G_INT_DISABLE)); 61591da177e4SLinus Torvalds 61605c1b85e2SAlexey Dobriyan return 0; /*No legacy device */ 61611da177e4SLinus Torvalds } 61621da177e4SLinus Torvalds 61631da177e4SLinus Torvalds else { 61641da177e4SLinus Torvalds 61651da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) { 61665c04a7b8SAlexey Dobriyan if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) { 61675c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig, 61685c04a7b8SAlexey Dobriyan (SCSI_ACK + S_ILL_PH)); 61691da177e4SLinus Torvalds ACCEPT_MSG(p_port); 61701da177e4SLinus Torvalds } 61711da177e4SLinus Torvalds } 61721da177e4SLinus Torvalds 61731da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1); 61741da177e4SLinus Torvalds 61751da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, 61765c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_page_ctrl) & 61775c04a7b8SAlexey Dobriyan ~G_INT_DISABLE)); 61781da177e4SLinus Torvalds 61795c1b85e2SAlexey Dobriyan return 1; /*Found one of them oldies! */ 61801da177e4SLinus Torvalds } 61811da177e4SLinus Torvalds } 61821da177e4SLinus Torvalds 61831da177e4SLinus Torvalds /*--------------------------------------------------------------------- 61841da177e4SLinus Torvalds * 618547b5d69cSJames Bottomley * Function: FPT_scwtsel 61861da177e4SLinus Torvalds * 61871da177e4SLinus Torvalds * Description: Wait to be selected by another SCAM initiator. 61881da177e4SLinus Torvalds * 61891da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 61901da177e4SLinus Torvalds 6191391e2f25SKhalid Aziz static void FPT_scwtsel(u32 p_port) 61921da177e4SLinus Torvalds { 61935c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) { 61941da177e4SLinus Torvalds } 61955c04a7b8SAlexey Dobriyan } 61961da177e4SLinus Torvalds 61971da177e4SLinus Torvalds /*--------------------------------------------------------------------- 61981da177e4SLinus Torvalds * 619947b5d69cSJames Bottomley * Function: FPT_inisci 62001da177e4SLinus Torvalds * 62011da177e4SLinus Torvalds * Description: Setup the data Structure with the info from the EEPROM. 62021da177e4SLinus Torvalds * 62031da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 62041da177e4SLinus Torvalds 6205391e2f25SKhalid Aziz static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id) 62061da177e4SLinus Torvalds { 6207db038cf8SAlexey Dobriyan unsigned char i, k, max_id; 6208c823feebSAlexey Dobriyan unsigned short ee_data; 620968d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam; 62101da177e4SLinus Torvalds 621147b5d69cSJames Bottomley pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo; 62121da177e4SLinus Torvalds 62131da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD) 62141da177e4SLinus Torvalds max_id = 0x08; 62151da177e4SLinus Torvalds 62161da177e4SLinus Torvalds else 62171da177e4SLinus Torvalds max_id = 0x10; 62181da177e4SLinus Torvalds 62191da177e4SLinus Torvalds if (pCurrNvRam) { 62201da177e4SLinus Torvalds for (i = 0; i < max_id; i++) { 62211da177e4SLinus Torvalds 62221da177e4SLinus Torvalds for (k = 0; k < 4; k++) 62235c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k] = 62245c04a7b8SAlexey Dobriyan pCurrNvRam->niScamTbl[i][k]; 62251da177e4SLinus Torvalds for (k = 4; k < ID_STRING_LENGTH; k++) 62265c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k] = 62275c04a7b8SAlexey Dobriyan (unsigned char)0x00; 62281da177e4SLinus Torvalds 622947b5d69cSJames Bottomley if (FPT_scamInfo[i].id_string[0] == 0x00) 623047b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ 62311da177e4SLinus Torvalds else 623247b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ 62331da177e4SLinus Torvalds 62341da177e4SLinus Torvalds } 62351da177e4SLinus Torvalds } else { 62365c04a7b8SAlexey Dobriyan for (i = 0; i < max_id; i++) { 62375c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k += 2) { 62385c04a7b8SAlexey Dobriyan ee_data = 62395c04a7b8SAlexey Dobriyan FPT_utilEERead(p_port, 62405c04a7b8SAlexey Dobriyan (unsigned 62415c04a7b8SAlexey Dobriyan short)((EE_SCAMBASE / 2) + 62425c04a7b8SAlexey Dobriyan (unsigned short)(i * 62435c04a7b8SAlexey Dobriyan ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2))); 62445c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k] = 62455c04a7b8SAlexey Dobriyan (unsigned char)ee_data; 62461da177e4SLinus Torvalds ee_data >>= 8; 62475c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k + 1] = 62485c04a7b8SAlexey Dobriyan (unsigned char)ee_data; 62491da177e4SLinus Torvalds } 62501da177e4SLinus Torvalds 625147b5d69cSJames Bottomley if ((FPT_scamInfo[i].id_string[0] == 0x00) || 625247b5d69cSJames Bottomley (FPT_scamInfo[i].id_string[0] == 0xFF)) 62531da177e4SLinus Torvalds 625447b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ 62551da177e4SLinus Torvalds 62561da177e4SLinus Torvalds else 625747b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ 62581da177e4SLinus Torvalds 62591da177e4SLinus Torvalds } 62601da177e4SLinus Torvalds } 62611da177e4SLinus Torvalds for (k = 0; k < ID_STRING_LENGTH; k++) 626247b5d69cSJames Bottomley FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k]; 62631da177e4SLinus Torvalds 62641da177e4SLinus Torvalds } 62651da177e4SLinus Torvalds 62661da177e4SLinus Torvalds /*--------------------------------------------------------------------- 62671da177e4SLinus Torvalds * 626847b5d69cSJames Bottomley * Function: FPT_scmachid 62691da177e4SLinus Torvalds * 62701da177e4SLinus Torvalds * Description: Match the Device ID string with our values stored in 62711da177e4SLinus Torvalds * the EEPROM. 62721da177e4SLinus Torvalds * 62731da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 62741da177e4SLinus Torvalds 62755c04a7b8SAlexey Dobriyan static unsigned char FPT_scmachid(unsigned char p_card, 62765c04a7b8SAlexey Dobriyan unsigned char p_id_string[]) 62771da177e4SLinus Torvalds { 62781da177e4SLinus Torvalds 6279db038cf8SAlexey Dobriyan unsigned char i, k, match; 62801da177e4SLinus Torvalds 62811da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR; i++) { 62821da177e4SLinus Torvalds 628347b5d69cSJames Bottomley match = 1; 62841da177e4SLinus Torvalds 62855c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) { 628647b5d69cSJames Bottomley if (p_id_string[k] != FPT_scamInfo[i].id_string[k]) 628747b5d69cSJames Bottomley match = 0; 62881da177e4SLinus Torvalds } 62891da177e4SLinus Torvalds 62905c04a7b8SAlexey Dobriyan if (match) { 629147b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_ASSIGNED; 62925c1b85e2SAlexey Dobriyan return i; 62931da177e4SLinus Torvalds } 62941da177e4SLinus Torvalds 62951da177e4SLinus Torvalds } 62961da177e4SLinus Torvalds 62971da177e4SLinus Torvalds if (p_id_string[0] & BIT(5)) 62981da177e4SLinus Torvalds i = 8; 62991da177e4SLinus Torvalds else 63001da177e4SLinus Torvalds i = MAX_SCSI_TAR; 63011da177e4SLinus Torvalds 63025c04a7b8SAlexey Dobriyan if (((p_id_string[0] & 0x06) == 0x02) 63035c04a7b8SAlexey Dobriyan || ((p_id_string[0] & 0x06) == 0x04)) 6304db038cf8SAlexey Dobriyan match = p_id_string[1] & (unsigned char)0x1F; 63051da177e4SLinus Torvalds else 63061da177e4SLinus Torvalds match = 7; 63071da177e4SLinus Torvalds 63085c04a7b8SAlexey Dobriyan while (i > 0) { 63091da177e4SLinus Torvalds i--; 63101da177e4SLinus Torvalds 63115c04a7b8SAlexey Dobriyan if (FPT_scamInfo[match].state == ID_UNUSED) { 63125c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) { 63135c04a7b8SAlexey Dobriyan FPT_scamInfo[match].id_string[k] = 63145c04a7b8SAlexey Dobriyan p_id_string[k]; 63151da177e4SLinus Torvalds } 63161da177e4SLinus Torvalds 631747b5d69cSJames Bottomley FPT_scamInfo[match].state = ID_ASSIGNED; 63181da177e4SLinus Torvalds 631947b5d69cSJames Bottomley if (FPT_BL_Card[p_card].pNvRamInfo == NULL) 63205c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |= 63215c04a7b8SAlexey Dobriyan F_UPDATE_EEPROM; 63225c1b85e2SAlexey Dobriyan return match; 63231da177e4SLinus Torvalds 63241da177e4SLinus Torvalds } 63251da177e4SLinus Torvalds 63261da177e4SLinus Torvalds match--; 63271da177e4SLinus Torvalds 63285c04a7b8SAlexey Dobriyan if (match == 0xFF) { 63291da177e4SLinus Torvalds if (p_id_string[0] & BIT(5)) 63301da177e4SLinus Torvalds match = 7; 63311da177e4SLinus Torvalds else 63321da177e4SLinus Torvalds match = MAX_SCSI_TAR - 1; 63331da177e4SLinus Torvalds } 63341da177e4SLinus Torvalds } 63351da177e4SLinus Torvalds 63365c04a7b8SAlexey Dobriyan if (p_id_string[0] & BIT(7)) { 63375c1b85e2SAlexey Dobriyan return CLR_PRIORITY; 63381da177e4SLinus Torvalds } 63391da177e4SLinus Torvalds 63401da177e4SLinus Torvalds if (p_id_string[0] & BIT(5)) 63411da177e4SLinus Torvalds i = 8; 63421da177e4SLinus Torvalds else 63431da177e4SLinus Torvalds i = MAX_SCSI_TAR; 63441da177e4SLinus Torvalds 63455c04a7b8SAlexey Dobriyan if (((p_id_string[0] & 0x06) == 0x02) 63465c04a7b8SAlexey Dobriyan || ((p_id_string[0] & 0x06) == 0x04)) 6347db038cf8SAlexey Dobriyan match = p_id_string[1] & (unsigned char)0x1F; 63481da177e4SLinus Torvalds else 63491da177e4SLinus Torvalds match = 7; 63501da177e4SLinus Torvalds 63515c04a7b8SAlexey Dobriyan while (i > 0) { 63521da177e4SLinus Torvalds 63531da177e4SLinus Torvalds i--; 63541da177e4SLinus Torvalds 63555c04a7b8SAlexey Dobriyan if (FPT_scamInfo[match].state == ID_UNASSIGNED) { 63565c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) { 63575c04a7b8SAlexey Dobriyan FPT_scamInfo[match].id_string[k] = 63585c04a7b8SAlexey Dobriyan p_id_string[k]; 63591da177e4SLinus Torvalds } 63601da177e4SLinus Torvalds 636147b5d69cSJames Bottomley FPT_scamInfo[match].id_string[0] |= BIT(7); 636247b5d69cSJames Bottomley FPT_scamInfo[match].state = ID_ASSIGNED; 636347b5d69cSJames Bottomley if (FPT_BL_Card[p_card].pNvRamInfo == NULL) 63645c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |= 63655c04a7b8SAlexey Dobriyan F_UPDATE_EEPROM; 63665c1b85e2SAlexey Dobriyan return match; 63671da177e4SLinus Torvalds 63681da177e4SLinus Torvalds } 63691da177e4SLinus Torvalds 63701da177e4SLinus Torvalds match--; 63711da177e4SLinus Torvalds 63725c04a7b8SAlexey Dobriyan if (match == 0xFF) { 63731da177e4SLinus Torvalds if (p_id_string[0] & BIT(5)) 63741da177e4SLinus Torvalds match = 7; 63751da177e4SLinus Torvalds else 63761da177e4SLinus Torvalds match = MAX_SCSI_TAR - 1; 63771da177e4SLinus Torvalds } 63781da177e4SLinus Torvalds } 63791da177e4SLinus Torvalds 63805c1b85e2SAlexey Dobriyan return NO_ID_AVAIL; 63811da177e4SLinus Torvalds } 63821da177e4SLinus Torvalds 63831da177e4SLinus Torvalds /*--------------------------------------------------------------------- 63841da177e4SLinus Torvalds * 638547b5d69cSJames Bottomley * Function: FPT_scsavdi 63861da177e4SLinus Torvalds * 63871da177e4SLinus Torvalds * Description: Save off the device SCAM ID strings. 63881da177e4SLinus Torvalds * 63891da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 63901da177e4SLinus Torvalds 6391391e2f25SKhalid Aziz static void FPT_scsavdi(unsigned char p_card, u32 p_port) 63921da177e4SLinus Torvalds { 6393db038cf8SAlexey Dobriyan unsigned char i, k, max_id; 6394c823feebSAlexey Dobriyan unsigned short ee_data, sum_data; 63951da177e4SLinus Torvalds 63961da177e4SLinus Torvalds sum_data = 0x0000; 63971da177e4SLinus Torvalds 63985c04a7b8SAlexey Dobriyan for (i = 1; i < EE_SCAMBASE / 2; i++) { 639947b5d69cSJames Bottomley sum_data += FPT_utilEERead(p_port, i); 64001da177e4SLinus Torvalds } 64011da177e4SLinus Torvalds 640247b5d69cSJames Bottomley FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */ 64031da177e4SLinus Torvalds 64041da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD) 64051da177e4SLinus Torvalds max_id = 0x08; 64061da177e4SLinus Torvalds 64071da177e4SLinus Torvalds else 64081da177e4SLinus Torvalds max_id = 0x10; 64091da177e4SLinus Torvalds 64105c04a7b8SAlexey Dobriyan for (i = 0; i < max_id; i++) { 64111da177e4SLinus Torvalds 64125c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k += 2) { 641347b5d69cSJames Bottomley ee_data = FPT_scamInfo[i].id_string[k + 1]; 64141da177e4SLinus Torvalds ee_data <<= 8; 641547b5d69cSJames Bottomley ee_data |= FPT_scamInfo[i].id_string[k]; 64161da177e4SLinus Torvalds sum_data += ee_data; 64175c04a7b8SAlexey Dobriyan FPT_utilEEWrite(p_port, ee_data, 64185c04a7b8SAlexey Dobriyan (unsigned short)((EE_SCAMBASE / 2) + 64195c04a7b8SAlexey Dobriyan (unsigned short)(i * 64205c04a7b8SAlexey Dobriyan ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2))); 64211da177e4SLinus Torvalds } 64221da177e4SLinus Torvalds } 64231da177e4SLinus Torvalds 642447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2); 642547b5d69cSJames Bottomley FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */ 64261da177e4SLinus Torvalds } 64271da177e4SLinus Torvalds 64281da177e4SLinus Torvalds /*--------------------------------------------------------------------- 64291da177e4SLinus Torvalds * 643047b5d69cSJames Bottomley * Function: FPT_XbowInit 64311da177e4SLinus Torvalds * 64321da177e4SLinus Torvalds * Description: Setup the Xbow for normal operation. 64331da177e4SLinus Torvalds * 64341da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 64351da177e4SLinus Torvalds 6436391e2f25SKhalid Aziz static void FPT_XbowInit(u32 port, unsigned char ScamFlg) 64371da177e4SLinus Torvalds { 6438db038cf8SAlexey Dobriyan unsigned char i; 64391da177e4SLinus Torvalds 64401da177e4SLinus Torvalds i = RD_HARPOON(port + hp_page_ctrl); 6441db038cf8SAlexey Dobriyan WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE)); 64421da177e4SLinus Torvalds 64431da177e4SLinus Torvalds WR_HARPOON(port + hp_scsireset, 0x00); 64441da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_1, HOST_MODE8); 64451da177e4SLinus Torvalds 64465c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET | 64471da177e4SLinus Torvalds FIFO_CLR)); 64481da177e4SLinus Torvalds 64491da177e4SLinus Torvalds WR_HARPOON(port + hp_scsireset, SCSI_INI); 64501da177e4SLinus Torvalds 64511da177e4SLinus Torvalds WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT); 64521da177e4SLinus Torvalds 64531da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */ 64541da177e4SLinus Torvalds WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL); 64551da177e4SLinus Torvalds 64561da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT); 64571da177e4SLinus Torvalds 645847b5d69cSJames Bottomley FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT | 64591da177e4SLinus Torvalds BUS_FREE | XFER_CNT_0 | AUTO_INT; 64601da177e4SLinus Torvalds 64611da177e4SLinus Torvalds if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) 646247b5d69cSJames Bottomley FPT_default_intena |= SCAM_SEL; 64631da177e4SLinus Torvalds 646447b5d69cSJames Bottomley WRW_HARPOON((port + hp_intena), FPT_default_intena); 64651da177e4SLinus Torvalds 64661da177e4SLinus Torvalds WR_HARPOON(port + hp_seltimeout, TO_290ms); 64671da177e4SLinus Torvalds 64681da177e4SLinus Torvalds /* Turn on SCSI_MODE8 for narrow cards to fix the 64691da177e4SLinus Torvalds strapping issue with the DUAL CHANNEL card */ 64701da177e4SLinus Torvalds if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD) 64711da177e4SLinus Torvalds WR_HARPOON(port + hp_addstat, SCSI_MODE8); 64721da177e4SLinus Torvalds 64731da177e4SLinus Torvalds WR_HARPOON(port + hp_page_ctrl, i); 64741da177e4SLinus Torvalds 64751da177e4SLinus Torvalds } 64761da177e4SLinus Torvalds 64771da177e4SLinus Torvalds /*--------------------------------------------------------------------- 64781da177e4SLinus Torvalds * 647947b5d69cSJames Bottomley * Function: FPT_BusMasterInit 64801da177e4SLinus Torvalds * 64811da177e4SLinus Torvalds * Description: Initialize the BusMaster for normal operations. 64821da177e4SLinus Torvalds * 64831da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 64841da177e4SLinus Torvalds 6485391e2f25SKhalid Aziz static void FPT_BusMasterInit(u32 p_port) 64861da177e4SLinus Torvalds { 64871da177e4SLinus Torvalds 64881da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST); 64891da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, 0x00); 64901da177e4SLinus Torvalds 64911da177e4SLinus Torvalds WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64); 64921da177e4SLinus Torvalds 64931da177e4SLinus Torvalds WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT)); 64941da177e4SLinus Torvalds 64951da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H)); 64961da177e4SLinus Torvalds 64971da177e4SLinus Torvalds RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */ 64981da177e4SLinus Torvalds WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); 64991da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) & 65001da177e4SLinus Torvalds ~SCATTER_EN)); 65011da177e4SLinus Torvalds } 65021da177e4SLinus Torvalds 65031da177e4SLinus Torvalds /*--------------------------------------------------------------------- 65041da177e4SLinus Torvalds * 650547b5d69cSJames Bottomley * Function: FPT_DiagEEPROM 65061da177e4SLinus Torvalds * 65071da177e4SLinus Torvalds * Description: Verfiy checksum and 'Key' and initialize the EEPROM if 65081da177e4SLinus Torvalds * necessary. 65091da177e4SLinus Torvalds * 65101da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 65111da177e4SLinus Torvalds 6512391e2f25SKhalid Aziz static void FPT_DiagEEPROM(u32 p_port) 65131da177e4SLinus Torvalds { 6514c823feebSAlexey Dobriyan unsigned short index, temp, max_wd_cnt; 65151da177e4SLinus Torvalds 65161da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD) 65171da177e4SLinus Torvalds max_wd_cnt = EEPROM_WD_CNT; 65181da177e4SLinus Torvalds else 65191da177e4SLinus Torvalds max_wd_cnt = EEPROM_WD_CNT * 2; 65201da177e4SLinus Torvalds 652147b5d69cSJames Bottomley temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2); 65221da177e4SLinus Torvalds 65231da177e4SLinus Torvalds if (temp == 0x4641) { 65241da177e4SLinus Torvalds 65251da177e4SLinus Torvalds for (index = 2; index < max_wd_cnt; index++) { 65261da177e4SLinus Torvalds 652747b5d69cSJames Bottomley temp += FPT_utilEERead(p_port, index); 65281da177e4SLinus Torvalds 65291da177e4SLinus Torvalds } 65301da177e4SLinus Torvalds 653147b5d69cSJames Bottomley if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) { 65321da177e4SLinus Torvalds 65331da177e4SLinus Torvalds return; /*EEPROM is Okay so return now! */ 65341da177e4SLinus Torvalds } 65351da177e4SLinus Torvalds } 65361da177e4SLinus Torvalds 6537db038cf8SAlexey Dobriyan FPT_utilEEWriteOnOff(p_port, (unsigned char)1); 65381da177e4SLinus Torvalds 65391da177e4SLinus Torvalds for (index = 0; index < max_wd_cnt; index++) { 65401da177e4SLinus Torvalds 654147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, index); 65421da177e4SLinus Torvalds } 65431da177e4SLinus Torvalds 65441da177e4SLinus Torvalds temp = 0; 65451da177e4SLinus Torvalds 654647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2); 65471da177e4SLinus Torvalds temp += 0x4641; 654847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2); 65491da177e4SLinus Torvalds temp += 0x3920; 655047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2); 65511da177e4SLinus Torvalds temp += 0x3033; 655247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2); 65531da177e4SLinus Torvalds temp += 0x2020; 655447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2); 65551da177e4SLinus Torvalds temp += 0x70D3; 655647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2); 65571da177e4SLinus Torvalds temp += 0x0010; 655847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2); 65591da177e4SLinus Torvalds temp += 0x0003; 656047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2); 65611da177e4SLinus Torvalds temp += 0x0007; 65621da177e4SLinus Torvalds 656347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2); 65641da177e4SLinus Torvalds temp += 0x0000; 656547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2); 65661da177e4SLinus Torvalds temp += 0x0000; 656747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2); 65681da177e4SLinus Torvalds temp += 0x0000; 65691da177e4SLinus Torvalds 657047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2); 65711da177e4SLinus Torvalds temp += 0x4242; 657247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2); 65731da177e4SLinus Torvalds temp += 0x4242; 657447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2); 65751da177e4SLinus Torvalds temp += 0x4242; 657647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2); 65771da177e4SLinus Torvalds temp += 0x4242; 657847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2); 65791da177e4SLinus Torvalds temp += 0x4242; 658047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2); 65811da177e4SLinus Torvalds temp += 0x4242; 658247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2); 65831da177e4SLinus Torvalds temp += 0x4242; 658447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2); 65851da177e4SLinus Torvalds temp += 0x4242; 65861da177e4SLinus Torvalds 658747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */ 65881da177e4SLinus Torvalds temp += 0x6C46; 658947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */ 65901da177e4SLinus Torvalds temp += 0x7361; 659147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5068, 68 / 2); 65921da177e4SLinus Torvalds temp += 0x5068; 659347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x696F, 70 / 2); 65941da177e4SLinus Torvalds temp += 0x696F; 659547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x746E, 72 / 2); 65961da177e4SLinus Torvalds temp += 0x746E; 659747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4C20, 74 / 2); 65981da177e4SLinus Torvalds temp += 0x4C20; 659947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2054, 76 / 2); 66001da177e4SLinus Torvalds temp += 0x2054; 660147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2020, 78 / 2); 66021da177e4SLinus Torvalds temp += 0x2020; 66031da177e4SLinus Torvalds 66041da177e4SLinus Torvalds index = ((EE_SCAMBASE / 2) + (7 * 16)); 660547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index); 66061da177e4SLinus Torvalds temp += (0x0700 + TYPE_CODE0); 66071da177e4SLinus Torvalds index++; 660847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */ 66091da177e4SLinus Torvalds temp += 0x5542; /* BUSLOGIC */ 66101da177e4SLinus Torvalds index++; 661147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4C53, index); 66121da177e4SLinus Torvalds temp += 0x4C53; 66131da177e4SLinus Torvalds index++; 661447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x474F, index); 66151da177e4SLinus Torvalds temp += 0x474F; 66161da177e4SLinus Torvalds index++; 661747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4349, index); 66181da177e4SLinus Torvalds temp += 0x4349; 66191da177e4SLinus Torvalds index++; 662047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */ 66211da177e4SLinus Torvalds temp += 0x5442; /* BT- 930 */ 66221da177e4SLinus Torvalds index++; 662347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x202D, index); 66241da177e4SLinus Torvalds temp += 0x202D; 66251da177e4SLinus Torvalds index++; 662647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3339, index); 66271da177e4SLinus Torvalds temp += 0x3339; 66281da177e4SLinus Torvalds index++; /*Serial # */ 662947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */ 66301da177e4SLinus Torvalds temp += 0x2030; 66311da177e4SLinus Torvalds index++; 663247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5453, index); 66331da177e4SLinus Torvalds temp += 0x5453; 66341da177e4SLinus Torvalds index++; 663547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5645, index); 66361da177e4SLinus Torvalds temp += 0x5645; 66371da177e4SLinus Torvalds index++; 663847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2045, index); 66391da177e4SLinus Torvalds temp += 0x2045; 66401da177e4SLinus Torvalds index++; 664147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x202F, index); 66421da177e4SLinus Torvalds temp += 0x202F; 66431da177e4SLinus Torvalds index++; 664447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4F4A, index); 66451da177e4SLinus Torvalds temp += 0x4F4A; 66461da177e4SLinus Torvalds index++; 664747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x204E, index); 66481da177e4SLinus Torvalds temp += 0x204E; 66491da177e4SLinus Torvalds index++; 665047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3539, index); 66511da177e4SLinus Torvalds temp += 0x3539; 66521da177e4SLinus Torvalds 665347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2); 66541da177e4SLinus Torvalds 6655db038cf8SAlexey Dobriyan FPT_utilEEWriteOnOff(p_port, (unsigned char)0); 66561da177e4SLinus Torvalds 66571da177e4SLinus Torvalds } 66581da177e4SLinus Torvalds 66591da177e4SLinus Torvalds /*--------------------------------------------------------------------- 66601da177e4SLinus Torvalds * 66611da177e4SLinus Torvalds * Function: Queue Search Select 66621da177e4SLinus Torvalds * 66631da177e4SLinus Torvalds * Description: Try to find a new command to execute. 66641da177e4SLinus Torvalds * 66651da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 66661da177e4SLinus Torvalds 66675c04a7b8SAlexey Dobriyan static void FPT_queueSearchSelect(struct sccb_card *pCurrCard, 66685c04a7b8SAlexey Dobriyan unsigned char p_card) 66691da177e4SLinus Torvalds { 6670db038cf8SAlexey Dobriyan unsigned char scan_ptr, lun; 6671f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 667269eb2ea4SAlexey Dobriyan struct sccb *pOldSccb; 66731da177e4SLinus Torvalds 66741da177e4SLinus Torvalds scan_ptr = pCurrCard->scanIndex; 66755c04a7b8SAlexey Dobriyan do { 667647b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr]; 66771da177e4SLinus Torvalds if ((pCurrCard->globalFlags & F_CONLUN_IO) && 66785c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != 66795c04a7b8SAlexey Dobriyan TAG_Q_TRYING)) { 66805c04a7b8SAlexey Dobriyan if (currTar_Info->TarSelQ_Cnt != 0) { 66811da177e4SLinus Torvalds 66821da177e4SLinus Torvalds scan_ptr++; 66831da177e4SLinus Torvalds if (scan_ptr == MAX_SCSI_TAR) 66841da177e4SLinus Torvalds scan_ptr = 0; 66851da177e4SLinus Torvalds 66865c04a7b8SAlexey Dobriyan for (lun = 0; lun < MAX_LUN; lun++) { 66875c04a7b8SAlexey Dobriyan if (currTar_Info->TarLUNBusy[lun] == 0) { 66881da177e4SLinus Torvalds 66895c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB = 66905c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head; 66911da177e4SLinus Torvalds pOldSccb = NULL; 66921da177e4SLinus Torvalds 66935c04a7b8SAlexey Dobriyan while ((pCurrCard-> 66945c04a7b8SAlexey Dobriyan currentSCCB != NULL) 66955c04a7b8SAlexey Dobriyan && (lun != 66965c04a7b8SAlexey Dobriyan pCurrCard-> 66975c04a7b8SAlexey Dobriyan currentSCCB->Lun)) { 66985c04a7b8SAlexey Dobriyan pOldSccb = 66995c04a7b8SAlexey Dobriyan pCurrCard-> 67005c04a7b8SAlexey Dobriyan currentSCCB; 67015c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB = 67025c04a7b8SAlexey Dobriyan (struct sccb 67035c04a7b8SAlexey Dobriyan *)(pCurrCard-> 67045c04a7b8SAlexey Dobriyan currentSCCB)-> 67051da177e4SLinus Torvalds Sccb_forwardlink; 67061da177e4SLinus Torvalds } 67075c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB == 67085c04a7b8SAlexey Dobriyan NULL) 67091da177e4SLinus Torvalds continue; 67105c04a7b8SAlexey Dobriyan if (pOldSccb != NULL) { 67115c04a7b8SAlexey Dobriyan pOldSccb-> 67125c04a7b8SAlexey Dobriyan Sccb_forwardlink = 67135c04a7b8SAlexey Dobriyan (struct sccb 67145c04a7b8SAlexey Dobriyan *)(pCurrCard-> 67155c04a7b8SAlexey Dobriyan currentSCCB)-> 67161da177e4SLinus Torvalds Sccb_forwardlink; 67175c04a7b8SAlexey Dobriyan pOldSccb-> 67185c04a7b8SAlexey Dobriyan Sccb_backlink = 67195c04a7b8SAlexey Dobriyan (struct sccb 67205c04a7b8SAlexey Dobriyan *)(pCurrCard-> 67215c04a7b8SAlexey Dobriyan currentSCCB)-> 67221da177e4SLinus Torvalds Sccb_backlink; 67235c04a7b8SAlexey Dobriyan currTar_Info-> 67245c04a7b8SAlexey Dobriyan TarSelQ_Cnt--; 67255c04a7b8SAlexey Dobriyan } else { 67265c04a7b8SAlexey Dobriyan currTar_Info-> 67275c04a7b8SAlexey Dobriyan TarSelQ_Head = 67285c04a7b8SAlexey Dobriyan (struct sccb 67295c04a7b8SAlexey Dobriyan *)(pCurrCard-> 67305c04a7b8SAlexey Dobriyan currentSCCB)-> 67315c04a7b8SAlexey Dobriyan Sccb_forwardlink; 67321da177e4SLinus Torvalds 67335c04a7b8SAlexey Dobriyan if (currTar_Info-> 67345c04a7b8SAlexey Dobriyan TarSelQ_Head == 67355c04a7b8SAlexey Dobriyan NULL) { 67365c04a7b8SAlexey Dobriyan currTar_Info-> 67375c04a7b8SAlexey Dobriyan TarSelQ_Tail 67385c04a7b8SAlexey Dobriyan = NULL; 67395c04a7b8SAlexey Dobriyan currTar_Info-> 67405c04a7b8SAlexey Dobriyan TarSelQ_Cnt 67415c04a7b8SAlexey Dobriyan = 0; 67425c04a7b8SAlexey Dobriyan } else { 67435c04a7b8SAlexey Dobriyan currTar_Info-> 67445c04a7b8SAlexey Dobriyan TarSelQ_Cnt--; 67455c04a7b8SAlexey Dobriyan currTar_Info-> 67465c04a7b8SAlexey Dobriyan TarSelQ_Head-> 67475c04a7b8SAlexey Dobriyan Sccb_backlink 67485c04a7b8SAlexey Dobriyan = 67495c04a7b8SAlexey Dobriyan (struct sccb 67505c04a7b8SAlexey Dobriyan *)NULL; 67511da177e4SLinus Torvalds } 67521da177e4SLinus Torvalds } 67531da177e4SLinus Torvalds pCurrCard->scanIndex = scan_ptr; 67541da177e4SLinus Torvalds 67555c04a7b8SAlexey Dobriyan pCurrCard->globalFlags |= 67565c04a7b8SAlexey Dobriyan F_NEW_SCCB_CMD; 67571da177e4SLinus Torvalds 67581da177e4SLinus Torvalds break; 67591da177e4SLinus Torvalds } 67601da177e4SLinus Torvalds } 67611da177e4SLinus Torvalds } 67621da177e4SLinus Torvalds 67635c04a7b8SAlexey Dobriyan else { 67641da177e4SLinus Torvalds scan_ptr++; 67651da177e4SLinus Torvalds if (scan_ptr == MAX_SCSI_TAR) { 67661da177e4SLinus Torvalds scan_ptr = 0; 67671da177e4SLinus Torvalds } 67681da177e4SLinus Torvalds } 67691da177e4SLinus Torvalds 67705c04a7b8SAlexey Dobriyan } else { 67711da177e4SLinus Torvalds if ((currTar_Info->TarSelQ_Cnt != 0) && 67725c04a7b8SAlexey Dobriyan (currTar_Info->TarLUNBusy[0] == 0)) { 67731da177e4SLinus Torvalds 67745c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB = 67755c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head; 67761da177e4SLinus Torvalds 67775c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head = 67785c04a7b8SAlexey Dobriyan (struct sccb *)(pCurrCard->currentSCCB)-> 67795c04a7b8SAlexey Dobriyan Sccb_forwardlink; 67801da177e4SLinus Torvalds 67815c04a7b8SAlexey Dobriyan if (currTar_Info->TarSelQ_Head == NULL) { 67821da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = NULL; 67831da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt = 0; 67845c04a7b8SAlexey Dobriyan } else { 67851da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt--; 67865c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head-> 67875c04a7b8SAlexey Dobriyan Sccb_backlink = (struct sccb *)NULL; 67881da177e4SLinus Torvalds } 67891da177e4SLinus Torvalds 67901da177e4SLinus Torvalds scan_ptr++; 67911da177e4SLinus Torvalds if (scan_ptr == MAX_SCSI_TAR) 67921da177e4SLinus Torvalds scan_ptr = 0; 67931da177e4SLinus Torvalds 67941da177e4SLinus Torvalds pCurrCard->scanIndex = scan_ptr; 67951da177e4SLinus Torvalds 67961da177e4SLinus Torvalds pCurrCard->globalFlags |= F_NEW_SCCB_CMD; 67971da177e4SLinus Torvalds 67981da177e4SLinus Torvalds break; 67991da177e4SLinus Torvalds } 68001da177e4SLinus Torvalds 68015c04a7b8SAlexey Dobriyan else { 68021da177e4SLinus Torvalds scan_ptr++; 68035c04a7b8SAlexey Dobriyan if (scan_ptr == MAX_SCSI_TAR) { 68041da177e4SLinus Torvalds scan_ptr = 0; 68051da177e4SLinus Torvalds } 68061da177e4SLinus Torvalds } 68071da177e4SLinus Torvalds } 68081da177e4SLinus Torvalds } while (scan_ptr != pCurrCard->scanIndex); 68091da177e4SLinus Torvalds } 68101da177e4SLinus Torvalds 68111da177e4SLinus Torvalds /*--------------------------------------------------------------------- 68121da177e4SLinus Torvalds * 68131da177e4SLinus Torvalds * Function: Queue Select Fail 68141da177e4SLinus Torvalds * 68151da177e4SLinus Torvalds * Description: Add the current SCCB to the head of the Queue. 68161da177e4SLinus Torvalds * 68171da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 68181da177e4SLinus Torvalds 68195c04a7b8SAlexey Dobriyan static void FPT_queueSelectFail(struct sccb_card *pCurrCard, 68205c04a7b8SAlexey Dobriyan unsigned char p_card) 68211da177e4SLinus Torvalds { 6822db038cf8SAlexey Dobriyan unsigned char thisTarg; 6823f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 68241da177e4SLinus Torvalds 68255c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) { 68265c04a7b8SAlexey Dobriyan thisTarg = 68275c04a7b8SAlexey Dobriyan (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))-> 68285c04a7b8SAlexey Dobriyan TargID); 682947b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; 68301da177e4SLinus Torvalds 683169eb2ea4SAlexey Dobriyan pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL; 68321da177e4SLinus Torvalds 68335c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB->Sccb_forwardlink = 68345c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head; 68351da177e4SLinus Torvalds 68365c04a7b8SAlexey Dobriyan if (currTar_Info->TarSelQ_Cnt == 0) { 68371da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB; 68381da177e4SLinus Torvalds } 68391da177e4SLinus Torvalds 68405c04a7b8SAlexey Dobriyan else { 68415c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head->Sccb_backlink = 68425c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB; 68431da177e4SLinus Torvalds } 68441da177e4SLinus Torvalds 68451da177e4SLinus Torvalds currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB; 68461da177e4SLinus Torvalds 68471da177e4SLinus Torvalds pCurrCard->currentSCCB = NULL; 68481da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt++; 68491da177e4SLinus Torvalds } 68501da177e4SLinus Torvalds } 68515c04a7b8SAlexey Dobriyan 68521da177e4SLinus Torvalds /*--------------------------------------------------------------------- 68531da177e4SLinus Torvalds * 68541da177e4SLinus Torvalds * Function: Queue Command Complete 68551da177e4SLinus Torvalds * 68561da177e4SLinus Torvalds * Description: Call the callback function with the current SCCB. 68571da177e4SLinus Torvalds * 68581da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 68591da177e4SLinus Torvalds 68605c04a7b8SAlexey Dobriyan static void FPT_queueCmdComplete(struct sccb_card *pCurrCard, 68615c04a7b8SAlexey Dobriyan struct sccb *p_sccb, unsigned char p_card) 68621da177e4SLinus Torvalds { 68631da177e4SLinus Torvalds 6864db038cf8SAlexey Dobriyan unsigned char i, SCSIcmd; 68651da177e4SLinus Torvalds CALL_BK_FN callback; 6866f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 68671da177e4SLinus Torvalds 68681da177e4SLinus Torvalds SCSIcmd = p_sccb->Cdb[0]; 68691da177e4SLinus Torvalds 68701da177e4SLinus Torvalds if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) { 68711da177e4SLinus Torvalds 68725c04a7b8SAlexey Dobriyan if ((p_sccb-> 68735c04a7b8SAlexey Dobriyan ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) 68745c04a7b8SAlexey Dobriyan && (p_sccb->HostStatus == SCCB_COMPLETE) 68755c04a7b8SAlexey Dobriyan && (p_sccb->TargetStatus != SSCHECK)) 68761da177e4SLinus Torvalds 68771da177e4SLinus Torvalds if ((SCSIcmd == SCSI_READ) || 68781da177e4SLinus Torvalds (SCSIcmd == SCSI_WRITE) || 68791da177e4SLinus Torvalds (SCSIcmd == SCSI_READ_EXTENDED) || 68801da177e4SLinus Torvalds (SCSIcmd == SCSI_WRITE_EXTENDED) || 68811da177e4SLinus Torvalds (SCSIcmd == SCSI_WRITE_AND_VERIFY) || 68821da177e4SLinus Torvalds (SCSIcmd == SCSI_START_STOP_UNIT) || 68831da177e4SLinus Torvalds (pCurrCard->globalFlags & F_NO_FILTER) 68841da177e4SLinus Torvalds ) 68851da177e4SLinus Torvalds p_sccb->HostStatus = SCCB_DATA_UNDER_RUN; 68861da177e4SLinus Torvalds } 68871da177e4SLinus Torvalds 68885c04a7b8SAlexey Dobriyan if (p_sccb->SccbStatus == SCCB_IN_PROCESS) { 68891da177e4SLinus Torvalds if (p_sccb->HostStatus || p_sccb->TargetStatus) 68901da177e4SLinus Torvalds p_sccb->SccbStatus = SCCB_ERROR; 68911da177e4SLinus Torvalds else 68921da177e4SLinus Torvalds p_sccb->SccbStatus = SCCB_SUCCESS; 68931da177e4SLinus Torvalds } 68941da177e4SLinus Torvalds 68951da177e4SLinus Torvalds if (p_sccb->Sccb_XferState & F_AUTO_SENSE) { 68961da177e4SLinus Torvalds 68971da177e4SLinus Torvalds p_sccb->CdbLength = p_sccb->Save_CdbLen; 68981da177e4SLinus Torvalds for (i = 0; i < 6; i++) { 68991da177e4SLinus Torvalds p_sccb->Cdb[i] = p_sccb->Save_Cdb[i]; 69001da177e4SLinus Torvalds } 69011da177e4SLinus Torvalds } 69021da177e4SLinus Torvalds 69031da177e4SLinus Torvalds if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) || 69041da177e4SLinus Torvalds (p_sccb->OperationCode == RESIDUAL_COMMAND)) { 69051da177e4SLinus Torvalds 690647b5d69cSJames Bottomley FPT_utilUpdateResidual(p_sccb); 69071da177e4SLinus Torvalds } 69081da177e4SLinus Torvalds 69091da177e4SLinus Torvalds pCurrCard->cmdCounter--; 69101da177e4SLinus Torvalds if (!pCurrCard->cmdCounter) { 69111da177e4SLinus Torvalds 69121da177e4SLinus Torvalds if (pCurrCard->globalFlags & F_GREEN_PC) { 69135c04a7b8SAlexey Dobriyan WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0, 69145c04a7b8SAlexey Dobriyan (PWR_DWN | CLKCTRL_DEFAULT)); 69151da177e4SLinus Torvalds WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK); 69161da177e4SLinus Torvalds } 69171da177e4SLinus Torvalds 69181da177e4SLinus Torvalds WR_HARPOON(pCurrCard->ioPort + hp_semaphore, 69195c04a7b8SAlexey Dobriyan (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) & 69205c04a7b8SAlexey Dobriyan ~SCCB_MGR_ACTIVE)); 69211da177e4SLinus Torvalds 69221da177e4SLinus Torvalds } 69231da177e4SLinus Torvalds 69245c04a7b8SAlexey Dobriyan if (pCurrCard->discQCount != 0) { 692547b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; 69261da177e4SLinus Torvalds if (((pCurrCard->globalFlags & F_CONLUN_IO) && 69275c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != 69285c04a7b8SAlexey Dobriyan TAG_Q_TRYING))) { 69291da177e4SLinus Torvalds pCurrCard->discQCount--; 69305c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info-> 69315c04a7b8SAlexey Dobriyan LunDiscQ_Idx[p_sccb->Lun]] = NULL; 69325c04a7b8SAlexey Dobriyan } else { 69335c04a7b8SAlexey Dobriyan if (p_sccb->Sccb_tag) { 69341da177e4SLinus Torvalds pCurrCard->discQCount--; 69351da177e4SLinus Torvalds pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL; 69365c04a7b8SAlexey Dobriyan } else { 69371da177e4SLinus Torvalds pCurrCard->discQCount--; 69385c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info-> 69395c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL; 69401da177e4SLinus Torvalds } 69411da177e4SLinus Torvalds } 69421da177e4SLinus Torvalds 69431da177e4SLinus Torvalds } 69441da177e4SLinus Torvalds 69451da177e4SLinus Torvalds callback = (CALL_BK_FN) p_sccb->SccbCallback; 69461da177e4SLinus Torvalds callback(p_sccb); 69471da177e4SLinus Torvalds pCurrCard->globalFlags |= F_NEW_SCCB_CMD; 69481da177e4SLinus Torvalds pCurrCard->currentSCCB = NULL; 69491da177e4SLinus Torvalds } 69501da177e4SLinus Torvalds 69511da177e4SLinus Torvalds /*--------------------------------------------------------------------- 69521da177e4SLinus Torvalds * 69531da177e4SLinus Torvalds * Function: Queue Disconnect 69541da177e4SLinus Torvalds * 69551da177e4SLinus Torvalds * Description: Add SCCB to our disconnect array. 69561da177e4SLinus Torvalds * 69571da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 695869eb2ea4SAlexey Dobriyan static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card) 69591da177e4SLinus Torvalds { 6960f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 69611da177e4SLinus Torvalds 696247b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID]; 69631da177e4SLinus Torvalds 696447b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && 69655c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) { 69665c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currTar_Info-> 69675c04a7b8SAlexey Dobriyan LunDiscQ_Idx[p_sccb->Lun]] = 69685c04a7b8SAlexey Dobriyan p_sccb; 69695c04a7b8SAlexey Dobriyan } else { 69705c04a7b8SAlexey Dobriyan if (p_sccb->Sccb_tag) { 69715c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = 69725c04a7b8SAlexey Dobriyan p_sccb; 69735c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 69745c04a7b8SAlexey Dobriyan 0; 697547b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++; 69765c04a7b8SAlexey Dobriyan } else { 69775c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currTar_Info-> 69785c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = p_sccb; 69791da177e4SLinus Torvalds } 69801da177e4SLinus Torvalds } 698147b5d69cSJames Bottomley FPT_BL_Card[p_card].currentSCCB = NULL; 69821da177e4SLinus Torvalds } 69831da177e4SLinus Torvalds 69841da177e4SLinus Torvalds /*--------------------------------------------------------------------- 69851da177e4SLinus Torvalds * 69861da177e4SLinus Torvalds * Function: Queue Flush SCCB 69871da177e4SLinus Torvalds * 69881da177e4SLinus Torvalds * Description: Flush all SCCB's back to the host driver for this target. 69891da177e4SLinus Torvalds * 69901da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 69911da177e4SLinus Torvalds 6992db038cf8SAlexey Dobriyan static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code) 69931da177e4SLinus Torvalds { 6994db038cf8SAlexey Dobriyan unsigned char qtag, thisTarg; 699569eb2ea4SAlexey Dobriyan struct sccb *currSCCB; 6996f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 69971da177e4SLinus Torvalds 699847b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB; 69995c04a7b8SAlexey Dobriyan if (currSCCB != NULL) { 7000db038cf8SAlexey Dobriyan thisTarg = (unsigned char)currSCCB->TargID; 700147b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; 70021da177e4SLinus Torvalds 70031da177e4SLinus Torvalds for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { 70041da177e4SLinus Torvalds 700547b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && 70065c04a7b8SAlexey Dobriyan (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == 70075c04a7b8SAlexey Dobriyan thisTarg)) { 70081da177e4SLinus Torvalds 70095c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[qtag]-> 70105c04a7b8SAlexey Dobriyan HostStatus = (unsigned char)error_code; 70111da177e4SLinus Torvalds 70125c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], 70135c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 70145c04a7b8SAlexey Dobriyan discQ_Tbl[qtag], p_card); 70151da177e4SLinus Torvalds 701647b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; 70171da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt--; 70181da177e4SLinus Torvalds 70191da177e4SLinus Torvalds } 70201da177e4SLinus Torvalds } 70211da177e4SLinus Torvalds } 70221da177e4SLinus Torvalds 70231da177e4SLinus Torvalds } 70241da177e4SLinus Torvalds 70251da177e4SLinus Torvalds /*--------------------------------------------------------------------- 70261da177e4SLinus Torvalds * 70271da177e4SLinus Torvalds * Function: Queue Flush Target SCCB 70281da177e4SLinus Torvalds * 70291da177e4SLinus Torvalds * Description: Flush all SCCB's back to the host driver for this target. 70301da177e4SLinus Torvalds * 70311da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 70321da177e4SLinus Torvalds 7033db038cf8SAlexey Dobriyan static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg, 7034db038cf8SAlexey Dobriyan unsigned char error_code) 70351da177e4SLinus Torvalds { 7036db038cf8SAlexey Dobriyan unsigned char qtag; 7037f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 70381da177e4SLinus Torvalds 703947b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg]; 70401da177e4SLinus Torvalds 70411da177e4SLinus Torvalds for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) { 70421da177e4SLinus Torvalds 704347b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && 70445c04a7b8SAlexey Dobriyan (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) { 70451da177e4SLinus Torvalds 70465c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = 70475c04a7b8SAlexey Dobriyan (unsigned char)error_code; 70481da177e4SLinus Torvalds 70495c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], 70505c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card]. 70515c04a7b8SAlexey Dobriyan discQ_Tbl[qtag], p_card); 70521da177e4SLinus Torvalds 705347b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL; 70541da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt--; 70551da177e4SLinus Torvalds 70561da177e4SLinus Torvalds } 70571da177e4SLinus Torvalds } 70581da177e4SLinus Torvalds 70591da177e4SLinus Torvalds } 70601da177e4SLinus Torvalds 706169eb2ea4SAlexey Dobriyan static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card) 70621da177e4SLinus Torvalds { 7063f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 706447b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID]; 70651da177e4SLinus Torvalds 70661da177e4SLinus Torvalds p_SCCB->Sccb_forwardlink = NULL; 70671da177e4SLinus Torvalds 70681da177e4SLinus Torvalds p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail; 70691da177e4SLinus Torvalds 70701da177e4SLinus Torvalds if (currTar_Info->TarSelQ_Cnt == 0) { 70711da177e4SLinus Torvalds 70721da177e4SLinus Torvalds currTar_Info->TarSelQ_Head = p_SCCB; 70731da177e4SLinus Torvalds } 70741da177e4SLinus Torvalds 70751da177e4SLinus Torvalds else { 70761da177e4SLinus Torvalds 70771da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB; 70781da177e4SLinus Torvalds } 70791da177e4SLinus Torvalds 70801da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = p_SCCB; 70811da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt++; 70821da177e4SLinus Torvalds } 70831da177e4SLinus Torvalds 70841da177e4SLinus Torvalds /*--------------------------------------------------------------------- 70851da177e4SLinus Torvalds * 70861da177e4SLinus Torvalds * Function: Queue Find SCCB 70871da177e4SLinus Torvalds * 70881da177e4SLinus Torvalds * Description: Search the target select Queue for this SCCB, and 70891da177e4SLinus Torvalds * remove it if found. 70901da177e4SLinus Torvalds * 70911da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 70921da177e4SLinus Torvalds 70935c04a7b8SAlexey Dobriyan static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB, 70945c04a7b8SAlexey Dobriyan unsigned char p_card) 70951da177e4SLinus Torvalds { 709669eb2ea4SAlexey Dobriyan struct sccb *q_ptr; 7097f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info; 70981da177e4SLinus Torvalds 709947b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID]; 71001da177e4SLinus Torvalds 71011da177e4SLinus Torvalds q_ptr = currTar_Info->TarSelQ_Head; 71021da177e4SLinus Torvalds 71031da177e4SLinus Torvalds while (q_ptr != NULL) { 71041da177e4SLinus Torvalds 71051da177e4SLinus Torvalds if (q_ptr == p_SCCB) { 71061da177e4SLinus Torvalds 71071da177e4SLinus Torvalds if (currTar_Info->TarSelQ_Head == q_ptr) { 71081da177e4SLinus Torvalds 71095c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head = 71105c04a7b8SAlexey Dobriyan q_ptr->Sccb_forwardlink; 71111da177e4SLinus Torvalds } 71121da177e4SLinus Torvalds 71131da177e4SLinus Torvalds if (currTar_Info->TarSelQ_Tail == q_ptr) { 71141da177e4SLinus Torvalds 71155c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Tail = 71165c04a7b8SAlexey Dobriyan q_ptr->Sccb_backlink; 71171da177e4SLinus Torvalds } 71181da177e4SLinus Torvalds 71191da177e4SLinus Torvalds if (q_ptr->Sccb_forwardlink != NULL) { 71205c04a7b8SAlexey Dobriyan q_ptr->Sccb_forwardlink->Sccb_backlink = 71215c04a7b8SAlexey Dobriyan q_ptr->Sccb_backlink; 71221da177e4SLinus Torvalds } 71231da177e4SLinus Torvalds 71241da177e4SLinus Torvalds if (q_ptr->Sccb_backlink != NULL) { 71255c04a7b8SAlexey Dobriyan q_ptr->Sccb_backlink->Sccb_forwardlink = 71265c04a7b8SAlexey Dobriyan q_ptr->Sccb_forwardlink; 71271da177e4SLinus Torvalds } 71281da177e4SLinus Torvalds 71291da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt--; 71301da177e4SLinus Torvalds 71315c1b85e2SAlexey Dobriyan return 1; 71321da177e4SLinus Torvalds } 71331da177e4SLinus Torvalds 71341da177e4SLinus Torvalds else { 71351da177e4SLinus Torvalds q_ptr = q_ptr->Sccb_forwardlink; 71361da177e4SLinus Torvalds } 71371da177e4SLinus Torvalds } 71381da177e4SLinus Torvalds 71395c1b85e2SAlexey Dobriyan return 0; 71401da177e4SLinus Torvalds 71411da177e4SLinus Torvalds } 71421da177e4SLinus Torvalds 71431da177e4SLinus Torvalds /*--------------------------------------------------------------------- 71441da177e4SLinus Torvalds * 71451da177e4SLinus Torvalds * Function: Utility Update Residual Count 71461da177e4SLinus Torvalds * 71471da177e4SLinus Torvalds * Description: Update the XferCnt to the remaining byte count. 71481da177e4SLinus Torvalds * If we transferred all the data then just write zero. 71491da177e4SLinus Torvalds * If Non-SG transfer then report Total Cnt - Actual Transfer 71501da177e4SLinus Torvalds * Cnt. For SG transfers add the count fields of all 71511da177e4SLinus Torvalds * remaining SG elements, as well as any partial remaining 71521da177e4SLinus Torvalds * element. 71531da177e4SLinus Torvalds * 71541da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 71551da177e4SLinus Torvalds 715669eb2ea4SAlexey Dobriyan static void FPT_utilUpdateResidual(struct sccb *p_SCCB) 71571da177e4SLinus Torvalds { 7158d63a4cccSAlexey Dobriyan unsigned long partial_cnt; 7159ce793215SAlexey Dobriyan unsigned int sg_index; 7160391e2f25SKhalid Aziz struct blogic_sg_seg *segp; 71611da177e4SLinus Torvalds 71621da177e4SLinus Torvalds if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) { 71631da177e4SLinus Torvalds 71641da177e4SLinus Torvalds p_SCCB->DataLength = 0x0000; 71651da177e4SLinus Torvalds } 71661da177e4SLinus Torvalds 71671da177e4SLinus Torvalds else if (p_SCCB->Sccb_XferState & F_SG_XFER) { 71681da177e4SLinus Torvalds 71691da177e4SLinus Torvalds partial_cnt = 0x0000; 71701da177e4SLinus Torvalds 71711da177e4SLinus Torvalds sg_index = p_SCCB->Sccb_sgseg; 71721da177e4SLinus Torvalds 71731da177e4SLinus Torvalds 71741da177e4SLinus Torvalds if (p_SCCB->Sccb_SGoffset) { 71751da177e4SLinus Torvalds 71761da177e4SLinus Torvalds partial_cnt = p_SCCB->Sccb_SGoffset; 71771da177e4SLinus Torvalds sg_index++; 71781da177e4SLinus Torvalds } 71791da177e4SLinus Torvalds 71805c04a7b8SAlexey Dobriyan while (((unsigned long)sg_index * 71815c04a7b8SAlexey Dobriyan (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) { 7182391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) + 7183391e2f25SKhalid Aziz (sg_index * 2); 7184391e2f25SKhalid Aziz partial_cnt += segp->segbytes; 71851da177e4SLinus Torvalds sg_index++; 71861da177e4SLinus Torvalds } 71871da177e4SLinus Torvalds 71881da177e4SLinus Torvalds p_SCCB->DataLength = partial_cnt; 71891da177e4SLinus Torvalds } 71901da177e4SLinus Torvalds 71911da177e4SLinus Torvalds else { 71921da177e4SLinus Torvalds 71931da177e4SLinus Torvalds p_SCCB->DataLength -= p_SCCB->Sccb_ATC; 71941da177e4SLinus Torvalds } 71951da177e4SLinus Torvalds } 71961da177e4SLinus Torvalds 71971da177e4SLinus Torvalds /*--------------------------------------------------------------------- 71981da177e4SLinus Torvalds * 71991da177e4SLinus Torvalds * Function: Wait 1 Second 72001da177e4SLinus Torvalds * 72011da177e4SLinus Torvalds * Description: Wait for 1 second. 72021da177e4SLinus Torvalds * 72031da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 72041da177e4SLinus Torvalds 7205391e2f25SKhalid Aziz static void FPT_Wait1Second(u32 p_port) 72061da177e4SLinus Torvalds { 7207db038cf8SAlexey Dobriyan unsigned char i; 72081da177e4SLinus Torvalds 72091da177e4SLinus Torvalds for (i = 0; i < 4; i++) { 72101da177e4SLinus Torvalds 721147b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms); 72121da177e4SLinus Torvalds 72131da177e4SLinus Torvalds if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST)) 72141da177e4SLinus Torvalds break; 72151da177e4SLinus Torvalds 72161da177e4SLinus Torvalds if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) 72171da177e4SLinus Torvalds break; 72181da177e4SLinus Torvalds } 72191da177e4SLinus Torvalds } 72201da177e4SLinus Torvalds 72211da177e4SLinus Torvalds /*--------------------------------------------------------------------- 72221da177e4SLinus Torvalds * 722347b5d69cSJames Bottomley * Function: FPT_Wait 72241da177e4SLinus Torvalds * 72251da177e4SLinus Torvalds * Description: Wait the desired delay. 72261da177e4SLinus Torvalds * 72271da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 72281da177e4SLinus Torvalds 7229391e2f25SKhalid Aziz static void FPT_Wait(u32 p_port, unsigned char p_delay) 72301da177e4SLinus Torvalds { 7231db038cf8SAlexey Dobriyan unsigned char old_timer; 7232db038cf8SAlexey Dobriyan unsigned char green_flag; 72331da177e4SLinus Torvalds 72341da177e4SLinus Torvalds old_timer = RD_HARPOON(p_port + hp_seltimeout); 72351da177e4SLinus Torvalds 72361da177e4SLinus Torvalds green_flag = RD_HARPOON(p_port + hp_clkctrl_0); 72371da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT); 72381da177e4SLinus Torvalds 72391da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, p_delay); 72401da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), TIMEOUT); 724147b5d69cSJames Bottomley WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT)); 72421da177e4SLinus Torvalds 72431da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, 72441da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_portctrl_0) | START_TO)); 72451da177e4SLinus Torvalds 72461da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) { 72471da177e4SLinus Torvalds 72481da177e4SLinus Torvalds if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST)) 72491da177e4SLinus Torvalds break; 72501da177e4SLinus Torvalds 72511da177e4SLinus Torvalds if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) 72521da177e4SLinus Torvalds break; 72531da177e4SLinus Torvalds } 72541da177e4SLinus Torvalds 72551da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, 72561da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO)); 72571da177e4SLinus Torvalds 72581da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), TIMEOUT); 725947b5d69cSJames Bottomley WRW_HARPOON((p_port + hp_intena), FPT_default_intena); 72601da177e4SLinus Torvalds 72611da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, green_flag); 72621da177e4SLinus Torvalds 72631da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, old_timer); 72641da177e4SLinus Torvalds } 72651da177e4SLinus Torvalds 72661da177e4SLinus Torvalds /*--------------------------------------------------------------------- 72671da177e4SLinus Torvalds * 72681da177e4SLinus Torvalds * Function: Enable/Disable Write to EEPROM 72691da177e4SLinus Torvalds * 72701da177e4SLinus Torvalds * Description: The EEPROM must first be enabled for writes 72711da177e4SLinus Torvalds * A total of 9 clocks are needed. 72721da177e4SLinus Torvalds * 72731da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 72741da177e4SLinus Torvalds 7275391e2f25SKhalid Aziz static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode) 72761da177e4SLinus Torvalds { 7277db038cf8SAlexey Dobriyan unsigned char ee_value; 72781da177e4SLinus Torvalds 72795c04a7b8SAlexey Dobriyan ee_value = 72805c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) & 72815c04a7b8SAlexey Dobriyan (EXT_ARB_ACK | SCSI_TERM_ENA_H)); 72821da177e4SLinus Torvalds 72831da177e4SLinus Torvalds if (p_mode) 72841da177e4SLinus Torvalds 728547b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR); 72861da177e4SLinus Torvalds 72871da177e4SLinus Torvalds else 72881da177e4SLinus Torvalds 728947b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR); 72901da177e4SLinus Torvalds 72911da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */ 72921da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */ 72931da177e4SLinus Torvalds } 72941da177e4SLinus Torvalds 72951da177e4SLinus Torvalds /*--------------------------------------------------------------------- 72961da177e4SLinus Torvalds * 72971da177e4SLinus Torvalds * Function: Write EEPROM 72981da177e4SLinus Torvalds * 72991da177e4SLinus Torvalds * Description: Write a word to the EEPROM at the specified 73001da177e4SLinus Torvalds * address. 73011da177e4SLinus Torvalds * 73021da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 73031da177e4SLinus Torvalds 7304391e2f25SKhalid Aziz static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data, 73055c04a7b8SAlexey Dobriyan unsigned short ee_addr) 73061da177e4SLinus Torvalds { 73071da177e4SLinus Torvalds 7308db038cf8SAlexey Dobriyan unsigned char ee_value; 7309c823feebSAlexey Dobriyan unsigned short i; 73101da177e4SLinus Torvalds 73115c04a7b8SAlexey Dobriyan ee_value = 73125c04a7b8SAlexey Dobriyan (unsigned 73135c04a7b8SAlexey Dobriyan char)((RD_HARPOON(p_port + hp_ee_ctrl) & 73145c04a7b8SAlexey Dobriyan (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS)); 73151da177e4SLinus Torvalds 731647b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr); 73171da177e4SLinus Torvalds 73181da177e4SLinus Torvalds ee_value |= (SEE_MS + SEE_CS); 73191da177e4SLinus Torvalds 73201da177e4SLinus Torvalds for (i = 0x8000; i != 0; i >>= 1) { 73211da177e4SLinus Torvalds 73221da177e4SLinus Torvalds if (i & ee_data) 73231da177e4SLinus Torvalds ee_value |= SEE_DO; 73241da177e4SLinus Torvalds else 73251da177e4SLinus Torvalds ee_value &= ~SEE_DO; 73261da177e4SLinus Torvalds 73271da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 73281da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 73291da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */ 73301da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 73311da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 73321da177e4SLinus Torvalds ee_value &= ~SEE_CLK; 73331da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 73341da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 73351da177e4SLinus Torvalds } 73361da177e4SLinus Torvalds ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H); 73371da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); 73381da177e4SLinus Torvalds 733947b5d69cSJames Bottomley FPT_Wait(p_port, TO_10ms); 73401da177e4SLinus Torvalds 73411da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */ 73421da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */ 73431da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */ 73441da177e4SLinus Torvalds } 73451da177e4SLinus Torvalds 73461da177e4SLinus Torvalds /*--------------------------------------------------------------------- 73471da177e4SLinus Torvalds * 73481da177e4SLinus Torvalds * Function: Read EEPROM 73491da177e4SLinus Torvalds * 73501da177e4SLinus Torvalds * Description: Read a word from the EEPROM at the desired 73511da177e4SLinus Torvalds * address. 73521da177e4SLinus Torvalds * 73531da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 73541da177e4SLinus Torvalds 7355391e2f25SKhalid Aziz static unsigned short FPT_utilEERead(u32 p_port, 73565c04a7b8SAlexey Dobriyan unsigned short ee_addr) 73571da177e4SLinus Torvalds { 7358c823feebSAlexey Dobriyan unsigned short i, ee_data1, ee_data2; 73591da177e4SLinus Torvalds 73601da177e4SLinus Torvalds i = 0; 736147b5d69cSJames Bottomley ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr); 73625c04a7b8SAlexey Dobriyan do { 736347b5d69cSJames Bottomley ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr); 73641da177e4SLinus Torvalds 73651da177e4SLinus Torvalds if (ee_data1 == ee_data2) 73665c1b85e2SAlexey Dobriyan return ee_data1; 73671da177e4SLinus Torvalds 73681da177e4SLinus Torvalds ee_data1 = ee_data2; 73691da177e4SLinus Torvalds i++; 73701da177e4SLinus Torvalds 73711da177e4SLinus Torvalds } while (i < 4); 73721da177e4SLinus Torvalds 73735c1b85e2SAlexey Dobriyan return ee_data1; 73741da177e4SLinus Torvalds } 73751da177e4SLinus Torvalds 73761da177e4SLinus Torvalds /*--------------------------------------------------------------------- 73771da177e4SLinus Torvalds * 73781da177e4SLinus Torvalds * Function: Read EEPROM Original 73791da177e4SLinus Torvalds * 73801da177e4SLinus Torvalds * Description: Read a word from the EEPROM at the desired 73811da177e4SLinus Torvalds * address. 73821da177e4SLinus Torvalds * 73831da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 73841da177e4SLinus Torvalds 7385391e2f25SKhalid Aziz static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr) 73861da177e4SLinus Torvalds { 73871da177e4SLinus Torvalds 7388db038cf8SAlexey Dobriyan unsigned char ee_value; 7389c823feebSAlexey Dobriyan unsigned short i, ee_data; 73901da177e4SLinus Torvalds 73915c04a7b8SAlexey Dobriyan ee_value = 73925c04a7b8SAlexey Dobriyan (unsigned 73935c04a7b8SAlexey Dobriyan char)((RD_HARPOON(p_port + hp_ee_ctrl) & 73945c04a7b8SAlexey Dobriyan (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS)); 73951da177e4SLinus Torvalds 739647b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr); 73971da177e4SLinus Torvalds 73981da177e4SLinus Torvalds ee_value |= (SEE_MS + SEE_CS); 73991da177e4SLinus Torvalds ee_data = 0; 74001da177e4SLinus Torvalds 74011da177e4SLinus Torvalds for (i = 1; i <= 16; i++) { 74021da177e4SLinus Torvalds 74031da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */ 74041da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74051da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74061da177e4SLinus Torvalds ee_value &= ~SEE_CLK; 74071da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74081da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74091da177e4SLinus Torvalds 74101da177e4SLinus Torvalds ee_data <<= 1; 74111da177e4SLinus Torvalds 74121da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI) 74131da177e4SLinus Torvalds ee_data |= 1; 74141da177e4SLinus Torvalds } 74151da177e4SLinus Torvalds 74161da177e4SLinus Torvalds ee_value &= ~(SEE_MS + SEE_CS); 74171da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */ 74181da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */ 74191da177e4SLinus Torvalds 74205c1b85e2SAlexey Dobriyan return ee_data; 74211da177e4SLinus Torvalds } 74221da177e4SLinus Torvalds 74231da177e4SLinus Torvalds /*--------------------------------------------------------------------- 74241da177e4SLinus Torvalds * 74251da177e4SLinus Torvalds * Function: Send EE command and Address to the EEPROM 74261da177e4SLinus Torvalds * 74271da177e4SLinus Torvalds * Description: Transfers the correct command and sends the address 74281da177e4SLinus Torvalds * to the eeprom. 74291da177e4SLinus Torvalds * 74301da177e4SLinus Torvalds *---------------------------------------------------------------------*/ 74311da177e4SLinus Torvalds 7432391e2f25SKhalid Aziz static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd, 74335c04a7b8SAlexey Dobriyan unsigned short ee_addr) 74341da177e4SLinus Torvalds { 7435db038cf8SAlexey Dobriyan unsigned char ee_value; 7436db038cf8SAlexey Dobriyan unsigned char narrow_flg; 74371da177e4SLinus Torvalds 7438c823feebSAlexey Dobriyan unsigned short i; 74391da177e4SLinus Torvalds 74405c04a7b8SAlexey Dobriyan narrow_flg = 74415c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) & 74425c04a7b8SAlexey Dobriyan NARROW_SCSI_CARD); 74431da177e4SLinus Torvalds 74441da177e4SLinus Torvalds ee_value = SEE_MS; 74451da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74461da177e4SLinus Torvalds 74471da177e4SLinus Torvalds ee_value |= SEE_CS; /* Set CS to EEPROM */ 74481da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74491da177e4SLinus Torvalds 74501da177e4SLinus Torvalds for (i = 0x04; i != 0; i >>= 1) { 74511da177e4SLinus Torvalds 74521da177e4SLinus Torvalds if (i & ee_cmd) 74531da177e4SLinus Torvalds ee_value |= SEE_DO; 74541da177e4SLinus Torvalds else 74551da177e4SLinus Torvalds ee_value &= ~SEE_DO; 74561da177e4SLinus Torvalds 74571da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74581da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74591da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */ 74601da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74611da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74621da177e4SLinus Torvalds ee_value &= ~SEE_CLK; 74631da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74641da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74651da177e4SLinus Torvalds } 74661da177e4SLinus Torvalds 74671da177e4SLinus Torvalds if (narrow_flg) 74681da177e4SLinus Torvalds i = 0x0080; 74691da177e4SLinus Torvalds 74701da177e4SLinus Torvalds else 74711da177e4SLinus Torvalds i = 0x0200; 74721da177e4SLinus Torvalds 74731da177e4SLinus Torvalds while (i != 0) { 74741da177e4SLinus Torvalds 74751da177e4SLinus Torvalds if (i & ee_addr) 74761da177e4SLinus Torvalds ee_value |= SEE_DO; 74771da177e4SLinus Torvalds else 74781da177e4SLinus Torvalds ee_value &= ~SEE_DO; 74791da177e4SLinus Torvalds 74801da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74811da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74821da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */ 74831da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74841da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74851da177e4SLinus Torvalds ee_value &= ~SEE_CLK; 74861da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74871da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); 74881da177e4SLinus Torvalds 74891da177e4SLinus Torvalds i >>= 1; 74901da177e4SLinus Torvalds } 74911da177e4SLinus Torvalds } 74921da177e4SLinus Torvalds 7493c823feebSAlexey Dobriyan static unsigned short FPT_CalcCrc16(unsigned char buffer[]) 74941da177e4SLinus Torvalds { 7495c823feebSAlexey Dobriyan unsigned short crc = 0; 74961da177e4SLinus Torvalds int i, j; 7497c823feebSAlexey Dobriyan unsigned short ch; 74985c04a7b8SAlexey Dobriyan for (i = 0; i < ID_STRING_LENGTH; i++) { 7499c823feebSAlexey Dobriyan ch = (unsigned short)buffer[i]; 75005c04a7b8SAlexey Dobriyan for (j = 0; j < 8; j++) { 75011da177e4SLinus Torvalds if ((crc ^ ch) & 1) 75021da177e4SLinus Torvalds crc = (crc >> 1) ^ CRCMASK; 75031da177e4SLinus Torvalds else 75041da177e4SLinus Torvalds crc >>= 1; 75051da177e4SLinus Torvalds ch >>= 1; 75061da177e4SLinus Torvalds } 75071da177e4SLinus Torvalds } 75085c1b85e2SAlexey Dobriyan return crc; 75091da177e4SLinus Torvalds } 75101da177e4SLinus Torvalds 7511db038cf8SAlexey Dobriyan static unsigned char FPT_CalcLrc(unsigned char buffer[]) 75121da177e4SLinus Torvalds { 75131da177e4SLinus Torvalds int i; 7514db038cf8SAlexey Dobriyan unsigned char lrc; 75151da177e4SLinus Torvalds lrc = 0; 75161da177e4SLinus Torvalds for (i = 0; i < ID_STRING_LENGTH; i++) 75171da177e4SLinus Torvalds lrc ^= buffer[i]; 75185c1b85e2SAlexey Dobriyan return lrc; 75191da177e4SLinus Torvalds } 75201da177e4SLinus Torvalds 75211da177e4SLinus Torvalds /* 75221da177e4SLinus Torvalds The following inline definitions avoid type conflicts. 75231da177e4SLinus Torvalds */ 75241da177e4SLinus Torvalds 75251da177e4SLinus Torvalds static inline unsigned char 7526839cb99eSKhalid Aziz FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo) 75271da177e4SLinus Torvalds { 75285c04a7b8SAlexey Dobriyan return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) 75295c04a7b8SAlexey Dobriyan FlashPointInfo); 75301da177e4SLinus Torvalds } 75311da177e4SLinus Torvalds 7532391e2f25SKhalid Aziz static inline void * 7533839cb99eSKhalid Aziz FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo) 75341da177e4SLinus Torvalds { 75355c04a7b8SAlexey Dobriyan return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) 75365c04a7b8SAlexey Dobriyan FlashPointInfo); 75371da177e4SLinus Torvalds } 75381da177e4SLinus Torvalds 75391da177e4SLinus Torvalds static inline void 7540391e2f25SKhalid Aziz FlashPoint__ReleaseHostAdapter(void *CardHandle) 75411da177e4SLinus Torvalds { 75421da177e4SLinus Torvalds FlashPoint_ReleaseHostAdapter(CardHandle); 75431da177e4SLinus Torvalds } 75441da177e4SLinus Torvalds 75451da177e4SLinus Torvalds static inline void 7546391e2f25SKhalid Aziz FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB) 75471da177e4SLinus Torvalds { 754869eb2ea4SAlexey Dobriyan FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB); 75491da177e4SLinus Torvalds } 75501da177e4SLinus Torvalds 75511da177e4SLinus Torvalds static inline void 7552391e2f25SKhalid Aziz FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB) 75531da177e4SLinus Torvalds { 755469eb2ea4SAlexey Dobriyan FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB); 75551da177e4SLinus Torvalds } 75561da177e4SLinus Torvalds 75572065e310SRichard Knutsson static inline bool 7558391e2f25SKhalid Aziz FlashPoint__InterruptPending(void *CardHandle) 75591da177e4SLinus Torvalds { 75601da177e4SLinus Torvalds return FlashPoint_InterruptPending(CardHandle); 75611da177e4SLinus Torvalds } 75621da177e4SLinus Torvalds 75631da177e4SLinus Torvalds static inline int 7564391e2f25SKhalid Aziz FlashPoint__HandleInterrupt(void *CardHandle) 75651da177e4SLinus Torvalds { 75661da177e4SLinus Torvalds return FlashPoint_HandleInterrupt(CardHandle); 75671da177e4SLinus Torvalds } 75681da177e4SLinus Torvalds 75691da177e4SLinus Torvalds #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter 75701da177e4SLinus Torvalds #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter 75711da177e4SLinus Torvalds #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter 75721da177e4SLinus Torvalds #define FlashPoint_StartCCB FlashPoint__StartCCB 75731da177e4SLinus Torvalds #define FlashPoint_AbortCCB FlashPoint__AbortCCB 75741da177e4SLinus Torvalds #define FlashPoint_InterruptPending FlashPoint__InterruptPending 75751da177e4SLinus Torvalds #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt 75761da177e4SLinus Torvalds 757778b4b05dSMatthew Wilcox #else /* !CONFIG_SCSI_FLASHPOINT */ 75781da177e4SLinus Torvalds 75791da177e4SLinus Torvalds /* 75801da177e4SLinus Torvalds Define prototypes for the FlashPoint SCCB Manager Functions. 75811da177e4SLinus Torvalds */ 75821da177e4SLinus Torvalds 7583839cb99eSKhalid Aziz extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *); 7584391e2f25SKhalid Aziz extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *); 7585391e2f25SKhalid Aziz extern void FlashPoint_StartCCB(void *, struct blogic_ccb *); 7586391e2f25SKhalid Aziz extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *); 7587391e2f25SKhalid Aziz extern bool FlashPoint_InterruptPending(void *); 7588391e2f25SKhalid Aziz extern int FlashPoint_HandleInterrupt(void *); 7589391e2f25SKhalid Aziz extern void FlashPoint_ReleaseHostAdapter(void *); 75901da177e4SLinus Torvalds 759178b4b05dSMatthew Wilcox #endif /* CONFIG_SCSI_FLASHPOINT */ 7592