blob: e98bbef485b8b03e8da1103f144d4d61a397d78f [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 -070043typedef unsigned short USHORT;
44typedef unsigned int UINT;
45typedef unsigned long ULONG;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048typedef unsigned short * ushort_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#define s08bits char
52#define s16bits short
53#define s32bits long
54
55#define u08bits unsigned s08bits
56#define u16bits unsigned s16bits
57#define u32bits unsigned s32bits
58
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080061#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070062#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
63
64
65
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
James Bottomley 47b5d692005-04-24 02:38:05 -050067typedef struct _SCCB *PSCCB;
68typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70
71typedef struct SCCBMgr_info {
72 ULONG si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080073 unsigned char si_present;
74 unsigned char si_intvect;
75 unsigned char si_id;
76 unsigned char si_lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 USHORT si_fw_revision;
78 USHORT si_per_targ_init_sync;
79 USHORT si_per_targ_fast_nego;
80 USHORT si_per_targ_ultra_nego;
81 USHORT si_per_targ_no_disc;
82 USHORT si_per_targ_wide_nego;
83 USHORT si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080084 unsigned char si_card_family;
85 unsigned char si_bustype;
86 unsigned char si_card_model[3];
87 unsigned char si_relative_cardnum;
88 unsigned char si_reserved[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 ULONG si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080090 unsigned char si_XlatInfo[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 ULONG si_reserved2[5];
92 ULONG si_secondary_range;
93} SCCBMGR_INFO;
94
James Bottomley 47b5d692005-04-24 02:38:05 -050095typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97
James Bottomley 47b5d692005-04-24 02:38:05 -050098#define SCSI_PARITY_ENA 0x0001
99#define LOW_BYTE_TERM 0x0010
100#define HIGH_BYTE_TERM 0x0020
101#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103#define SUPPORT_16TAR_32LUN 0x0002
104#define SOFT_RESET 0x0004
105#define EXTENDED_TRANSLATION 0x0008
106#define POST_ALL_UNDERRRUNS 0x0040
107#define FLAG_SCAM_ENABLED 0x0080
108#define FLAG_SCAM_LEVEL2 0x0100
109
110
111
112
113#define HARPOON_FAMILY 0x02
114
115
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Alexey Dobriyan323579882006-01-15 02:12:54 +0100117/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 * The UCB Manager treats the SCCB as it's 'native hardware structure'
119 */
120
121
122#pragma pack(1)
123typedef struct _SCCB {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800124 unsigned char OperationCode;
125 unsigned char ControlByte;
126 unsigned char CdbLength;
127 unsigned char RequestSenseLength;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 ULONG DataLength;
129 ULONG DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800130 unsigned char CcbRes[2];
131 unsigned char HostStatus;
132 unsigned char TargetStatus;
133 unsigned char TargID;
134 unsigned char Lun;
135 unsigned char Cdb[12];
136 unsigned char CcbRes1;
137 unsigned char Reserved1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 ULONG Reserved2;
139 ULONG SensePointer;
140
141
142 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
143 ULONG SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800144 unsigned char SccbStatus;
145 unsigned char SCCBRes2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 USHORT SccbOSFlags;
147
148
149 ULONG Sccb_XferCnt; /* actual transfer count */
150 ULONG Sccb_ATC;
151 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
152 ULONG Sccb_res1;
153 USHORT Sccb_MGRFlags;
154 USHORT Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800155 unsigned char Sccb_scsimsg; /* identify msg for selection */
156 unsigned char Sccb_tag;
157 unsigned char Sccb_scsistat;
158 unsigned char Sccb_idmsg; /* image of last msg in */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 PSCCB Sccb_forwardlink;
160 PSCCB Sccb_backlink;
161 ULONG Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800162 unsigned char Save_Cdb[6];
163 unsigned char Save_CdbLen;
164 unsigned char Sccb_XferState;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 ULONG Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 } SCCB;
167
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
169#pragma pack()
170
171
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173#define SCATTER_GATHER_COMMAND 0x02
174#define RESIDUAL_COMMAND 0x03
175#define RESIDUAL_SG_COMMAND 0x04
176#define RESET_COMMAND 0x81
177
178
179#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
180#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181#define SCCB_DATA_XFER_OUT 0x10 /* Write */
182#define SCCB_DATA_XFER_IN 0x08 /* Read */
183
184
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
186
187
188#define BUS_FREE_ST 0
189#define SELECT_ST 1
190#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
191#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
192#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
193#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
194#define COMMAND_ST 6
195#define DATA_OUT_ST 7
196#define DATA_IN_ST 8
197#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
200
201#define F_HOST_XFER_DIR 0x01
202#define F_ALL_XFERRED 0x02
203#define F_SG_XFER 0x04
204#define F_AUTO_SENSE 0x08
205#define F_ODD_BALL_CNT 0x10
206#define F_NO_DATA_YET 0x80
207
208
209#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210#define F_DEV_SELECTED 0x04
211
212
213#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
214#define SCCB_DATA_UNDER_RUN 0x0C
215#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
216#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
220#define SCCB_BM_ERR 0x30 /* BusMaster error. */
221#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
222
223
224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225
226
227#define SCCB_IN_PROCESS 0x00
228#define SCCB_SUCCESS 0x01
229#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234#define ORION_FW_REV 3110
235
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
237
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
240#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
James Bottomley 47b5d692005-04-24 02:38:05 -0500243#define MAX_SCSI_TAR 16
244#define MAX_LUN 32
245#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250
251
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -0800252#define RD_HARPOON(ioport) inb((u32bits)ioport)
253#define RDW_HARPOON(ioport) inw((u32bits)ioport)
254#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
255#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
256#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
257#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258
259
260#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261#define SYNC_TRYING BIT(6)
262#define SYNC_SUPPORTED (BIT(7)+BIT(6))
263
264#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265#define WIDE_ENABLED BIT(4)
266#define WIDE_NEGOCIATED BIT(5)
267
268#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269#define TAG_Q_TRYING BIT(2)
270#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272#define TAR_ALLOW_DISC BIT(0)
273
274
275#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276#define EE_SYNC_5MB BIT(0)
277#define EE_SYNC_10MB BIT(1)
278#define EE_SYNC_20MB (BIT(0)+BIT(1))
279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280#define EE_WIDE_SCSI BIT(7)
281
282
James Bottomley 47b5d692005-04-24 02:38:05 -0500283typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284
285
286typedef struct SCCBMgr_tar_info {
287
288 PSCCB TarSelQ_Head;
289 PSCCB TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800290 unsigned char TarLUN_CA; /*Contingent Allgiance */
291 unsigned char TarTagQ_Cnt;
292 unsigned char TarSelQ_Cnt;
293 unsigned char TarStatus;
294 unsigned char TarEEValue;
295 unsigned char TarSyncCtrl;
296 unsigned char TarReserved[2]; /* for alignment */
297 unsigned char LunDiscQ_Idx[MAX_LUN];
298 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299} SCCBMGR_TAR_INFO;
300
301typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800302 unsigned char niModel; /* Model No. of card */
303 unsigned char niCardNo; /* Card no. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 ULONG niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800305 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
306 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
307 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
308 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
309 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
310 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311}NVRAMINFO;
312
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
315#define MODEL_LT 1
316#define MODEL_DL 2
317#define MODEL_LW 3
318#define MODEL_DW 4
319
320
321typedef struct SCCBcard {
322 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 ULONG ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
327 USHORT cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800328 unsigned char discQCount;
329 unsigned char tagQ_Lst;
330 unsigned char cardIndex;
331 unsigned char scanIndex;
332 unsigned char globalFlags;
333 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 PNVRamInfo pNvRamInfo;
335 PSCCB discQ_Tbl[QUEUE_DEPTH];
336
337}SCCBCARD;
338
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340
341
342#define F_TAG_STARTED 0x01
343#define F_CONLUN_IO 0x02
344#define F_DO_RENEGO 0x04
345#define F_NO_FILTER 0x08
346#define F_GREEN_PC 0x10
347#define F_HOST_XFER_ACT 0x20
348#define F_NEW_SCCB_CMD 0x40
349#define F_UPDATE_EEPROM 0x80
350
351
352#define ID_STRING_LENGTH 32
353#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
354
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
356#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
357
358#define ASSIGN_ID 0x00
359#define SET_P_FLAG 0x01
360#define CFG_CMPLT 0x03
361#define DOM_MSTR 0x0F
362#define SYNC_PTRN 0x1F
363
364#define ID_0_7 0x18
365#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366#define MISC_CODE 0x14
367#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369
370
371#define INIT_SELTD 0x01
372#define LEVEL2_TAR 0x02
373
374
375enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
376 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
377 CLR_PRIORITY,NO_ID_AVAIL };
378
379typedef struct SCCBscam_info {
380
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800381 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 enum scam_id_st state;
383
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800384} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388#define SCSI_READ 0x08
389#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391#define SCSI_READ_EXTENDED 0x28
392#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
395
396
397#define SSGOOD 0x00
398#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399#define SSQ_FULL 0x28
400
401
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
403
404#define SMCMD_COMP 0x00
405#define SMEXT 0x01
406#define SMSAVE_DATA_PTR 0x02
407#define SMREST_DATA_PTR 0x03
408#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409#define SMABORT 0x06
410#define SMREJECT 0x07
411#define SMNO_OP 0x08
412#define SMPARITY 0x09
413#define SMDEV_RESET 0x0C
414#define SMABORT_TAG 0x0D
415#define SMINIT_RECOVERY 0x0F
416#define SMREL_RECOVERY 0x10
417
418#define SMIDENT 0x80
419#define DISC_PRIV 0x40
420
421
422#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423#define SMWDTR 0x03
424#define SM8BIT 0x00
425#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426#define SMIGNORWR 0x23 /* Ignore Wide Residue */
427
428
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430
431
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
433
434
435#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436#define TWELVE_BYTE_CMD 0x0C
437
438#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
440
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
442#define EEPROM_WD_CNT 256
443
444#define EEPROM_CHECK_SUM 0
445#define FW_SIGNATURE 2
446#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449#define SYSTEM_CONFIG 16
450#define SCSI_CONFIG 17
451#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452#define SCAM_CONFIG 20
453#define ADAPTER_SCSI_ID 24
454
455
456#define IGNORE_B_SCAN 32
457#define SEND_START_ENA 34
458#define DEVICE_ENABLE 36
459
460#define SYNC_RATE_TBL 38
461#define SYNC_RATE_TBL01 38
462#define SYNC_RATE_TBL23 40
463#define SYNC_RATE_TBL45 42
464#define SYNC_RATE_TBL67 44
465#define SYNC_RATE_TBL89 46
466#define SYNC_RATE_TBLab 48
467#define SYNC_RATE_TBLcd 50
468#define SYNC_RATE_TBLef 52
469
470
471
472#define EE_SCAMBASE 256
473
474
475
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 #define SCAM_ENABLED BIT(2)
477 #define SCAM_LEVEL2 BIT(3)
478
479
480 #define RENEGO_ENA BITW(10)
481 #define CONNIO_ENA BITW(11)
482 #define GREEN_PC_ENA BITW(12)
483
484
485 #define AUTO_RATE_00 00
486 #define AUTO_RATE_05 01
487 #define AUTO_RATE_10 02
488 #define AUTO_RATE_20 03
489
490 #define WIDE_NEGO_BIT BIT(7)
491 #define DISC_ENABLE_BIT BIT(6)
492
493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494
495 #define hp_vendor_id_0 0x00 /* LSB */
496 #define ORION_VEND_0 0x4B
497
498 #define hp_vendor_id_1 0x01 /* MSB */
499 #define ORION_VEND_1 0x10
500
501 #define hp_device_id_0 0x02 /* LSB */
502 #define ORION_DEV_0 0x30
503
504 #define hp_device_id_1 0x03 /* MSB */
505 #define ORION_DEV_1 0x81
506
507 /* Sub Vendor ID and Sub Device ID only available in
508 Harpoon Version 2 and higher */
509
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
514 #define hp_semaphore 0x0C
515 #define SCCB_MGR_ACTIVE BIT(0)
516 #define TICKLE_ME BIT(1)
517 #define SCCB_MGR_PRESENT BIT(3)
518 #define BIOS_IN_USE BIT(4)
519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
522 #define hp_sys_ctrl 0x0F
523
524 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
525 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
526 #define HALT_MACH BIT(3) /*Halt State Machine */
527 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800533
534
535
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
537 #define hp_host_blk_cnt 0x13
538
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
540
541 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
542
543
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
545 #define hp_int_mask 0x17
546
547 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
548 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550
551 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 #define hp_xfer_cnt_hi 0x1A
553 #define hp_xfer_cmd 0x1B
554
555 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
556 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
558
559 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560
561 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
563 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
564
565 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
566 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
568 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 #define hp_ee_ctrl 0x22
572
573 #define EXT_ARB_ACK BIT(7)
574 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
575 #define SEE_MS BIT(5)
576 #define SEE_CS BIT(3)
577 #define SEE_CLK BIT(2)
578 #define SEE_DO BIT(1)
579 #define SEE_DI BIT(0)
580
581 #define EE_READ 0x06
582 #define EE_WRITE 0x05
583 #define EWEN 0x04
584 #define EWEN_ADDR 0x03C0
585 #define EWDS 0x04
586 #define EWDS_ADDR 0x0000
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
591
592
593
594 #define hp_bm_ctrl 0x26
595
596 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
597 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
599 #define FAST_SINGLE BIT(6) /*?? */
600
601 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
604 #define hp_sg_addr 0x28
605 #define hp_page_ctrl 0x29
606
607 #define SCATTER_EN BIT(0)
608 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
610 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
611
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_pci_stat_cfg 0x2D
616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625
626 #define hp_rev_num 0x33
627
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628
629 #define hp_stack_data 0x34
630 #define hp_stack_addr 0x35
631
632 #define hp_ext_status 0x36
633
634 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
635 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
636 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 #define CMD_ABORTED BIT(4) /*Command aborted */
638 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
639 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
640 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
641 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
642 BM_PARITY_ERR | PIO_OVERRUN)
643
644 #define hp_int_status 0x37
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
647 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
650
651 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653
654
655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 #define hp_intena 0x40
657
658 #define RESET BITW(7)
659 #define PROG_HLT BITW(6)
660 #define PARITY BITW(5)
661 #define FIFO BITW(4)
662 #define SEL BITW(3)
663 #define SCAM_SEL BITW(2)
664 #define RSEL BITW(1)
665 #define TIMEOUT BITW(0)
666 #define BUS_FREE BITW(15)
667 #define XFER_CNT_0 BITW(14)
668 #define PHASE BITW(13)
669 #define IUNKWN BITW(12)
670 #define ICMD_COMP BITW(11)
671 #define ITICKLE BITW(10)
672 #define IDO_STRT BITW(9)
673 #define ITAR_DISC BITW(8)
674 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
675 #define CLR_ALL_INT 0xFFFF
676 #define CLR_ALL_INT_1 0xFF00
677
678 #define hp_intstat 0x42
679
680 #define hp_scsisig 0x44
681
682 #define SCSI_SEL BIT(7)
683 #define SCSI_BSY BIT(6)
684 #define SCSI_REQ BIT(5)
685 #define SCSI_ACK BIT(4)
686 #define SCSI_ATN BIT(3)
687 #define SCSI_CD BIT(2)
688 #define SCSI_MSG BIT(1)
689 #define SCSI_IOBIT BIT(0)
690
691 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
694 #define S_DATAI_PH ( BIT(0))
695 #define S_DATAO_PH 0x00
696 #define S_ILL_PH ( BIT(1) )
697
698 #define hp_scsictrl_0 0x45
699
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 #define SEL_TAR BIT(6)
701 #define ENA_ATN BIT(4)
702 #define ENA_RESEL BIT(2)
703 #define SCSI_RST BIT(1)
704 #define ENA_SCAM_SEL BIT(0)
705
706
707
708 #define hp_portctrl_0 0x46
709
710 #define SCSI_PORT BIT(7)
711 #define SCSI_INBIT BIT(6)
712 #define DMA_PORT BIT(5)
713 #define DMA_RD BIT(4)
714 #define HOST_PORT BIT(3)
715 #define HOST_WRT BIT(2)
716 #define SCSI_BUS_EN BIT(1)
717 #define START_TO BIT(0)
718
719 #define hp_scsireset 0x47
720
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 #define SCSI_INI BIT(6)
722 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 #define DMA_RESET BIT(3)
724 #define HPSCSI_RESET BIT(2)
725 #define PROG_RESET BIT(1)
726 #define FIFO_CLR BIT(0)
727
728 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 #define hp_addstat 0x4E
733
734 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 #define SCSI_MODE8 BIT(3)
736 #define SCSI_PAR_ERR BIT(0)
737
738 #define hp_prgmcnt_0 0x4F
739
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 #define hp_selfid_0 0x50
742 #define hp_selfid_1 0x51
743 #define hp_arb_id 0x52
744
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745
746 #define hp_select_id 0x53
747
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748
749 #define hp_synctarg_base 0x54
750 #define hp_synctarg_12 0x54
751 #define hp_synctarg_13 0x55
752 #define hp_synctarg_14 0x56
753 #define hp_synctarg_15 0x57
754
755 #define hp_synctarg_8 0x58
756 #define hp_synctarg_9 0x59
757 #define hp_synctarg_10 0x5A
758 #define hp_synctarg_11 0x5B
759
760 #define hp_synctarg_4 0x5C
761 #define hp_synctarg_5 0x5D
762 #define hp_synctarg_6 0x5E
763 #define hp_synctarg_7 0x5F
764
765 #define hp_synctarg_0 0x60
766 #define hp_synctarg_1 0x61
767 #define hp_synctarg_2 0x62
768 #define hp_synctarg_3 0x63
769
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 #define DEFAULT_OFFSET 0x0F
772
773 #define hp_autostart_0 0x64
774 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 #define hp_autostart_3 0x67
776
777
778
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 #define AUTO_IMMED BIT(5)
780 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782
783 #define hp_gp_reg_0 0x68
784 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 #define hp_gp_reg_3 0x6B
786
787 #define hp_seltimeout 0x6C
788
789
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 #define TO_4ms 0x67 /* 3.9959ms */
791
792 #define TO_5ms 0x03 /* 4.9152ms */
793 #define TO_10ms 0x07 /* 11.xxxms */
794 #define TO_250ms 0x99 /* 250.68ms */
795 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796
797 #define hp_clkctrl_0 0x6D
798
799 #define PWR_DWN BIT(6)
800 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
804
805 #define hp_fiforead 0x6E
806 #define hp_fifowrite 0x6F
807
808 #define hp_offsetctr 0x70
809 #define hp_xferstat 0x71
810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
813 #define hp_portctrl_1 0x72
814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 #define CHK_SCSI_P BIT(3)
816 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
818 #define hp_xfer_pad 0x73
819
820 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
822 #define hp_scsidata_0 0x74
823 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
827 #define hp_aramBase 0x80
828 #define BIOS_DATA_OFFSET 0x60
829 #define BIOS_RELATIVE_CARD 0x64
830
831
832
833
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 #define AR3 (BITW(9) + BITW(8))
835 #define SDATA BITW(10)
836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
839
840 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
841
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843
844 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
845
846 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
847
848
849 #define ADATA_OUT 0x00
850 #define ADATA_IN BITW(8)
851 #define ACOMMAND BITW(10)
852 #define ASTATUS (BITW(10)+BITW(8))
853 #define AMSG_OUT (BITW(10)+BITW(9))
854 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
856
857 #define BRH_OP BITW(13) /* Branch */
858
859
860 #define ALWAYS 0x00
861 #define EQUAL BITW(8)
862 #define NOT_EQ BITW(9)
863
864 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
865
866
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
869
870 #define MPM_OP BITW(15) /* Match phase and move data */
871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
873 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
874
875
876 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
877
878
879 #define D_AR0 0x00
880 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
882
883
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
890
891 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
892
893 #define SSI_OP (BITW(15)+BITW(11))
894
895
896 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
897 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
899 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
900 #define SSI_ITICKLE (ITICKLE >> 8)
901
902 #define SSI_IUNKWN (IUNKWN >> 8)
903 #define SSI_INO_CC (IUNKWN >> 8)
904 #define SSI_IRFAIL (IUNKWN >> 8)
905
906
907 #define NP 0x10 /*Next Phase */
908 #define NTCMD 0x02 /*Non- Tagged Command start */
909 #define CMDPZ 0x04 /*Command phase */
910 #define DINT 0x12 /*Data Out/In interrupt */
911 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 #define DC 0x19 /*Disconnect Message */
913 #define ST 0x1D /*Status Phase */
914 #define UNKNWN 0x24 /*Unknown bus action */
915 #define CC 0x25 /*Command Completion failure */
916 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
918
919
920 #define ID_MSG_STRT hp_aramBase + 0x00
921 #define NON_TAG_ID_MSG hp_aramBase + 0x06
922 #define CMD_STRT hp_aramBase + 0x08
923 #define SYNC_MSGS hp_aramBase + 0x08
924
925
926
927
928
929 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 #define DISCONNECT_START 0x10/2
931 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 #define SELCHK_STRT SELCHK/2
934
935
936
937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
939
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800941
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
943#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
944/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
945 xfercnt <<= 16,\
946 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
947 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
949 addr >>= 16,\
950 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
951 WR_HARP32(port,hp_xfercnt_0,count),\
952 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
953 count >>= 16,\
954 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
956#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
957 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
958
959
960#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
961 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
962
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
965#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
966 WR_HARPOON(port+hp_scsireset, 0x00))
967
968#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
969 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
970
971#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
972 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
973
974#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
975 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
976
977#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
978 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
979
980
981
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800983static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
984static void FPT_ssel(ULONG port, unsigned char p_card);
985static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
986static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
987static void FPT_stsyncn(ULONG port, unsigned char p_card);
988static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
989static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500990 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800991static void FPT_sresb(ULONG port, unsigned char p_card);
992static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
993static void FPT_schkdd(ULONG port, unsigned char p_card);
994static unsigned char FPT_RdStack(ULONG port, unsigned char index);
995static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
996static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800998static void FPT_SendMsg(ULONG port, unsigned char message);
999static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
1000 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001002static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001003static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001005static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1006static void FPT_stwidn(ULONG port, unsigned char p_card);
1007static void FPT_siwidr(ULONG port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001010static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1011static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001012static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001013 unsigned char p_card);
1014static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1015static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1016static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1017static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001018static void FPT_utilUpdateResidual(PSCCB p_SCCB);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001019static USHORT FPT_CalcCrc16(unsigned char buffer[]);
1020static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
1022
James Bottomley 47b5d692005-04-24 02:38:05 -05001023static void FPT_Wait1Second(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001024static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1025static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
James Bottomley 47b5d692005-04-24 02:38:05 -05001026static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1027static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1028static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001029static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, USHORT ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
1031
1032
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001033static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1034static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1035static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1036static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1037static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1038static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1039static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001041static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1042static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1043static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044
1045
1046
1047
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001048static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
James Bottomley 47b5d692005-04-24 02:38:05 -05001049static void FPT_BusMasterInit(ULONG p_port);
1050static void FPT_DiagEEPROM(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
1052
1053
1054
James Bottomley 47b5d692005-04-24 02:38:05 -05001055static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1056static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1057static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001058static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
James Bottomley 47b5d692005-04-24 02:38:05 -05001059static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001062static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
James Bottomley 47b5d692005-04-24 02:38:05 -05001063 PSCCBcard pCurrCard, USHORT p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
James Bottomley 47b5d692005-04-24 02:38:05 -05001065static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001066static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1067static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069
1070
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001071static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001073static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
James Bottomley 47b5d692005-04-24 02:38:05 -05001074static void FPT_scbusf(ULONG p_port);
1075static void FPT_scsel(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001076static void FPT_scasid(unsigned char p_card, ULONG p_port);
1077static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1078static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1079static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1080static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1081static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1082static unsigned char FPT_scvalq(unsigned char p_quintet);
1083static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
James Bottomley 47b5d692005-04-24 02:38:05 -05001084static void FPT_scwtsel(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001085static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1086static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1087static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001090static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001091static void FPT_autoLoadDefaultMap(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
1093
1094
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
James Bottomley 47b5d692005-04-24 02:38:05 -05001096static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1097static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1098static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1099static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
1101
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001102static unsigned char FPT_mbCards = 0;
1103static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001104 ' ', 'B', 'T', '-', '9', '3', '0', \
1105 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1106 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
James Bottomley 47b5d692005-04-24 02:38:05 -05001108static USHORT FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
1110
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001111static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
1114/*---------------------------------------------------------------------
1115 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001116 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 *
1118 * Description: Setup and/or Search for cards and return info to caller.
1119 *
1120 *---------------------------------------------------------------------*/
1121
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001122static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001124 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001126 unsigned char i,j,id,ScamFlg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 USHORT temp,temp2,temp3,temp4,temp5,temp6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 PNVRamInfo pCurrNvRam;
1130
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132
1133
1134 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1135 return((int)FAILURE);
1136
1137 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1138 return((int)FAILURE);
1139
1140 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1141 return((int)FAILURE);
1142
1143 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1144 return((int)FAILURE);
1145
1146
1147 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1148
1149/* For new Harpoon then check for sub_device ID LSB
1150 the bits(0-3) must be all ZERO for compatible with
1151 current version of SCCBMgr, else skip this Harpoon
1152 device. */
1153
1154 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1155 return((int)FAILURE);
1156 }
1157
1158 if (first_time)
1159 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001160 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001162 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 }
1164
James Bottomley 47b5d692005-04-24 02:38:05 -05001165 if(FPT_RdStack(ioport, 0) != 0x00) {
1166 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 {
1168 pCurrNvRam = NULL;
1169 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001170 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1171 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 }
1173 else
1174 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001175 if(FPT_mbCards < MAX_MB_CARDS) {
1176 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1177 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001179 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 }else
1181 return((int) FAILURE);
1182 }
1183 }else
1184 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
1186 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1187 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1188
1189 if(pCurrNvRam)
1190 pCardInfo->si_id = pCurrNvRam->niAdapId;
1191 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001192 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1193 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
1195 pCardInfo->si_lun = 0x00;
1196 pCardInfo->si_fw_revision = ORION_FW_REV;
1197 temp2 = 0x0000;
1198 temp3 = 0x0000;
1199 temp4 = 0x0000;
1200 temp5 = 0x0000;
1201 temp6 = 0x0000;
1202
1203 for (id = 0; id < (16/2); id++) {
1204
1205 if(pCurrNvRam){
1206 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1207 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1208 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1209 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001210 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
1212 for (i = 0; i < 2; temp >>=8,i++) {
1213
1214 temp2 >>= 1;
1215 temp3 >>= 1;
1216 temp4 >>= 1;
1217 temp5 >>= 1;
1218 temp6 >>= 1;
1219 switch (temp & 0x3)
1220 {
1221 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1222 temp6 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1224 temp5 |= 0x8000; /* Fall through */
1225 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1226 temp2 |= 0x8000; /* Fall through */
1227 case AUTO_RATE_00: /* Asynchronous */
1228 break;
1229 }
1230
1231 if (temp & DISC_ENABLE_BIT)
1232 temp3 |= 0x8000;
1233
1234 if (temp & WIDE_NEGO_BIT)
1235 temp4 |= 0x8000;
1236
1237 }
1238 }
1239
1240 pCardInfo->si_per_targ_init_sync = temp2;
1241 pCardInfo->si_per_targ_no_disc = temp3;
1242 pCardInfo->si_per_targ_wide_nego = temp4;
1243 pCardInfo->si_per_targ_fast_nego = temp5;
1244 pCardInfo->si_per_targ_ultra_nego = temp6;
1245
1246 if(pCurrNvRam)
1247 i = pCurrNvRam->niSysConf;
1248 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001249 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250
1251 if(pCurrNvRam)
1252 ScamFlg = pCurrNvRam->niScamConf;
1253 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001254 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
1256 pCardInfo->si_flags = 0x0000;
1257
1258 if (i & 0x01)
1259 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1260
1261 if (!(i & 0x02))
1262 pCardInfo->si_flags |= SOFT_RESET;
1263
1264 if (i & 0x10)
1265 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1266
1267 if (ScamFlg & SCAM_ENABLED)
1268 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1269
1270 if (ScamFlg & SCAM_LEVEL2)
1271 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1272
1273 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1274 if (i & 0x04) {
1275 j |= SCSI_TERM_ENA_L;
1276 }
1277 WR_HARPOON(ioport+hp_bm_ctrl, j );
1278
1279 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1280 if (i & 0x08) {
1281 j |= SCSI_TERM_ENA_H;
1282 }
1283 WR_HARPOON(ioport+hp_ee_ctrl, j );
1284
1285 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1286
1287 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1288
1289 pCardInfo->si_card_family = HARPOON_FAMILY;
1290 pCardInfo->si_bustype = BUSTYPE_PCI;
1291
1292 if(pCurrNvRam){
1293 pCardInfo->si_card_model[0] = '9';
1294 switch(pCurrNvRam->niModel & 0x0f){
1295 case MODEL_LT:
1296 pCardInfo->si_card_model[1] = '3';
1297 pCardInfo->si_card_model[2] = '0';
1298 break;
1299 case MODEL_LW:
1300 pCardInfo->si_card_model[1] = '5';
1301 pCardInfo->si_card_model[2] = '0';
1302 break;
1303 case MODEL_DL:
1304 pCardInfo->si_card_model[1] = '3';
1305 pCardInfo->si_card_model[2] = '2';
1306 break;
1307 case MODEL_DW:
1308 pCardInfo->si_card_model[1] = '5';
1309 pCardInfo->si_card_model[2] = '2';
1310 break;
1311 }
1312 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001313 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001314 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001315 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001317 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1318 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 }
1320
1321 if (pCardInfo->si_card_model[1] == '3')
1322 {
1323 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1324 pCardInfo->si_flags |= LOW_BYTE_TERM;
1325 }
1326 else if (pCardInfo->si_card_model[2] == '0')
1327 {
1328 temp = RD_HARPOON(ioport+hp_xfer_pad);
1329 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1330 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1331 pCardInfo->si_flags |= LOW_BYTE_TERM;
1332 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1333 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1334 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1335 WR_HARPOON(ioport+hp_xfer_pad, temp);
1336 }
1337 else
1338 {
1339 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1340 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1341 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1342 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1343 temp3 = 0;
1344 for (i = 0; i < 8; i++)
1345 {
1346 temp3 <<= 1;
1347 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1348 temp3 |= 1;
1349 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1350 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1351 }
1352 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1353 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1354 if (!(temp3 & BIT(7)))
1355 pCardInfo->si_flags |= LOW_BYTE_TERM;
1356 if (!(temp3 & BIT(6)))
1357 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1358 }
1359
1360
1361 ARAM_ACCESS(ioport);
1362
1363 for ( i = 0; i < 4; i++ ) {
1364
1365 pCardInfo->si_XlatInfo[i] =
1366 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1367 }
1368
1369 /* return with -1 if no sort, else return with
1370 logical card number sorted by BIOS (zero-based) */
1371
1372 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001373 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
1375 SGRAM_ACCESS(ioport);
1376
James Bottomley 47b5d692005-04-24 02:38:05 -05001377 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1378 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1379 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1380 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1381 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1382 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1383 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1384 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
1386 pCardInfo->si_present = 0x01;
1387
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 return(0);
1389}
1390
1391
1392/*---------------------------------------------------------------------
1393 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001394 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 *
1396 * Description: Setup adapter for normal operation (hard reset).
1397 *
1398 *---------------------------------------------------------------------*/
1399
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001400static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401{
1402 PSCCBcard CurrCard = NULL;
1403 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001404 unsigned char i,j,thisCard, ScamFlg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 USHORT temp,sync_bit_map,id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409
1410 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1411
1412 if (thisCard == MAX_CARDS) {
1413
1414 return(FAILURE);
1415 }
1416
James Bottomley 47b5d692005-04-24 02:38:05 -05001417 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
James Bottomley 47b5d692005-04-24 02:38:05 -05001419 CurrCard = &FPT_BL_Card[thisCard];
1420 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 break;
1422 }
1423
James Bottomley 47b5d692005-04-24 02:38:05 -05001424 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
James Bottomley 47b5d692005-04-24 02:38:05 -05001426 FPT_BL_Card[thisCard].ioPort = ioport;
1427 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
James Bottomley 47b5d692005-04-24 02:38:05 -05001429 if(FPT_mbCards)
1430 for(i = 0; i < FPT_mbCards; i++){
1431 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1432 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001434 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 CurrCard->cardIndex = thisCard;
1436 CurrCard->cardInfo = pCardInfo;
1437
1438 break;
1439 }
1440 }
1441
1442 pCurrNvRam = CurrCard->pNvRamInfo;
1443
1444 if(pCurrNvRam){
1445 ScamFlg = pCurrNvRam->niScamConf;
1446 }
1447 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001448 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 }
1450
1451
James Bottomley 47b5d692005-04-24 02:38:05 -05001452 FPT_BusMasterInit(ioport);
1453 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
James Bottomley 47b5d692005-04-24 02:38:05 -05001455 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
1457
1458 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1459
1460 WR_HARPOON(ioport+hp_selfid_0, id);
1461 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1462 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1463 CurrCard->ourId = pCardInfo->si_id;
1464
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001465 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 if (i & SCSI_PARITY_ENA)
1467 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1468
1469 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1470 if (i & LOW_BYTE_TERM)
1471 j |= SCSI_TERM_ENA_L;
1472 WR_HARPOON(ioport+hp_bm_ctrl, j);
1473
1474 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1475 if (i & HIGH_BYTE_TERM)
1476 j |= SCSI_TERM_ENA_H;
1477 WR_HARPOON(ioport+hp_ee_ctrl, j );
1478
1479
1480 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1481
James Bottomley 47b5d692005-04-24 02:38:05 -05001482 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483
James Bottomley 47b5d692005-04-24 02:38:05 -05001484 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 }
1486
1487
1488
1489 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1490 CurrCard->globalFlags |= F_NO_FILTER;
1491
1492 if(pCurrNvRam){
1493 if(pCurrNvRam->niSysConf & 0x10)
1494 CurrCard->globalFlags |= F_GREEN_PC;
1495 }
1496 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001497 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 CurrCard->globalFlags |= F_GREEN_PC;
1499 }
1500
1501 /* Set global flag to indicate Re-Negotiation to be done on all
1502 ckeck condition */
1503 if(pCurrNvRam){
1504 if(pCurrNvRam->niScsiConf & 0x04)
1505 CurrCard->globalFlags |= F_DO_RENEGO;
1506 }
1507 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001508 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 CurrCard->globalFlags |= F_DO_RENEGO;
1510 }
1511
1512 if(pCurrNvRam){
1513 if(pCurrNvRam->niScsiConf & 0x08)
1514 CurrCard->globalFlags |= F_CONLUN_IO;
1515 }
1516 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001517 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 CurrCard->globalFlags |= F_CONLUN_IO;
1519 }
1520
1521
1522 temp = pCardInfo->si_per_targ_no_disc;
1523
1524 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1525
1526 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001527 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 }
1529
1530 sync_bit_map = 0x0001;
1531
1532 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1533
1534 if(pCurrNvRam){
1535 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1536 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1537 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1538 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001539 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540
1541 for (i = 0; i < 2; temp >>=8,i++) {
1542
1543 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1544
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001545 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 }
1547
1548 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001549 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1550 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001551 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 }
1553
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1555 (id*2+i >= 8)){
1556*/
1557 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1558
James Bottomley 47b5d692005-04-24 02:38:05 -05001559 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
1561 }
1562
1563 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001564 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 }
1566
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 sync_bit_map <<= 1;
1569
1570
1571
1572 }
1573 }
1574
1575 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001576 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 return((ULONG)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579}
1580
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001581static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001583 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 ULONG portBase;
1585 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 PNVRamInfo pCurrNvRam;
1589
1590 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1591
1592 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001593 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1597 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
1599 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001600 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
1602 portBase = pCurrNvRam->niBaseAddr;
1603
1604 for(i = 0; i < MAX_SCSI_TAR; i++){
1605 regOffset = hp_aramBase + 64 + i*4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 scamData = *pScamTbl;
1608 WR_HARP32(portBase, regOffset, scamData);
1609 }
1610
1611 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001612 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 }
1614}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
1616
James Bottomley 47b5d692005-04-24 02:38:05 -05001617static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001619 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 ULONG portBase;
1621 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624
James Bottomley 47b5d692005-04-24 02:38:05 -05001625 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1626 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1627 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1628 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1629 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630
1631 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001632 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633
1634 portBase = pNvRamInfo->niBaseAddr;
1635
1636 for(i = 0; i < MAX_SCSI_TAR; i++){
1637 regOffset = hp_aramBase + 64 + i*4;
1638 RD_HARP32(portBase, regOffset, scamData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 *pScamTbl = scamData;
1641 }
1642
1643}
1644
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001645static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646{
1647 WR_HARPOON(portBase + hp_stack_addr, index);
1648 return(RD_HARPOON(portBase + hp_stack_data));
1649}
1650
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001651static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652{
1653 WR_HARPOON(portBase + hp_stack_addr, index);
1654 WR_HARPOON(portBase + hp_stack_data, data);
1655}
1656
1657
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001658static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659{
James Bottomley 47b5d692005-04-24 02:38:05 -05001660 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1661 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1663 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001664 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1666 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001667 return(1);
1668 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
1670}
1671/*---------------------------------------------------------------------
1672 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001673 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 *
1675 * Description: Start a command pointed to by p_Sccb. When the
1676 * command is completed it will be returned via the
1677 * callback function.
1678 *
1679 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001680static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 ULONG ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001683 unsigned char thisCard, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 PSCCB pSaveSccb;
1685 CALL_BK_FN callback;
1686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1688 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1689
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1691 {
1692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 p_Sccb->HostStatus = SCCB_COMPLETE;
1694 p_Sccb->SccbStatus = SCCB_ERROR;
1695 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1696 if (callback)
1697 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 return;
1700 }
1701
James Bottomley 47b5d692005-04-24 02:38:05 -05001702 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
1704
1705 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1706 {
1707 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1708 | SCCB_MGR_ACTIVE));
1709
1710 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1711 {
1712 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1713 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1714 }
1715 }
1716
1717 ((PSCCBcard)pCurrCard)->cmdCounter++;
1718
1719 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1720
1721 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1722 | TICKLE_ME));
1723 if(p_Sccb->OperationCode == RESET_COMMAND)
1724 {
1725 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1726 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001727 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1729 }
1730 else
1731 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001732 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 }
1734 }
1735
1736 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1737
1738 if(p_Sccb->OperationCode == RESET_COMMAND)
1739 {
1740 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1741 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001742 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1744 }
1745 else
1746 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001747 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 }
1749 }
1750
1751 else {
1752
1753 MDISABLE_INT(ioport);
1754
1755 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001756 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 lun = p_Sccb->Lun;
1758 else
1759 lun = 0;
1760 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001761 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1762 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1763 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
1765 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001766 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 }
1768
1769 else {
1770
1771 if(p_Sccb->OperationCode == RESET_COMMAND)
1772 {
1773 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1774 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001775 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1777 }
1778 else
1779 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001780 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 }
1782 }
1783
1784
1785 MENABLE_INT(ioport);
1786 }
1787
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788}
1789
1790
1791/*---------------------------------------------------------------------
1792 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001793 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 *
1795 * Description: Abort the command pointed to by p_Sccb. When the
1796 * command is completed it will be returned via the
1797 * callback function.
1798 *
1799 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001800static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001804 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001806 unsigned char TID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 PSCCB pSaveSCCB;
1808 PSCCBMgr_tar_info currTar_Info;
1809
1810
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1812
1813 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1814
James Bottomley 47b5d692005-04-24 02:38:05 -05001815 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 {
1817
James Bottomley 47b5d692005-04-24 02:38:05 -05001818 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 {
1820
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 ((PSCCBcard)pCurrCard)->cmdCounter--;
1822
1823 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1824 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001825 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 p_Sccb->SccbStatus = SCCB_ABORT;
1828 callback = p_Sccb->SccbCallback;
1829 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
1831 return(0);
1832 }
1833
1834 else
1835 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1837 {
1838 p_Sccb->SccbStatus = SCCB_ABORT;
1839 return(0);
1840
1841 }
1842
1843 else
1844 {
1845
1846 TID = p_Sccb->TargID;
1847
1848
1849 if(p_Sccb->Sccb_tag)
1850 {
1851 MDISABLE_INT(ioport);
1852 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1853 {
1854 p_Sccb->SccbStatus = SCCB_ABORT;
1855 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1857
1858 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1859 {
1860 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001861 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 }
1863 else
1864 {
1865 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1866 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001867 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1869 }
1870 }
1871 MENABLE_INT(ioport);
1872 return(0);
1873 }
1874 else
1875 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001876 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
James Bottomley 47b5d692005-04-24 02:38:05 -05001878 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 == p_Sccb)
1880 {
1881 p_Sccb->SccbStatus = SCCB_ABORT;
1882 return(0);
1883 }
1884 }
1885 }
1886 }
1887 }
1888 return(-1);
1889}
1890
1891
1892/*---------------------------------------------------------------------
1893 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001894 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 *
1896 * Description: Do a quick check to determine if there is a pending
1897 * interrupt for this card and disable the IRQ Pin if so.
1898 *
1899 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001900static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903
1904 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1905
1906 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1907 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001908 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 }
1910
1911 else
1912
James Bottomley 47b5d692005-04-24 02:38:05 -05001913 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914}
1915
1916
1917
1918/*---------------------------------------------------------------------
1919 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001920 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 *
1922 * Description: This is our entry point when an interrupt is generated
1923 * by the card and the upper level driver passes it on to
1924 * us.
1925 *
1926 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001927static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928{
1929 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001930 unsigned char thisCard,result,bm_status, bm_int_st;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 USHORT hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001932 unsigned char i, target;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
1935 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1936 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1937
1938 MDISABLE_INT(ioport);
1939
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001941 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 else
1943 bm_status = 0;
1944
1945 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1946
James Bottomley 47b5d692005-04-24 02:38:05 -05001947 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 bm_status)
1949 {
1950
1951 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1952
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001954 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1956 bm_status = 0;
1957
1958 if (result) {
1959
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 return(result);
1962 }
1963 }
1964
1965
1966 else if (hp_int & ICMD_COMP) {
1967
1968 if ( !(hp_int & BUS_FREE) ) {
1969 /* Wait for the BusFree before starting a new command. We
1970 must also check for being reselected since the BusFree
1971 may not show up if another device reselects us in 1.5us or
1972 less. SRR Wednesday, 3/8/1995.
1973 */
1974 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1975 }
1976
1977 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1978
James Bottomley 47b5d692005-04-24 02:38:05 -05001979 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980
1981/* WRW_HARPOON((ioport+hp_intstat),
1982 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1983 */
1984
1985 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1986
James Bottomley 47b5d692005-04-24 02:38:05 -05001987 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
1989 }
1990
1991
1992 else if (hp_int & ITAR_DISC)
1993 {
1994
1995 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1996
James Bottomley 47b5d692005-04-24 02:38:05 -05001997 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998
1999 }
2000
2001 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2002
2003 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2004 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2005
2006 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2007 }
2008
2009 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002010 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012 /* Wait for the BusFree before starting a new command. We
2013 must also check for being reselected since the BusFree
2014 may not show up if another device reselects us in 1.5us or
2015 less. SRR Wednesday, 3/8/1995.
2016 */
2017 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2018 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2019 RD_HARPOON((ioport+hp_scsisig)) ==
2020 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2021
2022 /*
2023 The additional loop exit condition above detects a timing problem
2024 with the revision D/E harpoon chips. The caller should reset the
2025 host adapter to recover when 0xFE is returned.
2026 */
2027 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2028 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 return 0xFE;
2031 }
2032
2033 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2034
2035
2036 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2037
2038 }
2039
2040
2041 else if (hp_int & RSEL) {
2042
2043 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2044
2045 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2046 {
2047 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2048 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002049 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 }
2051
2052 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2053 {
2054 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2055 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2056 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2057 }
2058
2059 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2060 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002061 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 }
2063
James Bottomley 47b5d692005-04-24 02:38:05 -05002064 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2065 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066
2067 }
2068
2069
2070 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2071 {
2072
2073 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002074 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075
2076 }
2077
2078
2079 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2080 {
2081 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002082 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002084 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 }
2086 else
2087 {
2088 /* Harpoon problem some SCSI target device respond to selection
2089 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2090 to latch the correct Target ID into reg. x53.
2091 The work around require to correct this reg. But when write to this
2092 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2093 need to read this reg first then restore it later. After update to 0x53 */
2094
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002095 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2096 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2097 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2098 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2099 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100 WR_HARPOON(ioport+hp_fifowrite, i);
2101 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2102 }
2103 }
2104
2105 else if (hp_int & XFER_CNT_0) {
2106
2107 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2108
James Bottomley 47b5d692005-04-24 02:38:05 -05002109 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110
2111 }
2112
2113
2114 else if (hp_int & BUS_FREE) {
2115
2116 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2117
2118 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2119
James Bottomley 47b5d692005-04-24 02:38:05 -05002120 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002121 }
2122
James Bottomley 47b5d692005-04-24 02:38:05 -05002123 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 }
2125
2126
2127 else if (hp_int & ITICKLE) {
2128
2129 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2130 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2131 }
2132
2133
2134
2135 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2136
2137
2138 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2139
2140
2141 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2142
James Bottomley 47b5d692005-04-24 02:38:05 -05002143 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 }
2145
2146 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2147 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002148 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 }
2150
2151 break;
2152
2153 }
2154
2155 } /*end while */
2156
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158
2159 return(0);
2160}
2161
2162/*---------------------------------------------------------------------
2163 *
2164 * Function: Sccb_bad_isr
2165 *
2166 * Description: Some type of interrupt has occurred which is slightly
2167 * out of the ordinary. We will now decode it fully, in
2168 * this routine. This is broken up in an attempt to save
2169 * processing time.
2170 *
2171 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002172static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
James Bottomley 47b5d692005-04-24 02:38:05 -05002173 PSCCBcard pCurrCard, USHORT p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002175 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002176 PSCCBMgr_tar_info currTar_Info;
2177 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178
2179
2180 if (RD_HARPOON(p_port+hp_ext_status) &
2181 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2182 {
2183
2184 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2185 {
2186
James Bottomley 47b5d692005-04-24 02:38:05 -05002187 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 }
2189
2190 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2191
2192 {
2193 WR_HARPOON(p_port+hp_pci_stat_cfg,
2194 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2195
2196 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2197
2198 }
2199
2200 if (pCurrCard->currentSCCB != NULL)
2201 {
2202
2203 if (!pCurrCard->currentSCCB->HostStatus)
2204 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2205
James Bottomley 47b5d692005-04-24 02:38:05 -05002206 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002208 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002210 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2212
2213 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2214 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002215 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216 }
2217 }
2218 }
2219
2220
2221 else if (p_int & RESET)
2222 {
2223
2224 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2225 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2226 if (pCurrCard->currentSCCB != NULL) {
2227
2228 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2229
James Bottomley 47b5d692005-04-24 02:38:05 -05002230 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 }
2232
2233
2234 DISABLE_AUTO(p_port);
2235
James Bottomley 47b5d692005-04-24 02:38:05 -05002236 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
2238 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2239
2240 pCurrNvRam = pCurrCard->pNvRamInfo;
2241 if(pCurrNvRam){
2242 ScamFlg = pCurrNvRam->niScamConf;
2243 }
2244 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002245 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 }
2247
James Bottomley 47b5d692005-04-24 02:38:05 -05002248 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
James Bottomley 47b5d692005-04-24 02:38:05 -05002250 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251
2252 return(0xFF);
2253 }
2254
2255
2256 else if (p_int & FIFO) {
2257
2258 WRW_HARPOON((p_port+hp_intstat), FIFO);
2259
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002261 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 }
2263
2264 else if (p_int & TIMEOUT)
2265 {
2266
2267 DISABLE_AUTO(p_port);
2268
2269 WRW_HARPOON((p_port+hp_intstat),
2270 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2271
2272 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2273
2274
James Bottomley 47b5d692005-04-24 02:38:05 -05002275 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2277 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002278 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002280 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
2282
2283 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2284 {
2285 currTar_Info->TarSyncCtrl = 0;
2286 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2287 }
2288
2289 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2290 {
2291 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2292 }
2293
James Bottomley 47b5d692005-04-24 02:38:05 -05002294 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295
James Bottomley 47b5d692005-04-24 02:38:05 -05002296 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
2298 }
2299
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300 else if (p_int & SCAM_SEL)
2301 {
2302
James Bottomley 47b5d692005-04-24 02:38:05 -05002303 FPT_scarb(p_port,LEVEL2_TAR);
2304 FPT_scsel(p_port);
2305 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306
James Bottomley 47b5d692005-04-24 02:38:05 -05002307 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308
2309 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2310 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311
2312 return(0x00);
2313}
2314
2315
2316/*---------------------------------------------------------------------
2317 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318 * Function: SccbMgrTableInit
2319 *
2320 * Description: Initialize all Sccb manager data structures.
2321 *
2322 *---------------------------------------------------------------------*/
2323
James Bottomley 47b5d692005-04-24 02:38:05 -05002324static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002326 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327
2328 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2329 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002330 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
James Bottomley 47b5d692005-04-24 02:38:05 -05002332 FPT_BL_Card[thisCard].ioPort = 0x00;
2333 FPT_BL_Card[thisCard].cardInfo = NULL;
2334 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2335 FPT_BL_Card[thisCard].ourId = 0x00;
2336 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 }
2338}
2339
2340
2341/*---------------------------------------------------------------------
2342 *
2343 * Function: SccbMgrTableInit
2344 *
2345 * Description: Initialize all Sccb manager data structures.
2346 *
2347 *---------------------------------------------------------------------*/
2348
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002349static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002351 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352
2353 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2354 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002355 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002356 }
2357
2358 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2359 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002360 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2361 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2362 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 }
2364
2365 pCurrCard->scanIndex = 0x00;
2366 pCurrCard->currentSCCB = NULL;
2367 pCurrCard->globalFlags = 0x00;
2368 pCurrCard->cmdCounter = 0x00;
2369 pCurrCard->tagQ_Lst = 0x01;
2370 pCurrCard->discQCount = 0;
2371
2372
2373}
2374
2375
2376/*---------------------------------------------------------------------
2377 *
2378 * Function: SccbMgrTableInit
2379 *
2380 * Description: Initialize all Sccb manager data structures.
2381 *
2382 *---------------------------------------------------------------------*/
2383
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002384static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385{
2386
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002387 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388 PSCCBMgr_tar_info currTar_Info;
2389
James Bottomley 47b5d692005-04-24 02:38:05 -05002390 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391
2392 currTar_Info->TarSelQ_Cnt = 0;
2393 currTar_Info->TarSyncCtrl = 0;
2394
2395 currTar_Info->TarSelQ_Head = NULL;
2396 currTar_Info->TarSelQ_Tail = NULL;
2397 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002398 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
2400
2401 for (lun = 0; lun < MAX_LUN; lun++)
2402 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002403 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404 currTar_Info->LunDiscQ_Idx[lun] = 0;
2405 }
2406
2407 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2408 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002409 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002411 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002413 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2414 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 }
2416 }
2417 }
2418}
2419
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420
2421/*---------------------------------------------------------------------
2422 *
2423 * Function: sfetm
2424 *
2425 * Description: Read in a message byte from the SCSI bus, and check
2426 * for a parity error.
2427 *
2428 *---------------------------------------------------------------------*/
2429
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002430static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002432 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 USHORT TimeOutLoop;
2434
2435 TimeOutLoop = 0;
2436 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2437 (TimeOutLoop++ < 20000) ){}
2438
2439
2440 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2441
2442 message = RD_HARPOON(port+hp_scsidata_0);
2443
2444 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2445
2446
2447 if (TimeOutLoop > 20000)
2448 message = 0x00; /* force message byte = 0 if Time Out on Req */
2449
2450 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2451 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2452 {
2453 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2454 WR_HARPOON(port+hp_xferstat, 0);
2455 WR_HARPOON(port+hp_fiforead, 0);
2456 WR_HARPOON(port+hp_fifowrite, 0);
2457 if (pCurrSCCB != NULL)
2458 {
2459 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2460 }
2461 message = 0x00;
2462 do
2463 {
2464 ACCEPT_MSG_ATN(port);
2465 TimeOutLoop = 0;
2466 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2467 (TimeOutLoop++ < 20000) ){}
2468 if (TimeOutLoop > 20000)
2469 {
2470 WRW_HARPOON((port+hp_intstat), PARITY);
2471 return(message);
2472 }
2473 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2474 {
2475 WRW_HARPOON((port+hp_intstat), PARITY);
2476 return(message);
2477 }
2478 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2479
2480 RD_HARPOON(port+hp_scsidata_0);
2481
2482 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2483
2484 }while(1);
2485
2486 }
2487 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2488 WR_HARPOON(port+hp_xferstat, 0);
2489 WR_HARPOON(port+hp_fiforead, 0);
2490 WR_HARPOON(port+hp_fifowrite, 0);
2491 return(message);
2492}
2493
2494
2495/*---------------------------------------------------------------------
2496 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002497 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 *
2499 * Description: Load up automation and select target device.
2500 *
2501 *---------------------------------------------------------------------*/
2502
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002503static void FPT_ssel(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504{
2505
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002506 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509 PSCCBcard CurrCard;
2510 PSCCB currSCCB;
2511 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002512 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513
James Bottomley 47b5d692005-04-24 02:38:05 -05002514 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 currSCCB = CurrCard->currentSCCB;
2516 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002517 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518 lastTag = CurrCard->tagQ_Lst;
2519
2520 ARAM_ACCESS(port);
2521
2522
2523 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2524 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2525
2526 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2527 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2528
2529 lun = currSCCB->Lun;
2530 else
2531 lun = 0;
2532
2533
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534 if (CurrCard->globalFlags & F_TAG_STARTED)
2535 {
2536 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2537 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002538 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2540 == TAG_Q_TRYING))
2541 {
2542
2543 if (currTar_Info->TarTagQ_Cnt !=0)
2544 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002545 currTar_Info->TarLUNBusy[lun] = 1;
2546 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547 SGRAM_ACCESS(port);
2548 return;
2549 }
2550
2551 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002552 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002553 }
2554
2555 } /*End non-tagged */
2556
2557 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002558 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559 }
2560
2561 } /*!Use cmd Q Tagged */
2562
2563 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002564 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002566 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 SGRAM_ACCESS(port);
2568 return;
2569 }
2570
James Bottomley 47b5d692005-04-24 02:38:05 -05002571 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572
2573 } /*else use cmd Q tagged */
2574
2575 } /*if glob tagged started */
2576
2577 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002578 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 }
2580
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581
2582
2583 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2584 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2585 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2586 {
2587 if(CurrCard->discQCount >= QUEUE_DEPTH)
2588 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002589 currTar_Info->TarLUNBusy[lun] = 1;
2590 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591 SGRAM_ACCESS(port);
2592 return;
2593 }
2594 for (i = 1; i < QUEUE_DEPTH; i++)
2595 {
2596 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2597 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2598 {
2599 CurrCard->tagQ_Lst = lastTag;
2600 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2601 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2602 CurrCard->discQCount++;
2603 break;
2604 }
2605 }
2606 if(i == QUEUE_DEPTH)
2607 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002608 currTar_Info->TarLUNBusy[lun] = 1;
2609 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 SGRAM_ACCESS(port);
2611 return;
2612 }
2613 }
2614
2615
2616
James Bottomley 47b5d692005-04-24 02:38:05 -05002617 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618
2619 WR_HARPOON(port+hp_select_id, target);
2620 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2621
2622 if (currSCCB->OperationCode == RESET_COMMAND) {
2623 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2624 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2625
2626 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2627
2628 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2629
2630 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002631 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2633
2634 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2635 {
2636 currTar_Info->TarSyncCtrl = 0;
2637 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2638 }
2639
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2641 {
2642 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2643 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644
James Bottomley 47b5d692005-04-24 02:38:05 -05002645 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2646 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647
2648 }
2649
2650 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2651 {
2652 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2653 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2654
2655 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2656
2657 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002658 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2659 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 WRW_HARPOON((port+SYNC_MSGS+2),
2661 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2662 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2663
2664 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002665 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
2667 }
2668
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002670 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2672 }
2673
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2675 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002676 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2678 }
2679
2680
2681 if (!auto_loaded)
2682 {
2683
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 if (currSCCB->ControlByte & F_USE_CMD_Q)
2685 {
2686
2687 CurrCard->globalFlags |= F_TAG_STARTED;
2688
2689 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2690 == TAG_Q_REJECT)
2691 {
2692 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2693
2694 /* Fix up the start instruction with a jump to
2695 Non-Tag-CMD handling */
2696 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2697
2698 WRW_HARPOON((port+NON_TAG_ID_MSG),
2699 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2700
2701 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2702
2703 /* Setup our STATE so we know what happend when
2704 the wheels fall off. */
2705 currSCCB->Sccb_scsistat = SELECT_ST;
2706
James Bottomley 47b5d692005-04-24 02:38:05 -05002707 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 }
2709
2710 else
2711 {
2712 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2713
2714 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002715 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2716 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717
2718 for (i = 1; i < QUEUE_DEPTH; i++)
2719 {
2720 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2721 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2722 {
2723 WRW_HARPOON((port+ID_MSG_STRT+6),
2724 (MPM_OP+AMSG_OUT+lastTag));
2725 CurrCard->tagQ_Lst = lastTag;
2726 currSCCB->Sccb_tag = lastTag;
2727 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2728 CurrCard->discQCount++;
2729 break;
2730 }
2731 }
2732
2733
2734 if ( i == QUEUE_DEPTH )
2735 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002736 currTar_Info->TarLUNBusy[lun] = 1;
2737 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 SGRAM_ACCESS(port);
2739 return;
2740 }
2741
2742 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2743
2744 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2745 }
2746 }
2747
2748 else
2749 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
2751 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2752
2753 WRW_HARPOON((port+NON_TAG_ID_MSG),
2754 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2755
2756 currSCCB->Sccb_scsistat = SELECT_ST;
2757
2758 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760
2761
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002762 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763
2764 cdb_reg = port + CMD_STRT;
2765
2766 for (i=0; i < currSCCB->CdbLength; i++)
2767 {
2768 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2769 cdb_reg +=2;
2770 theCCB++;
2771 }
2772
2773 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2774 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2775
2776 } /* auto_loaded */
2777
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2779 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
2781 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2782
2783 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2784
2785
2786 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2787 {
2788 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2789 }
2790 else
2791 {
2792
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002793/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 auto_loaded |= AUTO_IMMED; */
2795 auto_loaded = AUTO_IMMED;
2796
2797 DISABLE_AUTO(port);
2798
2799 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2800 }
2801
2802 SGRAM_ACCESS(port);
2803}
2804
2805
2806/*---------------------------------------------------------------------
2807 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002808 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809 *
2810 * Description: Hookup the correct CCB and handle the incoming messages.
2811 *
2812 *---------------------------------------------------------------------*/
2813
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002814static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815{
2816
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002817 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
2819
2820 PSCCBMgr_tar_info currTar_Info;
2821 PSCCB currSCCB;
2822
2823
2824
2825
2826 if(pCurrCard->currentSCCB != NULL)
2827 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002828 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 DISABLE_AUTO(port);
2830
2831
2832 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2833
2834
2835 currSCCB = pCurrCard->currentSCCB;
2836 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2837 {
2838 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2839 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2840 }
2841 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2842 {
2843 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2844 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2845 }
2846 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2847 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2848 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002849 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 if(currSCCB->Sccb_scsistat != ABORT_ST)
2851 {
2852 pCurrCard->discQCount--;
2853 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2854 = NULL;
2855 }
2856 }
2857 else
2858 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002859 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 if(currSCCB->Sccb_tag)
2861 {
2862 if(currSCCB->Sccb_scsistat != ABORT_ST)
2863 {
2864 pCurrCard->discQCount--;
2865 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2866 }
2867 }else
2868 {
2869 if(currSCCB->Sccb_scsistat != ABORT_ST)
2870 {
2871 pCurrCard->discQCount--;
2872 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2873 }
2874 }
2875 }
2876
James Bottomley 47b5d692005-04-24 02:38:05 -05002877 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 }
2879
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881
2882
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002883 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002884 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885
2886
2887 msgRetryCount = 0;
2888 do
2889 {
2890
James Bottomley 47b5d692005-04-24 02:38:05 -05002891 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 tag = 0;
2893
2894
2895 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2896 {
2897 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2898 {
2899
2900 WRW_HARPOON((port+hp_intstat), PHASE);
2901 return;
2902 }
2903 }
2904
2905 WRW_HARPOON((port+hp_intstat), PHASE);
2906 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2907 {
2908
James Bottomley 47b5d692005-04-24 02:38:05 -05002909 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910 if (message)
2911 {
2912
2913 if (message <= (0x80 | LUN_MASK))
2914 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002915 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2918 {
2919 if (currTar_Info->TarTagQ_Cnt != 0)
2920 {
2921
2922 if (!(currTar_Info->TarLUN_CA))
2923 {
2924 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2925
2926
James Bottomley 47b5d692005-04-24 02:38:05 -05002927 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 if (message)
2929 {
2930 ACCEPT_MSG(port);
2931 }
2932
2933 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002934 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935
James Bottomley 47b5d692005-04-24 02:38:05 -05002936 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002938 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939
2940 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002941 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 }
2943
2944 } /*C.A. exists! */
2945
2946 } /*End Q cnt != 0 */
2947
2948 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949
2950 } /*End valid ID message. */
2951
2952 else
2953 {
2954
2955 ACCEPT_MSG_ATN(port);
2956 }
2957
2958 } /* End good id message. */
2959
2960 else
2961 {
2962
James Bottomley 47b5d692005-04-24 02:38:05 -05002963 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 }
2965 }
2966 else
2967 {
2968 ACCEPT_MSG_ATN(port);
2969
2970 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2971 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2972 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2973
2974 return;
2975 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976
James Bottomley 47b5d692005-04-24 02:38:05 -05002977 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 {
2979 msgRetryCount++;
2980 if(msgRetryCount == 1)
2981 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002982 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 }
2984 else
2985 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002986 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987
James Bottomley 47b5d692005-04-24 02:38:05 -05002988 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989
James Bottomley 47b5d692005-04-24 02:38:05 -05002990 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991 {
2992
James Bottomley 47b5d692005-04-24 02:38:05 -05002993 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994
2995 }
2996
James Bottomley 47b5d692005-04-24 02:38:05 -05002997 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 {
2999
James Bottomley 47b5d692005-04-24 02:38:05 -05003000 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 }
3002
3003
James Bottomley 47b5d692005-04-24 02:38:05 -05003004 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3005 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006 return;
3007 }
3008 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003009 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010
3011
3012
3013 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3014 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3015 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003016 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3018 if(pCurrCard->currentSCCB != NULL)
3019 {
3020 ACCEPT_MSG(port);
3021 }
3022 else
3023 {
3024 ACCEPT_MSG_ATN(port);
3025 }
3026 }
3027 else
3028 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003029 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030
3031
3032 if (tag)
3033 {
3034 if (pCurrCard->discQ_Tbl[tag] != NULL)
3035 {
3036 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3037 currTar_Info->TarTagQ_Cnt--;
3038 ACCEPT_MSG(port);
3039 }
3040 else
3041 {
3042 ACCEPT_MSG_ATN(port);
3043 }
3044 }else
3045 {
3046 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3047 if(pCurrCard->currentSCCB != NULL)
3048 {
3049 ACCEPT_MSG(port);
3050 }
3051 else
3052 {
3053 ACCEPT_MSG_ATN(port);
3054 }
3055 }
3056 }
3057
3058 if(pCurrCard->currentSCCB != NULL)
3059 {
3060 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3061 {
3062 /* During Abort Tag command, the target could have got re-selected
3063 and completed the command. Check the select Q and remove the CCB
3064 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003065 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 }
3067 }
3068
3069
3070 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3071 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3072 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3073}
3074
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003075static void FPT_SendMsg(ULONG port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076{
3077 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3078 {
3079 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3080 {
3081
3082 WRW_HARPOON((port+hp_intstat), PHASE);
3083 return;
3084 }
3085 }
3086
3087 WRW_HARPOON((port+hp_intstat), PHASE);
3088 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3089 {
3090 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3091
3092
3093 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3094
3095 WR_HARPOON(port+hp_scsidata_0,message);
3096
3097 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3098
3099 ACCEPT_MSG(port);
3100
3101 WR_HARPOON(port+hp_portctrl_0, 0x00);
3102
3103 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3104 (message == SMABORT_TAG) )
3105 {
3106 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3107
3108 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3109 {
3110 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3111 }
3112 }
3113 }
3114}
3115
3116/*---------------------------------------------------------------------
3117 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003118 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 *
3120 * Description: Determine the proper responce to the message from the
3121 * target device.
3122 *
3123 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003124static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125{
3126 PSCCB currSCCB;
3127 PSCCBcard CurrCard;
3128 PSCCBMgr_tar_info currTar_Info;
3129
James Bottomley 47b5d692005-04-24 02:38:05 -05003130 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 currSCCB = CurrCard->currentSCCB;
3132
James Bottomley 47b5d692005-04-24 02:38:05 -05003133 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134
3135 if (message == SMREST_DATA_PTR)
3136 {
3137 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3138 {
3139 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3140
James Bottomley 47b5d692005-04-24 02:38:05 -05003141 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 }
3143
3144 ACCEPT_MSG(port);
3145 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3146 }
3147
3148 else if (message == SMCMD_COMP)
3149 {
3150
3151
3152 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3153 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003154 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3155 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156 }
3157
3158 ACCEPT_MSG(port);
3159
3160 }
3161
3162 else if ((message == SMNO_OP) || (message >= SMIDENT)
3163 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3164 {
3165
3166 ACCEPT_MSG(port);
3167 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3168 }
3169
3170 else if (message == SMREJECT)
3171 {
3172
3173 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3174 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3175 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3176 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3177
3178 {
3179 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3180
3181 ACCEPT_MSG(port);
3182
3183
3184 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3185 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3186
3187 if(currSCCB->Lun == 0x00)
3188 {
3189 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3190 {
3191
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003192 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
3194 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3195 }
3196
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3198 {
3199
3200
3201 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3202 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3203
3204 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3205
3206 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207
3208 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3209 {
3210 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003211 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212
3213
3214 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3215 CurrCard->discQCount--;
3216 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3217 currSCCB->Sccb_tag = 0x00;
3218
3219 }
3220 }
3221
3222 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3223 {
3224
3225
3226 if(currSCCB->Lun == 0x00)
3227 {
3228 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3229 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3230 }
3231 }
3232
3233 else
3234 {
3235
3236 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3237 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003238 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003240 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241
3242
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003243 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244
3245 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3246
3247 }
3248 }
3249
3250 else
3251 {
3252 ACCEPT_MSG(port);
3253
3254 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3255 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3256
3257 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3258 {
3259 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3260 }
3261 }
3262 }
3263
3264 else if (message == SMEXT)
3265 {
3266
3267 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003268 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003269 }
3270
3271 else if (message == SMIGNORWR)
3272 {
3273
3274 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3275
James Bottomley 47b5d692005-04-24 02:38:05 -05003276 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277
3278 if(currSCCB->Sccb_scsimsg != SMPARITY)
3279 ACCEPT_MSG(port);
3280 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3281 }
3282
3283
3284 else
3285 {
3286
3287 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3288 currSCCB->Sccb_scsimsg = SMREJECT;
3289
3290 ACCEPT_MSG_ATN(port);
3291 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3292 }
3293}
3294
3295
3296/*---------------------------------------------------------------------
3297 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003298 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299 *
3300 * Description: Decide what to do with the extended message.
3301 *
3302 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003303static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003305 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306
James Bottomley 47b5d692005-04-24 02:38:05 -05003307 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003308 if (length)
3309 {
3310
3311 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003312 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313 if (message)
3314 {
3315
3316 if (message == SMSYNC)
3317 {
3318
3319 if (length == 0x03)
3320 {
3321
3322 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003323 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003324 }
3325 else
3326 {
3327
3328 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3329 ACCEPT_MSG_ATN(port);
3330 }
3331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003332 else if (message == SMWDTR)
3333 {
3334
3335 if (length == 0x02)
3336 {
3337
3338 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003339 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003340 }
3341 else
3342 {
3343
3344 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3345 ACCEPT_MSG_ATN(port);
3346
3347 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3348 }
3349 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003350 else
3351 {
3352
3353 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3354 ACCEPT_MSG_ATN(port);
3355
3356 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3357 }
3358 }
3359 else
3360 {
3361 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3362 ACCEPT_MSG(port);
3363 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3364 }
3365 }else
3366 {
3367 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3368 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3369 }
3370}
3371
3372
3373/*---------------------------------------------------------------------
3374 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003375 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376 *
3377 * Description: Read in a message byte from the SCSI bus, and check
3378 * for a parity error.
3379 *
3380 *---------------------------------------------------------------------*/
3381
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003382static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383{
3384 PSCCB currSCCB;
3385 PSCCBMgr_tar_info currTar_Info;
3386
James Bottomley 47b5d692005-04-24 02:38:05 -05003387 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3388 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003389
3390 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3391
3392
3393 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003394 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003395
3396 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3397
3398 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3399 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3400 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3401
3402
3403 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3404
3405 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3406
3407 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3408
3409 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3410
3411 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3412
3413 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3414
3415 else
3416 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3417
3418
3419 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3420 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3421 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3422
3423
James Bottomley 47b5d692005-04-24 02:38:05 -05003424 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425 {
3426 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3427 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003428 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 }
3430 else
3431 {
3432 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3433 }
3434
3435
James Bottomley 47b5d692005-04-24 02:38:05 -05003436 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 }
3438
3439 else {
3440
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003441 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003443 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444 }
3445}
3446
3447
3448
3449/*---------------------------------------------------------------------
3450 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003451 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452 *
3453 * Description: The has sent us a Sync Nego message so handle it as
3454 * necessary.
3455 *
3456 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003457static void FPT_stsyncn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003458{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003459 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003460 PSCCB currSCCB;
3461 PSCCBMgr_tar_info currTar_Info;
3462
James Bottomley 47b5d692005-04-24 02:38:05 -05003463 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3464 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003465
James Bottomley 47b5d692005-04-24 02:38:05 -05003466 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467
3468 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3469 {
3470 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3471 return;
3472 }
3473
3474 ACCEPT_MSG(port);
3475
3476
James Bottomley 47b5d692005-04-24 02:38:05 -05003477 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478
3479 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3480 {
3481 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3482 return;
3483 }
3484
3485 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3486
3487 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3488
3489 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3490
3491 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3492
3493 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3494
3495 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3496 else
3497
3498 our_sync_msg = 0; /* Message = Async */
3499
3500 if (sync_msg < our_sync_msg) {
3501 sync_msg = our_sync_msg; /*if faster, then set to max. */
3502 }
3503
3504 if (offset == ASYNC)
3505 sync_msg = ASYNC;
3506
3507 if (offset > MAX_OFFSET)
3508 offset = MAX_OFFSET;
3509
3510 sync_reg = 0x00;
3511
3512 if (sync_msg > 12)
3513
3514 sync_reg = 0x20; /* Use 10MB/s */
3515
3516 if (sync_msg > 25)
3517
3518 sync_reg = 0x40; /* Use 6.6MB/s */
3519
3520 if (sync_msg > 38)
3521
3522 sync_reg = 0x60; /* Use 5MB/s */
3523
3524 if (sync_msg > 50)
3525
3526 sync_reg = 0x80; /* Use 4MB/s */
3527
3528 if (sync_msg > 62)
3529
3530 sync_reg = 0xA0; /* Use 3.33MB/s */
3531
3532 if (sync_msg > 75)
3533
3534 sync_reg = 0xC0; /* Use 2.85MB/s */
3535
3536 if (sync_msg > 87)
3537
3538 sync_reg = 0xE0; /* Use 2.5MB/s */
3539
3540 if (sync_msg > 100) {
3541
3542 sync_reg = 0x00; /* Use ASYNC */
3543 offset = 0x00;
3544 }
3545
3546
Linus Torvalds1da177e2005-04-16 15:20:36 -07003547 if (currTar_Info->TarStatus & WIDE_ENABLED)
3548
3549 sync_reg |= offset;
3550
3551 else
3552
3553 sync_reg |= (offset | NARROW_SCSI);
3554
James Bottomley 47b5d692005-04-24 02:38:05 -05003555 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556
3557
3558 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3559
3560
3561 ACCEPT_MSG(port);
3562
3563 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003564 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565
3566 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3567 }
3568
3569 else {
3570
3571
3572 ACCEPT_MSG_ATN(port);
3573
James Bottomley 47b5d692005-04-24 02:38:05 -05003574 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575
3576 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003577 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003578 }
3579}
3580
3581
3582/*---------------------------------------------------------------------
3583 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003584 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585 *
3586 * Description: Answer the targets sync message.
3587 *
3588 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003589static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590{
3591 ARAM_ACCESS(port);
3592 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3593 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3594 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3595 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3596 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3597 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3598 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3599 SGRAM_ACCESS(port);
3600
3601 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3602 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3603
3604 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3605
3606 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3607}
3608
3609
3610
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611/*---------------------------------------------------------------------
3612 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003613 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614 *
3615 * Description: Read in a message byte from the SCSI bus, and check
3616 * for a parity error.
3617 *
3618 *---------------------------------------------------------------------*/
3619
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003620static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003621{
3622 PSCCB currSCCB;
3623 PSCCBMgr_tar_info currTar_Info;
3624
James Bottomley 47b5d692005-04-24 02:38:05 -05003625 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3626 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003627
3628 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3629
3630
3631 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003632 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633
3634 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3635
3636 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3637 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3638 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3639 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3640 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3641 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3642
3643 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3644
3645
3646 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003647 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648
James Bottomley 47b5d692005-04-24 02:38:05 -05003649 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003650 }
3651
3652 else {
3653
3654 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003655 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656
3657 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003658 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003659 }
3660}
3661
3662
3663
3664/*---------------------------------------------------------------------
3665 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003666 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667 *
3668 * Description: The has sent us a Wide Nego message so handle it as
3669 * necessary.
3670 *
3671 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003672static void FPT_stwidn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003674 unsigned char width;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 PSCCB currSCCB;
3676 PSCCBMgr_tar_info currTar_Info;
3677
James Bottomley 47b5d692005-04-24 02:38:05 -05003678 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3679 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003680
James Bottomley 47b5d692005-04-24 02:38:05 -05003681 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003682
3683 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3684 {
3685 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3686 return;
3687 }
3688
3689
3690 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3691 width = 0;
3692
3693 if (width) {
3694 currTar_Info->TarStatus |= WIDE_ENABLED;
3695 width = 0;
3696 }
3697 else {
3698 width = NARROW_SCSI;
3699 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3700 }
3701
3702
James Bottomley 47b5d692005-04-24 02:38:05 -05003703 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704
3705
3706 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3707 {
3708
3709
3710
3711 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3712
3713 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3714 {
3715 ACCEPT_MSG_ATN(port);
3716 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003717 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003718 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3719 SGRAM_ACCESS(port);
3720 }
3721 else
3722 {
3723 ACCEPT_MSG(port);
3724 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3725 }
3726 }
3727
3728 else {
3729
3730
3731 ACCEPT_MSG_ATN(port);
3732
3733 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3734 width = SM16BIT;
3735 else
3736 width = SM8BIT;
3737
James Bottomley 47b5d692005-04-24 02:38:05 -05003738 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739
3740 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3741 }
3742}
3743
3744
3745/*---------------------------------------------------------------------
3746 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003747 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003748 *
3749 * Description: Answer the targets Wide nego message.
3750 *
3751 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003752static void FPT_siwidr(ULONG port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003753{
3754 ARAM_ACCESS(port);
3755 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3756 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3757 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3758 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3759 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3760 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3761 SGRAM_ACCESS(port);
3762
3763 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3764 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3765
3766 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3767
3768 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3769}
3770
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771
3772
3773/*---------------------------------------------------------------------
3774 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003775 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003776 *
3777 * Description: Write the desired value to the Sync Register for the
3778 * ID specified.
3779 *
3780 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003781static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003782 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003784 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785
3786 index = p_id;
3787
3788 switch (index) {
3789
3790 case 0:
3791 index = 12; /* hp_synctarg_0 */
3792 break;
3793 case 1:
3794 index = 13; /* hp_synctarg_1 */
3795 break;
3796 case 2:
3797 index = 14; /* hp_synctarg_2 */
3798 break;
3799 case 3:
3800 index = 15; /* hp_synctarg_3 */
3801 break;
3802 case 4:
3803 index = 8; /* hp_synctarg_4 */
3804 break;
3805 case 5:
3806 index = 9; /* hp_synctarg_5 */
3807 break;
3808 case 6:
3809 index = 10; /* hp_synctarg_6 */
3810 break;
3811 case 7:
3812 index = 11; /* hp_synctarg_7 */
3813 break;
3814 case 8:
3815 index = 4; /* hp_synctarg_8 */
3816 break;
3817 case 9:
3818 index = 5; /* hp_synctarg_9 */
3819 break;
3820 case 10:
3821 index = 6; /* hp_synctarg_10 */
3822 break;
3823 case 11:
3824 index = 7; /* hp_synctarg_11 */
3825 break;
3826 case 12:
3827 index = 0; /* hp_synctarg_12 */
3828 break;
3829 case 13:
3830 index = 1; /* hp_synctarg_13 */
3831 break;
3832 case 14:
3833 index = 2; /* hp_synctarg_14 */
3834 break;
3835 case 15:
3836 index = 3; /* hp_synctarg_15 */
3837
3838 }
3839
3840 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3841
3842 currTar_Info->TarSyncCtrl = p_sync_value;
3843}
3844
3845
3846/*---------------------------------------------------------------------
3847 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003848 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003849 *
3850 * Description: Reset the desired card's SCSI bus.
3851 *
3852 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003853static void FPT_sresb(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003855 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003856
3857 PSCCBMgr_tar_info currTar_Info;
3858
3859 WR_HARPOON(port+hp_page_ctrl,
3860 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3861 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3862
3863 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3864
3865 scsiID = RD_HARPOON(port+hp_seltimeout);
3866 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3867 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3868
3869 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3870
3871 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3872
3873 WR_HARPOON(port+hp_seltimeout,scsiID);
3874
3875 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3876
James Bottomley 47b5d692005-04-24 02:38:05 -05003877 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003878
3879 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3880
3881 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3882
3883 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3884 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003885 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886
3887 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3888 {
3889 currTar_Info->TarSyncCtrl = 0;
3890 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3891 }
3892
3893 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3894 {
3895 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3896 }
3897
James Bottomley 47b5d692005-04-24 02:38:05 -05003898 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899
James Bottomley 47b5d692005-04-24 02:38:05 -05003900 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901 }
3902
James Bottomley 47b5d692005-04-24 02:38:05 -05003903 FPT_BL_Card[p_card].scanIndex = 0x00;
3904 FPT_BL_Card[p_card].currentSCCB = NULL;
3905 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003907 FPT_BL_Card[p_card].cmdCounter = 0x00;
3908 FPT_BL_Card[p_card].discQCount = 0x00;
3909 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910
3911 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003912 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913
3914 WR_HARPOON(port+hp_page_ctrl,
3915 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3916
3917}
3918
3919/*---------------------------------------------------------------------
3920 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003921 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922 *
3923 * Description: Setup for the Auto Sense command.
3924 *
3925 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003926static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003928 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 PSCCB currSCCB;
3930
3931 currSCCB = pCurrCard->currentSCCB;
3932
3933
3934 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3935
3936 for (i = 0; i < 6; i++) {
3937
3938 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3939 }
3940
3941 currSCCB->CdbLength = SIX_BYTE_CMD;
3942 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003943 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944 currSCCB->Cdb[2] = 0x00;
3945 currSCCB->Cdb[3] = 0x00;
3946 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3947 currSCCB->Cdb[5] = 0x00;
3948
3949 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3950
3951 currSCCB->Sccb_ATC = 0x00;
3952
3953 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3954
3955 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3956
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003957 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003958
3959 currSCCB->ControlByte = 0x00;
3960
3961 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3962}
3963
3964
3965
3966/*---------------------------------------------------------------------
3967 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003968 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969 *
3970 * Description: Transfer data into the bit bucket until the device
3971 * decides to switch phase.
3972 *
3973 *---------------------------------------------------------------------*/
3974
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003975static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003977 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003978
3979
3980 DISABLE_AUTO(p_port);
3981
James Bottomley 47b5d692005-04-24 02:38:05 -05003982 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983
James Bottomley 47b5d692005-04-24 02:38:05 -05003984 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003985
3986 }
3987
3988 /* If the Automation handled the end of the transfer then do not
3989 match the phase or we will get out of sync with the ISR. */
3990
3991 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3992 return;
3993
3994 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3995
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003996 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997
3998 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3999
4000
4001 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4002
4003 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004004 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004006 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 {
4008 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4009
4010 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4011 {
4012 RD_HARPOON(p_port+hp_fifodata_0);
4013 }
4014 }
4015 else
4016 {
4017 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4018 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4019 {
4020 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4021 }
4022 }
4023 } /* End of While loop for padding data I/O phase */
4024
4025 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4026 {
4027 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4028 break;
4029 }
4030
4031 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4032 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4033 {
4034 RD_HARPOON(p_port+hp_fifodata_0);
4035 }
4036
4037 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4038 {
4039 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4040 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4041
4042 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4043 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4044 }
4045}
4046
4047
4048/*---------------------------------------------------------------------
4049 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004050 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051 *
4052 * Description: Make sure data has been flushed from both FIFOs and abort
4053 * the operations if necessary.
4054 *
4055 *---------------------------------------------------------------------*/
4056
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004057static void FPT_schkdd(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058{
4059 USHORT TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004060 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061
4062 PSCCB currSCCB;
4063
James Bottomley 47b5d692005-04-24 02:38:05 -05004064 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004065
4066
4067 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4068 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4069 return;
4070 }
4071
4072
4073
4074 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4075 {
4076
4077 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4078
4079 currSCCB->Sccb_XferCnt = 1;
4080
4081 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4082 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4083 WR_HARPOON(port+hp_xferstat, 0x00);
4084 }
4085
4086 else
4087 {
4088
4089 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4090
4091 currSCCB->Sccb_XferCnt = 0;
4092 }
4093
4094 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4095 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4096
4097 currSCCB->HostStatus = SCCB_PARITY_ERR;
4098 WRW_HARPOON((port+hp_intstat), PARITY);
4099 }
4100
4101
James Bottomley 47b5d692005-04-24 02:38:05 -05004102 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004103
4104
4105 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4106
4107 TimeOutLoop = 0;
4108
4109 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4110 {
4111 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4112 return;
4113 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004114 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 break;
4116 }
4117 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4118 return;
4119 }
4120 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4121 break;
4122 }
4123
4124 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4125 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004126 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4128 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4129 {
4130
4131 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4132
4133 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4134 {
4135 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004136 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 }
4138
4139 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004140 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141 }
4142 }
4143 else
4144 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004145 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004146 if (!(RDW_HARPOON((port+hp_intstat)) &
4147 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4148 {
4149 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004150 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 }
4152 }
4153
4154 }
4155
4156 else {
4157 WR_HARPOON(port+hp_portctrl_0, 0x00);
4158 }
4159}
4160
4161
4162/*---------------------------------------------------------------------
4163 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004164 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165 *
4166 * Description: Setup SCCB manager fields in this SCCB.
4167 *
4168 *---------------------------------------------------------------------*/
4169
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004170static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004171{
4172 PSCCBMgr_tar_info currTar_Info;
4173
4174 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4175 {
4176 return;
4177 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004178 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004179
4180 p_sccb->Sccb_XferState = 0x00;
4181 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4182
4183 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4184 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4185
4186 p_sccb->Sccb_SGoffset = 0;
4187 p_sccb->Sccb_XferState = F_SG_XFER;
4188 p_sccb->Sccb_XferCnt = 0x00;
4189 }
4190
4191 if (p_sccb->DataLength == 0x00)
4192
4193 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4194
4195 if (p_sccb->ControlByte & F_USE_CMD_Q)
4196 {
4197 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4198 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4199
4200 else
4201 currTar_Info->TarStatus |= TAG_Q_TRYING;
4202 }
4203
4204/* For !single SCSI device in system & device allow Disconnect
4205 or command is tag_q type then send Cmd with Disconnect Enable
4206 else send Cmd with Disconnect Disable */
4207
4208/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004209 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004210 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4211 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4212*/
4213 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4214 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004215 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004216 }
4217
4218 else {
4219
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004220 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004221 }
4222
4223 p_sccb->HostStatus = 0x00;
4224 p_sccb->TargetStatus = 0x00;
4225 p_sccb->Sccb_tag = 0x00;
4226 p_sccb->Sccb_MGRFlags = 0x00;
4227 p_sccb->Sccb_sgseg = 0x00;
4228 p_sccb->Sccb_ATC = 0x00;
4229 p_sccb->Sccb_savedATC = 0x00;
4230/*
4231 p_sccb->SccbVirtDataPtr = 0x00;
4232 p_sccb->Sccb_forwardlink = NULL;
4233 p_sccb->Sccb_backlink = NULL;
4234 */
4235 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4236 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4237 p_sccb->Sccb_scsimsg = SMNO_OP;
4238
4239}
4240
4241
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242/*---------------------------------------------------------------------
4243 *
4244 * Function: Phase Decode
4245 *
4246 * Description: Determine the phase and call the appropriate function.
4247 *
4248 *---------------------------------------------------------------------*/
4249
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004250static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251{
4252 unsigned char phase_ref;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004253 void (*phase) (ULONG, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004254
4255
4256 DISABLE_AUTO(p_port);
4257
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004258 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
James Bottomley 47b5d692005-04-24 02:38:05 -05004260 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261
4262 (*phase)(p_port, p_card); /* Call the correct phase func */
4263}
4264
4265
4266
4267/*---------------------------------------------------------------------
4268 *
4269 * Function: Data Out Phase
4270 *
4271 * Description: Start up both the BusMaster and Xbow.
4272 *
4273 *---------------------------------------------------------------------*/
4274
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004275static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004276{
4277
4278 PSCCB currSCCB;
4279
James Bottomley 47b5d692005-04-24 02:38:05 -05004280 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281 if (currSCCB == NULL)
4282 {
4283 return; /* Exit if No SCCB record */
4284 }
4285
4286 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4287 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4288
4289 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4290
4291 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4292
4293 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4294
James Bottomley 47b5d692005-04-24 02:38:05 -05004295 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004296
4297 if (currSCCB->Sccb_XferCnt == 0) {
4298
4299
4300 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4301 (currSCCB->HostStatus == SCCB_COMPLETE))
4302 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4303
James Bottomley 47b5d692005-04-24 02:38:05 -05004304 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004306 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307 }
4308}
4309
4310
4311/*---------------------------------------------------------------------
4312 *
4313 * Function: Data In Phase
4314 *
4315 * Description: Startup the BusMaster and the XBOW.
4316 *
4317 *---------------------------------------------------------------------*/
4318
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004319static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004320{
4321
4322 PSCCB currSCCB;
4323
James Bottomley 47b5d692005-04-24 02:38:05 -05004324 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325
4326 if (currSCCB == NULL)
4327 {
4328 return; /* Exit if No SCCB record */
4329 }
4330
4331
4332 currSCCB->Sccb_scsistat = DATA_IN_ST;
4333 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4334 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4335
4336 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4337
4338 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4339
4340 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4341
James Bottomley 47b5d692005-04-24 02:38:05 -05004342 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343
4344 if (currSCCB->Sccb_XferCnt == 0) {
4345
4346
4347 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4348 (currSCCB->HostStatus == SCCB_COMPLETE))
4349 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4350
James Bottomley 47b5d692005-04-24 02:38:05 -05004351 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004353 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004354
4355 }
4356}
4357
4358/*---------------------------------------------------------------------
4359 *
4360 * Function: Command Phase
4361 *
4362 * Description: Load the CDB into the automation and start it up.
4363 *
4364 *---------------------------------------------------------------------*/
4365
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004366static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367{
4368 PSCCB currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369 ULONG cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004370 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371
James Bottomley 47b5d692005-04-24 02:38:05 -05004372 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004373
4374 if (currSCCB->OperationCode == RESET_COMMAND) {
4375
4376 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4377 currSCCB->CdbLength = SIX_BYTE_CMD;
4378 }
4379
4380 WR_HARPOON(p_port+hp_scsisig, 0x00);
4381
4382 ARAM_ACCESS(p_port);
4383
4384
4385 cdb_reg = p_port + CMD_STRT;
4386
4387 for (i=0; i < currSCCB->CdbLength; i++) {
4388
4389 if (currSCCB->OperationCode == RESET_COMMAND)
4390
4391 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4392
4393 else
4394 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4395 cdb_reg +=2;
4396 }
4397
4398 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4399 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4400
4401 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4402
4403 currSCCB->Sccb_scsistat = COMMAND_ST;
4404
4405 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4406 SGRAM_ACCESS(p_port);
4407}
4408
4409
4410/*---------------------------------------------------------------------
4411 *
4412 * Function: Status phase
4413 *
4414 * Description: Bring in the status and command complete message bytes
4415 *
4416 *---------------------------------------------------------------------*/
4417
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004418static void FPT_phaseStatus(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004419{
4420 /* Start-up the automation to finish off this command and let the
4421 isr handle the interrupt for command complete when it comes in.
4422 We could wait here for the interrupt to be generated?
4423 */
4424
4425 WR_HARPOON(port+hp_scsisig, 0x00);
4426
4427 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4428}
4429
4430
4431/*---------------------------------------------------------------------
4432 *
4433 * Function: Phase Message Out
4434 *
4435 * Description: Send out our message (if we have one) and handle whatever
4436 * else is involed.
4437 *
4438 *---------------------------------------------------------------------*/
4439
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004440static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004442 unsigned char message,scsiID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 PSCCB currSCCB;
4444 PSCCBMgr_tar_info currTar_Info;
4445
James Bottomley 47b5d692005-04-24 02:38:05 -05004446 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447
4448 if (currSCCB != NULL) {
4449
4450 message = currSCCB->Sccb_scsimsg;
4451 scsiID = currSCCB->TargID;
4452
4453 if (message == SMDEV_RESET)
4454 {
4455
4456
James Bottomley 47b5d692005-04-24 02:38:05 -05004457 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004459 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460
James Bottomley 47b5d692005-04-24 02:38:05 -05004461 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462 {
4463
James Bottomley 47b5d692005-04-24 02:38:05 -05004464 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465
4466 }
4467
James Bottomley 47b5d692005-04-24 02:38:05 -05004468 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469 {
4470
James Bottomley 47b5d692005-04-24 02:38:05 -05004471 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472 }
4473
4474
James Bottomley 47b5d692005-04-24 02:38:05 -05004475 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4476 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004477 }
4478 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4479 {
4480 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004481 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004483 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4484 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 }
4486
4487 }
4488
4489 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4490 {
4491
4492
4493 if(message == SMNO_OP)
4494 {
4495 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4496
James Bottomley 47b5d692005-04-24 02:38:05 -05004497 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498 return;
4499 }
4500 }
4501 else
4502 {
4503
4504
4505 if (message == SMABORT)
4506
James Bottomley 47b5d692005-04-24 02:38:05 -05004507 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004508 }
4509
4510 }
4511 else
4512 {
4513 message = SMABORT;
4514 }
4515
4516 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4517
4518
4519 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4520
4521 WR_HARPOON(port+hp_scsidata_0,message);
4522
4523 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4524
4525 ACCEPT_MSG(port);
4526
4527 WR_HARPOON(port+hp_portctrl_0, 0x00);
4528
4529 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4530 (message == SMABORT_TAG) )
4531 {
4532
4533 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4534
4535 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4536 {
4537 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4538
4539 if (currSCCB != NULL)
4540 {
4541
James Bottomley 47b5d692005-04-24 02:38:05 -05004542 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4543 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4544 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004546 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547
James Bottomley 47b5d692005-04-24 02:38:05 -05004548 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 }
4550
4551 else
4552 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004553 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004554 }
4555 }
4556
4557 else
4558 {
4559
James Bottomley 47b5d692005-04-24 02:38:05 -05004560 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004561 }
4562 }
4563
4564 else
4565 {
4566
4567 if(message == SMPARITY)
4568 {
4569 currSCCB->Sccb_scsimsg = SMNO_OP;
4570 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4571 }
4572 else
4573 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004574 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004575 }
4576 }
4577}
4578
4579
4580/*---------------------------------------------------------------------
4581 *
4582 * Function: Message In phase
4583 *
4584 * Description: Bring in the message and determine what to do with it.
4585 *
4586 *---------------------------------------------------------------------*/
4587
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004588static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004590 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591 PSCCB currSCCB;
4592
James Bottomley 47b5d692005-04-24 02:38:05 -05004593 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004594
James Bottomley 47b5d692005-04-24 02:38:05 -05004595 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596 {
4597
James Bottomley 47b5d692005-04-24 02:38:05 -05004598 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004599 }
4600
4601 message = RD_HARPOON(port+hp_scsidata_0);
4602 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4603 {
4604
4605 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4606
4607 }
4608
4609 else
4610 {
4611
James Bottomley 47b5d692005-04-24 02:38:05 -05004612 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613 if (message)
4614 {
4615
4616
James Bottomley 47b5d692005-04-24 02:38:05 -05004617 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004618
4619 }
4620 else
4621 {
4622 if(currSCCB->Sccb_scsimsg != SMPARITY)
4623 ACCEPT_MSG(port);
4624 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4625 }
4626 }
4627
4628}
4629
4630
4631/*---------------------------------------------------------------------
4632 *
4633 * Function: Illegal phase
4634 *
4635 * Description: Target switched to some illegal phase, so all we can do
4636 * is report an error back to the host (if that is possible)
4637 * and send an ABORT message to the misbehaving target.
4638 *
4639 *---------------------------------------------------------------------*/
4640
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004641static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642{
4643 PSCCB currSCCB;
4644
James Bottomley 47b5d692005-04-24 02:38:05 -05004645 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004646
4647 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4648 if (currSCCB != NULL) {
4649
4650 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4651 currSCCB->Sccb_scsistat = ABORT_ST;
4652 currSCCB->Sccb_scsimsg = SMABORT;
4653 }
4654
4655 ACCEPT_MSG_ATN(port);
4656}
4657
4658
4659
4660/*---------------------------------------------------------------------
4661 *
4662 * Function: Phase Check FIFO
4663 *
4664 * Description: Make sure data has been flushed from both FIFOs and abort
4665 * the operations if necessary.
4666 *
4667 *---------------------------------------------------------------------*/
4668
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004669static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004670{
4671 ULONG xfercnt;
4672 PSCCB currSCCB;
4673
James Bottomley 47b5d692005-04-24 02:38:05 -05004674 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004675
4676 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4677 {
4678
4679 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4680 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4681
4682
4683 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4684 {
4685 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4686
4687 currSCCB->Sccb_XferCnt = 0;
4688
4689 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4690 (currSCCB->HostStatus == SCCB_COMPLETE))
4691 {
4692 currSCCB->HostStatus = SCCB_PARITY_ERR;
4693 WRW_HARPOON((port+hp_intstat), PARITY);
4694 }
4695
James Bottomley 47b5d692005-04-24 02:38:05 -05004696 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004697
James Bottomley 47b5d692005-04-24 02:38:05 -05004698 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004699
4700 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4701 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4702
4703 }
4704 } /*End Data In specific code. */
4705
4706
4707
Linus Torvalds1da177e2005-04-16 15:20:36 -07004708 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004709
4710
4711 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4712
4713
4714 WR_HARPOON(port+hp_portctrl_0, 0x00);
4715
4716 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4717
4718 currSCCB->Sccb_XferCnt = xfercnt;
4719
4720 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4721 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4722
4723 currSCCB->HostStatus = SCCB_PARITY_ERR;
4724 WRW_HARPOON((port+hp_intstat), PARITY);
4725 }
4726
4727
James Bottomley 47b5d692005-04-24 02:38:05 -05004728 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004729
4730
4731 WR_HARPOON(port+hp_fifowrite, 0x00);
4732 WR_HARPOON(port+hp_fiforead, 0x00);
4733 WR_HARPOON(port+hp_xferstat, 0x00);
4734
4735 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4736}
4737
4738
4739/*---------------------------------------------------------------------
4740 *
4741 * Function: Phase Bus Free
4742 *
4743 * Description: We just went bus free so figure out if it was
4744 * because of command complete or from a disconnect.
4745 *
4746 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004747static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004748{
4749 PSCCB currSCCB;
4750
James Bottomley 47b5d692005-04-24 02:38:05 -05004751 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004752
4753 if (currSCCB != NULL)
4754 {
4755
4756 DISABLE_AUTO(port);
4757
4758
4759 if (currSCCB->OperationCode == RESET_COMMAND)
4760 {
4761
James Bottomley 47b5d692005-04-24 02:38:05 -05004762 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4763 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004765 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004766 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004767
James Bottomley 47b5d692005-04-24 02:38:05 -05004768 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004769
James Bottomley 47b5d692005-04-24 02:38:05 -05004770 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004771
4772 }
4773
4774 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4775 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004776 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004777 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004778 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004779 }
4780
4781 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4782 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4784 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004785 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4786
James Bottomley 47b5d692005-04-24 02:38:05 -05004787 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004788 }
4789
Linus Torvalds1da177e2005-04-16 15:20:36 -07004790 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4791 {
4792 /* Make sure this is not a phony BUS_FREE. If we were
4793 reselected or if BUSY is NOT on then this is a
4794 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4795
4796 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4797 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4798 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004799 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004801 }
4802
4803 else
4804 {
4805 return;
4806 }
4807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004808
4809 else
4810 {
4811
4812 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4813
4814 if (!currSCCB->HostStatus)
4815 {
4816 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4817 }
4818
James Bottomley 47b5d692005-04-24 02:38:05 -05004819 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4820 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4821 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004822 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004823 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004824
James Bottomley 47b5d692005-04-24 02:38:05 -05004825 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004826 return;
4827 }
4828
4829
James Bottomley 47b5d692005-04-24 02:38:05 -05004830 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004831
4832 } /*end if !=null */
4833}
4834
4835
4836
4837
Linus Torvalds1da177e2005-04-16 15:20:36 -07004838/*---------------------------------------------------------------------
4839 *
4840 * Function: Auto Load Default Map
4841 *
4842 * Description: Load the Automation RAM with the defualt map values.
4843 *
4844 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004845static void FPT_autoLoadDefaultMap(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004846{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004847 ULONG map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004848
4849 ARAM_ACCESS(p_port);
4850 map_addr = p_port + hp_aramBase;
4851
4852 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4873 map_addr +=2;
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4875 map_addr +=2;
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4877 map_addr +=2;
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4883 map_addr +=2;
4884 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4885 map_addr +=2;
4886 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4887 map_addr +=2; /*This means AYNC DATA IN */
4888 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4909 map_addr +=2;
4910 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4911 map_addr +=2;
4912 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4913 map_addr +=2;
4914 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4917 map_addr +=2;
4918 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4919 map_addr +=2;
4920 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4921 map_addr +=2;
4922 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4923 map_addr +=2;
4924
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4926 map_addr +=2;
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4928 map_addr +=2;
4929 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4930 map_addr +=2;
4931 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4932 map_addr +=2; /* DIDN'T GET ONE */
4933 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4934 map_addr +=2;
4935 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4936 map_addr +=2;
4937 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4938
4939
4940
4941 SGRAM_ACCESS(p_port);
4942}
4943
4944/*---------------------------------------------------------------------
4945 *
4946 * Function: Auto Command Complete
4947 *
4948 * Description: Post command back to host and find another command
4949 * to execute.
4950 *
4951 *---------------------------------------------------------------------*/
4952
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004953static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004954{
4955 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004956 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004957
James Bottomley 47b5d692005-04-24 02:38:05 -05004958 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004959
4960 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4961
James Bottomley 47b5d692005-04-24 02:38:05 -05004962 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004963
4964 if (status_byte != SSGOOD) {
4965
4966 if (status_byte == SSQ_FULL) {
4967
4968
James Bottomley 47b5d692005-04-24 02:38:05 -05004969 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4970 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004971 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004972 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4973 if(FPT_BL_Card[p_card].discQCount != 0)
4974 FPT_BL_Card[p_card].discQCount--;
4975 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 -07004976 }
4977 else
4978 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004979 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004980 if(currSCCB->Sccb_tag)
4981 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004982 if(FPT_BL_Card[p_card].discQCount != 0)
4983 FPT_BL_Card[p_card].discQCount--;
4984 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004985 }else
4986 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004987 if(FPT_BL_Card[p_card].discQCount != 0)
4988 FPT_BL_Card[p_card].discQCount--;
4989 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004990 }
4991 }
4992
4993 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4994
James Bottomley 47b5d692005-04-24 02:38:05 -05004995 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004996
4997 return;
4998 }
4999
5000 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5001 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005002 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005003 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005004
James Bottomley 47b5d692005-04-24 02:38:05 -05005005 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5006 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005007
James Bottomley 47b5d692005-04-24 02:38:05 -05005008 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5009 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005010 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005011 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5012 if(FPT_BL_Card[p_card].discQCount != 0)
5013 FPT_BL_Card[p_card].discQCount--;
5014 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 -07005015 }
5016 else
5017 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005018 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005019 if(currSCCB->Sccb_tag)
5020 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005021 if(FPT_BL_Card[p_card].discQCount != 0)
5022 FPT_BL_Card[p_card].discQCount--;
5023 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005024 }else
5025 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005026 if(FPT_BL_Card[p_card].discQCount != 0)
5027 FPT_BL_Card[p_card].discQCount--;
5028 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005029 }
5030 }
5031 return;
5032
5033 }
5034
5035 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5036 {
5037
James Bottomley 47b5d692005-04-24 02:38:05 -05005038 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5039 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005040 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5041
James Bottomley 47b5d692005-04-24 02:38:05 -05005042 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5043 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005044
James Bottomley 47b5d692005-04-24 02:38:05 -05005045 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5046 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005047 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005048 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5049 if(FPT_BL_Card[p_card].discQCount != 0)
5050 FPT_BL_Card[p_card].discQCount--;
5051 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 -07005052 }
5053 else
5054 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005055 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005056 if(currSCCB->Sccb_tag)
5057 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005058 if(FPT_BL_Card[p_card].discQCount != 0)
5059 FPT_BL_Card[p_card].discQCount--;
5060 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005061 }else
5062 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005063 if(FPT_BL_Card[p_card].discQCount != 0)
5064 FPT_BL_Card[p_card].discQCount--;
5065 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005066 }
5067 }
5068 return;
5069
5070 }
5071
5072 if (status_byte == SSCHECK)
5073 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005074 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005075 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005076 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005077 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005078 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005079 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005080 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005081 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005082 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005083 }
5084 }
5085 }
5086
5087 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5088
5089 currSCCB->SccbStatus = SCCB_ERROR;
5090 currSCCB->TargetStatus = status_byte;
5091
5092 if (status_byte == SSCHECK) {
5093
James Bottomley 47b5d692005-04-24 02:38:05 -05005094 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5095 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005096
5097
Linus Torvalds1da177e2005-04-16 15:20:36 -07005098 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5099
5100 if (currSCCB->RequestSenseLength == 0)
5101 currSCCB->RequestSenseLength = 14;
5102
James Bottomley 47b5d692005-04-24 02:38:05 -05005103 FPT_ssenss(&FPT_BL_Card[p_card]);
5104 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005105
James Bottomley 47b5d692005-04-24 02:38:05 -05005106 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5107 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005108 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005109 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5110 if(FPT_BL_Card[p_card].discQCount != 0)
5111 FPT_BL_Card[p_card].discQCount--;
5112 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 -07005113 }
5114 else
5115 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005116 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005117 if(currSCCB->Sccb_tag)
5118 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005119 if(FPT_BL_Card[p_card].discQCount != 0)
5120 FPT_BL_Card[p_card].discQCount--;
5121 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005122 }else
5123 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005124 if(FPT_BL_Card[p_card].discQCount != 0)
5125 FPT_BL_Card[p_card].discQCount--;
5126 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005127 }
5128 }
5129 return;
5130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005131 }
5132 }
5133 }
5134
5135
James Bottomley 47b5d692005-04-24 02:38:05 -05005136 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5137 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5138 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005139 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005140 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005141
5142
James Bottomley 47b5d692005-04-24 02:38:05 -05005143 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005144}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005145
5146#define SHORT_WAIT 0x0000000F
5147#define LONG_WAIT 0x0000FFFFL
5148
Linus Torvalds1da177e2005-04-16 15:20:36 -07005149
5150/*---------------------------------------------------------------------
5151 *
5152 * Function: Data Transfer Processor
5153 *
5154 * Description: This routine performs two tasks.
5155 * (1) Start data transfer by calling HOST_DATA_XFER_START
5156 * function. Once data transfer is started, (2) Depends
5157 * on the type of data transfer mode Scatter/Gather mode
5158 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5159 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5160 * data transfer done. In Scatter/Gather mode, this routine
5161 * checks bus master command complete and dual rank busy
5162 * bit to keep chaining SC transfer command. Similarly,
5163 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5164 * (F_HOST_XFER_ACT bit) for data transfer done.
5165 *
5166 *---------------------------------------------------------------------*/
5167
James Bottomley 47b5d692005-04-24 02:38:05 -05005168static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005169{
5170 PSCCB currSCCB;
5171
5172 currSCCB = pCurrCard->currentSCCB;
5173
5174 if (currSCCB->Sccb_XferState & F_SG_XFER)
5175 {
5176 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5177
5178 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005179 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005180 currSCCB->Sccb_SGoffset = 0x00;
5181 }
5182 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5183
James Bottomley 47b5d692005-04-24 02:38:05 -05005184 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005185 }
5186
5187 else
5188 {
5189 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5190 {
5191 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5192
James Bottomley 47b5d692005-04-24 02:38:05 -05005193 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005194 }
5195 }
5196}
5197
5198
5199/*---------------------------------------------------------------------
5200 *
5201 * Function: BusMaster Scatter Gather Data Transfer Start
5202 *
5203 * Description:
5204 *
5205 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005206static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005207{
5208 ULONG count,addr,tmpSGCnt;
5209 UINT sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005210 unsigned char sg_count, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005211 ULONG reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212
5213
5214 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5215
5216 count = ((ULONG) HOST_RD_CMD)<<24;
5217 }
5218
5219 else {
5220 count = ((ULONG) HOST_WRT_CMD)<<24;
5221 }
5222
5223 sg_count = 0;
5224 tmpSGCnt = 0;
5225 sg_index = pcurrSCCB->Sccb_sgseg;
5226 reg_offset = hp_aramBase;
5227
5228
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005229 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230
5231
5232 WR_HARPOON(p_port+hp_page_ctrl, i);
5233
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005234 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07005235 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5236
Linus Torvalds1da177e2005-04-16 15:20:36 -07005237 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5238 (sg_index * 2));
5239
5240 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5241 (sg_index * 2));
5242
5243 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5244 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005245
5246
5247 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5248
5249 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5250 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5251
5252 tmpSGCnt = count & 0x00FFFFFFL;
5253 }
5254
5255 WR_HARP32(p_port,reg_offset,addr);
5256 reg_offset +=4;
5257
5258 WR_HARP32(p_port,reg_offset,count);
5259 reg_offset +=4;
5260
5261 count &= 0xFF000000L;
5262 sg_index++;
5263 sg_count++;
5264
5265 } /*End While */
5266
5267 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5268
5269 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5270
5271 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5272
5273 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5274
5275
5276 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5277 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5278 }
5279
5280 else {
5281
5282
5283 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5284 (tmpSGCnt & 0x000000001))
5285 {
5286
5287 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5288 tmpSGCnt--;
5289 }
5290
5291
5292 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5293
5294 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5295 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5296 }
5297
5298
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005299 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005300
5301}
5302
5303
5304/*---------------------------------------------------------------------
5305 *
5306 * Function: BusMaster Data Transfer Start
5307 *
5308 * Description:
5309 *
5310 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005311static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005312{
5313 ULONG addr,count;
5314
5315 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5316
5317 count = pcurrSCCB->Sccb_XferCnt;
5318
5319 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5320 }
5321
5322 else {
5323 addr = pcurrSCCB->SensePointer;
5324 count = pcurrSCCB->RequestSenseLength;
5325
5326 }
5327
Linus Torvalds1da177e2005-04-16 15:20:36 -07005328 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005329
5330
5331 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5332
5333 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5334 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5335
5336 WR_HARPOON(p_port+hp_xfer_cmd,
5337 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5338 }
5339
5340 else {
5341
5342 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5343 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5344
5345 WR_HARPOON(p_port+hp_xfer_cmd,
5346 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5347
5348 }
5349}
5350
5351
5352/*---------------------------------------------------------------------
5353 *
5354 * Function: BusMaster Timeout Handler
5355 *
5356 * Description: This function is called after a bus master command busy time
5357 * out is detected. This routines issue halt state machine
5358 * with a software time out for command busy. If command busy
5359 * is still asserted at the end of the time out, it issues
5360 * hard abort with another software time out. It hard abort
5361 * command busy is also time out, it'll just give up.
5362 *
5363 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005364static unsigned char FPT_busMstrTimeOut(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005365{
5366 ULONG timeout;
5367
5368 timeout = LONG_WAIT;
5369
5370 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5371
5372 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5373
5374
5375
5376 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5377 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5378
5379 timeout = LONG_WAIT;
5380 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5381 }
5382
5383 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5384
5385 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005386 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387 }
5388
5389 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005390 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005391 }
5392}
5393
5394
5395/*---------------------------------------------------------------------
5396 *
5397 * Function: Host Data Transfer Abort
5398 *
5399 * Description: Abort any in progress transfer.
5400 *
5401 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005402static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005403{
5404
5405 ULONG timeout;
5406 ULONG remain_cnt;
5407 UINT sg_ptr;
5408
James Bottomley 47b5d692005-04-24 02:38:05 -05005409 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005410
5411 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5412
5413
5414 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5415
5416 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5417 timeout = LONG_WAIT;
5418
5419 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5420
5421 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5422
5423 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5424
James Bottomley 47b5d692005-04-24 02:38:05 -05005425 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005426
5427 if (pCurrSCCB->HostStatus == 0x00)
5428
5429 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5430
5431 }
5432
5433 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5434
5435 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5436
5437 if (pCurrSCCB->HostStatus == 0x00)
5438
5439 {
5440 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005441 }
5442 }
5443 }
5444 }
5445
5446 else if (pCurrSCCB->Sccb_XferCnt) {
5447
5448 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5449
5450
5451 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5452 ~SCATTER_EN));
5453
5454 WR_HARPOON(port+hp_sg_addr,0x00);
5455
5456 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5457
5458 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5459
5460 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5461 }
5462
5463 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5464
5465 while (remain_cnt < 0x01000000L) {
5466
5467 sg_ptr--;
5468
Linus Torvalds1da177e2005-04-16 15:20:36 -07005469 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5470 DataPointer) + (sg_ptr * 2)))) {
5471
5472 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5473 DataPointer) + (sg_ptr * 2)));
5474 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005475
5476 else {
5477
5478 break;
5479 }
5480 }
5481
5482
5483
5484 if (remain_cnt < 0x01000000L) {
5485
5486
5487 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5488
5489 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5490
5491
5492 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5493 && (remain_cnt == 0))
5494
5495 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5496 }
5497
5498 else {
5499
5500
5501 if (pCurrSCCB->HostStatus == 0x00) {
5502
5503 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5504 }
5505 }
5506 }
5507
5508
5509 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5510
5511
5512 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5513
James Bottomley 47b5d692005-04-24 02:38:05 -05005514 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005515 }
5516
5517 else {
5518
5519 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5520
5521 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5522
5523 if (pCurrSCCB->HostStatus == 0x00) {
5524
5525 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005526 }
5527 }
5528 }
5529
5530 }
5531 }
5532
5533 else {
5534
5535
5536 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5537
5538 timeout = SHORT_WAIT;
5539
5540 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5541 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5542 timeout--) {}
5543 }
5544
5545 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5546
5547 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5548 FLUSH_XFER_CNTR));
5549
5550 timeout = LONG_WAIT;
5551
5552 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5553 timeout--) {}
5554
5555 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5556 ~FLUSH_XFER_CNTR));
5557
5558
5559 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5560
5561 if (pCurrSCCB->HostStatus == 0x00) {
5562
5563 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5564 }
5565
James Bottomley 47b5d692005-04-24 02:38:05 -05005566 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005567 }
5568 }
5569
5570 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5571
5572 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5573
5574 if (pCurrSCCB->HostStatus == 0x00) {
5575
5576 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005577 }
5578 }
5579 }
5580 }
5581
5582 }
5583
5584 else {
5585
5586
5587 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5588
5589 timeout = LONG_WAIT;
5590
5591 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5592
5593 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5594
5595 if (pCurrSCCB->HostStatus == 0x00) {
5596
5597 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5598 }
5599
James Bottomley 47b5d692005-04-24 02:38:05 -05005600 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005601 }
5602 }
5603
5604
5605 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5606
5607 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5608
5609 if (pCurrSCCB->HostStatus == 0x00) {
5610
5611 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005612 }
5613 }
5614
5615 }
5616
5617 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5618
5619 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5620 ~SCATTER_EN));
5621
5622 WR_HARPOON(port+hp_sg_addr,0x00);
5623
5624 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5625
5626 pCurrSCCB->Sccb_SGoffset = 0x00;
5627
5628
5629 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5630 pCurrSCCB->DataLength) {
5631
5632 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5633
5634 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5635
5636 }
5637 }
5638
5639 else {
5640
5641 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5642
5643 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5644 }
5645 }
5646
5647 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5648}
5649
5650
5651
5652/*---------------------------------------------------------------------
5653 *
5654 * Function: Host Data Transfer Restart
5655 *
5656 * Description: Reset the available count due to a restore data
5657 * pointers message.
5658 *
5659 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005660static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661{
5662 ULONG data_count;
5663 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005665
5666 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5667
5668 currSCCB->Sccb_XferCnt = 0;
5669
5670 sg_index = 0xffff; /*Index by long words into sg list. */
5671 data_count = 0; /*Running count of SG xfer counts. */
5672
Linus Torvalds1da177e2005-04-16 15:20:36 -07005673 sg_ptr = (ULONG *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005674
5675 while (data_count < currSCCB->Sccb_ATC) {
5676
5677 sg_index++;
5678 data_count += *(sg_ptr+(sg_index * 2));
5679 }
5680
5681 if (data_count == currSCCB->Sccb_ATC) {
5682
5683 currSCCB->Sccb_SGoffset = 0;
5684 sg_index++;
5685 }
5686
5687 else {
5688 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5689 }
5690
5691 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5692 }
5693
5694 else {
5695 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5696 }
5697}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005698
5699
5700
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701/*---------------------------------------------------------------------
5702 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005703 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005704 *
5705 * Description: Setup all data structures necessary for SCAM selection.
5706 *
5707 *---------------------------------------------------------------------*/
5708
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005709static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005710{
5711
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005712 unsigned char loser,assigned_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713 ULONG p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005714
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005715 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716 PSCCBcard currCard;
5717 PNVRamInfo pCurrNvRam;
5718
James Bottomley 47b5d692005-04-24 02:38:05 -05005719 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005720 p_port = currCard->ioPort;
5721 pCurrNvRam = currCard->pNvRamInfo;
5722
5723
5724 if(pCurrNvRam){
5725 ScamFlg = pCurrNvRam->niScamConf;
5726 i = pCurrNvRam->niSysConf;
5727 }
5728 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005729 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5730 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731 }
5732 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5733 return;
5734
James Bottomley 47b5d692005-04-24 02:38:05 -05005735 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005736
5737 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5738 too slow to return to SCAM selection */
5739
5740 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005741 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005743 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005744
James Bottomley 47b5d692005-04-24 02:38:05 -05005745 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005746
5747 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5748 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005749 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005750
James Bottomley 47b5d692005-04-24 02:38:05 -05005751 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005752
5753 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005754 FPT_scxferc(p_port,SYNC_PTRN);
5755 FPT_scxferc(p_port,DOM_MSTR);
5756 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005757 } while ( loser == 0xFF );
5758
James Bottomley 47b5d692005-04-24 02:38:05 -05005759 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005760
5761 if ((p_power_up) && (!loser))
5762 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005763 FPT_sresb(p_port,p_card);
5764 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005765
James Bottomley 47b5d692005-04-24 02:38:05 -05005766 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005767
James Bottomley 47b5d692005-04-24 02:38:05 -05005768 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769
5770 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005771 FPT_scxferc(p_port, SYNC_PTRN);
5772 FPT_scxferc(p_port, DOM_MSTR);
5773 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005774 id_string[0]);
5775 } while ( loser == 0xFF );
5776
James Bottomley 47b5d692005-04-24 02:38:05 -05005777 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005778 }
5779 }
5780
5781 else
5782 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005783 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005784 }
5785
5786
5787 if (!loser)
5788 {
5789
James Bottomley 47b5d692005-04-24 02:38:05 -05005790 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005791
5792
5793 if (ScamFlg & SCAM_ENABLED)
5794 {
5795
5796 for (i=0; i < MAX_SCSI_TAR; i++)
5797 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005798 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5799 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005800 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005801 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005802 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005803 FPT_scamInfo[i].state = LEGACY;
5804 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5805 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005806 {
5807
James Bottomley 47b5d692005-04-24 02:38:05 -05005808 FPT_scamInfo[i].id_string[0] = 0xFF;
5809 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005810 if(pCurrNvRam == NULL)
5811 currCard->globalFlags |= F_UPDATE_EEPROM;
5812 }
5813 }
5814 }
5815 }
5816
James Bottomley 47b5d692005-04-24 02:38:05 -05005817 FPT_sresb(p_port,p_card);
5818 FPT_Wait1Second(p_port);
5819 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5820 FPT_scsel(p_port);
5821 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005822 }
5823
Linus Torvalds1da177e2005-04-16 15:20:36 -07005824 }
5825
5826 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5827 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005828 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5829 assigned_id = 0;
5830 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831
5832 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005833 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005834
James Bottomley 47b5d692005-04-24 02:38:05 -05005835 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005836 if (i == ASSIGN_ID)
5837 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005838 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005839 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005840 i = FPT_scxferc(p_port,0x00);
5841 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005842 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005843 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005844
James Bottomley 47b5d692005-04-24 02:38:05 -05005845 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005846 {
5847 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005848 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005849 FPT_inisci(p_card, p_port, p_our_id);
5850 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5851 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005852 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005853 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854 }
5855 }
5856 }
5857 }
5858
5859 else if (i == SET_P_FLAG)
5860 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005861 if (!(FPT_scsendi(p_port,
5862 &FPT_scamInfo[p_our_id].id_string[0])))
5863 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005864 }
5865 }while (!assigned_id);
5866
James Bottomley 47b5d692005-04-24 02:38:05 -05005867 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005868 }
5869
Linus Torvalds1da177e2005-04-16 15:20:36 -07005870 if (ScamFlg & SCAM_ENABLED)
5871 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005872 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873 if (currCard->globalFlags & F_UPDATE_EEPROM)
5874 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005875 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005876 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5877 }
5878 }
5879
5880
Linus Torvalds1da177e2005-04-16 15:20:36 -07005881/*
5882 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5883 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005884 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5885 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005886 k++;
5887 }
5888
5889 if (k==2)
5890 currCard->globalFlags |= F_SINGLE_DEVICE;
5891 else
5892 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5893*/
5894}
5895
5896
5897/*---------------------------------------------------------------------
5898 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005899 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005900 *
5901 * Description: Gain control of the bus and wait SCAM select time (250ms)
5902 *
5903 *---------------------------------------------------------------------*/
5904
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005905static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005906{
5907 if (p_sel_type == INIT_SELTD)
5908 {
5909
5910 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5911
5912
5913 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005914 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005915
5916 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005917 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005918
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5920
5921 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5922
5923 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5924 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005925 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005926 }
5927
5928
5929 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5930
5931 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5932
5933 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5934 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005935 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005936 }
5937 }
5938
5939
5940 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5941 & ~ACTdeassert));
5942 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5943 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005944 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005945 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5946
5947 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5948
5949 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5950 & ~SCSI_BSY));
5951
James Bottomley 47b5d692005-04-24 02:38:05 -05005952 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005953
James Bottomley 47b5d692005-04-24 02:38:05 -05005954 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005955}
5956
5957
5958/*---------------------------------------------------------------------
5959 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005960 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005961 *
5962 * Description: Release the SCSI bus and disable SCAM selection.
5963 *
5964 *---------------------------------------------------------------------*/
5965
James Bottomley 47b5d692005-04-24 02:38:05 -05005966static void FPT_scbusf(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005967{
5968 WR_HARPOON(p_port+hp_page_ctrl,
5969 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5970
5971
5972 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5973
5974 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5975 & ~SCSI_BUS_EN));
5976
5977 WR_HARPOON(p_port+hp_scsisig, 0x00);
5978
5979
5980 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5981 & ~SCAM_EN));
5982
5983 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5984 | ACTdeassert));
5985
Linus Torvalds1da177e2005-04-16 15:20:36 -07005986 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005987
5988 WR_HARPOON(p_port+hp_page_ctrl,
5989 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5990}
5991
5992
5993
5994/*---------------------------------------------------------------------
5995 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005996 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997 *
5998 * Description: Assign an ID to all the SCAM devices.
5999 *
6000 *---------------------------------------------------------------------*/
6001
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006002static void FPT_scasid(unsigned char p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006004 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006005
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006006 unsigned char i,k,scam_id;
6007 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006008 PNVRamInfo pCurrNvRam;
6009 ushort_ptr pCrcBytes;
6010
James Bottomley 47b5d692005-04-24 02:38:05 -05006011 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006012
James Bottomley 47b5d692005-04-24 02:38:05 -05006013 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006014
6015 while (!i)
6016 {
6017
6018 for (k=0; k < ID_STRING_LENGTH; k++)
6019 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006020 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021 }
6022
James Bottomley 47b5d692005-04-24 02:38:05 -05006023 FPT_scxferc(p_port,SYNC_PTRN);
6024 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025
James Bottomley 47b5d692005-04-24 02:38:05 -05006026 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006027 {
6028 if(pCurrNvRam){
6029 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006030 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6031 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006032 temp_id_string[1] = crcBytes[2];
6033 temp_id_string[2] = crcBytes[0];
6034 temp_id_string[3] = crcBytes[1];
6035 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006036 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006037 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006038 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006039
6040 if (i == CLR_PRIORITY)
6041 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006042 FPT_scxferc(p_port,MISC_CODE);
6043 FPT_scxferc(p_port,CLR_P_FLAG);
6044 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006045 }
6046
6047 else if (i != NO_ID_AVAIL)
6048 {
6049 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006050 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006052 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006053
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006054 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006055
6056
6057 for (k=1; k < 0x08; k <<= 1)
6058 if (!( k & i ))
6059 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6060
James Bottomley 47b5d692005-04-24 02:38:05 -05006061 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006062
James Bottomley 47b5d692005-04-24 02:38:05 -05006063 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006064 }
6065 }
6066
6067 else
6068 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006069 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006070 }
6071
6072 } /*End while */
6073
James Bottomley 47b5d692005-04-24 02:38:05 -05006074 FPT_scxferc(p_port,SYNC_PTRN);
6075 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006076}
6077
6078
6079
6080
6081
6082/*---------------------------------------------------------------------
6083 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006084 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006085 *
6086 * Description: Select all the SCAM devices.
6087 *
6088 *---------------------------------------------------------------------*/
6089
James Bottomley 47b5d692005-04-24 02:38:05 -05006090static void FPT_scsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006091{
6092
6093 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006094 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006095
6096 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6097
6098
6099 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006100 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6101 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006102
6103
6104 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006105 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006106
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006107 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6108 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006109 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006110
6111 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6112}
6113
6114
6115
6116/*---------------------------------------------------------------------
6117 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006118 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006119 *
6120 * Description: Handshake the p_data (DB4-0) across the bus.
6121 *
6122 *---------------------------------------------------------------------*/
6123
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006124static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006125{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006126 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127
6128 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6129
6130 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6131
6132 curr_data &= ~BIT(7);
6133
6134 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6135
James Bottomley 47b5d692005-04-24 02:38:05 -05006136 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006137 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6138
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006139 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006140
6141 curr_data |= BIT(6);
6142
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6144
6145 curr_data &= ~BIT(5);
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(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006150
6151 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6152 curr_data |= BIT(7);
6153
6154 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6155
6156 curr_data &= ~BIT(6);
6157
6158 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6159
James Bottomley 47b5d692005-04-24 02:38:05 -05006160 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006161
6162 return(ret_data);
6163}
6164
6165
6166/*---------------------------------------------------------------------
6167 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006168 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006169 *
6170 * Description: Transfer our Identification string to determine if we
6171 * will be the dominant master.
6172 *
6173 *---------------------------------------------------------------------*/
6174
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006175static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006177 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006178
James Bottomley 47b5d692005-04-24 02:38:05 -05006179 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006180
6181 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6182
6183 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6184
6185 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006186 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006187
6188 else if (p_id_string[byte_cnt] & bit_cnt)
6189
James Bottomley 47b5d692005-04-24 02:38:05 -05006190 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006191
6192 else {
6193
James Bottomley 47b5d692005-04-24 02:38:05 -05006194 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006195 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006196 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006197 }
6198
6199 if ((ret_data & 0x1C) == 0x10)
6200 return(0x00); /*End of isolation stage, we won! */
6201
6202 if (ret_data & 0x1C)
6203 return(0xFF);
6204
6205 if ((defer) && (!(ret_data & 0x1F)))
6206 return(0x01); /*End of isolation stage, we lost. */
6207
6208 } /*bit loop */
6209
6210 } /*byte loop */
6211
6212 if (defer)
6213 return(0x01); /*We lost */
6214 else
6215 return(0); /*We WON! Yeeessss! */
6216}
6217
6218
6219
6220/*---------------------------------------------------------------------
6221 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006222 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006223 *
6224 * Description: Transfer the Identification string.
6225 *
6226 *---------------------------------------------------------------------*/
6227
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006228static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006229{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006230 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006231
6232 the_data = 0;
6233
6234 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6235
6236 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6237
James Bottomley 47b5d692005-04-24 02:38:05 -05006238 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006239
6240 if (ret_data & 0xFC)
6241 return(0xFF);
6242
6243 else {
6244
6245 the_data <<= 1;
6246 if (ret_data & BIT(1)) {
6247 the_data |= 1;
6248 }
6249 }
6250
6251 if ((ret_data & 0x1F) == 0)
6252 {
6253/*
6254 if(bit_cnt != 0 || bit_cnt != 8)
6255 {
6256 byte_cnt = 0;
6257 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006258 FPT_scxferc(p_port, SYNC_PTRN);
6259 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006260 continue;
6261 }
6262*/
6263 if (byte_cnt)
6264 return(0x00);
6265 else
6266 return(0xFF);
6267 }
6268
6269 } /*bit loop */
6270
6271 p_id_string[byte_cnt] = the_data;
6272
6273 } /*byte loop */
6274
6275 return(0);
6276}
6277
6278
6279
6280/*---------------------------------------------------------------------
6281 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006282 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006283 *
6284 * Description: Sample the SCSI data bus making sure the signal has been
6285 * deasserted for the correct number of consecutive samples.
6286 *
6287 *---------------------------------------------------------------------*/
6288
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006289static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006290{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006291 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006292
6293 i = 0;
6294 while ( i < MAX_SCSI_TAR ) {
6295
6296 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6297
6298 i = 0;
6299
6300 else
6301
6302 i++;
6303
6304 }
6305}
6306
6307
6308
6309/*---------------------------------------------------------------------
6310 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006311 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006312 *
6313 * Description: Sample the SCSI Signal lines making sure the signal has been
6314 * deasserted for the correct number of consecutive samples.
6315 *
6316 *---------------------------------------------------------------------*/
6317
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006318static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006319{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006320 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006321
6322 i = 0;
6323 while ( i < MAX_SCSI_TAR ) {
6324
6325 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6326
6327 i = 0;
6328
6329 else
6330
6331 i++;
6332
6333 }
6334}
6335
6336
6337/*---------------------------------------------------------------------
6338 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006339 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006340 *
6341 * Description: Make sure we received a valid data byte.
6342 *
6343 *---------------------------------------------------------------------*/
6344
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006345static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006347 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006348
6349 for (count=1; count < 0x08; count<<=1) {
6350 if (!(p_quintet & count))
6351 p_quintet -= 0x80;
6352 }
6353
6354 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006355 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006356
6357 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006358 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006359}
6360
6361
6362/*---------------------------------------------------------------------
6363 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006364 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006365 *
6366 * Description: Select the specified device ID using a selection timeout
6367 * less than 4ms. If somebody responds then it is a legacy
6368 * drive and this ID must be marked as such.
6369 *
6370 *---------------------------------------------------------------------*/
6371
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006372static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374 ULONG i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375
6376 WR_HARPOON(p_port+hp_page_ctrl,
6377 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6378
6379 ARAM_ACCESS(p_port);
6380
6381 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6382 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6383
6384
6385 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6386 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6387 }
6388 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6389
6390 WRW_HARPOON((p_port+hp_intstat),
6391 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6392
6393 WR_HARPOON(p_port+hp_select_id, targ_id);
6394
6395 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6396 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6397 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6398
6399
6400 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6401 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6402
6403 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006404 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006405
6406 DISABLE_AUTO(p_port);
6407
6408 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6409 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6410
6411 SGRAM_ACCESS(p_port);
6412
6413 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6414
6415 WRW_HARPOON((p_port+hp_intstat),
6416 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6417
6418 WR_HARPOON(p_port+hp_page_ctrl,
6419 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6420
James Bottomley 47b5d692005-04-24 02:38:05 -05006421 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006422 }
6423
6424 else {
6425
6426 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6427 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6428 {
6429 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6430 ACCEPT_MSG(p_port);
6431 }
6432 }
6433
6434 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6435
6436 WR_HARPOON(p_port+hp_page_ctrl,
6437 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6438
James Bottomley 47b5d692005-04-24 02:38:05 -05006439 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440 }
6441}
6442
Linus Torvalds1da177e2005-04-16 15:20:36 -07006443/*---------------------------------------------------------------------
6444 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006445 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446 *
6447 * Description: Wait to be selected by another SCAM initiator.
6448 *
6449 *---------------------------------------------------------------------*/
6450
James Bottomley 47b5d692005-04-24 02:38:05 -05006451static void FPT_scwtsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006452{
6453 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6454}
6455
6456
6457/*---------------------------------------------------------------------
6458 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006459 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460 *
6461 * Description: Setup the data Structure with the info from the EEPROM.
6462 *
6463 *---------------------------------------------------------------------*/
6464
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006465static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006467 unsigned char i,k,max_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006468 USHORT ee_data;
6469 PNVRamInfo pCurrNvRam;
6470
James Bottomley 47b5d692005-04-24 02:38:05 -05006471 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472
6473 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6474 max_id = 0x08;
6475
6476 else
6477 max_id = 0x10;
6478
6479 if(pCurrNvRam){
6480 for(i = 0; i < max_id; i++){
6481
6482 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006483 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006484 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006485 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006486
James Bottomley 47b5d692005-04-24 02:38:05 -05006487 if(FPT_scamInfo[i].id_string[0] == 0x00)
6488 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006490 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006491
6492 }
6493 }else {
6494 for (i=0; i < max_id; i++)
6495 {
6496 for (k=0; k < ID_STRING_LENGTH; k+=2)
6497 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006498 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006500 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006502 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503 }
6504
James Bottomley 47b5d692005-04-24 02:38:05 -05006505 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6506 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006507
James Bottomley 47b5d692005-04-24 02:38:05 -05006508 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006509
6510 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006511 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006512
6513 }
6514 }
6515 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006516 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006517
6518}
6519
6520/*---------------------------------------------------------------------
6521 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006522 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006523 *
6524 * Description: Match the Device ID string with our values stored in
6525 * the EEPROM.
6526 *
6527 *---------------------------------------------------------------------*/
6528
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006529static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006530{
6531
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006532 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006533
6534
6535 for (i=0; i < MAX_SCSI_TAR; i++) {
6536
James Bottomley 47b5d692005-04-24 02:38:05 -05006537 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538
6539 for (k=0; k < ID_STRING_LENGTH; k++)
6540 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006541 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6542 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006543 }
6544
6545 if (match)
6546 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006547 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 return(i);
6549 }
6550
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551 }
6552
6553
6554
6555 if (p_id_string[0] & BIT(5))
6556 i = 8;
6557 else
6558 i = MAX_SCSI_TAR;
6559
6560 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006561 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562 else
6563 match = 7;
6564
6565 while (i > 0)
6566 {
6567 i--;
6568
James Bottomley 47b5d692005-04-24 02:38:05 -05006569 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006570 {
6571 for (k=0; k < ID_STRING_LENGTH; k++)
6572 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006573 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006574 }
6575
James Bottomley 47b5d692005-04-24 02:38:05 -05006576 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006577
James Bottomley 47b5d692005-04-24 02:38:05 -05006578 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6579 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006580 return(match);
6581
6582 }
6583
6584
6585 match--;
6586
6587 if (match == 0xFF)
6588 {
6589 if (p_id_string[0] & BIT(5))
6590 match = 7;
6591 else
6592 match = MAX_SCSI_TAR-1;
6593 }
6594 }
6595
6596
6597
6598 if (p_id_string[0] & BIT(7))
6599 {
6600 return(CLR_PRIORITY);
6601 }
6602
6603
6604 if (p_id_string[0] & BIT(5))
6605 i = 8;
6606 else
6607 i = MAX_SCSI_TAR;
6608
6609 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006610 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006611 else
6612 match = 7;
6613
6614 while (i > 0)
6615 {
6616
6617 i--;
6618
James Bottomley 47b5d692005-04-24 02:38:05 -05006619 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006620 {
6621 for (k=0; k < ID_STRING_LENGTH; k++)
6622 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006623 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006624 }
6625
James Bottomley 47b5d692005-04-24 02:38:05 -05006626 FPT_scamInfo[match].id_string[0] |= BIT(7);
6627 FPT_scamInfo[match].state = ID_ASSIGNED;
6628 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6629 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006630 return(match);
6631
6632 }
6633
6634
6635 match--;
6636
6637 if (match == 0xFF)
6638 {
6639 if (p_id_string[0] & BIT(5))
6640 match = 7;
6641 else
6642 match = MAX_SCSI_TAR-1;
6643 }
6644 }
6645
6646 return(NO_ID_AVAIL);
6647}
6648
6649
6650/*---------------------------------------------------------------------
6651 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006652 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006653 *
6654 * Description: Save off the device SCAM ID strings.
6655 *
6656 *---------------------------------------------------------------------*/
6657
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006658static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006660 unsigned char i,k,max_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006661 USHORT ee_data,sum_data;
6662
6663
6664 sum_data = 0x0000;
6665
6666 for (i = 1; i < EE_SCAMBASE/2; i++)
6667 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006668 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006669 }
6670
6671
James Bottomley 47b5d692005-04-24 02:38:05 -05006672 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006673
6674 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6675 max_id = 0x08;
6676
6677 else
6678 max_id = 0x10;
6679
6680 for (i=0; i < max_id; i++)
6681 {
6682
6683 for (k=0; k < ID_STRING_LENGTH; k+=2)
6684 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006685 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006687 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006688 sum_data += ee_data;
James Bottomley 47b5d692005-04-24 02:38:05 -05006689 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6691 }
6692 }
6693
6694
James Bottomley 47b5d692005-04-24 02:38:05 -05006695 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6696 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006697}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698
6699/*---------------------------------------------------------------------
6700 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006701 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006702 *
6703 * Description: Setup the Xbow for normal operation.
6704 *
6705 *---------------------------------------------------------------------*/
6706
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006707static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006708{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006709unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006710
6711 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006712 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006713
6714 WR_HARPOON(port+hp_scsireset,0x00);
6715 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6716
6717 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6718 FIFO_CLR));
6719
6720 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6721
6722 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6723
6724 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6725 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6726
6727 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6728
James Bottomley 47b5d692005-04-24 02:38:05 -05006729 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006730 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6731
6732 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006733 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006734
James Bottomley 47b5d692005-04-24 02:38:05 -05006735 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006736
6737 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6738
6739 /* Turn on SCSI_MODE8 for narrow cards to fix the
6740 strapping issue with the DUAL CHANNEL card */
6741 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6742 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6743
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744 WR_HARPOON(port+hp_page_ctrl, i);
6745
6746}
6747
6748
6749/*---------------------------------------------------------------------
6750 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006751 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006752 *
6753 * Description: Initialize the BusMaster for normal operations.
6754 *
6755 *---------------------------------------------------------------------*/
6756
James Bottomley 47b5d692005-04-24 02:38:05 -05006757static void FPT_BusMasterInit(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006758{
6759
6760
6761 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6762 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6763
6764 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6765
6766
6767 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6768
6769 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6770
6771
Linus Torvalds1da177e2005-04-16 15:20:36 -07006772 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6773 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6774 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6775 ~SCATTER_EN));
6776}
6777
6778
6779/*---------------------------------------------------------------------
6780 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006781 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006782 *
6783 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6784 * necessary.
6785 *
6786 *---------------------------------------------------------------------*/
6787
James Bottomley 47b5d692005-04-24 02:38:05 -05006788static void FPT_DiagEEPROM(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789{
6790 USHORT index,temp,max_wd_cnt;
6791
6792 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6793 max_wd_cnt = EEPROM_WD_CNT;
6794 else
6795 max_wd_cnt = EEPROM_WD_CNT * 2;
6796
James Bottomley 47b5d692005-04-24 02:38:05 -05006797 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006798
6799 if (temp == 0x4641) {
6800
6801 for (index = 2; index < max_wd_cnt; index++) {
6802
James Bottomley 47b5d692005-04-24 02:38:05 -05006803 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006804
6805 }
6806
James Bottomley 47b5d692005-04-24 02:38:05 -05006807 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006808
6809 return; /*EEPROM is Okay so return now! */
6810 }
6811 }
6812
6813
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006814 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815
6816 for (index = 0; index < max_wd_cnt; index++) {
6817
James Bottomley 47b5d692005-04-24 02:38:05 -05006818 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819 }
6820
6821 temp = 0;
6822
James Bottomley 47b5d692005-04-24 02:38:05 -05006823 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006825 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006827 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006829 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006833 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006835 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006837 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838 temp += 0x0007;
6839
James Bottomley 47b5d692005-04-24 02:38:05 -05006840 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006842 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006844 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845 temp += 0x0000;
6846
James Bottomley 47b5d692005-04-24 02:38:05 -05006847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006852 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006853 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006855 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006857 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006859 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006861 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 temp += 0x4242;
6863
6864
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006866 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006867 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006868 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006869 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006871 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006873 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006875 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006877 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006878 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006879 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006880 temp += 0x2020;
6881
6882 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006883 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006884 temp += (0x0700+TYPE_CODE0);
6885 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006886 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887 temp += 0x5542; /* BUSLOGIC */
6888 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006889 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890 temp += 0x4C53;
6891 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006892 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006893 temp += 0x474F;
6894 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006895 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006896 temp += 0x4349;
6897 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006898 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006899 temp += 0x5442; /* BT- 930 */
6900 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006901 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006902 temp += 0x202D;
6903 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006904 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006905 temp += 0x3339;
6906 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006907 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006908 temp += 0x2030;
6909 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006910 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911 temp += 0x5453;
6912 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006913 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006914 temp += 0x5645;
6915 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006916 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006917 temp += 0x2045;
6918 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006919 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006920 temp += 0x202F;
6921 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006922 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006923 temp += 0x4F4A;
6924 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006925 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006926 temp += 0x204E;
6927 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006928 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006929 temp += 0x3539;
6930
6931
6932
James Bottomley 47b5d692005-04-24 02:38:05 -05006933 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006935 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006936
6937}
6938
Linus Torvalds1da177e2005-04-16 15:20:36 -07006939
6940/*---------------------------------------------------------------------
6941 *
6942 * Function: Queue Search Select
6943 *
6944 * Description: Try to find a new command to execute.
6945 *
6946 *---------------------------------------------------------------------*/
6947
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006948static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006949{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006950 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006951 PSCCBMgr_tar_info currTar_Info;
6952 PSCCB pOldSccb;
6953
6954 scan_ptr = pCurrCard->scanIndex;
6955 do
6956 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006957 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006958 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6959 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6960 {
6961 if (currTar_Info->TarSelQ_Cnt != 0)
6962 {
6963
6964 scan_ptr++;
6965 if (scan_ptr == MAX_SCSI_TAR)
6966 scan_ptr = 0;
6967
6968 for(lun=0; lun < MAX_LUN; lun++)
6969 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006970 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006971 {
6972
6973 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6974 pOldSccb = NULL;
6975
6976 while((pCurrCard->currentSCCB != NULL) &&
6977 (lun != pCurrCard->currentSCCB->Lun))
6978 {
6979 pOldSccb = pCurrCard->currentSCCB;
6980 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6981 Sccb_forwardlink;
6982 }
6983 if(pCurrCard->currentSCCB == NULL)
6984 continue;
6985 if(pOldSccb != NULL)
6986 {
6987 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6988 Sccb_forwardlink;
6989 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6990 Sccb_backlink;
6991 currTar_Info->TarSelQ_Cnt--;
6992 }
6993 else
6994 {
6995 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6996
6997 if (currTar_Info->TarSelQ_Head == NULL)
6998 {
6999 currTar_Info->TarSelQ_Tail = NULL;
7000 currTar_Info->TarSelQ_Cnt = 0;
7001 }
7002 else
7003 {
7004 currTar_Info->TarSelQ_Cnt--;
7005 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7006 }
7007 }
7008 pCurrCard->scanIndex = scan_ptr;
7009
7010 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7011
7012 break;
7013 }
7014 }
7015 }
7016
7017 else
7018 {
7019 scan_ptr++;
7020 if (scan_ptr == MAX_SCSI_TAR) {
7021 scan_ptr = 0;
7022 }
7023 }
7024
7025 }
7026 else
7027 {
7028 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007029 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007030 {
7031
7032 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7033
7034 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7035
7036 if (currTar_Info->TarSelQ_Head == NULL)
7037 {
7038 currTar_Info->TarSelQ_Tail = NULL;
7039 currTar_Info->TarSelQ_Cnt = 0;
7040 }
7041 else
7042 {
7043 currTar_Info->TarSelQ_Cnt--;
7044 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7045 }
7046
7047 scan_ptr++;
7048 if (scan_ptr == MAX_SCSI_TAR)
7049 scan_ptr = 0;
7050
7051 pCurrCard->scanIndex = scan_ptr;
7052
7053 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7054
7055 break;
7056 }
7057
7058 else
7059 {
7060 scan_ptr++;
7061 if (scan_ptr == MAX_SCSI_TAR)
7062 {
7063 scan_ptr = 0;
7064 }
7065 }
7066 }
7067 } while (scan_ptr != pCurrCard->scanIndex);
7068}
7069
7070
7071/*---------------------------------------------------------------------
7072 *
7073 * Function: Queue Select Fail
7074 *
7075 * Description: Add the current SCCB to the head of the Queue.
7076 *
7077 *---------------------------------------------------------------------*/
7078
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007079static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007080{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007081 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007082 PSCCBMgr_tar_info currTar_Info;
7083
7084 if (pCurrCard->currentSCCB != NULL)
7085 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007086 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007087 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007088
7089 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7090
7091 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7092
7093 if (currTar_Info->TarSelQ_Cnt == 0)
7094 {
7095 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7096 }
7097
7098 else
7099 {
7100 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7101 }
7102
7103
7104 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7105
7106 pCurrCard->currentSCCB = NULL;
7107 currTar_Info->TarSelQ_Cnt++;
7108 }
7109}
7110/*---------------------------------------------------------------------
7111 *
7112 * Function: Queue Command Complete
7113 *
7114 * Description: Call the callback function with the current SCCB.
7115 *
7116 *---------------------------------------------------------------------*/
7117
James Bottomley 47b5d692005-04-24 02:38:05 -05007118static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007119 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007120{
7121
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007122 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007123 CALL_BK_FN callback;
7124 PSCCBMgr_tar_info currTar_Info;
7125
7126 SCSIcmd = p_sccb->Cdb[0];
7127
7128
7129 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7130
7131 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7132 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7133 (p_sccb->TargetStatus != SSCHECK))
7134
7135 if ((SCSIcmd == SCSI_READ) ||
7136 (SCSIcmd == SCSI_WRITE) ||
7137 (SCSIcmd == SCSI_READ_EXTENDED) ||
7138 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7139 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7140 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7141 (pCurrCard->globalFlags & F_NO_FILTER)
7142 )
7143 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7144 }
7145
7146
7147 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7148 {
7149 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7150 p_sccb->SccbStatus = SCCB_ERROR;
7151 else
7152 p_sccb->SccbStatus = SCCB_SUCCESS;
7153 }
7154
7155 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7156
7157 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7158 for (i=0; i < 6; i++) {
7159 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7160 }
7161 }
7162
7163 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7164 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7165
James Bottomley 47b5d692005-04-24 02:38:05 -05007166 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007167 }
7168
7169 pCurrCard->cmdCounter--;
7170 if (!pCurrCard->cmdCounter) {
7171
7172 if (pCurrCard->globalFlags & F_GREEN_PC) {
7173 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7174 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7175 }
7176
7177 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7178 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7179
7180 }
7181
7182 if(pCurrCard->discQCount != 0)
7183 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007184 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007185 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7186 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7187 {
7188 pCurrCard->discQCount--;
7189 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7190 }
7191 else
7192 {
7193 if(p_sccb->Sccb_tag)
7194 {
7195 pCurrCard->discQCount--;
7196 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7197 }else
7198 {
7199 pCurrCard->discQCount--;
7200 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7201 }
7202 }
7203
7204 }
7205
7206 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7207 callback(p_sccb);
7208 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7209 pCurrCard->currentSCCB = NULL;
7210}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007211
7212
7213/*---------------------------------------------------------------------
7214 *
7215 * Function: Queue Disconnect
7216 *
7217 * Description: Add SCCB to our disconnect array.
7218 *
7219 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007220static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007221{
7222 PSCCBMgr_tar_info currTar_Info;
7223
James Bottomley 47b5d692005-04-24 02:38:05 -05007224 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007225
James Bottomley 47b5d692005-04-24 02:38:05 -05007226 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007227 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7228 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007229 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007230 }
7231 else
7232 {
7233 if (p_sccb->Sccb_tag)
7234 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007235 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7236 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7237 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007238 }else
7239 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007240 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007241 }
7242 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007243 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007244}
7245
7246
7247/*---------------------------------------------------------------------
7248 *
7249 * Function: Queue Flush SCCB
7250 *
7251 * Description: Flush all SCCB's back to the host driver for this target.
7252 *
7253 *---------------------------------------------------------------------*/
7254
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007255static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007256{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007257 unsigned char qtag,thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007258 PSCCB currSCCB;
7259 PSCCBMgr_tar_info currTar_Info;
7260
James Bottomley 47b5d692005-04-24 02:38:05 -05007261 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007262 if(currSCCB != NULL)
7263 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007264 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007265 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007266
7267 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7268
James Bottomley 47b5d692005-04-24 02:38:05 -05007269 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7270 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007271 {
7272
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007273 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007274
James Bottomley 47b5d692005-04-24 02:38:05 -05007275 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007276
James Bottomley 47b5d692005-04-24 02:38:05 -05007277 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007278 currTar_Info->TarTagQ_Cnt--;
7279
7280 }
7281 }
7282 }
7283
7284}
7285
7286/*---------------------------------------------------------------------
7287 *
7288 * Function: Queue Flush Target SCCB
7289 *
7290 * Description: Flush all SCCB's back to the host driver for this target.
7291 *
7292 *---------------------------------------------------------------------*/
7293
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007294static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7295 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007297 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007298 PSCCBMgr_tar_info currTar_Info;
7299
James Bottomley 47b5d692005-04-24 02:38:05 -05007300 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007301
7302 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7303
James Bottomley 47b5d692005-04-24 02:38:05 -05007304 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7305 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007306 {
7307
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007308 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007309
James Bottomley 47b5d692005-04-24 02:38:05 -05007310 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007311
James Bottomley 47b5d692005-04-24 02:38:05 -05007312 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007313 currTar_Info->TarTagQ_Cnt--;
7314
7315 }
7316 }
7317
7318}
7319
7320
7321
7322
7323
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007324static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007325{
7326 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007327 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007328
7329 p_SCCB->Sccb_forwardlink = NULL;
7330
7331 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7332
7333 if (currTar_Info->TarSelQ_Cnt == 0) {
7334
7335 currTar_Info->TarSelQ_Head = p_SCCB;
7336 }
7337
7338 else {
7339
7340 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7341 }
7342
7343
7344 currTar_Info->TarSelQ_Tail = p_SCCB;
7345 currTar_Info->TarSelQ_Cnt++;
7346}
7347
7348
7349/*---------------------------------------------------------------------
7350 *
7351 * Function: Queue Find SCCB
7352 *
7353 * Description: Search the target select Queue for this SCCB, and
7354 * remove it if found.
7355 *
7356 *---------------------------------------------------------------------*/
7357
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007358static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007359{
7360 PSCCB q_ptr;
7361 PSCCBMgr_tar_info currTar_Info;
7362
James Bottomley 47b5d692005-04-24 02:38:05 -05007363 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007364
7365 q_ptr = currTar_Info->TarSelQ_Head;
7366
7367 while(q_ptr != NULL) {
7368
7369 if (q_ptr == p_SCCB) {
7370
7371
7372 if (currTar_Info->TarSelQ_Head == q_ptr) {
7373
7374 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7375 }
7376
7377 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7378
7379 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7380 }
7381
7382 if (q_ptr->Sccb_forwardlink != NULL) {
7383 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7384 }
7385
7386 if (q_ptr->Sccb_backlink != NULL) {
7387 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7388 }
7389
7390 currTar_Info->TarSelQ_Cnt--;
7391
James Bottomley 47b5d692005-04-24 02:38:05 -05007392 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007393 }
7394
7395 else {
7396 q_ptr = q_ptr->Sccb_forwardlink;
7397 }
7398 }
7399
7400
James Bottomley 47b5d692005-04-24 02:38:05 -05007401 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007402
7403}
7404
7405
7406/*---------------------------------------------------------------------
7407 *
7408 * Function: Utility Update Residual Count
7409 *
7410 * Description: Update the XferCnt to the remaining byte count.
7411 * If we transferred all the data then just write zero.
7412 * If Non-SG transfer then report Total Cnt - Actual Transfer
7413 * Cnt. For SG transfers add the count fields of all
7414 * remaining SG elements, as well as any partial remaining
7415 * element.
7416 *
7417 *---------------------------------------------------------------------*/
7418
James Bottomley 47b5d692005-04-24 02:38:05 -05007419static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007420{
7421 ULONG partial_cnt;
7422 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007423 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007424
7425 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7426
7427 p_SCCB->DataLength = 0x0000;
7428 }
7429
7430 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7431
7432 partial_cnt = 0x0000;
7433
7434 sg_index = p_SCCB->Sccb_sgseg;
7435
Linus Torvalds1da177e2005-04-16 15:20:36 -07007436 sg_ptr = (ULONG *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007437
7438 if (p_SCCB->Sccb_SGoffset) {
7439
7440 partial_cnt = p_SCCB->Sccb_SGoffset;
7441 sg_index++;
7442 }
7443
7444 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7445 p_SCCB->DataLength ) {
7446
7447 partial_cnt += *(sg_ptr+(sg_index * 2));
7448 sg_index++;
7449 }
7450
7451 p_SCCB->DataLength = partial_cnt;
7452 }
7453
7454 else {
7455
7456 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7457 }
7458}
7459
7460
7461/*---------------------------------------------------------------------
7462 *
7463 * Function: Wait 1 Second
7464 *
7465 * Description: Wait for 1 second.
7466 *
7467 *---------------------------------------------------------------------*/
7468
James Bottomley 47b5d692005-04-24 02:38:05 -05007469static void FPT_Wait1Second(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007470{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007471 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007472
7473 for(i=0; i < 4; i++) {
7474
James Bottomley 47b5d692005-04-24 02:38:05 -05007475 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007476
7477 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7478 break;
7479
7480 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7481 break;
7482 }
7483}
7484
7485
7486/*---------------------------------------------------------------------
7487 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007488 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007489 *
7490 * Description: Wait the desired delay.
7491 *
7492 *---------------------------------------------------------------------*/
7493
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007494static void FPT_Wait(ULONG p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007495{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007496 unsigned char old_timer;
7497 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007498
7499 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7500
7501 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7502 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7503
7504 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7505 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007506 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007507
7508
7509 WR_HARPOON(p_port+hp_portctrl_0,
7510 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7511
7512 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7513
7514 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7515 break;
7516
7517 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7518 break;
7519 }
7520
7521 WR_HARPOON(p_port+hp_portctrl_0,
7522 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7523
7524 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007525 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007526
7527 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7528
7529 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7530}
7531
7532
7533/*---------------------------------------------------------------------
7534 *
7535 * Function: Enable/Disable Write to EEPROM
7536 *
7537 * Description: The EEPROM must first be enabled for writes
7538 * A total of 9 clocks are needed.
7539 *
7540 *---------------------------------------------------------------------*/
7541
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007542static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007543{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007544 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007545
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007546 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 -07007547
7548 if (p_mode)
7549
James Bottomley 47b5d692005-04-24 02:38:05 -05007550 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007551
7552 else
7553
7554
James Bottomley 47b5d692005-04-24 02:38:05 -05007555 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007556
7557 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7558 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7559}
7560
7561
7562/*---------------------------------------------------------------------
7563 *
7564 * Function: Write EEPROM
7565 *
7566 * Description: Write a word to the EEPROM at the specified
7567 * address.
7568 *
7569 *---------------------------------------------------------------------*/
7570
James Bottomley 47b5d692005-04-24 02:38:05 -05007571static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007572{
7573
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007574 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007575 USHORT i;
7576
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007577 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 -07007578 (SEE_MS | SEE_CS));
7579
7580
7581
James Bottomley 47b5d692005-04-24 02:38:05 -05007582 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007583
7584
7585 ee_value |= (SEE_MS + SEE_CS);
7586
7587 for(i = 0x8000; i != 0; i>>=1) {
7588
7589 if (i & ee_data)
7590 ee_value |= SEE_DO;
7591 else
7592 ee_value &= ~SEE_DO;
7593
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 ee_value |= SEE_CLK; /* Clock data! */
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 ee_value &= ~SEE_CLK;
7600 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7601 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7602 }
7603 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7604 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7605
James Bottomley 47b5d692005-04-24 02:38:05 -05007606 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007607
7608 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7609 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7610 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7611}
7612
7613/*---------------------------------------------------------------------
7614 *
7615 * Function: Read EEPROM
7616 *
7617 * Description: Read a word from the EEPROM at the desired
7618 * address.
7619 *
7620 *---------------------------------------------------------------------*/
7621
James Bottomley 47b5d692005-04-24 02:38:05 -05007622static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007623{
7624 USHORT i, ee_data1, ee_data2;
7625
7626 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007627 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007628 do
7629 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007630 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007631
7632 if(ee_data1 == ee_data2)
7633 return(ee_data1);
7634
7635 ee_data1 = ee_data2;
7636 i++;
7637
7638 }while(i < 4);
7639
7640 return(ee_data1);
7641}
7642
7643/*---------------------------------------------------------------------
7644 *
7645 * Function: Read EEPROM Original
7646 *
7647 * Description: Read a word from the EEPROM at the desired
7648 * address.
7649 *
7650 *---------------------------------------------------------------------*/
7651
James Bottomley 47b5d692005-04-24 02:38:05 -05007652static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007653{
7654
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007655 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007656 USHORT i, ee_data;
7657
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007658 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 -07007659 (SEE_MS | SEE_CS));
7660
7661
James Bottomley 47b5d692005-04-24 02:38:05 -05007662 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007663
7664
7665 ee_value |= (SEE_MS + SEE_CS);
7666 ee_data = 0;
7667
7668 for(i = 1; i <= 16; i++) {
7669
7670 ee_value |= SEE_CLK; /* Clock data! */
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 ee_value &= ~SEE_CLK;
7674 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7676
7677 ee_data <<= 1;
7678
7679 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7680 ee_data |= 1;
7681 }
7682
7683 ee_value &= ~(SEE_MS + SEE_CS);
7684 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7685 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7686
7687 return(ee_data);
7688}
7689
7690
7691/*---------------------------------------------------------------------
7692 *
7693 * Function: Send EE command and Address to the EEPROM
7694 *
7695 * Description: Transfers the correct command and sends the address
7696 * to the eeprom.
7697 *
7698 *---------------------------------------------------------------------*/
7699
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007700static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007701{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007702 unsigned char ee_value;
7703 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007704
7705 USHORT i;
7706
7707
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007708 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007709
7710
7711 ee_value = SEE_MS;
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713
7714 ee_value |= SEE_CS; /* Set CS to EEPROM */
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716
7717
7718 for(i = 0x04; i != 0; i>>=1) {
7719
7720 if (i & ee_cmd)
7721 ee_value |= SEE_DO;
7722 else
7723 ee_value &= ~SEE_DO;
7724
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 ee_value |= SEE_CLK; /* Clock data! */
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 ee_value &= ~SEE_CLK;
7731 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7733 }
7734
7735
7736 if (narrow_flg)
7737 i = 0x0080;
7738
7739 else
7740 i = 0x0200;
7741
7742
7743 while (i != 0) {
7744
7745 if (i & ee_addr)
7746 ee_value |= SEE_DO;
7747 else
7748 ee_value &= ~SEE_DO;
7749
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 ee_value |= SEE_CLK; /* Clock data! */
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 ee_value &= ~SEE_CLK;
7756 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7757 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7758
7759 i >>= 1;
7760 }
7761}
7762
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007763static USHORT FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007764{
7765 USHORT crc=0;
7766 int i,j;
7767 USHORT ch;
7768 for (i=0; i < ID_STRING_LENGTH; i++)
7769 {
7770 ch = (USHORT) buffer[i];
7771 for(j=0; j < 8; j++)
7772 {
7773 if ((crc ^ ch) & 1)
7774 crc = (crc >> 1) ^ CRCMASK;
7775 else
7776 crc >>= 1;
7777 ch >>= 1;
7778 }
7779 }
7780 return(crc);
7781}
7782
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007783static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007784{
7785 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007786 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007787 lrc = 0;
7788 for(i = 0; i < ID_STRING_LENGTH; i++)
7789 lrc ^= buffer[i];
7790 return(lrc);
7791}
7792
7793
7794
7795/*
7796 The following inline definitions avoid type conflicts.
7797*/
7798
7799static inline unsigned char
7800FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7801{
7802 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7803}
7804
7805
7806static inline FlashPoint_CardHandle_T
7807FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7808{
7809 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7810}
7811
7812static inline void
7813FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7814{
7815 FlashPoint_ReleaseHostAdapter(CardHandle);
7816}
7817
7818
7819static inline void
7820FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7821{
7822 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7823}
7824
7825
7826static inline void
7827FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7828{
7829 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7830}
7831
7832
7833static inline boolean
7834FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7835{
7836 return FlashPoint_InterruptPending(CardHandle);
7837}
7838
7839
7840static inline int
7841FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7842{
7843 return FlashPoint_HandleInterrupt(CardHandle);
7844}
7845
7846
7847#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7848#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7849#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7850#define FlashPoint_StartCCB FlashPoint__StartCCB
7851#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7852#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7853#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7854
7855
Linus Torvalds1da177e2005-04-16 15:20:36 -07007856#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7857
7858
7859/*
7860 Define prototypes for the FlashPoint SCCB Manager Functions.
7861*/
7862
7863extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7864extern FlashPoint_CardHandle_T
7865 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7866extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7867extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7868extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7869extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7870extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007871
7872
7873#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */