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;
434d431153SRandy Dunlap u16 si_mflags;
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
3081da177e4SLinus Torvalds #define SMIDENT 0x80
3091da177e4SLinus Torvalds #define DISC_PRIV 0x40
3101da177e4SLinus Torvalds
3111da177e4SLinus Torvalds #define SM8BIT 0x00
3121da177e4SLinus Torvalds #define SM16BIT 0x01
3131da177e4SLinus Torvalds
3141da177e4SLinus Torvalds #define SIX_BYTE_CMD 0x06
3151da177e4SLinus Torvalds #define TWELVE_BYTE_CMD 0x0C
3161da177e4SLinus Torvalds
3171da177e4SLinus Torvalds #define ASYNC 0x00
3181da177e4SLinus Torvalds #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
3191da177e4SLinus Torvalds
3201da177e4SLinus Torvalds #define EEPROM_WD_CNT 256
3211da177e4SLinus Torvalds
3221da177e4SLinus Torvalds #define EEPROM_CHECK_SUM 0
3231da177e4SLinus Torvalds #define FW_SIGNATURE 2
3241da177e4SLinus Torvalds #define MODEL_NUMB_0 4
3251da177e4SLinus Torvalds #define MODEL_NUMB_2 6
3261da177e4SLinus Torvalds #define MODEL_NUMB_4 8
3271da177e4SLinus Torvalds #define SYSTEM_CONFIG 16
3281da177e4SLinus Torvalds #define SCSI_CONFIG 17
3291da177e4SLinus Torvalds #define BIOS_CONFIG 18
3301da177e4SLinus Torvalds #define SCAM_CONFIG 20
3311da177e4SLinus Torvalds #define ADAPTER_SCSI_ID 24
3321da177e4SLinus Torvalds
3331da177e4SLinus Torvalds #define IGNORE_B_SCAN 32
3341da177e4SLinus Torvalds #define SEND_START_ENA 34
3351da177e4SLinus Torvalds #define DEVICE_ENABLE 36
3361da177e4SLinus Torvalds
3371da177e4SLinus Torvalds #define SYNC_RATE_TBL 38
3381da177e4SLinus Torvalds #define SYNC_RATE_TBL01 38
3391da177e4SLinus Torvalds #define SYNC_RATE_TBL23 40
3401da177e4SLinus Torvalds #define SYNC_RATE_TBL45 42
3411da177e4SLinus Torvalds #define SYNC_RATE_TBL67 44
3421da177e4SLinus Torvalds #define SYNC_RATE_TBL89 46
3431da177e4SLinus Torvalds #define SYNC_RATE_TBLab 48
3441da177e4SLinus Torvalds #define SYNC_RATE_TBLcd 50
3451da177e4SLinus Torvalds #define SYNC_RATE_TBLef 52
3461da177e4SLinus Torvalds
3471da177e4SLinus Torvalds #define EE_SCAMBASE 256
3481da177e4SLinus Torvalds
3491da177e4SLinus Torvalds #define SCAM_ENABLED BIT(2)
3501da177e4SLinus Torvalds #define SCAM_LEVEL2 BIT(3)
3511da177e4SLinus Torvalds
3521cafc30fSJiri Slaby #define RENEGO_ENA BIT(10)
3531cafc30fSJiri Slaby #define CONNIO_ENA BIT(11)
3541cafc30fSJiri Slaby #define GREEN_PC_ENA BIT(12)
3551da177e4SLinus Torvalds
3561da177e4SLinus Torvalds #define AUTO_RATE_00 00
3571da177e4SLinus Torvalds #define AUTO_RATE_05 01
3581da177e4SLinus Torvalds #define AUTO_RATE_10 02
3591da177e4SLinus Torvalds #define AUTO_RATE_20 03
3601da177e4SLinus Torvalds
3611da177e4SLinus Torvalds #define WIDE_NEGO_BIT BIT(7)
3621da177e4SLinus Torvalds #define DISC_ENABLE_BIT BIT(6)
3631da177e4SLinus Torvalds
3641da177e4SLinus Torvalds #define hp_vendor_id_0 0x00 /* LSB */
3651da177e4SLinus Torvalds #define ORION_VEND_0 0x4B
3661da177e4SLinus Torvalds
3671da177e4SLinus Torvalds #define hp_vendor_id_1 0x01 /* MSB */
3681da177e4SLinus Torvalds #define ORION_VEND_1 0x10
3691da177e4SLinus Torvalds
3701da177e4SLinus Torvalds #define hp_device_id_0 0x02 /* LSB */
3711da177e4SLinus Torvalds #define ORION_DEV_0 0x30
3721da177e4SLinus Torvalds
3731da177e4SLinus Torvalds #define hp_device_id_1 0x03 /* MSB */
3741da177e4SLinus Torvalds #define ORION_DEV_1 0x81
3751da177e4SLinus Torvalds
3761da177e4SLinus Torvalds /* Sub Vendor ID and Sub Device ID only available in
3771da177e4SLinus Torvalds Harpoon Version 2 and higher */
3781da177e4SLinus Torvalds
3791da177e4SLinus Torvalds #define hp_sub_device_id_0 0x06 /* LSB */
3801da177e4SLinus Torvalds
3811da177e4SLinus Torvalds #define hp_semaphore 0x0C
3821da177e4SLinus Torvalds #define SCCB_MGR_ACTIVE BIT(0)
3831da177e4SLinus Torvalds #define TICKLE_ME BIT(1)
3841da177e4SLinus Torvalds #define SCCB_MGR_PRESENT BIT(3)
3851da177e4SLinus Torvalds #define BIOS_IN_USE BIT(4)
3861da177e4SLinus Torvalds
3871da177e4SLinus Torvalds #define hp_sys_ctrl 0x0F
3881da177e4SLinus Torvalds
3891da177e4SLinus Torvalds #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
3901da177e4SLinus Torvalds #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
3911da177e4SLinus Torvalds #define HALT_MACH BIT(3) /*Halt State Machine */
3921da177e4SLinus Torvalds #define HARD_ABORT BIT(4) /*Hard Abort */
3931da177e4SLinus Torvalds
3941da177e4SLinus Torvalds #define hp_host_blk_cnt 0x13
3951da177e4SLinus Torvalds
3961da177e4SLinus Torvalds #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
3971da177e4SLinus Torvalds
3981da177e4SLinus Torvalds #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
3991da177e4SLinus Torvalds
4001da177e4SLinus Torvalds #define hp_int_mask 0x17
4011da177e4SLinus Torvalds
4021da177e4SLinus Torvalds #define INT_CMD_COMPL BIT(0) /* DMA command complete */
4031da177e4SLinus Torvalds #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
4041da177e4SLinus Torvalds
4051da177e4SLinus Torvalds #define hp_xfer_cnt_lo 0x18
4061da177e4SLinus Torvalds #define hp_xfer_cnt_hi 0x1A
4071da177e4SLinus Torvalds #define hp_xfer_cmd 0x1B
4081da177e4SLinus Torvalds
4091da177e4SLinus Torvalds #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
4101da177e4SLinus Torvalds #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
4111da177e4SLinus Torvalds
4121da177e4SLinus Torvalds #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
4131da177e4SLinus Torvalds
4141da177e4SLinus Torvalds #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
4151da177e4SLinus Torvalds
4161da177e4SLinus Torvalds #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
4171da177e4SLinus Torvalds
4181da177e4SLinus Torvalds #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
4191da177e4SLinus Torvalds #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
4201da177e4SLinus Torvalds
4211da177e4SLinus Torvalds #define hp_host_addr_lo 0x1C
4221da177e4SLinus Torvalds #define hp_host_addr_hmi 0x1E
4231da177e4SLinus Torvalds
4241da177e4SLinus Torvalds #define hp_ee_ctrl 0x22
4251da177e4SLinus Torvalds
4261da177e4SLinus Torvalds #define EXT_ARB_ACK BIT(7)
4271da177e4SLinus Torvalds #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
4281da177e4SLinus Torvalds #define SEE_MS BIT(5)
4291da177e4SLinus Torvalds #define SEE_CS BIT(3)
4301da177e4SLinus Torvalds #define SEE_CLK BIT(2)
4311da177e4SLinus Torvalds #define SEE_DO BIT(1)
4321da177e4SLinus Torvalds #define SEE_DI BIT(0)
4331da177e4SLinus Torvalds
4341da177e4SLinus Torvalds #define EE_READ 0x06
4351da177e4SLinus Torvalds #define EE_WRITE 0x05
4361da177e4SLinus Torvalds #define EWEN 0x04
4371da177e4SLinus Torvalds #define EWEN_ADDR 0x03C0
4381da177e4SLinus Torvalds #define EWDS 0x04
4391da177e4SLinus Torvalds #define EWDS_ADDR 0x0000
4401da177e4SLinus Torvalds
4411da177e4SLinus Torvalds #define hp_bm_ctrl 0x26
4421da177e4SLinus Torvalds
4431da177e4SLinus Torvalds #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
4441da177e4SLinus Torvalds #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
4451da177e4SLinus Torvalds #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
4461da177e4SLinus Torvalds #define FAST_SINGLE BIT(6) /*?? */
4471da177e4SLinus Torvalds
4481da177e4SLinus Torvalds #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
4491da177e4SLinus Torvalds
4501da177e4SLinus Torvalds #define hp_sg_addr 0x28
4511da177e4SLinus Torvalds #define hp_page_ctrl 0x29
4521da177e4SLinus Torvalds
4531da177e4SLinus Torvalds #define SCATTER_EN BIT(0)
4541da177e4SLinus Torvalds #define SGRAM_ARAM BIT(1)
4551da177e4SLinus Torvalds #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
4561da177e4SLinus Torvalds #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
4571da177e4SLinus Torvalds
4581da177e4SLinus Torvalds #define hp_pci_stat_cfg 0x2D
4591da177e4SLinus Torvalds
4601da177e4SLinus Torvalds #define REC_MASTER_ABORT BIT(5) /*received Master abort */
4611da177e4SLinus Torvalds
4621da177e4SLinus Torvalds #define hp_rev_num 0x33
4631da177e4SLinus Torvalds
4641da177e4SLinus Torvalds #define hp_stack_data 0x34
4651da177e4SLinus Torvalds #define hp_stack_addr 0x35
4661da177e4SLinus Torvalds
4671da177e4SLinus Torvalds #define hp_ext_status 0x36
4681da177e4SLinus Torvalds
4691da177e4SLinus Torvalds #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
4701da177e4SLinus Torvalds #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
4711da177e4SLinus Torvalds #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
4721da177e4SLinus Torvalds #define CMD_ABORTED BIT(4) /*Command aborted */
4731da177e4SLinus Torvalds #define BM_PARITY_ERR BIT(5) /*parity error on data received */
4741da177e4SLinus Torvalds #define PIO_OVERRUN BIT(6) /*Slave data overrun */
4751da177e4SLinus Torvalds #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
4761da177e4SLinus Torvalds #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
4771da177e4SLinus Torvalds BM_PARITY_ERR | PIO_OVERRUN)
4781da177e4SLinus Torvalds
4791da177e4SLinus Torvalds #define hp_int_status 0x37
4801da177e4SLinus Torvalds
4811da177e4SLinus Torvalds #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
4821da177e4SLinus Torvalds #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
4831da177e4SLinus Torvalds #define INT_ASSERTED BIT(5) /* */
4841da177e4SLinus Torvalds
4851da177e4SLinus Torvalds #define hp_fifo_cnt 0x38
4861da177e4SLinus Torvalds
4871da177e4SLinus Torvalds #define hp_intena 0x40
4881da177e4SLinus Torvalds
4891cafc30fSJiri Slaby #define RESET BIT(7)
4901cafc30fSJiri Slaby #define PROG_HLT BIT(6)
4911cafc30fSJiri Slaby #define PARITY BIT(5)
4921cafc30fSJiri Slaby #define FIFO BIT(4)
4931cafc30fSJiri Slaby #define SEL BIT(3)
4941cafc30fSJiri Slaby #define SCAM_SEL BIT(2)
4951cafc30fSJiri Slaby #define RSEL BIT(1)
4961cafc30fSJiri Slaby #define TIMEOUT BIT(0)
4971cafc30fSJiri Slaby #define BUS_FREE BIT(15)
4981cafc30fSJiri Slaby #define XFER_CNT_0 BIT(14)
4991cafc30fSJiri Slaby #define PHASE BIT(13)
5001cafc30fSJiri Slaby #define IUNKWN BIT(12)
5011cafc30fSJiri Slaby #define ICMD_COMP BIT(11)
5021cafc30fSJiri Slaby #define ITICKLE BIT(10)
5031cafc30fSJiri Slaby #define IDO_STRT BIT(9)
5041cafc30fSJiri Slaby #define ITAR_DISC BIT(8)
5051cafc30fSJiri Slaby #define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
5061da177e4SLinus Torvalds #define CLR_ALL_INT 0xFFFF
5071da177e4SLinus Torvalds #define CLR_ALL_INT_1 0xFF00
5081da177e4SLinus Torvalds
5091da177e4SLinus Torvalds #define hp_intstat 0x42
5101da177e4SLinus Torvalds
5111da177e4SLinus Torvalds #define hp_scsisig 0x44
5121da177e4SLinus Torvalds
5131da177e4SLinus Torvalds #define SCSI_SEL BIT(7)
5141da177e4SLinus Torvalds #define SCSI_BSY BIT(6)
5151da177e4SLinus Torvalds #define SCSI_REQ BIT(5)
5161da177e4SLinus Torvalds #define SCSI_ACK BIT(4)
5171da177e4SLinus Torvalds #define SCSI_ATN BIT(3)
5181da177e4SLinus Torvalds #define SCSI_CD BIT(2)
5191da177e4SLinus Torvalds #define SCSI_MSG BIT(1)
5201da177e4SLinus Torvalds #define SCSI_IOBIT BIT(0)
5211da177e4SLinus Torvalds
5221da177e4SLinus Torvalds #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
5231da177e4SLinus Torvalds #define S_MSGO_PH (BIT(2)+BIT(1) )
5241da177e4SLinus Torvalds #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
5251da177e4SLinus Torvalds #define S_DATAI_PH ( BIT(0))
5261da177e4SLinus Torvalds #define S_DATAO_PH 0x00
5271da177e4SLinus Torvalds #define S_ILL_PH ( BIT(1) )
5281da177e4SLinus Torvalds
5291da177e4SLinus Torvalds #define hp_scsictrl_0 0x45
5301da177e4SLinus Torvalds
5311da177e4SLinus Torvalds #define SEL_TAR BIT(6)
5321da177e4SLinus Torvalds #define ENA_ATN BIT(4)
5331da177e4SLinus Torvalds #define ENA_RESEL BIT(2)
5341da177e4SLinus Torvalds #define SCSI_RST BIT(1)
5351da177e4SLinus Torvalds #define ENA_SCAM_SEL BIT(0)
5361da177e4SLinus Torvalds
5371da177e4SLinus Torvalds #define hp_portctrl_0 0x46
5381da177e4SLinus Torvalds
5391da177e4SLinus Torvalds #define SCSI_PORT BIT(7)
5401da177e4SLinus Torvalds #define SCSI_INBIT BIT(6)
5411da177e4SLinus Torvalds #define DMA_PORT BIT(5)
5421da177e4SLinus Torvalds #define DMA_RD BIT(4)
5431da177e4SLinus Torvalds #define HOST_PORT BIT(3)
5441da177e4SLinus Torvalds #define HOST_WRT BIT(2)
5451da177e4SLinus Torvalds #define SCSI_BUS_EN BIT(1)
5461da177e4SLinus Torvalds #define START_TO BIT(0)
5471da177e4SLinus Torvalds
5481da177e4SLinus Torvalds #define hp_scsireset 0x47
5491da177e4SLinus Torvalds
5501da177e4SLinus Torvalds #define SCSI_INI BIT(6)
5511da177e4SLinus Torvalds #define SCAM_EN BIT(5)
5521da177e4SLinus Torvalds #define DMA_RESET BIT(3)
5531da177e4SLinus Torvalds #define HPSCSI_RESET BIT(2)
5541da177e4SLinus Torvalds #define PROG_RESET BIT(1)
5551da177e4SLinus Torvalds #define FIFO_CLR BIT(0)
5561da177e4SLinus Torvalds
5571da177e4SLinus Torvalds #define hp_xfercnt_0 0x48
5581da177e4SLinus Torvalds #define hp_xfercnt_2 0x4A
5591da177e4SLinus Torvalds
5601da177e4SLinus Torvalds #define hp_fifodata_0 0x4C
5611da177e4SLinus Torvalds #define hp_addstat 0x4E
5621da177e4SLinus Torvalds
5631da177e4SLinus Torvalds #define SCAM_TIMER BIT(7)
5641da177e4SLinus Torvalds #define SCSI_MODE8 BIT(3)
5651da177e4SLinus Torvalds #define SCSI_PAR_ERR BIT(0)
5661da177e4SLinus Torvalds
5671da177e4SLinus Torvalds #define hp_prgmcnt_0 0x4F
5681da177e4SLinus Torvalds
5691da177e4SLinus Torvalds #define hp_selfid_0 0x50
5701da177e4SLinus Torvalds #define hp_selfid_1 0x51
5711da177e4SLinus Torvalds #define hp_arb_id 0x52
5721da177e4SLinus Torvalds
5731da177e4SLinus Torvalds #define hp_select_id 0x53
5741da177e4SLinus Torvalds
5751da177e4SLinus Torvalds #define hp_synctarg_base 0x54
5761da177e4SLinus Torvalds #define hp_synctarg_12 0x54
5771da177e4SLinus Torvalds #define hp_synctarg_13 0x55
5781da177e4SLinus Torvalds #define hp_synctarg_14 0x56
5791da177e4SLinus Torvalds #define hp_synctarg_15 0x57
5801da177e4SLinus Torvalds
5811da177e4SLinus Torvalds #define hp_synctarg_8 0x58
5821da177e4SLinus Torvalds #define hp_synctarg_9 0x59
5831da177e4SLinus Torvalds #define hp_synctarg_10 0x5A
5841da177e4SLinus Torvalds #define hp_synctarg_11 0x5B
5851da177e4SLinus Torvalds
5861da177e4SLinus Torvalds #define hp_synctarg_4 0x5C
5871da177e4SLinus Torvalds #define hp_synctarg_5 0x5D
5881da177e4SLinus Torvalds #define hp_synctarg_6 0x5E
5891da177e4SLinus Torvalds #define hp_synctarg_7 0x5F
5901da177e4SLinus Torvalds
5911da177e4SLinus Torvalds #define hp_synctarg_0 0x60
5921da177e4SLinus Torvalds #define hp_synctarg_1 0x61
5931da177e4SLinus Torvalds #define hp_synctarg_2 0x62
5941da177e4SLinus Torvalds #define hp_synctarg_3 0x63
5951da177e4SLinus Torvalds
5961da177e4SLinus Torvalds #define NARROW_SCSI BIT(4)
5971da177e4SLinus Torvalds #define DEFAULT_OFFSET 0x0F
5981da177e4SLinus Torvalds
5991da177e4SLinus Torvalds #define hp_autostart_0 0x64
6001da177e4SLinus Torvalds #define hp_autostart_1 0x65
6011da177e4SLinus Torvalds #define hp_autostart_3 0x67
6021da177e4SLinus Torvalds
6031da177e4SLinus Torvalds #define AUTO_IMMED BIT(5)
6041da177e4SLinus Torvalds #define SELECT BIT(6)
6051da177e4SLinus Torvalds #define END_DATA (BIT(7)+BIT(6))
6061da177e4SLinus Torvalds
6071da177e4SLinus Torvalds #define hp_gp_reg_0 0x68
6081da177e4SLinus Torvalds #define hp_gp_reg_1 0x69
6091da177e4SLinus Torvalds #define hp_gp_reg_3 0x6B
6101da177e4SLinus Torvalds
6111da177e4SLinus Torvalds #define hp_seltimeout 0x6C
6121da177e4SLinus Torvalds
6131da177e4SLinus Torvalds #define TO_4ms 0x67 /* 3.9959ms */
6141da177e4SLinus Torvalds
6151da177e4SLinus Torvalds #define TO_5ms 0x03 /* 4.9152ms */
6161da177e4SLinus Torvalds #define TO_10ms 0x07 /* 11.xxxms */
6171da177e4SLinus Torvalds #define TO_250ms 0x99 /* 250.68ms */
6181da177e4SLinus Torvalds #define TO_290ms 0xB1 /* 289.99ms */
6191da177e4SLinus Torvalds
6201da177e4SLinus Torvalds #define hp_clkctrl_0 0x6D
6211da177e4SLinus Torvalds
6221da177e4SLinus Torvalds #define PWR_DWN BIT(6)
6231da177e4SLinus Torvalds #define ACTdeassert BIT(4)
6241da177e4SLinus Torvalds #define CLK_40MHZ (BIT(1) + BIT(0))
6251da177e4SLinus Torvalds
6261da177e4SLinus Torvalds #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
6271da177e4SLinus Torvalds
6281da177e4SLinus Torvalds #define hp_fiforead 0x6E
6291da177e4SLinus Torvalds #define hp_fifowrite 0x6F
6301da177e4SLinus Torvalds
6311da177e4SLinus Torvalds #define hp_offsetctr 0x70
6321da177e4SLinus Torvalds #define hp_xferstat 0x71
6331da177e4SLinus Torvalds
6341da177e4SLinus Torvalds #define FIFO_EMPTY BIT(6)
6351da177e4SLinus Torvalds
6361da177e4SLinus Torvalds #define hp_portctrl_1 0x72
6371da177e4SLinus Torvalds
6381da177e4SLinus Torvalds #define CHK_SCSI_P BIT(3)
6391da177e4SLinus Torvalds #define HOST_MODE8 BIT(0)
6401da177e4SLinus Torvalds
6411da177e4SLinus Torvalds #define hp_xfer_pad 0x73
6421da177e4SLinus Torvalds
6431da177e4SLinus Torvalds #define ID_UNLOCK BIT(3)
6441da177e4SLinus Torvalds
6451da177e4SLinus Torvalds #define hp_scsidata_0 0x74
6461da177e4SLinus Torvalds #define hp_scsidata_1 0x75
6471da177e4SLinus Torvalds
6481da177e4SLinus Torvalds #define hp_aramBase 0x80
6491da177e4SLinus Torvalds #define BIOS_DATA_OFFSET 0x60
6501da177e4SLinus Torvalds #define BIOS_RELATIVE_CARD 0x64
6511da177e4SLinus Torvalds
6521cafc30fSJiri Slaby #define AR3 (BIT(9) + BIT(8))
6531cafc30fSJiri Slaby #define SDATA BIT(10)
6541da177e4SLinus Torvalds
6551cafc30fSJiri Slaby #define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
6561da177e4SLinus Torvalds
6571cafc30fSJiri Slaby #define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
6581da177e4SLinus Torvalds
6591cafc30fSJiri Slaby #define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
6601da177e4SLinus Torvalds
6611cafc30fSJiri Slaby #define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
6621da177e4SLinus Torvalds
6631da177e4SLinus Torvalds #define ADATA_OUT 0x00
6641cafc30fSJiri Slaby #define ADATA_IN BIT(8)
6651cafc30fSJiri Slaby #define ACOMMAND BIT(10)
6661cafc30fSJiri Slaby #define ASTATUS (BIT(10)+BIT(8))
6671cafc30fSJiri Slaby #define AMSG_OUT (BIT(10)+BIT(9))
6681cafc30fSJiri Slaby #define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
6691da177e4SLinus Torvalds
6701cafc30fSJiri Slaby #define BRH_OP BIT(13) /* Branch */
6711da177e4SLinus Torvalds
6721da177e4SLinus Torvalds #define ALWAYS 0x00
6731cafc30fSJiri Slaby #define EQUAL BIT(8)
6741cafc30fSJiri Slaby #define NOT_EQ BIT(9)
6751da177e4SLinus Torvalds
6761cafc30fSJiri Slaby #define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
6771da177e4SLinus Torvalds
6781cafc30fSJiri Slaby #define FIFO_0 BIT(10)
6791da177e4SLinus Torvalds
6801cafc30fSJiri Slaby #define MPM_OP BIT(15) /* Match phase and move data */
6811da177e4SLinus Torvalds
6821cafc30fSJiri Slaby #define MRR_OP BIT(14) /* Move DReg. to Reg. */
6831da177e4SLinus Torvalds
6841da177e4SLinus Torvalds #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
6851da177e4SLinus Torvalds
6861da177e4SLinus Torvalds #define D_AR0 0x00
6871da177e4SLinus Torvalds #define D_AR1 BIT(0)
6881da177e4SLinus Torvalds #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
6891da177e4SLinus Torvalds
6901cafc30fSJiri Slaby #define RAT_OP (BIT(14)+BIT(13)+BIT(11))
6911da177e4SLinus Torvalds
6921cafc30fSJiri Slaby #define SSI_OP (BIT(15)+BIT(11))
6931da177e4SLinus Torvalds
6941da177e4SLinus Torvalds #define SSI_ITAR_DISC (ITAR_DISC >> 8)
6951da177e4SLinus Torvalds #define SSI_IDO_STRT (IDO_STRT >> 8)
6961da177e4SLinus Torvalds
6971da177e4SLinus Torvalds #define SSI_ICMD_COMP (ICMD_COMP >> 8)
6981da177e4SLinus Torvalds #define SSI_ITICKLE (ITICKLE >> 8)
6991da177e4SLinus Torvalds
7001da177e4SLinus Torvalds #define SSI_IUNKWN (IUNKWN >> 8)
7011da177e4SLinus Torvalds #define SSI_INO_CC (IUNKWN >> 8)
7021da177e4SLinus Torvalds #define SSI_IRFAIL (IUNKWN >> 8)
7031da177e4SLinus Torvalds
7041da177e4SLinus Torvalds #define NP 0x10 /*Next Phase */
7051da177e4SLinus Torvalds #define NTCMD 0x02 /*Non- Tagged Command start */
7061da177e4SLinus Torvalds #define CMDPZ 0x04 /*Command phase */
7071da177e4SLinus Torvalds #define DINT 0x12 /*Data Out/In interrupt */
7081da177e4SLinus Torvalds #define DI 0x13 /*Data Out */
7091da177e4SLinus Torvalds #define DC 0x19 /*Disconnect Message */
7101da177e4SLinus Torvalds #define ST 0x1D /*Status Phase */
7111da177e4SLinus Torvalds #define UNKNWN 0x24 /*Unknown bus action */
7121da177e4SLinus Torvalds #define CC 0x25 /*Command Completion failure */
7131da177e4SLinus Torvalds #define TICK 0x26 /*New target reselected us. */
7141da177e4SLinus Torvalds #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
7151da177e4SLinus Torvalds
7161da177e4SLinus Torvalds #define ID_MSG_STRT hp_aramBase + 0x00
7171da177e4SLinus Torvalds #define NON_TAG_ID_MSG hp_aramBase + 0x06
7181da177e4SLinus Torvalds #define CMD_STRT hp_aramBase + 0x08
7191da177e4SLinus Torvalds #define SYNC_MSGS hp_aramBase + 0x08
7201da177e4SLinus Torvalds
7211da177e4SLinus Torvalds #define TAG_STRT 0x00
7221da177e4SLinus Torvalds #define DISCONNECT_START 0x10/2
7231da177e4SLinus Torvalds #define END_DATA_START 0x14/2
7241da177e4SLinus Torvalds #define CMD_ONLY_STRT CMDPZ/2
7251da177e4SLinus Torvalds #define SELCHK_STRT SELCHK/2
7261da177e4SLinus Torvalds
7271da177e4SLinus Torvalds #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
7281da177e4SLinus Torvalds /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
7291da177e4SLinus Torvalds xfercnt <<= 16,\
730c823feebSAlexey Dobriyan xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
7311da177e4SLinus Torvalds */
732c823feebSAlexey Dobriyan #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
7331da177e4SLinus Torvalds addr >>= 16,\
734c823feebSAlexey Dobriyan WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
7351da177e4SLinus Torvalds WR_HARP32(port,hp_xfercnt_0,count),\
736c823feebSAlexey Dobriyan WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
7371da177e4SLinus Torvalds count >>= 16,\
7381da177e4SLinus Torvalds WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
7391da177e4SLinus Torvalds
7401da177e4SLinus Torvalds #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
7411da177e4SLinus Torvalds WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
7421da177e4SLinus Torvalds
7431da177e4SLinus Torvalds #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
7441da177e4SLinus Torvalds WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
7451da177e4SLinus Torvalds
7461da177e4SLinus Torvalds #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
7471da177e4SLinus Torvalds WR_HARPOON(port+hp_scsireset, 0x00))
7481da177e4SLinus Torvalds
7491da177e4SLinus Torvalds #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
7501da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
7511da177e4SLinus Torvalds
7521da177e4SLinus Torvalds #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
7531da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
7541da177e4SLinus Torvalds
7551da177e4SLinus Torvalds #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
7561da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
7571da177e4SLinus Torvalds
7581da177e4SLinus Torvalds #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
7591da177e4SLinus Torvalds (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
7601da177e4SLinus Torvalds
761391e2f25SKhalid Aziz static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
7625c04a7b8SAlexey Dobriyan unsigned char syncFlag);
763391e2f25SKhalid Aziz static void FPT_ssel(u32 port, unsigned char p_card);
764391e2f25SKhalid Aziz static void FPT_sres(u32 port, unsigned char p_card,
7655c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard);
766391e2f25SKhalid Aziz static void FPT_shandem(u32 port, unsigned char p_card,
7675c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB);
768391e2f25SKhalid Aziz static void FPT_stsyncn(u32 port, unsigned char p_card);
769391e2f25SKhalid Aziz static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
7705c04a7b8SAlexey Dobriyan unsigned char offset);
771391e2f25SKhalid Aziz static void FPT_sssyncv(u32 p_port, unsigned char p_id,
7725c04a7b8SAlexey Dobriyan unsigned char p_sync_value,
773f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info);
774391e2f25SKhalid Aziz static void FPT_sresb(u32 port, unsigned char p_card);
775391e2f25SKhalid Aziz static void FPT_sxfrp(u32 p_port, unsigned char p_card);
776391e2f25SKhalid Aziz static void FPT_schkdd(u32 port, unsigned char p_card);
777391e2f25SKhalid Aziz static unsigned char FPT_RdStack(u32 port, unsigned char index);
778391e2f25SKhalid Aziz static void FPT_WrStack(u32 portBase, unsigned char index,
7795c04a7b8SAlexey Dobriyan unsigned char data);
780391e2f25SKhalid Aziz static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
7811da177e4SLinus Torvalds
782391e2f25SKhalid Aziz static void FPT_SendMsg(u32 port, unsigned char message);
783db038cf8SAlexey Dobriyan static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
784db038cf8SAlexey Dobriyan unsigned char error_code);
7851da177e4SLinus Torvalds
78669eb2ea4SAlexey Dobriyan static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
78768d0c1aeSAlexey Dobriyan static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
7881da177e4SLinus Torvalds
789391e2f25SKhalid Aziz static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
790391e2f25SKhalid Aziz static void FPT_stwidn(u32 port, unsigned char p_card);
791391e2f25SKhalid Aziz static void FPT_siwidr(u32 port, unsigned char width);
7921da177e4SLinus Torvalds
7935c04a7b8SAlexey Dobriyan static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
794db038cf8SAlexey Dobriyan unsigned char p_card);
7955c04a7b8SAlexey Dobriyan static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
7965c04a7b8SAlexey Dobriyan static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
7975c04a7b8SAlexey Dobriyan struct sccb *p_SCCB, unsigned char p_card);
7985c04a7b8SAlexey Dobriyan static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
7995c04a7b8SAlexey Dobriyan unsigned char p_card);
800db038cf8SAlexey Dobriyan static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
80169eb2ea4SAlexey Dobriyan static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
8025c04a7b8SAlexey Dobriyan static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
8035c04a7b8SAlexey Dobriyan unsigned char p_card);
80469eb2ea4SAlexey Dobriyan static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
805c823feebSAlexey Dobriyan static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
806db038cf8SAlexey Dobriyan static unsigned char FPT_CalcLrc(unsigned char buffer[]);
8071da177e4SLinus Torvalds
808391e2f25SKhalid Aziz static void FPT_Wait1Second(u32 p_port);
809391e2f25SKhalid Aziz static void FPT_Wait(u32 p_port, unsigned char p_delay);
810391e2f25SKhalid Aziz static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
811391e2f25SKhalid Aziz static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
8125c04a7b8SAlexey Dobriyan unsigned short ee_addr);
813391e2f25SKhalid Aziz static unsigned short FPT_utilEERead(u32 p_port,
8145c04a7b8SAlexey Dobriyan unsigned short ee_addr);
815391e2f25SKhalid Aziz static unsigned short FPT_utilEEReadOrg(u32 p_port,
8165c04a7b8SAlexey Dobriyan unsigned short ee_addr);
817391e2f25SKhalid Aziz static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
8185c04a7b8SAlexey Dobriyan unsigned short ee_addr);
8191da177e4SLinus Torvalds
820391e2f25SKhalid Aziz static void FPT_phaseDataOut(u32 port, unsigned char p_card);
821391e2f25SKhalid Aziz static void FPT_phaseDataIn(u32 port, unsigned char p_card);
822391e2f25SKhalid Aziz static void FPT_phaseCommand(u32 port, unsigned char p_card);
823391e2f25SKhalid Aziz static void FPT_phaseStatus(u32 port, unsigned char p_card);
824391e2f25SKhalid Aziz static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
825391e2f25SKhalid Aziz static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
826391e2f25SKhalid Aziz static void FPT_phaseIllegal(u32 port, unsigned char p_card);
8271da177e4SLinus Torvalds
828391e2f25SKhalid Aziz static void FPT_phaseDecode(u32 port, unsigned char p_card);
829391e2f25SKhalid Aziz static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
830391e2f25SKhalid Aziz static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
8311da177e4SLinus Torvalds
832391e2f25SKhalid Aziz static void FPT_XbowInit(u32 port, unsigned char scamFlg);
833391e2f25SKhalid Aziz static void FPT_BusMasterInit(u32 p_port);
834391e2f25SKhalid Aziz static void FPT_DiagEEPROM(u32 p_port);
8351da177e4SLinus Torvalds
836391e2f25SKhalid Aziz static void FPT_dataXferProcessor(u32 port,
8375c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard);
838391e2f25SKhalid Aziz static void FPT_busMstrSGDataXferStart(u32 port,
8395c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB);
840391e2f25SKhalid Aziz static void FPT_busMstrDataXferStart(u32 port,
8415c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB);
842391e2f25SKhalid Aziz static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
8435c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB);
84469eb2ea4SAlexey Dobriyan static void FPT_hostDataXferRestart(struct sccb *currSCCB);
8451da177e4SLinus Torvalds
846391e2f25SKhalid Aziz static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
8475c04a7b8SAlexey Dobriyan unsigned char p_card,
8485c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard,
8495c04a7b8SAlexey Dobriyan unsigned short p_int);
8501da177e4SLinus Torvalds
85147b5d69cSJames Bottomley static void FPT_SccbMgrTableInitAll(void);
8525c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
8535c04a7b8SAlexey Dobriyan unsigned char p_card);
8545c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
8555c04a7b8SAlexey Dobriyan unsigned char target);
8561da177e4SLinus Torvalds
8575c04a7b8SAlexey Dobriyan static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
8585c04a7b8SAlexey Dobriyan unsigned char p_power_up);
8591da177e4SLinus Torvalds
860391e2f25SKhalid Aziz static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
861391e2f25SKhalid Aziz static void FPT_scbusf(u32 p_port);
862391e2f25SKhalid Aziz static void FPT_scsel(u32 p_port);
863391e2f25SKhalid Aziz static void FPT_scasid(unsigned char p_card, u32 p_port);
864391e2f25SKhalid Aziz static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
865391e2f25SKhalid Aziz static unsigned char FPT_scsendi(u32 p_port,
8665c04a7b8SAlexey Dobriyan unsigned char p_id_string[]);
867391e2f25SKhalid Aziz static unsigned char FPT_sciso(u32 p_port,
8685c04a7b8SAlexey Dobriyan unsigned char p_id_string[]);
869391e2f25SKhalid Aziz static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
870391e2f25SKhalid Aziz static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
871db038cf8SAlexey Dobriyan static unsigned char FPT_scvalq(unsigned char p_quintet);
872391e2f25SKhalid Aziz static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
873391e2f25SKhalid Aziz static void FPT_scwtsel(u32 p_port);
874391e2f25SKhalid Aziz static void FPT_inisci(unsigned char p_card, u32 p_port,
8755c04a7b8SAlexey Dobriyan unsigned char p_our_id);
876391e2f25SKhalid Aziz static void FPT_scsavdi(unsigned char p_card, u32 p_port);
8775c04a7b8SAlexey Dobriyan static unsigned char FPT_scmachid(unsigned char p_card,
8785c04a7b8SAlexey Dobriyan unsigned char p_id_string[]);
8791da177e4SLinus Torvalds
880391e2f25SKhalid Aziz static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
881391e2f25SKhalid Aziz static void FPT_autoLoadDefaultMap(u32 p_port);
8821da177e4SLinus Torvalds
8835c04a7b8SAlexey Dobriyan static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
8845c04a7b8SAlexey Dobriyan { {{0}} };
88513e6851aSAlexey Dobriyan static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
88647b5d69cSJames Bottomley static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
88768d0c1aeSAlexey Dobriyan static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
8881da177e4SLinus Torvalds
889db038cf8SAlexey Dobriyan static unsigned char FPT_mbCards = 0;
8905c04a7b8SAlexey Dobriyan static unsigned char FPT_scamHAString[] =
8915c04a7b8SAlexey Dobriyan { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
8925c04a7b8SAlexey Dobriyan ' ', 'B', 'T', '-', '9', '3', '0',
8935c04a7b8SAlexey Dobriyan 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
8945c04a7b8SAlexey Dobriyan 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
8955c04a7b8SAlexey Dobriyan };
8961da177e4SLinus Torvalds
897c823feebSAlexey Dobriyan static unsigned short FPT_default_intena = 0;
8981da177e4SLinus Torvalds
899391e2f25SKhalid Aziz static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
9005c04a7b8SAlexey Dobriyan 0};
9011da177e4SLinus Torvalds
9021da177e4SLinus Torvalds /*---------------------------------------------------------------------
9031da177e4SLinus Torvalds *
904d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_ProbeHostAdapter
9051da177e4SLinus Torvalds *
9061da177e4SLinus Torvalds * Description: Setup and/or Search for cards and return info to caller.
9071da177e4SLinus Torvalds *
9081da177e4SLinus Torvalds *---------------------------------------------------------------------*/
9091da177e4SLinus Torvalds
FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)9107f101662SAlexey Dobriyan static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
9111da177e4SLinus Torvalds {
912db038cf8SAlexey Dobriyan static unsigned char first_time = 1;
9131da177e4SLinus Torvalds
914db038cf8SAlexey Dobriyan unsigned char i, j, id, ScamFlg;
915c823feebSAlexey Dobriyan unsigned short temp, temp2, temp3, temp4, temp5, temp6;
916391e2f25SKhalid Aziz u32 ioport;
91768d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
9181da177e4SLinus Torvalds
9191da177e4SLinus Torvalds ioport = pCardInfo->si_baseaddr;
9201da177e4SLinus Torvalds
9211da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
9225c1b85e2SAlexey Dobriyan return (int)FAILURE;
9231da177e4SLinus Torvalds
9241da177e4SLinus Torvalds if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
9255c1b85e2SAlexey Dobriyan return (int)FAILURE;
9261da177e4SLinus Torvalds
9271da177e4SLinus Torvalds if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
9285c1b85e2SAlexey Dobriyan return (int)FAILURE;
9291da177e4SLinus Torvalds
9301da177e4SLinus Torvalds if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
9315c1b85e2SAlexey Dobriyan return (int)FAILURE;
9321da177e4SLinus Torvalds
9331da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
9341da177e4SLinus Torvalds
9351da177e4SLinus Torvalds /* For new Harpoon then check for sub_device ID LSB
9361da177e4SLinus Torvalds the bits(0-3) must be all ZERO for compatible with
9371da177e4SLinus Torvalds current version of SCCBMgr, else skip this Harpoon
9381da177e4SLinus Torvalds device. */
9391da177e4SLinus Torvalds
9401da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
9415c1b85e2SAlexey Dobriyan return (int)FAILURE;
9421da177e4SLinus Torvalds }
9431da177e4SLinus Torvalds
9445c04a7b8SAlexey Dobriyan if (first_time) {
94547b5d69cSJames Bottomley FPT_SccbMgrTableInitAll();
9461da177e4SLinus Torvalds first_time = 0;
94747b5d69cSJames Bottomley FPT_mbCards = 0;
9481da177e4SLinus Torvalds }
9491da177e4SLinus Torvalds
95047b5d69cSJames Bottomley if (FPT_RdStack(ioport, 0) != 0x00) {
9515c04a7b8SAlexey Dobriyan if (FPT_ChkIfChipInitialized(ioport) == 0) {
9521da177e4SLinus Torvalds pCurrNvRam = NULL;
9531da177e4SLinus Torvalds WR_HARPOON(ioport + hp_semaphore, 0x00);
95447b5d69cSJames Bottomley FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
95547b5d69cSJames Bottomley FPT_DiagEEPROM(ioport);
9565c04a7b8SAlexey Dobriyan } else {
95747b5d69cSJames Bottomley if (FPT_mbCards < MAX_MB_CARDS) {
95847b5d69cSJames Bottomley pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
95947b5d69cSJames Bottomley FPT_mbCards++;
9601da177e4SLinus Torvalds pCurrNvRam->niBaseAddr = ioport;
96147b5d69cSJames Bottomley FPT_RNVRamData(pCurrNvRam);
9621da177e4SLinus Torvalds } else
9635c1b85e2SAlexey Dobriyan return (int)FAILURE;
9641da177e4SLinus Torvalds }
9651da177e4SLinus Torvalds } else
9661da177e4SLinus Torvalds pCurrNvRam = NULL;
9671da177e4SLinus Torvalds
9681da177e4SLinus Torvalds WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
9691da177e4SLinus Torvalds WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
9701da177e4SLinus Torvalds
9711da177e4SLinus Torvalds if (pCurrNvRam)
9721da177e4SLinus Torvalds pCardInfo->si_id = pCurrNvRam->niAdapId;
9731da177e4SLinus Torvalds else
9745c04a7b8SAlexey Dobriyan pCardInfo->si_id =
9755c04a7b8SAlexey Dobriyan (unsigned
9765c04a7b8SAlexey Dobriyan char)(FPT_utilEERead(ioport,
9775c04a7b8SAlexey Dobriyan (ADAPTER_SCSI_ID /
9785c04a7b8SAlexey Dobriyan 2)) & (unsigned char)0x0FF);
9791da177e4SLinus Torvalds
9801da177e4SLinus Torvalds pCardInfo->si_lun = 0x00;
9811da177e4SLinus Torvalds pCardInfo->si_fw_revision = ORION_FW_REV;
9821da177e4SLinus Torvalds temp2 = 0x0000;
9831da177e4SLinus Torvalds temp3 = 0x0000;
9841da177e4SLinus Torvalds temp4 = 0x0000;
9851da177e4SLinus Torvalds temp5 = 0x0000;
9861da177e4SLinus Torvalds temp6 = 0x0000;
9871da177e4SLinus Torvalds
9881da177e4SLinus Torvalds for (id = 0; id < (16 / 2); id++) {
9891da177e4SLinus Torvalds
9901da177e4SLinus Torvalds if (pCurrNvRam) {
991c823feebSAlexey Dobriyan temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
9921da177e4SLinus Torvalds temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
9931da177e4SLinus Torvalds (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
9941da177e4SLinus Torvalds } else
9955c04a7b8SAlexey Dobriyan temp =
9965c04a7b8SAlexey Dobriyan FPT_utilEERead(ioport,
9975c04a7b8SAlexey Dobriyan (unsigned short)((SYNC_RATE_TBL / 2)
9985c04a7b8SAlexey Dobriyan + id));
9991da177e4SLinus Torvalds
10001da177e4SLinus Torvalds for (i = 0; i < 2; temp >>= 8, i++) {
10011da177e4SLinus Torvalds
10021da177e4SLinus Torvalds temp2 >>= 1;
10031da177e4SLinus Torvalds temp3 >>= 1;
10041da177e4SLinus Torvalds temp4 >>= 1;
10051da177e4SLinus Torvalds temp5 >>= 1;
10061da177e4SLinus Torvalds temp6 >>= 1;
10075c04a7b8SAlexey Dobriyan switch (temp & 0x3) {
10081da177e4SLinus Torvalds case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1009df561f66SGustavo A. R. Silva temp6 |= 0x8000;
1010df561f66SGustavo A. R. Silva fallthrough;
10111da177e4SLinus Torvalds case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1012df561f66SGustavo A. R. Silva temp5 |= 0x8000;
1013df561f66SGustavo A. R. Silva fallthrough;
10141da177e4SLinus Torvalds case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1015df561f66SGustavo A. R. Silva temp2 |= 0x8000;
1016df561f66SGustavo A. R. Silva fallthrough;
10171da177e4SLinus Torvalds case AUTO_RATE_00: /* Asynchronous */
10181da177e4SLinus Torvalds break;
10191da177e4SLinus Torvalds }
10201da177e4SLinus Torvalds
10211da177e4SLinus Torvalds if (temp & DISC_ENABLE_BIT)
10221da177e4SLinus Torvalds temp3 |= 0x8000;
10231da177e4SLinus Torvalds
10241da177e4SLinus Torvalds if (temp & WIDE_NEGO_BIT)
10251da177e4SLinus Torvalds temp4 |= 0x8000;
10261da177e4SLinus Torvalds
10271da177e4SLinus Torvalds }
10281da177e4SLinus Torvalds }
10291da177e4SLinus Torvalds
10301da177e4SLinus Torvalds pCardInfo->si_per_targ_init_sync = temp2;
10311da177e4SLinus Torvalds pCardInfo->si_per_targ_no_disc = temp3;
10321da177e4SLinus Torvalds pCardInfo->si_per_targ_wide_nego = temp4;
10331da177e4SLinus Torvalds pCardInfo->si_per_targ_fast_nego = temp5;
10341da177e4SLinus Torvalds pCardInfo->si_per_targ_ultra_nego = temp6;
10351da177e4SLinus Torvalds
10361da177e4SLinus Torvalds if (pCurrNvRam)
10371da177e4SLinus Torvalds i = pCurrNvRam->niSysConf;
10381da177e4SLinus Torvalds else
10395c04a7b8SAlexey Dobriyan i = (unsigned
10405c04a7b8SAlexey Dobriyan char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
10411da177e4SLinus Torvalds
10421da177e4SLinus Torvalds if (pCurrNvRam)
10431da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf;
10441da177e4SLinus Torvalds else
10455c04a7b8SAlexey Dobriyan ScamFlg =
10465c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
10471da177e4SLinus Torvalds
10484d431153SRandy Dunlap pCardInfo->si_mflags = 0x0000;
10491da177e4SLinus Torvalds
10501da177e4SLinus Torvalds if (i & 0x01)
10514d431153SRandy Dunlap pCardInfo->si_mflags |= SCSI_PARITY_ENA;
10521da177e4SLinus Torvalds
10531da177e4SLinus Torvalds if (!(i & 0x02))
10544d431153SRandy Dunlap pCardInfo->si_mflags |= SOFT_RESET;
10551da177e4SLinus Torvalds
10561da177e4SLinus Torvalds if (i & 0x10)
10574d431153SRandy Dunlap pCardInfo->si_mflags |= EXTENDED_TRANSLATION;
10581da177e4SLinus Torvalds
10591da177e4SLinus Torvalds if (ScamFlg & SCAM_ENABLED)
10604d431153SRandy Dunlap pCardInfo->si_mflags |= FLAG_SCAM_ENABLED;
10611da177e4SLinus Torvalds
10621da177e4SLinus Torvalds if (ScamFlg & SCAM_LEVEL2)
10634d431153SRandy Dunlap pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2;
10641da177e4SLinus Torvalds
10651da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
10661da177e4SLinus Torvalds if (i & 0x04) {
10671da177e4SLinus Torvalds j |= SCSI_TERM_ENA_L;
10681da177e4SLinus Torvalds }
10691da177e4SLinus Torvalds WR_HARPOON(ioport + hp_bm_ctrl, j);
10701da177e4SLinus Torvalds
10711da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
10721da177e4SLinus Torvalds if (i & 0x08) {
10731da177e4SLinus Torvalds j |= SCSI_TERM_ENA_H;
10741da177e4SLinus Torvalds }
10751da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, j);
10761da177e4SLinus Torvalds
10771da177e4SLinus Torvalds if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
10781da177e4SLinus Torvalds
10794d431153SRandy Dunlap pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN;
10801da177e4SLinus Torvalds
10811da177e4SLinus Torvalds pCardInfo->si_card_family = HARPOON_FAMILY;
10821da177e4SLinus Torvalds pCardInfo->si_bustype = BUSTYPE_PCI;
10831da177e4SLinus Torvalds
10841da177e4SLinus Torvalds if (pCurrNvRam) {
10851da177e4SLinus Torvalds pCardInfo->si_card_model[0] = '9';
10861da177e4SLinus Torvalds switch (pCurrNvRam->niModel & 0x0f) {
10871da177e4SLinus Torvalds case MODEL_LT:
10881da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '3';
10891da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '0';
10901da177e4SLinus Torvalds break;
10911da177e4SLinus Torvalds case MODEL_LW:
10921da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '5';
10931da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '0';
10941da177e4SLinus Torvalds break;
10951da177e4SLinus Torvalds case MODEL_DL:
10961da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '3';
10971da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '2';
10981da177e4SLinus Torvalds break;
10991da177e4SLinus Torvalds case MODEL_DW:
11001da177e4SLinus Torvalds pCardInfo->si_card_model[1] = '5';
11011da177e4SLinus Torvalds pCardInfo->si_card_model[2] = '2';
11021da177e4SLinus Torvalds break;
11031da177e4SLinus Torvalds }
11041da177e4SLinus Torvalds } else {
110547b5d69cSJames Bottomley temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1106db038cf8SAlexey Dobriyan pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
110747b5d69cSJames Bottomley temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
11081da177e4SLinus Torvalds
1109db038cf8SAlexey Dobriyan pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1110db038cf8SAlexey Dobriyan pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
11111da177e4SLinus Torvalds }
11121da177e4SLinus Torvalds
11135c04a7b8SAlexey Dobriyan if (pCardInfo->si_card_model[1] == '3') {
11141da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
11154d431153SRandy Dunlap pCardInfo->si_mflags |= LOW_BYTE_TERM;
11165c04a7b8SAlexey Dobriyan } else if (pCardInfo->si_card_model[2] == '0') {
11171da177e4SLinus Torvalds temp = RD_HARPOON(ioport + hp_xfer_pad);
11181da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
11191da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
11204d431153SRandy Dunlap pCardInfo->si_mflags |= LOW_BYTE_TERM;
11211da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
11221da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
11234d431153SRandy Dunlap pCardInfo->si_mflags |= HIGH_BYTE_TERM;
11241da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, temp);
11255c04a7b8SAlexey Dobriyan } else {
11261da177e4SLinus Torvalds temp = RD_HARPOON(ioport + hp_ee_ctrl);
11271da177e4SLinus Torvalds temp2 = RD_HARPOON(ioport + hp_xfer_pad);
11281da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
11291da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
11301da177e4SLinus Torvalds temp3 = 0;
11315c04a7b8SAlexey Dobriyan for (i = 0; i < 8; i++) {
11321da177e4SLinus Torvalds temp3 <<= 1;
11331da177e4SLinus Torvalds if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
11341da177e4SLinus Torvalds temp3 |= 1;
11351da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
11361da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
11371da177e4SLinus Torvalds }
11381da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, temp);
11391da177e4SLinus Torvalds WR_HARPOON(ioport + hp_xfer_pad, temp2);
11401da177e4SLinus Torvalds if (!(temp3 & BIT(7)))
11414d431153SRandy Dunlap pCardInfo->si_mflags |= LOW_BYTE_TERM;
11421da177e4SLinus Torvalds if (!(temp3 & BIT(6)))
11434d431153SRandy Dunlap pCardInfo->si_mflags |= HIGH_BYTE_TERM;
11441da177e4SLinus Torvalds }
11451da177e4SLinus Torvalds
11461da177e4SLinus Torvalds ARAM_ACCESS(ioport);
11471da177e4SLinus Torvalds
11481da177e4SLinus Torvalds for (i = 0; i < 4; i++) {
11491da177e4SLinus Torvalds
11501da177e4SLinus Torvalds pCardInfo->si_XlatInfo[i] =
11511da177e4SLinus Torvalds RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
11521da177e4SLinus Torvalds }
11531da177e4SLinus Torvalds
11541da177e4SLinus Torvalds /* return with -1 if no sort, else return with
11551da177e4SLinus Torvalds logical card number sorted by BIOS (zero-based) */
11561da177e4SLinus Torvalds
11571da177e4SLinus Torvalds pCardInfo->si_relative_cardnum =
11585c04a7b8SAlexey Dobriyan (unsigned
11595c04a7b8SAlexey Dobriyan char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
11601da177e4SLinus Torvalds
11611da177e4SLinus Torvalds SGRAM_ACCESS(ioport);
11621da177e4SLinus Torvalds
116347b5d69cSJames Bottomley FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
116447b5d69cSJames Bottomley FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
116547b5d69cSJames Bottomley FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
116647b5d69cSJames Bottomley FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
116747b5d69cSJames Bottomley FPT_s_PhaseTbl[4] = FPT_phaseCommand;
116847b5d69cSJames Bottomley FPT_s_PhaseTbl[5] = FPT_phaseStatus;
116947b5d69cSJames Bottomley FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
117047b5d69cSJames Bottomley FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
11711da177e4SLinus Torvalds
11721da177e4SLinus Torvalds pCardInfo->si_present = 0x01;
11731da177e4SLinus Torvalds
11745c1b85e2SAlexey Dobriyan return 0;
11751da177e4SLinus Torvalds }
11761da177e4SLinus Torvalds
11771da177e4SLinus Torvalds /*---------------------------------------------------------------------
11781da177e4SLinus Torvalds *
1179d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_HardwareResetHostAdapter
11801da177e4SLinus Torvalds *
11811da177e4SLinus Torvalds * Description: Setup adapter for normal operation (hard reset).
11821da177e4SLinus Torvalds *
11831da177e4SLinus Torvalds *---------------------------------------------------------------------*/
11841da177e4SLinus Torvalds
FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)1185391e2f25SKhalid Aziz static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
11865c04a7b8SAlexey Dobriyan *pCardInfo)
11871da177e4SLinus Torvalds {
118813e6851aSAlexey Dobriyan struct sccb_card *CurrCard = NULL;
118968d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
1190db038cf8SAlexey Dobriyan unsigned char i, j, thisCard, ScamFlg;
1191c823feebSAlexey Dobriyan unsigned short temp, sync_bit_map, id;
1192391e2f25SKhalid Aziz u32 ioport;
11931da177e4SLinus Torvalds
11941da177e4SLinus Torvalds ioport = pCardInfo->si_baseaddr;
11951da177e4SLinus Torvalds
11961da177e4SLinus Torvalds for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
11971da177e4SLinus Torvalds
1198391e2f25SKhalid Aziz if (thisCard == MAX_CARDS)
1199391e2f25SKhalid Aziz return (void *)FAILURE;
12001da177e4SLinus Torvalds
120147b5d69cSJames Bottomley if (FPT_BL_Card[thisCard].ioPort == ioport) {
12021da177e4SLinus Torvalds
120347b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[thisCard];
120447b5d69cSJames Bottomley FPT_SccbMgrTableInitCard(CurrCard, thisCard);
12051da177e4SLinus Torvalds break;
12061da177e4SLinus Torvalds }
12071da177e4SLinus Torvalds
120847b5d69cSJames Bottomley else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
12091da177e4SLinus Torvalds
121047b5d69cSJames Bottomley FPT_BL_Card[thisCard].ioPort = ioport;
121147b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[thisCard];
12121da177e4SLinus Torvalds
121347b5d69cSJames Bottomley if (FPT_mbCards)
121447b5d69cSJames Bottomley for (i = 0; i < FPT_mbCards; i++) {
12155c04a7b8SAlexey Dobriyan if (CurrCard->ioPort ==
12165c04a7b8SAlexey Dobriyan FPT_nvRamInfo[i].niBaseAddr)
12175c04a7b8SAlexey Dobriyan CurrCard->pNvRamInfo =
12185c04a7b8SAlexey Dobriyan &FPT_nvRamInfo[i];
12191da177e4SLinus Torvalds }
122047b5d69cSJames Bottomley FPT_SccbMgrTableInitCard(CurrCard, thisCard);
12211da177e4SLinus Torvalds CurrCard->cardIndex = thisCard;
12221da177e4SLinus Torvalds CurrCard->cardInfo = pCardInfo;
12231da177e4SLinus Torvalds
12241da177e4SLinus Torvalds break;
12251da177e4SLinus Torvalds }
12261da177e4SLinus Torvalds }
12271da177e4SLinus Torvalds
12281da177e4SLinus Torvalds pCurrNvRam = CurrCard->pNvRamInfo;
12291da177e4SLinus Torvalds
12301da177e4SLinus Torvalds if (pCurrNvRam) {
12311da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf;
12325c04a7b8SAlexey Dobriyan } else {
12335c04a7b8SAlexey Dobriyan ScamFlg =
12345c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
12351da177e4SLinus Torvalds }
12361da177e4SLinus Torvalds
123747b5d69cSJames Bottomley FPT_BusMasterInit(ioport);
123847b5d69cSJames Bottomley FPT_XbowInit(ioport, ScamFlg);
12391da177e4SLinus Torvalds
124047b5d69cSJames Bottomley FPT_autoLoadDefaultMap(ioport);
12411da177e4SLinus Torvalds
12425c04a7b8SAlexey Dobriyan for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
12435c04a7b8SAlexey Dobriyan }
12441da177e4SLinus Torvalds
12451da177e4SLinus Torvalds WR_HARPOON(ioport + hp_selfid_0, id);
12461da177e4SLinus Torvalds WR_HARPOON(ioport + hp_selfid_1, 0x00);
12471da177e4SLinus Torvalds WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
12481da177e4SLinus Torvalds CurrCard->ourId = pCardInfo->si_id;
12491da177e4SLinus Torvalds
12504d431153SRandy Dunlap i = (unsigned char)pCardInfo->si_mflags;
12511da177e4SLinus Torvalds if (i & SCSI_PARITY_ENA)
12521da177e4SLinus Torvalds WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
12531da177e4SLinus Torvalds
12541da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
12551da177e4SLinus Torvalds if (i & LOW_BYTE_TERM)
12561da177e4SLinus Torvalds j |= SCSI_TERM_ENA_L;
12571da177e4SLinus Torvalds WR_HARPOON(ioport + hp_bm_ctrl, j);
12581da177e4SLinus Torvalds
12591da177e4SLinus Torvalds j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
12601da177e4SLinus Torvalds if (i & HIGH_BYTE_TERM)
12611da177e4SLinus Torvalds j |= SCSI_TERM_ENA_H;
12621da177e4SLinus Torvalds WR_HARPOON(ioport + hp_ee_ctrl, j);
12631da177e4SLinus Torvalds
12644d431153SRandy Dunlap if (!(pCardInfo->si_mflags & SOFT_RESET)) {
12651da177e4SLinus Torvalds
126647b5d69cSJames Bottomley FPT_sresb(ioport, thisCard);
12671da177e4SLinus Torvalds
126847b5d69cSJames Bottomley FPT_scini(thisCard, pCardInfo->si_id, 0);
12691da177e4SLinus Torvalds }
12701da177e4SLinus Torvalds
12714d431153SRandy Dunlap if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS)
12721da177e4SLinus Torvalds CurrCard->globalFlags |= F_NO_FILTER;
12731da177e4SLinus Torvalds
12741da177e4SLinus Torvalds if (pCurrNvRam) {
12751da177e4SLinus Torvalds if (pCurrNvRam->niSysConf & 0x10)
12761da177e4SLinus Torvalds CurrCard->globalFlags |= F_GREEN_PC;
12775c04a7b8SAlexey Dobriyan } else {
127847b5d69cSJames Bottomley if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
12791da177e4SLinus Torvalds CurrCard->globalFlags |= F_GREEN_PC;
12801da177e4SLinus Torvalds }
12811da177e4SLinus Torvalds
12821da177e4SLinus Torvalds /* Set global flag to indicate Re-Negotiation to be done on all
12831da177e4SLinus Torvalds ckeck condition */
12841da177e4SLinus Torvalds if (pCurrNvRam) {
12851da177e4SLinus Torvalds if (pCurrNvRam->niScsiConf & 0x04)
12861da177e4SLinus Torvalds CurrCard->globalFlags |= F_DO_RENEGO;
12875c04a7b8SAlexey Dobriyan } else {
128847b5d69cSJames Bottomley if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
12891da177e4SLinus Torvalds CurrCard->globalFlags |= F_DO_RENEGO;
12901da177e4SLinus Torvalds }
12911da177e4SLinus Torvalds
12921da177e4SLinus Torvalds if (pCurrNvRam) {
12931da177e4SLinus Torvalds if (pCurrNvRam->niScsiConf & 0x08)
12941da177e4SLinus Torvalds CurrCard->globalFlags |= F_CONLUN_IO;
12955c04a7b8SAlexey Dobriyan } else {
129647b5d69cSJames Bottomley if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
12971da177e4SLinus Torvalds CurrCard->globalFlags |= F_CONLUN_IO;
12981da177e4SLinus Torvalds }
12991da177e4SLinus Torvalds
13001da177e4SLinus Torvalds temp = pCardInfo->si_per_targ_no_disc;
13011da177e4SLinus Torvalds
13021da177e4SLinus Torvalds for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
13031da177e4SLinus Torvalds
13041da177e4SLinus Torvalds if (temp & id)
130547b5d69cSJames Bottomley FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
13061da177e4SLinus Torvalds }
13071da177e4SLinus Torvalds
13081da177e4SLinus Torvalds sync_bit_map = 0x0001;
13091da177e4SLinus Torvalds
13101da177e4SLinus Torvalds for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
13111da177e4SLinus Torvalds
13121da177e4SLinus Torvalds if (pCurrNvRam) {
1313c823feebSAlexey Dobriyan temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
13141da177e4SLinus Torvalds temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
13151da177e4SLinus Torvalds (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
13161da177e4SLinus Torvalds } else
13175c04a7b8SAlexey Dobriyan temp =
13185c04a7b8SAlexey Dobriyan FPT_utilEERead(ioport,
13195c04a7b8SAlexey Dobriyan (unsigned short)((SYNC_RATE_TBL / 2)
13205c04a7b8SAlexey Dobriyan + id));
13211da177e4SLinus Torvalds
13221da177e4SLinus Torvalds for (i = 0; i < 2; temp >>= 8, i++) {
13231da177e4SLinus Torvalds
13241da177e4SLinus Torvalds if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
13251da177e4SLinus Torvalds
13265c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 +
13275c04a7b8SAlexey Dobriyan i].TarEEValue =
13285c04a7b8SAlexey Dobriyan (unsigned char)temp;
13291da177e4SLinus Torvalds }
13301da177e4SLinus Torvalds
13311da177e4SLinus Torvalds else {
13325c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 +
13335c04a7b8SAlexey Dobriyan i].TarStatus |=
13345c04a7b8SAlexey Dobriyan SYNC_SUPPORTED;
13355c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 +
13365c04a7b8SAlexey Dobriyan i].TarEEValue =
1337db038cf8SAlexey Dobriyan (unsigned char)(temp & ~EE_SYNC_MASK);
13381da177e4SLinus Torvalds }
13391da177e4SLinus Torvalds
13401da177e4SLinus Torvalds /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
13411da177e4SLinus Torvalds (id*2+i >= 8)){
13421da177e4SLinus Torvalds */
13431da177e4SLinus Torvalds if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
13441da177e4SLinus Torvalds
13455c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 +
13465c04a7b8SAlexey Dobriyan i].TarEEValue |=
13475c04a7b8SAlexey Dobriyan EE_WIDE_SCSI;
13481da177e4SLinus Torvalds
13491da177e4SLinus Torvalds }
13501da177e4SLinus Torvalds
13511da177e4SLinus Torvalds else { /* NARROW SCSI */
13525c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[thisCard][id * 2 +
13535c04a7b8SAlexey Dobriyan i].TarStatus |=
13545c04a7b8SAlexey Dobriyan WIDE_NEGOCIATED;
13551da177e4SLinus Torvalds }
13561da177e4SLinus Torvalds
13571da177e4SLinus Torvalds sync_bit_map <<= 1;
13581da177e4SLinus Torvalds
13591da177e4SLinus Torvalds }
13601da177e4SLinus Torvalds }
13611da177e4SLinus Torvalds
13621da177e4SLinus Torvalds WR_HARPOON((ioport + hp_semaphore),
13635c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
13645c04a7b8SAlexey Dobriyan SCCB_MGR_PRESENT));
13651da177e4SLinus Torvalds
1366391e2f25SKhalid Aziz return (void *)CurrCard;
13671da177e4SLinus Torvalds }
13681da177e4SLinus Torvalds
FlashPoint_ReleaseHostAdapter(void * pCurrCard)1369391e2f25SKhalid Aziz static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
13701da177e4SLinus Torvalds {
1371db038cf8SAlexey Dobriyan unsigned char i;
1372391e2f25SKhalid Aziz u32 portBase;
1373391e2f25SKhalid Aziz u32 regOffset;
1374391e2f25SKhalid Aziz u32 scamData;
1375391e2f25SKhalid Aziz u32 *pScamTbl;
137668d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
13771da177e4SLinus Torvalds
137813e6851aSAlexey Dobriyan pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
13791da177e4SLinus Torvalds
13801da177e4SLinus Torvalds if (pCurrNvRam) {
138147b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
138247b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
138347b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
138447b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
138547b5d69cSJames Bottomley FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
13861da177e4SLinus Torvalds
13871da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR / 2; i++)
13885c04a7b8SAlexey Dobriyan FPT_WrStack(pCurrNvRam->niBaseAddr,
13895c04a7b8SAlexey Dobriyan (unsigned char)(i + 5),
13905c04a7b8SAlexey Dobriyan pCurrNvRam->niSyncTbl[i]);
13911da177e4SLinus Torvalds
13921da177e4SLinus Torvalds portBase = pCurrNvRam->niBaseAddr;
13931da177e4SLinus Torvalds
13941da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR; i++) {
13951da177e4SLinus Torvalds regOffset = hp_aramBase + 64 + i * 4;
1396391e2f25SKhalid Aziz pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
13971da177e4SLinus Torvalds scamData = *pScamTbl;
13981da177e4SLinus Torvalds WR_HARP32(portBase, regOffset, scamData);
13991da177e4SLinus Torvalds }
14001da177e4SLinus Torvalds
14011da177e4SLinus Torvalds } else {
140213e6851aSAlexey Dobriyan FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
14031da177e4SLinus Torvalds }
14041da177e4SLinus Torvalds }
14051da177e4SLinus Torvalds
FPT_RNVRamData(struct nvram_info * pNvRamInfo)140668d0c1aeSAlexey Dobriyan static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
14071da177e4SLinus Torvalds {
1408db038cf8SAlexey Dobriyan unsigned char i;
1409391e2f25SKhalid Aziz u32 portBase;
1410391e2f25SKhalid Aziz u32 regOffset;
1411391e2f25SKhalid Aziz u32 scamData;
1412391e2f25SKhalid Aziz u32 *pScamTbl;
14131da177e4SLinus Torvalds
141447b5d69cSJames Bottomley pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
141547b5d69cSJames Bottomley pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
141647b5d69cSJames Bottomley pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
141747b5d69cSJames Bottomley pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
141847b5d69cSJames Bottomley pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
14191da177e4SLinus Torvalds
14201da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR / 2; i++)
14215c04a7b8SAlexey Dobriyan pNvRamInfo->niSyncTbl[i] =
14225c04a7b8SAlexey Dobriyan FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
14231da177e4SLinus Torvalds
14241da177e4SLinus Torvalds portBase = pNvRamInfo->niBaseAddr;
14251da177e4SLinus Torvalds
14261da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR; i++) {
14271da177e4SLinus Torvalds regOffset = hp_aramBase + 64 + i * 4;
14281da177e4SLinus Torvalds RD_HARP32(portBase, regOffset, scamData);
1429391e2f25SKhalid Aziz pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
14301da177e4SLinus Torvalds *pScamTbl = scamData;
14311da177e4SLinus Torvalds }
14321da177e4SLinus Torvalds
14331da177e4SLinus Torvalds }
14341da177e4SLinus Torvalds
FPT_RdStack(u32 portBase,unsigned char index)1435391e2f25SKhalid Aziz static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
14361da177e4SLinus Torvalds {
14371da177e4SLinus Torvalds WR_HARPOON(portBase + hp_stack_addr, index);
14385c1b85e2SAlexey Dobriyan return RD_HARPOON(portBase + hp_stack_data);
14391da177e4SLinus Torvalds }
14401da177e4SLinus Torvalds
FPT_WrStack(u32 portBase,unsigned char index,unsigned char data)1441391e2f25SKhalid Aziz static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
14421da177e4SLinus Torvalds {
14431da177e4SLinus Torvalds WR_HARPOON(portBase + hp_stack_addr, index);
14441da177e4SLinus Torvalds WR_HARPOON(portBase + hp_stack_data, data);
14451da177e4SLinus Torvalds }
14461da177e4SLinus Torvalds
FPT_ChkIfChipInitialized(u32 ioPort)1447391e2f25SKhalid Aziz static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
14481da177e4SLinus Torvalds {
144947b5d69cSJames Bottomley if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
14505c1b85e2SAlexey Dobriyan return 0;
14511da177e4SLinus Torvalds if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
14521da177e4SLinus Torvalds != CLKCTRL_DEFAULT)
14535c1b85e2SAlexey Dobriyan return 0;
14541da177e4SLinus Torvalds if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
14551da177e4SLinus Torvalds (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
14565c1b85e2SAlexey Dobriyan return 1;
14575c1b85e2SAlexey Dobriyan return 0;
14581da177e4SLinus Torvalds
14591da177e4SLinus Torvalds }
14605c04a7b8SAlexey Dobriyan
14611da177e4SLinus Torvalds /*---------------------------------------------------------------------
14621da177e4SLinus Torvalds *
1463d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_StartCCB
14641da177e4SLinus Torvalds *
14651da177e4SLinus Torvalds * Description: Start a command pointed to by p_Sccb. When the
14661da177e4SLinus Torvalds * command is completed it will be returned via the
14671da177e4SLinus Torvalds * callback function.
14681da177e4SLinus Torvalds *
14691da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FlashPoint_StartCCB(void * curr_card,struct sccb * p_Sccb)1470391e2f25SKhalid Aziz static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
14711da177e4SLinus Torvalds {
1472391e2f25SKhalid Aziz u32 ioport;
1473db038cf8SAlexey Dobriyan unsigned char thisCard, lun;
147469eb2ea4SAlexey Dobriyan struct sccb *pSaveSccb;
14751da177e4SLinus Torvalds CALL_BK_FN callback;
1476391e2f25SKhalid Aziz struct sccb_card *pCurrCard = curr_card;
14771da177e4SLinus Torvalds
1478391e2f25SKhalid Aziz thisCard = pCurrCard->cardIndex;
1479391e2f25SKhalid Aziz ioport = pCurrCard->ioPort;
14801da177e4SLinus Torvalds
14811377d8ddSAdrian Bunk if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
14821da177e4SLinus Torvalds
14831da177e4SLinus Torvalds p_Sccb->HostStatus = SCCB_COMPLETE;
14841da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ERROR;
14851da177e4SLinus Torvalds callback = (CALL_BK_FN) p_Sccb->SccbCallback;
14861da177e4SLinus Torvalds if (callback)
14871da177e4SLinus Torvalds callback(p_Sccb);
14881da177e4SLinus Torvalds
14891da177e4SLinus Torvalds return;
14901da177e4SLinus Torvalds }
14911da177e4SLinus Torvalds
149247b5d69cSJames Bottomley FPT_sinits(p_Sccb, thisCard);
14931da177e4SLinus Torvalds
1494391e2f25SKhalid Aziz if (!pCurrCard->cmdCounter) {
14955c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_semaphore,
14965c04a7b8SAlexey Dobriyan (RD_HARPOON(ioport + hp_semaphore)
14971da177e4SLinus Torvalds | SCCB_MGR_ACTIVE));
14981da177e4SLinus Torvalds
1499391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_GREEN_PC) {
15001da177e4SLinus Torvalds WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
15011da177e4SLinus Torvalds WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
15021da177e4SLinus Torvalds }
15031da177e4SLinus Torvalds }
15041da177e4SLinus Torvalds
1505391e2f25SKhalid Aziz pCurrCard->cmdCounter++;
15061da177e4SLinus Torvalds
15071da177e4SLinus Torvalds if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
15081da177e4SLinus Torvalds
15095c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_semaphore,
15105c04a7b8SAlexey Dobriyan (RD_HARPOON(ioport + hp_semaphore)
15111da177e4SLinus Torvalds | TICKLE_ME));
15125c04a7b8SAlexey Dobriyan if (p_Sccb->OperationCode == RESET_COMMAND) {
15135c04a7b8SAlexey Dobriyan pSaveSccb =
1514391e2f25SKhalid Aziz pCurrCard->currentSCCB;
1515391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb;
151647b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1517391e2f25SKhalid Aziz pCurrCard->currentSCCB =
15185c04a7b8SAlexey Dobriyan pSaveSccb;
15195c04a7b8SAlexey Dobriyan } else {
152047b5d69cSJames Bottomley FPT_queueAddSccb(p_Sccb, thisCard);
15211da177e4SLinus Torvalds }
15221da177e4SLinus Torvalds }
15231da177e4SLinus Torvalds
15241da177e4SLinus Torvalds else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
15251da177e4SLinus Torvalds
15265c04a7b8SAlexey Dobriyan if (p_Sccb->OperationCode == RESET_COMMAND) {
15275c04a7b8SAlexey Dobriyan pSaveSccb =
1528391e2f25SKhalid Aziz pCurrCard->currentSCCB;
1529391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb;
153047b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1531391e2f25SKhalid Aziz pCurrCard->currentSCCB =
15325c04a7b8SAlexey Dobriyan pSaveSccb;
15335c04a7b8SAlexey Dobriyan } else {
153447b5d69cSJames Bottomley FPT_queueAddSccb(p_Sccb, thisCard);
15351da177e4SLinus Torvalds }
15361da177e4SLinus Torvalds }
15371da177e4SLinus Torvalds
15381da177e4SLinus Torvalds else {
15391da177e4SLinus Torvalds
15401da177e4SLinus Torvalds MDISABLE_INT(ioport);
15411da177e4SLinus Torvalds
1542391e2f25SKhalid Aziz if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
15435c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
15445c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
15451da177e4SLinus Torvalds lun = p_Sccb->Lun;
15461da177e4SLinus Torvalds else
15471da177e4SLinus Torvalds lun = 0;
1548391e2f25SKhalid Aziz if ((pCurrCard->currentSCCB == NULL) &&
15495c04a7b8SAlexey Dobriyan (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
15505c04a7b8SAlexey Dobriyan && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
155147b5d69cSJames Bottomley == 0)) {
15521da177e4SLinus Torvalds
1553391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb;
155447b5d69cSJames Bottomley FPT_ssel(p_Sccb->SccbIOPort, thisCard);
15551da177e4SLinus Torvalds }
15561da177e4SLinus Torvalds
15571da177e4SLinus Torvalds else {
15581da177e4SLinus Torvalds
15595c04a7b8SAlexey Dobriyan if (p_Sccb->OperationCode == RESET_COMMAND) {
1560391e2f25SKhalid Aziz pSaveSccb = pCurrCard->currentSCCB;
1561391e2f25SKhalid Aziz pCurrCard->currentSCCB = p_Sccb;
15625c04a7b8SAlexey Dobriyan FPT_queueSelectFail(&FPT_BL_Card[thisCard],
15635c04a7b8SAlexey Dobriyan thisCard);
1564391e2f25SKhalid Aziz pCurrCard->currentSCCB = pSaveSccb;
15655c04a7b8SAlexey Dobriyan } else {
156647b5d69cSJames Bottomley FPT_queueAddSccb(p_Sccb, thisCard);
15671da177e4SLinus Torvalds }
15681da177e4SLinus Torvalds }
15691da177e4SLinus Torvalds
15701da177e4SLinus Torvalds MENABLE_INT(ioport);
15711da177e4SLinus Torvalds }
15721da177e4SLinus Torvalds
15731da177e4SLinus Torvalds }
15741da177e4SLinus Torvalds
15751da177e4SLinus Torvalds /*---------------------------------------------------------------------
15761da177e4SLinus Torvalds *
1577d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_AbortCCB
15781da177e4SLinus Torvalds *
15791da177e4SLinus Torvalds * Description: Abort the command pointed to by p_Sccb. When the
15801da177e4SLinus Torvalds * command is completed it will be returned via the
15811da177e4SLinus Torvalds * callback function.
15821da177e4SLinus Torvalds *
15831da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FlashPoint_AbortCCB(void * pCurrCard,struct sccb * p_Sccb)1584391e2f25SKhalid Aziz static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
15851da177e4SLinus Torvalds {
1586391e2f25SKhalid Aziz u32 ioport;
15871da177e4SLinus Torvalds
1588db038cf8SAlexey Dobriyan unsigned char thisCard;
15891da177e4SLinus Torvalds CALL_BK_FN callback;
159069eb2ea4SAlexey Dobriyan struct sccb *pSaveSCCB;
1591f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
15921da177e4SLinus Torvalds
159313e6851aSAlexey Dobriyan ioport = ((struct sccb_card *)pCurrCard)->ioPort;
15941da177e4SLinus Torvalds
159513e6851aSAlexey Dobriyan thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
15961da177e4SLinus Torvalds
15975c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
15981da177e4SLinus Torvalds
15995c04a7b8SAlexey Dobriyan if (FPT_queueFindSccb(p_Sccb, thisCard)) {
16001da177e4SLinus Torvalds
160113e6851aSAlexey Dobriyan ((struct sccb_card *)pCurrCard)->cmdCounter--;
16021da177e4SLinus Torvalds
160313e6851aSAlexey Dobriyan if (!((struct sccb_card *)pCurrCard)->cmdCounter)
16045c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_semaphore,
16055c04a7b8SAlexey Dobriyan (RD_HARPOON(ioport + hp_semaphore)
16065c04a7b8SAlexey Dobriyan & (unsigned
16075c04a7b8SAlexey Dobriyan char)(~(SCCB_MGR_ACTIVE |
16085c04a7b8SAlexey Dobriyan TICKLE_ME))));
16091da177e4SLinus Torvalds
16101da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT;
16111da177e4SLinus Torvalds callback = p_Sccb->SccbCallback;
16121da177e4SLinus Torvalds callback(p_Sccb);
16131da177e4SLinus Torvalds
16145c1b85e2SAlexey Dobriyan return 0;
16151da177e4SLinus Torvalds }
16161da177e4SLinus Torvalds
16175c04a7b8SAlexey Dobriyan else {
16185c04a7b8SAlexey Dobriyan if (((struct sccb_card *)pCurrCard)->currentSCCB ==
16195c04a7b8SAlexey Dobriyan p_Sccb) {
16201da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT;
16215c1b85e2SAlexey Dobriyan return 0;
16221da177e4SLinus Torvalds
16231da177e4SLinus Torvalds }
16241da177e4SLinus Torvalds
16255c04a7b8SAlexey Dobriyan else {
16265c04a7b8SAlexey Dobriyan if (p_Sccb->Sccb_tag) {
16271da177e4SLinus Torvalds MDISABLE_INT(ioport);
16285c04a7b8SAlexey Dobriyan if (((struct sccb_card *)pCurrCard)->
16295c04a7b8SAlexey Dobriyan discQ_Tbl[p_Sccb->Sccb_tag] ==
16305c04a7b8SAlexey Dobriyan p_Sccb) {
16311da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT;
16325c04a7b8SAlexey Dobriyan p_Sccb->Sccb_scsistat =
16335c04a7b8SAlexey Dobriyan ABORT_ST;
16345c04a7b8SAlexey Dobriyan p_Sccb->Sccb_scsimsg =
1635a87afe28SHannes Reinecke ABORT_TASK;
16361da177e4SLinus Torvalds
16375c04a7b8SAlexey Dobriyan if (((struct sccb_card *)
16385c04a7b8SAlexey Dobriyan pCurrCard)->currentSCCB ==
16395c04a7b8SAlexey Dobriyan NULL) {
16405c04a7b8SAlexey Dobriyan ((struct sccb_card *)
16415c04a7b8SAlexey Dobriyan pCurrCard)->
16425c04a7b8SAlexey Dobriyan currentSCCB = p_Sccb;
16435c04a7b8SAlexey Dobriyan FPT_ssel(ioport,
16445c04a7b8SAlexey Dobriyan thisCard);
16455c04a7b8SAlexey Dobriyan } else {
16465c04a7b8SAlexey Dobriyan pSaveSCCB =
16475c04a7b8SAlexey Dobriyan ((struct sccb_card
16485c04a7b8SAlexey Dobriyan *)pCurrCard)->
16495c04a7b8SAlexey Dobriyan currentSCCB;
16505c04a7b8SAlexey Dobriyan ((struct sccb_card *)
16515c04a7b8SAlexey Dobriyan pCurrCard)->
16525c04a7b8SAlexey Dobriyan currentSCCB = p_Sccb;
165313e6851aSAlexey Dobriyan FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
16545c04a7b8SAlexey Dobriyan ((struct sccb_card *)
16555c04a7b8SAlexey Dobriyan pCurrCard)->
16565c04a7b8SAlexey Dobriyan currentSCCB = pSaveSCCB;
16571da177e4SLinus Torvalds }
16581da177e4SLinus Torvalds }
16591da177e4SLinus Torvalds MENABLE_INT(ioport);
16605c1b85e2SAlexey Dobriyan return 0;
16615c04a7b8SAlexey Dobriyan } else {
16625c04a7b8SAlexey Dobriyan currTar_Info =
16635c04a7b8SAlexey Dobriyan &FPT_sccbMgrTbl[thisCard][p_Sccb->
16645c04a7b8SAlexey Dobriyan TargID];
16651da177e4SLinus Torvalds
16665c04a7b8SAlexey Dobriyan if (FPT_BL_Card[thisCard].
16675c04a7b8SAlexey Dobriyan discQ_Tbl[currTar_Info->
16685c04a7b8SAlexey Dobriyan LunDiscQ_Idx[p_Sccb->Lun]]
16695c04a7b8SAlexey Dobriyan == p_Sccb) {
16701da177e4SLinus Torvalds p_Sccb->SccbStatus = SCCB_ABORT;
16715c1b85e2SAlexey Dobriyan return 0;
16721da177e4SLinus Torvalds }
16731da177e4SLinus Torvalds }
16741da177e4SLinus Torvalds }
16751da177e4SLinus Torvalds }
16761da177e4SLinus Torvalds }
16775c1b85e2SAlexey Dobriyan return -1;
16781da177e4SLinus Torvalds }
16791da177e4SLinus Torvalds
16801da177e4SLinus Torvalds /*---------------------------------------------------------------------
16811da177e4SLinus Torvalds *
1682d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_InterruptPending
16831da177e4SLinus Torvalds *
16841da177e4SLinus Torvalds * Description: Do a quick check to determine if there is a pending
16851da177e4SLinus Torvalds * interrupt for this card and disable the IRQ Pin if so.
16861da177e4SLinus Torvalds *
16871da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FlashPoint_InterruptPending(void * pCurrCard)1688391e2f25SKhalid Aziz static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
16891da177e4SLinus Torvalds {
1690391e2f25SKhalid Aziz u32 ioport;
16911da177e4SLinus Torvalds
169213e6851aSAlexey Dobriyan ioport = ((struct sccb_card *)pCurrCard)->ioPort;
16931da177e4SLinus Torvalds
16945c04a7b8SAlexey Dobriyan if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
16955c1b85e2SAlexey Dobriyan return 1;
16961da177e4SLinus Torvalds }
16971da177e4SLinus Torvalds
16981da177e4SLinus Torvalds else
16991da177e4SLinus Torvalds
17005c1b85e2SAlexey Dobriyan return 0;
17011da177e4SLinus Torvalds }
17021da177e4SLinus Torvalds
17031da177e4SLinus Torvalds /*---------------------------------------------------------------------
17041da177e4SLinus Torvalds *
1705d8b6b8bdSAlexey Dobriyan * Function: FlashPoint_HandleInterrupt
17061da177e4SLinus Torvalds *
17071da177e4SLinus Torvalds * Description: This is our entry point when an interrupt is generated
17081da177e4SLinus Torvalds * by the card and the upper level driver passes it on to
17091da177e4SLinus Torvalds * us.
17101da177e4SLinus Torvalds *
17111da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FlashPoint_HandleInterrupt(void * pcard)1712391e2f25SKhalid Aziz static int FlashPoint_HandleInterrupt(void *pcard)
17131da177e4SLinus Torvalds {
171469eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
1715*554b117eSColin Ian King unsigned char thisCard, result, bm_status;
1716c823feebSAlexey Dobriyan unsigned short hp_int;
1717db038cf8SAlexey Dobriyan unsigned char i, target;
1718391e2f25SKhalid Aziz struct sccb_card *pCurrCard = pcard;
1719391e2f25SKhalid Aziz u32 ioport;
17201da177e4SLinus Torvalds
1721391e2f25SKhalid Aziz thisCard = pCurrCard->cardIndex;
1722391e2f25SKhalid Aziz ioport = pCurrCard->ioPort;
17231da177e4SLinus Torvalds
17241da177e4SLinus Torvalds MDISABLE_INT(ioport);
17251da177e4SLinus Torvalds
1726*554b117eSColin Ian King if (RD_HARPOON(ioport + hp_int_status) & EXT_STATUS_ON)
1727391e2f25SKhalid Aziz bm_status = RD_HARPOON(ioport + hp_ext_status) &
1728391e2f25SKhalid Aziz (unsigned char)BAD_EXT_STATUS;
17291da177e4SLinus Torvalds else
17301da177e4SLinus Torvalds bm_status = 0;
17311da177e4SLinus Torvalds
17321da177e4SLinus Torvalds WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
17331da177e4SLinus Torvalds
1734391e2f25SKhalid Aziz while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1735391e2f25SKhalid Aziz FPT_default_intena) | bm_status) {
17361da177e4SLinus Torvalds
1737391e2f25SKhalid Aziz currSCCB = pCurrCard->currentSCCB;
17381da177e4SLinus Torvalds
17391da177e4SLinus Torvalds if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
17405c04a7b8SAlexey Dobriyan result =
1741391e2f25SKhalid Aziz FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
17425c04a7b8SAlexey Dobriyan hp_int);
17435c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat),
17445c04a7b8SAlexey Dobriyan (FIFO | TIMEOUT | RESET | SCAM_SEL));
17451da177e4SLinus Torvalds bm_status = 0;
17461da177e4SLinus Torvalds
17471da177e4SLinus Torvalds if (result) {
17481da177e4SLinus Torvalds
17491da177e4SLinus Torvalds MENABLE_INT(ioport);
17505c1b85e2SAlexey Dobriyan return result;
17511da177e4SLinus Torvalds }
17521da177e4SLinus Torvalds }
17531da177e4SLinus Torvalds
17541da177e4SLinus Torvalds else if (hp_int & ICMD_COMP) {
17551da177e4SLinus Torvalds
17561da177e4SLinus Torvalds if (!(hp_int & BUS_FREE)) {
17571da177e4SLinus Torvalds /* Wait for the BusFree before starting a new command. We
17581da177e4SLinus Torvalds must also check for being reselected since the BusFree
17591da177e4SLinus Torvalds may not show up if another device reselects us in 1.5us or
17601da177e4SLinus Torvalds less. SRR Wednesday, 3/8/1995.
17611da177e4SLinus Torvalds */
17625c04a7b8SAlexey Dobriyan while (!
17635c04a7b8SAlexey Dobriyan (RDW_HARPOON((ioport + hp_intstat)) &
17645c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))) ;
17651da177e4SLinus Torvalds }
17661da177e4SLinus Torvalds
1767391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
17681da177e4SLinus Torvalds
176947b5d69cSJames Bottomley FPT_phaseChkFifo(ioport, thisCard);
17701da177e4SLinus Torvalds
17711da177e4SLinus Torvalds /* WRW_HARPOON((ioport+hp_intstat),
17721da177e4SLinus Torvalds (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
17731da177e4SLinus Torvalds */
17741da177e4SLinus Torvalds
17751da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
17761da177e4SLinus Torvalds
177747b5d69cSJames Bottomley FPT_autoCmdCmplt(ioport, thisCard);
17781da177e4SLinus Torvalds
17791da177e4SLinus Torvalds }
17801da177e4SLinus Torvalds
17815c04a7b8SAlexey Dobriyan else if (hp_int & ITAR_DISC) {
17821da177e4SLinus Torvalds
1783391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
178447b5d69cSJames Bottomley FPT_phaseChkFifo(ioport, thisCard);
17851da177e4SLinus Torvalds
1786391e2f25SKhalid Aziz if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1787a87afe28SHannes Reinecke SAVE_POINTERS) {
17881da177e4SLinus Torvalds
17891da177e4SLinus Torvalds WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
17901da177e4SLinus Torvalds currSCCB->Sccb_XferState |= F_NO_DATA_YET;
17911da177e4SLinus Torvalds
17921da177e4SLinus Torvalds currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
17931da177e4SLinus Torvalds }
17941da177e4SLinus Torvalds
17951da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DISCONNECT_ST;
179647b5d69cSJames Bottomley FPT_queueDisconnect(currSCCB, thisCard);
17971da177e4SLinus Torvalds
17981da177e4SLinus Torvalds /* Wait for the BusFree before starting a new command. We
17991da177e4SLinus Torvalds must also check for being reselected since the BusFree
18001da177e4SLinus Torvalds may not show up if another device reselects us in 1.5us or
18011da177e4SLinus Torvalds less. SRR Wednesday, 3/8/1995.
18021da177e4SLinus Torvalds */
18035c04a7b8SAlexey Dobriyan while (!
18045c04a7b8SAlexey Dobriyan (RDW_HARPOON((ioport + hp_intstat)) &
18055c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))
18065c04a7b8SAlexey Dobriyan && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
18075c04a7b8SAlexey Dobriyan && RD_HARPOON((ioport + hp_scsisig)) ==
18085c04a7b8SAlexey Dobriyan (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
18095c04a7b8SAlexey Dobriyan SCSI_IOBIT))) ;
18101da177e4SLinus Torvalds
18111da177e4SLinus Torvalds /*
18121da177e4SLinus Torvalds The additional loop exit condition above detects a timing problem
18131da177e4SLinus Torvalds with the revision D/E harpoon chips. The caller should reset the
18141da177e4SLinus Torvalds host adapter to recover when 0xFE is returned.
18151da177e4SLinus Torvalds */
18165c04a7b8SAlexey Dobriyan if (!
18175c04a7b8SAlexey Dobriyan (RDW_HARPOON((ioport + hp_intstat)) &
18185c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))) {
18191da177e4SLinus Torvalds MENABLE_INT(ioport);
18201da177e4SLinus Torvalds return 0xFE;
18211da177e4SLinus Torvalds }
18221da177e4SLinus Torvalds
18235c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat),
18245c04a7b8SAlexey Dobriyan (BUS_FREE | ITAR_DISC));
18251da177e4SLinus Torvalds
1826391e2f25SKhalid Aziz pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
18271da177e4SLinus Torvalds
18281da177e4SLinus Torvalds }
18291da177e4SLinus Torvalds
18301da177e4SLinus Torvalds else if (hp_int & RSEL) {
18311da177e4SLinus Torvalds
18325c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat),
18335c04a7b8SAlexey Dobriyan (PROG_HLT | RSEL | PHASE | BUS_FREE));
18341da177e4SLinus Torvalds
18355c04a7b8SAlexey Dobriyan if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1836391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
183747b5d69cSJames Bottomley FPT_phaseChkFifo(ioport, thisCard);
18381da177e4SLinus Torvalds
18395c04a7b8SAlexey Dobriyan if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1840a87afe28SHannes Reinecke SAVE_POINTERS) {
18411da177e4SLinus Torvalds WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
18425c04a7b8SAlexey Dobriyan currSCCB->Sccb_XferState |=
18435c04a7b8SAlexey Dobriyan F_NO_DATA_YET;
18445c04a7b8SAlexey Dobriyan currSCCB->Sccb_savedATC =
18455c04a7b8SAlexey Dobriyan currSCCB->Sccb_ATC;
18461da177e4SLinus Torvalds }
18471da177e4SLinus Torvalds
18485c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat),
18495c04a7b8SAlexey Dobriyan (BUS_FREE | ITAR_DISC));
18501da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DISCONNECT_ST;
185147b5d69cSJames Bottomley FPT_queueDisconnect(currSCCB, thisCard);
18521da177e4SLinus Torvalds }
18531da177e4SLinus Torvalds
1854391e2f25SKhalid Aziz FPT_sres(ioport, thisCard, pCurrCard);
185547b5d69cSJames Bottomley FPT_phaseDecode(ioport, thisCard);
18561da177e4SLinus Torvalds
18571da177e4SLinus Torvalds }
18581da177e4SLinus Torvalds
18595c04a7b8SAlexey Dobriyan else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
18601da177e4SLinus Torvalds
18615c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat),
18625c04a7b8SAlexey Dobriyan (IDO_STRT | XFER_CNT_0));
186347b5d69cSJames Bottomley FPT_phaseDecode(ioport, thisCard);
18641da177e4SLinus Torvalds
18651da177e4SLinus Torvalds }
18661da177e4SLinus Torvalds
18675c04a7b8SAlexey Dobriyan else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
18685c04a7b8SAlexey Dobriyan WRW_HARPOON((ioport + hp_intstat),
18695c04a7b8SAlexey Dobriyan (PHASE | IUNKWN | PROG_HLT));
18705c04a7b8SAlexey Dobriyan if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
18715c04a7b8SAlexey Dobriyan 0x3f) < (unsigned char)SELCHK) {
187247b5d69cSJames Bottomley FPT_phaseDecode(ioport, thisCard);
18735c04a7b8SAlexey Dobriyan } else {
18741da177e4SLinus Torvalds /* Harpoon problem some SCSI target device respond to selection
18751da177e4SLinus Torvalds with short BUSY pulse (<400ns) this will make the Harpoon is not able
18761da177e4SLinus Torvalds to latch the correct Target ID into reg. x53.
18771da177e4SLinus Torvalds The work around require to correct this reg. But when write to this
18781da177e4SLinus Torvalds reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
18791da177e4SLinus Torvalds need to read this reg first then restore it later. After update to 0x53 */
18801da177e4SLinus Torvalds
18815c04a7b8SAlexey Dobriyan i = (unsigned
18825c04a7b8SAlexey Dobriyan char)(RD_HARPOON(ioport + hp_fifowrite));
18835c04a7b8SAlexey Dobriyan target =
18845c04a7b8SAlexey Dobriyan (unsigned
18855c04a7b8SAlexey Dobriyan char)(RD_HARPOON(ioport + hp_gp_reg_3));
18865c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_xfer_pad,
18875c04a7b8SAlexey Dobriyan (unsigned char)ID_UNLOCK);
18885c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_select_id,
18895c04a7b8SAlexey Dobriyan (unsigned char)(target | target <<
18905c04a7b8SAlexey Dobriyan 4));
18915c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_xfer_pad,
18925c04a7b8SAlexey Dobriyan (unsigned char)0x00);
18931da177e4SLinus Torvalds WR_HARPOON(ioport + hp_fifowrite, i);
18945c04a7b8SAlexey Dobriyan WR_HARPOON(ioport + hp_autostart_3,
18955c04a7b8SAlexey Dobriyan (AUTO_IMMED + TAG_STRT));
18961da177e4SLinus Torvalds }
18971da177e4SLinus Torvalds }
18981da177e4SLinus Torvalds
18991da177e4SLinus Torvalds else if (hp_int & XFER_CNT_0) {
19001da177e4SLinus Torvalds
19011da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
19021da177e4SLinus Torvalds
190347b5d69cSJames Bottomley FPT_schkdd(ioport, thisCard);
19041da177e4SLinus Torvalds
19051da177e4SLinus Torvalds }
19061da177e4SLinus Torvalds
19071da177e4SLinus Torvalds else if (hp_int & BUS_FREE) {
19081da177e4SLinus Torvalds
19091da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
19101da177e4SLinus Torvalds
1911391e2f25SKhalid Aziz if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
19121da177e4SLinus Torvalds
19135c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(ioport, thisCard,
19145c04a7b8SAlexey Dobriyan currSCCB);
19151da177e4SLinus Torvalds }
19161da177e4SLinus Torvalds
191747b5d69cSJames Bottomley FPT_phaseBusFree(ioport, thisCard);
19181da177e4SLinus Torvalds }
19191da177e4SLinus Torvalds
19201da177e4SLinus Torvalds else if (hp_int & ITICKLE) {
19211da177e4SLinus Torvalds
19221da177e4SLinus Torvalds WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1923391e2f25SKhalid Aziz pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
19241da177e4SLinus Torvalds }
19251da177e4SLinus Torvalds
19265c04a7b8SAlexey Dobriyan if (((struct sccb_card *)pCurrCard)->
19275c04a7b8SAlexey Dobriyan globalFlags & F_NEW_SCCB_CMD) {
19281da177e4SLinus Torvalds
1929391e2f25SKhalid Aziz pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
19301da177e4SLinus Torvalds
1931391e2f25SKhalid Aziz if (pCurrCard->currentSCCB == NULL)
1932391e2f25SKhalid Aziz FPT_queueSearchSelect(pCurrCard, thisCard);
19331da177e4SLinus Torvalds
1934391e2f25SKhalid Aziz if (pCurrCard->currentSCCB != NULL) {
1935391e2f25SKhalid Aziz pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
193647b5d69cSJames Bottomley FPT_ssel(ioport, thisCard);
19371da177e4SLinus Torvalds }
19381da177e4SLinus Torvalds
19391da177e4SLinus Torvalds break;
19401da177e4SLinus Torvalds
19411da177e4SLinus Torvalds }
19421da177e4SLinus Torvalds
19431da177e4SLinus Torvalds } /*end while */
19441da177e4SLinus Torvalds
19451da177e4SLinus Torvalds MENABLE_INT(ioport);
19461da177e4SLinus Torvalds
19475c1b85e2SAlexey Dobriyan return 0;
19481da177e4SLinus Torvalds }
19491da177e4SLinus Torvalds
19501da177e4SLinus Torvalds /*---------------------------------------------------------------------
19511da177e4SLinus Torvalds *
19521da177e4SLinus Torvalds * Function: Sccb_bad_isr
19531da177e4SLinus Torvalds *
19541da177e4SLinus Torvalds * Description: Some type of interrupt has occurred which is slightly
19551da177e4SLinus Torvalds * out of the ordinary. We will now decode it fully, in
19561da177e4SLinus Torvalds * this routine. This is broken up in an attempt to save
19571da177e4SLinus Torvalds * processing time.
19581da177e4SLinus Torvalds *
19591da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_SccbMgr_bad_isr(u32 p_port,unsigned char p_card,struct sccb_card * pCurrCard,unsigned short p_int)1960391e2f25SKhalid Aziz static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
19615c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard,
19625c04a7b8SAlexey Dobriyan unsigned short p_int)
19631da177e4SLinus Torvalds {
1964db038cf8SAlexey Dobriyan unsigned char temp, ScamFlg;
1965f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
196668d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
19671da177e4SLinus Torvalds
19681da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ext_status) &
19695c04a7b8SAlexey Dobriyan (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
19701da177e4SLinus Torvalds
19715c04a7b8SAlexey Dobriyan if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
19721da177e4SLinus Torvalds
19735c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(p_port, p_card,
19745c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB);
19751da177e4SLinus Torvalds }
19761da177e4SLinus Torvalds
19771da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
19781da177e4SLinus Torvalds {
19791da177e4SLinus Torvalds WR_HARPOON(p_port + hp_pci_stat_cfg,
19805c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_pci_stat_cfg) &
19815c04a7b8SAlexey Dobriyan ~REC_MASTER_ABORT));
19821da177e4SLinus Torvalds
19831da177e4SLinus Torvalds WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
19841da177e4SLinus Torvalds
19851da177e4SLinus Torvalds }
19861da177e4SLinus Torvalds
19875c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) {
19881da177e4SLinus Torvalds
19891da177e4SLinus Torvalds if (!pCurrCard->currentSCCB->HostStatus)
19905c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB->HostStatus =
19915c04a7b8SAlexey Dobriyan SCCB_BM_ERR;
19921da177e4SLinus Torvalds
199347b5d69cSJames Bottomley FPT_sxfrp(p_port, p_card);
19941da177e4SLinus Torvalds
1995db038cf8SAlexey Dobriyan temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
19961da177e4SLinus Torvalds (EXT_ARB_ACK | SCSI_TERM_ENA_H));
19975c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_ee_ctrl,
19985c04a7b8SAlexey Dobriyan ((unsigned char)temp | SEE_MS | SEE_CS));
19991da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, temp);
20001da177e4SLinus Torvalds
20015c04a7b8SAlexey Dobriyan if (!
20025c04a7b8SAlexey Dobriyan (RDW_HARPOON((p_port + hp_intstat)) &
20035c04a7b8SAlexey Dobriyan (BUS_FREE | RESET))) {
200447b5d69cSJames Bottomley FPT_phaseDecode(p_port, p_card);
20051da177e4SLinus Torvalds }
20061da177e4SLinus Torvalds }
20071da177e4SLinus Torvalds }
20081da177e4SLinus Torvalds
20095c04a7b8SAlexey Dobriyan else if (p_int & RESET) {
20101da177e4SLinus Torvalds
20111da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
20121da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
20131da177e4SLinus Torvalds if (pCurrCard->currentSCCB != NULL) {
20141da177e4SLinus Torvalds
20151da177e4SLinus Torvalds if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
20161da177e4SLinus Torvalds
20175c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(p_port, p_card,
20185c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB);
20191da177e4SLinus Torvalds }
20201da177e4SLinus Torvalds
20211da177e4SLinus Torvalds DISABLE_AUTO(p_port);
20221da177e4SLinus Torvalds
202347b5d69cSJames Bottomley FPT_sresb(p_port, p_card);
20241da177e4SLinus Torvalds
20255c04a7b8SAlexey Dobriyan while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
20265c04a7b8SAlexey Dobriyan }
20271da177e4SLinus Torvalds
20281da177e4SLinus Torvalds pCurrNvRam = pCurrCard->pNvRamInfo;
20291da177e4SLinus Torvalds if (pCurrNvRam) {
20301da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf;
20315c04a7b8SAlexey Dobriyan } else {
20325c04a7b8SAlexey Dobriyan ScamFlg =
20335c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(p_port,
20345c04a7b8SAlexey Dobriyan SCAM_CONFIG / 2);
20351da177e4SLinus Torvalds }
20361da177e4SLinus Torvalds
203747b5d69cSJames Bottomley FPT_XbowInit(p_port, ScamFlg);
20381da177e4SLinus Torvalds
203947b5d69cSJames Bottomley FPT_scini(p_card, pCurrCard->ourId, 0);
20401da177e4SLinus Torvalds
20415c1b85e2SAlexey Dobriyan return 0xFF;
20421da177e4SLinus Torvalds }
20431da177e4SLinus Torvalds
20441da177e4SLinus Torvalds else if (p_int & FIFO) {
20451da177e4SLinus Torvalds
20461da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), FIFO);
20471da177e4SLinus Torvalds
20481da177e4SLinus Torvalds if (pCurrCard->currentSCCB != NULL)
204947b5d69cSJames Bottomley FPT_sxfrp(p_port, p_card);
20501da177e4SLinus Torvalds }
20511da177e4SLinus Torvalds
20525c04a7b8SAlexey Dobriyan else if (p_int & TIMEOUT) {
20531da177e4SLinus Torvalds
20541da177e4SLinus Torvalds DISABLE_AUTO(p_port);
20551da177e4SLinus Torvalds
20561da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat),
20575c04a7b8SAlexey Dobriyan (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
20585c04a7b8SAlexey Dobriyan IUNKWN));
20591da177e4SLinus Torvalds
20601da177e4SLinus Torvalds pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
20611da177e4SLinus Torvalds
20625c04a7b8SAlexey Dobriyan currTar_Info =
20635c04a7b8SAlexey Dobriyan &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
20645c04a7b8SAlexey Dobriyan if ((pCurrCard->globalFlags & F_CONLUN_IO)
20655c04a7b8SAlexey Dobriyan && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
20665c04a7b8SAlexey Dobriyan TAG_Q_TRYING))
20675c04a7b8SAlexey Dobriyan currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
20685c04a7b8SAlexey Dobriyan 0;
20691da177e4SLinus Torvalds else
207047b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 0;
20711da177e4SLinus Torvalds
20725c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
20731da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0;
20741da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
20751da177e4SLinus Torvalds }
20761da177e4SLinus Torvalds
20775c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
20781da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
20791da177e4SLinus Torvalds }
20801da177e4SLinus Torvalds
20815c04a7b8SAlexey Dobriyan FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
20825c04a7b8SAlexey Dobriyan currTar_Info);
20831da177e4SLinus Torvalds
208447b5d69cSJames Bottomley FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
20851da177e4SLinus Torvalds
20861da177e4SLinus Torvalds }
20871da177e4SLinus Torvalds
20885c04a7b8SAlexey Dobriyan else if (p_int & SCAM_SEL) {
20891da177e4SLinus Torvalds
209047b5d69cSJames Bottomley FPT_scarb(p_port, LEVEL2_TAR);
209147b5d69cSJames Bottomley FPT_scsel(p_port);
209247b5d69cSJames Bottomley FPT_scasid(p_card, p_port);
20931da177e4SLinus Torvalds
209447b5d69cSJames Bottomley FPT_scbusf(p_port);
20951da177e4SLinus Torvalds
20961da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
20971da177e4SLinus Torvalds }
20981da177e4SLinus Torvalds
20995c1b85e2SAlexey Dobriyan return 0x00;
21001da177e4SLinus Torvalds }
21011da177e4SLinus Torvalds
21021da177e4SLinus Torvalds /*---------------------------------------------------------------------
21031da177e4SLinus Torvalds *
21041da177e4SLinus Torvalds * Function: SccbMgrTableInit
21051da177e4SLinus Torvalds *
21061da177e4SLinus Torvalds * Description: Initialize all Sccb manager data structures.
21071da177e4SLinus Torvalds *
21081da177e4SLinus Torvalds *---------------------------------------------------------------------*/
21091da177e4SLinus Torvalds
FPT_SccbMgrTableInitAll(void)2110cd9d715cSSudip Mukherjee static void FPT_SccbMgrTableInitAll(void)
21111da177e4SLinus Torvalds {
2112db038cf8SAlexey Dobriyan unsigned char thisCard;
21131da177e4SLinus Torvalds
21145c04a7b8SAlexey Dobriyan for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
211547b5d69cSJames Bottomley FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
21161da177e4SLinus Torvalds
211747b5d69cSJames Bottomley FPT_BL_Card[thisCard].ioPort = 0x00;
211847b5d69cSJames Bottomley FPT_BL_Card[thisCard].cardInfo = NULL;
211947b5d69cSJames Bottomley FPT_BL_Card[thisCard].cardIndex = 0xFF;
212047b5d69cSJames Bottomley FPT_BL_Card[thisCard].ourId = 0x00;
212147b5d69cSJames Bottomley FPT_BL_Card[thisCard].pNvRamInfo = NULL;
21221da177e4SLinus Torvalds }
21231da177e4SLinus Torvalds }
21241da177e4SLinus Torvalds
21251da177e4SLinus Torvalds /*---------------------------------------------------------------------
21261da177e4SLinus Torvalds *
21271da177e4SLinus Torvalds * Function: SccbMgrTableInit
21281da177e4SLinus Torvalds *
21291da177e4SLinus Torvalds * Description: Initialize all Sccb manager data structures.
21301da177e4SLinus Torvalds *
21311da177e4SLinus Torvalds *---------------------------------------------------------------------*/
21321da177e4SLinus Torvalds
FPT_SccbMgrTableInitCard(struct sccb_card * pCurrCard,unsigned char p_card)21335c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
21345c04a7b8SAlexey Dobriyan unsigned char p_card)
21351da177e4SLinus Torvalds {
2136db038cf8SAlexey Dobriyan unsigned char scsiID, qtag;
21371da177e4SLinus Torvalds
21385c04a7b8SAlexey Dobriyan for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
213947b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
21401da177e4SLinus Torvalds }
21411da177e4SLinus Torvalds
21425c04a7b8SAlexey Dobriyan for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
214347b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
214447b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
214547b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, scsiID);
21461da177e4SLinus Torvalds }
21471da177e4SLinus Torvalds
21481da177e4SLinus Torvalds pCurrCard->scanIndex = 0x00;
21491da177e4SLinus Torvalds pCurrCard->currentSCCB = NULL;
21501da177e4SLinus Torvalds pCurrCard->globalFlags = 0x00;
21511da177e4SLinus Torvalds pCurrCard->cmdCounter = 0x00;
21521da177e4SLinus Torvalds pCurrCard->tagQ_Lst = 0x01;
21531da177e4SLinus Torvalds pCurrCard->discQCount = 0;
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
FPT_SccbMgrTableInitTarget(unsigned char p_card,unsigned char target)21655c04a7b8SAlexey Dobriyan static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
21665c04a7b8SAlexey Dobriyan unsigned char target)
21671da177e4SLinus Torvalds {
21681da177e4SLinus Torvalds
2169db038cf8SAlexey Dobriyan unsigned char lun, qtag;
2170f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
21711da177e4SLinus Torvalds
217247b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][target];
21731da177e4SLinus Torvalds
21741da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt = 0;
21751da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0;
21761da177e4SLinus Torvalds
21771da177e4SLinus Torvalds currTar_Info->TarSelQ_Head = NULL;
21781da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = NULL;
21791da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt = 0;
218047b5d69cSJames Bottomley currTar_Info->TarLUN_CA = 0;
21811da177e4SLinus Torvalds
21825c04a7b8SAlexey Dobriyan for (lun = 0; lun < MAX_LUN; lun++) {
218347b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 0;
21841da177e4SLinus Torvalds currTar_Info->LunDiscQ_Idx[lun] = 0;
21851da177e4SLinus Torvalds }
21861da177e4SLinus Torvalds
21875c04a7b8SAlexey Dobriyan for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
21885c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
21895c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
21905c04a7b8SAlexey Dobriyan target) {
219147b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
219247b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--;
21931da177e4SLinus Torvalds }
21941da177e4SLinus Torvalds }
21951da177e4SLinus Torvalds }
21961da177e4SLinus Torvalds }
21971da177e4SLinus Torvalds
21981da177e4SLinus Torvalds /*---------------------------------------------------------------------
21991da177e4SLinus Torvalds *
22001da177e4SLinus Torvalds * Function: sfetm
22011da177e4SLinus Torvalds *
22021da177e4SLinus Torvalds * Description: Read in a message byte from the SCSI bus, and check
22031da177e4SLinus Torvalds * for a parity error.
22041da177e4SLinus Torvalds *
22051da177e4SLinus Torvalds *---------------------------------------------------------------------*/
22061da177e4SLinus Torvalds
FPT_sfm(u32 port,struct sccb * pCurrSCCB)2207391e2f25SKhalid Aziz static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
22081da177e4SLinus Torvalds {
2209db038cf8SAlexey Dobriyan unsigned char message;
2210c823feebSAlexey Dobriyan unsigned short TimeOutLoop;
22111da177e4SLinus Torvalds
22121da177e4SLinus Torvalds TimeOutLoop = 0;
22131da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
22145c04a7b8SAlexey Dobriyan (TimeOutLoop++ < 20000)) {
22155c04a7b8SAlexey Dobriyan }
22161da177e4SLinus Torvalds
22171da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
22181da177e4SLinus Torvalds
22191da177e4SLinus Torvalds message = RD_HARPOON(port + hp_scsidata_0);
22201da177e4SLinus Torvalds
22211da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
22221da177e4SLinus Torvalds
22231da177e4SLinus Torvalds if (TimeOutLoop > 20000)
22241da177e4SLinus Torvalds message = 0x00; /* force message byte = 0 if Time Out on Req */
22251da177e4SLinus Torvalds
22261da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
22275c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
22281da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
22291da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0);
22301da177e4SLinus Torvalds WR_HARPOON(port + hp_fiforead, 0);
22311da177e4SLinus Torvalds WR_HARPOON(port + hp_fifowrite, 0);
22325c04a7b8SAlexey Dobriyan if (pCurrSCCB != NULL) {
2233a87afe28SHannes Reinecke pCurrSCCB->Sccb_scsimsg = MSG_PARITY_ERROR;
22341da177e4SLinus Torvalds }
22351da177e4SLinus Torvalds message = 0x00;
22365c04a7b8SAlexey Dobriyan do {
22371da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
22381da177e4SLinus Torvalds TimeOutLoop = 0;
22391da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
22405c04a7b8SAlexey Dobriyan (TimeOutLoop++ < 20000)) {
22415c04a7b8SAlexey Dobriyan }
22425c04a7b8SAlexey Dobriyan if (TimeOutLoop > 20000) {
22431da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY);
22445c1b85e2SAlexey Dobriyan return message;
22451da177e4SLinus Torvalds }
22465c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
22475c04a7b8SAlexey Dobriyan S_MSGI_PH) {
22481da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY);
22495c1b85e2SAlexey Dobriyan return message;
22501da177e4SLinus Torvalds }
22511da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
22521da177e4SLinus Torvalds
22531da177e4SLinus Torvalds RD_HARPOON(port + hp_scsidata_0);
22541da177e4SLinus Torvalds
22551da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
22561da177e4SLinus Torvalds
22571da177e4SLinus Torvalds } while (1);
22581da177e4SLinus Torvalds
22591da177e4SLinus Torvalds }
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);
22645c1b85e2SAlexey Dobriyan return message;
22651da177e4SLinus Torvalds }
22661da177e4SLinus Torvalds
22671da177e4SLinus Torvalds /*---------------------------------------------------------------------
22681da177e4SLinus Torvalds *
226947b5d69cSJames Bottomley * Function: FPT_ssel
22701da177e4SLinus Torvalds *
22711da177e4SLinus Torvalds * Description: Load up automation and select target device.
22721da177e4SLinus Torvalds *
22731da177e4SLinus Torvalds *---------------------------------------------------------------------*/
22741da177e4SLinus Torvalds
FPT_ssel(u32 port,unsigned char p_card)2275391e2f25SKhalid Aziz static void FPT_ssel(u32 port, unsigned char p_card)
22761da177e4SLinus Torvalds {
22771da177e4SLinus Torvalds
2278db038cf8SAlexey Dobriyan unsigned char auto_loaded, i, target, *theCCB;
22791da177e4SLinus Torvalds
2280391e2f25SKhalid Aziz u32 cdb_reg;
228113e6851aSAlexey Dobriyan struct sccb_card *CurrCard;
228269eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
2283f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
2284db038cf8SAlexey Dobriyan unsigned char lastTag, lun;
22851da177e4SLinus Torvalds
228647b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[p_card];
22871da177e4SLinus Torvalds currSCCB = CurrCard->currentSCCB;
22881da177e4SLinus Torvalds target = currSCCB->TargID;
228947b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][target];
22901da177e4SLinus Torvalds lastTag = CurrCard->tagQ_Lst;
22911da177e4SLinus Torvalds
22921da177e4SLinus Torvalds ARAM_ACCESS(port);
22931da177e4SLinus Torvalds
22941da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
22951da177e4SLinus Torvalds currSCCB->ControlByte &= ~F_USE_CMD_Q;
22961da177e4SLinus Torvalds
22971da177e4SLinus Torvalds if (((CurrCard->globalFlags & F_CONLUN_IO) &&
22981da177e4SLinus Torvalds ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
22991da177e4SLinus Torvalds
23001da177e4SLinus Torvalds lun = currSCCB->Lun;
23011da177e4SLinus Torvalds else
23021da177e4SLinus Torvalds lun = 0;
23031da177e4SLinus Torvalds
23045c04a7b8SAlexey Dobriyan if (CurrCard->globalFlags & F_TAG_STARTED) {
23055c04a7b8SAlexey Dobriyan if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
230647b5d69cSJames Bottomley if ((currTar_Info->TarLUN_CA == 0)
23071da177e4SLinus Torvalds && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
23085c04a7b8SAlexey Dobriyan == TAG_Q_TRYING)) {
23091da177e4SLinus Torvalds
23105c04a7b8SAlexey Dobriyan if (currTar_Info->TarTagQ_Cnt != 0) {
231147b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
231247b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card);
23131da177e4SLinus Torvalds SGRAM_ACCESS(port);
23141da177e4SLinus Torvalds return;
23151da177e4SLinus Torvalds }
23161da177e4SLinus Torvalds
23171da177e4SLinus Torvalds else {
231847b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
23191da177e4SLinus Torvalds }
23201da177e4SLinus Torvalds
23215c04a7b8SAlexey Dobriyan }
23225c04a7b8SAlexey Dobriyan /*End non-tagged */
23231da177e4SLinus Torvalds else {
232447b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
23251da177e4SLinus Torvalds }
23261da177e4SLinus Torvalds
23275c04a7b8SAlexey Dobriyan }
23285c04a7b8SAlexey Dobriyan /*!Use cmd Q Tagged */
23291da177e4SLinus Torvalds else {
23305c04a7b8SAlexey Dobriyan if (currTar_Info->TarLUN_CA == 1) {
233147b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card);
23321da177e4SLinus Torvalds SGRAM_ACCESS(port);
23331da177e4SLinus Torvalds return;
23341da177e4SLinus Torvalds }
23351da177e4SLinus Torvalds
233647b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
23371da177e4SLinus Torvalds
23381da177e4SLinus Torvalds } /*else use cmd Q tagged */
23391da177e4SLinus Torvalds
23405c04a7b8SAlexey Dobriyan }
23415c04a7b8SAlexey Dobriyan /*if glob tagged started */
23421da177e4SLinus Torvalds else {
234347b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
23441da177e4SLinus Torvalds }
23451da177e4SLinus Torvalds
23461da177e4SLinus Torvalds if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
23471da177e4SLinus Torvalds ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
23485c04a7b8SAlexey Dobriyan || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
23495c04a7b8SAlexey Dobriyan if (CurrCard->discQCount >= QUEUE_DEPTH) {
235047b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
235147b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card);
23521da177e4SLinus Torvalds SGRAM_ACCESS(port);
23531da177e4SLinus Torvalds return;
23541da177e4SLinus Torvalds }
23555c04a7b8SAlexey Dobriyan for (i = 1; i < QUEUE_DEPTH; i++) {
23565c04a7b8SAlexey Dobriyan if (++lastTag >= QUEUE_DEPTH)
23575c04a7b8SAlexey Dobriyan lastTag = 1;
23585c04a7b8SAlexey Dobriyan if (CurrCard->discQ_Tbl[lastTag] == NULL) {
23591da177e4SLinus Torvalds CurrCard->tagQ_Lst = lastTag;
23601da177e4SLinus Torvalds currTar_Info->LunDiscQ_Idx[lun] = lastTag;
23611da177e4SLinus Torvalds CurrCard->discQ_Tbl[lastTag] = currSCCB;
23621da177e4SLinus Torvalds CurrCard->discQCount++;
23631da177e4SLinus Torvalds break;
23641da177e4SLinus Torvalds }
23651da177e4SLinus Torvalds }
23665c04a7b8SAlexey Dobriyan if (i == QUEUE_DEPTH) {
236747b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
236847b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card);
23691da177e4SLinus Torvalds SGRAM_ACCESS(port);
23701da177e4SLinus Torvalds return;
23711da177e4SLinus Torvalds }
23721da177e4SLinus Torvalds }
23731da177e4SLinus Torvalds
237447b5d69cSJames Bottomley auto_loaded = 0;
23751da177e4SLinus Torvalds
23761da177e4SLinus Torvalds WR_HARPOON(port + hp_select_id, target);
23771da177e4SLinus Torvalds WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
23781da177e4SLinus Torvalds
23791da177e4SLinus Torvalds if (currSCCB->OperationCode == RESET_COMMAND) {
23801da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
23815c04a7b8SAlexey Dobriyan (currSCCB->
23825c04a7b8SAlexey Dobriyan Sccb_idmsg & ~DISC_PRIV)));
23831da177e4SLinus Torvalds
23841da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
23851da177e4SLinus Torvalds
2386a87afe28SHannes Reinecke currSCCB->Sccb_scsimsg = TARGET_RESET;
23871da177e4SLinus Torvalds
23881da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
238947b5d69cSJames Bottomley auto_loaded = 1;
23901da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_BDR_ST;
23911da177e4SLinus Torvalds
23925c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
23931da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0;
23941da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
23951da177e4SLinus Torvalds }
23961da177e4SLinus Torvalds
23975c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
23981da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
23991da177e4SLinus Torvalds }
24001da177e4SLinus Torvalds
240147b5d69cSJames Bottomley FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
240247b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, target);
24031da177e4SLinus Torvalds
24041da177e4SLinus Torvalds }
24051da177e4SLinus Torvalds
24065c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == ABORT_ST) {
24071da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
24085c04a7b8SAlexey Dobriyan (currSCCB->
24095c04a7b8SAlexey Dobriyan Sccb_idmsg & ~DISC_PRIV)));
24101da177e4SLinus Torvalds
24111da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
24121da177e4SLinus Torvalds
24131da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
24145c04a7b8SAlexey Dobriyan (((unsigned
24155c04a7b8SAlexey Dobriyan char)(currSCCB->
24165c04a7b8SAlexey Dobriyan ControlByte &
24175c04a7b8SAlexey Dobriyan TAG_TYPE_MASK)
24185c04a7b8SAlexey Dobriyan >> 6) | (unsigned char)
24195c04a7b8SAlexey Dobriyan 0x20)));
24201da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2),
24211da177e4SLinus Torvalds (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
24221da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
24231da177e4SLinus Torvalds
24241da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
242547b5d69cSJames Bottomley auto_loaded = 1;
24261da177e4SLinus Torvalds
24271da177e4SLinus Torvalds }
24281da177e4SLinus Torvalds
24291da177e4SLinus Torvalds else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
243047b5d69cSJames Bottomley auto_loaded = FPT_siwidn(port, p_card);
24311da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_WN_ST;
24321da177e4SLinus Torvalds }
24331da177e4SLinus Torvalds
24341da177e4SLinus Torvalds else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
24351da177e4SLinus Torvalds == SYNC_SUPPORTED)) {
243647b5d69cSJames Bottomley auto_loaded = FPT_sisyncn(port, p_card, 0);
24371da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_SN_ST;
24381da177e4SLinus Torvalds }
24391da177e4SLinus Torvalds
24405c04a7b8SAlexey Dobriyan if (!auto_loaded) {
24411da177e4SLinus Torvalds
24425c04a7b8SAlexey Dobriyan if (currSCCB->ControlByte & F_USE_CMD_Q) {
24431da177e4SLinus Torvalds
24441da177e4SLinus Torvalds CurrCard->globalFlags |= F_TAG_STARTED;
24451da177e4SLinus Torvalds
24461da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
24475c04a7b8SAlexey Dobriyan == TAG_Q_REJECT) {
24481da177e4SLinus Torvalds currSCCB->ControlByte &= ~F_USE_CMD_Q;
24491da177e4SLinus Torvalds
24501da177e4SLinus Torvalds /* Fix up the start instruction with a jump to
24511da177e4SLinus Torvalds Non-Tag-CMD handling */
24525c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT),
24535c04a7b8SAlexey Dobriyan BRH_OP + ALWAYS + NTCMD);
24541da177e4SLinus Torvalds
24551da177e4SLinus Torvalds WRW_HARPOON((port + NON_TAG_ID_MSG),
24565c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT +
24575c04a7b8SAlexey Dobriyan currSCCB->Sccb_idmsg));
24581da177e4SLinus Torvalds
24595c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3,
24605c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT));
24611da177e4SLinus Torvalds
246225985edcSLucas De Marchi /* Setup our STATE so we know what happened when
24631da177e4SLinus Torvalds the wheels fall off. */
24641da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_ST;
24651da177e4SLinus Torvalds
246647b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
24671da177e4SLinus Torvalds }
24681da177e4SLinus Torvalds
24695c04a7b8SAlexey Dobriyan else {
24705c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT),
24715c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT +
24725c04a7b8SAlexey Dobriyan currSCCB->Sccb_idmsg));
24731da177e4SLinus Torvalds
24745c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT + 2),
24755c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT +
24765c04a7b8SAlexey Dobriyan (((unsigned char)(currSCCB->
24775c04a7b8SAlexey Dobriyan ControlByte &
24785c04a7b8SAlexey Dobriyan TAG_TYPE_MASK)
2479db038cf8SAlexey Dobriyan >> 6) | (unsigned char)0x20)));
24801da177e4SLinus Torvalds
24815c04a7b8SAlexey Dobriyan for (i = 1; i < QUEUE_DEPTH; i++) {
24825c04a7b8SAlexey Dobriyan if (++lastTag >= QUEUE_DEPTH)
24835c04a7b8SAlexey Dobriyan lastTag = 1;
24845c04a7b8SAlexey Dobriyan if (CurrCard->discQ_Tbl[lastTag] ==
24855c04a7b8SAlexey Dobriyan NULL) {
24865c04a7b8SAlexey Dobriyan WRW_HARPOON((port +
24875c04a7b8SAlexey Dobriyan ID_MSG_STRT + 6),
24885c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT +
24895c04a7b8SAlexey Dobriyan lastTag));
24901da177e4SLinus Torvalds CurrCard->tagQ_Lst = lastTag;
24911da177e4SLinus Torvalds currSCCB->Sccb_tag = lastTag;
24925c04a7b8SAlexey Dobriyan CurrCard->discQ_Tbl[lastTag] =
24935c04a7b8SAlexey Dobriyan currSCCB;
24941da177e4SLinus Torvalds CurrCard->discQCount++;
24951da177e4SLinus Torvalds break;
24961da177e4SLinus Torvalds }
24971da177e4SLinus Torvalds }
24981da177e4SLinus Torvalds
24995c04a7b8SAlexey Dobriyan if (i == QUEUE_DEPTH) {
250047b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
250147b5d69cSJames Bottomley FPT_queueSelectFail(CurrCard, p_card);
25021da177e4SLinus Torvalds SGRAM_ACCESS(port);
25031da177e4SLinus Torvalds return;
25041da177e4SLinus Torvalds }
25051da177e4SLinus Torvalds
25061da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_Q_ST;
25071da177e4SLinus Torvalds
25085c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3,
25095c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT));
25101da177e4SLinus Torvalds }
25111da177e4SLinus Torvalds }
25121da177e4SLinus Torvalds
25135c04a7b8SAlexey Dobriyan else {
25141da177e4SLinus Torvalds
25155c04a7b8SAlexey Dobriyan WRW_HARPOON((port + ID_MSG_STRT),
25165c04a7b8SAlexey Dobriyan BRH_OP + ALWAYS + NTCMD);
25171da177e4SLinus Torvalds
25181da177e4SLinus Torvalds WRW_HARPOON((port + NON_TAG_ID_MSG),
25191da177e4SLinus Torvalds (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
25201da177e4SLinus Torvalds
25211da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_ST;
25221da177e4SLinus Torvalds
25235c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3,
25245c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT));
25251da177e4SLinus Torvalds }
25261da177e4SLinus Torvalds
2527db038cf8SAlexey Dobriyan theCCB = (unsigned char *)&currSCCB->Cdb[0];
25281da177e4SLinus Torvalds
25291da177e4SLinus Torvalds cdb_reg = port + CMD_STRT;
25301da177e4SLinus Torvalds
25315c04a7b8SAlexey Dobriyan for (i = 0; i < currSCCB->CdbLength; i++) {
25321da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
25331da177e4SLinus Torvalds cdb_reg += 2;
25341da177e4SLinus Torvalds theCCB++;
25351da177e4SLinus Torvalds }
25361da177e4SLinus Torvalds
25371da177e4SLinus Torvalds if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
25381da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
25391da177e4SLinus Torvalds
25405c04a7b8SAlexey Dobriyan }
25415c04a7b8SAlexey Dobriyan /* auto_loaded */
2542c823feebSAlexey Dobriyan WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
25431da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0x00);
25441da177e4SLinus Torvalds
25451da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
25461da177e4SLinus Torvalds
25471da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
25481da177e4SLinus Torvalds
25495c04a7b8SAlexey Dobriyan if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
25505c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_scsictrl_0,
25515c04a7b8SAlexey Dobriyan (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
25525c04a7b8SAlexey Dobriyan } else {
25531da177e4SLinus Torvalds
2554db038cf8SAlexey Dobriyan /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
25551da177e4SLinus Torvalds auto_loaded |= AUTO_IMMED; */
25561da177e4SLinus Torvalds auto_loaded = AUTO_IMMED;
25571da177e4SLinus Torvalds
25581da177e4SLinus Torvalds DISABLE_AUTO(port);
25591da177e4SLinus Torvalds
25601da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, auto_loaded);
25611da177e4SLinus Torvalds }
25621da177e4SLinus Torvalds
25631da177e4SLinus Torvalds SGRAM_ACCESS(port);
25641da177e4SLinus Torvalds }
25651da177e4SLinus Torvalds
25661da177e4SLinus Torvalds /*---------------------------------------------------------------------
25671da177e4SLinus Torvalds *
256847b5d69cSJames Bottomley * Function: FPT_sres
25691da177e4SLinus Torvalds *
25701da177e4SLinus Torvalds * Description: Hookup the correct CCB and handle the incoming messages.
25711da177e4SLinus Torvalds *
25721da177e4SLinus Torvalds *---------------------------------------------------------------------*/
25731da177e4SLinus Torvalds
FPT_sres(u32 port,unsigned char p_card,struct sccb_card * pCurrCard)2574391e2f25SKhalid Aziz static void FPT_sres(u32 port, unsigned char p_card,
25755c04a7b8SAlexey Dobriyan struct sccb_card *pCurrCard)
25761da177e4SLinus Torvalds {
25771da177e4SLinus Torvalds
2578db038cf8SAlexey Dobriyan unsigned char our_target, message, lun = 0, tag, msgRetryCount;
25791da177e4SLinus Torvalds
2580f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
258169eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
25821da177e4SLinus Torvalds
25835c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) {
25845c04a7b8SAlexey Dobriyan currTar_Info =
25855c04a7b8SAlexey Dobriyan &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
25861da177e4SLinus Torvalds DISABLE_AUTO(port);
25871da177e4SLinus Torvalds
25881da177e4SLinus Torvalds WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
25891da177e4SLinus Torvalds
25901da177e4SLinus Torvalds currSCCB = pCurrCard->currentSCCB;
25915c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
25921da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
25931da177e4SLinus Torvalds currSCCB->Sccb_scsistat = BUS_FREE_ST;
25941da177e4SLinus Torvalds }
25955c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
25961da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
25971da177e4SLinus Torvalds currSCCB->Sccb_scsistat = BUS_FREE_ST;
25981da177e4SLinus Torvalds }
25991da177e4SLinus Torvalds if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
26005c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
26015c04a7b8SAlexey Dobriyan TAG_Q_TRYING))) {
260247b5d69cSJames Bottomley currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
26035c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat != ABORT_ST) {
26041da177e4SLinus Torvalds pCurrCard->discQCount--;
26055c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->
26065c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->
26075c04a7b8SAlexey Dobriyan Lun]]
26081da177e4SLinus Torvalds = NULL;
26091da177e4SLinus Torvalds }
26105c04a7b8SAlexey Dobriyan } else {
261147b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 0;
26125c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) {
26135c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat != ABORT_ST) {
26141da177e4SLinus Torvalds pCurrCard->discQCount--;
26155c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currSCCB->
26165c04a7b8SAlexey Dobriyan Sccb_tag] = NULL;
26171da177e4SLinus Torvalds }
26185c04a7b8SAlexey Dobriyan } else {
26195c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat != ABORT_ST) {
26201da177e4SLinus Torvalds pCurrCard->discQCount--;
26215c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->
26225c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] =
26235c04a7b8SAlexey Dobriyan NULL;
26241da177e4SLinus Torvalds }
26251da177e4SLinus Torvalds }
26261da177e4SLinus Torvalds }
26271da177e4SLinus Torvalds
262847b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
26291da177e4SLinus Torvalds }
26301da177e4SLinus Torvalds
2631c823feebSAlexey Dobriyan WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
26321da177e4SLinus Torvalds
2633db038cf8SAlexey Dobriyan our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
263447b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
26351da177e4SLinus Torvalds
26361da177e4SLinus Torvalds msgRetryCount = 0;
26375c04a7b8SAlexey Dobriyan do {
26381da177e4SLinus Torvalds
263947b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
26401da177e4SLinus Torvalds tag = 0;
26411da177e4SLinus Torvalds
26425c04a7b8SAlexey Dobriyan while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
26435c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
26441da177e4SLinus Torvalds
26451da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE);
26461da177e4SLinus Torvalds return;
26471da177e4SLinus Torvalds }
26481da177e4SLinus Torvalds }
26491da177e4SLinus Torvalds
26501da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE);
26515c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
26521da177e4SLinus Torvalds
265347b5d69cSJames Bottomley message = FPT_sfm(port, pCurrCard->currentSCCB);
26545c04a7b8SAlexey Dobriyan if (message) {
26551da177e4SLinus Torvalds
26565c04a7b8SAlexey Dobriyan if (message <= (0x80 | LUN_MASK)) {
2657db038cf8SAlexey Dobriyan lun = message & (unsigned char)LUN_MASK;
26581da177e4SLinus Torvalds
26595c04a7b8SAlexey Dobriyan if ((currTar_Info->
26605c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) ==
26615c04a7b8SAlexey Dobriyan TAG_Q_TRYING) {
26625c04a7b8SAlexey Dobriyan if (currTar_Info->TarTagQ_Cnt !=
26635c04a7b8SAlexey Dobriyan 0) {
26641da177e4SLinus Torvalds
26655c04a7b8SAlexey Dobriyan if (!
26665c04a7b8SAlexey Dobriyan (currTar_Info->
26675c04a7b8SAlexey Dobriyan TarLUN_CA)) {
26681da177e4SLinus Torvalds ACCEPT_MSG(port); /*Release the ACK for ID msg. */
26691da177e4SLinus Torvalds
26705c04a7b8SAlexey Dobriyan message =
26715c04a7b8SAlexey Dobriyan FPT_sfm
26725c04a7b8SAlexey Dobriyan (port,
26735c04a7b8SAlexey Dobriyan pCurrCard->
26745c04a7b8SAlexey Dobriyan currentSCCB);
26755c04a7b8SAlexey Dobriyan if (message) {
26765c04a7b8SAlexey Dobriyan ACCEPT_MSG
26775c04a7b8SAlexey Dobriyan (port);
26781da177e4SLinus Torvalds }
26791da177e4SLinus Torvalds
26801da177e4SLinus Torvalds else
26815c04a7b8SAlexey Dobriyan message
26825c04a7b8SAlexey Dobriyan = 0;
26831da177e4SLinus Torvalds
26845c04a7b8SAlexey Dobriyan if (message !=
26855c04a7b8SAlexey Dobriyan 0) {
26865c04a7b8SAlexey Dobriyan tag =
26875c04a7b8SAlexey Dobriyan FPT_sfm
26885c04a7b8SAlexey Dobriyan (port,
26895c04a7b8SAlexey Dobriyan pCurrCard->
26905c04a7b8SAlexey Dobriyan currentSCCB);
26911da177e4SLinus Torvalds
26925c04a7b8SAlexey Dobriyan if (!
26935c04a7b8SAlexey Dobriyan (tag))
26945c04a7b8SAlexey Dobriyan message
26955c04a7b8SAlexey Dobriyan =
26965c04a7b8SAlexey Dobriyan 0;
26971da177e4SLinus Torvalds }
26981da177e4SLinus Torvalds
26995c04a7b8SAlexey Dobriyan }
27005c04a7b8SAlexey Dobriyan /*C.A. exists! */
27015c04a7b8SAlexey Dobriyan }
27025c04a7b8SAlexey Dobriyan /*End Q cnt != 0 */
27035c04a7b8SAlexey Dobriyan }
27045c04a7b8SAlexey Dobriyan /*End Tag cmds supported! */
27055c04a7b8SAlexey Dobriyan }
27065c04a7b8SAlexey Dobriyan /*End valid ID message. */
27075c04a7b8SAlexey Dobriyan else {
27081da177e4SLinus Torvalds
27091da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
27101da177e4SLinus Torvalds }
27111da177e4SLinus Torvalds
27125c04a7b8SAlexey Dobriyan }
27135c04a7b8SAlexey Dobriyan /* End good id message. */
27145c04a7b8SAlexey Dobriyan else {
27151da177e4SLinus Torvalds
271647b5d69cSJames Bottomley message = 0;
27171da177e4SLinus Torvalds }
27185c04a7b8SAlexey Dobriyan } else {
27191da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
27201da177e4SLinus Torvalds
27215c04a7b8SAlexey Dobriyan while (!
27225c04a7b8SAlexey Dobriyan (RDW_HARPOON((port + hp_intstat)) &
27235c04a7b8SAlexey Dobriyan (PHASE | RESET))
27245c04a7b8SAlexey Dobriyan && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
27255c04a7b8SAlexey Dobriyan && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
27261da177e4SLinus Torvalds
27271da177e4SLinus Torvalds return;
27281da177e4SLinus Torvalds }
27291da177e4SLinus Torvalds
27305c04a7b8SAlexey Dobriyan if (message == 0) {
27311da177e4SLinus Torvalds msgRetryCount++;
27325c04a7b8SAlexey Dobriyan if (msgRetryCount == 1) {
2733a87afe28SHannes Reinecke FPT_SendMsg(port, MSG_PARITY_ERROR);
27345c04a7b8SAlexey Dobriyan } else {
2735a87afe28SHannes Reinecke FPT_SendMsg(port, TARGET_RESET);
27361da177e4SLinus Torvalds
27375c04a7b8SAlexey Dobriyan FPT_sssyncv(port, our_target, NARROW_SCSI,
27385c04a7b8SAlexey Dobriyan currTar_Info);
27391da177e4SLinus Torvalds
27405c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][our_target].
27415c04a7b8SAlexey Dobriyan TarEEValue & EE_SYNC_MASK) {
27421da177e4SLinus Torvalds
27435c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][our_target].
27445c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_SYNC_MASK;
27451da177e4SLinus Torvalds
27461da177e4SLinus Torvalds }
27471da177e4SLinus Torvalds
27485c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][our_target].
27495c04a7b8SAlexey Dobriyan TarEEValue & EE_WIDE_SCSI) {
27501da177e4SLinus Torvalds
27515c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][our_target].
27525c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_WIDE_MASK;
27531da177e4SLinus Torvalds }
27541da177e4SLinus Torvalds
27555c04a7b8SAlexey Dobriyan FPT_queueFlushTargSccb(p_card, our_target,
27565c04a7b8SAlexey Dobriyan SCCB_COMPLETE);
275747b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, our_target);
27581da177e4SLinus Torvalds return;
27591da177e4SLinus Torvalds }
27601da177e4SLinus Torvalds }
276147b5d69cSJames Bottomley } while (message == 0);
27621da177e4SLinus Torvalds
27631da177e4SLinus Torvalds if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
27645c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
276547b5d69cSJames Bottomley currTar_Info->TarLUNBusy[lun] = 1;
27665c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB =
27675c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
27685c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) {
27691da177e4SLinus Torvalds ACCEPT_MSG(port);
27705c04a7b8SAlexey Dobriyan } else {
27711da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
27721da177e4SLinus Torvalds }
27735c04a7b8SAlexey Dobriyan } else {
277447b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 1;
27751da177e4SLinus Torvalds
27765c04a7b8SAlexey Dobriyan if (tag) {
27775c04a7b8SAlexey Dobriyan if (pCurrCard->discQ_Tbl[tag] != NULL) {
27785c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB =
27795c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[tag];
27801da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt--;
27811da177e4SLinus Torvalds ACCEPT_MSG(port);
27825c04a7b8SAlexey Dobriyan } else {
27831da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
27841da177e4SLinus Torvalds }
27855c04a7b8SAlexey Dobriyan } else {
27865c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB =
27875c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
27885c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) {
27891da177e4SLinus Torvalds ACCEPT_MSG(port);
27905c04a7b8SAlexey Dobriyan } else {
27911da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
27921da177e4SLinus Torvalds }
27931da177e4SLinus Torvalds }
27941da177e4SLinus Torvalds }
27951da177e4SLinus Torvalds
27965c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) {
27975c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
27981da177e4SLinus Torvalds /* During Abort Tag command, the target could have got re-selected
27991da177e4SLinus Torvalds and completed the command. Check the select Q and remove the CCB
28001da177e4SLinus Torvalds if it is in the Select Q */
280147b5d69cSJames Bottomley FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
28021da177e4SLinus Torvalds }
28031da177e4SLinus Torvalds }
28041da177e4SLinus Torvalds
28051da177e4SLinus Torvalds while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
28061da177e4SLinus Torvalds !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
28071da177e4SLinus Torvalds (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
28081da177e4SLinus Torvalds }
28091da177e4SLinus Torvalds
FPT_SendMsg(u32 port,unsigned char message)2810391e2f25SKhalid Aziz static void FPT_SendMsg(u32 port, unsigned char message)
28111da177e4SLinus Torvalds {
28125c04a7b8SAlexey Dobriyan while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
28135c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
28141da177e4SLinus Torvalds
28151da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE);
28161da177e4SLinus Torvalds return;
28171da177e4SLinus Torvalds }
28181da177e4SLinus Torvalds }
28191da177e4SLinus Torvalds
28201da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PHASE);
28215c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
28225c04a7b8SAlexey Dobriyan WRW_HARPOON((port + hp_intstat),
28235c04a7b8SAlexey Dobriyan (BUS_FREE | PHASE | XFER_CNT_0));
28241da177e4SLinus Torvalds
28251da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
28261da177e4SLinus Torvalds
28271da177e4SLinus Torvalds WR_HARPOON(port + hp_scsidata_0, message);
28281da177e4SLinus Torvalds
28291da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
28301da177e4SLinus Torvalds
28311da177e4SLinus Torvalds ACCEPT_MSG(port);
28321da177e4SLinus Torvalds
28331da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00);
28341da177e4SLinus Torvalds
2835a87afe28SHannes Reinecke if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
2836a87afe28SHannes Reinecke (message == ABORT_TASK)) {
28375c04a7b8SAlexey Dobriyan while (!
28385c04a7b8SAlexey Dobriyan (RDW_HARPOON((port + hp_intstat)) &
28395c04a7b8SAlexey Dobriyan (BUS_FREE | PHASE))) {
28405c04a7b8SAlexey Dobriyan }
28411da177e4SLinus Torvalds
28425c04a7b8SAlexey Dobriyan if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
28431da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), BUS_FREE);
28441da177e4SLinus Torvalds }
28451da177e4SLinus Torvalds }
28461da177e4SLinus Torvalds }
28471da177e4SLinus Torvalds }
28481da177e4SLinus Torvalds
28491da177e4SLinus Torvalds /*---------------------------------------------------------------------
28501da177e4SLinus Torvalds *
285147b5d69cSJames Bottomley * Function: FPT_sdecm
28521da177e4SLinus Torvalds *
285325985edcSLucas De Marchi * Description: Determine the proper response to the message from the
28541da177e4SLinus Torvalds * target device.
28551da177e4SLinus Torvalds *
28561da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_sdecm(unsigned char message,u32 port,unsigned char p_card)2857391e2f25SKhalid Aziz static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
28581da177e4SLinus Torvalds {
285969eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
286013e6851aSAlexey Dobriyan struct sccb_card *CurrCard;
2861f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
28621da177e4SLinus Torvalds
286347b5d69cSJames Bottomley CurrCard = &FPT_BL_Card[p_card];
28641da177e4SLinus Torvalds currSCCB = CurrCard->currentSCCB;
28651da177e4SLinus Torvalds
286647b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
28671da177e4SLinus Torvalds
2868a87afe28SHannes Reinecke if (message == RESTORE_POINTERS) {
28695c04a7b8SAlexey Dobriyan if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
28701da177e4SLinus Torvalds currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
28711da177e4SLinus Torvalds
287247b5d69cSJames Bottomley FPT_hostDataXferRestart(currSCCB);
28731da177e4SLinus Torvalds }
28741da177e4SLinus Torvalds
28751da177e4SLinus Torvalds ACCEPT_MSG(port);
28765c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
28775c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
28781da177e4SLinus Torvalds }
28791da177e4SLinus Torvalds
2880a87afe28SHannes Reinecke else if (message == COMMAND_COMPLETE) {
28811da177e4SLinus Torvalds
28825c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
28835c04a7b8SAlexey Dobriyan currTar_Info->TarStatus &=
28845c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_TAG_Q_MASK;
2885db038cf8SAlexey Dobriyan currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
28861da177e4SLinus Torvalds }
28871da177e4SLinus Torvalds
28881da177e4SLinus Torvalds ACCEPT_MSG(port);
28891da177e4SLinus Torvalds
28901da177e4SLinus Torvalds }
28911da177e4SLinus Torvalds
2892a87afe28SHannes Reinecke else if ((message == NOP) || (message >= IDENTIFY_BASE) ||
2893a87afe28SHannes Reinecke (message == INITIATE_RECOVERY) ||
2894a87afe28SHannes Reinecke (message == RELEASE_RECOVERY)) {
28951da177e4SLinus Torvalds
28961da177e4SLinus Torvalds ACCEPT_MSG(port);
28975c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
28985c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
28991da177e4SLinus Torvalds }
29001da177e4SLinus Torvalds
2901a87afe28SHannes Reinecke else if (message == MESSAGE_REJECT) {
29021da177e4SLinus Torvalds
29031da177e4SLinus Torvalds if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
29041da177e4SLinus Torvalds (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
29055c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
29065c04a7b8SAlexey Dobriyan || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
29075c04a7b8SAlexey Dobriyan TAG_Q_TRYING))
29081da177e4SLinus Torvalds {
29091da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), BUS_FREE);
29101da177e4SLinus Torvalds
29111da177e4SLinus Torvalds ACCEPT_MSG(port);
29121da177e4SLinus Torvalds
29131da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
29145c04a7b8SAlexey Dobriyan (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
29151da177e4SLinus Torvalds {
29161da177e4SLinus Torvalds }
29171da177e4SLinus Torvalds
29185c04a7b8SAlexey Dobriyan if (currSCCB->Lun == 0x00) {
2919adb11023SNathan Chancellor if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
29201da177e4SLinus Torvalds
29215c04a7b8SAlexey Dobriyan currTar_Info->TarStatus |=
29225c04a7b8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED;
29231da177e4SLinus Torvalds
29245c04a7b8SAlexey Dobriyan currTar_Info->TarEEValue &=
29255c04a7b8SAlexey Dobriyan ~EE_SYNC_MASK;
29265c04a7b8SAlexey Dobriyan }
29271da177e4SLinus Torvalds
2928adb11023SNathan Chancellor else if (currSCCB->Sccb_scsistat ==
2929adb11023SNathan Chancellor SELECT_WN_ST) {
29305c04a7b8SAlexey Dobriyan
29315c04a7b8SAlexey Dobriyan currTar_Info->TarStatus =
29325c04a7b8SAlexey Dobriyan (currTar_Info->
29335c04a7b8SAlexey Dobriyan TarStatus & ~WIDE_ENABLED) |
29345c04a7b8SAlexey Dobriyan WIDE_NEGOCIATED;
29355c04a7b8SAlexey Dobriyan
29365c04a7b8SAlexey Dobriyan currTar_Info->TarEEValue &=
29375c04a7b8SAlexey Dobriyan ~EE_WIDE_SCSI;
29381da177e4SLinus Torvalds
29391da177e4SLinus Torvalds }
29401da177e4SLinus Torvalds
29415c04a7b8SAlexey Dobriyan else if ((currTar_Info->
29425c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) ==
29435c04a7b8SAlexey Dobriyan TAG_Q_TRYING) {
29445c04a7b8SAlexey Dobriyan currTar_Info->TarStatus =
29455c04a7b8SAlexey Dobriyan (currTar_Info->
29465c04a7b8SAlexey Dobriyan TarStatus & ~(unsigned char)
29475c04a7b8SAlexey Dobriyan TAR_TAG_Q_MASK) | TAG_Q_REJECT;
29481da177e4SLinus Torvalds
29491da177e4SLinus Torvalds currSCCB->ControlByte &= ~F_USE_CMD_Q;
29501da177e4SLinus Torvalds CurrCard->discQCount--;
29515c04a7b8SAlexey Dobriyan CurrCard->discQ_Tbl[currSCCB->
29525c04a7b8SAlexey Dobriyan Sccb_tag] = NULL;
29531da177e4SLinus Torvalds currSCCB->Sccb_tag = 0x00;
29541da177e4SLinus Torvalds
29551da177e4SLinus Torvalds }
29561da177e4SLinus Torvalds }
29571da177e4SLinus Torvalds
29585c04a7b8SAlexey Dobriyan if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
29591da177e4SLinus Torvalds
29605c04a7b8SAlexey Dobriyan if (currSCCB->Lun == 0x00) {
29615c04a7b8SAlexey Dobriyan WRW_HARPOON((port + hp_intstat),
29625c04a7b8SAlexey Dobriyan BUS_FREE);
29631da177e4SLinus Torvalds CurrCard->globalFlags |= F_NEW_SCCB_CMD;
29641da177e4SLinus Torvalds }
29651da177e4SLinus Torvalds }
29661da177e4SLinus Torvalds
29675c04a7b8SAlexey Dobriyan else {
29681da177e4SLinus Torvalds
29691da177e4SLinus Torvalds if ((CurrCard->globalFlags & F_CONLUN_IO) &&
29705c04a7b8SAlexey Dobriyan ((currTar_Info->
29715c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) !=
29725c04a7b8SAlexey Dobriyan TAG_Q_TRYING))
29735c04a7b8SAlexey Dobriyan currTar_Info->TarLUNBusy[currSCCB->
29745c04a7b8SAlexey Dobriyan Lun] = 1;
29751da177e4SLinus Torvalds else
297647b5d69cSJames Bottomley currTar_Info->TarLUNBusy[0] = 1;
29771da177e4SLinus Torvalds
29785c04a7b8SAlexey Dobriyan currSCCB->ControlByte &=
29795c04a7b8SAlexey Dobriyan ~(unsigned char)F_USE_CMD_Q;
29801da177e4SLinus Torvalds
29815c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
29825c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
29831da177e4SLinus Torvalds
29841da177e4SLinus Torvalds }
29851da177e4SLinus Torvalds }
29861da177e4SLinus Torvalds
29875c04a7b8SAlexey Dobriyan else {
29881da177e4SLinus Torvalds ACCEPT_MSG(port);
29891da177e4SLinus Torvalds
29901da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
29915c04a7b8SAlexey Dobriyan (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
29921da177e4SLinus Torvalds {
29935c04a7b8SAlexey Dobriyan }
29945c04a7b8SAlexey Dobriyan
29955c04a7b8SAlexey Dobriyan if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
29965c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
29975c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
29981da177e4SLinus Torvalds }
29991da177e4SLinus Torvalds }
30001da177e4SLinus Torvalds }
30011da177e4SLinus Torvalds
3002a87afe28SHannes Reinecke else if (message == EXTENDED_MESSAGE) {
30031da177e4SLinus Torvalds
30041da177e4SLinus Torvalds ACCEPT_MSG(port);
300547b5d69cSJames Bottomley FPT_shandem(port, p_card, currSCCB);
30061da177e4SLinus Torvalds }
30071da177e4SLinus Torvalds
3008a87afe28SHannes Reinecke else if (message == IGNORE_WIDE_RESIDUE) {
30091da177e4SLinus Torvalds
30101da177e4SLinus Torvalds ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
30111da177e4SLinus Torvalds
301247b5d69cSJames Bottomley message = FPT_sfm(port, currSCCB);
30131da177e4SLinus Torvalds
3014a87afe28SHannes Reinecke if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
30151da177e4SLinus Torvalds ACCEPT_MSG(port);
30165c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
30175c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
30181da177e4SLinus Torvalds }
30191da177e4SLinus Torvalds
30205c04a7b8SAlexey Dobriyan else {
30211da177e4SLinus Torvalds
30221da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3023a87afe28SHannes Reinecke currSCCB->Sccb_scsimsg = MESSAGE_REJECT;
30241da177e4SLinus Torvalds
30251da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
30265c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
30275c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
30281da177e4SLinus Torvalds }
30291da177e4SLinus Torvalds }
30301da177e4SLinus Torvalds
30311da177e4SLinus Torvalds /*---------------------------------------------------------------------
30321da177e4SLinus Torvalds *
303347b5d69cSJames Bottomley * Function: FPT_shandem
30341da177e4SLinus Torvalds *
30351da177e4SLinus Torvalds * Description: Decide what to do with the extended message.
30361da177e4SLinus Torvalds *
30371da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_shandem(u32 port,unsigned char p_card,struct sccb * pCurrSCCB)3038391e2f25SKhalid Aziz static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
30391da177e4SLinus Torvalds {
3040db038cf8SAlexey Dobriyan unsigned char length, message;
30411da177e4SLinus Torvalds
304247b5d69cSJames Bottomley length = FPT_sfm(port, pCurrSCCB);
30435c04a7b8SAlexey Dobriyan if (length) {
30441da177e4SLinus Torvalds
30451da177e4SLinus Torvalds ACCEPT_MSG(port);
304647b5d69cSJames Bottomley message = FPT_sfm(port, pCurrSCCB);
30475c04a7b8SAlexey Dobriyan if (message) {
30481da177e4SLinus Torvalds
3049a87afe28SHannes Reinecke if (message == EXTENDED_SDTR) {
30501da177e4SLinus Torvalds
30515c04a7b8SAlexey Dobriyan if (length == 0x03) {
30521da177e4SLinus Torvalds
30531da177e4SLinus Torvalds ACCEPT_MSG(port);
305447b5d69cSJames Bottomley FPT_stsyncn(port, p_card);
30555c04a7b8SAlexey Dobriyan } else {
30561da177e4SLinus Torvalds
3057a87afe28SHannes Reinecke pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
30581da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
30591da177e4SLinus Torvalds }
3060a87afe28SHannes Reinecke } else if (message == EXTENDED_WDTR) {
30611da177e4SLinus Torvalds
30625c04a7b8SAlexey Dobriyan if (length == 0x02) {
30631da177e4SLinus Torvalds
30641da177e4SLinus Torvalds ACCEPT_MSG(port);
306547b5d69cSJames Bottomley FPT_stwidn(port, p_card);
30665c04a7b8SAlexey Dobriyan } else {
30671da177e4SLinus Torvalds
3068a87afe28SHannes Reinecke pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
30691da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
30701da177e4SLinus Torvalds
30715c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
30725c04a7b8SAlexey Dobriyan (AUTO_IMMED +
30735c04a7b8SAlexey Dobriyan DISCONNECT_START));
30741da177e4SLinus Torvalds }
30755c04a7b8SAlexey Dobriyan } else {
30761da177e4SLinus Torvalds
3077a87afe28SHannes Reinecke pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
30781da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
30791da177e4SLinus Torvalds
30805c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
30815c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
30821da177e4SLinus Torvalds }
30835c04a7b8SAlexey Dobriyan } else {
3084a87afe28SHannes Reinecke if (pCurrSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
30851da177e4SLinus Torvalds ACCEPT_MSG(port);
30865c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
30875c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
30881da177e4SLinus Torvalds }
30895c04a7b8SAlexey Dobriyan } else {
3090a87afe28SHannes Reinecke if (pCurrSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)
30915c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
30925c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
30931da177e4SLinus Torvalds }
30941da177e4SLinus Torvalds }
30951da177e4SLinus Torvalds
30961da177e4SLinus Torvalds /*---------------------------------------------------------------------
30971da177e4SLinus Torvalds *
309847b5d69cSJames Bottomley * Function: FPT_sisyncn
30991da177e4SLinus Torvalds *
31001da177e4SLinus Torvalds * Description: Read in a message byte from the SCSI bus, and check
31011da177e4SLinus Torvalds * for a parity error.
31021da177e4SLinus Torvalds *
31031da177e4SLinus Torvalds *---------------------------------------------------------------------*/
31041da177e4SLinus Torvalds
FPT_sisyncn(u32 port,unsigned char p_card,unsigned char syncFlag)3105391e2f25SKhalid Aziz static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
31065c04a7b8SAlexey Dobriyan unsigned char syncFlag)
31071da177e4SLinus Torvalds {
310869eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
3109f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
31101da177e4SLinus Torvalds
311147b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
311247b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
31131da177e4SLinus Torvalds
31141da177e4SLinus Torvalds if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
31151da177e4SLinus Torvalds
31161da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT),
31175c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT +
31185c04a7b8SAlexey Dobriyan (currSCCB->
31195c04a7b8SAlexey Dobriyan Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
31201da177e4SLinus Torvalds
31211da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
31221da177e4SLinus Torvalds
31235c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 0),
3124a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
31251da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
31265c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 4),
3127a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
31281da177e4SLinus Torvalds
31291da177e4SLinus Torvalds if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
31301da177e4SLinus Torvalds
31315c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6),
31325c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 12));
31331da177e4SLinus Torvalds
31345c04a7b8SAlexey Dobriyan else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
31355c04a7b8SAlexey Dobriyan EE_SYNC_10MB)
31361da177e4SLinus Torvalds
31375c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6),
31385c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 25));
31391da177e4SLinus Torvalds
31405c04a7b8SAlexey Dobriyan else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
31415c04a7b8SAlexey Dobriyan EE_SYNC_5MB)
31421da177e4SLinus Torvalds
31435c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6),
31445c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 50));
31451da177e4SLinus Torvalds
31461da177e4SLinus Torvalds else
31475c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 6),
31485c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + 00));
31491da177e4SLinus Torvalds
31501da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
31515c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 10),
31525c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
31531da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
31541da177e4SLinus Torvalds
31555c04a7b8SAlexey Dobriyan if (syncFlag == 0) {
31565c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3,
31575c04a7b8SAlexey Dobriyan (SELECT + SELCHK_STRT));
31585c04a7b8SAlexey Dobriyan currTar_Info->TarStatus =
31595c04a7b8SAlexey Dobriyan ((currTar_Info->
31605c04a7b8SAlexey Dobriyan TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
31615c04a7b8SAlexey Dobriyan (unsigned char)SYNC_TRYING);
31625c04a7b8SAlexey Dobriyan } else {
31635c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_3,
31645c04a7b8SAlexey Dobriyan (AUTO_IMMED + CMD_ONLY_STRT));
31651da177e4SLinus Torvalds }
31661da177e4SLinus Torvalds
31675c1b85e2SAlexey Dobriyan return 1;
31681da177e4SLinus Torvalds }
31691da177e4SLinus Torvalds
31701da177e4SLinus Torvalds else {
31711da177e4SLinus Torvalds
3172db038cf8SAlexey Dobriyan currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
31731da177e4SLinus Torvalds currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
31745c1b85e2SAlexey Dobriyan return 0;
31751da177e4SLinus Torvalds }
31761da177e4SLinus Torvalds }
31771da177e4SLinus Torvalds
31781da177e4SLinus Torvalds /*---------------------------------------------------------------------
31791da177e4SLinus Torvalds *
318047b5d69cSJames Bottomley * Function: FPT_stsyncn
31811da177e4SLinus Torvalds *
31821da177e4SLinus Torvalds * Description: The has sent us a Sync Nego message so handle it as
31831da177e4SLinus Torvalds * necessary.
31841da177e4SLinus Torvalds *
31851da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_stsyncn(u32 port,unsigned char p_card)3186391e2f25SKhalid Aziz static void FPT_stsyncn(u32 port, unsigned char p_card)
31871da177e4SLinus Torvalds {
3188db038cf8SAlexey Dobriyan unsigned char sync_msg, offset, sync_reg, our_sync_msg;
318969eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
3190f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
31911da177e4SLinus Torvalds
319247b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
319347b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
31941da177e4SLinus Torvalds
319547b5d69cSJames Bottomley sync_msg = FPT_sfm(port, currSCCB);
31961da177e4SLinus Torvalds
3197a87afe28SHannes Reinecke if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
31985c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
31995c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
32001da177e4SLinus Torvalds return;
32011da177e4SLinus Torvalds }
32021da177e4SLinus Torvalds
32031da177e4SLinus Torvalds ACCEPT_MSG(port);
32041da177e4SLinus Torvalds
320547b5d69cSJames Bottomley offset = FPT_sfm(port, currSCCB);
32061da177e4SLinus Torvalds
3207a87afe28SHannes Reinecke if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
32085c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
32095c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
32101da177e4SLinus Torvalds return;
32111da177e4SLinus Torvalds }
32121da177e4SLinus Torvalds
32131da177e4SLinus Torvalds if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
32141da177e4SLinus Torvalds
32151da177e4SLinus Torvalds our_sync_msg = 12; /* Setup our Message to 20mb/s */
32161da177e4SLinus Torvalds
32171da177e4SLinus Torvalds else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
32181da177e4SLinus Torvalds
32191da177e4SLinus Torvalds our_sync_msg = 25; /* Setup our Message to 10mb/s */
32201da177e4SLinus Torvalds
32211da177e4SLinus Torvalds else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
32221da177e4SLinus Torvalds
32231da177e4SLinus Torvalds our_sync_msg = 50; /* Setup our Message to 5mb/s */
32241da177e4SLinus Torvalds else
32251da177e4SLinus Torvalds
32261da177e4SLinus Torvalds our_sync_msg = 0; /* Message = Async */
32271da177e4SLinus Torvalds
32281da177e4SLinus Torvalds if (sync_msg < our_sync_msg) {
32291da177e4SLinus Torvalds sync_msg = our_sync_msg; /*if faster, then set to max. */
32301da177e4SLinus Torvalds }
32311da177e4SLinus Torvalds
32321da177e4SLinus Torvalds if (offset == ASYNC)
32331da177e4SLinus Torvalds sync_msg = ASYNC;
32341da177e4SLinus Torvalds
32351da177e4SLinus Torvalds if (offset > MAX_OFFSET)
32361da177e4SLinus Torvalds offset = MAX_OFFSET;
32371da177e4SLinus Torvalds
32381da177e4SLinus Torvalds sync_reg = 0x00;
32391da177e4SLinus Torvalds
32401da177e4SLinus Torvalds if (sync_msg > 12)
32411da177e4SLinus Torvalds
32421da177e4SLinus Torvalds sync_reg = 0x20; /* Use 10MB/s */
32431da177e4SLinus Torvalds
32441da177e4SLinus Torvalds if (sync_msg > 25)
32451da177e4SLinus Torvalds
32461da177e4SLinus Torvalds sync_reg = 0x40; /* Use 6.6MB/s */
32471da177e4SLinus Torvalds
32481da177e4SLinus Torvalds if (sync_msg > 38)
32491da177e4SLinus Torvalds
32501da177e4SLinus Torvalds sync_reg = 0x60; /* Use 5MB/s */
32511da177e4SLinus Torvalds
32521da177e4SLinus Torvalds if (sync_msg > 50)
32531da177e4SLinus Torvalds
32541da177e4SLinus Torvalds sync_reg = 0x80; /* Use 4MB/s */
32551da177e4SLinus Torvalds
32561da177e4SLinus Torvalds if (sync_msg > 62)
32571da177e4SLinus Torvalds
32581da177e4SLinus Torvalds sync_reg = 0xA0; /* Use 3.33MB/s */
32591da177e4SLinus Torvalds
32601da177e4SLinus Torvalds if (sync_msg > 75)
32611da177e4SLinus Torvalds
32621da177e4SLinus Torvalds sync_reg = 0xC0; /* Use 2.85MB/s */
32631da177e4SLinus Torvalds
32641da177e4SLinus Torvalds if (sync_msg > 87)
32651da177e4SLinus Torvalds
32661da177e4SLinus Torvalds sync_reg = 0xE0; /* Use 2.5MB/s */
32671da177e4SLinus Torvalds
32681da177e4SLinus Torvalds if (sync_msg > 100) {
32691da177e4SLinus Torvalds
32701da177e4SLinus Torvalds sync_reg = 0x00; /* Use ASYNC */
32711da177e4SLinus Torvalds offset = 0x00;
32721da177e4SLinus Torvalds }
32731da177e4SLinus Torvalds
32741da177e4SLinus Torvalds if (currTar_Info->TarStatus & WIDE_ENABLED)
32751da177e4SLinus Torvalds
32761da177e4SLinus Torvalds sync_reg |= offset;
32771da177e4SLinus Torvalds
32781da177e4SLinus Torvalds else
32791da177e4SLinus Torvalds
32801da177e4SLinus Torvalds sync_reg |= (offset | NARROW_SCSI);
32811da177e4SLinus Torvalds
328247b5d69cSJames Bottomley FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
32831da177e4SLinus Torvalds
32841da177e4SLinus Torvalds if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
32851da177e4SLinus Torvalds
32861da177e4SLinus Torvalds ACCEPT_MSG(port);
32871da177e4SLinus Torvalds
32881da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus &
32895c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_SYNC_MASK) |
32905c04a7b8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED);
32911da177e4SLinus Torvalds
32925c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
32935c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
32941da177e4SLinus Torvalds }
32951da177e4SLinus Torvalds
32961da177e4SLinus Torvalds else {
32971da177e4SLinus Torvalds
32981da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
32991da177e4SLinus Torvalds
330047b5d69cSJames Bottomley FPT_sisyncr(port, sync_msg, offset);
33011da177e4SLinus Torvalds
33021da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus &
33035c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_SYNC_MASK) |
33045c04a7b8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED);
33051da177e4SLinus Torvalds }
33061da177e4SLinus Torvalds }
33071da177e4SLinus Torvalds
33081da177e4SLinus Torvalds /*---------------------------------------------------------------------
33091da177e4SLinus Torvalds *
331047b5d69cSJames Bottomley * Function: FPT_sisyncr
33111da177e4SLinus Torvalds *
33121da177e4SLinus Torvalds * Description: Answer the targets sync message.
33131da177e4SLinus Torvalds *
33141da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_sisyncr(u32 port,unsigned char sync_pulse,unsigned char offset)3315391e2f25SKhalid Aziz static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
33165c04a7b8SAlexey Dobriyan unsigned char offset)
33171da177e4SLinus Torvalds {
33181da177e4SLinus Torvalds ARAM_ACCESS(port);
3319a87afe28SHannes Reinecke WRW_HARPOON((port + SYNC_MSGS + 0),
3320a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
33211da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3322a87afe28SHannes Reinecke WRW_HARPOON((port + SYNC_MSGS + 4),
3323a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
33241da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
33251da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
33261da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
33271da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
33281da177e4SLinus Torvalds SGRAM_ACCESS(port);
33291da177e4SLinus Torvalds
33301da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
33311da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
33321da177e4SLinus Torvalds
33331da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
33341da177e4SLinus Torvalds
33355c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
33361da177e4SLinus Torvalds }
33375c04a7b8SAlexey Dobriyan }
33381da177e4SLinus Torvalds
33391da177e4SLinus Torvalds /*---------------------------------------------------------------------
33401da177e4SLinus Torvalds *
334147b5d69cSJames Bottomley * Function: FPT_siwidn
33421da177e4SLinus Torvalds *
33431da177e4SLinus Torvalds * Description: Read in a message byte from the SCSI bus, and check
33441da177e4SLinus Torvalds * for a parity error.
33451da177e4SLinus Torvalds *
33461da177e4SLinus Torvalds *---------------------------------------------------------------------*/
33471da177e4SLinus Torvalds
FPT_siwidn(u32 port,unsigned char p_card)3348391e2f25SKhalid Aziz static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
33491da177e4SLinus Torvalds {
335069eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
3351f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
33521da177e4SLinus Torvalds
335347b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
335447b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
33551da177e4SLinus Torvalds
33561da177e4SLinus Torvalds if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
33571da177e4SLinus Torvalds
33581da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT),
33595c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT +
33605c04a7b8SAlexey Dobriyan (currSCCB->
33615c04a7b8SAlexey Dobriyan Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
33621da177e4SLinus Torvalds
33631da177e4SLinus Torvalds WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
33641da177e4SLinus Torvalds
33655c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 0),
3366a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
33671da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
33685c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 4),
3369a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
33701da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
33715c04a7b8SAlexey Dobriyan WRW_HARPOON((port + SYNC_MSGS + 8),
33725c04a7b8SAlexey Dobriyan (MPM_OP + AMSG_OUT + SM16BIT));
33731da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
33741da177e4SLinus Torvalds
33751da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
33761da177e4SLinus Torvalds
33771da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus &
33785c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_WIDE_MASK) |
33795c04a7b8SAlexey Dobriyan (unsigned char)WIDE_ENABLED);
33801da177e4SLinus Torvalds
33815c1b85e2SAlexey Dobriyan return 1;
33821da177e4SLinus Torvalds }
33831da177e4SLinus Torvalds
33841da177e4SLinus Torvalds else {
33851da177e4SLinus Torvalds
33861da177e4SLinus Torvalds currTar_Info->TarStatus = ((currTar_Info->TarStatus &
33875c04a7b8SAlexey Dobriyan ~(unsigned char)TAR_WIDE_MASK) |
33885c04a7b8SAlexey Dobriyan WIDE_NEGOCIATED);
33891da177e4SLinus Torvalds
33901da177e4SLinus Torvalds currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
33915c1b85e2SAlexey Dobriyan return 0;
33921da177e4SLinus Torvalds }
33931da177e4SLinus Torvalds }
33941da177e4SLinus Torvalds
33951da177e4SLinus Torvalds /*---------------------------------------------------------------------
33961da177e4SLinus Torvalds *
339747b5d69cSJames Bottomley * Function: FPT_stwidn
33981da177e4SLinus Torvalds *
33991da177e4SLinus Torvalds * Description: The has sent us a Wide Nego message so handle it as
34001da177e4SLinus Torvalds * necessary.
34011da177e4SLinus Torvalds *
34021da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_stwidn(u32 port,unsigned char p_card)3403391e2f25SKhalid Aziz static void FPT_stwidn(u32 port, unsigned char p_card)
34041da177e4SLinus Torvalds {
3405db038cf8SAlexey Dobriyan unsigned char width;
340669eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
3407f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
34081da177e4SLinus Torvalds
340947b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
341047b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
34111da177e4SLinus Torvalds
341247b5d69cSJames Bottomley width = FPT_sfm(port, currSCCB);
34131da177e4SLinus Torvalds
3414a87afe28SHannes Reinecke if ((width == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
34155c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
34165c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
34171da177e4SLinus Torvalds return;
34181da177e4SLinus Torvalds }
34191da177e4SLinus Torvalds
34201da177e4SLinus Torvalds if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
34211da177e4SLinus Torvalds width = 0;
34221da177e4SLinus Torvalds
34231da177e4SLinus Torvalds if (width) {
34241da177e4SLinus Torvalds currTar_Info->TarStatus |= WIDE_ENABLED;
34251da177e4SLinus Torvalds width = 0;
34265c04a7b8SAlexey Dobriyan } else {
34271da177e4SLinus Torvalds width = NARROW_SCSI;
34281da177e4SLinus Torvalds currTar_Info->TarStatus &= ~WIDE_ENABLED;
34291da177e4SLinus Torvalds }
34301da177e4SLinus Torvalds
343147b5d69cSJames Bottomley FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
34321da177e4SLinus Torvalds
34335c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
34341da177e4SLinus Torvalds
34351da177e4SLinus Torvalds currTar_Info->TarStatus |= WIDE_NEGOCIATED;
34361da177e4SLinus Torvalds
34375c04a7b8SAlexey Dobriyan if (!
34385c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
34395c04a7b8SAlexey Dobriyan SYNC_SUPPORTED)) {
34401da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
34411da177e4SLinus Torvalds ARAM_ACCESS(port);
344247b5d69cSJames Bottomley FPT_sisyncn(port, p_card, 1);
34431da177e4SLinus Torvalds currSCCB->Sccb_scsistat = SELECT_SN_ST;
34441da177e4SLinus Torvalds SGRAM_ACCESS(port);
34455c04a7b8SAlexey Dobriyan } else {
34461da177e4SLinus Torvalds ACCEPT_MSG(port);
34475c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
34485c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
34491da177e4SLinus Torvalds }
34501da177e4SLinus Torvalds }
34511da177e4SLinus Torvalds
34521da177e4SLinus Torvalds else {
34531da177e4SLinus Torvalds
34541da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
34551da177e4SLinus Torvalds
34561da177e4SLinus Torvalds if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
34571da177e4SLinus Torvalds width = SM16BIT;
34581da177e4SLinus Torvalds else
34591da177e4SLinus Torvalds width = SM8BIT;
34601da177e4SLinus Torvalds
346147b5d69cSJames Bottomley FPT_siwidr(port, width);
34621da177e4SLinus Torvalds
34631da177e4SLinus Torvalds currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
34641da177e4SLinus Torvalds }
34651da177e4SLinus Torvalds }
34661da177e4SLinus Torvalds
34671da177e4SLinus Torvalds /*---------------------------------------------------------------------
34681da177e4SLinus Torvalds *
346947b5d69cSJames Bottomley * Function: FPT_siwidr
34701da177e4SLinus Torvalds *
34711da177e4SLinus Torvalds * Description: Answer the targets Wide nego message.
34721da177e4SLinus Torvalds *
34731da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_siwidr(u32 port,unsigned char width)3474391e2f25SKhalid Aziz static void FPT_siwidr(u32 port, unsigned char width)
34751da177e4SLinus Torvalds {
34761da177e4SLinus Torvalds ARAM_ACCESS(port);
3477a87afe28SHannes Reinecke WRW_HARPOON((port + SYNC_MSGS + 0),
3478a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
34791da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3480a87afe28SHannes Reinecke WRW_HARPOON((port + SYNC_MSGS + 4),
3481a87afe28SHannes Reinecke (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
34821da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
34831da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
34841da177e4SLinus Torvalds WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
34851da177e4SLinus Torvalds SGRAM_ACCESS(port);
34861da177e4SLinus Torvalds
34871da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
34881da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
34891da177e4SLinus Torvalds
34901da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
34911da177e4SLinus Torvalds
34925c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
34931da177e4SLinus Torvalds }
34945c04a7b8SAlexey Dobriyan }
34951da177e4SLinus Torvalds
34961da177e4SLinus Torvalds /*---------------------------------------------------------------------
34971da177e4SLinus Torvalds *
349847b5d69cSJames Bottomley * Function: FPT_sssyncv
34991da177e4SLinus Torvalds *
35001da177e4SLinus Torvalds * Description: Write the desired value to the Sync Register for the
35011da177e4SLinus Torvalds * ID specified.
35021da177e4SLinus Torvalds *
35031da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_sssyncv(u32 p_port,unsigned char p_id,unsigned char p_sync_value,struct sccb_mgr_tar_info * currTar_Info)3504391e2f25SKhalid Aziz static void FPT_sssyncv(u32 p_port, unsigned char p_id,
35055c04a7b8SAlexey Dobriyan unsigned char p_sync_value,
3506f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info)
35071da177e4SLinus Torvalds {
3508db038cf8SAlexey Dobriyan unsigned char index;
35091da177e4SLinus Torvalds
35101da177e4SLinus Torvalds index = p_id;
35111da177e4SLinus Torvalds
35121da177e4SLinus Torvalds switch (index) {
35131da177e4SLinus Torvalds
35141da177e4SLinus Torvalds case 0:
35151da177e4SLinus Torvalds index = 12; /* hp_synctarg_0 */
35161da177e4SLinus Torvalds break;
35171da177e4SLinus Torvalds case 1:
35181da177e4SLinus Torvalds index = 13; /* hp_synctarg_1 */
35191da177e4SLinus Torvalds break;
35201da177e4SLinus Torvalds case 2:
35211da177e4SLinus Torvalds index = 14; /* hp_synctarg_2 */
35221da177e4SLinus Torvalds break;
35231da177e4SLinus Torvalds case 3:
35241da177e4SLinus Torvalds index = 15; /* hp_synctarg_3 */
35251da177e4SLinus Torvalds break;
35261da177e4SLinus Torvalds case 4:
35271da177e4SLinus Torvalds index = 8; /* hp_synctarg_4 */
35281da177e4SLinus Torvalds break;
35291da177e4SLinus Torvalds case 5:
35301da177e4SLinus Torvalds index = 9; /* hp_synctarg_5 */
35311da177e4SLinus Torvalds break;
35321da177e4SLinus Torvalds case 6:
35331da177e4SLinus Torvalds index = 10; /* hp_synctarg_6 */
35341da177e4SLinus Torvalds break;
35351da177e4SLinus Torvalds case 7:
35361da177e4SLinus Torvalds index = 11; /* hp_synctarg_7 */
35371da177e4SLinus Torvalds break;
35381da177e4SLinus Torvalds case 8:
35391da177e4SLinus Torvalds index = 4; /* hp_synctarg_8 */
35401da177e4SLinus Torvalds break;
35411da177e4SLinus Torvalds case 9:
35421da177e4SLinus Torvalds index = 5; /* hp_synctarg_9 */
35431da177e4SLinus Torvalds break;
35441da177e4SLinus Torvalds case 10:
35451da177e4SLinus Torvalds index = 6; /* hp_synctarg_10 */
35461da177e4SLinus Torvalds break;
35471da177e4SLinus Torvalds case 11:
35481da177e4SLinus Torvalds index = 7; /* hp_synctarg_11 */
35491da177e4SLinus Torvalds break;
35501da177e4SLinus Torvalds case 12:
35511da177e4SLinus Torvalds index = 0; /* hp_synctarg_12 */
35521da177e4SLinus Torvalds break;
35531da177e4SLinus Torvalds case 13:
35541da177e4SLinus Torvalds index = 1; /* hp_synctarg_13 */
35551da177e4SLinus Torvalds break;
35561da177e4SLinus Torvalds case 14:
35571da177e4SLinus Torvalds index = 2; /* hp_synctarg_14 */
35581da177e4SLinus Torvalds break;
35591da177e4SLinus Torvalds case 15:
35601da177e4SLinus Torvalds index = 3; /* hp_synctarg_15 */
35611da177e4SLinus Torvalds
35621da177e4SLinus Torvalds }
35631da177e4SLinus Torvalds
35641da177e4SLinus Torvalds WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
35651da177e4SLinus Torvalds
35661da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = p_sync_value;
35671da177e4SLinus Torvalds }
35681da177e4SLinus Torvalds
35691da177e4SLinus Torvalds /*---------------------------------------------------------------------
35701da177e4SLinus Torvalds *
357147b5d69cSJames Bottomley * Function: FPT_sresb
35721da177e4SLinus Torvalds *
35731da177e4SLinus Torvalds * Description: Reset the desired card's SCSI bus.
35741da177e4SLinus Torvalds *
35751da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_sresb(u32 port,unsigned char p_card)3576391e2f25SKhalid Aziz static void FPT_sresb(u32 port, unsigned char p_card)
35771da177e4SLinus Torvalds {
3578db038cf8SAlexey Dobriyan unsigned char scsiID, i;
35791da177e4SLinus Torvalds
3580f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
35811da177e4SLinus Torvalds
35821da177e4SLinus Torvalds WR_HARPOON(port + hp_page_ctrl,
35831da177e4SLinus Torvalds (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
35841da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
35851da177e4SLinus Torvalds
35861da177e4SLinus Torvalds WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
35871da177e4SLinus Torvalds
35881da177e4SLinus Torvalds scsiID = RD_HARPOON(port + hp_seltimeout);
35891da177e4SLinus Torvalds WR_HARPOON(port + hp_seltimeout, TO_5ms);
35901da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), TIMEOUT);
35911da177e4SLinus Torvalds
35921da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
35931da177e4SLinus Torvalds
35945c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
35955c04a7b8SAlexey Dobriyan }
35961da177e4SLinus Torvalds
35971da177e4SLinus Torvalds WR_HARPOON(port + hp_seltimeout, scsiID);
35981da177e4SLinus Torvalds
35991da177e4SLinus Torvalds WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
36001da177e4SLinus Torvalds
360147b5d69cSJames Bottomley FPT_Wait(port, TO_5ms);
36021da177e4SLinus Torvalds
36031da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
36041da177e4SLinus Torvalds
36051da177e4SLinus Torvalds WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
36061da177e4SLinus Torvalds
36075c04a7b8SAlexey Dobriyan for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
360847b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
36091da177e4SLinus Torvalds
36105c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
36111da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0;
36121da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
36131da177e4SLinus Torvalds }
36141da177e4SLinus Torvalds
36155c04a7b8SAlexey Dobriyan if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
36161da177e4SLinus Torvalds currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
36171da177e4SLinus Torvalds }
36181da177e4SLinus Torvalds
361947b5d69cSJames Bottomley FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
36201da177e4SLinus Torvalds
362147b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, scsiID);
36221da177e4SLinus Torvalds }
36231da177e4SLinus Torvalds
362447b5d69cSJames Bottomley FPT_BL_Card[p_card].scanIndex = 0x00;
362547b5d69cSJames Bottomley FPT_BL_Card[p_card].currentSCCB = NULL;
362647b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
36271da177e4SLinus Torvalds | F_NEW_SCCB_CMD);
362847b5d69cSJames Bottomley FPT_BL_Card[p_card].cmdCounter = 0x00;
362947b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount = 0x00;
363047b5d69cSJames Bottomley FPT_BL_Card[p_card].tagQ_Lst = 0x01;
36311da177e4SLinus Torvalds
36321da177e4SLinus Torvalds for (i = 0; i < QUEUE_DEPTH; i++)
363347b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
36341da177e4SLinus Torvalds
36351da177e4SLinus Torvalds WR_HARPOON(port + hp_page_ctrl,
36361da177e4SLinus Torvalds (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
36371da177e4SLinus Torvalds
36381da177e4SLinus Torvalds }
36391da177e4SLinus Torvalds
36401da177e4SLinus Torvalds /*---------------------------------------------------------------------
36411da177e4SLinus Torvalds *
364247b5d69cSJames Bottomley * Function: FPT_ssenss
36431da177e4SLinus Torvalds *
36441da177e4SLinus Torvalds * Description: Setup for the Auto Sense command.
36451da177e4SLinus Torvalds *
36461da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_ssenss(struct sccb_card * pCurrCard)364713e6851aSAlexey Dobriyan static void FPT_ssenss(struct sccb_card *pCurrCard)
36481da177e4SLinus Torvalds {
3649db038cf8SAlexey Dobriyan unsigned char i;
365069eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
36511da177e4SLinus Torvalds
36521da177e4SLinus Torvalds currSCCB = pCurrCard->currentSCCB;
36531da177e4SLinus Torvalds
36541da177e4SLinus Torvalds currSCCB->Save_CdbLen = currSCCB->CdbLength;
36551da177e4SLinus Torvalds
36561da177e4SLinus Torvalds for (i = 0; i < 6; i++) {
36571da177e4SLinus Torvalds
36581da177e4SLinus Torvalds currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
36591da177e4SLinus Torvalds }
36601da177e4SLinus Torvalds
36611da177e4SLinus Torvalds currSCCB->CdbLength = SIX_BYTE_CMD;
3662a87afe28SHannes Reinecke currSCCB->Cdb[0] = REQUEST_SENSE;
3663db038cf8SAlexey Dobriyan currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
36641da177e4SLinus Torvalds currSCCB->Cdb[2] = 0x00;
36651da177e4SLinus Torvalds currSCCB->Cdb[3] = 0x00;
36661da177e4SLinus Torvalds currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
36671da177e4SLinus Torvalds currSCCB->Cdb[5] = 0x00;
36681da177e4SLinus Torvalds
3669391e2f25SKhalid Aziz currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
36701da177e4SLinus Torvalds
36711da177e4SLinus Torvalds currSCCB->Sccb_ATC = 0x00;
36721da177e4SLinus Torvalds
36731da177e4SLinus Torvalds currSCCB->Sccb_XferState |= F_AUTO_SENSE;
36741da177e4SLinus Torvalds
36751da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~F_SG_XFER;
36761da177e4SLinus Torvalds
3677db038cf8SAlexey Dobriyan currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
36781da177e4SLinus Torvalds
36791da177e4SLinus Torvalds currSCCB->ControlByte = 0x00;
36801da177e4SLinus Torvalds
36811da177e4SLinus Torvalds currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
36821da177e4SLinus Torvalds }
36831da177e4SLinus Torvalds
36841da177e4SLinus Torvalds /*---------------------------------------------------------------------
36851da177e4SLinus Torvalds *
368647b5d69cSJames Bottomley * Function: FPT_sxfrp
36871da177e4SLinus Torvalds *
36881da177e4SLinus Torvalds * Description: Transfer data into the bit bucket until the device
36891da177e4SLinus Torvalds * decides to switch phase.
36901da177e4SLinus Torvalds *
36911da177e4SLinus Torvalds *---------------------------------------------------------------------*/
36921da177e4SLinus Torvalds
FPT_sxfrp(u32 p_port,unsigned char p_card)3693391e2f25SKhalid Aziz static void FPT_sxfrp(u32 p_port, unsigned char p_card)
36941da177e4SLinus Torvalds {
3695db038cf8SAlexey Dobriyan unsigned char curr_phz;
36961da177e4SLinus Torvalds
36971da177e4SLinus Torvalds DISABLE_AUTO(p_port);
36981da177e4SLinus Torvalds
369947b5d69cSJames Bottomley if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
37001da177e4SLinus Torvalds
37015c04a7b8SAlexey Dobriyan FPT_hostDataXferAbort(p_port, p_card,
37025c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].currentSCCB);
37031da177e4SLinus Torvalds
37041da177e4SLinus Torvalds }
37051da177e4SLinus Torvalds
37061da177e4SLinus Torvalds /* If the Automation handled the end of the transfer then do not
37071da177e4SLinus Torvalds match the phase or we will get out of sync with the ISR. */
37081da177e4SLinus Torvalds
37095c04a7b8SAlexey Dobriyan if (RDW_HARPOON((p_port + hp_intstat)) &
37105c04a7b8SAlexey Dobriyan (BUS_FREE | XFER_CNT_0 | AUTO_INT))
37111da177e4SLinus Torvalds return;
37121da177e4SLinus Torvalds
37131da177e4SLinus Torvalds WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
37141da177e4SLinus Torvalds
3715db038cf8SAlexey Dobriyan curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
37161da177e4SLinus Torvalds
37171da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
37181da177e4SLinus Torvalds
37191da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, curr_phz);
37201da177e4SLinus Torvalds
37211da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
37225c04a7b8SAlexey Dobriyan (curr_phz ==
37235c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
37241da177e4SLinus Torvalds {
37255c04a7b8SAlexey Dobriyan if (curr_phz & (unsigned char)SCSI_IOBIT) {
37265c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
37275c04a7b8SAlexey Dobriyan (SCSI_PORT | HOST_PORT | SCSI_INBIT));
37281da177e4SLinus Torvalds
37295c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
37301da177e4SLinus Torvalds RD_HARPOON(p_port + hp_fifodata_0);
37311da177e4SLinus Torvalds }
37325c04a7b8SAlexey Dobriyan } else {
37335c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
37345c04a7b8SAlexey Dobriyan (SCSI_PORT | HOST_PORT | HOST_WRT));
37355c04a7b8SAlexey Dobriyan if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
37361da177e4SLinus Torvalds WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
37371da177e4SLinus Torvalds }
37381da177e4SLinus Torvalds }
37391da177e4SLinus Torvalds } /* End of While loop for padding data I/O phase */
37401da177e4SLinus Torvalds
37415c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
37421da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
37431da177e4SLinus Torvalds break;
37441da177e4SLinus Torvalds }
37451da177e4SLinus Torvalds
37465c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
37475c04a7b8SAlexey Dobriyan (SCSI_PORT | HOST_PORT | SCSI_INBIT));
37485c04a7b8SAlexey Dobriyan while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
37491da177e4SLinus Torvalds RD_HARPOON(p_port + hp_fifodata_0);
37501da177e4SLinus Torvalds }
37511da177e4SLinus Torvalds
37525c04a7b8SAlexey Dobriyan if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
37535c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_autostart_0,
37545c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
37555c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
37561da177e4SLinus Torvalds }
37571da177e4SLinus Torvalds
37585c04a7b8SAlexey Dobriyan if (RDW_HARPOON((p_port + hp_intstat)) &
37595c04a7b8SAlexey Dobriyan (ICMD_COMP | ITAR_DISC))
37605c04a7b8SAlexey Dobriyan while (!
37615c04a7b8SAlexey Dobriyan (RDW_HARPOON((p_port + hp_intstat)) &
37625c04a7b8SAlexey Dobriyan (BUS_FREE | RSEL))) ;
37635c04a7b8SAlexey Dobriyan }
37645c04a7b8SAlexey Dobriyan }
37651da177e4SLinus Torvalds
37661da177e4SLinus Torvalds /*---------------------------------------------------------------------
37671da177e4SLinus Torvalds *
376847b5d69cSJames Bottomley * Function: FPT_schkdd
37691da177e4SLinus Torvalds *
37701da177e4SLinus Torvalds * Description: Make sure data has been flushed from both FIFOs and abort
37711da177e4SLinus Torvalds * the operations if necessary.
37721da177e4SLinus Torvalds *
37731da177e4SLinus Torvalds *---------------------------------------------------------------------*/
37741da177e4SLinus Torvalds
FPT_schkdd(u32 port,unsigned char p_card)3775391e2f25SKhalid Aziz static void FPT_schkdd(u32 port, unsigned char p_card)
37761da177e4SLinus Torvalds {
3777c823feebSAlexey Dobriyan unsigned short TimeOutLoop;
3778db038cf8SAlexey Dobriyan unsigned char sPhase;
37791da177e4SLinus Torvalds
378069eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
37811da177e4SLinus Torvalds
378247b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
37831da177e4SLinus Torvalds
37841da177e4SLinus Torvalds if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
37851da177e4SLinus Torvalds (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
37861da177e4SLinus Torvalds return;
37871da177e4SLinus Torvalds }
37881da177e4SLinus Torvalds
37895c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
37901da177e4SLinus Torvalds
37911da177e4SLinus Torvalds currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
37921da177e4SLinus Torvalds
37931da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 1;
37941da177e4SLinus Torvalds
37951da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3796c823feebSAlexey Dobriyan WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
37971da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0x00);
37981da177e4SLinus Torvalds }
37991da177e4SLinus Torvalds
38005c04a7b8SAlexey Dobriyan else {
38011da177e4SLinus Torvalds
38021da177e4SLinus Torvalds currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
38031da177e4SLinus Torvalds
38041da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 0;
38051da177e4SLinus Torvalds }
38061da177e4SLinus Torvalds
38071da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
38081da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE)) {
38091da177e4SLinus Torvalds
38101da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PARITY_ERR;
38111da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY);
38121da177e4SLinus Torvalds }
38131da177e4SLinus Torvalds
381447b5d69cSJames Bottomley FPT_hostDataXferAbort(port, p_card, currSCCB);
38151da177e4SLinus Torvalds
38165c04a7b8SAlexey Dobriyan while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
38175c04a7b8SAlexey Dobriyan }
38181da177e4SLinus Torvalds
38191da177e4SLinus Torvalds TimeOutLoop = 0;
38201da177e4SLinus Torvalds
38215c04a7b8SAlexey Dobriyan while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
38221da177e4SLinus Torvalds if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
38231da177e4SLinus Torvalds return;
38241da177e4SLinus Torvalds }
3825db038cf8SAlexey Dobriyan if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
38261da177e4SLinus Torvalds break;
38271da177e4SLinus Torvalds }
38281da177e4SLinus Torvalds if (RDW_HARPOON((port + hp_intstat)) & RESET) {
38291da177e4SLinus Torvalds return;
38301da177e4SLinus Torvalds }
38315c04a7b8SAlexey Dobriyan if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
38325c04a7b8SAlexey Dobriyan || (TimeOutLoop++ > 0x3000))
38331da177e4SLinus Torvalds break;
38341da177e4SLinus Torvalds }
38351da177e4SLinus Torvalds
38361da177e4SLinus Torvalds sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
38371da177e4SLinus Torvalds if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3838db038cf8SAlexey Dobriyan (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
38391da177e4SLinus Torvalds (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
38405c04a7b8SAlexey Dobriyan (sPhase == (SCSI_BSY | S_DATAI_PH))) {
38411da177e4SLinus Torvalds
38421da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
38431da177e4SLinus Torvalds
38445c04a7b8SAlexey Dobriyan if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
38451da177e4SLinus Torvalds if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
384647b5d69cSJames Bottomley FPT_phaseDataIn(port, p_card);
38471da177e4SLinus Torvalds }
38481da177e4SLinus Torvalds
38491da177e4SLinus Torvalds else {
385047b5d69cSJames Bottomley FPT_phaseDataOut(port, p_card);
38511da177e4SLinus Torvalds }
38525c04a7b8SAlexey Dobriyan } else {
385347b5d69cSJames Bottomley FPT_sxfrp(port, p_card);
38541da177e4SLinus Torvalds if (!(RDW_HARPOON((port + hp_intstat)) &
38555c04a7b8SAlexey Dobriyan (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
38561da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), AUTO_INT);
385747b5d69cSJames Bottomley FPT_phaseDecode(port, p_card);
38581da177e4SLinus Torvalds }
38591da177e4SLinus Torvalds }
38601da177e4SLinus Torvalds
38611da177e4SLinus Torvalds }
38621da177e4SLinus Torvalds
38631da177e4SLinus Torvalds else {
38641da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00);
38651da177e4SLinus Torvalds }
38661da177e4SLinus Torvalds }
38671da177e4SLinus Torvalds
38681da177e4SLinus Torvalds /*---------------------------------------------------------------------
38691da177e4SLinus Torvalds *
387047b5d69cSJames Bottomley * Function: FPT_sinits
38711da177e4SLinus Torvalds *
38721da177e4SLinus Torvalds * Description: Setup SCCB manager fields in this SCCB.
38731da177e4SLinus Torvalds *
38741da177e4SLinus Torvalds *---------------------------------------------------------------------*/
38751da177e4SLinus Torvalds
FPT_sinits(struct sccb * p_sccb,unsigned char p_card)387669eb2ea4SAlexey Dobriyan static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
38771da177e4SLinus Torvalds {
3878f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
38791da177e4SLinus Torvalds
38805d7ebb9cSDan Carpenter if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
38811da177e4SLinus Torvalds return;
38821da177e4SLinus Torvalds }
388347b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
38841da177e4SLinus Torvalds
38851da177e4SLinus Torvalds p_sccb->Sccb_XferState = 0x00;
38861da177e4SLinus Torvalds p_sccb->Sccb_XferCnt = p_sccb->DataLength;
38871da177e4SLinus Torvalds
38881da177e4SLinus Torvalds if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
38891da177e4SLinus Torvalds (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
38901da177e4SLinus Torvalds
38911da177e4SLinus Torvalds p_sccb->Sccb_SGoffset = 0;
38921da177e4SLinus Torvalds p_sccb->Sccb_XferState = F_SG_XFER;
38931da177e4SLinus Torvalds p_sccb->Sccb_XferCnt = 0x00;
38941da177e4SLinus Torvalds }
38951da177e4SLinus Torvalds
38961da177e4SLinus Torvalds if (p_sccb->DataLength == 0x00)
38971da177e4SLinus Torvalds
38981da177e4SLinus Torvalds p_sccb->Sccb_XferState |= F_ALL_XFERRED;
38991da177e4SLinus Torvalds
39005c04a7b8SAlexey Dobriyan if (p_sccb->ControlByte & F_USE_CMD_Q) {
39011da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
39021da177e4SLinus Torvalds p_sccb->ControlByte &= ~F_USE_CMD_Q;
39031da177e4SLinus Torvalds
39041da177e4SLinus Torvalds else
39051da177e4SLinus Torvalds currTar_Info->TarStatus |= TAG_Q_TRYING;
39061da177e4SLinus Torvalds }
39071da177e4SLinus Torvalds
39081da177e4SLinus Torvalds /* For !single SCSI device in system & device allow Disconnect
39091da177e4SLinus Torvalds or command is tag_q type then send Cmd with Disconnect Enable
39101da177e4SLinus Torvalds else send Cmd with Disconnect Disable */
39111da177e4SLinus Torvalds
39121da177e4SLinus Torvalds /*
391347b5d69cSJames Bottomley if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
39141da177e4SLinus Torvalds (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
39151da177e4SLinus Torvalds (currTar_Info->TarStatus & TAG_Q_TRYING)) {
39161da177e4SLinus Torvalds */
39171da177e4SLinus Torvalds if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
39181da177e4SLinus Torvalds (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3919a87afe28SHannes Reinecke p_sccb->Sccb_idmsg = IDENTIFY(true, p_sccb->Lun);
3920a87afe28SHannes Reinecke } else {
3921a87afe28SHannes Reinecke p_sccb->Sccb_idmsg = IDENTIFY(false, p_sccb->Lun);
39221da177e4SLinus Torvalds }
39231da177e4SLinus Torvalds
39241da177e4SLinus Torvalds p_sccb->HostStatus = 0x00;
39251da177e4SLinus Torvalds p_sccb->TargetStatus = 0x00;
39261da177e4SLinus Torvalds p_sccb->Sccb_tag = 0x00;
39271da177e4SLinus Torvalds p_sccb->Sccb_MGRFlags = 0x00;
39281da177e4SLinus Torvalds p_sccb->Sccb_sgseg = 0x00;
39291da177e4SLinus Torvalds p_sccb->Sccb_ATC = 0x00;
39301da177e4SLinus Torvalds p_sccb->Sccb_savedATC = 0x00;
39311da177e4SLinus Torvalds /*
39321da177e4SLinus Torvalds p_sccb->SccbVirtDataPtr = 0x00;
39331da177e4SLinus Torvalds p_sccb->Sccb_forwardlink = NULL;
39341da177e4SLinus Torvalds p_sccb->Sccb_backlink = NULL;
39351da177e4SLinus Torvalds */
39361da177e4SLinus Torvalds p_sccb->Sccb_scsistat = BUS_FREE_ST;
39371da177e4SLinus Torvalds p_sccb->SccbStatus = SCCB_IN_PROCESS;
3938a87afe28SHannes Reinecke p_sccb->Sccb_scsimsg = NOP;
39391da177e4SLinus Torvalds
39401da177e4SLinus Torvalds }
39411da177e4SLinus Torvalds
39421da177e4SLinus Torvalds /*---------------------------------------------------------------------
39431da177e4SLinus Torvalds *
39441da177e4SLinus Torvalds * Function: Phase Decode
39451da177e4SLinus Torvalds *
39461da177e4SLinus Torvalds * Description: Determine the phase and call the appropriate function.
39471da177e4SLinus Torvalds *
39481da177e4SLinus Torvalds *---------------------------------------------------------------------*/
39491da177e4SLinus Torvalds
FPT_phaseDecode(u32 p_port,unsigned char p_card)3950391e2f25SKhalid Aziz static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
39511da177e4SLinus Torvalds {
39521da177e4SLinus Torvalds unsigned char phase_ref;
3953391e2f25SKhalid Aziz void (*phase) (u32, unsigned char);
39541da177e4SLinus Torvalds
39551da177e4SLinus Torvalds DISABLE_AUTO(p_port);
39561da177e4SLinus Torvalds
39575c04a7b8SAlexey Dobriyan phase_ref =
39585c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
39591da177e4SLinus Torvalds
396047b5d69cSJames Bottomley phase = FPT_s_PhaseTbl[phase_ref];
39611da177e4SLinus Torvalds
39621da177e4SLinus Torvalds (*phase) (p_port, p_card); /* Call the correct phase func */
39631da177e4SLinus Torvalds }
39641da177e4SLinus Torvalds
39651da177e4SLinus Torvalds /*---------------------------------------------------------------------
39661da177e4SLinus Torvalds *
39671da177e4SLinus Torvalds * Function: Data Out Phase
39681da177e4SLinus Torvalds *
39691da177e4SLinus Torvalds * Description: Start up both the BusMaster and Xbow.
39701da177e4SLinus Torvalds *
39711da177e4SLinus Torvalds *---------------------------------------------------------------------*/
39721da177e4SLinus Torvalds
FPT_phaseDataOut(u32 port,unsigned char p_card)3973391e2f25SKhalid Aziz static void FPT_phaseDataOut(u32 port, unsigned char p_card)
39741da177e4SLinus Torvalds {
39751da177e4SLinus Torvalds
397669eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
39771da177e4SLinus Torvalds
397847b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
39795c04a7b8SAlexey Dobriyan if (currSCCB == NULL) {
39801da177e4SLinus Torvalds return; /* Exit if No SCCB record */
39811da177e4SLinus Torvalds }
39821da177e4SLinus Torvalds
39831da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DATA_OUT_ST;
39841da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
39851da177e4SLinus Torvalds
39861da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
39871da177e4SLinus Torvalds
39881da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
39891da177e4SLinus Torvalds
39901da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
39911da177e4SLinus Torvalds
399247b5d69cSJames Bottomley FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
39931da177e4SLinus Torvalds
39941da177e4SLinus Torvalds if (currSCCB->Sccb_XferCnt == 0) {
39951da177e4SLinus Torvalds
39961da177e4SLinus Torvalds if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
39971da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE))
39981da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
39991da177e4SLinus Torvalds
400047b5d69cSJames Bottomley FPT_sxfrp(port, p_card);
40011da177e4SLinus Torvalds if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
400247b5d69cSJames Bottomley FPT_phaseDecode(port, p_card);
40031da177e4SLinus Torvalds }
40041da177e4SLinus Torvalds }
40051da177e4SLinus Torvalds
40061da177e4SLinus Torvalds /*---------------------------------------------------------------------
40071da177e4SLinus Torvalds *
40081da177e4SLinus Torvalds * Function: Data In Phase
40091da177e4SLinus Torvalds *
40101da177e4SLinus Torvalds * Description: Startup the BusMaster and the XBOW.
40111da177e4SLinus Torvalds *
40121da177e4SLinus Torvalds *---------------------------------------------------------------------*/
40131da177e4SLinus Torvalds
FPT_phaseDataIn(u32 port,unsigned char p_card)4014391e2f25SKhalid Aziz static void FPT_phaseDataIn(u32 port, unsigned char p_card)
40151da177e4SLinus Torvalds {
40161da177e4SLinus Torvalds
401769eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
40181da177e4SLinus Torvalds
401947b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
40201da177e4SLinus Torvalds
40215c04a7b8SAlexey Dobriyan if (currSCCB == NULL) {
40221da177e4SLinus Torvalds return; /* Exit if No SCCB record */
40231da177e4SLinus Torvalds }
40241da177e4SLinus Torvalds
40251da177e4SLinus Torvalds currSCCB->Sccb_scsistat = DATA_IN_ST;
40261da177e4SLinus Torvalds currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
40271da177e4SLinus Torvalds currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
40281da177e4SLinus Torvalds
40291da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
40301da177e4SLinus Torvalds
40311da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
40321da177e4SLinus Torvalds
40331da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
40341da177e4SLinus Torvalds
403547b5d69cSJames Bottomley FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
40361da177e4SLinus Torvalds
40371da177e4SLinus Torvalds if (currSCCB->Sccb_XferCnt == 0) {
40381da177e4SLinus Torvalds
40391da177e4SLinus Torvalds if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
40401da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE))
40411da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
40421da177e4SLinus Torvalds
404347b5d69cSJames Bottomley FPT_sxfrp(port, p_card);
40441da177e4SLinus Torvalds if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
404547b5d69cSJames Bottomley FPT_phaseDecode(port, p_card);
40461da177e4SLinus Torvalds
40471da177e4SLinus Torvalds }
40481da177e4SLinus Torvalds }
40491da177e4SLinus Torvalds
40501da177e4SLinus Torvalds /*---------------------------------------------------------------------
40511da177e4SLinus Torvalds *
40521da177e4SLinus Torvalds * Function: Command Phase
40531da177e4SLinus Torvalds *
40541da177e4SLinus Torvalds * Description: Load the CDB into the automation and start it up.
40551da177e4SLinus Torvalds *
40561da177e4SLinus Torvalds *---------------------------------------------------------------------*/
40571da177e4SLinus Torvalds
FPT_phaseCommand(u32 p_port,unsigned char p_card)4058391e2f25SKhalid Aziz static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
40591da177e4SLinus Torvalds {
406069eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
4061391e2f25SKhalid Aziz u32 cdb_reg;
4062db038cf8SAlexey Dobriyan unsigned char i;
40631da177e4SLinus Torvalds
406447b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
40651da177e4SLinus Torvalds
40661da177e4SLinus Torvalds if (currSCCB->OperationCode == RESET_COMMAND) {
40671da177e4SLinus Torvalds
40681da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
40691da177e4SLinus Torvalds currSCCB->CdbLength = SIX_BYTE_CMD;
40701da177e4SLinus Torvalds }
40711da177e4SLinus Torvalds
40721da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, 0x00);
40731da177e4SLinus Torvalds
40741da177e4SLinus Torvalds ARAM_ACCESS(p_port);
40751da177e4SLinus Torvalds
40761da177e4SLinus Torvalds cdb_reg = p_port + CMD_STRT;
40771da177e4SLinus Torvalds
40781da177e4SLinus Torvalds for (i = 0; i < currSCCB->CdbLength; i++) {
40791da177e4SLinus Torvalds
40801da177e4SLinus Torvalds if (currSCCB->OperationCode == RESET_COMMAND)
40811da177e4SLinus Torvalds
40821da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
40831da177e4SLinus Torvalds
40841da177e4SLinus Torvalds else
40855c04a7b8SAlexey Dobriyan WRW_HARPOON(cdb_reg,
40865c04a7b8SAlexey Dobriyan (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
40871da177e4SLinus Torvalds cdb_reg += 2;
40881da177e4SLinus Torvalds }
40891da177e4SLinus Torvalds
40901da177e4SLinus Torvalds if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
40911da177e4SLinus Torvalds WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
40921da177e4SLinus Torvalds
40931da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
40941da177e4SLinus Torvalds
40951da177e4SLinus Torvalds currSCCB->Sccb_scsistat = COMMAND_ST;
40961da177e4SLinus Torvalds
40971da177e4SLinus Torvalds WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
40981da177e4SLinus Torvalds SGRAM_ACCESS(p_port);
40991da177e4SLinus Torvalds }
41001da177e4SLinus Torvalds
41011da177e4SLinus Torvalds /*---------------------------------------------------------------------
41021da177e4SLinus Torvalds *
41031da177e4SLinus Torvalds * Function: Status phase
41041da177e4SLinus Torvalds *
41051da177e4SLinus Torvalds * Description: Bring in the status and command complete message bytes
41061da177e4SLinus Torvalds *
41071da177e4SLinus Torvalds *---------------------------------------------------------------------*/
41081da177e4SLinus Torvalds
FPT_phaseStatus(u32 port,unsigned char p_card)4109391e2f25SKhalid Aziz static void FPT_phaseStatus(u32 port, unsigned char p_card)
41101da177e4SLinus Torvalds {
41111da177e4SLinus Torvalds /* Start-up the automation to finish off this command and let the
41121da177e4SLinus Torvalds isr handle the interrupt for command complete when it comes in.
41131da177e4SLinus Torvalds We could wait here for the interrupt to be generated?
41141da177e4SLinus Torvalds */
41151da177e4SLinus Torvalds
41161da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, 0x00);
41171da177e4SLinus Torvalds
41181da177e4SLinus Torvalds WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
41191da177e4SLinus Torvalds }
41201da177e4SLinus Torvalds
41211da177e4SLinus Torvalds /*---------------------------------------------------------------------
41221da177e4SLinus Torvalds *
41231da177e4SLinus Torvalds * Function: Phase Message Out
41241da177e4SLinus Torvalds *
41251da177e4SLinus Torvalds * Description: Send out our message (if we have one) and handle whatever
41261da177e4SLinus Torvalds * else is involed.
41271da177e4SLinus Torvalds *
41281da177e4SLinus Torvalds *---------------------------------------------------------------------*/
41291da177e4SLinus Torvalds
FPT_phaseMsgOut(u32 port,unsigned char p_card)4130391e2f25SKhalid Aziz static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
41311da177e4SLinus Torvalds {
4132db038cf8SAlexey Dobriyan unsigned char message, scsiID;
413369eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
4134f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
41351da177e4SLinus Torvalds
413647b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
41371da177e4SLinus Torvalds
41381da177e4SLinus Torvalds if (currSCCB != NULL) {
41391da177e4SLinus Torvalds
41401da177e4SLinus Torvalds message = currSCCB->Sccb_scsimsg;
41411da177e4SLinus Torvalds scsiID = currSCCB->TargID;
41421da177e4SLinus Torvalds
4143a87afe28SHannes Reinecke if (message == TARGET_RESET) {
41441da177e4SLinus Torvalds
414547b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
41461da177e4SLinus Torvalds currTar_Info->TarSyncCtrl = 0;
414747b5d69cSJames Bottomley FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
41481da177e4SLinus Torvalds
41495c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][scsiID].
41505c04a7b8SAlexey Dobriyan TarEEValue & EE_SYNC_MASK) {
41511da177e4SLinus Torvalds
41525c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
41535c04a7b8SAlexey Dobriyan ~TAR_SYNC_MASK;
41541da177e4SLinus Torvalds
41551da177e4SLinus Torvalds }
41561da177e4SLinus Torvalds
41575c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][scsiID].
41585c04a7b8SAlexey Dobriyan TarEEValue & EE_WIDE_SCSI) {
41591da177e4SLinus Torvalds
41605c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
41615c04a7b8SAlexey Dobriyan ~TAR_WIDE_MASK;
41621da177e4SLinus Torvalds }
41631da177e4SLinus Torvalds
416447b5d69cSJames Bottomley FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
416547b5d69cSJames Bottomley FPT_SccbMgrTableInitTarget(p_card, scsiID);
41665c04a7b8SAlexey Dobriyan } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
41671da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_COMPLETE;
41685c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
41695c04a7b8SAlexey Dobriyan NULL) {
41705c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
41715c04a7b8SAlexey Dobriyan Sccb_tag] = NULL;
417247b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
41731da177e4SLinus Torvalds }
41741da177e4SLinus Torvalds
41751da177e4SLinus Torvalds }
41761da177e4SLinus Torvalds
41775c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
41781da177e4SLinus Torvalds
4179a87afe28SHannes Reinecke if (message == NOP) {
41801da177e4SLinus Torvalds currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
41811da177e4SLinus Torvalds
418247b5d69cSJames Bottomley FPT_ssel(port, p_card);
41831da177e4SLinus Torvalds return;
41841da177e4SLinus Torvalds }
41855c04a7b8SAlexey Dobriyan } else {
41861da177e4SLinus Torvalds
4187a87afe28SHannes Reinecke if (message == ABORT_TASK_SET)
41881da177e4SLinus Torvalds
418947b5d69cSJames Bottomley FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
41901da177e4SLinus Torvalds }
41911da177e4SLinus Torvalds
41925c04a7b8SAlexey Dobriyan } else {
4193a87afe28SHannes Reinecke message = ABORT_TASK_SET;
41941da177e4SLinus Torvalds }
41951da177e4SLinus Torvalds
41961da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
41971da177e4SLinus Torvalds
41981da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
41991da177e4SLinus Torvalds
42001da177e4SLinus Torvalds WR_HARPOON(port + hp_scsidata_0, message);
42011da177e4SLinus Torvalds
42021da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
42031da177e4SLinus Torvalds
42041da177e4SLinus Torvalds ACCEPT_MSG(port);
42051da177e4SLinus Torvalds
42061da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00);
42071da177e4SLinus Torvalds
4208a87afe28SHannes Reinecke if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
4209a87afe28SHannes Reinecke (message == ABORT_TASK)) {
42101da177e4SLinus Torvalds
42115c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
42125c04a7b8SAlexey Dobriyan }
42131da177e4SLinus Torvalds
42145c04a7b8SAlexey Dobriyan if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
42151da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), BUS_FREE);
42161da177e4SLinus Torvalds
42175c04a7b8SAlexey Dobriyan if (currSCCB != NULL) {
42181da177e4SLinus Torvalds
42195c04a7b8SAlexey Dobriyan if ((FPT_BL_Card[p_card].
42205c04a7b8SAlexey Dobriyan globalFlags & F_CONLUN_IO)
42215c04a7b8SAlexey Dobriyan &&
42225c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
42235c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) !=
42245c04a7b8SAlexey Dobriyan TAG_Q_TRYING))
42255c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->
42265c04a7b8SAlexey Dobriyan TargID].
42275c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 0;
42281da177e4SLinus Torvalds else
42295c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->
42305c04a7b8SAlexey Dobriyan TargID].
42315c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 0;
42321da177e4SLinus Torvalds
42335c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card],
42345c04a7b8SAlexey Dobriyan currSCCB, p_card);
42351da177e4SLinus Torvalds }
42361da177e4SLinus Torvalds
42375c04a7b8SAlexey Dobriyan else {
42385c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |=
42395c04a7b8SAlexey Dobriyan F_NEW_SCCB_CMD;
42401da177e4SLinus Torvalds }
42411da177e4SLinus Torvalds }
42421da177e4SLinus Torvalds
42435c04a7b8SAlexey Dobriyan else {
42441da177e4SLinus Torvalds
424547b5d69cSJames Bottomley FPT_sxfrp(port, p_card);
42461da177e4SLinus Torvalds }
42471da177e4SLinus Torvalds }
42481da177e4SLinus Torvalds
42495c04a7b8SAlexey Dobriyan else {
42501da177e4SLinus Torvalds
4251a87afe28SHannes Reinecke if (message == MSG_PARITY_ERROR) {
4252a87afe28SHannes Reinecke currSCCB->Sccb_scsimsg = NOP;
42535c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
42545c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
42555c04a7b8SAlexey Dobriyan } else {
425647b5d69cSJames Bottomley FPT_sxfrp(port, p_card);
42571da177e4SLinus Torvalds }
42581da177e4SLinus Torvalds }
42591da177e4SLinus Torvalds }
42601da177e4SLinus Torvalds
42611da177e4SLinus Torvalds /*---------------------------------------------------------------------
42621da177e4SLinus Torvalds *
42631da177e4SLinus Torvalds * Function: Message In phase
42641da177e4SLinus Torvalds *
42651da177e4SLinus Torvalds * Description: Bring in the message and determine what to do with it.
42661da177e4SLinus Torvalds *
42671da177e4SLinus Torvalds *---------------------------------------------------------------------*/
42681da177e4SLinus Torvalds
FPT_phaseMsgIn(u32 port,unsigned char p_card)4269391e2f25SKhalid Aziz static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
42701da177e4SLinus Torvalds {
4271db038cf8SAlexey Dobriyan unsigned char message;
427269eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
42731da177e4SLinus Torvalds
427447b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
42751da177e4SLinus Torvalds
42765c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
42771da177e4SLinus Torvalds
427847b5d69cSJames Bottomley FPT_phaseChkFifo(port, p_card);
42791da177e4SLinus Torvalds }
42801da177e4SLinus Torvalds
42811da177e4SLinus Torvalds message = RD_HARPOON(port + hp_scsidata_0);
4282a87afe28SHannes Reinecke if ((message == DISCONNECT) || (message == SAVE_POINTERS)) {
42831da177e4SLinus Torvalds
42845c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
42855c04a7b8SAlexey Dobriyan (AUTO_IMMED + END_DATA_START));
42861da177e4SLinus Torvalds
42871da177e4SLinus Torvalds }
42881da177e4SLinus Torvalds
42895c04a7b8SAlexey Dobriyan else {
42901da177e4SLinus Torvalds
429147b5d69cSJames Bottomley message = FPT_sfm(port, currSCCB);
42925c04a7b8SAlexey Dobriyan if (message) {
42931da177e4SLinus Torvalds
429447b5d69cSJames Bottomley FPT_sdecm(message, port, p_card);
42951da177e4SLinus Torvalds
42965c04a7b8SAlexey Dobriyan } else {
4297a87afe28SHannes Reinecke if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
42981da177e4SLinus Torvalds ACCEPT_MSG(port);
42995c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_autostart_1,
43005c04a7b8SAlexey Dobriyan (AUTO_IMMED + DISCONNECT_START));
43011da177e4SLinus Torvalds }
43021da177e4SLinus Torvalds }
43031da177e4SLinus Torvalds
43041da177e4SLinus Torvalds }
43051da177e4SLinus Torvalds
43061da177e4SLinus Torvalds /*---------------------------------------------------------------------
43071da177e4SLinus Torvalds *
43081da177e4SLinus Torvalds * Function: Illegal phase
43091da177e4SLinus Torvalds *
43101da177e4SLinus Torvalds * Description: Target switched to some illegal phase, so all we can do
43111da177e4SLinus Torvalds * is report an error back to the host (if that is possible)
43121da177e4SLinus Torvalds * and send an ABORT message to the misbehaving target.
43131da177e4SLinus Torvalds *
43141da177e4SLinus Torvalds *---------------------------------------------------------------------*/
43151da177e4SLinus Torvalds
FPT_phaseIllegal(u32 port,unsigned char p_card)4316391e2f25SKhalid Aziz static void FPT_phaseIllegal(u32 port, unsigned char p_card)
43171da177e4SLinus Torvalds {
431869eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
43191da177e4SLinus Torvalds
432047b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
43211da177e4SLinus Torvalds
43221da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
43231da177e4SLinus Torvalds if (currSCCB != NULL) {
43241da177e4SLinus Torvalds
43251da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
43261da177e4SLinus Torvalds currSCCB->Sccb_scsistat = ABORT_ST;
4327a87afe28SHannes Reinecke currSCCB->Sccb_scsimsg = ABORT_TASK_SET;
43281da177e4SLinus Torvalds }
43291da177e4SLinus Torvalds
43301da177e4SLinus Torvalds ACCEPT_MSG_ATN(port);
43311da177e4SLinus Torvalds }
43321da177e4SLinus Torvalds
43331da177e4SLinus Torvalds /*---------------------------------------------------------------------
43341da177e4SLinus Torvalds *
43351da177e4SLinus Torvalds * Function: Phase Check FIFO
43361da177e4SLinus Torvalds *
43371da177e4SLinus Torvalds * Description: Make sure data has been flushed from both FIFOs and abort
43381da177e4SLinus Torvalds * the operations if necessary.
43391da177e4SLinus Torvalds *
43401da177e4SLinus Torvalds *---------------------------------------------------------------------*/
43411da177e4SLinus Torvalds
FPT_phaseChkFifo(u32 port,unsigned char p_card)4342391e2f25SKhalid Aziz static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
43431da177e4SLinus Torvalds {
4344391e2f25SKhalid Aziz u32 xfercnt;
434569eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
43461da177e4SLinus Torvalds
434747b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
43481da177e4SLinus Torvalds
43495c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
43501da177e4SLinus Torvalds
43511da177e4SLinus Torvalds while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
43525c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
43535c04a7b8SAlexey Dobriyan }
43541da177e4SLinus Torvalds
43555c04a7b8SAlexey Dobriyan if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
43561da177e4SLinus Torvalds currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
43571da177e4SLinus Torvalds
43581da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 0;
43591da177e4SLinus Torvalds
43601da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
43615c04a7b8SAlexey Dobriyan (currSCCB->HostStatus == SCCB_COMPLETE)) {
43621da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PARITY_ERR;
43631da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY);
43641da177e4SLinus Torvalds }
43651da177e4SLinus Torvalds
436647b5d69cSJames Bottomley FPT_hostDataXferAbort(port, p_card, currSCCB);
43671da177e4SLinus Torvalds
436847b5d69cSJames Bottomley FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
43691da177e4SLinus Torvalds
43705c04a7b8SAlexey Dobriyan while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
43715c04a7b8SAlexey Dobriyan && (RD_HARPOON(port + hp_ext_status) &
43725c04a7b8SAlexey Dobriyan BM_CMD_BUSY)) {
43735c04a7b8SAlexey Dobriyan }
43741da177e4SLinus Torvalds
43751da177e4SLinus Torvalds }
43765c04a7b8SAlexey Dobriyan }
43771da177e4SLinus Torvalds
43785c04a7b8SAlexey Dobriyan /*End Data In specific code. */
43791da177e4SLinus Torvalds GET_XFER_CNT(port, xfercnt);
43801da177e4SLinus Torvalds
43811da177e4SLinus Torvalds WR_HARPOON(port + hp_xfercnt_0, 0x00);
43821da177e4SLinus Torvalds
43831da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_0, 0x00);
43841da177e4SLinus Torvalds
43851da177e4SLinus Torvalds currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
43861da177e4SLinus Torvalds
43871da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = xfercnt;
43881da177e4SLinus Torvalds
43891da177e4SLinus Torvalds if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
43901da177e4SLinus Torvalds (currSCCB->HostStatus == SCCB_COMPLETE)) {
43911da177e4SLinus Torvalds
43921da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PARITY_ERR;
43931da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), PARITY);
43941da177e4SLinus Torvalds }
43951da177e4SLinus Torvalds
439647b5d69cSJames Bottomley FPT_hostDataXferAbort(port, p_card, currSCCB);
43971da177e4SLinus Torvalds
43981da177e4SLinus Torvalds WR_HARPOON(port + hp_fifowrite, 0x00);
43991da177e4SLinus Torvalds WR_HARPOON(port + hp_fiforead, 0x00);
44001da177e4SLinus Torvalds WR_HARPOON(port + hp_xferstat, 0x00);
44011da177e4SLinus Torvalds
44021da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
44031da177e4SLinus Torvalds }
44041da177e4SLinus Torvalds
44051da177e4SLinus Torvalds /*---------------------------------------------------------------------
44061da177e4SLinus Torvalds *
44071da177e4SLinus Torvalds * Function: Phase Bus Free
44081da177e4SLinus Torvalds *
44091da177e4SLinus Torvalds * Description: We just went bus free so figure out if it was
44101da177e4SLinus Torvalds * because of command complete or from a disconnect.
44111da177e4SLinus Torvalds *
44121da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_phaseBusFree(u32 port,unsigned char p_card)4413391e2f25SKhalid Aziz static void FPT_phaseBusFree(u32 port, unsigned char p_card)
44141da177e4SLinus Torvalds {
441569eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
44161da177e4SLinus Torvalds
441747b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
44181da177e4SLinus Torvalds
44195c04a7b8SAlexey Dobriyan if (currSCCB != NULL) {
44201da177e4SLinus Torvalds
44211da177e4SLinus Torvalds DISABLE_AUTO(port);
44221da177e4SLinus Torvalds
44235c04a7b8SAlexey Dobriyan if (currSCCB->OperationCode == RESET_COMMAND) {
44241da177e4SLinus Torvalds
442547b5d69cSJames Bottomley if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
44265c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44275c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
44285c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44295c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 0;
44301da177e4SLinus Torvalds else
44315c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44325c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 0;
44331da177e4SLinus Torvalds
44345c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
44355c04a7b8SAlexey Dobriyan p_card);
44361da177e4SLinus Torvalds
443747b5d69cSJames Bottomley FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
44381da177e4SLinus Torvalds
44391da177e4SLinus Torvalds }
44401da177e4SLinus Torvalds
44415c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
444247b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4443db038cf8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED;
44445c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
44455c04a7b8SAlexey Dobriyan ~EE_SYNC_MASK;
44461da177e4SLinus Torvalds }
44471da177e4SLinus Torvalds
44485c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
444947b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
445047b5d69cSJames Bottomley (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44511da177e4SLinus Torvalds TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
44521da177e4SLinus Torvalds
44535c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
44545c04a7b8SAlexey Dobriyan ~EE_WIDE_SCSI;
44551da177e4SLinus Torvalds }
44561da177e4SLinus Torvalds
44575c04a7b8SAlexey Dobriyan else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
44581da177e4SLinus Torvalds /* Make sure this is not a phony BUS_FREE. If we were
44591da177e4SLinus Torvalds reselected or if BUSY is NOT on then this is a
44601da177e4SLinus Torvalds valid BUS FREE. SRR Wednesday, 5/10/1995. */
44611da177e4SLinus Torvalds
44621da177e4SLinus Torvalds if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
44635c04a7b8SAlexey Dobriyan (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
44645c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44655c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_TAG_Q_MASK;
44665c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44675c04a7b8SAlexey Dobriyan TarStatus |= TAG_Q_REJECT;
44681da177e4SLinus Torvalds }
44691da177e4SLinus Torvalds
44705c04a7b8SAlexey Dobriyan else {
44711da177e4SLinus Torvalds return;
44721da177e4SLinus Torvalds }
44731da177e4SLinus Torvalds }
44741da177e4SLinus Torvalds
44755c04a7b8SAlexey Dobriyan else {
44761da177e4SLinus Torvalds
44771da177e4SLinus Torvalds currSCCB->Sccb_scsistat = BUS_FREE_ST;
44781da177e4SLinus Torvalds
44795c04a7b8SAlexey Dobriyan if (!currSCCB->HostStatus) {
44801da177e4SLinus Torvalds currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
44811da177e4SLinus Torvalds }
44821da177e4SLinus Torvalds
448347b5d69cSJames Bottomley if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
44845c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44855c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
44865c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44875c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 0;
44881da177e4SLinus Torvalds else
44895c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
44905c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 0;
44911da177e4SLinus Torvalds
44925c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
44935c04a7b8SAlexey Dobriyan p_card);
44941da177e4SLinus Torvalds return;
44951da177e4SLinus Torvalds }
44961da177e4SLinus Torvalds
449747b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
44981da177e4SLinus Torvalds
44991da177e4SLinus Torvalds } /*end if !=null */
45001da177e4SLinus Torvalds }
45011da177e4SLinus Torvalds
45021da177e4SLinus Torvalds /*---------------------------------------------------------------------
45031da177e4SLinus Torvalds *
45041da177e4SLinus Torvalds * Function: Auto Load Default Map
45051da177e4SLinus Torvalds *
4506083d248bSzuoqilin * Description: Load the Automation RAM with the default map values.
45071da177e4SLinus Torvalds *
45081da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_autoLoadDefaultMap(u32 p_port)4509391e2f25SKhalid Aziz static void FPT_autoLoadDefaultMap(u32 p_port)
45101da177e4SLinus Torvalds {
4511391e2f25SKhalid Aziz u32 map_addr;
45121da177e4SLinus Torvalds
45131da177e4SLinus Torvalds ARAM_ACCESS(p_port);
45141da177e4SLinus Torvalds map_addr = p_port + hp_aramBase;
45151da177e4SLinus Torvalds
45161da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
45171da177e4SLinus Torvalds map_addr += 2;
45181da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
45191da177e4SLinus Torvalds map_addr += 2;
45201da177e4SLinus Torvalds WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
45211da177e4SLinus Torvalds map_addr += 2;
45221da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
45231da177e4SLinus Torvalds map_addr += 2;
45241da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
45251da177e4SLinus Torvalds map_addr += 2;
45261da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
45271da177e4SLinus Torvalds map_addr += 2;
45281da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
45291da177e4SLinus Torvalds map_addr += 2;
45301da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
45311da177e4SLinus Torvalds map_addr += 2;
45321da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
45331da177e4SLinus Torvalds map_addr += 2;
45341da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
45351da177e4SLinus Torvalds map_addr += 2;
45361da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
45371da177e4SLinus Torvalds map_addr += 2;
45381da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
45391da177e4SLinus Torvalds map_addr += 2;
45401da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
45411da177e4SLinus Torvalds map_addr += 2;
45421da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
45431da177e4SLinus Torvalds map_addr += 2;
45441da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
45451da177e4SLinus Torvalds map_addr += 2;
45461da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
45471da177e4SLinus Torvalds map_addr += 2;
45481da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
45491da177e4SLinus Torvalds map_addr += 2;
45501da177e4SLinus Torvalds WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
45511da177e4SLinus Torvalds map_addr += 2; /*This means AYNC DATA IN */
45521da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
45531da177e4SLinus Torvalds map_addr += 2;
45541da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
45551da177e4SLinus Torvalds map_addr += 2;
45561da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
45571da177e4SLinus Torvalds map_addr += 2;
45581da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
45591da177e4SLinus Torvalds map_addr += 2;
45601da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
45611da177e4SLinus Torvalds map_addr += 2;
45621da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
45631da177e4SLinus Torvalds map_addr += 2;
45641da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
45651da177e4SLinus Torvalds map_addr += 2;
45661da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
45671da177e4SLinus Torvalds map_addr += 2;
45681da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
45691da177e4SLinus Torvalds map_addr += 2;
45701da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
45711da177e4SLinus Torvalds map_addr += 2;
45721da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
45731da177e4SLinus Torvalds map_addr += 2;
45741da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
45751da177e4SLinus Torvalds map_addr += 2;
45761da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
45771da177e4SLinus Torvalds map_addr += 2;
45781da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
45791da177e4SLinus Torvalds map_addr += 2;
45801da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
45811da177e4SLinus Torvalds map_addr += 2;
45821da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
45831da177e4SLinus Torvalds map_addr += 2;
45841da177e4SLinus Torvalds WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
45851da177e4SLinus Torvalds map_addr += 2;
45861da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
45871da177e4SLinus Torvalds map_addr += 2;
45881da177e4SLinus Torvalds
45891da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
45901da177e4SLinus Torvalds map_addr += 2;
45911da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
45921da177e4SLinus Torvalds map_addr += 2;
45931da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
45941da177e4SLinus Torvalds map_addr += 2;
45951da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
45961da177e4SLinus Torvalds map_addr += 2; /* DIDN'T GET ONE */
45971da177e4SLinus Torvalds WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
45981da177e4SLinus Torvalds map_addr += 2;
45991da177e4SLinus Torvalds WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
46001da177e4SLinus Torvalds map_addr += 2;
46011da177e4SLinus Torvalds WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
46021da177e4SLinus Torvalds
46031da177e4SLinus Torvalds SGRAM_ACCESS(p_port);
46041da177e4SLinus Torvalds }
46051da177e4SLinus Torvalds
46061da177e4SLinus Torvalds /*---------------------------------------------------------------------
46071da177e4SLinus Torvalds *
46081da177e4SLinus Torvalds * Function: Auto Command Complete
46091da177e4SLinus Torvalds *
46101da177e4SLinus Torvalds * Description: Post command back to host and find another command
46111da177e4SLinus Torvalds * to execute.
46121da177e4SLinus Torvalds *
46131da177e4SLinus Torvalds *---------------------------------------------------------------------*/
46141da177e4SLinus Torvalds
FPT_autoCmdCmplt(u32 p_port,unsigned char p_card)4615391e2f25SKhalid Aziz static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
46161da177e4SLinus Torvalds {
461769eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
4618db038cf8SAlexey Dobriyan unsigned char status_byte;
46191da177e4SLinus Torvalds
462047b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
46211da177e4SLinus Torvalds
46221da177e4SLinus Torvalds status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
46231da177e4SLinus Torvalds
462447b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
46251da177e4SLinus Torvalds
4626a87afe28SHannes Reinecke if (status_byte != SAM_STAT_GOOD) {
46271da177e4SLinus Torvalds
4628a87afe28SHannes Reinecke if (status_byte == SAM_STAT_TASK_SET_FULL) {
46291da177e4SLinus Torvalds
463047b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
46315c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
46325c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
46335c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
46345c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 1;
463547b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
463647b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--;
46375c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
46385c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card]
46395c04a7b8SAlexey Dobriyan [currSCCB->TargID].
46405c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->Lun]] =
46415c04a7b8SAlexey Dobriyan NULL;
46425c04a7b8SAlexey Dobriyan } else {
46435c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
46445c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1;
46455c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) {
464647b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
46475c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
46485c04a7b8SAlexey Dobriyan discQCount--;
46495c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
46505c04a7b8SAlexey Dobriyan Sccb_tag]
46515c04a7b8SAlexey Dobriyan = NULL;
46525c04a7b8SAlexey Dobriyan } else {
465347b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
46545c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
46555c04a7b8SAlexey Dobriyan discQCount--;
46565c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
46575c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card]
46585c04a7b8SAlexey Dobriyan [currSCCB->TargID].
46595c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL;
46601da177e4SLinus Torvalds }
46611da177e4SLinus Torvalds }
46621da177e4SLinus Torvalds
46631da177e4SLinus Torvalds currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
46641da177e4SLinus Torvalds
466547b5d69cSJames Bottomley FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
46661da177e4SLinus Torvalds
46671da177e4SLinus Torvalds return;
46681da177e4SLinus Torvalds }
46691da177e4SLinus Torvalds
46705c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
467147b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4672db038cf8SAlexey Dobriyan (unsigned char)SYNC_SUPPORTED;
46731da177e4SLinus Torvalds
46745c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
46755c04a7b8SAlexey Dobriyan ~EE_SYNC_MASK;
467647b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
46771da177e4SLinus Torvalds
467847b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
46795c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
46805c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
46815c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
46825c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 1;
468347b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
468447b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--;
46855c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
46865c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card]
46875c04a7b8SAlexey Dobriyan [currSCCB->TargID].
46885c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->Lun]] =
46895c04a7b8SAlexey Dobriyan NULL;
46905c04a7b8SAlexey Dobriyan } else {
46915c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
46925c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1;
46935c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) {
469447b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
46955c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
46965c04a7b8SAlexey Dobriyan discQCount--;
46975c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
46985c04a7b8SAlexey Dobriyan Sccb_tag]
46995c04a7b8SAlexey Dobriyan = NULL;
47005c04a7b8SAlexey Dobriyan } else {
470147b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
47025c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
47035c04a7b8SAlexey Dobriyan discQCount--;
47045c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
47055c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card]
47065c04a7b8SAlexey Dobriyan [currSCCB->TargID].
47075c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL;
47081da177e4SLinus Torvalds }
47091da177e4SLinus Torvalds }
47101da177e4SLinus Torvalds return;
47111da177e4SLinus Torvalds
47121da177e4SLinus Torvalds }
47131da177e4SLinus Torvalds
47145c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
47151da177e4SLinus Torvalds
471647b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
471747b5d69cSJames Bottomley (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47181da177e4SLinus Torvalds TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
47191da177e4SLinus Torvalds
47205c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
47215c04a7b8SAlexey Dobriyan ~EE_WIDE_SCSI;
472247b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
47231da177e4SLinus Torvalds
472447b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
47255c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47265c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
47275c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47285c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] = 1;
472947b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
473047b5d69cSJames Bottomley FPT_BL_Card[p_card].discQCount--;
47315c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
47325c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card]
47335c04a7b8SAlexey Dobriyan [currSCCB->TargID].
47345c04a7b8SAlexey Dobriyan LunDiscQ_Idx[currSCCB->Lun]] =
47355c04a7b8SAlexey Dobriyan NULL;
47365c04a7b8SAlexey Dobriyan } else {
47375c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47385c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1;
47395c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) {
474047b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
47415c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
47425c04a7b8SAlexey Dobriyan discQCount--;
47435c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
47445c04a7b8SAlexey Dobriyan Sccb_tag]
47455c04a7b8SAlexey Dobriyan = NULL;
47465c04a7b8SAlexey Dobriyan } else {
474747b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQCount != 0)
47485c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
47495c04a7b8SAlexey Dobriyan discQCount--;
47505c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
47515c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl[p_card]
47525c04a7b8SAlexey Dobriyan [currSCCB->TargID].
47535c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL;
47541da177e4SLinus Torvalds }
47551da177e4SLinus Torvalds }
47561da177e4SLinus Torvalds return;
47571da177e4SLinus Torvalds
47581da177e4SLinus Torvalds }
47591da177e4SLinus Torvalds
4760a87afe28SHannes Reinecke if (status_byte == SAM_STAT_CHECK_CONDITION) {
47615c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
47625c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47635c04a7b8SAlexey Dobriyan TarEEValue & EE_SYNC_MASK) {
47645c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->
47655c04a7b8SAlexey Dobriyan TargID].
47665c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_SYNC_MASK;
47671da177e4SLinus Torvalds }
47685c04a7b8SAlexey Dobriyan if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47695c04a7b8SAlexey Dobriyan TarEEValue & EE_WIDE_SCSI) {
47705c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->
47715c04a7b8SAlexey Dobriyan TargID].
47725c04a7b8SAlexey Dobriyan TarStatus &= ~TAR_WIDE_MASK;
47731da177e4SLinus Torvalds }
47741da177e4SLinus Torvalds }
47751da177e4SLinus Torvalds }
47761da177e4SLinus Torvalds
47771da177e4SLinus Torvalds if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
47781da177e4SLinus Torvalds
47791da177e4SLinus Torvalds currSCCB->SccbStatus = SCCB_ERROR;
47801da177e4SLinus Torvalds currSCCB->TargetStatus = status_byte;
47811da177e4SLinus Torvalds
4782a87afe28SHannes Reinecke if (status_byte == SAM_STAT_CHECK_CONDITION) {
47831da177e4SLinus Torvalds
47845c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].
47855c04a7b8SAlexey Dobriyan TarLUN_CA = 1;
47861da177e4SLinus Torvalds
47875c04a7b8SAlexey Dobriyan if (currSCCB->RequestSenseLength !=
47885c04a7b8SAlexey Dobriyan NO_AUTO_REQUEST_SENSE) {
47891da177e4SLinus Torvalds
47901da177e4SLinus Torvalds if (currSCCB->RequestSenseLength == 0)
47915c04a7b8SAlexey Dobriyan currSCCB->RequestSenseLength =
47925c04a7b8SAlexey Dobriyan 14;
47931da177e4SLinus Torvalds
479447b5d69cSJames Bottomley FPT_ssenss(&FPT_BL_Card[p_card]);
47955c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |=
47965c04a7b8SAlexey Dobriyan F_NEW_SCCB_CMD;
47971da177e4SLinus Torvalds
47985c04a7b8SAlexey Dobriyan if (((FPT_BL_Card[p_card].
47995c04a7b8SAlexey Dobriyan globalFlags & F_CONLUN_IO)
48005c04a7b8SAlexey Dobriyan &&
48015c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card]
48025c04a7b8SAlexey Dobriyan [currSCCB->TargID].
48035c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) !=
48045c04a7b8SAlexey Dobriyan TAG_Q_TRYING))) {
48055c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card]
48065c04a7b8SAlexey Dobriyan [currSCCB->TargID].
48075c04a7b8SAlexey Dobriyan TarLUNBusy[currSCCB->Lun] =
48085c04a7b8SAlexey Dobriyan 1;
48095c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].
48105c04a7b8SAlexey Dobriyan discQCount != 0)
48115c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
48125c04a7b8SAlexey Dobriyan discQCount--;
48135c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
48145c04a7b8SAlexey Dobriyan discQ_Tbl[FPT_sccbMgrTbl
48155c04a7b8SAlexey Dobriyan [p_card]
48165c04a7b8SAlexey Dobriyan [currSCCB->
48175c04a7b8SAlexey Dobriyan TargID].
48185c04a7b8SAlexey Dobriyan LunDiscQ_Idx
48195c04a7b8SAlexey Dobriyan [currSCCB->Lun]] =
48205c04a7b8SAlexey Dobriyan NULL;
48215c04a7b8SAlexey Dobriyan } else {
48225c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card]
48235c04a7b8SAlexey Dobriyan [currSCCB->TargID].
48245c04a7b8SAlexey Dobriyan TarLUNBusy[0] = 1;
48255c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_tag) {
48265c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].
48275c04a7b8SAlexey Dobriyan discQCount != 0)
48285c04a7b8SAlexey Dobriyan FPT_BL_Card
48295c04a7b8SAlexey Dobriyan [p_card].
48305c04a7b8SAlexey Dobriyan discQCount--;
48315c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
48325c04a7b8SAlexey Dobriyan discQ_Tbl[currSCCB->
48335c04a7b8SAlexey Dobriyan Sccb_tag]
48345c04a7b8SAlexey Dobriyan = NULL;
48355c04a7b8SAlexey Dobriyan } else {
48365c04a7b8SAlexey Dobriyan if (FPT_BL_Card[p_card].
48375c04a7b8SAlexey Dobriyan discQCount != 0)
48385c04a7b8SAlexey Dobriyan FPT_BL_Card
48395c04a7b8SAlexey Dobriyan [p_card].
48405c04a7b8SAlexey Dobriyan discQCount--;
48415c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
48425c04a7b8SAlexey Dobriyan discQ_Tbl
48435c04a7b8SAlexey Dobriyan [FPT_sccbMgrTbl
48445c04a7b8SAlexey Dobriyan [p_card][currSCCB->
48455c04a7b8SAlexey Dobriyan TargID].
48465c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] =
48475c04a7b8SAlexey Dobriyan NULL;
48481da177e4SLinus Torvalds }
48491da177e4SLinus Torvalds }
48501da177e4SLinus Torvalds return;
48511da177e4SLinus Torvalds }
48521da177e4SLinus Torvalds }
485347b5d69cSJames Bottomley }
485447b5d69cSJames Bottomley }
485547b5d69cSJames Bottomley
485647b5d69cSJames Bottomley if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
48575c04a7b8SAlexey Dobriyan ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
48585c04a7b8SAlexey Dobriyan TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
48595c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
48605c04a7b8SAlexey Dobriyan Lun] = 0;
48611da177e4SLinus Torvalds else
486247b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
486347b5d69cSJames Bottomley
486447b5d69cSJames Bottomley FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
48651da177e4SLinus Torvalds }
48661da177e4SLinus Torvalds
48671da177e4SLinus Torvalds #define SHORT_WAIT 0x0000000F
48681da177e4SLinus Torvalds #define LONG_WAIT 0x0000FFFFL
48691da177e4SLinus Torvalds
48701da177e4SLinus Torvalds /*---------------------------------------------------------------------
48711da177e4SLinus Torvalds *
48721da177e4SLinus Torvalds * Function: Data Transfer Processor
48731da177e4SLinus Torvalds *
48741da177e4SLinus Torvalds * Description: This routine performs two tasks.
48751da177e4SLinus Torvalds * (1) Start data transfer by calling HOST_DATA_XFER_START
48761da177e4SLinus Torvalds * function. Once data transfer is started, (2) Depends
48771da177e4SLinus Torvalds * on the type of data transfer mode Scatter/Gather mode
48781da177e4SLinus Torvalds * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
48791da177e4SLinus Torvalds * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
48801da177e4SLinus Torvalds * data transfer done. In Scatter/Gather mode, this routine
48811da177e4SLinus Torvalds * checks bus master command complete and dual rank busy
48821da177e4SLinus Torvalds * bit to keep chaining SC transfer command. Similarly,
48831da177e4SLinus Torvalds * in Scatter/Gather mode, it checks Sccb_MGRFlag
48841da177e4SLinus Torvalds * (F_HOST_XFER_ACT bit) for data transfer done.
48851da177e4SLinus Torvalds *
48861da177e4SLinus Torvalds *---------------------------------------------------------------------*/
48871da177e4SLinus Torvalds
FPT_dataXferProcessor(u32 port,struct sccb_card * pCurrCard)4888391e2f25SKhalid Aziz static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
48891da177e4SLinus Torvalds {
489069eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
48911da177e4SLinus Torvalds
48921da177e4SLinus Torvalds currSCCB = pCurrCard->currentSCCB;
48931da177e4SLinus Torvalds
48945c04a7b8SAlexey Dobriyan if (currSCCB->Sccb_XferState & F_SG_XFER) {
48951da177e4SLinus Torvalds if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
48961da177e4SLinus Torvalds {
4897db038cf8SAlexey Dobriyan currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
48981da177e4SLinus Torvalds currSCCB->Sccb_SGoffset = 0x00;
48991da177e4SLinus Torvalds }
49001da177e4SLinus Torvalds pCurrCard->globalFlags |= F_HOST_XFER_ACT;
49011da177e4SLinus Torvalds
490247b5d69cSJames Bottomley FPT_busMstrSGDataXferStart(port, currSCCB);
49031da177e4SLinus Torvalds }
49041da177e4SLinus Torvalds
49055c04a7b8SAlexey Dobriyan else {
49065c04a7b8SAlexey Dobriyan if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
49071da177e4SLinus Torvalds pCurrCard->globalFlags |= F_HOST_XFER_ACT;
49081da177e4SLinus Torvalds
490947b5d69cSJames Bottomley FPT_busMstrDataXferStart(port, currSCCB);
49101da177e4SLinus Torvalds }
49111da177e4SLinus Torvalds }
49121da177e4SLinus Torvalds }
49131da177e4SLinus Torvalds
49141da177e4SLinus Torvalds /*---------------------------------------------------------------------
49151da177e4SLinus Torvalds *
49161da177e4SLinus Torvalds * Function: BusMaster Scatter Gather Data Transfer Start
49171da177e4SLinus Torvalds *
49181da177e4SLinus Torvalds * Description:
49191da177e4SLinus Torvalds *
49201da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_busMstrSGDataXferStart(u32 p_port,struct sccb * pcurrSCCB)4921391e2f25SKhalid Aziz static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
49221da177e4SLinus Torvalds {
4923391e2f25SKhalid Aziz u32 count, addr, tmpSGCnt;
4924ce793215SAlexey Dobriyan unsigned int sg_index;
4925db038cf8SAlexey Dobriyan unsigned char sg_count, i;
4926391e2f25SKhalid Aziz u32 reg_offset;
4927391e2f25SKhalid Aziz struct blogic_sg_seg *segp;
49281da177e4SLinus Torvalds
4929391e2f25SKhalid Aziz if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4930391e2f25SKhalid Aziz count = ((u32)HOST_RD_CMD) << 24;
4931391e2f25SKhalid Aziz else
4932391e2f25SKhalid Aziz count = ((u32)HOST_WRT_CMD) << 24;
49331da177e4SLinus Torvalds
49341da177e4SLinus Torvalds sg_count = 0;
49351da177e4SLinus Torvalds tmpSGCnt = 0;
49361da177e4SLinus Torvalds sg_index = pcurrSCCB->Sccb_sgseg;
49371da177e4SLinus Torvalds reg_offset = hp_aramBase;
49381da177e4SLinus Torvalds
49395c04a7b8SAlexey Dobriyan i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
49405c04a7b8SAlexey Dobriyan ~(SGRAM_ARAM | SCATTER_EN));
49411da177e4SLinus Torvalds
49421da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, i);
49431da177e4SLinus Torvalds
4944db038cf8SAlexey Dobriyan while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4945391e2f25SKhalid Aziz ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
49465c04a7b8SAlexey Dobriyan pcurrSCCB->DataLength)) {
49471da177e4SLinus Torvalds
4948391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4949391e2f25SKhalid Aziz sg_index;
4950391e2f25SKhalid Aziz tmpSGCnt += segp->segbytes;
4951391e2f25SKhalid Aziz count |= segp->segbytes;
4952391e2f25SKhalid Aziz addr = segp->segdata;
49531da177e4SLinus Torvalds
49541da177e4SLinus Torvalds if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
49555c04a7b8SAlexey Dobriyan addr +=
49565c04a7b8SAlexey Dobriyan ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
49575c04a7b8SAlexey Dobriyan count =
49585c04a7b8SAlexey Dobriyan (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
49591da177e4SLinus Torvalds tmpSGCnt = count & 0x00FFFFFFL;
49601da177e4SLinus Torvalds }
49611da177e4SLinus Torvalds
49621da177e4SLinus Torvalds WR_HARP32(p_port, reg_offset, addr);
49631da177e4SLinus Torvalds reg_offset += 4;
49641da177e4SLinus Torvalds
49651da177e4SLinus Torvalds WR_HARP32(p_port, reg_offset, count);
49661da177e4SLinus Torvalds reg_offset += 4;
49671da177e4SLinus Torvalds
49681da177e4SLinus Torvalds count &= 0xFF000000L;
49691da177e4SLinus Torvalds sg_index++;
49701da177e4SLinus Torvalds sg_count++;
49711da177e4SLinus Torvalds
49721da177e4SLinus Torvalds } /*End While */
49731da177e4SLinus Torvalds
49741da177e4SLinus Torvalds pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
49751da177e4SLinus Torvalds
49761da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
49771da177e4SLinus Torvalds
49781da177e4SLinus Torvalds if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
49791da177e4SLinus Torvalds
49801da177e4SLinus Torvalds WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
49811da177e4SLinus Torvalds
49825c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
49835c04a7b8SAlexey Dobriyan (DMA_PORT | SCSI_PORT | SCSI_INBIT));
49841da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
49851da177e4SLinus Torvalds }
49861da177e4SLinus Torvalds
49871da177e4SLinus Torvalds else {
49881da177e4SLinus Torvalds
49891da177e4SLinus Torvalds if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
49905c04a7b8SAlexey Dobriyan (tmpSGCnt & 0x000000001)) {
49911da177e4SLinus Torvalds
49921da177e4SLinus Torvalds pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
49931da177e4SLinus Torvalds tmpSGCnt--;
49941da177e4SLinus Torvalds }
49951da177e4SLinus Torvalds
49961da177e4SLinus Torvalds WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
49971da177e4SLinus Torvalds
49985c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
49995c04a7b8SAlexey Dobriyan (SCSI_PORT | DMA_PORT | DMA_RD));
50001da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
50011da177e4SLinus Torvalds }
50021da177e4SLinus Torvalds
5003db038cf8SAlexey Dobriyan WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
50041da177e4SLinus Torvalds
50051da177e4SLinus Torvalds }
50061da177e4SLinus Torvalds
50071da177e4SLinus Torvalds /*---------------------------------------------------------------------
50081da177e4SLinus Torvalds *
50091da177e4SLinus Torvalds * Function: BusMaster Data Transfer Start
50101da177e4SLinus Torvalds *
50111da177e4SLinus Torvalds * Description:
50121da177e4SLinus Torvalds *
50131da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_busMstrDataXferStart(u32 p_port,struct sccb * pcurrSCCB)5014391e2f25SKhalid Aziz static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
50151da177e4SLinus Torvalds {
5016391e2f25SKhalid Aziz u32 addr, count;
50171da177e4SLinus Torvalds
50181da177e4SLinus Torvalds if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
50191da177e4SLinus Torvalds
50201da177e4SLinus Torvalds count = pcurrSCCB->Sccb_XferCnt;
50211da177e4SLinus Torvalds
5022391e2f25SKhalid Aziz addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
50231da177e4SLinus Torvalds }
50241da177e4SLinus Torvalds
50251da177e4SLinus Torvalds else {
50261da177e4SLinus Torvalds addr = pcurrSCCB->SensePointer;
50271da177e4SLinus Torvalds count = pcurrSCCB->RequestSenseLength;
50281da177e4SLinus Torvalds
50291da177e4SLinus Torvalds }
50301da177e4SLinus Torvalds
50311da177e4SLinus Torvalds HP_SETUP_ADDR_CNT(p_port, addr, count);
50321da177e4SLinus Torvalds
50331da177e4SLinus Torvalds if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
50341da177e4SLinus Torvalds
50355c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
50365c04a7b8SAlexey Dobriyan (DMA_PORT | SCSI_PORT | SCSI_INBIT));
50371da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
50381da177e4SLinus Torvalds
50391da177e4SLinus Torvalds WR_HARPOON(p_port + hp_xfer_cmd,
50401da177e4SLinus Torvalds (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
50411da177e4SLinus Torvalds }
50421da177e4SLinus Torvalds
50431da177e4SLinus Torvalds else {
50441da177e4SLinus Torvalds
50455c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_portctrl_0,
50465c04a7b8SAlexey Dobriyan (SCSI_PORT | DMA_PORT | DMA_RD));
50471da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
50481da177e4SLinus Torvalds
50491da177e4SLinus Torvalds WR_HARPOON(p_port + hp_xfer_cmd,
50501da177e4SLinus Torvalds (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
50511da177e4SLinus Torvalds
50521da177e4SLinus Torvalds }
50531da177e4SLinus Torvalds }
50541da177e4SLinus Torvalds
50551da177e4SLinus Torvalds /*---------------------------------------------------------------------
50561da177e4SLinus Torvalds *
50571da177e4SLinus Torvalds * Function: BusMaster Timeout Handler
50581da177e4SLinus Torvalds *
50591da177e4SLinus Torvalds * Description: This function is called after a bus master command busy time
50601da177e4SLinus Torvalds * out is detected. This routines issue halt state machine
50611da177e4SLinus Torvalds * with a software time out for command busy. If command busy
50621da177e4SLinus Torvalds * is still asserted at the end of the time out, it issues
50631da177e4SLinus Torvalds * hard abort with another software time out. It hard abort
50641da177e4SLinus Torvalds * command busy is also time out, it'll just give up.
50651da177e4SLinus Torvalds *
50661da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_busMstrTimeOut(u32 p_port)5067391e2f25SKhalid Aziz static unsigned char FPT_busMstrTimeOut(u32 p_port)
50681da177e4SLinus Torvalds {
5069d63a4cccSAlexey Dobriyan unsigned long timeout;
50701da177e4SLinus Torvalds
50711da177e4SLinus Torvalds timeout = LONG_WAIT;
50721da177e4SLinus Torvalds
50731da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
50741da177e4SLinus Torvalds
50755c04a7b8SAlexey Dobriyan while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
50765c04a7b8SAlexey Dobriyan && timeout--) {
50775c04a7b8SAlexey Dobriyan }
50781da177e4SLinus Torvalds
50791da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
50801da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
50811da177e4SLinus Torvalds
50821da177e4SLinus Torvalds timeout = LONG_WAIT;
50835c04a7b8SAlexey Dobriyan while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
50845c04a7b8SAlexey Dobriyan && timeout--) {
50855c04a7b8SAlexey Dobriyan }
50861da177e4SLinus Torvalds }
50871da177e4SLinus Torvalds
50881da177e4SLinus Torvalds RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
50891da177e4SLinus Torvalds
50901da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
50915c1b85e2SAlexey Dobriyan return 1;
50921da177e4SLinus Torvalds }
50931da177e4SLinus Torvalds
50941da177e4SLinus Torvalds else {
50955c1b85e2SAlexey Dobriyan return 0;
50961da177e4SLinus Torvalds }
50971da177e4SLinus Torvalds }
50981da177e4SLinus Torvalds
50991da177e4SLinus Torvalds /*---------------------------------------------------------------------
51001da177e4SLinus Torvalds *
51011da177e4SLinus Torvalds * Function: Host Data Transfer Abort
51021da177e4SLinus Torvalds *
51031da177e4SLinus Torvalds * Description: Abort any in progress transfer.
51041da177e4SLinus Torvalds *
51051da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_hostDataXferAbort(u32 port,unsigned char p_card,struct sccb * pCurrSCCB)5106391e2f25SKhalid Aziz static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
51075c04a7b8SAlexey Dobriyan struct sccb *pCurrSCCB)
51081da177e4SLinus Torvalds {
51091da177e4SLinus Torvalds
5110d63a4cccSAlexey Dobriyan unsigned long timeout;
5111d63a4cccSAlexey Dobriyan unsigned long remain_cnt;
5112391e2f25SKhalid Aziz u32 sg_ptr;
5113391e2f25SKhalid Aziz struct blogic_sg_seg *segp;
51141da177e4SLinus Torvalds
511547b5d69cSJames Bottomley FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
51161da177e4SLinus Torvalds
51171da177e4SLinus Torvalds if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
51181da177e4SLinus Torvalds
51191da177e4SLinus Torvalds if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
51201da177e4SLinus Torvalds
51215c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl,
51225c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) |
51235c04a7b8SAlexey Dobriyan FLUSH_XFER_CNTR));
51241da177e4SLinus Torvalds timeout = LONG_WAIT;
51251da177e4SLinus Torvalds
51265c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
51275c04a7b8SAlexey Dobriyan && timeout--) {
51285c04a7b8SAlexey Dobriyan }
51291da177e4SLinus Torvalds
51305c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl,
51315c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) &
51325c04a7b8SAlexey Dobriyan ~FLUSH_XFER_CNTR));
51331da177e4SLinus Torvalds
51341da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
51351da177e4SLinus Torvalds
513647b5d69cSJames Bottomley if (FPT_busMstrTimeOut(port)) {
51371da177e4SLinus Torvalds
51381da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00)
51391da177e4SLinus Torvalds
51405c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus =
51415c04a7b8SAlexey Dobriyan SCCB_BM_ERR;
51421da177e4SLinus Torvalds
51431da177e4SLinus Torvalds }
51441da177e4SLinus Torvalds
51455c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_int_status) &
51465c04a7b8SAlexey Dobriyan INT_EXT_STATUS)
51471da177e4SLinus Torvalds
51485c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) &
51495c04a7b8SAlexey Dobriyan BAD_EXT_STATUS)
51501da177e4SLinus Torvalds
51515c04a7b8SAlexey Dobriyan if (pCurrSCCB->HostStatus ==
51525c04a7b8SAlexey Dobriyan 0x00)
51531da177e4SLinus Torvalds {
51545c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus =
51555c04a7b8SAlexey Dobriyan SCCB_BM_ERR;
51561da177e4SLinus Torvalds }
51571da177e4SLinus Torvalds }
51581da177e4SLinus Torvalds }
51591da177e4SLinus Torvalds }
51601da177e4SLinus Torvalds
51611da177e4SLinus Torvalds else if (pCurrSCCB->Sccb_XferCnt) {
51621da177e4SLinus Torvalds
51631da177e4SLinus Torvalds if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
51641da177e4SLinus Torvalds
51655c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_page_ctrl,
51665c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_page_ctrl) &
51671da177e4SLinus Torvalds ~SCATTER_EN));
51681da177e4SLinus Torvalds
51691da177e4SLinus Torvalds WR_HARPOON(port + hp_sg_addr, 0x00);
51701da177e4SLinus Torvalds
51711da177e4SLinus Torvalds sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
51721da177e4SLinus Torvalds
51735c04a7b8SAlexey Dobriyan if (sg_ptr >
51745c04a7b8SAlexey Dobriyan (unsigned int)(pCurrSCCB->DataLength /
51755c04a7b8SAlexey Dobriyan SG_ELEMENT_SIZE)) {
51761da177e4SLinus Torvalds
5177391e2f25SKhalid Aziz sg_ptr = (u32)(pCurrSCCB->DataLength /
51785c04a7b8SAlexey Dobriyan SG_ELEMENT_SIZE);
51791da177e4SLinus Torvalds }
51801da177e4SLinus Torvalds
51811da177e4SLinus Torvalds remain_cnt = pCurrSCCB->Sccb_XferCnt;
51821da177e4SLinus Torvalds
51831da177e4SLinus Torvalds while (remain_cnt < 0x01000000L) {
51841da177e4SLinus Torvalds
51851da177e4SLinus Torvalds sg_ptr--;
5186391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(pCurrSCCB->
5187391e2f25SKhalid Aziz DataPointer) + (sg_ptr * 2);
5188391e2f25SKhalid Aziz if (remain_cnt > (unsigned long)segp->segbytes)
51895c04a7b8SAlexey Dobriyan remain_cnt -=
5190391e2f25SKhalid Aziz (unsigned long)segp->segbytes;
5191391e2f25SKhalid Aziz else
51921da177e4SLinus Torvalds break;
51931da177e4SLinus Torvalds }
51941da177e4SLinus Torvalds
51951da177e4SLinus Torvalds if (remain_cnt < 0x01000000L) {
51961da177e4SLinus Torvalds
51971da177e4SLinus Torvalds pCurrSCCB->Sccb_SGoffset = remain_cnt;
51981da177e4SLinus Torvalds
5199c823feebSAlexey Dobriyan pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
52001da177e4SLinus Torvalds
52015c04a7b8SAlexey Dobriyan if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
52025c04a7b8SAlexey Dobriyan pCurrSCCB->DataLength && (remain_cnt == 0))
52031da177e4SLinus Torvalds
52045c04a7b8SAlexey Dobriyan pCurrSCCB->Sccb_XferState |=
52055c04a7b8SAlexey Dobriyan F_ALL_XFERRED;
52061da177e4SLinus Torvalds }
52071da177e4SLinus Torvalds
52081da177e4SLinus Torvalds else {
52091da177e4SLinus Torvalds
52101da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) {
52111da177e4SLinus Torvalds
52125c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus =
52135c04a7b8SAlexey Dobriyan SCCB_GROSS_FW_ERR;
52141da177e4SLinus Torvalds }
52151da177e4SLinus Torvalds }
52161da177e4SLinus Torvalds }
52171da177e4SLinus Torvalds
52181da177e4SLinus Torvalds if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
52191da177e4SLinus Torvalds
52201da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
52211da177e4SLinus Torvalds
522247b5d69cSJames Bottomley FPT_busMstrTimeOut(port);
52231da177e4SLinus Torvalds }
52241da177e4SLinus Torvalds
52251da177e4SLinus Torvalds else {
52261da177e4SLinus Torvalds
52275c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_int_status) &
52285c04a7b8SAlexey Dobriyan INT_EXT_STATUS) {
52291da177e4SLinus Torvalds
52305c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) &
52315c04a7b8SAlexey Dobriyan BAD_EXT_STATUS) {
52321da177e4SLinus Torvalds
52335c04a7b8SAlexey Dobriyan if (pCurrSCCB->HostStatus ==
52345c04a7b8SAlexey Dobriyan 0x00) {
52351da177e4SLinus Torvalds
52365c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus =
52375c04a7b8SAlexey Dobriyan SCCB_BM_ERR;
52381da177e4SLinus Torvalds }
52391da177e4SLinus Torvalds }
52401da177e4SLinus Torvalds }
52411da177e4SLinus Torvalds
52421da177e4SLinus Torvalds }
52431da177e4SLinus Torvalds }
52441da177e4SLinus Torvalds
52451da177e4SLinus Torvalds else {
52461da177e4SLinus Torvalds
52471da177e4SLinus Torvalds if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
52481da177e4SLinus Torvalds
52491da177e4SLinus Torvalds timeout = SHORT_WAIT;
52501da177e4SLinus Torvalds
52515c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) &
52525c04a7b8SAlexey Dobriyan BM_CMD_BUSY)
52535c04a7b8SAlexey Dobriyan && ((RD_HARPOON(port + hp_fifo_cnt)) >=
52545c04a7b8SAlexey Dobriyan BM_THRESHOLD) && timeout--) {
52555c04a7b8SAlexey Dobriyan }
52561da177e4SLinus Torvalds }
52571da177e4SLinus Torvalds
52581da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
52591da177e4SLinus Torvalds
52605c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl,
52615c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) |
52621da177e4SLinus Torvalds FLUSH_XFER_CNTR));
52631da177e4SLinus Torvalds
52641da177e4SLinus Torvalds timeout = LONG_WAIT;
52651da177e4SLinus Torvalds
52665c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) &
52675c04a7b8SAlexey Dobriyan BM_CMD_BUSY) && timeout--) {
52685c04a7b8SAlexey Dobriyan }
52691da177e4SLinus Torvalds
52705c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_bm_ctrl,
52715c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_bm_ctrl) &
52721da177e4SLinus Torvalds ~FLUSH_XFER_CNTR));
52731da177e4SLinus Torvalds
52745c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) &
52755c04a7b8SAlexey Dobriyan BM_CMD_BUSY) {
52761da177e4SLinus Torvalds
52771da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) {
52781da177e4SLinus Torvalds
52795c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus =
52805c04a7b8SAlexey Dobriyan SCCB_BM_ERR;
52811da177e4SLinus Torvalds }
52821da177e4SLinus Torvalds
528347b5d69cSJames Bottomley FPT_busMstrTimeOut(port);
52841da177e4SLinus Torvalds }
52851da177e4SLinus Torvalds }
52861da177e4SLinus Torvalds
52871da177e4SLinus Torvalds if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
52881da177e4SLinus Torvalds
52895c04a7b8SAlexey Dobriyan if (RD_HARPOON(port + hp_ext_status) &
52905c04a7b8SAlexey Dobriyan BAD_EXT_STATUS) {
52911da177e4SLinus Torvalds
52921da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) {
52931da177e4SLinus Torvalds
52945c04a7b8SAlexey Dobriyan pCurrSCCB->HostStatus =
52955c04a7b8SAlexey Dobriyan SCCB_BM_ERR;
52961da177e4SLinus Torvalds }
52971da177e4SLinus Torvalds }
52981da177e4SLinus Torvalds }
52991da177e4SLinus Torvalds }
53001da177e4SLinus Torvalds
53011da177e4SLinus Torvalds }
53021da177e4SLinus Torvalds
53031da177e4SLinus Torvalds else {
53041da177e4SLinus Torvalds
53051da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
53061da177e4SLinus Torvalds
53071da177e4SLinus Torvalds timeout = LONG_WAIT;
53081da177e4SLinus Torvalds
53095c04a7b8SAlexey Dobriyan while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
53105c04a7b8SAlexey Dobriyan && timeout--) {
53115c04a7b8SAlexey Dobriyan }
53121da177e4SLinus Torvalds
53131da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
53141da177e4SLinus Torvalds
53151da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) {
53161da177e4SLinus Torvalds
53171da177e4SLinus Torvalds pCurrSCCB->HostStatus = SCCB_BM_ERR;
53181da177e4SLinus Torvalds }
53191da177e4SLinus Torvalds
532047b5d69cSJames Bottomley FPT_busMstrTimeOut(port);
53211da177e4SLinus Torvalds }
53221da177e4SLinus Torvalds }
53231da177e4SLinus Torvalds
53241da177e4SLinus Torvalds if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
53251da177e4SLinus Torvalds
53261da177e4SLinus Torvalds if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
53271da177e4SLinus Torvalds
53281da177e4SLinus Torvalds if (pCurrSCCB->HostStatus == 0x00) {
53291da177e4SLinus Torvalds
53301da177e4SLinus Torvalds pCurrSCCB->HostStatus = SCCB_BM_ERR;
53311da177e4SLinus Torvalds }
53321da177e4SLinus Torvalds }
53331da177e4SLinus Torvalds
53341da177e4SLinus Torvalds }
53351da177e4SLinus Torvalds
53361da177e4SLinus Torvalds if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
53371da177e4SLinus Torvalds
53385c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_page_ctrl,
53395c04a7b8SAlexey Dobriyan (RD_HARPOON(port + hp_page_ctrl) &
53401da177e4SLinus Torvalds ~SCATTER_EN));
53411da177e4SLinus Torvalds
53421da177e4SLinus Torvalds WR_HARPOON(port + hp_sg_addr, 0x00);
53431da177e4SLinus Torvalds
53441da177e4SLinus Torvalds pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
53451da177e4SLinus Torvalds
53461da177e4SLinus Torvalds pCurrSCCB->Sccb_SGoffset = 0x00;
53471da177e4SLinus Torvalds
5348391e2f25SKhalid Aziz if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
53491da177e4SLinus Torvalds pCurrSCCB->DataLength) {
53501da177e4SLinus Torvalds
53511da177e4SLinus Torvalds pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
53525c04a7b8SAlexey Dobriyan pCurrSCCB->Sccb_sgseg =
53535c04a7b8SAlexey Dobriyan (unsigned short)(pCurrSCCB->DataLength /
53545c04a7b8SAlexey Dobriyan SG_ELEMENT_SIZE);
53551da177e4SLinus Torvalds }
53561da177e4SLinus Torvalds }
53571da177e4SLinus Torvalds
53581da177e4SLinus Torvalds else {
53591da177e4SLinus Torvalds if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
53601da177e4SLinus Torvalds pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
53611da177e4SLinus Torvalds }
53621da177e4SLinus Torvalds }
53631da177e4SLinus Torvalds
53641da177e4SLinus Torvalds WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
53651da177e4SLinus Torvalds }
53661da177e4SLinus Torvalds
53671da177e4SLinus Torvalds /*---------------------------------------------------------------------
53681da177e4SLinus Torvalds *
53691da177e4SLinus Torvalds * Function: Host Data Transfer Restart
53701da177e4SLinus Torvalds *
53711da177e4SLinus Torvalds * Description: Reset the available count due to a restore data
53721da177e4SLinus Torvalds * pointers message.
53731da177e4SLinus Torvalds *
53741da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_hostDataXferRestart(struct sccb * currSCCB)537569eb2ea4SAlexey Dobriyan static void FPT_hostDataXferRestart(struct sccb *currSCCB)
53761da177e4SLinus Torvalds {
5377d63a4cccSAlexey Dobriyan unsigned long data_count;
5378ce793215SAlexey Dobriyan unsigned int sg_index;
5379391e2f25SKhalid Aziz struct blogic_sg_seg *segp;
53801da177e4SLinus Torvalds
53811da177e4SLinus Torvalds if (currSCCB->Sccb_XferState & F_SG_XFER) {
53821da177e4SLinus Torvalds
53831da177e4SLinus Torvalds currSCCB->Sccb_XferCnt = 0;
53841da177e4SLinus Torvalds
53851da177e4SLinus Torvalds sg_index = 0xffff; /*Index by long words into sg list. */
53861da177e4SLinus Torvalds data_count = 0; /*Running count of SG xfer counts. */
53871da177e4SLinus Torvalds
53881da177e4SLinus Torvalds
53891da177e4SLinus Torvalds while (data_count < currSCCB->Sccb_ATC) {
53901da177e4SLinus Torvalds
53911da177e4SLinus Torvalds sg_index++;
5392391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5393391e2f25SKhalid Aziz (sg_index * 2);
5394391e2f25SKhalid Aziz data_count += segp->segbytes;
53951da177e4SLinus Torvalds }
53961da177e4SLinus Torvalds
53971da177e4SLinus Torvalds if (data_count == currSCCB->Sccb_ATC) {
53981da177e4SLinus Torvalds
53991da177e4SLinus Torvalds currSCCB->Sccb_SGoffset = 0;
54001da177e4SLinus Torvalds sg_index++;
54011da177e4SLinus Torvalds }
54021da177e4SLinus Torvalds
54031da177e4SLinus Torvalds else {
54045c04a7b8SAlexey Dobriyan currSCCB->Sccb_SGoffset =
54055c04a7b8SAlexey Dobriyan data_count - currSCCB->Sccb_ATC;
54061da177e4SLinus Torvalds }
54071da177e4SLinus Torvalds
5408c823feebSAlexey Dobriyan currSCCB->Sccb_sgseg = (unsigned short)sg_index;
54091da177e4SLinus Torvalds }
54101da177e4SLinus Torvalds
54111da177e4SLinus Torvalds else {
54125c04a7b8SAlexey Dobriyan currSCCB->Sccb_XferCnt =
54135c04a7b8SAlexey Dobriyan currSCCB->DataLength - currSCCB->Sccb_ATC;
54141da177e4SLinus Torvalds }
54151da177e4SLinus Torvalds }
54161da177e4SLinus Torvalds
54171da177e4SLinus Torvalds /*---------------------------------------------------------------------
54181da177e4SLinus Torvalds *
541947b5d69cSJames Bottomley * Function: FPT_scini
54201da177e4SLinus Torvalds *
54211da177e4SLinus Torvalds * Description: Setup all data structures necessary for SCAM selection.
54221da177e4SLinus Torvalds *
54231da177e4SLinus Torvalds *---------------------------------------------------------------------*/
54241da177e4SLinus Torvalds
FPT_scini(unsigned char p_card,unsigned char p_our_id,unsigned char p_power_up)54255c04a7b8SAlexey Dobriyan static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
54265c04a7b8SAlexey Dobriyan unsigned char p_power_up)
54271da177e4SLinus Torvalds {
54281da177e4SLinus Torvalds
5429db038cf8SAlexey Dobriyan unsigned char loser, assigned_id;
5430391e2f25SKhalid Aziz u32 p_port;
54311da177e4SLinus Torvalds
5432db038cf8SAlexey Dobriyan unsigned char i, k, ScamFlg;
543313e6851aSAlexey Dobriyan struct sccb_card *currCard;
543468d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
54351da177e4SLinus Torvalds
543647b5d69cSJames Bottomley currCard = &FPT_BL_Card[p_card];
54371da177e4SLinus Torvalds p_port = currCard->ioPort;
54381da177e4SLinus Torvalds pCurrNvRam = currCard->pNvRamInfo;
54391da177e4SLinus Torvalds
54401da177e4SLinus Torvalds if (pCurrNvRam) {
54411da177e4SLinus Torvalds ScamFlg = pCurrNvRam->niScamConf;
54421da177e4SLinus Torvalds i = pCurrNvRam->niSysConf;
54435c04a7b8SAlexey Dobriyan } else {
54445c04a7b8SAlexey Dobriyan ScamFlg =
54455c04a7b8SAlexey Dobriyan (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
54465c04a7b8SAlexey Dobriyan i = (unsigned
54475c04a7b8SAlexey Dobriyan char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
54481da177e4SLinus Torvalds }
54491da177e4SLinus Torvalds if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
54501da177e4SLinus Torvalds return;
54511da177e4SLinus Torvalds
545247b5d69cSJames Bottomley FPT_inisci(p_card, p_port, p_our_id);
54531da177e4SLinus Torvalds
54541da177e4SLinus Torvalds /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
54551da177e4SLinus Torvalds too slow to return to SCAM selection */
54561da177e4SLinus Torvalds
54571da177e4SLinus Torvalds /* if (p_power_up)
545847b5d69cSJames Bottomley FPT_Wait1Second(p_port);
54591da177e4SLinus Torvalds else
546047b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms); */
54611da177e4SLinus Torvalds
546247b5d69cSJames Bottomley FPT_Wait1Second(p_port);
54631da177e4SLinus Torvalds
54645c04a7b8SAlexey Dobriyan if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
54655c04a7b8SAlexey Dobriyan while (!(FPT_scarb(p_port, INIT_SELTD))) {
54665c04a7b8SAlexey Dobriyan }
54671da177e4SLinus Torvalds
546847b5d69cSJames Bottomley FPT_scsel(p_port);
54691da177e4SLinus Torvalds
54701da177e4SLinus Torvalds do {
547147b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN);
547247b5d69cSJames Bottomley FPT_scxferc(p_port, DOM_MSTR);
54735c04a7b8SAlexey Dobriyan loser =
54745c04a7b8SAlexey Dobriyan FPT_scsendi(p_port,
54755c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id].id_string[0]);
54761da177e4SLinus Torvalds } while (loser == 0xFF);
54771da177e4SLinus Torvalds
547847b5d69cSJames Bottomley FPT_scbusf(p_port);
54791da177e4SLinus Torvalds
54805c04a7b8SAlexey Dobriyan if ((p_power_up) && (!loser)) {
548147b5d69cSJames Bottomley FPT_sresb(p_port, p_card);
548247b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms);
54831da177e4SLinus Torvalds
54845c04a7b8SAlexey Dobriyan while (!(FPT_scarb(p_port, INIT_SELTD))) {
54855c04a7b8SAlexey Dobriyan }
54861da177e4SLinus Torvalds
548747b5d69cSJames Bottomley FPT_scsel(p_port);
54881da177e4SLinus Torvalds
54891da177e4SLinus Torvalds do {
549047b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN);
549147b5d69cSJames Bottomley FPT_scxferc(p_port, DOM_MSTR);
54925c04a7b8SAlexey Dobriyan loser =
54935c04a7b8SAlexey Dobriyan FPT_scsendi(p_port,
54945c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id].
54951da177e4SLinus Torvalds id_string[0]);
54961da177e4SLinus Torvalds } while (loser == 0xFF);
54971da177e4SLinus Torvalds
549847b5d69cSJames Bottomley FPT_scbusf(p_port);
54991da177e4SLinus Torvalds }
55001da177e4SLinus Torvalds }
55011da177e4SLinus Torvalds
55025c04a7b8SAlexey Dobriyan else {
550347b5d69cSJames Bottomley loser = 0;
55041da177e4SLinus Torvalds }
55051da177e4SLinus Torvalds
55065c04a7b8SAlexey Dobriyan if (!loser) {
55071da177e4SLinus Torvalds
550847b5d69cSJames Bottomley FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
55091da177e4SLinus Torvalds
55105c04a7b8SAlexey Dobriyan if (ScamFlg & SCAM_ENABLED) {
55111da177e4SLinus Torvalds
55125c04a7b8SAlexey Dobriyan for (i = 0; i < MAX_SCSI_TAR; i++) {
551347b5d69cSJames Bottomley if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
55145c04a7b8SAlexey Dobriyan (FPT_scamInfo[i].state == ID_UNUSED)) {
55155c04a7b8SAlexey Dobriyan if (FPT_scsell(p_port, i)) {
551647b5d69cSJames Bottomley FPT_scamInfo[i].state = LEGACY;
55175c04a7b8SAlexey Dobriyan if ((FPT_scamInfo[i].
55185c04a7b8SAlexey Dobriyan id_string[0] != 0xFF)
55195c04a7b8SAlexey Dobriyan || (FPT_scamInfo[i].
55205c04a7b8SAlexey Dobriyan id_string[1] != 0xFA)) {
55211da177e4SLinus Torvalds
55225c04a7b8SAlexey Dobriyan FPT_scamInfo[i].
55235c04a7b8SAlexey Dobriyan id_string[0] = 0xFF;
55245c04a7b8SAlexey Dobriyan FPT_scamInfo[i].
55255c04a7b8SAlexey Dobriyan id_string[1] = 0xFA;
55261da177e4SLinus Torvalds if (pCurrNvRam == NULL)
55275c04a7b8SAlexey Dobriyan currCard->
55285c04a7b8SAlexey Dobriyan globalFlags
55295c04a7b8SAlexey Dobriyan |=
55305c04a7b8SAlexey Dobriyan F_UPDATE_EEPROM;
55311da177e4SLinus Torvalds }
55321da177e4SLinus Torvalds }
55331da177e4SLinus Torvalds }
55341da177e4SLinus Torvalds }
55351da177e4SLinus Torvalds
553647b5d69cSJames Bottomley FPT_sresb(p_port, p_card);
553747b5d69cSJames Bottomley FPT_Wait1Second(p_port);
55385c04a7b8SAlexey Dobriyan while (!(FPT_scarb(p_port, INIT_SELTD))) {
55395c04a7b8SAlexey Dobriyan }
554047b5d69cSJames Bottomley FPT_scsel(p_port);
554147b5d69cSJames Bottomley FPT_scasid(p_card, p_port);
55421da177e4SLinus Torvalds }
55431da177e4SLinus Torvalds
55441da177e4SLinus Torvalds }
55451da177e4SLinus Torvalds
55465c04a7b8SAlexey Dobriyan else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
554747b5d69cSJames Bottomley FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
554847b5d69cSJames Bottomley assigned_id = 0;
554947b5d69cSJames Bottomley FPT_scwtsel(p_port);
55501da177e4SLinus Torvalds
55511da177e4SLinus Torvalds do {
55525c04a7b8SAlexey Dobriyan while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
55535c04a7b8SAlexey Dobriyan }
55541da177e4SLinus Torvalds
555547b5d69cSJames Bottomley i = FPT_scxferc(p_port, 0x00);
55565c04a7b8SAlexey Dobriyan if (i == ASSIGN_ID) {
55575c04a7b8SAlexey Dobriyan if (!
55585c04a7b8SAlexey Dobriyan (FPT_scsendi
55595c04a7b8SAlexey Dobriyan (p_port,
55605c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id].id_string[0]))) {
556147b5d69cSJames Bottomley i = FPT_scxferc(p_port, 0x00);
55625c04a7b8SAlexey Dobriyan if (FPT_scvalq(i)) {
556347b5d69cSJames Bottomley k = FPT_scxferc(p_port, 0x00);
55641da177e4SLinus Torvalds
55655c04a7b8SAlexey Dobriyan if (FPT_scvalq(k)) {
55661da177e4SLinus Torvalds currCard->ourId =
55675c04a7b8SAlexey Dobriyan ((unsigned char)(i
55685c04a7b8SAlexey Dobriyan <<
55695c04a7b8SAlexey Dobriyan 3)
55705c04a7b8SAlexey Dobriyan +
55715c04a7b8SAlexey Dobriyan (k &
55725c04a7b8SAlexey Dobriyan (unsigned char)7))
55735c04a7b8SAlexey Dobriyan & (unsigned char)
55745c04a7b8SAlexey Dobriyan 0x3F;
55755c04a7b8SAlexey Dobriyan FPT_inisci(p_card,
55765c04a7b8SAlexey Dobriyan p_port,
55775c04a7b8SAlexey Dobriyan p_our_id);
55785c04a7b8SAlexey Dobriyan FPT_scamInfo[currCard->
55795c04a7b8SAlexey Dobriyan ourId].
55805c04a7b8SAlexey Dobriyan state = ID_ASSIGNED;
55815c04a7b8SAlexey Dobriyan FPT_scamInfo[currCard->
55825c04a7b8SAlexey Dobriyan ourId].
55835c04a7b8SAlexey Dobriyan id_string[0]
55841da177e4SLinus Torvalds = SLV_TYPE_CODE0;
558547b5d69cSJames Bottomley assigned_id = 1;
55861da177e4SLinus Torvalds }
55871da177e4SLinus Torvalds }
55881da177e4SLinus Torvalds }
55891da177e4SLinus Torvalds }
55901da177e4SLinus Torvalds
55915c04a7b8SAlexey Dobriyan else if (i == SET_P_FLAG) {
559247b5d69cSJames Bottomley if (!(FPT_scsendi(p_port,
55935c04a7b8SAlexey Dobriyan &FPT_scamInfo[p_our_id].
55945c04a7b8SAlexey Dobriyan id_string[0])))
55955c04a7b8SAlexey Dobriyan FPT_scamInfo[p_our_id].id_string[0] |=
55965c04a7b8SAlexey Dobriyan 0x80;
55971da177e4SLinus Torvalds }
55981da177e4SLinus Torvalds } while (!assigned_id);
55991da177e4SLinus Torvalds
56005c04a7b8SAlexey Dobriyan while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
56015c04a7b8SAlexey Dobriyan }
56021da177e4SLinus Torvalds }
56031da177e4SLinus Torvalds
56045c04a7b8SAlexey Dobriyan if (ScamFlg & SCAM_ENABLED) {
560547b5d69cSJames Bottomley FPT_scbusf(p_port);
56065c04a7b8SAlexey Dobriyan if (currCard->globalFlags & F_UPDATE_EEPROM) {
560747b5d69cSJames Bottomley FPT_scsavdi(p_card, p_port);
56081da177e4SLinus Torvalds currCard->globalFlags &= ~F_UPDATE_EEPROM;
56091da177e4SLinus Torvalds }
56101da177e4SLinus Torvalds }
56111da177e4SLinus Torvalds
56121da177e4SLinus Torvalds /*
56131da177e4SLinus Torvalds for (i=0,k=0; i < MAX_SCSI_TAR; i++)
56141da177e4SLinus Torvalds {
561547b5d69cSJames Bottomley if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
561647b5d69cSJames Bottomley (FPT_scamInfo[i].state == LEGACY))
56171da177e4SLinus Torvalds k++;
56181da177e4SLinus Torvalds }
56191da177e4SLinus Torvalds
56201da177e4SLinus Torvalds if (k==2)
56211da177e4SLinus Torvalds currCard->globalFlags |= F_SINGLE_DEVICE;
56221da177e4SLinus Torvalds else
56231da177e4SLinus Torvalds currCard->globalFlags &= ~F_SINGLE_DEVICE;
56241da177e4SLinus Torvalds */
56251da177e4SLinus Torvalds }
56261da177e4SLinus Torvalds
56271da177e4SLinus Torvalds /*---------------------------------------------------------------------
56281da177e4SLinus Torvalds *
562947b5d69cSJames Bottomley * Function: FPT_scarb
56301da177e4SLinus Torvalds *
56311da177e4SLinus Torvalds * Description: Gain control of the bus and wait SCAM select time (250ms)
56321da177e4SLinus Torvalds *
56331da177e4SLinus Torvalds *---------------------------------------------------------------------*/
56341da177e4SLinus Torvalds
FPT_scarb(u32 p_port,unsigned char p_sel_type)5635391e2f25SKhalid Aziz static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
56361da177e4SLinus Torvalds {
56375c04a7b8SAlexey Dobriyan if (p_sel_type == INIT_SELTD) {
56381da177e4SLinus Torvalds
56395c04a7b8SAlexey Dobriyan while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
56405c04a7b8SAlexey Dobriyan }
56411da177e4SLinus Torvalds
56421da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
56435c1b85e2SAlexey Dobriyan return 0;
56441da177e4SLinus Torvalds
56451da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
56465c1b85e2SAlexey Dobriyan return 0;
56471da177e4SLinus Torvalds
56485c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
56495c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
56501da177e4SLinus Torvalds
56511da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
56521da177e4SLinus Torvalds
56535c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
56545c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) &
56551da177e4SLinus Torvalds ~SCSI_BSY));
56565c1b85e2SAlexey Dobriyan return 0;
56571da177e4SLinus Torvalds }
56581da177e4SLinus Torvalds
56595c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
56605c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
56611da177e4SLinus Torvalds
56621da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
56631da177e4SLinus Torvalds
56645c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
56655c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) &
56661da177e4SLinus Torvalds ~(SCSI_BSY | SCSI_SEL)));
56675c1b85e2SAlexey Dobriyan return 0;
56681da177e4SLinus Torvalds }
56691da177e4SLinus Torvalds }
56701da177e4SLinus Torvalds
56711da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
56721da177e4SLinus Torvalds & ~ACTdeassert));
56731da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
56741da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, 0x00);
56751da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_1, 0x00);
56761da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
56771da177e4SLinus Torvalds
56785c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
56795c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
56801da177e4SLinus Torvalds
56811da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
56821da177e4SLinus Torvalds & ~SCSI_BSY));
56831da177e4SLinus Torvalds
568447b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms);
56851da177e4SLinus Torvalds
56865c1b85e2SAlexey Dobriyan return 1;
56871da177e4SLinus Torvalds }
56881da177e4SLinus Torvalds
56891da177e4SLinus Torvalds /*---------------------------------------------------------------------
56901da177e4SLinus Torvalds *
569147b5d69cSJames Bottomley * Function: FPT_scbusf
56921da177e4SLinus Torvalds *
56931da177e4SLinus Torvalds * Description: Release the SCSI bus and disable SCAM selection.
56941da177e4SLinus Torvalds *
56951da177e4SLinus Torvalds *---------------------------------------------------------------------*/
56961da177e4SLinus Torvalds
FPT_scbusf(u32 p_port)5697391e2f25SKhalid Aziz static void FPT_scbusf(u32 p_port)
56981da177e4SLinus Torvalds {
56991da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl,
57001da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
57011da177e4SLinus Torvalds
57021da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, 0x00);
57031da177e4SLinus Torvalds
57041da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
57051da177e4SLinus Torvalds & ~SCSI_BUS_EN));
57061da177e4SLinus Torvalds
57071da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, 0x00);
57081da177e4SLinus Torvalds
57091da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
57101da177e4SLinus Torvalds & ~SCAM_EN));
57111da177e4SLinus Torvalds
57121da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
57131da177e4SLinus Torvalds | ACTdeassert));
57141da177e4SLinus Torvalds
57151da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
57161da177e4SLinus Torvalds
57171da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl,
57181da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
57191da177e4SLinus Torvalds }
57201da177e4SLinus Torvalds
57211da177e4SLinus Torvalds /*---------------------------------------------------------------------
57221da177e4SLinus Torvalds *
572347b5d69cSJames Bottomley * Function: FPT_scasid
57241da177e4SLinus Torvalds *
57251da177e4SLinus Torvalds * Description: Assign an ID to all the SCAM devices.
57261da177e4SLinus Torvalds *
57271da177e4SLinus Torvalds *---------------------------------------------------------------------*/
57281da177e4SLinus Torvalds
FPT_scasid(unsigned char p_card,u32 p_port)5729391e2f25SKhalid Aziz static void FPT_scasid(unsigned char p_card, u32 p_port)
57301da177e4SLinus Torvalds {
5731db038cf8SAlexey Dobriyan unsigned char temp_id_string[ID_STRING_LENGTH];
57321da177e4SLinus Torvalds
5733db038cf8SAlexey Dobriyan unsigned char i, k, scam_id;
5734db038cf8SAlexey Dobriyan unsigned char crcBytes[3];
573568d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
5736fd1e29edSAlexey Dobriyan unsigned short *pCrcBytes;
57371da177e4SLinus Torvalds
573847b5d69cSJames Bottomley pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
57391da177e4SLinus Torvalds
574047b5d69cSJames Bottomley i = 0;
57411da177e4SLinus Torvalds
57425c04a7b8SAlexey Dobriyan while (!i) {
57431da177e4SLinus Torvalds
57445c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) {
5745db038cf8SAlexey Dobriyan temp_id_string[k] = (unsigned char)0x00;
57461da177e4SLinus Torvalds }
57471da177e4SLinus Torvalds
574847b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN);
574947b5d69cSJames Bottomley FPT_scxferc(p_port, ASSIGN_ID);
57501da177e4SLinus Torvalds
57515c04a7b8SAlexey Dobriyan if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
57521da177e4SLinus Torvalds if (pCurrNvRam) {
5753fd1e29edSAlexey Dobriyan pCrcBytes = (unsigned short *)&crcBytes[0];
575447b5d69cSJames Bottomley *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
575547b5d69cSJames Bottomley crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
57561da177e4SLinus Torvalds temp_id_string[1] = crcBytes[2];
57571da177e4SLinus Torvalds temp_id_string[2] = crcBytes[0];
57581da177e4SLinus Torvalds temp_id_string[3] = crcBytes[1];
57591da177e4SLinus Torvalds for (k = 4; k < ID_STRING_LENGTH; k++)
5760db038cf8SAlexey Dobriyan temp_id_string[k] = (unsigned char)0x00;
57611da177e4SLinus Torvalds }
576247b5d69cSJames Bottomley i = FPT_scmachid(p_card, temp_id_string);
57631da177e4SLinus Torvalds
57645c04a7b8SAlexey Dobriyan if (i == CLR_PRIORITY) {
576547b5d69cSJames Bottomley FPT_scxferc(p_port, MISC_CODE);
576647b5d69cSJames Bottomley FPT_scxferc(p_port, CLR_P_FLAG);
576747b5d69cSJames Bottomley i = 0; /*Not the last ID yet. */
57681da177e4SLinus Torvalds }
57691da177e4SLinus Torvalds
57705c04a7b8SAlexey Dobriyan else if (i != NO_ID_AVAIL) {
57711da177e4SLinus Torvalds if (i < 8)
577247b5d69cSJames Bottomley FPT_scxferc(p_port, ID_0_7);
57731da177e4SLinus Torvalds else
577447b5d69cSJames Bottomley FPT_scxferc(p_port, ID_8_F);
57751da177e4SLinus Torvalds
5776db038cf8SAlexey Dobriyan scam_id = (i & (unsigned char)0x07);
57771da177e4SLinus Torvalds
57781da177e4SLinus Torvalds for (k = 1; k < 0x08; k <<= 1)
57791da177e4SLinus Torvalds if (!(k & i))
57801da177e4SLinus Torvalds scam_id += 0x08; /*Count number of zeros in DB0-3. */
57811da177e4SLinus Torvalds
578247b5d69cSJames Bottomley FPT_scxferc(p_port, scam_id);
57831da177e4SLinus Torvalds
578447b5d69cSJames Bottomley i = 0; /*Not the last ID yet. */
57851da177e4SLinus Torvalds }
57861da177e4SLinus Torvalds }
57871da177e4SLinus Torvalds
57885c04a7b8SAlexey Dobriyan else {
578947b5d69cSJames Bottomley i = 1;
57901da177e4SLinus Torvalds }
57911da177e4SLinus Torvalds
57921da177e4SLinus Torvalds } /*End while */
57931da177e4SLinus Torvalds
579447b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN);
579547b5d69cSJames Bottomley FPT_scxferc(p_port, CFG_CMPLT);
57961da177e4SLinus Torvalds }
57971da177e4SLinus Torvalds
57981da177e4SLinus Torvalds /*---------------------------------------------------------------------
57991da177e4SLinus Torvalds *
580047b5d69cSJames Bottomley * Function: FPT_scsel
58011da177e4SLinus Torvalds *
58021da177e4SLinus Torvalds * Description: Select all the SCAM devices.
58031da177e4SLinus Torvalds *
58041da177e4SLinus Torvalds *---------------------------------------------------------------------*/
58051da177e4SLinus Torvalds
FPT_scsel(u32 p_port)5806391e2f25SKhalid Aziz static void FPT_scsel(u32 p_port)
58071da177e4SLinus Torvalds {
58081da177e4SLinus Torvalds
58091da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
581047b5d69cSJames Bottomley FPT_scwiros(p_port, SCSI_MSG);
58111da177e4SLinus Torvalds
58121da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
58131da177e4SLinus Torvalds
58145c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
58155c04a7b8SAlexey Dobriyan (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
58165c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsidata_0,
58175c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5818db038cf8SAlexey Dobriyan (unsigned char)(BIT(7) + BIT(6))));
58191da177e4SLinus Torvalds
58201da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
582147b5d69cSJames Bottomley FPT_scwiros(p_port, SCSI_SEL);
58221da177e4SLinus Torvalds
58235c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsidata_0,
58245c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5825db038cf8SAlexey Dobriyan ~(unsigned char)BIT(6)));
582647b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(6));
58271da177e4SLinus Torvalds
58285c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
58295c04a7b8SAlexey Dobriyan (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
58301da177e4SLinus Torvalds }
58311da177e4SLinus Torvalds
58321da177e4SLinus Torvalds /*---------------------------------------------------------------------
58331da177e4SLinus Torvalds *
583447b5d69cSJames Bottomley * Function: FPT_scxferc
58351da177e4SLinus Torvalds *
58361da177e4SLinus Torvalds * Description: Handshake the p_data (DB4-0) across the bus.
58371da177e4SLinus Torvalds *
58381da177e4SLinus Torvalds *---------------------------------------------------------------------*/
58391da177e4SLinus Torvalds
FPT_scxferc(u32 p_port,unsigned char p_data)5840391e2f25SKhalid Aziz static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
58411da177e4SLinus Torvalds {
5842db038cf8SAlexey Dobriyan unsigned char curr_data, ret_data;
58431da177e4SLinus Torvalds
58441da177e4SLinus Torvalds curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
58451da177e4SLinus Torvalds
58461da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data);
58471da177e4SLinus Torvalds
58481da177e4SLinus Torvalds curr_data &= ~BIT(7);
58491da177e4SLinus Torvalds
58501da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data);
58511da177e4SLinus Torvalds
585247b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
58531da177e4SLinus Torvalds while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
58541da177e4SLinus Torvalds
5855db038cf8SAlexey Dobriyan ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
58561da177e4SLinus Torvalds
58571da177e4SLinus Torvalds curr_data |= BIT(6);
58581da177e4SLinus Torvalds
58591da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data);
58601da177e4SLinus Torvalds
58611da177e4SLinus Torvalds curr_data &= ~BIT(5);
58621da177e4SLinus Torvalds
58631da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data);
58641da177e4SLinus Torvalds
586547b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
58661da177e4SLinus Torvalds
58671da177e4SLinus Torvalds curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
58681da177e4SLinus Torvalds curr_data |= BIT(7);
58691da177e4SLinus Torvalds
58701da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data);
58711da177e4SLinus Torvalds
58721da177e4SLinus Torvalds curr_data &= ~BIT(6);
58731da177e4SLinus Torvalds
58741da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsidata_0, curr_data);
58751da177e4SLinus Torvalds
587647b5d69cSJames Bottomley FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
58771da177e4SLinus Torvalds
58785c1b85e2SAlexey Dobriyan return ret_data;
58791da177e4SLinus Torvalds }
58801da177e4SLinus Torvalds
58811da177e4SLinus Torvalds /*---------------------------------------------------------------------
58821da177e4SLinus Torvalds *
588347b5d69cSJames Bottomley * Function: FPT_scsendi
58841da177e4SLinus Torvalds *
58851da177e4SLinus Torvalds * Description: Transfer our Identification string to determine if we
58861da177e4SLinus Torvalds * will be the dominant master.
58871da177e4SLinus Torvalds *
58881da177e4SLinus Torvalds *---------------------------------------------------------------------*/
58891da177e4SLinus Torvalds
FPT_scsendi(u32 p_port,unsigned char p_id_string[])5890391e2f25SKhalid Aziz static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
58911da177e4SLinus Torvalds {
5892db038cf8SAlexey Dobriyan unsigned char ret_data, byte_cnt, bit_cnt, defer;
58931da177e4SLinus Torvalds
589447b5d69cSJames Bottomley defer = 0;
58951da177e4SLinus Torvalds
58961da177e4SLinus Torvalds for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
58971da177e4SLinus Torvalds
58981da177e4SLinus Torvalds for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
58991da177e4SLinus Torvalds
59001da177e4SLinus Torvalds if (defer)
590147b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 00);
59021da177e4SLinus Torvalds
59031da177e4SLinus Torvalds else if (p_id_string[byte_cnt] & bit_cnt)
59041da177e4SLinus Torvalds
590547b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 02);
59061da177e4SLinus Torvalds
59071da177e4SLinus Torvalds else {
59081da177e4SLinus Torvalds
590947b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 01);
59101da177e4SLinus Torvalds if (ret_data & 02)
591147b5d69cSJames Bottomley defer = 1;
59121da177e4SLinus Torvalds }
59131da177e4SLinus Torvalds
59141da177e4SLinus Torvalds if ((ret_data & 0x1C) == 0x10)
59155c1b85e2SAlexey Dobriyan return 0x00; /*End of isolation stage, we won! */
59161da177e4SLinus Torvalds
59171da177e4SLinus Torvalds if (ret_data & 0x1C)
59185c1b85e2SAlexey Dobriyan return 0xFF;
59191da177e4SLinus Torvalds
59201da177e4SLinus Torvalds if ((defer) && (!(ret_data & 0x1F)))
59215c1b85e2SAlexey Dobriyan return 0x01; /*End of isolation stage, we lost. */
59221da177e4SLinus Torvalds
59231da177e4SLinus Torvalds } /*bit loop */
59241da177e4SLinus Torvalds
59251da177e4SLinus Torvalds } /*byte loop */
59261da177e4SLinus Torvalds
59271da177e4SLinus Torvalds if (defer)
59285c1b85e2SAlexey Dobriyan return 0x01; /*We lost */
59291da177e4SLinus Torvalds else
59305c1b85e2SAlexey Dobriyan return 0; /*We WON! Yeeessss! */
59311da177e4SLinus Torvalds }
59321da177e4SLinus Torvalds
59331da177e4SLinus Torvalds /*---------------------------------------------------------------------
59341da177e4SLinus Torvalds *
593547b5d69cSJames Bottomley * Function: FPT_sciso
59361da177e4SLinus Torvalds *
59371da177e4SLinus Torvalds * Description: Transfer the Identification string.
59381da177e4SLinus Torvalds *
59391da177e4SLinus Torvalds *---------------------------------------------------------------------*/
59401da177e4SLinus Torvalds
FPT_sciso(u32 p_port,unsigned char p_id_string[])5941391e2f25SKhalid Aziz static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
59421da177e4SLinus Torvalds {
5943db038cf8SAlexey Dobriyan unsigned char ret_data, the_data, byte_cnt, bit_cnt;
59441da177e4SLinus Torvalds
59451da177e4SLinus Torvalds the_data = 0;
59461da177e4SLinus Torvalds
59471da177e4SLinus Torvalds for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
59481da177e4SLinus Torvalds
59491da177e4SLinus Torvalds for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
59501da177e4SLinus Torvalds
595147b5d69cSJames Bottomley ret_data = FPT_scxferc(p_port, 0);
59521da177e4SLinus Torvalds
59531da177e4SLinus Torvalds if (ret_data & 0xFC)
59545c1b85e2SAlexey Dobriyan return 0xFF;
59551da177e4SLinus Torvalds
59561da177e4SLinus Torvalds else {
59571da177e4SLinus Torvalds
59581da177e4SLinus Torvalds the_data <<= 1;
59591da177e4SLinus Torvalds if (ret_data & BIT(1)) {
59601da177e4SLinus Torvalds the_data |= 1;
59611da177e4SLinus Torvalds }
59621da177e4SLinus Torvalds }
59631da177e4SLinus Torvalds
59645c04a7b8SAlexey Dobriyan if ((ret_data & 0x1F) == 0) {
59651da177e4SLinus Torvalds /*
59661da177e4SLinus Torvalds if(bit_cnt != 0 || bit_cnt != 8)
59671da177e4SLinus Torvalds {
59681da177e4SLinus Torvalds byte_cnt = 0;
59691da177e4SLinus Torvalds bit_cnt = 0;
597047b5d69cSJames Bottomley FPT_scxferc(p_port, SYNC_PTRN);
597147b5d69cSJames Bottomley FPT_scxferc(p_port, ASSIGN_ID);
59721da177e4SLinus Torvalds continue;
59731da177e4SLinus Torvalds }
59741da177e4SLinus Torvalds */
59751da177e4SLinus Torvalds if (byte_cnt)
59765c1b85e2SAlexey Dobriyan return 0x00;
59771da177e4SLinus Torvalds else
59785c1b85e2SAlexey Dobriyan return 0xFF;
59791da177e4SLinus Torvalds }
59801da177e4SLinus Torvalds
59811da177e4SLinus Torvalds } /*bit loop */
59821da177e4SLinus Torvalds
59831da177e4SLinus Torvalds p_id_string[byte_cnt] = the_data;
59841da177e4SLinus Torvalds
59851da177e4SLinus Torvalds } /*byte loop */
59861da177e4SLinus Torvalds
59875c1b85e2SAlexey Dobriyan return 0;
59881da177e4SLinus Torvalds }
59891da177e4SLinus Torvalds
59901da177e4SLinus Torvalds /*---------------------------------------------------------------------
59911da177e4SLinus Torvalds *
599247b5d69cSJames Bottomley * Function: FPT_scwirod
59931da177e4SLinus Torvalds *
59941da177e4SLinus Torvalds * Description: Sample the SCSI data bus making sure the signal has been
59951da177e4SLinus Torvalds * deasserted for the correct number of consecutive samples.
59961da177e4SLinus Torvalds *
59971da177e4SLinus Torvalds *---------------------------------------------------------------------*/
59981da177e4SLinus Torvalds
FPT_scwirod(u32 p_port,unsigned char p_data_bit)5999391e2f25SKhalid Aziz static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
60001da177e4SLinus Torvalds {
6001db038cf8SAlexey Dobriyan unsigned char i;
60021da177e4SLinus Torvalds
60031da177e4SLinus Torvalds i = 0;
60041da177e4SLinus Torvalds while (i < MAX_SCSI_TAR) {
60051da177e4SLinus Torvalds
60061da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
60071da177e4SLinus Torvalds
60081da177e4SLinus Torvalds i = 0;
60091da177e4SLinus Torvalds
60101da177e4SLinus Torvalds else
60111da177e4SLinus Torvalds
60121da177e4SLinus Torvalds i++;
60131da177e4SLinus Torvalds
60141da177e4SLinus Torvalds }
60151da177e4SLinus Torvalds }
60161da177e4SLinus Torvalds
60171da177e4SLinus Torvalds /*---------------------------------------------------------------------
60181da177e4SLinus Torvalds *
601947b5d69cSJames Bottomley * Function: FPT_scwiros
60201da177e4SLinus Torvalds *
60211da177e4SLinus Torvalds * Description: Sample the SCSI Signal lines making sure the signal has been
60221da177e4SLinus Torvalds * deasserted for the correct number of consecutive samples.
60231da177e4SLinus Torvalds *
60241da177e4SLinus Torvalds *---------------------------------------------------------------------*/
60251da177e4SLinus Torvalds
FPT_scwiros(u32 p_port,unsigned char p_data_bit)6026391e2f25SKhalid Aziz static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
60271da177e4SLinus Torvalds {
6028db038cf8SAlexey Dobriyan unsigned char i;
60291da177e4SLinus Torvalds
60301da177e4SLinus Torvalds i = 0;
60311da177e4SLinus Torvalds while (i < MAX_SCSI_TAR) {
60321da177e4SLinus Torvalds
60331da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
60341da177e4SLinus Torvalds
60351da177e4SLinus Torvalds i = 0;
60361da177e4SLinus Torvalds
60371da177e4SLinus Torvalds else
60381da177e4SLinus Torvalds
60391da177e4SLinus Torvalds i++;
60401da177e4SLinus Torvalds
60411da177e4SLinus Torvalds }
60421da177e4SLinus Torvalds }
60431da177e4SLinus Torvalds
60441da177e4SLinus Torvalds /*---------------------------------------------------------------------
60451da177e4SLinus Torvalds *
604647b5d69cSJames Bottomley * Function: FPT_scvalq
60471da177e4SLinus Torvalds *
60481da177e4SLinus Torvalds * Description: Make sure we received a valid data byte.
60491da177e4SLinus Torvalds *
60501da177e4SLinus Torvalds *---------------------------------------------------------------------*/
60511da177e4SLinus Torvalds
FPT_scvalq(unsigned char p_quintet)6052db038cf8SAlexey Dobriyan static unsigned char FPT_scvalq(unsigned char p_quintet)
60531da177e4SLinus Torvalds {
6054db038cf8SAlexey Dobriyan unsigned char count;
60551da177e4SLinus Torvalds
60561da177e4SLinus Torvalds for (count = 1; count < 0x08; count <<= 1) {
60571da177e4SLinus Torvalds if (!(p_quintet & count))
60581da177e4SLinus Torvalds p_quintet -= 0x80;
60591da177e4SLinus Torvalds }
60601da177e4SLinus Torvalds
60611da177e4SLinus Torvalds if (p_quintet & 0x18)
60625c1b85e2SAlexey Dobriyan return 0;
60631da177e4SLinus Torvalds
60641da177e4SLinus Torvalds else
60655c1b85e2SAlexey Dobriyan return 1;
60661da177e4SLinus Torvalds }
60671da177e4SLinus Torvalds
60681da177e4SLinus Torvalds /*---------------------------------------------------------------------
60691da177e4SLinus Torvalds *
607047b5d69cSJames Bottomley * Function: FPT_scsell
60711da177e4SLinus Torvalds *
60721da177e4SLinus Torvalds * Description: Select the specified device ID using a selection timeout
60731da177e4SLinus Torvalds * less than 4ms. If somebody responds then it is a legacy
60741da177e4SLinus Torvalds * drive and this ID must be marked as such.
60751da177e4SLinus Torvalds *
60761da177e4SLinus Torvalds *---------------------------------------------------------------------*/
60771da177e4SLinus Torvalds
FPT_scsell(u32 p_port,unsigned char targ_id)6078391e2f25SKhalid Aziz static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
60791da177e4SLinus Torvalds {
6080d63a4cccSAlexey Dobriyan unsigned long i;
60811da177e4SLinus Torvalds
60821da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl,
60831da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
60841da177e4SLinus Torvalds
60851da177e4SLinus Torvalds ARAM_ACCESS(p_port);
60861da177e4SLinus Torvalds
60875c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_addstat,
60885c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
60891da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
60901da177e4SLinus Torvalds
60911da177e4SLinus Torvalds for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
60921da177e4SLinus Torvalds WRW_HARPOON(i, (MPM_OP + ACOMMAND));
60931da177e4SLinus Torvalds }
60941da177e4SLinus Torvalds WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
60951da177e4SLinus Torvalds
60961da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat),
60971da177e4SLinus Torvalds (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
60981da177e4SLinus Torvalds
60991da177e4SLinus Torvalds WR_HARPOON(p_port + hp_select_id, targ_id);
61001da177e4SLinus Torvalds
61011da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
61021da177e4SLinus Torvalds WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
61031da177e4SLinus Torvalds WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
61041da177e4SLinus Torvalds
61051da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) &
61065c04a7b8SAlexey Dobriyan (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
61075c04a7b8SAlexey Dobriyan }
61081da177e4SLinus Torvalds
61091da177e4SLinus Torvalds if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
611047b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms);
61111da177e4SLinus Torvalds
61121da177e4SLinus Torvalds DISABLE_AUTO(p_port);
61131da177e4SLinus Torvalds
61145c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_addstat,
61155c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
61161da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
61171da177e4SLinus Torvalds
61181da177e4SLinus Torvalds SGRAM_ACCESS(p_port);
61191da177e4SLinus Torvalds
61201da177e4SLinus Torvalds if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
61211da177e4SLinus Torvalds
61221da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat),
61231da177e4SLinus Torvalds (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
61241da177e4SLinus Torvalds
61251da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl,
61265c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_page_ctrl) &
61275c04a7b8SAlexey Dobriyan ~G_INT_DISABLE));
61281da177e4SLinus Torvalds
61295c1b85e2SAlexey Dobriyan return 0; /*No legacy device */
61301da177e4SLinus Torvalds }
61311da177e4SLinus Torvalds
61321da177e4SLinus Torvalds else {
61331da177e4SLinus Torvalds
61341da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
61355c04a7b8SAlexey Dobriyan if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
61365c04a7b8SAlexey Dobriyan WR_HARPOON(p_port + hp_scsisig,
61375c04a7b8SAlexey Dobriyan (SCSI_ACK + S_ILL_PH));
61381da177e4SLinus Torvalds ACCEPT_MSG(p_port);
61391da177e4SLinus Torvalds }
61401da177e4SLinus Torvalds }
61411da177e4SLinus Torvalds
61421da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
61431da177e4SLinus Torvalds
61441da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl,
61455c04a7b8SAlexey Dobriyan (RD_HARPOON(p_port + hp_page_ctrl) &
61465c04a7b8SAlexey Dobriyan ~G_INT_DISABLE));
61471da177e4SLinus Torvalds
61485c1b85e2SAlexey Dobriyan return 1; /*Found one of them oldies! */
61491da177e4SLinus Torvalds }
61501da177e4SLinus Torvalds }
61511da177e4SLinus Torvalds
61521da177e4SLinus Torvalds /*---------------------------------------------------------------------
61531da177e4SLinus Torvalds *
615447b5d69cSJames Bottomley * Function: FPT_scwtsel
61551da177e4SLinus Torvalds *
61561da177e4SLinus Torvalds * Description: Wait to be selected by another SCAM initiator.
61571da177e4SLinus Torvalds *
61581da177e4SLinus Torvalds *---------------------------------------------------------------------*/
61591da177e4SLinus Torvalds
FPT_scwtsel(u32 p_port)6160391e2f25SKhalid Aziz static void FPT_scwtsel(u32 p_port)
61611da177e4SLinus Torvalds {
61625c04a7b8SAlexey Dobriyan while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
61631da177e4SLinus Torvalds }
61645c04a7b8SAlexey Dobriyan }
61651da177e4SLinus Torvalds
61661da177e4SLinus Torvalds /*---------------------------------------------------------------------
61671da177e4SLinus Torvalds *
616847b5d69cSJames Bottomley * Function: FPT_inisci
61691da177e4SLinus Torvalds *
61701da177e4SLinus Torvalds * Description: Setup the data Structure with the info from the EEPROM.
61711da177e4SLinus Torvalds *
61721da177e4SLinus Torvalds *---------------------------------------------------------------------*/
61731da177e4SLinus Torvalds
FPT_inisci(unsigned char p_card,u32 p_port,unsigned char p_our_id)6174391e2f25SKhalid Aziz static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
61751da177e4SLinus Torvalds {
6176db038cf8SAlexey Dobriyan unsigned char i, k, max_id;
6177c823feebSAlexey Dobriyan unsigned short ee_data;
617868d0c1aeSAlexey Dobriyan struct nvram_info *pCurrNvRam;
61791da177e4SLinus Torvalds
618047b5d69cSJames Bottomley pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
61811da177e4SLinus Torvalds
61821da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
61831da177e4SLinus Torvalds max_id = 0x08;
61841da177e4SLinus Torvalds
61851da177e4SLinus Torvalds else
61861da177e4SLinus Torvalds max_id = 0x10;
61871da177e4SLinus Torvalds
61881da177e4SLinus Torvalds if (pCurrNvRam) {
61891da177e4SLinus Torvalds for (i = 0; i < max_id; i++) {
61901da177e4SLinus Torvalds
61911da177e4SLinus Torvalds for (k = 0; k < 4; k++)
61925c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k] =
61935c04a7b8SAlexey Dobriyan pCurrNvRam->niScamTbl[i][k];
61941da177e4SLinus Torvalds for (k = 4; k < ID_STRING_LENGTH; k++)
61955c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k] =
61965c04a7b8SAlexey Dobriyan (unsigned char)0x00;
61971da177e4SLinus Torvalds
619847b5d69cSJames Bottomley if (FPT_scamInfo[i].id_string[0] == 0x00)
619947b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
62001da177e4SLinus Torvalds else
620147b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
62021da177e4SLinus Torvalds
62031da177e4SLinus Torvalds }
62041da177e4SLinus Torvalds } else {
62055c04a7b8SAlexey Dobriyan for (i = 0; i < max_id; i++) {
62065c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k += 2) {
62075c04a7b8SAlexey Dobriyan ee_data =
62085c04a7b8SAlexey Dobriyan FPT_utilEERead(p_port,
62095c04a7b8SAlexey Dobriyan (unsigned
62105c04a7b8SAlexey Dobriyan short)((EE_SCAMBASE / 2) +
62115c04a7b8SAlexey Dobriyan (unsigned short)(i *
62125c04a7b8SAlexey Dobriyan ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
62135c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k] =
62145c04a7b8SAlexey Dobriyan (unsigned char)ee_data;
62151da177e4SLinus Torvalds ee_data >>= 8;
62165c04a7b8SAlexey Dobriyan FPT_scamInfo[i].id_string[k + 1] =
62175c04a7b8SAlexey Dobriyan (unsigned char)ee_data;
62181da177e4SLinus Torvalds }
62191da177e4SLinus Torvalds
622047b5d69cSJames Bottomley if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
622147b5d69cSJames Bottomley (FPT_scamInfo[i].id_string[0] == 0xFF))
62221da177e4SLinus Torvalds
622347b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
62241da177e4SLinus Torvalds
62251da177e4SLinus Torvalds else
622647b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
62271da177e4SLinus Torvalds
62281da177e4SLinus Torvalds }
62291da177e4SLinus Torvalds }
62301da177e4SLinus Torvalds for (k = 0; k < ID_STRING_LENGTH; k++)
623147b5d69cSJames Bottomley FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
62321da177e4SLinus Torvalds
62331da177e4SLinus Torvalds }
62341da177e4SLinus Torvalds
62351da177e4SLinus Torvalds /*---------------------------------------------------------------------
62361da177e4SLinus Torvalds *
623747b5d69cSJames Bottomley * Function: FPT_scmachid
62381da177e4SLinus Torvalds *
62391da177e4SLinus Torvalds * Description: Match the Device ID string with our values stored in
62401da177e4SLinus Torvalds * the EEPROM.
62411da177e4SLinus Torvalds *
62421da177e4SLinus Torvalds *---------------------------------------------------------------------*/
62431da177e4SLinus Torvalds
FPT_scmachid(unsigned char p_card,unsigned char p_id_string[])62445c04a7b8SAlexey Dobriyan static unsigned char FPT_scmachid(unsigned char p_card,
62455c04a7b8SAlexey Dobriyan unsigned char p_id_string[])
62461da177e4SLinus Torvalds {
62471da177e4SLinus Torvalds
6248db038cf8SAlexey Dobriyan unsigned char i, k, match;
62491da177e4SLinus Torvalds
62501da177e4SLinus Torvalds for (i = 0; i < MAX_SCSI_TAR; i++) {
62511da177e4SLinus Torvalds
625247b5d69cSJames Bottomley match = 1;
62531da177e4SLinus Torvalds
62545c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) {
625547b5d69cSJames Bottomley if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
625647b5d69cSJames Bottomley match = 0;
62571da177e4SLinus Torvalds }
62581da177e4SLinus Torvalds
62595c04a7b8SAlexey Dobriyan if (match) {
626047b5d69cSJames Bottomley FPT_scamInfo[i].state = ID_ASSIGNED;
62615c1b85e2SAlexey Dobriyan return i;
62621da177e4SLinus Torvalds }
62631da177e4SLinus Torvalds
62641da177e4SLinus Torvalds }
62651da177e4SLinus Torvalds
62661da177e4SLinus Torvalds if (p_id_string[0] & BIT(5))
62671da177e4SLinus Torvalds i = 8;
62681da177e4SLinus Torvalds else
62691da177e4SLinus Torvalds i = MAX_SCSI_TAR;
62701da177e4SLinus Torvalds
62715c04a7b8SAlexey Dobriyan if (((p_id_string[0] & 0x06) == 0x02)
62725c04a7b8SAlexey Dobriyan || ((p_id_string[0] & 0x06) == 0x04))
6273db038cf8SAlexey Dobriyan match = p_id_string[1] & (unsigned char)0x1F;
62741da177e4SLinus Torvalds else
62751da177e4SLinus Torvalds match = 7;
62761da177e4SLinus Torvalds
62775c04a7b8SAlexey Dobriyan while (i > 0) {
62781da177e4SLinus Torvalds i--;
62791da177e4SLinus Torvalds
62805c04a7b8SAlexey Dobriyan if (FPT_scamInfo[match].state == ID_UNUSED) {
62815c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) {
62825c04a7b8SAlexey Dobriyan FPT_scamInfo[match].id_string[k] =
62835c04a7b8SAlexey Dobriyan p_id_string[k];
62841da177e4SLinus Torvalds }
62851da177e4SLinus Torvalds
628647b5d69cSJames Bottomley FPT_scamInfo[match].state = ID_ASSIGNED;
62871da177e4SLinus Torvalds
628847b5d69cSJames Bottomley if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
62895c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |=
62905c04a7b8SAlexey Dobriyan F_UPDATE_EEPROM;
62915c1b85e2SAlexey Dobriyan return match;
62921da177e4SLinus Torvalds
62931da177e4SLinus Torvalds }
62941da177e4SLinus Torvalds
62951da177e4SLinus Torvalds match--;
62961da177e4SLinus Torvalds
62975c04a7b8SAlexey Dobriyan if (match == 0xFF) {
62981da177e4SLinus Torvalds if (p_id_string[0] & BIT(5))
62991da177e4SLinus Torvalds match = 7;
63001da177e4SLinus Torvalds else
63011da177e4SLinus Torvalds match = MAX_SCSI_TAR - 1;
63021da177e4SLinus Torvalds }
63031da177e4SLinus Torvalds }
63041da177e4SLinus Torvalds
63055c04a7b8SAlexey Dobriyan if (p_id_string[0] & BIT(7)) {
63065c1b85e2SAlexey Dobriyan return CLR_PRIORITY;
63071da177e4SLinus Torvalds }
63081da177e4SLinus Torvalds
63091da177e4SLinus Torvalds if (p_id_string[0] & BIT(5))
63101da177e4SLinus Torvalds i = 8;
63111da177e4SLinus Torvalds else
63121da177e4SLinus Torvalds i = MAX_SCSI_TAR;
63131da177e4SLinus Torvalds
63145c04a7b8SAlexey Dobriyan if (((p_id_string[0] & 0x06) == 0x02)
63155c04a7b8SAlexey Dobriyan || ((p_id_string[0] & 0x06) == 0x04))
6316db038cf8SAlexey Dobriyan match = p_id_string[1] & (unsigned char)0x1F;
63171da177e4SLinus Torvalds else
63181da177e4SLinus Torvalds match = 7;
63191da177e4SLinus Torvalds
63205c04a7b8SAlexey Dobriyan while (i > 0) {
63211da177e4SLinus Torvalds
63221da177e4SLinus Torvalds i--;
63231da177e4SLinus Torvalds
63245c04a7b8SAlexey Dobriyan if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
63255c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k++) {
63265c04a7b8SAlexey Dobriyan FPT_scamInfo[match].id_string[k] =
63275c04a7b8SAlexey Dobriyan p_id_string[k];
63281da177e4SLinus Torvalds }
63291da177e4SLinus Torvalds
633047b5d69cSJames Bottomley FPT_scamInfo[match].id_string[0] |= BIT(7);
633147b5d69cSJames Bottomley FPT_scamInfo[match].state = ID_ASSIGNED;
633247b5d69cSJames Bottomley if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
63335c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].globalFlags |=
63345c04a7b8SAlexey Dobriyan F_UPDATE_EEPROM;
63355c1b85e2SAlexey Dobriyan return match;
63361da177e4SLinus Torvalds
63371da177e4SLinus Torvalds }
63381da177e4SLinus Torvalds
63391da177e4SLinus Torvalds match--;
63401da177e4SLinus Torvalds
63415c04a7b8SAlexey Dobriyan if (match == 0xFF) {
63421da177e4SLinus Torvalds if (p_id_string[0] & BIT(5))
63431da177e4SLinus Torvalds match = 7;
63441da177e4SLinus Torvalds else
63451da177e4SLinus Torvalds match = MAX_SCSI_TAR - 1;
63461da177e4SLinus Torvalds }
63471da177e4SLinus Torvalds }
63481da177e4SLinus Torvalds
63495c1b85e2SAlexey Dobriyan return NO_ID_AVAIL;
63501da177e4SLinus Torvalds }
63511da177e4SLinus Torvalds
63521da177e4SLinus Torvalds /*---------------------------------------------------------------------
63531da177e4SLinus Torvalds *
635447b5d69cSJames Bottomley * Function: FPT_scsavdi
63551da177e4SLinus Torvalds *
63561da177e4SLinus Torvalds * Description: Save off the device SCAM ID strings.
63571da177e4SLinus Torvalds *
63581da177e4SLinus Torvalds *---------------------------------------------------------------------*/
63591da177e4SLinus Torvalds
FPT_scsavdi(unsigned char p_card,u32 p_port)6360391e2f25SKhalid Aziz static void FPT_scsavdi(unsigned char p_card, u32 p_port)
63611da177e4SLinus Torvalds {
6362db038cf8SAlexey Dobriyan unsigned char i, k, max_id;
6363c823feebSAlexey Dobriyan unsigned short ee_data, sum_data;
63641da177e4SLinus Torvalds
63651da177e4SLinus Torvalds sum_data = 0x0000;
63661da177e4SLinus Torvalds
63675c04a7b8SAlexey Dobriyan for (i = 1; i < EE_SCAMBASE / 2; i++) {
636847b5d69cSJames Bottomley sum_data += FPT_utilEERead(p_port, i);
63691da177e4SLinus Torvalds }
63701da177e4SLinus Torvalds
637147b5d69cSJames Bottomley FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
63721da177e4SLinus Torvalds
63731da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
63741da177e4SLinus Torvalds max_id = 0x08;
63751da177e4SLinus Torvalds
63761da177e4SLinus Torvalds else
63771da177e4SLinus Torvalds max_id = 0x10;
63781da177e4SLinus Torvalds
63795c04a7b8SAlexey Dobriyan for (i = 0; i < max_id; i++) {
63801da177e4SLinus Torvalds
63815c04a7b8SAlexey Dobriyan for (k = 0; k < ID_STRING_LENGTH; k += 2) {
638247b5d69cSJames Bottomley ee_data = FPT_scamInfo[i].id_string[k + 1];
63831da177e4SLinus Torvalds ee_data <<= 8;
638447b5d69cSJames Bottomley ee_data |= FPT_scamInfo[i].id_string[k];
63851da177e4SLinus Torvalds sum_data += ee_data;
63865c04a7b8SAlexey Dobriyan FPT_utilEEWrite(p_port, ee_data,
63875c04a7b8SAlexey Dobriyan (unsigned short)((EE_SCAMBASE / 2) +
63885c04a7b8SAlexey Dobriyan (unsigned short)(i *
63895c04a7b8SAlexey Dobriyan ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
63901da177e4SLinus Torvalds }
63911da177e4SLinus Torvalds }
63921da177e4SLinus Torvalds
639347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
639447b5d69cSJames Bottomley FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
63951da177e4SLinus Torvalds }
63961da177e4SLinus Torvalds
63971da177e4SLinus Torvalds /*---------------------------------------------------------------------
63981da177e4SLinus Torvalds *
639947b5d69cSJames Bottomley * Function: FPT_XbowInit
64001da177e4SLinus Torvalds *
64011da177e4SLinus Torvalds * Description: Setup the Xbow for normal operation.
64021da177e4SLinus Torvalds *
64031da177e4SLinus Torvalds *---------------------------------------------------------------------*/
64041da177e4SLinus Torvalds
FPT_XbowInit(u32 port,unsigned char ScamFlg)6405391e2f25SKhalid Aziz static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
64061da177e4SLinus Torvalds {
6407db038cf8SAlexey Dobriyan unsigned char i;
64081da177e4SLinus Torvalds
64091da177e4SLinus Torvalds i = RD_HARPOON(port + hp_page_ctrl);
6410db038cf8SAlexey Dobriyan WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
64111da177e4SLinus Torvalds
64121da177e4SLinus Torvalds WR_HARPOON(port + hp_scsireset, 0x00);
64131da177e4SLinus Torvalds WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
64141da177e4SLinus Torvalds
64155c04a7b8SAlexey Dobriyan WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
64161da177e4SLinus Torvalds FIFO_CLR));
64171da177e4SLinus Torvalds
64181da177e4SLinus Torvalds WR_HARPOON(port + hp_scsireset, SCSI_INI);
64191da177e4SLinus Torvalds
64201da177e4SLinus Torvalds WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
64211da177e4SLinus Torvalds
64221da177e4SLinus Torvalds WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
64231da177e4SLinus Torvalds WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
64241da177e4SLinus Torvalds
64251da177e4SLinus Torvalds WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
64261da177e4SLinus Torvalds
642747b5d69cSJames Bottomley FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
64281da177e4SLinus Torvalds BUS_FREE | XFER_CNT_0 | AUTO_INT;
64291da177e4SLinus Torvalds
64301da177e4SLinus Torvalds if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
643147b5d69cSJames Bottomley FPT_default_intena |= SCAM_SEL;
64321da177e4SLinus Torvalds
643347b5d69cSJames Bottomley WRW_HARPOON((port + hp_intena), FPT_default_intena);
64341da177e4SLinus Torvalds
64351da177e4SLinus Torvalds WR_HARPOON(port + hp_seltimeout, TO_290ms);
64361da177e4SLinus Torvalds
64371da177e4SLinus Torvalds /* Turn on SCSI_MODE8 for narrow cards to fix the
64381da177e4SLinus Torvalds strapping issue with the DUAL CHANNEL card */
64391da177e4SLinus Torvalds if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
64401da177e4SLinus Torvalds WR_HARPOON(port + hp_addstat, SCSI_MODE8);
64411da177e4SLinus Torvalds
64421da177e4SLinus Torvalds WR_HARPOON(port + hp_page_ctrl, i);
64431da177e4SLinus Torvalds
64441da177e4SLinus Torvalds }
64451da177e4SLinus Torvalds
64461da177e4SLinus Torvalds /*---------------------------------------------------------------------
64471da177e4SLinus Torvalds *
644847b5d69cSJames Bottomley * Function: FPT_BusMasterInit
64491da177e4SLinus Torvalds *
64501da177e4SLinus Torvalds * Description: Initialize the BusMaster for normal operations.
64511da177e4SLinus Torvalds *
64521da177e4SLinus Torvalds *---------------------------------------------------------------------*/
64531da177e4SLinus Torvalds
FPT_BusMasterInit(u32 p_port)6454391e2f25SKhalid Aziz static void FPT_BusMasterInit(u32 p_port)
64551da177e4SLinus Torvalds {
64561da177e4SLinus Torvalds
64571da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
64581da177e4SLinus Torvalds WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
64591da177e4SLinus Torvalds
64601da177e4SLinus Torvalds WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
64611da177e4SLinus Torvalds
64621da177e4SLinus Torvalds WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
64631da177e4SLinus Torvalds
64641da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
64651da177e4SLinus Torvalds
64661da177e4SLinus Torvalds RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
64671da177e4SLinus Torvalds WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
64681da177e4SLinus Torvalds WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
64691da177e4SLinus Torvalds ~SCATTER_EN));
64701da177e4SLinus Torvalds }
64711da177e4SLinus Torvalds
64721da177e4SLinus Torvalds /*---------------------------------------------------------------------
64731da177e4SLinus Torvalds *
647447b5d69cSJames Bottomley * Function: FPT_DiagEEPROM
64751da177e4SLinus Torvalds *
64761da177e4SLinus Torvalds * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
64771da177e4SLinus Torvalds * necessary.
64781da177e4SLinus Torvalds *
64791da177e4SLinus Torvalds *---------------------------------------------------------------------*/
64801da177e4SLinus Torvalds
FPT_DiagEEPROM(u32 p_port)6481391e2f25SKhalid Aziz static void FPT_DiagEEPROM(u32 p_port)
64821da177e4SLinus Torvalds {
6483c823feebSAlexey Dobriyan unsigned short index, temp, max_wd_cnt;
64841da177e4SLinus Torvalds
64851da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
64861da177e4SLinus Torvalds max_wd_cnt = EEPROM_WD_CNT;
64871da177e4SLinus Torvalds else
64881da177e4SLinus Torvalds max_wd_cnt = EEPROM_WD_CNT * 2;
64891da177e4SLinus Torvalds
649047b5d69cSJames Bottomley temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
64911da177e4SLinus Torvalds
64921da177e4SLinus Torvalds if (temp == 0x4641) {
64931da177e4SLinus Torvalds
64941da177e4SLinus Torvalds for (index = 2; index < max_wd_cnt; index++) {
64951da177e4SLinus Torvalds
649647b5d69cSJames Bottomley temp += FPT_utilEERead(p_port, index);
64971da177e4SLinus Torvalds
64981da177e4SLinus Torvalds }
64991da177e4SLinus Torvalds
650047b5d69cSJames Bottomley if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
65011da177e4SLinus Torvalds
65021da177e4SLinus Torvalds return; /*EEPROM is Okay so return now! */
65031da177e4SLinus Torvalds }
65041da177e4SLinus Torvalds }
65051da177e4SLinus Torvalds
6506db038cf8SAlexey Dobriyan FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
65071da177e4SLinus Torvalds
65081da177e4SLinus Torvalds for (index = 0; index < max_wd_cnt; index++) {
65091da177e4SLinus Torvalds
651047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, index);
65111da177e4SLinus Torvalds }
65121da177e4SLinus Torvalds
65131da177e4SLinus Torvalds temp = 0;
65141da177e4SLinus Torvalds
651547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
65161da177e4SLinus Torvalds temp += 0x4641;
651747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
65181da177e4SLinus Torvalds temp += 0x3920;
651947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
65201da177e4SLinus Torvalds temp += 0x3033;
652147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
65221da177e4SLinus Torvalds temp += 0x2020;
652347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
65241da177e4SLinus Torvalds temp += 0x70D3;
652547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
65261da177e4SLinus Torvalds temp += 0x0010;
652747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
65281da177e4SLinus Torvalds temp += 0x0003;
652947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
65301da177e4SLinus Torvalds temp += 0x0007;
65311da177e4SLinus Torvalds
653247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
65331da177e4SLinus Torvalds temp += 0x0000;
653447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
65351da177e4SLinus Torvalds temp += 0x0000;
653647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
65371da177e4SLinus Torvalds temp += 0x0000;
65381da177e4SLinus Torvalds
653947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
65401da177e4SLinus Torvalds temp += 0x4242;
654147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
65421da177e4SLinus Torvalds temp += 0x4242;
654347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
65441da177e4SLinus Torvalds temp += 0x4242;
654547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
65461da177e4SLinus Torvalds temp += 0x4242;
654747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
65481da177e4SLinus Torvalds temp += 0x4242;
654947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
65501da177e4SLinus Torvalds temp += 0x4242;
655147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
65521da177e4SLinus Torvalds temp += 0x4242;
655347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
65541da177e4SLinus Torvalds temp += 0x4242;
65551da177e4SLinus Torvalds
655647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
65571da177e4SLinus Torvalds temp += 0x6C46;
655847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
65591da177e4SLinus Torvalds temp += 0x7361;
656047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
65611da177e4SLinus Torvalds temp += 0x5068;
656247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
65631da177e4SLinus Torvalds temp += 0x696F;
656447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
65651da177e4SLinus Torvalds temp += 0x746E;
656647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
65671da177e4SLinus Torvalds temp += 0x4C20;
656847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
65691da177e4SLinus Torvalds temp += 0x2054;
657047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
65711da177e4SLinus Torvalds temp += 0x2020;
65721da177e4SLinus Torvalds
65731da177e4SLinus Torvalds index = ((EE_SCAMBASE / 2) + (7 * 16));
657447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
65751da177e4SLinus Torvalds temp += (0x0700 + TYPE_CODE0);
65761da177e4SLinus Torvalds index++;
657747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
65781da177e4SLinus Torvalds temp += 0x5542; /* BUSLOGIC */
65791da177e4SLinus Torvalds index++;
658047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4C53, index);
65811da177e4SLinus Torvalds temp += 0x4C53;
65821da177e4SLinus Torvalds index++;
658347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x474F, index);
65841da177e4SLinus Torvalds temp += 0x474F;
65851da177e4SLinus Torvalds index++;
658647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4349, index);
65871da177e4SLinus Torvalds temp += 0x4349;
65881da177e4SLinus Torvalds index++;
658947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
65901da177e4SLinus Torvalds temp += 0x5442; /* BT- 930 */
65911da177e4SLinus Torvalds index++;
659247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x202D, index);
65931da177e4SLinus Torvalds temp += 0x202D;
65941da177e4SLinus Torvalds index++;
659547b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3339, index);
65961da177e4SLinus Torvalds temp += 0x3339;
65971da177e4SLinus Torvalds index++; /*Serial # */
659847b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
65991da177e4SLinus Torvalds temp += 0x2030;
66001da177e4SLinus Torvalds index++;
660147b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5453, index);
66021da177e4SLinus Torvalds temp += 0x5453;
66031da177e4SLinus Torvalds index++;
660447b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x5645, index);
66051da177e4SLinus Torvalds temp += 0x5645;
66061da177e4SLinus Torvalds index++;
660747b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x2045, index);
66081da177e4SLinus Torvalds temp += 0x2045;
66091da177e4SLinus Torvalds index++;
661047b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x202F, index);
66111da177e4SLinus Torvalds temp += 0x202F;
66121da177e4SLinus Torvalds index++;
661347b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x4F4A, index);
66141da177e4SLinus Torvalds temp += 0x4F4A;
66151da177e4SLinus Torvalds index++;
661647b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x204E, index);
66171da177e4SLinus Torvalds temp += 0x204E;
66181da177e4SLinus Torvalds index++;
661947b5d69cSJames Bottomley FPT_utilEEWrite(p_port, 0x3539, index);
66201da177e4SLinus Torvalds temp += 0x3539;
66211da177e4SLinus Torvalds
662247b5d69cSJames Bottomley FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
66231da177e4SLinus Torvalds
6624db038cf8SAlexey Dobriyan FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
66251da177e4SLinus Torvalds
66261da177e4SLinus Torvalds }
66271da177e4SLinus Torvalds
66281da177e4SLinus Torvalds /*---------------------------------------------------------------------
66291da177e4SLinus Torvalds *
66301da177e4SLinus Torvalds * Function: Queue Search Select
66311da177e4SLinus Torvalds *
66321da177e4SLinus Torvalds * Description: Try to find a new command to execute.
66331da177e4SLinus Torvalds *
66341da177e4SLinus Torvalds *---------------------------------------------------------------------*/
66351da177e4SLinus Torvalds
FPT_queueSearchSelect(struct sccb_card * pCurrCard,unsigned char p_card)66365c04a7b8SAlexey Dobriyan static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
66375c04a7b8SAlexey Dobriyan unsigned char p_card)
66381da177e4SLinus Torvalds {
6639db038cf8SAlexey Dobriyan unsigned char scan_ptr, lun;
6640f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
664169eb2ea4SAlexey Dobriyan struct sccb *pOldSccb;
66421da177e4SLinus Torvalds
66431da177e4SLinus Torvalds scan_ptr = pCurrCard->scanIndex;
66445c04a7b8SAlexey Dobriyan do {
664547b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
66461da177e4SLinus Torvalds if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
66475c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
66485c04a7b8SAlexey Dobriyan TAG_Q_TRYING)) {
66495c04a7b8SAlexey Dobriyan if (currTar_Info->TarSelQ_Cnt != 0) {
66501da177e4SLinus Torvalds
66511da177e4SLinus Torvalds scan_ptr++;
66521da177e4SLinus Torvalds if (scan_ptr == MAX_SCSI_TAR)
66531da177e4SLinus Torvalds scan_ptr = 0;
66541da177e4SLinus Torvalds
66555c04a7b8SAlexey Dobriyan for (lun = 0; lun < MAX_LUN; lun++) {
66565c04a7b8SAlexey Dobriyan if (currTar_Info->TarLUNBusy[lun] == 0) {
66571da177e4SLinus Torvalds
66585c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB =
66595c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head;
66601da177e4SLinus Torvalds pOldSccb = NULL;
66611da177e4SLinus Torvalds
66625c04a7b8SAlexey Dobriyan while ((pCurrCard->
66635c04a7b8SAlexey Dobriyan currentSCCB != NULL)
66645c04a7b8SAlexey Dobriyan && (lun !=
66655c04a7b8SAlexey Dobriyan pCurrCard->
66665c04a7b8SAlexey Dobriyan currentSCCB->Lun)) {
66675c04a7b8SAlexey Dobriyan pOldSccb =
66685c04a7b8SAlexey Dobriyan pCurrCard->
66695c04a7b8SAlexey Dobriyan currentSCCB;
66705c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB =
66715c04a7b8SAlexey Dobriyan (struct sccb
66725c04a7b8SAlexey Dobriyan *)(pCurrCard->
66735c04a7b8SAlexey Dobriyan currentSCCB)->
66741da177e4SLinus Torvalds Sccb_forwardlink;
66751da177e4SLinus Torvalds }
66765c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB ==
66775c04a7b8SAlexey Dobriyan NULL)
66781da177e4SLinus Torvalds continue;
66795c04a7b8SAlexey Dobriyan if (pOldSccb != NULL) {
66805c04a7b8SAlexey Dobriyan pOldSccb->
66815c04a7b8SAlexey Dobriyan Sccb_forwardlink =
66825c04a7b8SAlexey Dobriyan (struct sccb
66835c04a7b8SAlexey Dobriyan *)(pCurrCard->
66845c04a7b8SAlexey Dobriyan currentSCCB)->
66851da177e4SLinus Torvalds Sccb_forwardlink;
66865c04a7b8SAlexey Dobriyan pOldSccb->
66875c04a7b8SAlexey Dobriyan Sccb_backlink =
66885c04a7b8SAlexey Dobriyan (struct sccb
66895c04a7b8SAlexey Dobriyan *)(pCurrCard->
66905c04a7b8SAlexey Dobriyan currentSCCB)->
66911da177e4SLinus Torvalds Sccb_backlink;
66925c04a7b8SAlexey Dobriyan currTar_Info->
66935c04a7b8SAlexey Dobriyan TarSelQ_Cnt--;
66945c04a7b8SAlexey Dobriyan } else {
66955c04a7b8SAlexey Dobriyan currTar_Info->
66965c04a7b8SAlexey Dobriyan TarSelQ_Head =
66975c04a7b8SAlexey Dobriyan (struct sccb
66985c04a7b8SAlexey Dobriyan *)(pCurrCard->
66995c04a7b8SAlexey Dobriyan currentSCCB)->
67005c04a7b8SAlexey Dobriyan Sccb_forwardlink;
67011da177e4SLinus Torvalds
67025c04a7b8SAlexey Dobriyan if (currTar_Info->
67035c04a7b8SAlexey Dobriyan TarSelQ_Head ==
67045c04a7b8SAlexey Dobriyan NULL) {
67055c04a7b8SAlexey Dobriyan currTar_Info->
67065c04a7b8SAlexey Dobriyan TarSelQ_Tail
67075c04a7b8SAlexey Dobriyan = NULL;
67085c04a7b8SAlexey Dobriyan currTar_Info->
67095c04a7b8SAlexey Dobriyan TarSelQ_Cnt
67105c04a7b8SAlexey Dobriyan = 0;
67115c04a7b8SAlexey Dobriyan } else {
67125c04a7b8SAlexey Dobriyan currTar_Info->
67135c04a7b8SAlexey Dobriyan TarSelQ_Cnt--;
67145c04a7b8SAlexey Dobriyan currTar_Info->
67155c04a7b8SAlexey Dobriyan TarSelQ_Head->
67165c04a7b8SAlexey Dobriyan Sccb_backlink
67175c04a7b8SAlexey Dobriyan =
67185c04a7b8SAlexey Dobriyan (struct sccb
67195c04a7b8SAlexey Dobriyan *)NULL;
67201da177e4SLinus Torvalds }
67211da177e4SLinus Torvalds }
67221da177e4SLinus Torvalds pCurrCard->scanIndex = scan_ptr;
67231da177e4SLinus Torvalds
67245c04a7b8SAlexey Dobriyan pCurrCard->globalFlags |=
67255c04a7b8SAlexey Dobriyan F_NEW_SCCB_CMD;
67261da177e4SLinus Torvalds
67271da177e4SLinus Torvalds break;
67281da177e4SLinus Torvalds }
67291da177e4SLinus Torvalds }
67301da177e4SLinus Torvalds }
67311da177e4SLinus Torvalds
67325c04a7b8SAlexey Dobriyan else {
67331da177e4SLinus Torvalds scan_ptr++;
67341da177e4SLinus Torvalds if (scan_ptr == MAX_SCSI_TAR) {
67351da177e4SLinus Torvalds scan_ptr = 0;
67361da177e4SLinus Torvalds }
67371da177e4SLinus Torvalds }
67381da177e4SLinus Torvalds
67395c04a7b8SAlexey Dobriyan } else {
67401da177e4SLinus Torvalds if ((currTar_Info->TarSelQ_Cnt != 0) &&
67415c04a7b8SAlexey Dobriyan (currTar_Info->TarLUNBusy[0] == 0)) {
67421da177e4SLinus Torvalds
67435c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB =
67445c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head;
67451da177e4SLinus Torvalds
67465c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head =
67475c04a7b8SAlexey Dobriyan (struct sccb *)(pCurrCard->currentSCCB)->
67485c04a7b8SAlexey Dobriyan Sccb_forwardlink;
67491da177e4SLinus Torvalds
67505c04a7b8SAlexey Dobriyan if (currTar_Info->TarSelQ_Head == NULL) {
67511da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = NULL;
67521da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt = 0;
67535c04a7b8SAlexey Dobriyan } else {
67541da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt--;
67555c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head->
67565c04a7b8SAlexey Dobriyan Sccb_backlink = (struct sccb *)NULL;
67571da177e4SLinus Torvalds }
67581da177e4SLinus Torvalds
67591da177e4SLinus Torvalds scan_ptr++;
67601da177e4SLinus Torvalds if (scan_ptr == MAX_SCSI_TAR)
67611da177e4SLinus Torvalds scan_ptr = 0;
67621da177e4SLinus Torvalds
67631da177e4SLinus Torvalds pCurrCard->scanIndex = scan_ptr;
67641da177e4SLinus Torvalds
67651da177e4SLinus Torvalds pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
67661da177e4SLinus Torvalds
67671da177e4SLinus Torvalds break;
67681da177e4SLinus Torvalds }
67691da177e4SLinus Torvalds
67705c04a7b8SAlexey Dobriyan else {
67711da177e4SLinus Torvalds scan_ptr++;
67725c04a7b8SAlexey Dobriyan if (scan_ptr == MAX_SCSI_TAR) {
67731da177e4SLinus Torvalds scan_ptr = 0;
67741da177e4SLinus Torvalds }
67751da177e4SLinus Torvalds }
67761da177e4SLinus Torvalds }
67771da177e4SLinus Torvalds } while (scan_ptr != pCurrCard->scanIndex);
67781da177e4SLinus Torvalds }
67791da177e4SLinus Torvalds
67801da177e4SLinus Torvalds /*---------------------------------------------------------------------
67811da177e4SLinus Torvalds *
67821da177e4SLinus Torvalds * Function: Queue Select Fail
67831da177e4SLinus Torvalds *
67841da177e4SLinus Torvalds * Description: Add the current SCCB to the head of the Queue.
67851da177e4SLinus Torvalds *
67861da177e4SLinus Torvalds *---------------------------------------------------------------------*/
67871da177e4SLinus Torvalds
FPT_queueSelectFail(struct sccb_card * pCurrCard,unsigned char p_card)67885c04a7b8SAlexey Dobriyan static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
67895c04a7b8SAlexey Dobriyan unsigned char p_card)
67901da177e4SLinus Torvalds {
6791db038cf8SAlexey Dobriyan unsigned char thisTarg;
6792f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
67931da177e4SLinus Torvalds
67945c04a7b8SAlexey Dobriyan if (pCurrCard->currentSCCB != NULL) {
67955c04a7b8SAlexey Dobriyan thisTarg =
67965c04a7b8SAlexey Dobriyan (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
67975c04a7b8SAlexey Dobriyan TargID);
679847b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
67991da177e4SLinus Torvalds
680069eb2ea4SAlexey Dobriyan pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
68011da177e4SLinus Torvalds
68025c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB->Sccb_forwardlink =
68035c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head;
68041da177e4SLinus Torvalds
68055c04a7b8SAlexey Dobriyan if (currTar_Info->TarSelQ_Cnt == 0) {
68061da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
68071da177e4SLinus Torvalds }
68081da177e4SLinus Torvalds
68095c04a7b8SAlexey Dobriyan else {
68105c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head->Sccb_backlink =
68115c04a7b8SAlexey Dobriyan pCurrCard->currentSCCB;
68121da177e4SLinus Torvalds }
68131da177e4SLinus Torvalds
68141da177e4SLinus Torvalds currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
68151da177e4SLinus Torvalds
68161da177e4SLinus Torvalds pCurrCard->currentSCCB = NULL;
68171da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt++;
68181da177e4SLinus Torvalds }
68191da177e4SLinus Torvalds }
68205c04a7b8SAlexey Dobriyan
68211da177e4SLinus Torvalds /*---------------------------------------------------------------------
68221da177e4SLinus Torvalds *
68231da177e4SLinus Torvalds * Function: Queue Command Complete
68241da177e4SLinus Torvalds *
68251da177e4SLinus Torvalds * Description: Call the callback function with the current SCCB.
68261da177e4SLinus Torvalds *
68271da177e4SLinus Torvalds *---------------------------------------------------------------------*/
68281da177e4SLinus Torvalds
FPT_queueCmdComplete(struct sccb_card * pCurrCard,struct sccb * p_sccb,unsigned char p_card)68295c04a7b8SAlexey Dobriyan static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
68305c04a7b8SAlexey Dobriyan struct sccb *p_sccb, unsigned char p_card)
68311da177e4SLinus Torvalds {
68321da177e4SLinus Torvalds
6833db038cf8SAlexey Dobriyan unsigned char i, SCSIcmd;
68341da177e4SLinus Torvalds CALL_BK_FN callback;
6835f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
68361da177e4SLinus Torvalds
68371da177e4SLinus Torvalds SCSIcmd = p_sccb->Cdb[0];
68381da177e4SLinus Torvalds
68391da177e4SLinus Torvalds if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
68401da177e4SLinus Torvalds
68415c04a7b8SAlexey Dobriyan if ((p_sccb->
68425c04a7b8SAlexey Dobriyan ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
68435c04a7b8SAlexey Dobriyan && (p_sccb->HostStatus == SCCB_COMPLETE)
6844a87afe28SHannes Reinecke && (p_sccb->TargetStatus != SAM_STAT_CHECK_CONDITION))
68451da177e4SLinus Torvalds
6846a87afe28SHannes Reinecke if ((SCSIcmd == READ_6) ||
6847a87afe28SHannes Reinecke (SCSIcmd == WRITE_6) ||
6848a87afe28SHannes Reinecke (SCSIcmd == READ_10) ||
6849a87afe28SHannes Reinecke (SCSIcmd == WRITE_10) ||
6850a87afe28SHannes Reinecke (SCSIcmd == WRITE_VERIFY) ||
6851a87afe28SHannes Reinecke (SCSIcmd == START_STOP) ||
68521da177e4SLinus Torvalds (pCurrCard->globalFlags & F_NO_FILTER)
68531da177e4SLinus Torvalds )
68541da177e4SLinus Torvalds p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
68551da177e4SLinus Torvalds }
68561da177e4SLinus Torvalds
68575c04a7b8SAlexey Dobriyan if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
68581da177e4SLinus Torvalds if (p_sccb->HostStatus || p_sccb->TargetStatus)
68591da177e4SLinus Torvalds p_sccb->SccbStatus = SCCB_ERROR;
68601da177e4SLinus Torvalds else
68611da177e4SLinus Torvalds p_sccb->SccbStatus = SCCB_SUCCESS;
68621da177e4SLinus Torvalds }
68631da177e4SLinus Torvalds
68641da177e4SLinus Torvalds if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
68651da177e4SLinus Torvalds
68661da177e4SLinus Torvalds p_sccb->CdbLength = p_sccb->Save_CdbLen;
68671da177e4SLinus Torvalds for (i = 0; i < 6; i++) {
68681da177e4SLinus Torvalds p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
68691da177e4SLinus Torvalds }
68701da177e4SLinus Torvalds }
68711da177e4SLinus Torvalds
68721da177e4SLinus Torvalds if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
68731da177e4SLinus Torvalds (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
68741da177e4SLinus Torvalds
687547b5d69cSJames Bottomley FPT_utilUpdateResidual(p_sccb);
68761da177e4SLinus Torvalds }
68771da177e4SLinus Torvalds
68781da177e4SLinus Torvalds pCurrCard->cmdCounter--;
68791da177e4SLinus Torvalds if (!pCurrCard->cmdCounter) {
68801da177e4SLinus Torvalds
68811da177e4SLinus Torvalds if (pCurrCard->globalFlags & F_GREEN_PC) {
68825c04a7b8SAlexey Dobriyan WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
68835c04a7b8SAlexey Dobriyan (PWR_DWN | CLKCTRL_DEFAULT));
68841da177e4SLinus Torvalds WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
68851da177e4SLinus Torvalds }
68861da177e4SLinus Torvalds
68871da177e4SLinus Torvalds WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
68885c04a7b8SAlexey Dobriyan (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
68895c04a7b8SAlexey Dobriyan ~SCCB_MGR_ACTIVE));
68901da177e4SLinus Torvalds
68911da177e4SLinus Torvalds }
68921da177e4SLinus Torvalds
68935c04a7b8SAlexey Dobriyan if (pCurrCard->discQCount != 0) {
689447b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
68951da177e4SLinus Torvalds if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
68965c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
68975c04a7b8SAlexey Dobriyan TAG_Q_TRYING))) {
68981da177e4SLinus Torvalds pCurrCard->discQCount--;
68995c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->
69005c04a7b8SAlexey Dobriyan LunDiscQ_Idx[p_sccb->Lun]] = NULL;
69015c04a7b8SAlexey Dobriyan } else {
69025c04a7b8SAlexey Dobriyan if (p_sccb->Sccb_tag) {
69031da177e4SLinus Torvalds pCurrCard->discQCount--;
69041da177e4SLinus Torvalds pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
69055c04a7b8SAlexey Dobriyan } else {
69061da177e4SLinus Torvalds pCurrCard->discQCount--;
69075c04a7b8SAlexey Dobriyan pCurrCard->discQ_Tbl[currTar_Info->
69085c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = NULL;
69091da177e4SLinus Torvalds }
69101da177e4SLinus Torvalds }
69111da177e4SLinus Torvalds
69121da177e4SLinus Torvalds }
69131da177e4SLinus Torvalds
69141da177e4SLinus Torvalds callback = (CALL_BK_FN) p_sccb->SccbCallback;
69151da177e4SLinus Torvalds callback(p_sccb);
69161da177e4SLinus Torvalds pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
69171da177e4SLinus Torvalds pCurrCard->currentSCCB = NULL;
69181da177e4SLinus Torvalds }
69191da177e4SLinus Torvalds
69201da177e4SLinus Torvalds /*---------------------------------------------------------------------
69211da177e4SLinus Torvalds *
69221da177e4SLinus Torvalds * Function: Queue Disconnect
69231da177e4SLinus Torvalds *
69241da177e4SLinus Torvalds * Description: Add SCCB to our disconnect array.
69251da177e4SLinus Torvalds *
69261da177e4SLinus Torvalds *---------------------------------------------------------------------*/
FPT_queueDisconnect(struct sccb * p_sccb,unsigned char p_card)692769eb2ea4SAlexey Dobriyan static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
69281da177e4SLinus Torvalds {
6929f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
69301da177e4SLinus Torvalds
693147b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
69321da177e4SLinus Torvalds
693347b5d69cSJames Bottomley if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
69345c04a7b8SAlexey Dobriyan ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
69355c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
69365c04a7b8SAlexey Dobriyan LunDiscQ_Idx[p_sccb->Lun]] =
69375c04a7b8SAlexey Dobriyan p_sccb;
69385c04a7b8SAlexey Dobriyan } else {
69395c04a7b8SAlexey Dobriyan if (p_sccb->Sccb_tag) {
69405c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
69415c04a7b8SAlexey Dobriyan p_sccb;
69425c04a7b8SAlexey Dobriyan FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
69435c04a7b8SAlexey Dobriyan 0;
694447b5d69cSJames Bottomley FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
69455c04a7b8SAlexey Dobriyan } else {
69465c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
69475c04a7b8SAlexey Dobriyan LunDiscQ_Idx[0]] = p_sccb;
69481da177e4SLinus Torvalds }
69491da177e4SLinus Torvalds }
695047b5d69cSJames Bottomley FPT_BL_Card[p_card].currentSCCB = NULL;
69511da177e4SLinus Torvalds }
69521da177e4SLinus Torvalds
69531da177e4SLinus Torvalds /*---------------------------------------------------------------------
69541da177e4SLinus Torvalds *
69551da177e4SLinus Torvalds * Function: Queue Flush SCCB
69561da177e4SLinus Torvalds *
69571da177e4SLinus Torvalds * Description: Flush all SCCB's back to the host driver for this target.
69581da177e4SLinus Torvalds *
69591da177e4SLinus Torvalds *---------------------------------------------------------------------*/
69601da177e4SLinus Torvalds
FPT_queueFlushSccb(unsigned char p_card,unsigned char error_code)6961db038cf8SAlexey Dobriyan static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
69621da177e4SLinus Torvalds {
6963db038cf8SAlexey Dobriyan unsigned char qtag, thisTarg;
696469eb2ea4SAlexey Dobriyan struct sccb *currSCCB;
6965f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
69661da177e4SLinus Torvalds
696747b5d69cSJames Bottomley currSCCB = FPT_BL_Card[p_card].currentSCCB;
69685c04a7b8SAlexey Dobriyan if (currSCCB != NULL) {
6969db038cf8SAlexey Dobriyan thisTarg = (unsigned char)currSCCB->TargID;
697047b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
69711da177e4SLinus Torvalds
69721da177e4SLinus Torvalds for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
69731da177e4SLinus Torvalds
697447b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
69755c04a7b8SAlexey Dobriyan (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
69765c04a7b8SAlexey Dobriyan thisTarg)) {
69771da177e4SLinus Torvalds
69785c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[qtag]->
69795c04a7b8SAlexey Dobriyan HostStatus = (unsigned char)error_code;
69801da177e4SLinus Torvalds
69815c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card],
69825c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
69835c04a7b8SAlexey Dobriyan discQ_Tbl[qtag], p_card);
69841da177e4SLinus Torvalds
698547b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
69861da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt--;
69871da177e4SLinus Torvalds
69881da177e4SLinus Torvalds }
69891da177e4SLinus Torvalds }
69901da177e4SLinus Torvalds }
69911da177e4SLinus Torvalds
69921da177e4SLinus Torvalds }
69931da177e4SLinus Torvalds
69941da177e4SLinus Torvalds /*---------------------------------------------------------------------
69951da177e4SLinus Torvalds *
69961da177e4SLinus Torvalds * Function: Queue Flush Target SCCB
69971da177e4SLinus Torvalds *
69981da177e4SLinus Torvalds * Description: Flush all SCCB's back to the host driver for this target.
69991da177e4SLinus Torvalds *
70001da177e4SLinus Torvalds *---------------------------------------------------------------------*/
70011da177e4SLinus Torvalds
FPT_queueFlushTargSccb(unsigned char p_card,unsigned char thisTarg,unsigned char error_code)7002db038cf8SAlexey Dobriyan static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7003db038cf8SAlexey Dobriyan unsigned char error_code)
70041da177e4SLinus Torvalds {
7005db038cf8SAlexey Dobriyan unsigned char qtag;
7006f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
70071da177e4SLinus Torvalds
700847b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
70091da177e4SLinus Torvalds
70101da177e4SLinus Torvalds for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
70111da177e4SLinus Torvalds
701247b5d69cSJames Bottomley if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
70135c04a7b8SAlexey Dobriyan (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
70141da177e4SLinus Torvalds
70155c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
70165c04a7b8SAlexey Dobriyan (unsigned char)error_code;
70171da177e4SLinus Torvalds
70185c04a7b8SAlexey Dobriyan FPT_queueCmdComplete(&FPT_BL_Card[p_card],
70195c04a7b8SAlexey Dobriyan FPT_BL_Card[p_card].
70205c04a7b8SAlexey Dobriyan discQ_Tbl[qtag], p_card);
70211da177e4SLinus Torvalds
702247b5d69cSJames Bottomley FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
70231da177e4SLinus Torvalds currTar_Info->TarTagQ_Cnt--;
70241da177e4SLinus Torvalds
70251da177e4SLinus Torvalds }
70261da177e4SLinus Torvalds }
70271da177e4SLinus Torvalds
70281da177e4SLinus Torvalds }
70291da177e4SLinus Torvalds
FPT_queueAddSccb(struct sccb * p_SCCB,unsigned char p_card)703069eb2ea4SAlexey Dobriyan static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
70311da177e4SLinus Torvalds {
7032f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
703347b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
70341da177e4SLinus Torvalds
70351da177e4SLinus Torvalds p_SCCB->Sccb_forwardlink = NULL;
70361da177e4SLinus Torvalds
70371da177e4SLinus Torvalds p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
70381da177e4SLinus Torvalds
70391da177e4SLinus Torvalds if (currTar_Info->TarSelQ_Cnt == 0) {
70401da177e4SLinus Torvalds
70411da177e4SLinus Torvalds currTar_Info->TarSelQ_Head = p_SCCB;
70421da177e4SLinus Torvalds }
70431da177e4SLinus Torvalds
70441da177e4SLinus Torvalds else {
70451da177e4SLinus Torvalds
70461da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
70471da177e4SLinus Torvalds }
70481da177e4SLinus Torvalds
70491da177e4SLinus Torvalds currTar_Info->TarSelQ_Tail = p_SCCB;
70501da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt++;
70511da177e4SLinus Torvalds }
70521da177e4SLinus Torvalds
70531da177e4SLinus Torvalds /*---------------------------------------------------------------------
70541da177e4SLinus Torvalds *
70551da177e4SLinus Torvalds * Function: Queue Find SCCB
70561da177e4SLinus Torvalds *
70571da177e4SLinus Torvalds * Description: Search the target select Queue for this SCCB, and
70581da177e4SLinus Torvalds * remove it if found.
70591da177e4SLinus Torvalds *
70601da177e4SLinus Torvalds *---------------------------------------------------------------------*/
70611da177e4SLinus Torvalds
FPT_queueFindSccb(struct sccb * p_SCCB,unsigned char p_card)70625c04a7b8SAlexey Dobriyan static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
70635c04a7b8SAlexey Dobriyan unsigned char p_card)
70641da177e4SLinus Torvalds {
706569eb2ea4SAlexey Dobriyan struct sccb *q_ptr;
7066f31dc0cdSAlexey Dobriyan struct sccb_mgr_tar_info *currTar_Info;
70671da177e4SLinus Torvalds
706847b5d69cSJames Bottomley currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
70691da177e4SLinus Torvalds
70701da177e4SLinus Torvalds q_ptr = currTar_Info->TarSelQ_Head;
70711da177e4SLinus Torvalds
70721da177e4SLinus Torvalds while (q_ptr != NULL) {
70731da177e4SLinus Torvalds
70741da177e4SLinus Torvalds if (q_ptr == p_SCCB) {
70751da177e4SLinus Torvalds
70761da177e4SLinus Torvalds if (currTar_Info->TarSelQ_Head == q_ptr) {
70771da177e4SLinus Torvalds
70785c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Head =
70795c04a7b8SAlexey Dobriyan q_ptr->Sccb_forwardlink;
70801da177e4SLinus Torvalds }
70811da177e4SLinus Torvalds
70821da177e4SLinus Torvalds if (currTar_Info->TarSelQ_Tail == q_ptr) {
70831da177e4SLinus Torvalds
70845c04a7b8SAlexey Dobriyan currTar_Info->TarSelQ_Tail =
70855c04a7b8SAlexey Dobriyan q_ptr->Sccb_backlink;
70861da177e4SLinus Torvalds }
70871da177e4SLinus Torvalds
70881da177e4SLinus Torvalds if (q_ptr->Sccb_forwardlink != NULL) {
70895c04a7b8SAlexey Dobriyan q_ptr->Sccb_forwardlink->Sccb_backlink =
70905c04a7b8SAlexey Dobriyan q_ptr->Sccb_backlink;
70911da177e4SLinus Torvalds }
70921da177e4SLinus Torvalds
70931da177e4SLinus Torvalds if (q_ptr->Sccb_backlink != NULL) {
70945c04a7b8SAlexey Dobriyan q_ptr->Sccb_backlink->Sccb_forwardlink =
70955c04a7b8SAlexey Dobriyan q_ptr->Sccb_forwardlink;
70961da177e4SLinus Torvalds }
70971da177e4SLinus Torvalds
70981da177e4SLinus Torvalds currTar_Info->TarSelQ_Cnt--;
70991da177e4SLinus Torvalds
71005c1b85e2SAlexey Dobriyan return 1;
71011da177e4SLinus Torvalds }
71021da177e4SLinus Torvalds
71031da177e4SLinus Torvalds else {
71041da177e4SLinus Torvalds q_ptr = q_ptr->Sccb_forwardlink;
71051da177e4SLinus Torvalds }
71061da177e4SLinus Torvalds }
71071da177e4SLinus Torvalds
71085c1b85e2SAlexey Dobriyan return 0;
71091da177e4SLinus Torvalds
71101da177e4SLinus Torvalds }
71111da177e4SLinus Torvalds
71121da177e4SLinus Torvalds /*---------------------------------------------------------------------
71131da177e4SLinus Torvalds *
71141da177e4SLinus Torvalds * Function: Utility Update Residual Count
71151da177e4SLinus Torvalds *
71161da177e4SLinus Torvalds * Description: Update the XferCnt to the remaining byte count.
71171da177e4SLinus Torvalds * If we transferred all the data then just write zero.
71181da177e4SLinus Torvalds * If Non-SG transfer then report Total Cnt - Actual Transfer
71191da177e4SLinus Torvalds * Cnt. For SG transfers add the count fields of all
71201da177e4SLinus Torvalds * remaining SG elements, as well as any partial remaining
71211da177e4SLinus Torvalds * element.
71221da177e4SLinus Torvalds *
71231da177e4SLinus Torvalds *---------------------------------------------------------------------*/
71241da177e4SLinus Torvalds
FPT_utilUpdateResidual(struct sccb * p_SCCB)712569eb2ea4SAlexey Dobriyan static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
71261da177e4SLinus Torvalds {
7127d63a4cccSAlexey Dobriyan unsigned long partial_cnt;
7128ce793215SAlexey Dobriyan unsigned int sg_index;
7129391e2f25SKhalid Aziz struct blogic_sg_seg *segp;
71301da177e4SLinus Torvalds
71311da177e4SLinus Torvalds if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
71321da177e4SLinus Torvalds
71331da177e4SLinus Torvalds p_SCCB->DataLength = 0x0000;
71341da177e4SLinus Torvalds }
71351da177e4SLinus Torvalds
71361da177e4SLinus Torvalds else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
71371da177e4SLinus Torvalds
71381da177e4SLinus Torvalds partial_cnt = 0x0000;
71391da177e4SLinus Torvalds
71401da177e4SLinus Torvalds sg_index = p_SCCB->Sccb_sgseg;
71411da177e4SLinus Torvalds
71421da177e4SLinus Torvalds
71431da177e4SLinus Torvalds if (p_SCCB->Sccb_SGoffset) {
71441da177e4SLinus Torvalds
71451da177e4SLinus Torvalds partial_cnt = p_SCCB->Sccb_SGoffset;
71461da177e4SLinus Torvalds sg_index++;
71471da177e4SLinus Torvalds }
71481da177e4SLinus Torvalds
71495c04a7b8SAlexey Dobriyan while (((unsigned long)sg_index *
71505c04a7b8SAlexey Dobriyan (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7151391e2f25SKhalid Aziz segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7152391e2f25SKhalid Aziz (sg_index * 2);
7153391e2f25SKhalid Aziz partial_cnt += segp->segbytes;
71541da177e4SLinus Torvalds sg_index++;
71551da177e4SLinus Torvalds }
71561da177e4SLinus Torvalds
71571da177e4SLinus Torvalds p_SCCB->DataLength = partial_cnt;
71581da177e4SLinus Torvalds }
71591da177e4SLinus Torvalds
71601da177e4SLinus Torvalds else {
71611da177e4SLinus Torvalds
71621da177e4SLinus Torvalds p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
71631da177e4SLinus Torvalds }
71641da177e4SLinus Torvalds }
71651da177e4SLinus Torvalds
71661da177e4SLinus Torvalds /*---------------------------------------------------------------------
71671da177e4SLinus Torvalds *
71681da177e4SLinus Torvalds * Function: Wait 1 Second
71691da177e4SLinus Torvalds *
71701da177e4SLinus Torvalds * Description: Wait for 1 second.
71711da177e4SLinus Torvalds *
71721da177e4SLinus Torvalds *---------------------------------------------------------------------*/
71731da177e4SLinus Torvalds
FPT_Wait1Second(u32 p_port)7174391e2f25SKhalid Aziz static void FPT_Wait1Second(u32 p_port)
71751da177e4SLinus Torvalds {
7176db038cf8SAlexey Dobriyan unsigned char i;
71771da177e4SLinus Torvalds
71781da177e4SLinus Torvalds for (i = 0; i < 4; i++) {
71791da177e4SLinus Torvalds
718047b5d69cSJames Bottomley FPT_Wait(p_port, TO_250ms);
71811da177e4SLinus Torvalds
71821da177e4SLinus Torvalds if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
71831da177e4SLinus Torvalds break;
71841da177e4SLinus Torvalds
71851da177e4SLinus Torvalds if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
71861da177e4SLinus Torvalds break;
71871da177e4SLinus Torvalds }
71881da177e4SLinus Torvalds }
71891da177e4SLinus Torvalds
71901da177e4SLinus Torvalds /*---------------------------------------------------------------------
71911da177e4SLinus Torvalds *
719247b5d69cSJames Bottomley * Function: FPT_Wait
71931da177e4SLinus Torvalds *
71941da177e4SLinus Torvalds * Description: Wait the desired delay.
71951da177e4SLinus Torvalds *
71961da177e4SLinus Torvalds *---------------------------------------------------------------------*/
71971da177e4SLinus Torvalds
FPT_Wait(u32 p_port,unsigned char p_delay)7198391e2f25SKhalid Aziz static void FPT_Wait(u32 p_port, unsigned char p_delay)
71991da177e4SLinus Torvalds {
7200db038cf8SAlexey Dobriyan unsigned char old_timer;
7201db038cf8SAlexey Dobriyan unsigned char green_flag;
72021da177e4SLinus Torvalds
72031da177e4SLinus Torvalds old_timer = RD_HARPOON(p_port + hp_seltimeout);
72041da177e4SLinus Torvalds
72051da177e4SLinus Torvalds green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
72061da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
72071da177e4SLinus Torvalds
72081da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, p_delay);
72091da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
721047b5d69cSJames Bottomley WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
72111da177e4SLinus Torvalds
72121da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0,
72131da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
72141da177e4SLinus Torvalds
72151da177e4SLinus Torvalds while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
72161da177e4SLinus Torvalds
72171da177e4SLinus Torvalds if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
72181da177e4SLinus Torvalds break;
72191da177e4SLinus Torvalds
72201da177e4SLinus Torvalds if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
72211da177e4SLinus Torvalds break;
72221da177e4SLinus Torvalds }
72231da177e4SLinus Torvalds
72241da177e4SLinus Torvalds WR_HARPOON(p_port + hp_portctrl_0,
72251da177e4SLinus Torvalds (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
72261da177e4SLinus Torvalds
72271da177e4SLinus Torvalds WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
722847b5d69cSJames Bottomley WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
72291da177e4SLinus Torvalds
72301da177e4SLinus Torvalds WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
72311da177e4SLinus Torvalds
72321da177e4SLinus Torvalds WR_HARPOON(p_port + hp_seltimeout, old_timer);
72331da177e4SLinus Torvalds }
72341da177e4SLinus Torvalds
72351da177e4SLinus Torvalds /*---------------------------------------------------------------------
72361da177e4SLinus Torvalds *
72371da177e4SLinus Torvalds * Function: Enable/Disable Write to EEPROM
72381da177e4SLinus Torvalds *
72391da177e4SLinus Torvalds * Description: The EEPROM must first be enabled for writes
72401da177e4SLinus Torvalds * A total of 9 clocks are needed.
72411da177e4SLinus Torvalds *
72421da177e4SLinus Torvalds *---------------------------------------------------------------------*/
72431da177e4SLinus Torvalds
FPT_utilEEWriteOnOff(u32 p_port,unsigned char p_mode)7244391e2f25SKhalid Aziz static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
72451da177e4SLinus Torvalds {
7246db038cf8SAlexey Dobriyan unsigned char ee_value;
72471da177e4SLinus Torvalds
72485c04a7b8SAlexey Dobriyan ee_value =
72495c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
72505c04a7b8SAlexey Dobriyan (EXT_ARB_ACK | SCSI_TERM_ENA_H));
72511da177e4SLinus Torvalds
72521da177e4SLinus Torvalds if (p_mode)
72531da177e4SLinus Torvalds
725447b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
72551da177e4SLinus Torvalds
72561da177e4SLinus Torvalds else
72571da177e4SLinus Torvalds
725847b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
72591da177e4SLinus Torvalds
72601da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
72611da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
72621da177e4SLinus Torvalds }
72631da177e4SLinus Torvalds
72641da177e4SLinus Torvalds /*---------------------------------------------------------------------
72651da177e4SLinus Torvalds *
72661da177e4SLinus Torvalds * Function: Write EEPROM
72671da177e4SLinus Torvalds *
72681da177e4SLinus Torvalds * Description: Write a word to the EEPROM at the specified
72691da177e4SLinus Torvalds * address.
72701da177e4SLinus Torvalds *
72711da177e4SLinus Torvalds *---------------------------------------------------------------------*/
72721da177e4SLinus Torvalds
FPT_utilEEWrite(u32 p_port,unsigned short ee_data,unsigned short ee_addr)7273391e2f25SKhalid Aziz static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
72745c04a7b8SAlexey Dobriyan unsigned short ee_addr)
72751da177e4SLinus Torvalds {
72761da177e4SLinus Torvalds
7277db038cf8SAlexey Dobriyan unsigned char ee_value;
7278c823feebSAlexey Dobriyan unsigned short i;
72791da177e4SLinus Torvalds
72805c04a7b8SAlexey Dobriyan ee_value =
72815c04a7b8SAlexey Dobriyan (unsigned
72825c04a7b8SAlexey Dobriyan char)((RD_HARPOON(p_port + hp_ee_ctrl) &
72835c04a7b8SAlexey Dobriyan (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
72841da177e4SLinus Torvalds
728547b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
72861da177e4SLinus Torvalds
72871da177e4SLinus Torvalds ee_value |= (SEE_MS + SEE_CS);
72881da177e4SLinus Torvalds
72891da177e4SLinus Torvalds for (i = 0x8000; i != 0; i >>= 1) {
72901da177e4SLinus Torvalds
72911da177e4SLinus Torvalds if (i & ee_data)
72921da177e4SLinus Torvalds ee_value |= SEE_DO;
72931da177e4SLinus Torvalds else
72941da177e4SLinus Torvalds ee_value &= ~SEE_DO;
72951da177e4SLinus Torvalds
72961da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
72971da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
72981da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */
72991da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73001da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73011da177e4SLinus Torvalds ee_value &= ~SEE_CLK;
73021da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73031da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73041da177e4SLinus Torvalds }
73051da177e4SLinus Torvalds ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
73061da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
73071da177e4SLinus Torvalds
730847b5d69cSJames Bottomley FPT_Wait(p_port, TO_10ms);
73091da177e4SLinus Torvalds
73101da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
73111da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
73121da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
73131da177e4SLinus Torvalds }
73141da177e4SLinus Torvalds
73151da177e4SLinus Torvalds /*---------------------------------------------------------------------
73161da177e4SLinus Torvalds *
73171da177e4SLinus Torvalds * Function: Read EEPROM
73181da177e4SLinus Torvalds *
73191da177e4SLinus Torvalds * Description: Read a word from the EEPROM at the desired
73201da177e4SLinus Torvalds * address.
73211da177e4SLinus Torvalds *
73221da177e4SLinus Torvalds *---------------------------------------------------------------------*/
73231da177e4SLinus Torvalds
FPT_utilEERead(u32 p_port,unsigned short ee_addr)7324391e2f25SKhalid Aziz static unsigned short FPT_utilEERead(u32 p_port,
73255c04a7b8SAlexey Dobriyan unsigned short ee_addr)
73261da177e4SLinus Torvalds {
7327c823feebSAlexey Dobriyan unsigned short i, ee_data1, ee_data2;
73281da177e4SLinus Torvalds
73291da177e4SLinus Torvalds i = 0;
733047b5d69cSJames Bottomley ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
73315c04a7b8SAlexey Dobriyan do {
733247b5d69cSJames Bottomley ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
73331da177e4SLinus Torvalds
73341da177e4SLinus Torvalds if (ee_data1 == ee_data2)
73355c1b85e2SAlexey Dobriyan return ee_data1;
73361da177e4SLinus Torvalds
73371da177e4SLinus Torvalds ee_data1 = ee_data2;
73381da177e4SLinus Torvalds i++;
73391da177e4SLinus Torvalds
73401da177e4SLinus Torvalds } while (i < 4);
73411da177e4SLinus Torvalds
73425c1b85e2SAlexey Dobriyan return ee_data1;
73431da177e4SLinus Torvalds }
73441da177e4SLinus Torvalds
73451da177e4SLinus Torvalds /*---------------------------------------------------------------------
73461da177e4SLinus Torvalds *
73471da177e4SLinus Torvalds * Function: Read EEPROM Original
73481da177e4SLinus Torvalds *
73491da177e4SLinus Torvalds * Description: Read a word from the EEPROM at the desired
73501da177e4SLinus Torvalds * address.
73511da177e4SLinus Torvalds *
73521da177e4SLinus Torvalds *---------------------------------------------------------------------*/
73531da177e4SLinus Torvalds
FPT_utilEEReadOrg(u32 p_port,unsigned short ee_addr)7354391e2f25SKhalid Aziz static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
73551da177e4SLinus Torvalds {
73561da177e4SLinus Torvalds
7357db038cf8SAlexey Dobriyan unsigned char ee_value;
7358c823feebSAlexey Dobriyan unsigned short i, ee_data;
73591da177e4SLinus Torvalds
73605c04a7b8SAlexey Dobriyan ee_value =
73615c04a7b8SAlexey Dobriyan (unsigned
73625c04a7b8SAlexey Dobriyan char)((RD_HARPOON(p_port + hp_ee_ctrl) &
73635c04a7b8SAlexey Dobriyan (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
73641da177e4SLinus Torvalds
736547b5d69cSJames Bottomley FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
73661da177e4SLinus Torvalds
73671da177e4SLinus Torvalds ee_value |= (SEE_MS + SEE_CS);
73681da177e4SLinus Torvalds ee_data = 0;
73691da177e4SLinus Torvalds
73701da177e4SLinus Torvalds for (i = 1; i <= 16; i++) {
73711da177e4SLinus Torvalds
73721da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */
73731da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73741da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73751da177e4SLinus Torvalds ee_value &= ~SEE_CLK;
73761da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73771da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
73781da177e4SLinus Torvalds
73791da177e4SLinus Torvalds ee_data <<= 1;
73801da177e4SLinus Torvalds
73811da177e4SLinus Torvalds if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
73821da177e4SLinus Torvalds ee_data |= 1;
73831da177e4SLinus Torvalds }
73841da177e4SLinus Torvalds
73851da177e4SLinus Torvalds ee_value &= ~(SEE_MS + SEE_CS);
73861da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
73871da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
73881da177e4SLinus Torvalds
73895c1b85e2SAlexey Dobriyan return ee_data;
73901da177e4SLinus Torvalds }
73911da177e4SLinus Torvalds
73921da177e4SLinus Torvalds /*---------------------------------------------------------------------
73931da177e4SLinus Torvalds *
73941da177e4SLinus Torvalds * Function: Send EE command and Address to the EEPROM
73951da177e4SLinus Torvalds *
73961da177e4SLinus Torvalds * Description: Transfers the correct command and sends the address
73971da177e4SLinus Torvalds * to the eeprom.
73981da177e4SLinus Torvalds *
73991da177e4SLinus Torvalds *---------------------------------------------------------------------*/
74001da177e4SLinus Torvalds
FPT_utilEESendCmdAddr(u32 p_port,unsigned char ee_cmd,unsigned short ee_addr)7401391e2f25SKhalid Aziz static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
74025c04a7b8SAlexey Dobriyan unsigned short ee_addr)
74031da177e4SLinus Torvalds {
7404db038cf8SAlexey Dobriyan unsigned char ee_value;
7405db038cf8SAlexey Dobriyan unsigned char narrow_flg;
74061da177e4SLinus Torvalds
7407c823feebSAlexey Dobriyan unsigned short i;
74081da177e4SLinus Torvalds
74095c04a7b8SAlexey Dobriyan narrow_flg =
74105c04a7b8SAlexey Dobriyan (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
74115c04a7b8SAlexey Dobriyan NARROW_SCSI_CARD);
74121da177e4SLinus Torvalds
74131da177e4SLinus Torvalds ee_value = SEE_MS;
74141da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74151da177e4SLinus Torvalds
74161da177e4SLinus Torvalds ee_value |= SEE_CS; /* Set CS to EEPROM */
74171da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74181da177e4SLinus Torvalds
74191da177e4SLinus Torvalds for (i = 0x04; i != 0; i >>= 1) {
74201da177e4SLinus Torvalds
74211da177e4SLinus Torvalds if (i & ee_cmd)
74221da177e4SLinus Torvalds ee_value |= SEE_DO;
74231da177e4SLinus Torvalds else
74241da177e4SLinus Torvalds ee_value &= ~SEE_DO;
74251da177e4SLinus Torvalds
74261da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74271da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74281da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */
74291da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74301da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74311da177e4SLinus Torvalds ee_value &= ~SEE_CLK;
74321da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74331da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74341da177e4SLinus Torvalds }
74351da177e4SLinus Torvalds
74361da177e4SLinus Torvalds if (narrow_flg)
74371da177e4SLinus Torvalds i = 0x0080;
74381da177e4SLinus Torvalds
74391da177e4SLinus Torvalds else
74401da177e4SLinus Torvalds i = 0x0200;
74411da177e4SLinus Torvalds
74421da177e4SLinus Torvalds while (i != 0) {
74431da177e4SLinus Torvalds
74441da177e4SLinus Torvalds if (i & ee_addr)
74451da177e4SLinus Torvalds ee_value |= SEE_DO;
74461da177e4SLinus Torvalds else
74471da177e4SLinus Torvalds ee_value &= ~SEE_DO;
74481da177e4SLinus Torvalds
74491da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74501da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74511da177e4SLinus Torvalds ee_value |= SEE_CLK; /* Clock data! */
74521da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74531da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74541da177e4SLinus Torvalds ee_value &= ~SEE_CLK;
74551da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74561da177e4SLinus Torvalds WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
74571da177e4SLinus Torvalds
74581da177e4SLinus Torvalds i >>= 1;
74591da177e4SLinus Torvalds }
74601da177e4SLinus Torvalds }
74611da177e4SLinus Torvalds
FPT_CalcCrc16(unsigned char buffer[])7462c823feebSAlexey Dobriyan static unsigned short FPT_CalcCrc16(unsigned char buffer[])
74631da177e4SLinus Torvalds {
7464c823feebSAlexey Dobriyan unsigned short crc = 0;
74651da177e4SLinus Torvalds int i, j;
7466c823feebSAlexey Dobriyan unsigned short ch;
74675c04a7b8SAlexey Dobriyan for (i = 0; i < ID_STRING_LENGTH; i++) {
7468c823feebSAlexey Dobriyan ch = (unsigned short)buffer[i];
74695c04a7b8SAlexey Dobriyan for (j = 0; j < 8; j++) {
74701da177e4SLinus Torvalds if ((crc ^ ch) & 1)
74711da177e4SLinus Torvalds crc = (crc >> 1) ^ CRCMASK;
74721da177e4SLinus Torvalds else
74731da177e4SLinus Torvalds crc >>= 1;
74741da177e4SLinus Torvalds ch >>= 1;
74751da177e4SLinus Torvalds }
74761da177e4SLinus Torvalds }
74775c1b85e2SAlexey Dobriyan return crc;
74781da177e4SLinus Torvalds }
74791da177e4SLinus Torvalds
FPT_CalcLrc(unsigned char buffer[])7480db038cf8SAlexey Dobriyan static unsigned char FPT_CalcLrc(unsigned char buffer[])
74811da177e4SLinus Torvalds {
74821da177e4SLinus Torvalds int i;
7483db038cf8SAlexey Dobriyan unsigned char lrc;
74841da177e4SLinus Torvalds lrc = 0;
74851da177e4SLinus Torvalds for (i = 0; i < ID_STRING_LENGTH; i++)
74861da177e4SLinus Torvalds lrc ^= buffer[i];
74875c1b85e2SAlexey Dobriyan return lrc;
74881da177e4SLinus Torvalds }
74891da177e4SLinus Torvalds
74901da177e4SLinus Torvalds /*
74911da177e4SLinus Torvalds The following inline definitions avoid type conflicts.
74921da177e4SLinus Torvalds */
74931da177e4SLinus Torvalds
74941da177e4SLinus Torvalds static inline unsigned char
FlashPoint__ProbeHostAdapter(struct fpoint_info * FlashPointInfo)7495839cb99eSKhalid Aziz FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
74961da177e4SLinus Torvalds {
74975c04a7b8SAlexey Dobriyan return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
74985c04a7b8SAlexey Dobriyan FlashPointInfo);
74991da177e4SLinus Torvalds }
75001da177e4SLinus Torvalds
7501391e2f25SKhalid Aziz static inline void *
FlashPoint__HardwareResetHostAdapter(struct fpoint_info * FlashPointInfo)7502839cb99eSKhalid Aziz FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
75031da177e4SLinus Torvalds {
75045c04a7b8SAlexey Dobriyan return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
75055c04a7b8SAlexey Dobriyan FlashPointInfo);
75061da177e4SLinus Torvalds }
75071da177e4SLinus Torvalds
75081da177e4SLinus Torvalds static inline void
FlashPoint__ReleaseHostAdapter(void * CardHandle)7509391e2f25SKhalid Aziz FlashPoint__ReleaseHostAdapter(void *CardHandle)
75101da177e4SLinus Torvalds {
75111da177e4SLinus Torvalds FlashPoint_ReleaseHostAdapter(CardHandle);
75121da177e4SLinus Torvalds }
75131da177e4SLinus Torvalds
75141da177e4SLinus Torvalds static inline void
FlashPoint__StartCCB(void * CardHandle,struct blogic_ccb * CCB)7515391e2f25SKhalid Aziz FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
75161da177e4SLinus Torvalds {
751769eb2ea4SAlexey Dobriyan FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
75181da177e4SLinus Torvalds }
75191da177e4SLinus Torvalds
75201da177e4SLinus Torvalds static inline void
FlashPoint__AbortCCB(void * CardHandle,struct blogic_ccb * CCB)7521391e2f25SKhalid Aziz FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
75221da177e4SLinus Torvalds {
752369eb2ea4SAlexey Dobriyan FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
75241da177e4SLinus Torvalds }
75251da177e4SLinus Torvalds
75262065e310SRichard Knutsson static inline bool
FlashPoint__InterruptPending(void * CardHandle)7527391e2f25SKhalid Aziz FlashPoint__InterruptPending(void *CardHandle)
75281da177e4SLinus Torvalds {
75291da177e4SLinus Torvalds return FlashPoint_InterruptPending(CardHandle);
75301da177e4SLinus Torvalds }
75311da177e4SLinus Torvalds
75321da177e4SLinus Torvalds static inline int
FlashPoint__HandleInterrupt(void * CardHandle)7533391e2f25SKhalid Aziz FlashPoint__HandleInterrupt(void *CardHandle)
75341da177e4SLinus Torvalds {
75351da177e4SLinus Torvalds return FlashPoint_HandleInterrupt(CardHandle);
75361da177e4SLinus Torvalds }
75371da177e4SLinus Torvalds
75381da177e4SLinus Torvalds #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
75391da177e4SLinus Torvalds #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
75401da177e4SLinus Torvalds #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
75411da177e4SLinus Torvalds #define FlashPoint_StartCCB FlashPoint__StartCCB
75421da177e4SLinus Torvalds #define FlashPoint_AbortCCB FlashPoint__AbortCCB
75431da177e4SLinus Torvalds #define FlashPoint_InterruptPending FlashPoint__InterruptPending
75441da177e4SLinus Torvalds #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
75451da177e4SLinus Torvalds
754678b4b05dSMatthew Wilcox #else /* !CONFIG_SCSI_FLASHPOINT */
75471da177e4SLinus Torvalds
75481da177e4SLinus Torvalds /*
75491da177e4SLinus Torvalds Define prototypes for the FlashPoint SCCB Manager Functions.
75501da177e4SLinus Torvalds */
75511da177e4SLinus Torvalds
7552839cb99eSKhalid Aziz extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7553391e2f25SKhalid Aziz extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7554391e2f25SKhalid Aziz extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7555391e2f25SKhalid Aziz extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7556391e2f25SKhalid Aziz extern bool FlashPoint_InterruptPending(void *);
7557391e2f25SKhalid Aziz extern int FlashPoint_HandleInterrupt(void *);
7558391e2f25SKhalid Aziz extern void FlashPoint_ReleaseHostAdapter(void *);
75591da177e4SLinus Torvalds
756078b4b05dSMatthew Wilcox #endif /* CONFIG_SCSI_FLASHPOINT */
7561