blob: 88b7da37139991973dba4c2d78a32c59f0e39ce1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#define CRCMASK 0xA001
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define FAILURE 0xFFFFFFFFL
41
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080051#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080052#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
54
55
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -080056struct sccb;
57typedef void (*CALL_BK_FN)(struct sccb *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59
60typedef struct SCCBMgr_info {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080061 unsigned long si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080062 unsigned char si_present;
63 unsigned char si_intvect;
64 unsigned char si_id;
65 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080066 unsigned short si_fw_revision;
67 unsigned short si_per_targ_init_sync;
68 unsigned short si_per_targ_fast_nego;
69 unsigned short si_per_targ_ultra_nego;
70 unsigned short si_per_targ_no_disc;
71 unsigned short si_per_targ_wide_nego;
72 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080073 unsigned char si_card_family;
74 unsigned char si_bustype;
75 unsigned char si_card_model[3];
76 unsigned char si_relative_cardnum;
77 unsigned char si_reserved[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080078 unsigned long si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080079 unsigned char si_XlatInfo[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080080 unsigned long si_reserved2[5];
81 unsigned long si_secondary_range;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082} SCCBMGR_INFO;
83
James Bottomley 47b5d692005-04-24 02:38:05 -050084typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
86
James Bottomley 47b5d692005-04-24 02:38:05 -050087#define SCSI_PARITY_ENA 0x0001
88#define LOW_BYTE_TERM 0x0010
89#define HIGH_BYTE_TERM 0x0020
90#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92#define SUPPORT_16TAR_32LUN 0x0002
93#define SOFT_RESET 0x0004
94#define EXTENDED_TRANSLATION 0x0008
95#define POST_ALL_UNDERRRUNS 0x0040
96#define FLAG_SCAM_ENABLED 0x0080
97#define FLAG_SCAM_LEVEL2 0x0100
98
99
100
101
102#define HARPOON_FAMILY 0x02
103
104
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
Alexey Dobriyan323579882006-01-15 02:12:54 +0100106/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 * The UCB Manager treats the SCCB as it's 'native hardware structure'
108 */
109
110
111#pragma pack(1)
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800112struct sccb {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800113 unsigned char OperationCode;
114 unsigned char ControlByte;
115 unsigned char CdbLength;
116 unsigned char RequestSenseLength;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800117 unsigned long DataLength;
118 unsigned long DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800119 unsigned char CcbRes[2];
120 unsigned char HostStatus;
121 unsigned char TargetStatus;
122 unsigned char TargID;
123 unsigned char Lun;
124 unsigned char Cdb[12];
125 unsigned char CcbRes1;
126 unsigned char Reserved1;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800127 unsigned long Reserved2;
128 unsigned long SensePointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
130
131 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800132 unsigned long SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800133 unsigned char SccbStatus;
134 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800135 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136
137
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800138 unsigned long Sccb_XferCnt; /* actual transfer count */
139 unsigned long Sccb_ATC;
140 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
141 unsigned long Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800142 unsigned short Sccb_MGRFlags;
143 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800144 unsigned char Sccb_scsimsg; /* identify msg for selection */
145 unsigned char Sccb_tag;
146 unsigned char Sccb_scsistat;
147 unsigned char Sccb_idmsg; /* image of last msg in */
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800148 struct sccb * Sccb_forwardlink;
149 struct sccb * Sccb_backlink;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800150 unsigned long Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800151 unsigned char Save_Cdb[6];
152 unsigned char Save_CdbLen;
153 unsigned char Sccb_XferState;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800154 unsigned long Sccb_SGoffset;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800155 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157
158#pragma pack()
159
160
161
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162#define SCATTER_GATHER_COMMAND 0x02
163#define RESIDUAL_COMMAND 0x03
164#define RESIDUAL_SG_COMMAND 0x04
165#define RESET_COMMAND 0x81
166
167
168#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
169#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170#define SCCB_DATA_XFER_OUT 0x10 /* Write */
171#define SCCB_DATA_XFER_IN 0x08 /* Read */
172
173
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
175
176
177#define BUS_FREE_ST 0
178#define SELECT_ST 1
179#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
180#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
181#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
182#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
183#define COMMAND_ST 6
184#define DATA_OUT_ST 7
185#define DATA_IN_ST 8
186#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188
189
190#define F_HOST_XFER_DIR 0x01
191#define F_ALL_XFERRED 0x02
192#define F_SG_XFER 0x04
193#define F_AUTO_SENSE 0x08
194#define F_ODD_BALL_CNT 0x10
195#define F_NO_DATA_YET 0x80
196
197
198#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199#define F_DEV_SELECTED 0x04
200
201
202#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
203#define SCCB_DATA_UNDER_RUN 0x0C
204#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
205#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
207
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
209#define SCCB_BM_ERR 0x30 /* BusMaster error. */
210#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
211
212
213
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214
215
216#define SCCB_IN_PROCESS 0x00
217#define SCCB_SUCCESS 0x01
218#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221
222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223#define ORION_FW_REV 3110
224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
James Bottomley 47b5d692005-04-24 02:38:05 -0500232#define MAX_SCSI_TAR 16
233#define MAX_LUN 32
234#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
238#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
240
Alexey Dobriyanad0e1d92006-03-08 00:14:28 -0800241#define RD_HARPOON(ioport) inb((u32)ioport)
242#define RDW_HARPOON(ioport) inw((u32)ioport)
243#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
244#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
245#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
246#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248
249#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250#define SYNC_TRYING BIT(6)
251#define SYNC_SUPPORTED (BIT(7)+BIT(6))
252
253#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254#define WIDE_ENABLED BIT(4)
255#define WIDE_NEGOCIATED BIT(5)
256
257#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258#define TAG_Q_TRYING BIT(2)
259#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260
261#define TAR_ALLOW_DISC BIT(0)
262
263
264#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265#define EE_SYNC_5MB BIT(0)
266#define EE_SYNC_10MB BIT(1)
267#define EE_SYNC_20MB (BIT(0)+BIT(1))
268
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269#define EE_WIDE_SCSI BIT(7)
270
271
James Bottomley 47b5d692005-04-24 02:38:05 -0500272typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273
274
275typedef struct SCCBMgr_tar_info {
276
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800277 struct sccb * TarSelQ_Head;
278 struct sccb * TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800279 unsigned char TarLUN_CA; /*Contingent Allgiance */
280 unsigned char TarTagQ_Cnt;
281 unsigned char TarSelQ_Cnt;
282 unsigned char TarStatus;
283 unsigned char TarEEValue;
284 unsigned char TarSyncCtrl;
285 unsigned char TarReserved[2]; /* for alignment */
286 unsigned char LunDiscQ_Idx[MAX_LUN];
287 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288} SCCBMGR_TAR_INFO;
289
290typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800291 unsigned char niModel; /* Model No. of card */
292 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800293 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800294 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
295 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
296 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
297 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
298 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
299 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300}NVRAMINFO;
301
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303
304#define MODEL_LT 1
305#define MODEL_DL 2
306#define MODEL_LW 3
307#define MODEL_DW 4
308
309
310typedef struct SCCBcard {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800311 struct sccb * currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800314 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800316 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800317 unsigned char discQCount;
318 unsigned char tagQ_Lst;
319 unsigned char cardIndex;
320 unsigned char scanIndex;
321 unsigned char globalFlags;
322 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 PNVRamInfo pNvRamInfo;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800324 struct sccb * discQ_Tbl[QUEUE_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
326}SCCBCARD;
327
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329
330
331#define F_TAG_STARTED 0x01
332#define F_CONLUN_IO 0x02
333#define F_DO_RENEGO 0x04
334#define F_NO_FILTER 0x08
335#define F_GREEN_PC 0x10
336#define F_HOST_XFER_ACT 0x20
337#define F_NEW_SCCB_CMD 0x40
338#define F_UPDATE_EEPROM 0x80
339
340
341#define ID_STRING_LENGTH 32
342#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344
345#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
346
347#define ASSIGN_ID 0x00
348#define SET_P_FLAG 0x01
349#define CFG_CMPLT 0x03
350#define DOM_MSTR 0x0F
351#define SYNC_PTRN 0x1F
352
353#define ID_0_7 0x18
354#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355#define MISC_CODE 0x14
356#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
359
360#define INIT_SELTD 0x01
361#define LEVEL2_TAR 0x02
362
363
364enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
365 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
366 CLR_PRIORITY,NO_ID_AVAIL };
367
368typedef struct SCCBscam_info {
369
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800370 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 enum scam_id_st state;
372
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800373} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377#define SCSI_READ 0x08
378#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380#define SCSI_READ_EXTENDED 0x28
381#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
384
385
386#define SSGOOD 0x00
387#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388#define SSQ_FULL 0x28
389
390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
392
393#define SMCMD_COMP 0x00
394#define SMEXT 0x01
395#define SMSAVE_DATA_PTR 0x02
396#define SMREST_DATA_PTR 0x03
397#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398#define SMABORT 0x06
399#define SMREJECT 0x07
400#define SMNO_OP 0x08
401#define SMPARITY 0x09
402#define SMDEV_RESET 0x0C
403#define SMABORT_TAG 0x0D
404#define SMINIT_RECOVERY 0x0F
405#define SMREL_RECOVERY 0x10
406
407#define SMIDENT 0x80
408#define DISC_PRIV 0x40
409
410
411#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412#define SMWDTR 0x03
413#define SM8BIT 0x00
414#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415#define SMIGNORWR 0x23 /* Ignore Wide Residue */
416
417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
419
420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421
422
423
424#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425#define TWELVE_BYTE_CMD 0x0C
426
427#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431#define EEPROM_WD_CNT 256
432
433#define EEPROM_CHECK_SUM 0
434#define FW_SIGNATURE 2
435#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438#define SYSTEM_CONFIG 16
439#define SCSI_CONFIG 17
440#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441#define SCAM_CONFIG 20
442#define ADAPTER_SCSI_ID 24
443
444
445#define IGNORE_B_SCAN 32
446#define SEND_START_ENA 34
447#define DEVICE_ENABLE 36
448
449#define SYNC_RATE_TBL 38
450#define SYNC_RATE_TBL01 38
451#define SYNC_RATE_TBL23 40
452#define SYNC_RATE_TBL45 42
453#define SYNC_RATE_TBL67 44
454#define SYNC_RATE_TBL89 46
455#define SYNC_RATE_TBLab 48
456#define SYNC_RATE_TBLcd 50
457#define SYNC_RATE_TBLef 52
458
459
460
461#define EE_SCAMBASE 256
462
463
464
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 #define SCAM_ENABLED BIT(2)
466 #define SCAM_LEVEL2 BIT(3)
467
468
469 #define RENEGO_ENA BITW(10)
470 #define CONNIO_ENA BITW(11)
471 #define GREEN_PC_ENA BITW(12)
472
473
474 #define AUTO_RATE_00 00
475 #define AUTO_RATE_05 01
476 #define AUTO_RATE_10 02
477 #define AUTO_RATE_20 03
478
479 #define WIDE_NEGO_BIT BIT(7)
480 #define DISC_ENABLE_BIT BIT(6)
481
482
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483
484 #define hp_vendor_id_0 0x00 /* LSB */
485 #define ORION_VEND_0 0x4B
486
487 #define hp_vendor_id_1 0x01 /* MSB */
488 #define ORION_VEND_1 0x10
489
490 #define hp_device_id_0 0x02 /* LSB */
491 #define ORION_DEV_0 0x30
492
493 #define hp_device_id_1 0x03 /* MSB */
494 #define ORION_DEV_1 0x81
495
496 /* Sub Vendor ID and Sub Device ID only available in
497 Harpoon Version 2 and higher */
498
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
501
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502
503 #define hp_semaphore 0x0C
504 #define SCCB_MGR_ACTIVE BIT(0)
505 #define TICKLE_ME BIT(1)
506 #define SCCB_MGR_PRESENT BIT(3)
507 #define BIOS_IN_USE BIT(4)
508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
511 #define hp_sys_ctrl 0x0F
512
513 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
514 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
515 #define HALT_MACH BIT(3) /*Halt State Machine */
516 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800522
523
524
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
526 #define hp_host_blk_cnt 0x13
527
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
529
530 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
531
532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
534 #define hp_int_mask 0x17
535
536 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
537 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538
539
540 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 #define hp_xfer_cnt_hi 0x1A
542 #define hp_xfer_cmd 0x1B
543
544 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
545 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547
548 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551
552 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
553
554 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
555 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
557 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 #define hp_ee_ctrl 0x22
561
562 #define EXT_ARB_ACK BIT(7)
563 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
564 #define SEE_MS BIT(5)
565 #define SEE_CS BIT(3)
566 #define SEE_CLK BIT(2)
567 #define SEE_DO BIT(1)
568 #define SEE_DI BIT(0)
569
570 #define EE_READ 0x06
571 #define EE_WRITE 0x05
572 #define EWEN 0x04
573 #define EWEN_ADDR 0x03C0
574 #define EWDS 0x04
575 #define EWDS_ADDR 0x0000
576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
580
581
582
583 #define hp_bm_ctrl 0x26
584
585 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
586 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
588 #define FAST_SINGLE BIT(6) /*?? */
589
590 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592
593 #define hp_sg_addr 0x28
594 #define hp_page_ctrl 0x29
595
596 #define SCATTER_EN BIT(0)
597 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
599 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
600
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
604 #define hp_pci_stat_cfg 0x2D
605
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
615 #define hp_rev_num 0x33
616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
618 #define hp_stack_data 0x34
619 #define hp_stack_addr 0x35
620
621 #define hp_ext_status 0x36
622
623 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
624 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
625 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 #define CMD_ABORTED BIT(4) /*Command aborted */
627 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
628 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
629 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
630 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
631 BM_PARITY_ERR | PIO_OVERRUN)
632
633 #define hp_int_status 0x37
634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
636 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
639
640 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
643
644
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 #define hp_intena 0x40
646
647 #define RESET BITW(7)
648 #define PROG_HLT BITW(6)
649 #define PARITY BITW(5)
650 #define FIFO BITW(4)
651 #define SEL BITW(3)
652 #define SCAM_SEL BITW(2)
653 #define RSEL BITW(1)
654 #define TIMEOUT BITW(0)
655 #define BUS_FREE BITW(15)
656 #define XFER_CNT_0 BITW(14)
657 #define PHASE BITW(13)
658 #define IUNKWN BITW(12)
659 #define ICMD_COMP BITW(11)
660 #define ITICKLE BITW(10)
661 #define IDO_STRT BITW(9)
662 #define ITAR_DISC BITW(8)
663 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
664 #define CLR_ALL_INT 0xFFFF
665 #define CLR_ALL_INT_1 0xFF00
666
667 #define hp_intstat 0x42
668
669 #define hp_scsisig 0x44
670
671 #define SCSI_SEL BIT(7)
672 #define SCSI_BSY BIT(6)
673 #define SCSI_REQ BIT(5)
674 #define SCSI_ACK BIT(4)
675 #define SCSI_ATN BIT(3)
676 #define SCSI_CD BIT(2)
677 #define SCSI_MSG BIT(1)
678 #define SCSI_IOBIT BIT(0)
679
680 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
683 #define S_DATAI_PH ( BIT(0))
684 #define S_DATAO_PH 0x00
685 #define S_ILL_PH ( BIT(1) )
686
687 #define hp_scsictrl_0 0x45
688
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 #define SEL_TAR BIT(6)
690 #define ENA_ATN BIT(4)
691 #define ENA_RESEL BIT(2)
692 #define SCSI_RST BIT(1)
693 #define ENA_SCAM_SEL BIT(0)
694
695
696
697 #define hp_portctrl_0 0x46
698
699 #define SCSI_PORT BIT(7)
700 #define SCSI_INBIT BIT(6)
701 #define DMA_PORT BIT(5)
702 #define DMA_RD BIT(4)
703 #define HOST_PORT BIT(3)
704 #define HOST_WRT BIT(2)
705 #define SCSI_BUS_EN BIT(1)
706 #define START_TO BIT(0)
707
708 #define hp_scsireset 0x47
709
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 #define SCSI_INI BIT(6)
711 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 #define DMA_RESET BIT(3)
713 #define HPSCSI_RESET BIT(2)
714 #define PROG_RESET BIT(1)
715 #define FIFO_CLR BIT(0)
716
717 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
720 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 #define hp_addstat 0x4E
722
723 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 #define SCSI_MODE8 BIT(3)
725 #define SCSI_PAR_ERR BIT(0)
726
727 #define hp_prgmcnt_0 0x4F
728
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
730 #define hp_selfid_0 0x50
731 #define hp_selfid_1 0x51
732 #define hp_arb_id 0x52
733
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
735 #define hp_select_id 0x53
736
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737
738 #define hp_synctarg_base 0x54
739 #define hp_synctarg_12 0x54
740 #define hp_synctarg_13 0x55
741 #define hp_synctarg_14 0x56
742 #define hp_synctarg_15 0x57
743
744 #define hp_synctarg_8 0x58
745 #define hp_synctarg_9 0x59
746 #define hp_synctarg_10 0x5A
747 #define hp_synctarg_11 0x5B
748
749 #define hp_synctarg_4 0x5C
750 #define hp_synctarg_5 0x5D
751 #define hp_synctarg_6 0x5E
752 #define hp_synctarg_7 0x5F
753
754 #define hp_synctarg_0 0x60
755 #define hp_synctarg_1 0x61
756 #define hp_synctarg_2 0x62
757 #define hp_synctarg_3 0x63
758
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 #define DEFAULT_OFFSET 0x0F
761
762 #define hp_autostart_0 0x64
763 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 #define hp_autostart_3 0x67
765
766
767
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 #define AUTO_IMMED BIT(5)
769 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
772 #define hp_gp_reg_0 0x68
773 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 #define hp_gp_reg_3 0x6B
775
776 #define hp_seltimeout 0x6C
777
778
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 #define TO_4ms 0x67 /* 3.9959ms */
780
781 #define TO_5ms 0x03 /* 4.9152ms */
782 #define TO_10ms 0x07 /* 11.xxxms */
783 #define TO_250ms 0x99 /* 250.68ms */
784 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786 #define hp_clkctrl_0 0x6D
787
788 #define PWR_DWN BIT(6)
789 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
792 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
793
794 #define hp_fiforead 0x6E
795 #define hp_fifowrite 0x6F
796
797 #define hp_offsetctr 0x70
798 #define hp_xferstat 0x71
799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 #define hp_portctrl_1 0x72
803
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804 #define CHK_SCSI_P BIT(3)
805 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806
807 #define hp_xfer_pad 0x73
808
809 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 #define hp_scsidata_0 0x74
812 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
816 #define hp_aramBase 0x80
817 #define BIOS_DATA_OFFSET 0x60
818 #define BIOS_RELATIVE_CARD 0x64
819
820
821
822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 #define AR3 (BITW(9) + BITW(8))
824 #define SDATA BITW(10)
825
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
828
829 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
834
835 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
836
837
838 #define ADATA_OUT 0x00
839 #define ADATA_IN BITW(8)
840 #define ACOMMAND BITW(10)
841 #define ASTATUS (BITW(10)+BITW(8))
842 #define AMSG_OUT (BITW(10)+BITW(9))
843 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
845
846 #define BRH_OP BITW(13) /* Branch */
847
848
849 #define ALWAYS 0x00
850 #define EQUAL BITW(8)
851 #define NOT_EQ BITW(9)
852
853 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
854
855
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857
858
859 #define MPM_OP BITW(15) /* Match phase and move data */
860
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861
862 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
863
864
865 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
866
867
868 #define D_AR0 0x00
869 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
871
872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878
879
880 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
881
882 #define SSI_OP (BITW(15)+BITW(11))
883
884
885 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
886 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
888 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
889 #define SSI_ITICKLE (ITICKLE >> 8)
890
891 #define SSI_IUNKWN (IUNKWN >> 8)
892 #define SSI_INO_CC (IUNKWN >> 8)
893 #define SSI_IRFAIL (IUNKWN >> 8)
894
895
896 #define NP 0x10 /*Next Phase */
897 #define NTCMD 0x02 /*Non- Tagged Command start */
898 #define CMDPZ 0x04 /*Command phase */
899 #define DINT 0x12 /*Data Out/In interrupt */
900 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 #define DC 0x19 /*Disconnect Message */
902 #define ST 0x1D /*Status Phase */
903 #define UNKNWN 0x24 /*Unknown bus action */
904 #define CC 0x25 /*Command Completion failure */
905 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
907
908
909 #define ID_MSG_STRT hp_aramBase + 0x00
910 #define NON_TAG_ID_MSG hp_aramBase + 0x06
911 #define CMD_STRT hp_aramBase + 0x08
912 #define SYNC_MSGS hp_aramBase + 0x08
913
914
915
916
917
918 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 #define DISCONNECT_START 0x10/2
920 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 #define SELCHK_STRT SELCHK/2
923
924
925
926
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
928
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800930
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
932#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
933/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
934 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800935 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800937#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800939 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800941 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 count >>= 16,\
943 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944
945#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
946 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
947
948
949#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
950 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
954#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
955 WR_HARPOON(port+hp_scsireset, 0x00))
956
957#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
958 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
959
960#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
961 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
962
963#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
964 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
965
966#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
967 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
968
969
970
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800972static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
973static void FPT_ssel(unsigned long port, unsigned char p_card);
974static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800975static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800976static void FPT_stsyncn(unsigned long port, unsigned char p_card);
977static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
978static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500979 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800980static void FPT_sresb(unsigned long port, unsigned char p_card);
981static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
982static void FPT_schkdd(unsigned long port, unsigned char p_card);
983static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
984static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
985static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800987static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800988static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
989 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800991static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -0500992static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800994static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
995static void FPT_stwidn(unsigned long port, unsigned char p_card);
996static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
998
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800999static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001000static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
1001static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001002 unsigned char p_card);
1003static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1004static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001005static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1006static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1007static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001008static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001009static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010
1011
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001012static void FPT_Wait1Second(unsigned long p_port);
1013static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1014static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1015static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1016static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1017static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1018static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019
1020
1021
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001022static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1023static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1024static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1025static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1026static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1027static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1028static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001030static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1031static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1032static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033
1034
1035
1036
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001037static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1038static void FPT_BusMasterInit(unsigned long p_port);
1039static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
1041
1042
1043
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001044static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001045static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1046static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1047static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1048static void FPT_hostDataXferRestart(struct sccb * currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001051static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001052 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
James Bottomley 47b5d692005-04-24 02:38:05 -05001054static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001055static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1056static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
1058
1059
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001060static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001062static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1063static void FPT_scbusf(unsigned long p_port);
1064static void FPT_scsel(unsigned long p_port);
1065static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1066static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1067static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1068static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1069static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1070static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001071static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001072static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1073static void FPT_scwtsel(unsigned long p_port);
1074static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1075static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001076static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001079static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1080static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
1082
1083
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
James Bottomley 47b5d692005-04-24 02:38:05 -05001085static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1086static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1087static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1088static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
1090
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001091static unsigned char FPT_mbCards = 0;
1092static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001093 ' ', 'B', 'T', '-', '9', '3', '0', \
1094 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1095 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001097static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
1099
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001100static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
1103/*---------------------------------------------------------------------
1104 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001105 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 *
1107 * Description: Setup and/or Search for cards and return info to caller.
1108 *
1109 *---------------------------------------------------------------------*/
1110
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001111static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001113 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001115 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001116 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001117 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 PNVRamInfo pCurrNvRam;
1119
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121
1122
1123 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1124 return((int)FAILURE);
1125
1126 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1127 return((int)FAILURE);
1128
1129 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1130 return((int)FAILURE);
1131
1132 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1133 return((int)FAILURE);
1134
1135
1136 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1137
1138/* For new Harpoon then check for sub_device ID LSB
1139 the bits(0-3) must be all ZERO for compatible with
1140 current version of SCCBMgr, else skip this Harpoon
1141 device. */
1142
1143 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1144 return((int)FAILURE);
1145 }
1146
1147 if (first_time)
1148 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001149 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001151 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 }
1153
James Bottomley 47b5d692005-04-24 02:38:05 -05001154 if(FPT_RdStack(ioport, 0) != 0x00) {
1155 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 {
1157 pCurrNvRam = NULL;
1158 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001159 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1160 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 }
1162 else
1163 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001164 if(FPT_mbCards < MAX_MB_CARDS) {
1165 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1166 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001168 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 }else
1170 return((int) FAILURE);
1171 }
1172 }else
1173 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1176 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1177
1178 if(pCurrNvRam)
1179 pCardInfo->si_id = pCurrNvRam->niAdapId;
1180 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001181 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1182 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
1184 pCardInfo->si_lun = 0x00;
1185 pCardInfo->si_fw_revision = ORION_FW_REV;
1186 temp2 = 0x0000;
1187 temp3 = 0x0000;
1188 temp4 = 0x0000;
1189 temp5 = 0x0000;
1190 temp6 = 0x0000;
1191
1192 for (id = 0; id < (16/2); id++) {
1193
1194 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001195 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1197 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1198 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001199 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
1201 for (i = 0; i < 2; temp >>=8,i++) {
1202
1203 temp2 >>= 1;
1204 temp3 >>= 1;
1205 temp4 >>= 1;
1206 temp5 >>= 1;
1207 temp6 >>= 1;
1208 switch (temp & 0x3)
1209 {
1210 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1211 temp6 |= 0x8000; /* Fall through */
1212 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1213 temp5 |= 0x8000; /* Fall through */
1214 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1215 temp2 |= 0x8000; /* Fall through */
1216 case AUTO_RATE_00: /* Asynchronous */
1217 break;
1218 }
1219
1220 if (temp & DISC_ENABLE_BIT)
1221 temp3 |= 0x8000;
1222
1223 if (temp & WIDE_NEGO_BIT)
1224 temp4 |= 0x8000;
1225
1226 }
1227 }
1228
1229 pCardInfo->si_per_targ_init_sync = temp2;
1230 pCardInfo->si_per_targ_no_disc = temp3;
1231 pCardInfo->si_per_targ_wide_nego = temp4;
1232 pCardInfo->si_per_targ_fast_nego = temp5;
1233 pCardInfo->si_per_targ_ultra_nego = temp6;
1234
1235 if(pCurrNvRam)
1236 i = pCurrNvRam->niSysConf;
1237 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001238 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
1240 if(pCurrNvRam)
1241 ScamFlg = pCurrNvRam->niScamConf;
1242 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001243 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
1245 pCardInfo->si_flags = 0x0000;
1246
1247 if (i & 0x01)
1248 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1249
1250 if (!(i & 0x02))
1251 pCardInfo->si_flags |= SOFT_RESET;
1252
1253 if (i & 0x10)
1254 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1255
1256 if (ScamFlg & SCAM_ENABLED)
1257 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1258
1259 if (ScamFlg & SCAM_LEVEL2)
1260 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1261
1262 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1263 if (i & 0x04) {
1264 j |= SCSI_TERM_ENA_L;
1265 }
1266 WR_HARPOON(ioport+hp_bm_ctrl, j );
1267
1268 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1269 if (i & 0x08) {
1270 j |= SCSI_TERM_ENA_H;
1271 }
1272 WR_HARPOON(ioport+hp_ee_ctrl, j );
1273
1274 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1275
1276 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1277
1278 pCardInfo->si_card_family = HARPOON_FAMILY;
1279 pCardInfo->si_bustype = BUSTYPE_PCI;
1280
1281 if(pCurrNvRam){
1282 pCardInfo->si_card_model[0] = '9';
1283 switch(pCurrNvRam->niModel & 0x0f){
1284 case MODEL_LT:
1285 pCardInfo->si_card_model[1] = '3';
1286 pCardInfo->si_card_model[2] = '0';
1287 break;
1288 case MODEL_LW:
1289 pCardInfo->si_card_model[1] = '5';
1290 pCardInfo->si_card_model[2] = '0';
1291 break;
1292 case MODEL_DL:
1293 pCardInfo->si_card_model[1] = '3';
1294 pCardInfo->si_card_model[2] = '2';
1295 break;
1296 case MODEL_DW:
1297 pCardInfo->si_card_model[1] = '5';
1298 pCardInfo->si_card_model[2] = '2';
1299 break;
1300 }
1301 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001302 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001303 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001304 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001306 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1307 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 }
1309
1310 if (pCardInfo->si_card_model[1] == '3')
1311 {
1312 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1313 pCardInfo->si_flags |= LOW_BYTE_TERM;
1314 }
1315 else if (pCardInfo->si_card_model[2] == '0')
1316 {
1317 temp = RD_HARPOON(ioport+hp_xfer_pad);
1318 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1319 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1320 pCardInfo->si_flags |= LOW_BYTE_TERM;
1321 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1322 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1323 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1324 WR_HARPOON(ioport+hp_xfer_pad, temp);
1325 }
1326 else
1327 {
1328 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1329 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1330 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1331 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1332 temp3 = 0;
1333 for (i = 0; i < 8; i++)
1334 {
1335 temp3 <<= 1;
1336 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1337 temp3 |= 1;
1338 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1339 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1340 }
1341 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1342 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1343 if (!(temp3 & BIT(7)))
1344 pCardInfo->si_flags |= LOW_BYTE_TERM;
1345 if (!(temp3 & BIT(6)))
1346 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1347 }
1348
1349
1350 ARAM_ACCESS(ioport);
1351
1352 for ( i = 0; i < 4; i++ ) {
1353
1354 pCardInfo->si_XlatInfo[i] =
1355 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1356 }
1357
1358 /* return with -1 if no sort, else return with
1359 logical card number sorted by BIOS (zero-based) */
1360
1361 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001362 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
1364 SGRAM_ACCESS(ioport);
1365
James Bottomley 47b5d692005-04-24 02:38:05 -05001366 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1367 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1368 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1369 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1370 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1371 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1372 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1373 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
1375 pCardInfo->si_present = 0x01;
1376
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 return(0);
1378}
1379
1380
1381/*---------------------------------------------------------------------
1382 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001383 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 *
1385 * Description: Setup adapter for normal operation (hard reset).
1386 *
1387 *---------------------------------------------------------------------*/
1388
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001389static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390{
1391 PSCCBcard CurrCard = NULL;
1392 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001393 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001394 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001395 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398
1399 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1400
1401 if (thisCard == MAX_CARDS) {
1402
1403 return(FAILURE);
1404 }
1405
James Bottomley 47b5d692005-04-24 02:38:05 -05001406 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
James Bottomley 47b5d692005-04-24 02:38:05 -05001408 CurrCard = &FPT_BL_Card[thisCard];
1409 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 break;
1411 }
1412
James Bottomley 47b5d692005-04-24 02:38:05 -05001413 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
James Bottomley 47b5d692005-04-24 02:38:05 -05001415 FPT_BL_Card[thisCard].ioPort = ioport;
1416 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
James Bottomley 47b5d692005-04-24 02:38:05 -05001418 if(FPT_mbCards)
1419 for(i = 0; i < FPT_mbCards; i++){
1420 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1421 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001423 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 CurrCard->cardIndex = thisCard;
1425 CurrCard->cardInfo = pCardInfo;
1426
1427 break;
1428 }
1429 }
1430
1431 pCurrNvRam = CurrCard->pNvRamInfo;
1432
1433 if(pCurrNvRam){
1434 ScamFlg = pCurrNvRam->niScamConf;
1435 }
1436 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001437 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 }
1439
1440
James Bottomley 47b5d692005-04-24 02:38:05 -05001441 FPT_BusMasterInit(ioport);
1442 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
James Bottomley 47b5d692005-04-24 02:38:05 -05001444 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445
1446
1447 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1448
1449 WR_HARPOON(ioport+hp_selfid_0, id);
1450 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1451 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1452 CurrCard->ourId = pCardInfo->si_id;
1453
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001454 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 if (i & SCSI_PARITY_ENA)
1456 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1457
1458 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1459 if (i & LOW_BYTE_TERM)
1460 j |= SCSI_TERM_ENA_L;
1461 WR_HARPOON(ioport+hp_bm_ctrl, j);
1462
1463 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1464 if (i & HIGH_BYTE_TERM)
1465 j |= SCSI_TERM_ENA_H;
1466 WR_HARPOON(ioport+hp_ee_ctrl, j );
1467
1468
1469 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1470
James Bottomley 47b5d692005-04-24 02:38:05 -05001471 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
James Bottomley 47b5d692005-04-24 02:38:05 -05001473 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 }
1475
1476
1477
1478 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1479 CurrCard->globalFlags |= F_NO_FILTER;
1480
1481 if(pCurrNvRam){
1482 if(pCurrNvRam->niSysConf & 0x10)
1483 CurrCard->globalFlags |= F_GREEN_PC;
1484 }
1485 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001486 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 CurrCard->globalFlags |= F_GREEN_PC;
1488 }
1489
1490 /* Set global flag to indicate Re-Negotiation to be done on all
1491 ckeck condition */
1492 if(pCurrNvRam){
1493 if(pCurrNvRam->niScsiConf & 0x04)
1494 CurrCard->globalFlags |= F_DO_RENEGO;
1495 }
1496 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001497 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 CurrCard->globalFlags |= F_DO_RENEGO;
1499 }
1500
1501 if(pCurrNvRam){
1502 if(pCurrNvRam->niScsiConf & 0x08)
1503 CurrCard->globalFlags |= F_CONLUN_IO;
1504 }
1505 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001506 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 CurrCard->globalFlags |= F_CONLUN_IO;
1508 }
1509
1510
1511 temp = pCardInfo->si_per_targ_no_disc;
1512
1513 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1514
1515 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001516 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 }
1518
1519 sync_bit_map = 0x0001;
1520
1521 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1522
1523 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001524 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1526 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1527 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001528 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529
1530 for (i = 0; i < 2; temp >>=8,i++) {
1531
1532 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1533
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001534 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 }
1536
1537 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001538 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1539 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001540 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 }
1542
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1544 (id*2+i >= 8)){
1545*/
1546 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1547
James Bottomley 47b5d692005-04-24 02:38:05 -05001548 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
1550 }
1551
1552 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001553 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 }
1555
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
1557 sync_bit_map <<= 1;
1558
1559
1560
1561 }
1562 }
1563
1564 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001565 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001567 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568}
1569
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001570static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001572 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001573 unsigned long portBase;
1574 unsigned long regOffset;
1575 unsigned long scamData;
1576 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 PNVRamInfo pCurrNvRam;
1578
1579 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1580
1581 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001582 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1585 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1586 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
1588 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001589 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590
1591 portBase = pCurrNvRam->niBaseAddr;
1592
1593 for(i = 0; i < MAX_SCSI_TAR; i++){
1594 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001595 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 scamData = *pScamTbl;
1597 WR_HARP32(portBase, regOffset, scamData);
1598 }
1599
1600 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001601 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 }
1603}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
1605
James Bottomley 47b5d692005-04-24 02:38:05 -05001606static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001608 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001609 unsigned long portBase;
1610 unsigned long regOffset;
1611 unsigned long scamData;
1612 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613
James Bottomley 47b5d692005-04-24 02:38:05 -05001614 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1615 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1616 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1617 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1618 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
1620 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001621 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622
1623 portBase = pNvRamInfo->niBaseAddr;
1624
1625 for(i = 0; i < MAX_SCSI_TAR; i++){
1626 regOffset = hp_aramBase + 64 + i*4;
1627 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001628 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 *pScamTbl = scamData;
1630 }
1631
1632}
1633
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001634static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635{
1636 WR_HARPOON(portBase + hp_stack_addr, index);
1637 return(RD_HARPOON(portBase + hp_stack_data));
1638}
1639
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001640static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641{
1642 WR_HARPOON(portBase + hp_stack_addr, index);
1643 WR_HARPOON(portBase + hp_stack_data, data);
1644}
1645
1646
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001647static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648{
James Bottomley 47b5d692005-04-24 02:38:05 -05001649 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1650 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1652 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001653 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1655 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001656 return(1);
1657 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
1659}
1660/*---------------------------------------------------------------------
1661 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001662 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 *
1664 * Description: Start a command pointed to by p_Sccb. When the
1665 * command is completed it will be returned via the
1666 * callback function.
1667 *
1668 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001669static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001671 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001672 unsigned char thisCard, lun;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001673 struct sccb * pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 CALL_BK_FN callback;
1675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1677 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1680 {
1681
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 p_Sccb->HostStatus = SCCB_COMPLETE;
1683 p_Sccb->SccbStatus = SCCB_ERROR;
1684 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1685 if (callback)
1686 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 return;
1689 }
1690
James Bottomley 47b5d692005-04-24 02:38:05 -05001691 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
1693
1694 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1695 {
1696 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1697 | SCCB_MGR_ACTIVE));
1698
1699 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1700 {
1701 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1702 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1703 }
1704 }
1705
1706 ((PSCCBcard)pCurrCard)->cmdCounter++;
1707
1708 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1709
1710 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1711 | TICKLE_ME));
1712 if(p_Sccb->OperationCode == RESET_COMMAND)
1713 {
1714 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1715 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001716 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1718 }
1719 else
1720 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001721 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 }
1723 }
1724
1725 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1726
1727 if(p_Sccb->OperationCode == RESET_COMMAND)
1728 {
1729 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1730 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001731 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1733 }
1734 else
1735 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001736 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 }
1738 }
1739
1740 else {
1741
1742 MDISABLE_INT(ioport);
1743
1744 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001745 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 lun = p_Sccb->Lun;
1747 else
1748 lun = 0;
1749 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001750 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1751 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1752 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
1754 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001755 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757
1758 else {
1759
1760 if(p_Sccb->OperationCode == RESET_COMMAND)
1761 {
1762 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1763 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001764 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1766 }
1767 else
1768 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001769 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 }
1771 }
1772
1773
1774 MENABLE_INT(ioport);
1775 }
1776
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777}
1778
1779
1780/*---------------------------------------------------------------------
1781 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001782 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 *
1784 * Description: Abort the command pointed to by p_Sccb. When the
1785 * command is completed it will be returned via the
1786 * callback function.
1787 *
1788 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001789static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001791 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001793 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001795 unsigned char TID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001796 struct sccb * pSaveSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 PSCCBMgr_tar_info currTar_Info;
1798
1799
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1801
1802 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1803
James Bottomley 47b5d692005-04-24 02:38:05 -05001804 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 {
1806
James Bottomley 47b5d692005-04-24 02:38:05 -05001807 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 {
1809
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 ((PSCCBcard)pCurrCard)->cmdCounter--;
1811
1812 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1813 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001814 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 p_Sccb->SccbStatus = SCCB_ABORT;
1817 callback = p_Sccb->SccbCallback;
1818 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 return(0);
1821 }
1822
1823 else
1824 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1826 {
1827 p_Sccb->SccbStatus = SCCB_ABORT;
1828 return(0);
1829
1830 }
1831
1832 else
1833 {
1834
1835 TID = p_Sccb->TargID;
1836
1837
1838 if(p_Sccb->Sccb_tag)
1839 {
1840 MDISABLE_INT(ioport);
1841 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1842 {
1843 p_Sccb->SccbStatus = SCCB_ABORT;
1844 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1846
1847 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1848 {
1849 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001850 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 }
1852 else
1853 {
1854 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1855 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001856 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1858 }
1859 }
1860 MENABLE_INT(ioport);
1861 return(0);
1862 }
1863 else
1864 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001865 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866
James Bottomley 47b5d692005-04-24 02:38:05 -05001867 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 == p_Sccb)
1869 {
1870 p_Sccb->SccbStatus = SCCB_ABORT;
1871 return(0);
1872 }
1873 }
1874 }
1875 }
1876 }
1877 return(-1);
1878}
1879
1880
1881/*---------------------------------------------------------------------
1882 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001883 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 *
1885 * Description: Do a quick check to determine if there is a pending
1886 * interrupt for this card and disable the IRQ Pin if so.
1887 *
1888 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001889static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001891 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892
1893 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1894
1895 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1896 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001897 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 }
1899
1900 else
1901
James Bottomley 47b5d692005-04-24 02:38:05 -05001902 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903}
1904
1905
1906
1907/*---------------------------------------------------------------------
1908 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001909 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 *
1911 * Description: This is our entry point when an interrupt is generated
1912 * by the card and the upper level driver passes it on to
1913 * us.
1914 *
1915 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001916static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001918 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001919 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001920 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001921 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001922 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923
1924 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1925 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1926
1927 MDISABLE_INT(ioport);
1928
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001930 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 else
1932 bm_status = 0;
1933
1934 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1935
James Bottomley 47b5d692005-04-24 02:38:05 -05001936 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 bm_status)
1938 {
1939
1940 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1941
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001943 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1945 bm_status = 0;
1946
1947 if (result) {
1948
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 return(result);
1951 }
1952 }
1953
1954
1955 else if (hp_int & ICMD_COMP) {
1956
1957 if ( !(hp_int & BUS_FREE) ) {
1958 /* Wait for the BusFree before starting a new command. We
1959 must also check for being reselected since the BusFree
1960 may not show up if another device reselects us in 1.5us or
1961 less. SRR Wednesday, 3/8/1995.
1962 */
1963 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1964 }
1965
1966 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1967
James Bottomley 47b5d692005-04-24 02:38:05 -05001968 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969
1970/* WRW_HARPOON((ioport+hp_intstat),
1971 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1972 */
1973
1974 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1975
James Bottomley 47b5d692005-04-24 02:38:05 -05001976 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
1978 }
1979
1980
1981 else if (hp_int & ITAR_DISC)
1982 {
1983
1984 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1985
James Bottomley 47b5d692005-04-24 02:38:05 -05001986 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987
1988 }
1989
1990 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1991
1992 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1993 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1994
1995 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1996 }
1997
1998 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05001999 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000
2001 /* Wait for the BusFree before starting a new command. We
2002 must also check for being reselected since the BusFree
2003 may not show up if another device reselects us in 1.5us or
2004 less. SRR Wednesday, 3/8/1995.
2005 */
2006 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2007 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2008 RD_HARPOON((ioport+hp_scsisig)) ==
2009 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2010
2011 /*
2012 The additional loop exit condition above detects a timing problem
2013 with the revision D/E harpoon chips. The caller should reset the
2014 host adapter to recover when 0xFE is returned.
2015 */
2016 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2017 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 return 0xFE;
2020 }
2021
2022 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2023
2024
2025 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2026
2027 }
2028
2029
2030 else if (hp_int & RSEL) {
2031
2032 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2033
2034 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2035 {
2036 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2037 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002038 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 }
2040
2041 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2042 {
2043 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2044 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2045 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2046 }
2047
2048 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2049 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002050 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 }
2052
James Bottomley 47b5d692005-04-24 02:38:05 -05002053 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2054 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055
2056 }
2057
2058
2059 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2060 {
2061
2062 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002063 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
2065 }
2066
2067
2068 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2069 {
2070 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002071 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002073 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074 }
2075 else
2076 {
2077 /* Harpoon problem some SCSI target device respond to selection
2078 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2079 to latch the correct Target ID into reg. x53.
2080 The work around require to correct this reg. But when write to this
2081 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2082 need to read this reg first then restore it later. After update to 0x53 */
2083
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002084 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2085 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2086 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2087 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2088 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 WR_HARPOON(ioport+hp_fifowrite, i);
2090 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2091 }
2092 }
2093
2094 else if (hp_int & XFER_CNT_0) {
2095
2096 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2097
James Bottomley 47b5d692005-04-24 02:38:05 -05002098 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099
2100 }
2101
2102
2103 else if (hp_int & BUS_FREE) {
2104
2105 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2106
2107 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2108
James Bottomley 47b5d692005-04-24 02:38:05 -05002109 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110 }
2111
James Bottomley 47b5d692005-04-24 02:38:05 -05002112 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113 }
2114
2115
2116 else if (hp_int & ITICKLE) {
2117
2118 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2119 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2120 }
2121
2122
2123
2124 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2125
2126
2127 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2128
2129
2130 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2131
James Bottomley 47b5d692005-04-24 02:38:05 -05002132 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 }
2134
2135 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2136 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002137 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138 }
2139
2140 break;
2141
2142 }
2143
2144 } /*end while */
2145
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147
2148 return(0);
2149}
2150
2151/*---------------------------------------------------------------------
2152 *
2153 * Function: Sccb_bad_isr
2154 *
2155 * Description: Some type of interrupt has occurred which is slightly
2156 * out of the ordinary. We will now decode it fully, in
2157 * this routine. This is broken up in an attempt to save
2158 * processing time.
2159 *
2160 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002161static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002162 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002164 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002165 PSCCBMgr_tar_info currTar_Info;
2166 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167
2168
2169 if (RD_HARPOON(p_port+hp_ext_status) &
2170 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2171 {
2172
2173 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2174 {
2175
James Bottomley 47b5d692005-04-24 02:38:05 -05002176 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177 }
2178
2179 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2180
2181 {
2182 WR_HARPOON(p_port+hp_pci_stat_cfg,
2183 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2184
2185 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2186
2187 }
2188
2189 if (pCurrCard->currentSCCB != NULL)
2190 {
2191
2192 if (!pCurrCard->currentSCCB->HostStatus)
2193 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2194
James Bottomley 47b5d692005-04-24 02:38:05 -05002195 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002197 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002199 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2201
2202 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2203 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002204 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 }
2206 }
2207 }
2208
2209
2210 else if (p_int & RESET)
2211 {
2212
2213 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2214 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2215 if (pCurrCard->currentSCCB != NULL) {
2216
2217 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2218
James Bottomley 47b5d692005-04-24 02:38:05 -05002219 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002220 }
2221
2222
2223 DISABLE_AUTO(p_port);
2224
James Bottomley 47b5d692005-04-24 02:38:05 -05002225 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226
2227 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2228
2229 pCurrNvRam = pCurrCard->pNvRamInfo;
2230 if(pCurrNvRam){
2231 ScamFlg = pCurrNvRam->niScamConf;
2232 }
2233 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002234 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 }
2236
James Bottomley 47b5d692005-04-24 02:38:05 -05002237 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
James Bottomley 47b5d692005-04-24 02:38:05 -05002239 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240
2241 return(0xFF);
2242 }
2243
2244
2245 else if (p_int & FIFO) {
2246
2247 WRW_HARPOON((p_port+hp_intstat), FIFO);
2248
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002250 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 }
2252
2253 else if (p_int & TIMEOUT)
2254 {
2255
2256 DISABLE_AUTO(p_port);
2257
2258 WRW_HARPOON((p_port+hp_intstat),
2259 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2260
2261 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2262
2263
James Bottomley 47b5d692005-04-24 02:38:05 -05002264 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2266 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002267 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002269 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270
2271
2272 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2273 {
2274 currTar_Info->TarSyncCtrl = 0;
2275 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2276 }
2277
2278 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2279 {
2280 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2281 }
2282
James Bottomley 47b5d692005-04-24 02:38:05 -05002283 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284
James Bottomley 47b5d692005-04-24 02:38:05 -05002285 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286
2287 }
2288
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 else if (p_int & SCAM_SEL)
2290 {
2291
James Bottomley 47b5d692005-04-24 02:38:05 -05002292 FPT_scarb(p_port,LEVEL2_TAR);
2293 FPT_scsel(p_port);
2294 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295
James Bottomley 47b5d692005-04-24 02:38:05 -05002296 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
2298 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2299 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300
2301 return(0x00);
2302}
2303
2304
2305/*---------------------------------------------------------------------
2306 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307 * Function: SccbMgrTableInit
2308 *
2309 * Description: Initialize all Sccb manager data structures.
2310 *
2311 *---------------------------------------------------------------------*/
2312
James Bottomley 47b5d692005-04-24 02:38:05 -05002313static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002315 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
2317 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2318 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002319 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320
James Bottomley 47b5d692005-04-24 02:38:05 -05002321 FPT_BL_Card[thisCard].ioPort = 0x00;
2322 FPT_BL_Card[thisCard].cardInfo = NULL;
2323 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2324 FPT_BL_Card[thisCard].ourId = 0x00;
2325 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 }
2327}
2328
2329
2330/*---------------------------------------------------------------------
2331 *
2332 * Function: SccbMgrTableInit
2333 *
2334 * Description: Initialize all Sccb manager data structures.
2335 *
2336 *---------------------------------------------------------------------*/
2337
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002338static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002340 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
2342 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2343 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002344 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345 }
2346
2347 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2348 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002349 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2350 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2351 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 }
2353
2354 pCurrCard->scanIndex = 0x00;
2355 pCurrCard->currentSCCB = NULL;
2356 pCurrCard->globalFlags = 0x00;
2357 pCurrCard->cmdCounter = 0x00;
2358 pCurrCard->tagQ_Lst = 0x01;
2359 pCurrCard->discQCount = 0;
2360
2361
2362}
2363
2364
2365/*---------------------------------------------------------------------
2366 *
2367 * Function: SccbMgrTableInit
2368 *
2369 * Description: Initialize all Sccb manager data structures.
2370 *
2371 *---------------------------------------------------------------------*/
2372
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002373static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374{
2375
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002376 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377 PSCCBMgr_tar_info currTar_Info;
2378
James Bottomley 47b5d692005-04-24 02:38:05 -05002379 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002380
2381 currTar_Info->TarSelQ_Cnt = 0;
2382 currTar_Info->TarSyncCtrl = 0;
2383
2384 currTar_Info->TarSelQ_Head = NULL;
2385 currTar_Info->TarSelQ_Tail = NULL;
2386 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002387 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388
2389
2390 for (lun = 0; lun < MAX_LUN; lun++)
2391 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002392 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002393 currTar_Info->LunDiscQ_Idx[lun] = 0;
2394 }
2395
2396 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2397 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002398 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002400 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002402 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2403 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404 }
2405 }
2406 }
2407}
2408
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409
2410/*---------------------------------------------------------------------
2411 *
2412 * Function: sfetm
2413 *
2414 * Description: Read in a message byte from the SCSI bus, and check
2415 * for a parity error.
2416 *
2417 *---------------------------------------------------------------------*/
2418
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002419static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002421 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002422 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423
2424 TimeOutLoop = 0;
2425 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2426 (TimeOutLoop++ < 20000) ){}
2427
2428
2429 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2430
2431 message = RD_HARPOON(port+hp_scsidata_0);
2432
2433 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2434
2435
2436 if (TimeOutLoop > 20000)
2437 message = 0x00; /* force message byte = 0 if Time Out on Req */
2438
2439 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2440 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2441 {
2442 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2443 WR_HARPOON(port+hp_xferstat, 0);
2444 WR_HARPOON(port+hp_fiforead, 0);
2445 WR_HARPOON(port+hp_fifowrite, 0);
2446 if (pCurrSCCB != NULL)
2447 {
2448 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2449 }
2450 message = 0x00;
2451 do
2452 {
2453 ACCEPT_MSG_ATN(port);
2454 TimeOutLoop = 0;
2455 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2456 (TimeOutLoop++ < 20000) ){}
2457 if (TimeOutLoop > 20000)
2458 {
2459 WRW_HARPOON((port+hp_intstat), PARITY);
2460 return(message);
2461 }
2462 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2463 {
2464 WRW_HARPOON((port+hp_intstat), PARITY);
2465 return(message);
2466 }
2467 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2468
2469 RD_HARPOON(port+hp_scsidata_0);
2470
2471 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2472
2473 }while(1);
2474
2475 }
2476 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2477 WR_HARPOON(port+hp_xferstat, 0);
2478 WR_HARPOON(port+hp_fiforead, 0);
2479 WR_HARPOON(port+hp_fifowrite, 0);
2480 return(message);
2481}
2482
2483
2484/*---------------------------------------------------------------------
2485 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002486 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 *
2488 * Description: Load up automation and select target device.
2489 *
2490 *---------------------------------------------------------------------*/
2491
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002492static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493{
2494
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002495 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002497 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 PSCCBcard CurrCard;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002499 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002501 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502
James Bottomley 47b5d692005-04-24 02:38:05 -05002503 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 currSCCB = CurrCard->currentSCCB;
2505 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002506 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 lastTag = CurrCard->tagQ_Lst;
2508
2509 ARAM_ACCESS(port);
2510
2511
2512 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2513 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2514
2515 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2516 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2517
2518 lun = currSCCB->Lun;
2519 else
2520 lun = 0;
2521
2522
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 if (CurrCard->globalFlags & F_TAG_STARTED)
2524 {
2525 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2526 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002527 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2529 == TAG_Q_TRYING))
2530 {
2531
2532 if (currTar_Info->TarTagQ_Cnt !=0)
2533 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002534 currTar_Info->TarLUNBusy[lun] = 1;
2535 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 SGRAM_ACCESS(port);
2537 return;
2538 }
2539
2540 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002541 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542 }
2543
2544 } /*End non-tagged */
2545
2546 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002547 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 }
2549
2550 } /*!Use cmd Q Tagged */
2551
2552 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002553 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002555 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556 SGRAM_ACCESS(port);
2557 return;
2558 }
2559
James Bottomley 47b5d692005-04-24 02:38:05 -05002560 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561
2562 } /*else use cmd Q tagged */
2563
2564 } /*if glob tagged started */
2565
2566 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002567 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568 }
2569
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
2571
2572 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2573 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2574 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2575 {
2576 if(CurrCard->discQCount >= QUEUE_DEPTH)
2577 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002578 currTar_Info->TarLUNBusy[lun] = 1;
2579 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 SGRAM_ACCESS(port);
2581 return;
2582 }
2583 for (i = 1; i < QUEUE_DEPTH; i++)
2584 {
2585 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2586 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2587 {
2588 CurrCard->tagQ_Lst = lastTag;
2589 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2590 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2591 CurrCard->discQCount++;
2592 break;
2593 }
2594 }
2595 if(i == QUEUE_DEPTH)
2596 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002597 currTar_Info->TarLUNBusy[lun] = 1;
2598 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599 SGRAM_ACCESS(port);
2600 return;
2601 }
2602 }
2603
2604
2605
James Bottomley 47b5d692005-04-24 02:38:05 -05002606 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607
2608 WR_HARPOON(port+hp_select_id, target);
2609 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2610
2611 if (currSCCB->OperationCode == RESET_COMMAND) {
2612 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2613 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2614
2615 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2616
2617 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2618
2619 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002620 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2622
2623 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2624 {
2625 currTar_Info->TarSyncCtrl = 0;
2626 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2627 }
2628
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2630 {
2631 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2632 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633
James Bottomley 47b5d692005-04-24 02:38:05 -05002634 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2635 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636
2637 }
2638
2639 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2640 {
2641 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2642 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2643
2644 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2645
2646 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002647 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2648 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 WRW_HARPOON((port+SYNC_MSGS+2),
2650 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2651 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2652
2653 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002654 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655
2656 }
2657
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002659 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2661 }
2662
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2664 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002665 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2667 }
2668
2669
2670 if (!auto_loaded)
2671 {
2672
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 if (currSCCB->ControlByte & F_USE_CMD_Q)
2674 {
2675
2676 CurrCard->globalFlags |= F_TAG_STARTED;
2677
2678 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2679 == TAG_Q_REJECT)
2680 {
2681 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2682
2683 /* Fix up the start instruction with a jump to
2684 Non-Tag-CMD handling */
2685 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2686
2687 WRW_HARPOON((port+NON_TAG_ID_MSG),
2688 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2689
2690 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2691
2692 /* Setup our STATE so we know what happend when
2693 the wheels fall off. */
2694 currSCCB->Sccb_scsistat = SELECT_ST;
2695
James Bottomley 47b5d692005-04-24 02:38:05 -05002696 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 }
2698
2699 else
2700 {
2701 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2702
2703 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002704 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2705 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
2707 for (i = 1; i < QUEUE_DEPTH; i++)
2708 {
2709 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2710 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2711 {
2712 WRW_HARPOON((port+ID_MSG_STRT+6),
2713 (MPM_OP+AMSG_OUT+lastTag));
2714 CurrCard->tagQ_Lst = lastTag;
2715 currSCCB->Sccb_tag = lastTag;
2716 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2717 CurrCard->discQCount++;
2718 break;
2719 }
2720 }
2721
2722
2723 if ( i == QUEUE_DEPTH )
2724 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002725 currTar_Info->TarLUNBusy[lun] = 1;
2726 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 SGRAM_ACCESS(port);
2728 return;
2729 }
2730
2731 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2732
2733 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2734 }
2735 }
2736
2737 else
2738 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739
2740 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2741
2742 WRW_HARPOON((port+NON_TAG_ID_MSG),
2743 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2744
2745 currSCCB->Sccb_scsistat = SELECT_ST;
2746
2747 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749
2750
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002751 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752
2753 cdb_reg = port + CMD_STRT;
2754
2755 for (i=0; i < currSCCB->CdbLength; i++)
2756 {
2757 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2758 cdb_reg +=2;
2759 theCCB++;
2760 }
2761
2762 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2763 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2764
2765 } /* auto_loaded */
2766
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002767 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769
2770 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2771
2772 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2773
2774
2775 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2776 {
2777 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2778 }
2779 else
2780 {
2781
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002782/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783 auto_loaded |= AUTO_IMMED; */
2784 auto_loaded = AUTO_IMMED;
2785
2786 DISABLE_AUTO(port);
2787
2788 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2789 }
2790
2791 SGRAM_ACCESS(port);
2792}
2793
2794
2795/*---------------------------------------------------------------------
2796 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002797 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798 *
2799 * Description: Hookup the correct CCB and handle the incoming messages.
2800 *
2801 *---------------------------------------------------------------------*/
2802
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002803static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804{
2805
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002806 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807
2808
2809 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002810 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811
2812
2813
2814
2815 if(pCurrCard->currentSCCB != NULL)
2816 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002817 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818 DISABLE_AUTO(port);
2819
2820
2821 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2822
2823
2824 currSCCB = pCurrCard->currentSCCB;
2825 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2826 {
2827 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2828 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2829 }
2830 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2831 {
2832 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2833 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2834 }
2835 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2836 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2837 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002838 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 if(currSCCB->Sccb_scsistat != ABORT_ST)
2840 {
2841 pCurrCard->discQCount--;
2842 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2843 = NULL;
2844 }
2845 }
2846 else
2847 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002848 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 if(currSCCB->Sccb_tag)
2850 {
2851 if(currSCCB->Sccb_scsistat != ABORT_ST)
2852 {
2853 pCurrCard->discQCount--;
2854 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2855 }
2856 }else
2857 {
2858 if(currSCCB->Sccb_scsistat != ABORT_ST)
2859 {
2860 pCurrCard->discQCount--;
2861 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2862 }
2863 }
2864 }
2865
James Bottomley 47b5d692005-04-24 02:38:05 -05002866 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 }
2868
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002869 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870
2871
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002872 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002873 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
2875
2876 msgRetryCount = 0;
2877 do
2878 {
2879
James Bottomley 47b5d692005-04-24 02:38:05 -05002880 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 tag = 0;
2882
2883
2884 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2885 {
2886 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2887 {
2888
2889 WRW_HARPOON((port+hp_intstat), PHASE);
2890 return;
2891 }
2892 }
2893
2894 WRW_HARPOON((port+hp_intstat), PHASE);
2895 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2896 {
2897
James Bottomley 47b5d692005-04-24 02:38:05 -05002898 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 if (message)
2900 {
2901
2902 if (message <= (0x80 | LUN_MASK))
2903 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002904 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2907 {
2908 if (currTar_Info->TarTagQ_Cnt != 0)
2909 {
2910
2911 if (!(currTar_Info->TarLUN_CA))
2912 {
2913 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2914
2915
James Bottomley 47b5d692005-04-24 02:38:05 -05002916 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 if (message)
2918 {
2919 ACCEPT_MSG(port);
2920 }
2921
2922 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002923 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924
James Bottomley 47b5d692005-04-24 02:38:05 -05002925 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002927 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928
2929 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002930 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 }
2932
2933 } /*C.A. exists! */
2934
2935 } /*End Q cnt != 0 */
2936
2937 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938
2939 } /*End valid ID message. */
2940
2941 else
2942 {
2943
2944 ACCEPT_MSG_ATN(port);
2945 }
2946
2947 } /* End good id message. */
2948
2949 else
2950 {
2951
James Bottomley 47b5d692005-04-24 02:38:05 -05002952 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 }
2954 }
2955 else
2956 {
2957 ACCEPT_MSG_ATN(port);
2958
2959 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2960 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2961 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2962
2963 return;
2964 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965
James Bottomley 47b5d692005-04-24 02:38:05 -05002966 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967 {
2968 msgRetryCount++;
2969 if(msgRetryCount == 1)
2970 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002971 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972 }
2973 else
2974 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002975 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976
James Bottomley 47b5d692005-04-24 02:38:05 -05002977 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978
James Bottomley 47b5d692005-04-24 02:38:05 -05002979 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 {
2981
James Bottomley 47b5d692005-04-24 02:38:05 -05002982 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983
2984 }
2985
James Bottomley 47b5d692005-04-24 02:38:05 -05002986 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 {
2988
James Bottomley 47b5d692005-04-24 02:38:05 -05002989 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 }
2991
2992
James Bottomley 47b5d692005-04-24 02:38:05 -05002993 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2994 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 return;
2996 }
2997 }
James Bottomley 47b5d692005-04-24 02:38:05 -05002998 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999
3000
3001
3002 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3003 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3004 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003005 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3007 if(pCurrCard->currentSCCB != NULL)
3008 {
3009 ACCEPT_MSG(port);
3010 }
3011 else
3012 {
3013 ACCEPT_MSG_ATN(port);
3014 }
3015 }
3016 else
3017 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003018 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003019
3020
3021 if (tag)
3022 {
3023 if (pCurrCard->discQ_Tbl[tag] != NULL)
3024 {
3025 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3026 currTar_Info->TarTagQ_Cnt--;
3027 ACCEPT_MSG(port);
3028 }
3029 else
3030 {
3031 ACCEPT_MSG_ATN(port);
3032 }
3033 }else
3034 {
3035 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3036 if(pCurrCard->currentSCCB != NULL)
3037 {
3038 ACCEPT_MSG(port);
3039 }
3040 else
3041 {
3042 ACCEPT_MSG_ATN(port);
3043 }
3044 }
3045 }
3046
3047 if(pCurrCard->currentSCCB != NULL)
3048 {
3049 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3050 {
3051 /* During Abort Tag command, the target could have got re-selected
3052 and completed the command. Check the select Q and remove the CCB
3053 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003054 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 }
3056 }
3057
3058
3059 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3060 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3061 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3062}
3063
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003064static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065{
3066 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3067 {
3068 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3069 {
3070
3071 WRW_HARPOON((port+hp_intstat), PHASE);
3072 return;
3073 }
3074 }
3075
3076 WRW_HARPOON((port+hp_intstat), PHASE);
3077 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3078 {
3079 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3080
3081
3082 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3083
3084 WR_HARPOON(port+hp_scsidata_0,message);
3085
3086 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3087
3088 ACCEPT_MSG(port);
3089
3090 WR_HARPOON(port+hp_portctrl_0, 0x00);
3091
3092 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3093 (message == SMABORT_TAG) )
3094 {
3095 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3096
3097 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3098 {
3099 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3100 }
3101 }
3102 }
3103}
3104
3105/*---------------------------------------------------------------------
3106 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003107 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 *
3109 * Description: Determine the proper responce to the message from the
3110 * target device.
3111 *
3112 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003113static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003115 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116 PSCCBcard CurrCard;
3117 PSCCBMgr_tar_info currTar_Info;
3118
James Bottomley 47b5d692005-04-24 02:38:05 -05003119 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 currSCCB = CurrCard->currentSCCB;
3121
James Bottomley 47b5d692005-04-24 02:38:05 -05003122 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123
3124 if (message == SMREST_DATA_PTR)
3125 {
3126 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3127 {
3128 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3129
James Bottomley 47b5d692005-04-24 02:38:05 -05003130 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 }
3132
3133 ACCEPT_MSG(port);
3134 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3135 }
3136
3137 else if (message == SMCMD_COMP)
3138 {
3139
3140
3141 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3142 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003143 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3144 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 }
3146
3147 ACCEPT_MSG(port);
3148
3149 }
3150
3151 else if ((message == SMNO_OP) || (message >= SMIDENT)
3152 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3153 {
3154
3155 ACCEPT_MSG(port);
3156 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3157 }
3158
3159 else if (message == SMREJECT)
3160 {
3161
3162 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3163 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3164 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3165 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3166
3167 {
3168 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3169
3170 ACCEPT_MSG(port);
3171
3172
3173 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3174 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3175
3176 if(currSCCB->Lun == 0x00)
3177 {
3178 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3179 {
3180
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003181 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003182
3183 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3184 }
3185
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3187 {
3188
3189
3190 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3191 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3192
3193 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3194
3195 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196
3197 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3198 {
3199 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003200 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003201
3202
3203 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3204 CurrCard->discQCount--;
3205 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3206 currSCCB->Sccb_tag = 0x00;
3207
3208 }
3209 }
3210
3211 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3212 {
3213
3214
3215 if(currSCCB->Lun == 0x00)
3216 {
3217 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3218 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3219 }
3220 }
3221
3222 else
3223 {
3224
3225 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3226 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003227 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003228 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003229 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003230
3231
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003232 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233
3234 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3235
3236 }
3237 }
3238
3239 else
3240 {
3241 ACCEPT_MSG(port);
3242
3243 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3244 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3245
3246 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3247 {
3248 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3249 }
3250 }
3251 }
3252
3253 else if (message == SMEXT)
3254 {
3255
3256 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003257 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003258 }
3259
3260 else if (message == SMIGNORWR)
3261 {
3262
3263 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3264
James Bottomley 47b5d692005-04-24 02:38:05 -05003265 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266
3267 if(currSCCB->Sccb_scsimsg != SMPARITY)
3268 ACCEPT_MSG(port);
3269 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3270 }
3271
3272
3273 else
3274 {
3275
3276 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3277 currSCCB->Sccb_scsimsg = SMREJECT;
3278
3279 ACCEPT_MSG_ATN(port);
3280 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3281 }
3282}
3283
3284
3285/*---------------------------------------------------------------------
3286 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003287 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288 *
3289 * Description: Decide what to do with the extended message.
3290 *
3291 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003292static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003293{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003294 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295
James Bottomley 47b5d692005-04-24 02:38:05 -05003296 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003297 if (length)
3298 {
3299
3300 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003301 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302 if (message)
3303 {
3304
3305 if (message == SMSYNC)
3306 {
3307
3308 if (length == 0x03)
3309 {
3310
3311 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003312 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313 }
3314 else
3315 {
3316
3317 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3318 ACCEPT_MSG_ATN(port);
3319 }
3320 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321 else if (message == SMWDTR)
3322 {
3323
3324 if (length == 0x02)
3325 {
3326
3327 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003328 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329 }
3330 else
3331 {
3332
3333 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3334 ACCEPT_MSG_ATN(port);
3335
3336 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3337 }
3338 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 else
3340 {
3341
3342 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3343 ACCEPT_MSG_ATN(port);
3344
3345 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3346 }
3347 }
3348 else
3349 {
3350 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3351 ACCEPT_MSG(port);
3352 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3353 }
3354 }else
3355 {
3356 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3357 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3358 }
3359}
3360
3361
3362/*---------------------------------------------------------------------
3363 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003364 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003365 *
3366 * Description: Read in a message byte from the SCSI bus, and check
3367 * for a parity error.
3368 *
3369 *---------------------------------------------------------------------*/
3370
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003371static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003373 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374 PSCCBMgr_tar_info currTar_Info;
3375
James Bottomley 47b5d692005-04-24 02:38:05 -05003376 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3377 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378
3379 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3380
3381
3382 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003383 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384
3385 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3386
3387 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3388 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3389 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3390
3391
3392 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3393
3394 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3395
3396 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3397
3398 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3399
3400 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3401
3402 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3403
3404 else
3405 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3406
3407
3408 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3409 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3410 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3411
3412
James Bottomley 47b5d692005-04-24 02:38:05 -05003413 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414 {
3415 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3416 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003417 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003418 }
3419 else
3420 {
3421 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3422 }
3423
3424
James Bottomley 47b5d692005-04-24 02:38:05 -05003425 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 }
3427
3428 else {
3429
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003430 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003432 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003433 }
3434}
3435
3436
3437
3438/*---------------------------------------------------------------------
3439 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003440 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441 *
3442 * Description: The has sent us a Sync Nego message so handle it as
3443 * necessary.
3444 *
3445 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003446static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003448 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003449 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450 PSCCBMgr_tar_info currTar_Info;
3451
James Bottomley 47b5d692005-04-24 02:38:05 -05003452 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3453 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454
James Bottomley 47b5d692005-04-24 02:38:05 -05003455 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456
3457 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3458 {
3459 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3460 return;
3461 }
3462
3463 ACCEPT_MSG(port);
3464
3465
James Bottomley 47b5d692005-04-24 02:38:05 -05003466 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467
3468 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3469 {
3470 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3471 return;
3472 }
3473
3474 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3475
3476 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3477
3478 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3479
3480 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3481
3482 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3483
3484 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3485 else
3486
3487 our_sync_msg = 0; /* Message = Async */
3488
3489 if (sync_msg < our_sync_msg) {
3490 sync_msg = our_sync_msg; /*if faster, then set to max. */
3491 }
3492
3493 if (offset == ASYNC)
3494 sync_msg = ASYNC;
3495
3496 if (offset > MAX_OFFSET)
3497 offset = MAX_OFFSET;
3498
3499 sync_reg = 0x00;
3500
3501 if (sync_msg > 12)
3502
3503 sync_reg = 0x20; /* Use 10MB/s */
3504
3505 if (sync_msg > 25)
3506
3507 sync_reg = 0x40; /* Use 6.6MB/s */
3508
3509 if (sync_msg > 38)
3510
3511 sync_reg = 0x60; /* Use 5MB/s */
3512
3513 if (sync_msg > 50)
3514
3515 sync_reg = 0x80; /* Use 4MB/s */
3516
3517 if (sync_msg > 62)
3518
3519 sync_reg = 0xA0; /* Use 3.33MB/s */
3520
3521 if (sync_msg > 75)
3522
3523 sync_reg = 0xC0; /* Use 2.85MB/s */
3524
3525 if (sync_msg > 87)
3526
3527 sync_reg = 0xE0; /* Use 2.5MB/s */
3528
3529 if (sync_msg > 100) {
3530
3531 sync_reg = 0x00; /* Use ASYNC */
3532 offset = 0x00;
3533 }
3534
3535
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 if (currTar_Info->TarStatus & WIDE_ENABLED)
3537
3538 sync_reg |= offset;
3539
3540 else
3541
3542 sync_reg |= (offset | NARROW_SCSI);
3543
James Bottomley 47b5d692005-04-24 02:38:05 -05003544 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545
3546
3547 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3548
3549
3550 ACCEPT_MSG(port);
3551
3552 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003553 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003554
3555 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3556 }
3557
3558 else {
3559
3560
3561 ACCEPT_MSG_ATN(port);
3562
James Bottomley 47b5d692005-04-24 02:38:05 -05003563 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564
3565 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003566 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003567 }
3568}
3569
3570
3571/*---------------------------------------------------------------------
3572 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003573 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574 *
3575 * Description: Answer the targets sync message.
3576 *
3577 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003578static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003579{
3580 ARAM_ACCESS(port);
3581 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3582 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3583 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3584 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3585 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3586 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3587 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3588 SGRAM_ACCESS(port);
3589
3590 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3591 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3592
3593 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3594
3595 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3596}
3597
3598
3599
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600/*---------------------------------------------------------------------
3601 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003602 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003603 *
3604 * Description: Read in a message byte from the SCSI bus, and check
3605 * for a parity error.
3606 *
3607 *---------------------------------------------------------------------*/
3608
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003609static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003611 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612 PSCCBMgr_tar_info currTar_Info;
3613
James Bottomley 47b5d692005-04-24 02:38:05 -05003614 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3615 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616
3617 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3618
3619
3620 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003621 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622
3623 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3624
3625 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3626 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3627 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3628 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3629 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3630 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3631
3632 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3633
3634
3635 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003636 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637
James Bottomley 47b5d692005-04-24 02:38:05 -05003638 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003639 }
3640
3641 else {
3642
3643 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003644 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645
3646 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003647 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 }
3649}
3650
3651
3652
3653/*---------------------------------------------------------------------
3654 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003655 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656 *
3657 * Description: The has sent us a Wide Nego message so handle it as
3658 * necessary.
3659 *
3660 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003661static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003663 unsigned char width;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003664 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 PSCCBMgr_tar_info currTar_Info;
3666
James Bottomley 47b5d692005-04-24 02:38:05 -05003667 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3668 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669
James Bottomley 47b5d692005-04-24 02:38:05 -05003670 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671
3672 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3673 {
3674 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3675 return;
3676 }
3677
3678
3679 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3680 width = 0;
3681
3682 if (width) {
3683 currTar_Info->TarStatus |= WIDE_ENABLED;
3684 width = 0;
3685 }
3686 else {
3687 width = NARROW_SCSI;
3688 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3689 }
3690
3691
James Bottomley 47b5d692005-04-24 02:38:05 -05003692 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003693
3694
3695 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3696 {
3697
3698
3699
3700 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3701
3702 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3703 {
3704 ACCEPT_MSG_ATN(port);
3705 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003706 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3708 SGRAM_ACCESS(port);
3709 }
3710 else
3711 {
3712 ACCEPT_MSG(port);
3713 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3714 }
3715 }
3716
3717 else {
3718
3719
3720 ACCEPT_MSG_ATN(port);
3721
3722 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3723 width = SM16BIT;
3724 else
3725 width = SM8BIT;
3726
James Bottomley 47b5d692005-04-24 02:38:05 -05003727 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3730 }
3731}
3732
3733
3734/*---------------------------------------------------------------------
3735 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003736 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737 *
3738 * Description: Answer the targets Wide nego message.
3739 *
3740 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003741static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003742{
3743 ARAM_ACCESS(port);
3744 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3745 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3746 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3747 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3748 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3749 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3750 SGRAM_ACCESS(port);
3751
3752 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3753 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3754
3755 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3756
3757 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3758}
3759
Linus Torvalds1da177e2005-04-16 15:20:36 -07003760
3761
3762/*---------------------------------------------------------------------
3763 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003764 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 *
3766 * Description: Write the desired value to the Sync Register for the
3767 * ID specified.
3768 *
3769 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003770static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003771 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003773 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774
3775 index = p_id;
3776
3777 switch (index) {
3778
3779 case 0:
3780 index = 12; /* hp_synctarg_0 */
3781 break;
3782 case 1:
3783 index = 13; /* hp_synctarg_1 */
3784 break;
3785 case 2:
3786 index = 14; /* hp_synctarg_2 */
3787 break;
3788 case 3:
3789 index = 15; /* hp_synctarg_3 */
3790 break;
3791 case 4:
3792 index = 8; /* hp_synctarg_4 */
3793 break;
3794 case 5:
3795 index = 9; /* hp_synctarg_5 */
3796 break;
3797 case 6:
3798 index = 10; /* hp_synctarg_6 */
3799 break;
3800 case 7:
3801 index = 11; /* hp_synctarg_7 */
3802 break;
3803 case 8:
3804 index = 4; /* hp_synctarg_8 */
3805 break;
3806 case 9:
3807 index = 5; /* hp_synctarg_9 */
3808 break;
3809 case 10:
3810 index = 6; /* hp_synctarg_10 */
3811 break;
3812 case 11:
3813 index = 7; /* hp_synctarg_11 */
3814 break;
3815 case 12:
3816 index = 0; /* hp_synctarg_12 */
3817 break;
3818 case 13:
3819 index = 1; /* hp_synctarg_13 */
3820 break;
3821 case 14:
3822 index = 2; /* hp_synctarg_14 */
3823 break;
3824 case 15:
3825 index = 3; /* hp_synctarg_15 */
3826
3827 }
3828
3829 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3830
3831 currTar_Info->TarSyncCtrl = p_sync_value;
3832}
3833
3834
3835/*---------------------------------------------------------------------
3836 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003837 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838 *
3839 * Description: Reset the desired card's SCSI bus.
3840 *
3841 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003842static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003844 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845
3846 PSCCBMgr_tar_info currTar_Info;
3847
3848 WR_HARPOON(port+hp_page_ctrl,
3849 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3850 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3851
3852 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3853
3854 scsiID = RD_HARPOON(port+hp_seltimeout);
3855 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3856 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3857
3858 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3859
3860 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3861
3862 WR_HARPOON(port+hp_seltimeout,scsiID);
3863
3864 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3865
James Bottomley 47b5d692005-04-24 02:38:05 -05003866 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867
3868 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3869
3870 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3871
3872 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3873 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003874 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875
3876 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3877 {
3878 currTar_Info->TarSyncCtrl = 0;
3879 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3880 }
3881
3882 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3883 {
3884 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3885 }
3886
James Bottomley 47b5d692005-04-24 02:38:05 -05003887 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888
James Bottomley 47b5d692005-04-24 02:38:05 -05003889 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003890 }
3891
James Bottomley 47b5d692005-04-24 02:38:05 -05003892 FPT_BL_Card[p_card].scanIndex = 0x00;
3893 FPT_BL_Card[p_card].currentSCCB = NULL;
3894 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003896 FPT_BL_Card[p_card].cmdCounter = 0x00;
3897 FPT_BL_Card[p_card].discQCount = 0x00;
3898 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899
3900 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003901 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902
3903 WR_HARPOON(port+hp_page_ctrl,
3904 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3905
3906}
3907
3908/*---------------------------------------------------------------------
3909 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003910 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911 *
3912 * Description: Setup for the Auto Sense command.
3913 *
3914 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003915static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003917 unsigned char i;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003918 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919
3920 currSCCB = pCurrCard->currentSCCB;
3921
3922
3923 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3924
3925 for (i = 0; i < 6; i++) {
3926
3927 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3928 }
3929
3930 currSCCB->CdbLength = SIX_BYTE_CMD;
3931 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003932 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003933 currSCCB->Cdb[2] = 0x00;
3934 currSCCB->Cdb[3] = 0x00;
3935 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3936 currSCCB->Cdb[5] = 0x00;
3937
3938 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3939
3940 currSCCB->Sccb_ATC = 0x00;
3941
3942 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3943
3944 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3945
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003946 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947
3948 currSCCB->ControlByte = 0x00;
3949
3950 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3951}
3952
3953
3954
3955/*---------------------------------------------------------------------
3956 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003957 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958 *
3959 * Description: Transfer data into the bit bucket until the device
3960 * decides to switch phase.
3961 *
3962 *---------------------------------------------------------------------*/
3963
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003964static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003966 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967
3968
3969 DISABLE_AUTO(p_port);
3970
James Bottomley 47b5d692005-04-24 02:38:05 -05003971 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972
James Bottomley 47b5d692005-04-24 02:38:05 -05003973 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974
3975 }
3976
3977 /* If the Automation handled the end of the transfer then do not
3978 match the phase or we will get out of sync with the ISR. */
3979
3980 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3981 return;
3982
3983 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3984
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003985 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986
3987 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3988
3989
3990 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3991
3992 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003993 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003994 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003995 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996 {
3997 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3998
3999 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4000 {
4001 RD_HARPOON(p_port+hp_fifodata_0);
4002 }
4003 }
4004 else
4005 {
4006 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4007 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4008 {
4009 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4010 }
4011 }
4012 } /* End of While loop for padding data I/O phase */
4013
4014 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4015 {
4016 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4017 break;
4018 }
4019
4020 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4021 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4022 {
4023 RD_HARPOON(p_port+hp_fifodata_0);
4024 }
4025
4026 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4027 {
4028 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4029 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4030
4031 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4032 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4033 }
4034}
4035
4036
4037/*---------------------------------------------------------------------
4038 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004039 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004040 *
4041 * Description: Make sure data has been flushed from both FIFOs and abort
4042 * the operations if necessary.
4043 *
4044 *---------------------------------------------------------------------*/
4045
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004046static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004048 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004049 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004051 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052
James Bottomley 47b5d692005-04-24 02:38:05 -05004053 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054
4055
4056 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4057 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4058 return;
4059 }
4060
4061
4062
4063 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4064 {
4065
4066 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4067
4068 currSCCB->Sccb_XferCnt = 1;
4069
4070 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004071 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004072 WR_HARPOON(port+hp_xferstat, 0x00);
4073 }
4074
4075 else
4076 {
4077
4078 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4079
4080 currSCCB->Sccb_XferCnt = 0;
4081 }
4082
4083 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4084 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4085
4086 currSCCB->HostStatus = SCCB_PARITY_ERR;
4087 WRW_HARPOON((port+hp_intstat), PARITY);
4088 }
4089
4090
James Bottomley 47b5d692005-04-24 02:38:05 -05004091 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004092
4093
4094 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4095
4096 TimeOutLoop = 0;
4097
4098 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4099 {
4100 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4101 return;
4102 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004103 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104 break;
4105 }
4106 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4107 return;
4108 }
4109 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4110 break;
4111 }
4112
4113 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4114 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004115 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004116 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4117 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4118 {
4119
4120 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4121
4122 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4123 {
4124 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004125 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 }
4127
4128 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004129 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004130 }
4131 }
4132 else
4133 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004134 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135 if (!(RDW_HARPOON((port+hp_intstat)) &
4136 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4137 {
4138 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004139 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 }
4141 }
4142
4143 }
4144
4145 else {
4146 WR_HARPOON(port+hp_portctrl_0, 0x00);
4147 }
4148}
4149
4150
4151/*---------------------------------------------------------------------
4152 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004153 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 *
4155 * Description: Setup SCCB manager fields in this SCCB.
4156 *
4157 *---------------------------------------------------------------------*/
4158
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004159static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004160{
4161 PSCCBMgr_tar_info currTar_Info;
4162
4163 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4164 {
4165 return;
4166 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004167 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004168
4169 p_sccb->Sccb_XferState = 0x00;
4170 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4171
4172 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4173 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4174
4175 p_sccb->Sccb_SGoffset = 0;
4176 p_sccb->Sccb_XferState = F_SG_XFER;
4177 p_sccb->Sccb_XferCnt = 0x00;
4178 }
4179
4180 if (p_sccb->DataLength == 0x00)
4181
4182 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4183
4184 if (p_sccb->ControlByte & F_USE_CMD_Q)
4185 {
4186 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4187 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4188
4189 else
4190 currTar_Info->TarStatus |= TAG_Q_TRYING;
4191 }
4192
4193/* For !single SCSI device in system & device allow Disconnect
4194 or command is tag_q type then send Cmd with Disconnect Enable
4195 else send Cmd with Disconnect Disable */
4196
4197/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004198 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004199 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4200 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4201*/
4202 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4203 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004204 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004205 }
4206
4207 else {
4208
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004209 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 }
4211
4212 p_sccb->HostStatus = 0x00;
4213 p_sccb->TargetStatus = 0x00;
4214 p_sccb->Sccb_tag = 0x00;
4215 p_sccb->Sccb_MGRFlags = 0x00;
4216 p_sccb->Sccb_sgseg = 0x00;
4217 p_sccb->Sccb_ATC = 0x00;
4218 p_sccb->Sccb_savedATC = 0x00;
4219/*
4220 p_sccb->SccbVirtDataPtr = 0x00;
4221 p_sccb->Sccb_forwardlink = NULL;
4222 p_sccb->Sccb_backlink = NULL;
4223 */
4224 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4225 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4226 p_sccb->Sccb_scsimsg = SMNO_OP;
4227
4228}
4229
4230
Linus Torvalds1da177e2005-04-16 15:20:36 -07004231/*---------------------------------------------------------------------
4232 *
4233 * Function: Phase Decode
4234 *
4235 * Description: Determine the phase and call the appropriate function.
4236 *
4237 *---------------------------------------------------------------------*/
4238
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004239static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240{
4241 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004242 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243
4244
4245 DISABLE_AUTO(p_port);
4246
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004247 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248
James Bottomley 47b5d692005-04-24 02:38:05 -05004249 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250
4251 (*phase)(p_port, p_card); /* Call the correct phase func */
4252}
4253
4254
4255
4256/*---------------------------------------------------------------------
4257 *
4258 * Function: Data Out Phase
4259 *
4260 * Description: Start up both the BusMaster and Xbow.
4261 *
4262 *---------------------------------------------------------------------*/
4263
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004264static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265{
4266
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004267 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268
James Bottomley 47b5d692005-04-24 02:38:05 -05004269 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270 if (currSCCB == NULL)
4271 {
4272 return; /* Exit if No SCCB record */
4273 }
4274
4275 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4276 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4277
4278 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4279
4280 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4281
4282 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4283
James Bottomley 47b5d692005-04-24 02:38:05 -05004284 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004285
4286 if (currSCCB->Sccb_XferCnt == 0) {
4287
4288
4289 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4290 (currSCCB->HostStatus == SCCB_COMPLETE))
4291 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4292
James Bottomley 47b5d692005-04-24 02:38:05 -05004293 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004295 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296 }
4297}
4298
4299
4300/*---------------------------------------------------------------------
4301 *
4302 * Function: Data In Phase
4303 *
4304 * Description: Startup the BusMaster and the XBOW.
4305 *
4306 *---------------------------------------------------------------------*/
4307
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004308static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309{
4310
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004311 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312
James Bottomley 47b5d692005-04-24 02:38:05 -05004313 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004314
4315 if (currSCCB == NULL)
4316 {
4317 return; /* Exit if No SCCB record */
4318 }
4319
4320
4321 currSCCB->Sccb_scsistat = DATA_IN_ST;
4322 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4323 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4324
4325 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4326
4327 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4328
4329 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4330
James Bottomley 47b5d692005-04-24 02:38:05 -05004331 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004332
4333 if (currSCCB->Sccb_XferCnt == 0) {
4334
4335
4336 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4337 (currSCCB->HostStatus == SCCB_COMPLETE))
4338 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4339
James Bottomley 47b5d692005-04-24 02:38:05 -05004340 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004342 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343
4344 }
4345}
4346
4347/*---------------------------------------------------------------------
4348 *
4349 * Function: Command Phase
4350 *
4351 * Description: Load the CDB into the automation and start it up.
4352 *
4353 *---------------------------------------------------------------------*/
4354
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004355static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004357 struct sccb * currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004358 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004359 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360
James Bottomley 47b5d692005-04-24 02:38:05 -05004361 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362
4363 if (currSCCB->OperationCode == RESET_COMMAND) {
4364
4365 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4366 currSCCB->CdbLength = SIX_BYTE_CMD;
4367 }
4368
4369 WR_HARPOON(p_port+hp_scsisig, 0x00);
4370
4371 ARAM_ACCESS(p_port);
4372
4373
4374 cdb_reg = p_port + CMD_STRT;
4375
4376 for (i=0; i < currSCCB->CdbLength; i++) {
4377
4378 if (currSCCB->OperationCode == RESET_COMMAND)
4379
4380 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4381
4382 else
4383 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4384 cdb_reg +=2;
4385 }
4386
4387 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4388 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4389
4390 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4391
4392 currSCCB->Sccb_scsistat = COMMAND_ST;
4393
4394 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4395 SGRAM_ACCESS(p_port);
4396}
4397
4398
4399/*---------------------------------------------------------------------
4400 *
4401 * Function: Status phase
4402 *
4403 * Description: Bring in the status and command complete message bytes
4404 *
4405 *---------------------------------------------------------------------*/
4406
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004407static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408{
4409 /* Start-up the automation to finish off this command and let the
4410 isr handle the interrupt for command complete when it comes in.
4411 We could wait here for the interrupt to be generated?
4412 */
4413
4414 WR_HARPOON(port+hp_scsisig, 0x00);
4415
4416 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4417}
4418
4419
4420/*---------------------------------------------------------------------
4421 *
4422 * Function: Phase Message Out
4423 *
4424 * Description: Send out our message (if we have one) and handle whatever
4425 * else is involed.
4426 *
4427 *---------------------------------------------------------------------*/
4428
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004429static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004430{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004431 unsigned char message,scsiID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004432 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 PSCCBMgr_tar_info currTar_Info;
4434
James Bottomley 47b5d692005-04-24 02:38:05 -05004435 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436
4437 if (currSCCB != NULL) {
4438
4439 message = currSCCB->Sccb_scsimsg;
4440 scsiID = currSCCB->TargID;
4441
4442 if (message == SMDEV_RESET)
4443 {
4444
4445
James Bottomley 47b5d692005-04-24 02:38:05 -05004446 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004448 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449
James Bottomley 47b5d692005-04-24 02:38:05 -05004450 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 {
4452
James Bottomley 47b5d692005-04-24 02:38:05 -05004453 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454
4455 }
4456
James Bottomley 47b5d692005-04-24 02:38:05 -05004457 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 {
4459
James Bottomley 47b5d692005-04-24 02:38:05 -05004460 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461 }
4462
4463
James Bottomley 47b5d692005-04-24 02:38:05 -05004464 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4465 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466 }
4467 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4468 {
4469 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004470 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004472 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4473 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474 }
4475
4476 }
4477
4478 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4479 {
4480
4481
4482 if(message == SMNO_OP)
4483 {
4484 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4485
James Bottomley 47b5d692005-04-24 02:38:05 -05004486 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004487 return;
4488 }
4489 }
4490 else
4491 {
4492
4493
4494 if (message == SMABORT)
4495
James Bottomley 47b5d692005-04-24 02:38:05 -05004496 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 }
4498
4499 }
4500 else
4501 {
4502 message = SMABORT;
4503 }
4504
4505 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4506
4507
4508 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4509
4510 WR_HARPOON(port+hp_scsidata_0,message);
4511
4512 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4513
4514 ACCEPT_MSG(port);
4515
4516 WR_HARPOON(port+hp_portctrl_0, 0x00);
4517
4518 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4519 (message == SMABORT_TAG) )
4520 {
4521
4522 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4523
4524 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4525 {
4526 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4527
4528 if (currSCCB != NULL)
4529 {
4530
James Bottomley 47b5d692005-04-24 02:38:05 -05004531 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4532 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4533 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004534 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004535 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536
James Bottomley 47b5d692005-04-24 02:38:05 -05004537 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004538 }
4539
4540 else
4541 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004542 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543 }
4544 }
4545
4546 else
4547 {
4548
James Bottomley 47b5d692005-04-24 02:38:05 -05004549 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 }
4551 }
4552
4553 else
4554 {
4555
4556 if(message == SMPARITY)
4557 {
4558 currSCCB->Sccb_scsimsg = SMNO_OP;
4559 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4560 }
4561 else
4562 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004563 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564 }
4565 }
4566}
4567
4568
4569/*---------------------------------------------------------------------
4570 *
4571 * Function: Message In phase
4572 *
4573 * Description: Bring in the message and determine what to do with it.
4574 *
4575 *---------------------------------------------------------------------*/
4576
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004577static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004578{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004579 unsigned char message;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004580 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581
James Bottomley 47b5d692005-04-24 02:38:05 -05004582 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583
James Bottomley 47b5d692005-04-24 02:38:05 -05004584 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585 {
4586
James Bottomley 47b5d692005-04-24 02:38:05 -05004587 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588 }
4589
4590 message = RD_HARPOON(port+hp_scsidata_0);
4591 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4592 {
4593
4594 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4595
4596 }
4597
4598 else
4599 {
4600
James Bottomley 47b5d692005-04-24 02:38:05 -05004601 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602 if (message)
4603 {
4604
4605
James Bottomley 47b5d692005-04-24 02:38:05 -05004606 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004607
4608 }
4609 else
4610 {
4611 if(currSCCB->Sccb_scsimsg != SMPARITY)
4612 ACCEPT_MSG(port);
4613 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4614 }
4615 }
4616
4617}
4618
4619
4620/*---------------------------------------------------------------------
4621 *
4622 * Function: Illegal phase
4623 *
4624 * Description: Target switched to some illegal phase, so all we can do
4625 * is report an error back to the host (if that is possible)
4626 * and send an ABORT message to the misbehaving target.
4627 *
4628 *---------------------------------------------------------------------*/
4629
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004630static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004631{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004632 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004633
James Bottomley 47b5d692005-04-24 02:38:05 -05004634 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004635
4636 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4637 if (currSCCB != NULL) {
4638
4639 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4640 currSCCB->Sccb_scsistat = ABORT_ST;
4641 currSCCB->Sccb_scsimsg = SMABORT;
4642 }
4643
4644 ACCEPT_MSG_ATN(port);
4645}
4646
4647
4648
4649/*---------------------------------------------------------------------
4650 *
4651 * Function: Phase Check FIFO
4652 *
4653 * Description: Make sure data has been flushed from both FIFOs and abort
4654 * the operations if necessary.
4655 *
4656 *---------------------------------------------------------------------*/
4657
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004658static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004659{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004660 unsigned long xfercnt;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004661 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662
James Bottomley 47b5d692005-04-24 02:38:05 -05004663 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004664
4665 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4666 {
4667
4668 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4669 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4670
4671
4672 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4673 {
4674 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4675
4676 currSCCB->Sccb_XferCnt = 0;
4677
4678 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4679 (currSCCB->HostStatus == SCCB_COMPLETE))
4680 {
4681 currSCCB->HostStatus = SCCB_PARITY_ERR;
4682 WRW_HARPOON((port+hp_intstat), PARITY);
4683 }
4684
James Bottomley 47b5d692005-04-24 02:38:05 -05004685 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004686
James Bottomley 47b5d692005-04-24 02:38:05 -05004687 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004688
4689 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4690 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4691
4692 }
4693 } /*End Data In specific code. */
4694
4695
4696
Linus Torvalds1da177e2005-04-16 15:20:36 -07004697 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004698
4699
4700 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4701
4702
4703 WR_HARPOON(port+hp_portctrl_0, 0x00);
4704
4705 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4706
4707 currSCCB->Sccb_XferCnt = xfercnt;
4708
4709 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4710 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4711
4712 currSCCB->HostStatus = SCCB_PARITY_ERR;
4713 WRW_HARPOON((port+hp_intstat), PARITY);
4714 }
4715
4716
James Bottomley 47b5d692005-04-24 02:38:05 -05004717 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004718
4719
4720 WR_HARPOON(port+hp_fifowrite, 0x00);
4721 WR_HARPOON(port+hp_fiforead, 0x00);
4722 WR_HARPOON(port+hp_xferstat, 0x00);
4723
4724 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4725}
4726
4727
4728/*---------------------------------------------------------------------
4729 *
4730 * Function: Phase Bus Free
4731 *
4732 * Description: We just went bus free so figure out if it was
4733 * because of command complete or from a disconnect.
4734 *
4735 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004736static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004737{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004738 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004739
James Bottomley 47b5d692005-04-24 02:38:05 -05004740 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004741
4742 if (currSCCB != NULL)
4743 {
4744
4745 DISABLE_AUTO(port);
4746
4747
4748 if (currSCCB->OperationCode == RESET_COMMAND)
4749 {
4750
James Bottomley 47b5d692005-04-24 02:38:05 -05004751 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4752 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4753 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004754 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004755 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756
James Bottomley 47b5d692005-04-24 02:38:05 -05004757 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004758
James Bottomley 47b5d692005-04-24 02:38:05 -05004759 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004760
4761 }
4762
4763 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4764 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004766 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004767 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004768 }
4769
4770 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4771 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004772 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4773 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004774 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4775
James Bottomley 47b5d692005-04-24 02:38:05 -05004776 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004777 }
4778
Linus Torvalds1da177e2005-04-16 15:20:36 -07004779 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4780 {
4781 /* Make sure this is not a phony BUS_FREE. If we were
4782 reselected or if BUSY is NOT on then this is a
4783 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4784
4785 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4786 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4787 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4789 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004790 }
4791
4792 else
4793 {
4794 return;
4795 }
4796 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004797
4798 else
4799 {
4800
4801 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4802
4803 if (!currSCCB->HostStatus)
4804 {
4805 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4806 }
4807
James Bottomley 47b5d692005-04-24 02:38:05 -05004808 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4809 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4810 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004811 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004812 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004813
James Bottomley 47b5d692005-04-24 02:38:05 -05004814 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004815 return;
4816 }
4817
4818
James Bottomley 47b5d692005-04-24 02:38:05 -05004819 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004820
4821 } /*end if !=null */
4822}
4823
4824
4825
4826
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827/*---------------------------------------------------------------------
4828 *
4829 * Function: Auto Load Default Map
4830 *
4831 * Description: Load the Automation RAM with the defualt map values.
4832 *
4833 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004834static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004835{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004836 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004837
4838 ARAM_ACCESS(p_port);
4839 map_addr = p_port + hp_aramBase;
4840
4841 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4842 map_addr +=2;
4843 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4844 map_addr +=2;
4845 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4846 map_addr +=2;
4847 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4848 map_addr +=2;
4849 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4850 map_addr +=2;
4851 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4852 map_addr +=2;
4853 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4876 map_addr +=2; /*This means AYNC DATA IN */
4877 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4888 map_addr +=2;
4889 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4910 map_addr +=2;
4911 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4912 map_addr +=2;
4913
4914 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4917 map_addr +=2;
4918 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4919 map_addr +=2;
4920 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4921 map_addr +=2; /* DIDN'T GET ONE */
4922 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4923 map_addr +=2;
4924 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4925 map_addr +=2;
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4927
4928
4929
4930 SGRAM_ACCESS(p_port);
4931}
4932
4933/*---------------------------------------------------------------------
4934 *
4935 * Function: Auto Command Complete
4936 *
4937 * Description: Post command back to host and find another command
4938 * to execute.
4939 *
4940 *---------------------------------------------------------------------*/
4941
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004942static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004943{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004944 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004945 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004946
James Bottomley 47b5d692005-04-24 02:38:05 -05004947 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004948
4949 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4950
James Bottomley 47b5d692005-04-24 02:38:05 -05004951 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004952
4953 if (status_byte != SSGOOD) {
4954
4955 if (status_byte == SSQ_FULL) {
4956
4957
James Bottomley 47b5d692005-04-24 02:38:05 -05004958 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4959 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004960 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004961 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4962 if(FPT_BL_Card[p_card].discQCount != 0)
4963 FPT_BL_Card[p_card].discQCount--;
4964 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004965 }
4966 else
4967 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004968 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004969 if(currSCCB->Sccb_tag)
4970 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004971 if(FPT_BL_Card[p_card].discQCount != 0)
4972 FPT_BL_Card[p_card].discQCount--;
4973 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004974 }else
4975 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004976 if(FPT_BL_Card[p_card].discQCount != 0)
4977 FPT_BL_Card[p_card].discQCount--;
4978 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004979 }
4980 }
4981
4982 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4983
James Bottomley 47b5d692005-04-24 02:38:05 -05004984 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004985
4986 return;
4987 }
4988
4989 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4990 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004991 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004992 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004993
James Bottomley 47b5d692005-04-24 02:38:05 -05004994 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4995 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004996
James Bottomley 47b5d692005-04-24 02:38:05 -05004997 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4998 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004999 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005000 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5001 if(FPT_BL_Card[p_card].discQCount != 0)
5002 FPT_BL_Card[p_card].discQCount--;
5003 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005004 }
5005 else
5006 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005007 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005008 if(currSCCB->Sccb_tag)
5009 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005010 if(FPT_BL_Card[p_card].discQCount != 0)
5011 FPT_BL_Card[p_card].discQCount--;
5012 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005013 }else
5014 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005015 if(FPT_BL_Card[p_card].discQCount != 0)
5016 FPT_BL_Card[p_card].discQCount--;
5017 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005018 }
5019 }
5020 return;
5021
5022 }
5023
5024 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5025 {
5026
James Bottomley 47b5d692005-04-24 02:38:05 -05005027 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5028 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005029 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5030
James Bottomley 47b5d692005-04-24 02:38:05 -05005031 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5032 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005033
James Bottomley 47b5d692005-04-24 02:38:05 -05005034 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5035 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005036 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005037 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5038 if(FPT_BL_Card[p_card].discQCount != 0)
5039 FPT_BL_Card[p_card].discQCount--;
5040 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005041 }
5042 else
5043 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005044 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005045 if(currSCCB->Sccb_tag)
5046 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005047 if(FPT_BL_Card[p_card].discQCount != 0)
5048 FPT_BL_Card[p_card].discQCount--;
5049 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005050 }else
5051 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005052 if(FPT_BL_Card[p_card].discQCount != 0)
5053 FPT_BL_Card[p_card].discQCount--;
5054 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005055 }
5056 }
5057 return;
5058
5059 }
5060
5061 if (status_byte == SSCHECK)
5062 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005063 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005064 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005065 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005066 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005067 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005068 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005069 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005070 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005071 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005072 }
5073 }
5074 }
5075
5076 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5077
5078 currSCCB->SccbStatus = SCCB_ERROR;
5079 currSCCB->TargetStatus = status_byte;
5080
5081 if (status_byte == SSCHECK) {
5082
James Bottomley 47b5d692005-04-24 02:38:05 -05005083 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5084 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005085
5086
Linus Torvalds1da177e2005-04-16 15:20:36 -07005087 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5088
5089 if (currSCCB->RequestSenseLength == 0)
5090 currSCCB->RequestSenseLength = 14;
5091
James Bottomley 47b5d692005-04-24 02:38:05 -05005092 FPT_ssenss(&FPT_BL_Card[p_card]);
5093 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005094
James Bottomley 47b5d692005-04-24 02:38:05 -05005095 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5096 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005097 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005098 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5099 if(FPT_BL_Card[p_card].discQCount != 0)
5100 FPT_BL_Card[p_card].discQCount--;
5101 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005102 }
5103 else
5104 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005105 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005106 if(currSCCB->Sccb_tag)
5107 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005108 if(FPT_BL_Card[p_card].discQCount != 0)
5109 FPT_BL_Card[p_card].discQCount--;
5110 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005111 }else
5112 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005113 if(FPT_BL_Card[p_card].discQCount != 0)
5114 FPT_BL_Card[p_card].discQCount--;
5115 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005116 }
5117 }
5118 return;
5119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005120 }
5121 }
5122 }
5123
5124
James Bottomley 47b5d692005-04-24 02:38:05 -05005125 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5126 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5127 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005128 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005129 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005130
5131
James Bottomley 47b5d692005-04-24 02:38:05 -05005132 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005133}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005134
5135#define SHORT_WAIT 0x0000000F
5136#define LONG_WAIT 0x0000FFFFL
5137
Linus Torvalds1da177e2005-04-16 15:20:36 -07005138
5139/*---------------------------------------------------------------------
5140 *
5141 * Function: Data Transfer Processor
5142 *
5143 * Description: This routine performs two tasks.
5144 * (1) Start data transfer by calling HOST_DATA_XFER_START
5145 * function. Once data transfer is started, (2) Depends
5146 * on the type of data transfer mode Scatter/Gather mode
5147 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5148 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5149 * data transfer done. In Scatter/Gather mode, this routine
5150 * checks bus master command complete and dual rank busy
5151 * bit to keep chaining SC transfer command. Similarly,
5152 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5153 * (F_HOST_XFER_ACT bit) for data transfer done.
5154 *
5155 *---------------------------------------------------------------------*/
5156
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005157static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005158{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005159 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005160
5161 currSCCB = pCurrCard->currentSCCB;
5162
5163 if (currSCCB->Sccb_XferState & F_SG_XFER)
5164 {
5165 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5166
5167 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005168 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005169 currSCCB->Sccb_SGoffset = 0x00;
5170 }
5171 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5172
James Bottomley 47b5d692005-04-24 02:38:05 -05005173 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005174 }
5175
5176 else
5177 {
5178 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5179 {
5180 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5181
James Bottomley 47b5d692005-04-24 02:38:05 -05005182 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005183 }
5184 }
5185}
5186
5187
5188/*---------------------------------------------------------------------
5189 *
5190 * Function: BusMaster Scatter Gather Data Transfer Start
5191 *
5192 * Description:
5193 *
5194 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005195static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005196{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005197 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005198 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005199 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005200 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005201
5202
5203 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5204
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005205 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005206 }
5207
5208 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005209 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005210 }
5211
5212 sg_count = 0;
5213 tmpSGCnt = 0;
5214 sg_index = pcurrSCCB->Sccb_sgseg;
5215 reg_offset = hp_aramBase;
5216
5217
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005218 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005219
5220
5221 WR_HARPOON(p_port+hp_page_ctrl, i);
5222
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005223 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005224 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005225
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005226 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005227 (sg_index * 2));
5228
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005229 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230 (sg_index * 2));
5231
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005232 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005233 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234
5235
5236 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5237
5238 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5239 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5240
5241 tmpSGCnt = count & 0x00FFFFFFL;
5242 }
5243
5244 WR_HARP32(p_port,reg_offset,addr);
5245 reg_offset +=4;
5246
5247 WR_HARP32(p_port,reg_offset,count);
5248 reg_offset +=4;
5249
5250 count &= 0xFF000000L;
5251 sg_index++;
5252 sg_count++;
5253
5254 } /*End While */
5255
5256 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5257
5258 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5259
5260 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5261
5262 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5263
5264
5265 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5266 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5267 }
5268
5269 else {
5270
5271
5272 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5273 (tmpSGCnt & 0x000000001))
5274 {
5275
5276 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5277 tmpSGCnt--;
5278 }
5279
5280
5281 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5282
5283 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5284 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5285 }
5286
5287
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005288 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005289
5290}
5291
5292
5293/*---------------------------------------------------------------------
5294 *
5295 * Function: BusMaster Data Transfer Start
5296 *
5297 * Description:
5298 *
5299 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005300static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005301{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005302 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005303
5304 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5305
5306 count = pcurrSCCB->Sccb_XferCnt;
5307
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005308 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005309 }
5310
5311 else {
5312 addr = pcurrSCCB->SensePointer;
5313 count = pcurrSCCB->RequestSenseLength;
5314
5315 }
5316
Linus Torvalds1da177e2005-04-16 15:20:36 -07005317 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005318
5319
5320 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5321
5322 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5323 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5324
5325 WR_HARPOON(p_port+hp_xfer_cmd,
5326 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5327 }
5328
5329 else {
5330
5331 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5332 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5333
5334 WR_HARPOON(p_port+hp_xfer_cmd,
5335 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5336
5337 }
5338}
5339
5340
5341/*---------------------------------------------------------------------
5342 *
5343 * Function: BusMaster Timeout Handler
5344 *
5345 * Description: This function is called after a bus master command busy time
5346 * out is detected. This routines issue halt state machine
5347 * with a software time out for command busy. If command busy
5348 * is still asserted at the end of the time out, it issues
5349 * hard abort with another software time out. It hard abort
5350 * command busy is also time out, it'll just give up.
5351 *
5352 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005353static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005355 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005356
5357 timeout = LONG_WAIT;
5358
5359 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5360
5361 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5362
5363
5364
5365 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5366 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5367
5368 timeout = LONG_WAIT;
5369 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5370 }
5371
5372 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5373
5374 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005375 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005376 }
5377
5378 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005379 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005380 }
5381}
5382
5383
5384/*---------------------------------------------------------------------
5385 *
5386 * Function: Host Data Transfer Abort
5387 *
5388 * Description: Abort any in progress transfer.
5389 *
5390 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005391static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005392{
5393
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005394 unsigned long timeout;
5395 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005396 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005397
James Bottomley 47b5d692005-04-24 02:38:05 -05005398 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005399
5400 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5401
5402
5403 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5404
5405 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5406 timeout = LONG_WAIT;
5407
5408 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5409
5410 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5411
5412 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5413
James Bottomley 47b5d692005-04-24 02:38:05 -05005414 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005415
5416 if (pCurrSCCB->HostStatus == 0x00)
5417
5418 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5419
5420 }
5421
5422 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5423
5424 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5425
5426 if (pCurrSCCB->HostStatus == 0x00)
5427
5428 {
5429 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005430 }
5431 }
5432 }
5433 }
5434
5435 else if (pCurrSCCB->Sccb_XferCnt) {
5436
5437 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5438
5439
5440 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5441 ~SCATTER_EN));
5442
5443 WR_HARPOON(port+hp_sg_addr,0x00);
5444
5445 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5446
Alexey Dobriyance793212006-03-08 00:14:26 -08005447 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005448
Alexey Dobriyance793212006-03-08 00:14:26 -08005449 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005450 }
5451
5452 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5453
5454 while (remain_cnt < 0x01000000L) {
5455
5456 sg_ptr--;
5457
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005458 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005459 DataPointer) + (sg_ptr * 2)))) {
5460
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005461 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005462 DataPointer) + (sg_ptr * 2)));
5463 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005464
5465 else {
5466
5467 break;
5468 }
5469 }
5470
5471
5472
5473 if (remain_cnt < 0x01000000L) {
5474
5475
5476 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5477
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005478 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005479
5480
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005481 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005482 && (remain_cnt == 0))
5483
5484 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5485 }
5486
5487 else {
5488
5489
5490 if (pCurrSCCB->HostStatus == 0x00) {
5491
5492 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5493 }
5494 }
5495 }
5496
5497
5498 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5499
5500
5501 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5502
James Bottomley 47b5d692005-04-24 02:38:05 -05005503 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005504 }
5505
5506 else {
5507
5508 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5509
5510 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5511
5512 if (pCurrSCCB->HostStatus == 0x00) {
5513
5514 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005515 }
5516 }
5517 }
5518
5519 }
5520 }
5521
5522 else {
5523
5524
5525 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5526
5527 timeout = SHORT_WAIT;
5528
5529 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5530 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5531 timeout--) {}
5532 }
5533
5534 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5535
5536 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5537 FLUSH_XFER_CNTR));
5538
5539 timeout = LONG_WAIT;
5540
5541 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5542 timeout--) {}
5543
5544 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5545 ~FLUSH_XFER_CNTR));
5546
5547
5548 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5549
5550 if (pCurrSCCB->HostStatus == 0x00) {
5551
5552 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5553 }
5554
James Bottomley 47b5d692005-04-24 02:38:05 -05005555 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005556 }
5557 }
5558
5559 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5560
5561 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5562
5563 if (pCurrSCCB->HostStatus == 0x00) {
5564
5565 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005566 }
5567 }
5568 }
5569 }
5570
5571 }
5572
5573 else {
5574
5575
5576 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5577
5578 timeout = LONG_WAIT;
5579
5580 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5581
5582 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5583
5584 if (pCurrSCCB->HostStatus == 0x00) {
5585
5586 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5587 }
5588
James Bottomley 47b5d692005-04-24 02:38:05 -05005589 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005590 }
5591 }
5592
5593
5594 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5595
5596 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5597
5598 if (pCurrSCCB->HostStatus == 0x00) {
5599
5600 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005601 }
5602 }
5603
5604 }
5605
5606 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5607
5608 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5609 ~SCATTER_EN));
5610
5611 WR_HARPOON(port+hp_sg_addr,0x00);
5612
5613 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5614
5615 pCurrSCCB->Sccb_SGoffset = 0x00;
5616
5617
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005618 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005619 pCurrSCCB->DataLength) {
5620
5621 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5622
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005623 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005624
5625 }
5626 }
5627
5628 else {
5629
5630 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5631
5632 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5633 }
5634 }
5635
5636 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5637}
5638
5639
5640
5641/*---------------------------------------------------------------------
5642 *
5643 * Function: Host Data Transfer Restart
5644 *
5645 * Description: Reset the available count due to a restore data
5646 * pointers message.
5647 *
5648 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005649static void FPT_hostDataXferRestart(struct sccb * currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005650{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005651 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005652 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005653 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005654
5655 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5656
5657 currSCCB->Sccb_XferCnt = 0;
5658
5659 sg_index = 0xffff; /*Index by long words into sg list. */
5660 data_count = 0; /*Running count of SG xfer counts. */
5661
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005662 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005663
5664 while (data_count < currSCCB->Sccb_ATC) {
5665
5666 sg_index++;
5667 data_count += *(sg_ptr+(sg_index * 2));
5668 }
5669
5670 if (data_count == currSCCB->Sccb_ATC) {
5671
5672 currSCCB->Sccb_SGoffset = 0;
5673 sg_index++;
5674 }
5675
5676 else {
5677 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5678 }
5679
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005680 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005681 }
5682
5683 else {
5684 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5685 }
5686}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005687
5688
5689
Linus Torvalds1da177e2005-04-16 15:20:36 -07005690/*---------------------------------------------------------------------
5691 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005692 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005693 *
5694 * Description: Setup all data structures necessary for SCAM selection.
5695 *
5696 *---------------------------------------------------------------------*/
5697
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005698static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699{
5700
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005701 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005702 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005703
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005704 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005705 PSCCBcard currCard;
5706 PNVRamInfo pCurrNvRam;
5707
James Bottomley 47b5d692005-04-24 02:38:05 -05005708 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005709 p_port = currCard->ioPort;
5710 pCurrNvRam = currCard->pNvRamInfo;
5711
5712
5713 if(pCurrNvRam){
5714 ScamFlg = pCurrNvRam->niScamConf;
5715 i = pCurrNvRam->niSysConf;
5716 }
5717 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005718 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5719 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005720 }
5721 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5722 return;
5723
James Bottomley 47b5d692005-04-24 02:38:05 -05005724 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005725
5726 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5727 too slow to return to SCAM selection */
5728
5729 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005730 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005732 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733
James Bottomley 47b5d692005-04-24 02:38:05 -05005734 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005735
5736 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5737 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005738 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005739
James Bottomley 47b5d692005-04-24 02:38:05 -05005740 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005741
5742 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005743 FPT_scxferc(p_port,SYNC_PTRN);
5744 FPT_scxferc(p_port,DOM_MSTR);
5745 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005746 } while ( loser == 0xFF );
5747
James Bottomley 47b5d692005-04-24 02:38:05 -05005748 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005749
5750 if ((p_power_up) && (!loser))
5751 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005752 FPT_sresb(p_port,p_card);
5753 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005754
James Bottomley 47b5d692005-04-24 02:38:05 -05005755 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756
James Bottomley 47b5d692005-04-24 02:38:05 -05005757 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005758
5759 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005760 FPT_scxferc(p_port, SYNC_PTRN);
5761 FPT_scxferc(p_port, DOM_MSTR);
5762 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763 id_string[0]);
5764 } while ( loser == 0xFF );
5765
James Bottomley 47b5d692005-04-24 02:38:05 -05005766 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005767 }
5768 }
5769
5770 else
5771 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005772 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005773 }
5774
5775
5776 if (!loser)
5777 {
5778
James Bottomley 47b5d692005-04-24 02:38:05 -05005779 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005780
5781
5782 if (ScamFlg & SCAM_ENABLED)
5783 {
5784
5785 for (i=0; i < MAX_SCSI_TAR; i++)
5786 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005787 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5788 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005789 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005790 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005791 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005792 FPT_scamInfo[i].state = LEGACY;
5793 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5794 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005795 {
5796
James Bottomley 47b5d692005-04-24 02:38:05 -05005797 FPT_scamInfo[i].id_string[0] = 0xFF;
5798 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005799 if(pCurrNvRam == NULL)
5800 currCard->globalFlags |= F_UPDATE_EEPROM;
5801 }
5802 }
5803 }
5804 }
5805
James Bottomley 47b5d692005-04-24 02:38:05 -05005806 FPT_sresb(p_port,p_card);
5807 FPT_Wait1Second(p_port);
5808 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5809 FPT_scsel(p_port);
5810 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005811 }
5812
Linus Torvalds1da177e2005-04-16 15:20:36 -07005813 }
5814
5815 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5816 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005817 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5818 assigned_id = 0;
5819 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005820
5821 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005822 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005823
James Bottomley 47b5d692005-04-24 02:38:05 -05005824 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005825 if (i == ASSIGN_ID)
5826 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005827 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005828 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005829 i = FPT_scxferc(p_port,0x00);
5830 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005832 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833
James Bottomley 47b5d692005-04-24 02:38:05 -05005834 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835 {
5836 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005837 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005838 FPT_inisci(p_card, p_port, p_our_id);
5839 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5840 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005842 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843 }
5844 }
5845 }
5846 }
5847
5848 else if (i == SET_P_FLAG)
5849 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005850 if (!(FPT_scsendi(p_port,
5851 &FPT_scamInfo[p_our_id].id_string[0])))
5852 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 }
5854 }while (!assigned_id);
5855
James Bottomley 47b5d692005-04-24 02:38:05 -05005856 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005857 }
5858
Linus Torvalds1da177e2005-04-16 15:20:36 -07005859 if (ScamFlg & SCAM_ENABLED)
5860 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005861 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005862 if (currCard->globalFlags & F_UPDATE_EEPROM)
5863 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005864 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005865 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5866 }
5867 }
5868
5869
Linus Torvalds1da177e2005-04-16 15:20:36 -07005870/*
5871 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5872 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005873 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5874 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005875 k++;
5876 }
5877
5878 if (k==2)
5879 currCard->globalFlags |= F_SINGLE_DEVICE;
5880 else
5881 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5882*/
5883}
5884
5885
5886/*---------------------------------------------------------------------
5887 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005888 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005889 *
5890 * Description: Gain control of the bus and wait SCAM select time (250ms)
5891 *
5892 *---------------------------------------------------------------------*/
5893
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005894static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005895{
5896 if (p_sel_type == INIT_SELTD)
5897 {
5898
5899 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5900
5901
5902 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005903 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005904
5905 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005906 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005907
5908 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5909
5910 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5911
5912 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5913 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005914 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005915 }
5916
5917
5918 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5919
5920 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5921
5922 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5923 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005924 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005925 }
5926 }
5927
5928
5929 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5930 & ~ACTdeassert));
5931 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5932 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005933 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005934 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5935
5936 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5937
5938 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5939 & ~SCSI_BSY));
5940
James Bottomley 47b5d692005-04-24 02:38:05 -05005941 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942
James Bottomley 47b5d692005-04-24 02:38:05 -05005943 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005944}
5945
5946
5947/*---------------------------------------------------------------------
5948 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005949 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005950 *
5951 * Description: Release the SCSI bus and disable SCAM selection.
5952 *
5953 *---------------------------------------------------------------------*/
5954
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005955static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005956{
5957 WR_HARPOON(p_port+hp_page_ctrl,
5958 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5959
5960
5961 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5962
5963 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5964 & ~SCSI_BUS_EN));
5965
5966 WR_HARPOON(p_port+hp_scsisig, 0x00);
5967
5968
5969 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5970 & ~SCAM_EN));
5971
5972 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5973 | ACTdeassert));
5974
Linus Torvalds1da177e2005-04-16 15:20:36 -07005975 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005976
5977 WR_HARPOON(p_port+hp_page_ctrl,
5978 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5979}
5980
5981
5982
5983/*---------------------------------------------------------------------
5984 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005985 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005986 *
5987 * Description: Assign an ID to all the SCAM devices.
5988 *
5989 *---------------------------------------------------------------------*/
5990
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005991static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005992{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005993 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005994
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005995 unsigned char i,k,scam_id;
5996 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997 PNVRamInfo pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08005998 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005999
James Bottomley 47b5d692005-04-24 02:38:05 -05006000 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006001
James Bottomley 47b5d692005-04-24 02:38:05 -05006002 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003
6004 while (!i)
6005 {
6006
6007 for (k=0; k < ID_STRING_LENGTH; k++)
6008 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006009 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006010 }
6011
James Bottomley 47b5d692005-04-24 02:38:05 -05006012 FPT_scxferc(p_port,SYNC_PTRN);
6013 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006014
James Bottomley 47b5d692005-04-24 02:38:05 -05006015 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006016 {
6017 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006018 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006019 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6020 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021 temp_id_string[1] = crcBytes[2];
6022 temp_id_string[2] = crcBytes[0];
6023 temp_id_string[3] = crcBytes[1];
6024 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006025 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006026 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006027 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006028
6029 if (i == CLR_PRIORITY)
6030 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006031 FPT_scxferc(p_port,MISC_CODE);
6032 FPT_scxferc(p_port,CLR_P_FLAG);
6033 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006034 }
6035
6036 else if (i != NO_ID_AVAIL)
6037 {
6038 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006039 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006040 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006041 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006043 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006044
6045
6046 for (k=1; k < 0x08; k <<= 1)
6047 if (!( k & i ))
6048 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6049
James Bottomley 47b5d692005-04-24 02:38:05 -05006050 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051
James Bottomley 47b5d692005-04-24 02:38:05 -05006052 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006053 }
6054 }
6055
6056 else
6057 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006058 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006059 }
6060
6061 } /*End while */
6062
James Bottomley 47b5d692005-04-24 02:38:05 -05006063 FPT_scxferc(p_port,SYNC_PTRN);
6064 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006065}
6066
6067
6068
6069
6070
6071/*---------------------------------------------------------------------
6072 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006073 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006074 *
6075 * Description: Select all the SCAM devices.
6076 *
6077 *---------------------------------------------------------------------*/
6078
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006079static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006080{
6081
6082 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006083 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006084
6085 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6086
6087
6088 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006089 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6090 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006091
6092
6093 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006094 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006095
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006096 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6097 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006098 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006099
6100 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6101}
6102
6103
6104
6105/*---------------------------------------------------------------------
6106 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006107 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006108 *
6109 * Description: Handshake the p_data (DB4-0) across the bus.
6110 *
6111 *---------------------------------------------------------------------*/
6112
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006113static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006114{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006115 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006116
6117 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6118
6119 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6120
6121 curr_data &= ~BIT(7);
6122
6123 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6124
James Bottomley 47b5d692005-04-24 02:38:05 -05006125 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006126 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6127
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006128 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006129
6130 curr_data |= BIT(6);
6131
6132 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133
6134 curr_data &= ~BIT(5);
6135
6136 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6137
James Bottomley 47b5d692005-04-24 02:38:05 -05006138 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006139
6140 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6141 curr_data |= BIT(7);
6142
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6144
6145 curr_data &= ~BIT(6);
6146
6147 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6148
James Bottomley 47b5d692005-04-24 02:38:05 -05006149 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006150
6151 return(ret_data);
6152}
6153
6154
6155/*---------------------------------------------------------------------
6156 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006157 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006158 *
6159 * Description: Transfer our Identification string to determine if we
6160 * will be the dominant master.
6161 *
6162 *---------------------------------------------------------------------*/
6163
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006164static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006165{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006166 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006167
James Bottomley 47b5d692005-04-24 02:38:05 -05006168 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006169
6170 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6171
6172 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6173
6174 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006175 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176
6177 else if (p_id_string[byte_cnt] & bit_cnt)
6178
James Bottomley 47b5d692005-04-24 02:38:05 -05006179 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006180
6181 else {
6182
James Bottomley 47b5d692005-04-24 02:38:05 -05006183 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006184 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006185 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006186 }
6187
6188 if ((ret_data & 0x1C) == 0x10)
6189 return(0x00); /*End of isolation stage, we won! */
6190
6191 if (ret_data & 0x1C)
6192 return(0xFF);
6193
6194 if ((defer) && (!(ret_data & 0x1F)))
6195 return(0x01); /*End of isolation stage, we lost. */
6196
6197 } /*bit loop */
6198
6199 } /*byte loop */
6200
6201 if (defer)
6202 return(0x01); /*We lost */
6203 else
6204 return(0); /*We WON! Yeeessss! */
6205}
6206
6207
6208
6209/*---------------------------------------------------------------------
6210 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006211 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006212 *
6213 * Description: Transfer the Identification string.
6214 *
6215 *---------------------------------------------------------------------*/
6216
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006217static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006218{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006219 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006220
6221 the_data = 0;
6222
6223 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6224
6225 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6226
James Bottomley 47b5d692005-04-24 02:38:05 -05006227 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006228
6229 if (ret_data & 0xFC)
6230 return(0xFF);
6231
6232 else {
6233
6234 the_data <<= 1;
6235 if (ret_data & BIT(1)) {
6236 the_data |= 1;
6237 }
6238 }
6239
6240 if ((ret_data & 0x1F) == 0)
6241 {
6242/*
6243 if(bit_cnt != 0 || bit_cnt != 8)
6244 {
6245 byte_cnt = 0;
6246 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006247 FPT_scxferc(p_port, SYNC_PTRN);
6248 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006249 continue;
6250 }
6251*/
6252 if (byte_cnt)
6253 return(0x00);
6254 else
6255 return(0xFF);
6256 }
6257
6258 } /*bit loop */
6259
6260 p_id_string[byte_cnt] = the_data;
6261
6262 } /*byte loop */
6263
6264 return(0);
6265}
6266
6267
6268
6269/*---------------------------------------------------------------------
6270 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006271 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006272 *
6273 * Description: Sample the SCSI data bus making sure the signal has been
6274 * deasserted for the correct number of consecutive samples.
6275 *
6276 *---------------------------------------------------------------------*/
6277
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006278static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006279{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006280 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006281
6282 i = 0;
6283 while ( i < MAX_SCSI_TAR ) {
6284
6285 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6286
6287 i = 0;
6288
6289 else
6290
6291 i++;
6292
6293 }
6294}
6295
6296
6297
6298/*---------------------------------------------------------------------
6299 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006300 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006301 *
6302 * Description: Sample the SCSI Signal lines making sure the signal has been
6303 * deasserted for the correct number of consecutive samples.
6304 *
6305 *---------------------------------------------------------------------*/
6306
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006307static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006308{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006309 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006310
6311 i = 0;
6312 while ( i < MAX_SCSI_TAR ) {
6313
6314 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6315
6316 i = 0;
6317
6318 else
6319
6320 i++;
6321
6322 }
6323}
6324
6325
6326/*---------------------------------------------------------------------
6327 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006328 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006329 *
6330 * Description: Make sure we received a valid data byte.
6331 *
6332 *---------------------------------------------------------------------*/
6333
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006334static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006335{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006336 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006337
6338 for (count=1; count < 0x08; count<<=1) {
6339 if (!(p_quintet & count))
6340 p_quintet -= 0x80;
6341 }
6342
6343 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006344 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006345
6346 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006347 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006348}
6349
6350
6351/*---------------------------------------------------------------------
6352 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006353 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006354 *
6355 * Description: Select the specified device ID using a selection timeout
6356 * less than 4ms. If somebody responds then it is a legacy
6357 * drive and this ID must be marked as such.
6358 *
6359 *---------------------------------------------------------------------*/
6360
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006361static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006362{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006363 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006364
6365 WR_HARPOON(p_port+hp_page_ctrl,
6366 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6367
6368 ARAM_ACCESS(p_port);
6369
6370 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6371 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6372
6373
6374 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6375 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6376 }
6377 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6378
6379 WRW_HARPOON((p_port+hp_intstat),
6380 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6381
6382 WR_HARPOON(p_port+hp_select_id, targ_id);
6383
6384 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6385 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6386 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6387
6388
6389 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6390 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6391
6392 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006393 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006394
6395 DISABLE_AUTO(p_port);
6396
6397 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6398 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6399
6400 SGRAM_ACCESS(p_port);
6401
6402 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6403
6404 WRW_HARPOON((p_port+hp_intstat),
6405 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6406
6407 WR_HARPOON(p_port+hp_page_ctrl,
6408 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6409
James Bottomley 47b5d692005-04-24 02:38:05 -05006410 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006411 }
6412
6413 else {
6414
6415 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6416 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6417 {
6418 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6419 ACCEPT_MSG(p_port);
6420 }
6421 }
6422
6423 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6424
6425 WR_HARPOON(p_port+hp_page_ctrl,
6426 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6427
James Bottomley 47b5d692005-04-24 02:38:05 -05006428 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006429 }
6430}
6431
Linus Torvalds1da177e2005-04-16 15:20:36 -07006432/*---------------------------------------------------------------------
6433 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006434 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006435 *
6436 * Description: Wait to be selected by another SCAM initiator.
6437 *
6438 *---------------------------------------------------------------------*/
6439
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006440static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006441{
6442 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6443}
6444
6445
6446/*---------------------------------------------------------------------
6447 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006448 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006449 *
6450 * Description: Setup the data Structure with the info from the EEPROM.
6451 *
6452 *---------------------------------------------------------------------*/
6453
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006454static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006456 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006457 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458 PNVRamInfo pCurrNvRam;
6459
James Bottomley 47b5d692005-04-24 02:38:05 -05006460 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006461
6462 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6463 max_id = 0x08;
6464
6465 else
6466 max_id = 0x10;
6467
6468 if(pCurrNvRam){
6469 for(i = 0; i < max_id; i++){
6470
6471 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006472 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006473 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006474 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006475
James Bottomley 47b5d692005-04-24 02:38:05 -05006476 if(FPT_scamInfo[i].id_string[0] == 0x00)
6477 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006478 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006479 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006480
6481 }
6482 }else {
6483 for (i=0; i < max_id; i++)
6484 {
6485 for (k=0; k < ID_STRING_LENGTH; k+=2)
6486 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006487 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6488 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006489 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006491 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006492 }
6493
James Bottomley 47b5d692005-04-24 02:38:05 -05006494 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6495 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006496
James Bottomley 47b5d692005-04-24 02:38:05 -05006497 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498
6499 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006500 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501
6502 }
6503 }
6504 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006505 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506
6507}
6508
6509/*---------------------------------------------------------------------
6510 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006511 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512 *
6513 * Description: Match the Device ID string with our values stored in
6514 * the EEPROM.
6515 *
6516 *---------------------------------------------------------------------*/
6517
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006518static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006519{
6520
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006521 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006522
6523
6524 for (i=0; i < MAX_SCSI_TAR; i++) {
6525
James Bottomley 47b5d692005-04-24 02:38:05 -05006526 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006527
6528 for (k=0; k < ID_STRING_LENGTH; k++)
6529 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006530 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6531 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006532 }
6533
6534 if (match)
6535 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006536 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537 return(i);
6538 }
6539
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540 }
6541
6542
6543
6544 if (p_id_string[0] & BIT(5))
6545 i = 8;
6546 else
6547 i = MAX_SCSI_TAR;
6548
6549 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006550 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551 else
6552 match = 7;
6553
6554 while (i > 0)
6555 {
6556 i--;
6557
James Bottomley 47b5d692005-04-24 02:38:05 -05006558 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559 {
6560 for (k=0; k < ID_STRING_LENGTH; k++)
6561 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006562 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563 }
6564
James Bottomley 47b5d692005-04-24 02:38:05 -05006565 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566
James Bottomley 47b5d692005-04-24 02:38:05 -05006567 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6568 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006569 return(match);
6570
6571 }
6572
6573
6574 match--;
6575
6576 if (match == 0xFF)
6577 {
6578 if (p_id_string[0] & BIT(5))
6579 match = 7;
6580 else
6581 match = MAX_SCSI_TAR-1;
6582 }
6583 }
6584
6585
6586
6587 if (p_id_string[0] & BIT(7))
6588 {
6589 return(CLR_PRIORITY);
6590 }
6591
6592
6593 if (p_id_string[0] & BIT(5))
6594 i = 8;
6595 else
6596 i = MAX_SCSI_TAR;
6597
6598 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006599 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006600 else
6601 match = 7;
6602
6603 while (i > 0)
6604 {
6605
6606 i--;
6607
James Bottomley 47b5d692005-04-24 02:38:05 -05006608 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006609 {
6610 for (k=0; k < ID_STRING_LENGTH; k++)
6611 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006612 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006613 }
6614
James Bottomley 47b5d692005-04-24 02:38:05 -05006615 FPT_scamInfo[match].id_string[0] |= BIT(7);
6616 FPT_scamInfo[match].state = ID_ASSIGNED;
6617 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6618 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006619 return(match);
6620
6621 }
6622
6623
6624 match--;
6625
6626 if (match == 0xFF)
6627 {
6628 if (p_id_string[0] & BIT(5))
6629 match = 7;
6630 else
6631 match = MAX_SCSI_TAR-1;
6632 }
6633 }
6634
6635 return(NO_ID_AVAIL);
6636}
6637
6638
6639/*---------------------------------------------------------------------
6640 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006641 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006642 *
6643 * Description: Save off the device SCAM ID strings.
6644 *
6645 *---------------------------------------------------------------------*/
6646
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006647static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006648{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006649 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006650 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006651
6652
6653 sum_data = 0x0000;
6654
6655 for (i = 1; i < EE_SCAMBASE/2; i++)
6656 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006657 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006658 }
6659
6660
James Bottomley 47b5d692005-04-24 02:38:05 -05006661 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006662
6663 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6664 max_id = 0x08;
6665
6666 else
6667 max_id = 0x10;
6668
6669 for (i=0; i < max_id; i++)
6670 {
6671
6672 for (k=0; k < ID_STRING_LENGTH; k+=2)
6673 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006674 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006675 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006676 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006677 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006678 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6679 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006680 }
6681 }
6682
6683
James Bottomley 47b5d692005-04-24 02:38:05 -05006684 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6685 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687
6688/*---------------------------------------------------------------------
6689 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006690 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006691 *
6692 * Description: Setup the Xbow for normal operation.
6693 *
6694 *---------------------------------------------------------------------*/
6695
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006696static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006697{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006698unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006699
6700 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006701 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006702
6703 WR_HARPOON(port+hp_scsireset,0x00);
6704 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6705
6706 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6707 FIFO_CLR));
6708
6709 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6710
6711 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6712
6713 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6714 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6715
6716 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6717
James Bottomley 47b5d692005-04-24 02:38:05 -05006718 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6720
6721 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006722 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723
James Bottomley 47b5d692005-04-24 02:38:05 -05006724 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725
6726 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6727
6728 /* Turn on SCSI_MODE8 for narrow cards to fix the
6729 strapping issue with the DUAL CHANNEL card */
6730 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6731 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6732
Linus Torvalds1da177e2005-04-16 15:20:36 -07006733 WR_HARPOON(port+hp_page_ctrl, i);
6734
6735}
6736
6737
6738/*---------------------------------------------------------------------
6739 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006740 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006741 *
6742 * Description: Initialize the BusMaster for normal operations.
6743 *
6744 *---------------------------------------------------------------------*/
6745
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006746static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747{
6748
6749
6750 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6751 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6752
6753 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6754
6755
6756 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6757
6758 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6759
6760
Linus Torvalds1da177e2005-04-16 15:20:36 -07006761 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6762 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6763 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6764 ~SCATTER_EN));
6765}
6766
6767
6768/*---------------------------------------------------------------------
6769 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006770 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006771 *
6772 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6773 * necessary.
6774 *
6775 *---------------------------------------------------------------------*/
6776
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006777static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006779 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006780
6781 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6782 max_wd_cnt = EEPROM_WD_CNT;
6783 else
6784 max_wd_cnt = EEPROM_WD_CNT * 2;
6785
James Bottomley 47b5d692005-04-24 02:38:05 -05006786 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787
6788 if (temp == 0x4641) {
6789
6790 for (index = 2; index < max_wd_cnt; index++) {
6791
James Bottomley 47b5d692005-04-24 02:38:05 -05006792 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793
6794 }
6795
James Bottomley 47b5d692005-04-24 02:38:05 -05006796 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797
6798 return; /*EEPROM is Okay so return now! */
6799 }
6800 }
6801
6802
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006803 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006804
6805 for (index = 0; index < max_wd_cnt; index++) {
6806
James Bottomley 47b5d692005-04-24 02:38:05 -05006807 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808 }
6809
6810 temp = 0;
6811
James Bottomley 47b5d692005-04-24 02:38:05 -05006812 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006814 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006816 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006818 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006820 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006822 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006823 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006824 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006826 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827 temp += 0x0007;
6828
James Bottomley 47b5d692005-04-24 02:38:05 -05006829 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006833 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 temp += 0x0000;
6835
James Bottomley 47b5d692005-04-24 02:38:05 -05006836 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006838 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006840 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006842 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006844 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006847 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006849 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851 temp += 0x4242;
6852
6853
James Bottomley 47b5d692005-04-24 02:38:05 -05006854 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006856 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006858 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006860 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006862 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006863 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006864 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006866 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869 temp += 0x2020;
6870
6871 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006872 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 temp += (0x0700+TYPE_CODE0);
6874 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006875 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 temp += 0x5542; /* BUSLOGIC */
6877 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006878 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879 temp += 0x4C53;
6880 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006881 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006882 temp += 0x474F;
6883 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006884 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 temp += 0x4349;
6886 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006887 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006888 temp += 0x5442; /* BT- 930 */
6889 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006890 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 temp += 0x202D;
6892 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006893 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006894 temp += 0x3339;
6895 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006896 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006897 temp += 0x2030;
6898 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006899 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900 temp += 0x5453;
6901 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006902 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006903 temp += 0x5645;
6904 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006905 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006906 temp += 0x2045;
6907 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006908 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909 temp += 0x202F;
6910 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006911 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912 temp += 0x4F4A;
6913 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006914 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006915 temp += 0x204E;
6916 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006917 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006918 temp += 0x3539;
6919
6920
6921
James Bottomley 47b5d692005-04-24 02:38:05 -05006922 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006923
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006924 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006925
6926}
6927
Linus Torvalds1da177e2005-04-16 15:20:36 -07006928
6929/*---------------------------------------------------------------------
6930 *
6931 * Function: Queue Search Select
6932 *
6933 * Description: Try to find a new command to execute.
6934 *
6935 *---------------------------------------------------------------------*/
6936
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006937static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006938{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006939 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006941 struct sccb * pOldSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006942
6943 scan_ptr = pCurrCard->scanIndex;
6944 do
6945 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006946 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006947 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6948 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6949 {
6950 if (currTar_Info->TarSelQ_Cnt != 0)
6951 {
6952
6953 scan_ptr++;
6954 if (scan_ptr == MAX_SCSI_TAR)
6955 scan_ptr = 0;
6956
6957 for(lun=0; lun < MAX_LUN; lun++)
6958 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006959 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006960 {
6961
6962 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6963 pOldSccb = NULL;
6964
6965 while((pCurrCard->currentSCCB != NULL) &&
6966 (lun != pCurrCard->currentSCCB->Lun))
6967 {
6968 pOldSccb = pCurrCard->currentSCCB;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006969 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006970 Sccb_forwardlink;
6971 }
6972 if(pCurrCard->currentSCCB == NULL)
6973 continue;
6974 if(pOldSccb != NULL)
6975 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006976 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006977 Sccb_forwardlink;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006978 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006979 Sccb_backlink;
6980 currTar_Info->TarSelQ_Cnt--;
6981 }
6982 else
6983 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006984 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006985
6986 if (currTar_Info->TarSelQ_Head == NULL)
6987 {
6988 currTar_Info->TarSelQ_Tail = NULL;
6989 currTar_Info->TarSelQ_Cnt = 0;
6990 }
6991 else
6992 {
6993 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006994 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006995 }
6996 }
6997 pCurrCard->scanIndex = scan_ptr;
6998
6999 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7000
7001 break;
7002 }
7003 }
7004 }
7005
7006 else
7007 {
7008 scan_ptr++;
7009 if (scan_ptr == MAX_SCSI_TAR) {
7010 scan_ptr = 0;
7011 }
7012 }
7013
7014 }
7015 else
7016 {
7017 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007018 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007019 {
7020
7021 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7022
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007023 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007024
7025 if (currTar_Info->TarSelQ_Head == NULL)
7026 {
7027 currTar_Info->TarSelQ_Tail = NULL;
7028 currTar_Info->TarSelQ_Cnt = 0;
7029 }
7030 else
7031 {
7032 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007033 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007034 }
7035
7036 scan_ptr++;
7037 if (scan_ptr == MAX_SCSI_TAR)
7038 scan_ptr = 0;
7039
7040 pCurrCard->scanIndex = scan_ptr;
7041
7042 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7043
7044 break;
7045 }
7046
7047 else
7048 {
7049 scan_ptr++;
7050 if (scan_ptr == MAX_SCSI_TAR)
7051 {
7052 scan_ptr = 0;
7053 }
7054 }
7055 }
7056 } while (scan_ptr != pCurrCard->scanIndex);
7057}
7058
7059
7060/*---------------------------------------------------------------------
7061 *
7062 * Function: Queue Select Fail
7063 *
7064 * Description: Add the current SCCB to the head of the Queue.
7065 *
7066 *---------------------------------------------------------------------*/
7067
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007068static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007069{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007070 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007071 PSCCBMgr_tar_info currTar_Info;
7072
7073 if (pCurrCard->currentSCCB != NULL)
7074 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007075 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007076 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007077
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007078 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007079
7080 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7081
7082 if (currTar_Info->TarSelQ_Cnt == 0)
7083 {
7084 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7085 }
7086
7087 else
7088 {
7089 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7090 }
7091
7092
7093 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7094
7095 pCurrCard->currentSCCB = NULL;
7096 currTar_Info->TarSelQ_Cnt++;
7097 }
7098}
7099/*---------------------------------------------------------------------
7100 *
7101 * Function: Queue Command Complete
7102 *
7103 * Description: Call the callback function with the current SCCB.
7104 *
7105 *---------------------------------------------------------------------*/
7106
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007107static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007108 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007109{
7110
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007111 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007112 CALL_BK_FN callback;
7113 PSCCBMgr_tar_info currTar_Info;
7114
7115 SCSIcmd = p_sccb->Cdb[0];
7116
7117
7118 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7119
7120 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7121 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7122 (p_sccb->TargetStatus != SSCHECK))
7123
7124 if ((SCSIcmd == SCSI_READ) ||
7125 (SCSIcmd == SCSI_WRITE) ||
7126 (SCSIcmd == SCSI_READ_EXTENDED) ||
7127 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7128 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7129 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7130 (pCurrCard->globalFlags & F_NO_FILTER)
7131 )
7132 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7133 }
7134
7135
7136 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7137 {
7138 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7139 p_sccb->SccbStatus = SCCB_ERROR;
7140 else
7141 p_sccb->SccbStatus = SCCB_SUCCESS;
7142 }
7143
7144 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7145
7146 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7147 for (i=0; i < 6; i++) {
7148 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7149 }
7150 }
7151
7152 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7153 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7154
James Bottomley 47b5d692005-04-24 02:38:05 -05007155 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007156 }
7157
7158 pCurrCard->cmdCounter--;
7159 if (!pCurrCard->cmdCounter) {
7160
7161 if (pCurrCard->globalFlags & F_GREEN_PC) {
7162 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7163 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7164 }
7165
7166 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7167 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7168
7169 }
7170
7171 if(pCurrCard->discQCount != 0)
7172 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007173 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007174 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7175 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7176 {
7177 pCurrCard->discQCount--;
7178 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7179 }
7180 else
7181 {
7182 if(p_sccb->Sccb_tag)
7183 {
7184 pCurrCard->discQCount--;
7185 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7186 }else
7187 {
7188 pCurrCard->discQCount--;
7189 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7190 }
7191 }
7192
7193 }
7194
7195 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7196 callback(p_sccb);
7197 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7198 pCurrCard->currentSCCB = NULL;
7199}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007200
7201
7202/*---------------------------------------------------------------------
7203 *
7204 * Function: Queue Disconnect
7205 *
7206 * Description: Add SCCB to our disconnect array.
7207 *
7208 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007209static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007210{
7211 PSCCBMgr_tar_info currTar_Info;
7212
James Bottomley 47b5d692005-04-24 02:38:05 -05007213 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007214
James Bottomley 47b5d692005-04-24 02:38:05 -05007215 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007216 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7217 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007218 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007219 }
7220 else
7221 {
7222 if (p_sccb->Sccb_tag)
7223 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007224 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7225 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7226 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007227 }else
7228 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007229 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007230 }
7231 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007232 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007233}
7234
7235
7236/*---------------------------------------------------------------------
7237 *
7238 * Function: Queue Flush SCCB
7239 *
7240 * Description: Flush all SCCB's back to the host driver for this target.
7241 *
7242 *---------------------------------------------------------------------*/
7243
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007244static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007245{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007246 unsigned char qtag,thisTarg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007247 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007248 PSCCBMgr_tar_info currTar_Info;
7249
James Bottomley 47b5d692005-04-24 02:38:05 -05007250 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007251 if(currSCCB != NULL)
7252 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007253 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007254 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007255
7256 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7257
James Bottomley 47b5d692005-04-24 02:38:05 -05007258 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7259 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007260 {
7261
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007262 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007263
James Bottomley 47b5d692005-04-24 02:38:05 -05007264 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007265
James Bottomley 47b5d692005-04-24 02:38:05 -05007266 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007267 currTar_Info->TarTagQ_Cnt--;
7268
7269 }
7270 }
7271 }
7272
7273}
7274
7275/*---------------------------------------------------------------------
7276 *
7277 * Function: Queue Flush Target SCCB
7278 *
7279 * Description: Flush all SCCB's back to the host driver for this target.
7280 *
7281 *---------------------------------------------------------------------*/
7282
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007283static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7284 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007285{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007286 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007287 PSCCBMgr_tar_info currTar_Info;
7288
James Bottomley 47b5d692005-04-24 02:38:05 -05007289 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007290
7291 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7292
James Bottomley 47b5d692005-04-24 02:38:05 -05007293 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7294 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007295 {
7296
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007297 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007298
James Bottomley 47b5d692005-04-24 02:38:05 -05007299 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007300
James Bottomley 47b5d692005-04-24 02:38:05 -05007301 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007302 currTar_Info->TarTagQ_Cnt--;
7303
7304 }
7305 }
7306
7307}
7308
7309
7310
7311
7312
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007313static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007314{
7315 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007316 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007317
7318 p_SCCB->Sccb_forwardlink = NULL;
7319
7320 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7321
7322 if (currTar_Info->TarSelQ_Cnt == 0) {
7323
7324 currTar_Info->TarSelQ_Head = p_SCCB;
7325 }
7326
7327 else {
7328
7329 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7330 }
7331
7332
7333 currTar_Info->TarSelQ_Tail = p_SCCB;
7334 currTar_Info->TarSelQ_Cnt++;
7335}
7336
7337
7338/*---------------------------------------------------------------------
7339 *
7340 * Function: Queue Find SCCB
7341 *
7342 * Description: Search the target select Queue for this SCCB, and
7343 * remove it if found.
7344 *
7345 *---------------------------------------------------------------------*/
7346
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007347static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007348{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007349 struct sccb * q_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007350 PSCCBMgr_tar_info currTar_Info;
7351
James Bottomley 47b5d692005-04-24 02:38:05 -05007352 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007353
7354 q_ptr = currTar_Info->TarSelQ_Head;
7355
7356 while(q_ptr != NULL) {
7357
7358 if (q_ptr == p_SCCB) {
7359
7360
7361 if (currTar_Info->TarSelQ_Head == q_ptr) {
7362
7363 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7364 }
7365
7366 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7367
7368 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7369 }
7370
7371 if (q_ptr->Sccb_forwardlink != NULL) {
7372 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7373 }
7374
7375 if (q_ptr->Sccb_backlink != NULL) {
7376 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7377 }
7378
7379 currTar_Info->TarSelQ_Cnt--;
7380
James Bottomley 47b5d692005-04-24 02:38:05 -05007381 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007382 }
7383
7384 else {
7385 q_ptr = q_ptr->Sccb_forwardlink;
7386 }
7387 }
7388
7389
James Bottomley 47b5d692005-04-24 02:38:05 -05007390 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007391
7392}
7393
7394
7395/*---------------------------------------------------------------------
7396 *
7397 * Function: Utility Update Residual Count
7398 *
7399 * Description: Update the XferCnt to the remaining byte count.
7400 * If we transferred all the data then just write zero.
7401 * If Non-SG transfer then report Total Cnt - Actual Transfer
7402 * Cnt. For SG transfers add the count fields of all
7403 * remaining SG elements, as well as any partial remaining
7404 * element.
7405 *
7406 *---------------------------------------------------------------------*/
7407
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007408static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007409{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007410 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007411 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007412 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007413
7414 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7415
7416 p_SCCB->DataLength = 0x0000;
7417 }
7418
7419 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7420
7421 partial_cnt = 0x0000;
7422
7423 sg_index = p_SCCB->Sccb_sgseg;
7424
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007425 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007426
7427 if (p_SCCB->Sccb_SGoffset) {
7428
7429 partial_cnt = p_SCCB->Sccb_SGoffset;
7430 sg_index++;
7431 }
7432
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007433 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007434 p_SCCB->DataLength ) {
7435
7436 partial_cnt += *(sg_ptr+(sg_index * 2));
7437 sg_index++;
7438 }
7439
7440 p_SCCB->DataLength = partial_cnt;
7441 }
7442
7443 else {
7444
7445 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7446 }
7447}
7448
7449
7450/*---------------------------------------------------------------------
7451 *
7452 * Function: Wait 1 Second
7453 *
7454 * Description: Wait for 1 second.
7455 *
7456 *---------------------------------------------------------------------*/
7457
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007458static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007459{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007460 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007461
7462 for(i=0; i < 4; i++) {
7463
James Bottomley 47b5d692005-04-24 02:38:05 -05007464 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007465
7466 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7467 break;
7468
7469 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7470 break;
7471 }
7472}
7473
7474
7475/*---------------------------------------------------------------------
7476 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007477 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007478 *
7479 * Description: Wait the desired delay.
7480 *
7481 *---------------------------------------------------------------------*/
7482
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007483static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007484{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007485 unsigned char old_timer;
7486 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007487
7488 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7489
7490 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7491 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7492
7493 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7494 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007495 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007496
7497
7498 WR_HARPOON(p_port+hp_portctrl_0,
7499 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7500
7501 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7502
7503 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7504 break;
7505
7506 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7507 break;
7508 }
7509
7510 WR_HARPOON(p_port+hp_portctrl_0,
7511 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7512
7513 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007514 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007515
7516 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7517
7518 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7519}
7520
7521
7522/*---------------------------------------------------------------------
7523 *
7524 * Function: Enable/Disable Write to EEPROM
7525 *
7526 * Description: The EEPROM must first be enabled for writes
7527 * A total of 9 clocks are needed.
7528 *
7529 *---------------------------------------------------------------------*/
7530
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007531static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007532{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007533 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007534
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007535 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007536
7537 if (p_mode)
7538
James Bottomley 47b5d692005-04-24 02:38:05 -05007539 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007540
7541 else
7542
7543
James Bottomley 47b5d692005-04-24 02:38:05 -05007544 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007545
7546 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7547 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7548}
7549
7550
7551/*---------------------------------------------------------------------
7552 *
7553 * Function: Write EEPROM
7554 *
7555 * Description: Write a word to the EEPROM at the specified
7556 * address.
7557 *
7558 *---------------------------------------------------------------------*/
7559
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007560static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007561{
7562
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007563 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007564 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007565
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007566 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
Linus Torvalds1da177e2005-04-16 15:20:36 -07007567 (SEE_MS | SEE_CS));
7568
7569
7570
James Bottomley 47b5d692005-04-24 02:38:05 -05007571 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007572
7573
7574 ee_value |= (SEE_MS + SEE_CS);
7575
7576 for(i = 0x8000; i != 0; i>>=1) {
7577
7578 if (i & ee_data)
7579 ee_value |= SEE_DO;
7580 else
7581 ee_value &= ~SEE_DO;
7582
7583 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 ee_value |= SEE_CLK; /* Clock data! */
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 ee_value &= ~SEE_CLK;
7589 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7590 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7591 }
7592 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7593 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7594
James Bottomley 47b5d692005-04-24 02:38:05 -05007595 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007596
7597 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7598 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7600}
7601
7602/*---------------------------------------------------------------------
7603 *
7604 * Function: Read EEPROM
7605 *
7606 * Description: Read a word from the EEPROM at the desired
7607 * address.
7608 *
7609 *---------------------------------------------------------------------*/
7610
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007611static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007612{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007613 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007614
7615 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007616 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007617 do
7618 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007619 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007620
7621 if(ee_data1 == ee_data2)
7622 return(ee_data1);
7623
7624 ee_data1 = ee_data2;
7625 i++;
7626
7627 }while(i < 4);
7628
7629 return(ee_data1);
7630}
7631
7632/*---------------------------------------------------------------------
7633 *
7634 * Function: Read EEPROM Original
7635 *
7636 * Description: Read a word from the EEPROM at the desired
7637 * address.
7638 *
7639 *---------------------------------------------------------------------*/
7640
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007641static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007642{
7643
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007644 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007645 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007646
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007647 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
Linus Torvalds1da177e2005-04-16 15:20:36 -07007648 (SEE_MS | SEE_CS));
7649
7650
James Bottomley 47b5d692005-04-24 02:38:05 -05007651 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007652
7653
7654 ee_value |= (SEE_MS + SEE_CS);
7655 ee_data = 0;
7656
7657 for(i = 1; i <= 16; i++) {
7658
7659 ee_value |= SEE_CLK; /* Clock data! */
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7662 ee_value &= ~SEE_CLK;
7663 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7664 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7665
7666 ee_data <<= 1;
7667
7668 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7669 ee_data |= 1;
7670 }
7671
7672 ee_value &= ~(SEE_MS + SEE_CS);
7673 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7674 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7675
7676 return(ee_data);
7677}
7678
7679
7680/*---------------------------------------------------------------------
7681 *
7682 * Function: Send EE command and Address to the EEPROM
7683 *
7684 * Description: Transfers the correct command and sends the address
7685 * to the eeprom.
7686 *
7687 *---------------------------------------------------------------------*/
7688
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007689static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007690{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007691 unsigned char ee_value;
7692 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007693
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007694 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007695
7696
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007697 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007698
7699
7700 ee_value = SEE_MS;
7701 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7702
7703 ee_value |= SEE_CS; /* Set CS to EEPROM */
7704 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7705
7706
7707 for(i = 0x04; i != 0; i>>=1) {
7708
7709 if (i & ee_cmd)
7710 ee_value |= SEE_DO;
7711 else
7712 ee_value &= ~SEE_DO;
7713
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 ee_value |= SEE_CLK; /* Clock data! */
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 ee_value &= ~SEE_CLK;
7720 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7721 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7722 }
7723
7724
7725 if (narrow_flg)
7726 i = 0x0080;
7727
7728 else
7729 i = 0x0200;
7730
7731
7732 while (i != 0) {
7733
7734 if (i & ee_addr)
7735 ee_value |= SEE_DO;
7736 else
7737 ee_value &= ~SEE_DO;
7738
7739 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 ee_value |= SEE_CLK; /* Clock data! */
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 ee_value &= ~SEE_CLK;
7745 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747
7748 i >>= 1;
7749 }
7750}
7751
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007752static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007753{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007754 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007755 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007756 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007757 for (i=0; i < ID_STRING_LENGTH; i++)
7758 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007759 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007760 for(j=0; j < 8; j++)
7761 {
7762 if ((crc ^ ch) & 1)
7763 crc = (crc >> 1) ^ CRCMASK;
7764 else
7765 crc >>= 1;
7766 ch >>= 1;
7767 }
7768 }
7769 return(crc);
7770}
7771
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007772static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007773{
7774 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007775 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007776 lrc = 0;
7777 for(i = 0; i < ID_STRING_LENGTH; i++)
7778 lrc ^= buffer[i];
7779 return(lrc);
7780}
7781
7782
7783
7784/*
7785 The following inline definitions avoid type conflicts.
7786*/
7787
7788static inline unsigned char
7789FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7790{
7791 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7792}
7793
7794
7795static inline FlashPoint_CardHandle_T
7796FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7797{
7798 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7799}
7800
7801static inline void
7802FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7803{
7804 FlashPoint_ReleaseHostAdapter(CardHandle);
7805}
7806
7807
7808static inline void
7809FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7810{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007811 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007812}
7813
7814
7815static inline void
7816FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7817{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007818 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007819}
7820
7821
7822static inline boolean
7823FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7824{
7825 return FlashPoint_InterruptPending(CardHandle);
7826}
7827
7828
7829static inline int
7830FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7831{
7832 return FlashPoint_HandleInterrupt(CardHandle);
7833}
7834
7835
7836#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7837#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7838#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7839#define FlashPoint_StartCCB FlashPoint__StartCCB
7840#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7841#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7842#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7843
7844
Linus Torvalds1da177e2005-04-16 15:20:36 -07007845#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7846
7847
7848/*
7849 Define prototypes for the FlashPoint SCCB Manager Functions.
7850*/
7851
7852extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7853extern FlashPoint_CardHandle_T
7854 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7855extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7856extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7857extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7858extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7859extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007860
7861
7862#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */