blob: a981dea3bbfb50383c8ca829473dda867904b895 [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 long ULONG;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
45
Linus Torvalds1da177e2005-04-16 15:20:36 -070046typedef unsigned short * ushort_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
48
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#define s08bits char
50#define s16bits short
51#define s32bits long
52
53#define u08bits unsigned s08bits
54#define u16bits unsigned s16bits
55#define u32bits unsigned s32bits
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080059#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080060#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
62
63
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
James Bottomley 47b5d692005-04-24 02:38:05 -050065typedef struct _SCCB *PSCCB;
66typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
68
69typedef struct SCCBMgr_info {
70 ULONG si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080071 unsigned char si_present;
72 unsigned char si_intvect;
73 unsigned char si_id;
74 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080075 unsigned short si_fw_revision;
76 unsigned short si_per_targ_init_sync;
77 unsigned short si_per_targ_fast_nego;
78 unsigned short si_per_targ_ultra_nego;
79 unsigned short si_per_targ_no_disc;
80 unsigned short si_per_targ_wide_nego;
81 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080082 unsigned char si_card_family;
83 unsigned char si_bustype;
84 unsigned char si_card_model[3];
85 unsigned char si_relative_cardnum;
86 unsigned char si_reserved[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -070087 ULONG si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080088 unsigned char si_XlatInfo[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 ULONG si_reserved2[5];
90 ULONG si_secondary_range;
91} SCCBMGR_INFO;
92
James Bottomley 47b5d692005-04-24 02:38:05 -050093typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
95
James Bottomley 47b5d692005-04-24 02:38:05 -050096#define SCSI_PARITY_ENA 0x0001
97#define LOW_BYTE_TERM 0x0010
98#define HIGH_BYTE_TERM 0x0020
99#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
101#define SUPPORT_16TAR_32LUN 0x0002
102#define SOFT_RESET 0x0004
103#define EXTENDED_TRANSLATION 0x0008
104#define POST_ALL_UNDERRRUNS 0x0040
105#define FLAG_SCAM_ENABLED 0x0080
106#define FLAG_SCAM_LEVEL2 0x0100
107
108
109
110
111#define HARPOON_FAMILY 0x02
112
113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Alexey Dobriyan323579882006-01-15 02:12:54 +0100115/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 * The UCB Manager treats the SCCB as it's 'native hardware structure'
117 */
118
119
120#pragma pack(1)
121typedef struct _SCCB {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800122 unsigned char OperationCode;
123 unsigned char ControlByte;
124 unsigned char CdbLength;
125 unsigned char RequestSenseLength;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 ULONG DataLength;
127 ULONG DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800128 unsigned char CcbRes[2];
129 unsigned char HostStatus;
130 unsigned char TargetStatus;
131 unsigned char TargID;
132 unsigned char Lun;
133 unsigned char Cdb[12];
134 unsigned char CcbRes1;
135 unsigned char Reserved1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 ULONG Reserved2;
137 ULONG SensePointer;
138
139
140 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
141 ULONG SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800142 unsigned char SccbStatus;
143 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800144 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146
147 ULONG Sccb_XferCnt; /* actual transfer count */
148 ULONG Sccb_ATC;
149 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
150 ULONG Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800151 unsigned short Sccb_MGRFlags;
152 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800153 unsigned char Sccb_scsimsg; /* identify msg for selection */
154 unsigned char Sccb_tag;
155 unsigned char Sccb_scsistat;
156 unsigned char Sccb_idmsg; /* image of last msg in */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 PSCCB Sccb_forwardlink;
158 PSCCB Sccb_backlink;
159 ULONG Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800160 unsigned char Save_Cdb[6];
161 unsigned char Save_CdbLen;
162 unsigned char Sccb_XferState;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 ULONG Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 } SCCB;
165
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
167#pragma pack()
168
169
170
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171#define SCATTER_GATHER_COMMAND 0x02
172#define RESIDUAL_COMMAND 0x03
173#define RESIDUAL_SG_COMMAND 0x04
174#define RESET_COMMAND 0x81
175
176
177#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
178#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179#define SCCB_DATA_XFER_OUT 0x10 /* Write */
180#define SCCB_DATA_XFER_IN 0x08 /* Read */
181
182
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
184
185
186#define BUS_FREE_ST 0
187#define SELECT_ST 1
188#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
189#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
190#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
191#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
192#define COMMAND_ST 6
193#define DATA_OUT_ST 7
194#define DATA_IN_ST 8
195#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
198
199#define F_HOST_XFER_DIR 0x01
200#define F_ALL_XFERRED 0x02
201#define F_SG_XFER 0x04
202#define F_AUTO_SENSE 0x08
203#define F_ODD_BALL_CNT 0x10
204#define F_NO_DATA_YET 0x80
205
206
207#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208#define F_DEV_SELECTED 0x04
209
210
211#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
212#define SCCB_DATA_UNDER_RUN 0x0C
213#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
214#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
216
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
218#define SCCB_BM_ERR 0x30 /* BusMaster error. */
219#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
220
221
222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223
224
225#define SCCB_IN_PROCESS 0x00
226#define SCCB_SUCCESS 0x01
227#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232#define ORION_FW_REV 3110
233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
235
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
238#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240
James Bottomley 47b5d692005-04-24 02:38:05 -0500241#define MAX_SCSI_TAR 16
242#define MAX_LUN 32
243#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -0800250#define RD_HARPOON(ioport) inb((u32bits)ioport)
251#define RDW_HARPOON(ioport) inw((u32bits)ioport)
252#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
253#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
254#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
255#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
257
258#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259#define SYNC_TRYING BIT(6)
260#define SYNC_SUPPORTED (BIT(7)+BIT(6))
261
262#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263#define WIDE_ENABLED BIT(4)
264#define WIDE_NEGOCIATED BIT(5)
265
266#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267#define TAG_Q_TRYING BIT(2)
268#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269
270#define TAR_ALLOW_DISC BIT(0)
271
272
273#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274#define EE_SYNC_5MB BIT(0)
275#define EE_SYNC_10MB BIT(1)
276#define EE_SYNC_20MB (BIT(0)+BIT(1))
277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278#define EE_WIDE_SCSI BIT(7)
279
280
James Bottomley 47b5d692005-04-24 02:38:05 -0500281typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
283
284typedef struct SCCBMgr_tar_info {
285
286 PSCCB TarSelQ_Head;
287 PSCCB TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800288 unsigned char TarLUN_CA; /*Contingent Allgiance */
289 unsigned char TarTagQ_Cnt;
290 unsigned char TarSelQ_Cnt;
291 unsigned char TarStatus;
292 unsigned char TarEEValue;
293 unsigned char TarSyncCtrl;
294 unsigned char TarReserved[2]; /* for alignment */
295 unsigned char LunDiscQ_Idx[MAX_LUN];
296 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297} SCCBMGR_TAR_INFO;
298
299typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800300 unsigned char niModel; /* Model No. of card */
301 unsigned char niCardNo; /* Card no. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 ULONG niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800303 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
304 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
305 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
306 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
307 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
308 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309}NVRAMINFO;
310
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
313#define MODEL_LT 1
314#define MODEL_DL 2
315#define MODEL_LW 3
316#define MODEL_DW 4
317
318
319typedef struct SCCBcard {
320 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 ULONG ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800325 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800326 unsigned char discQCount;
327 unsigned char tagQ_Lst;
328 unsigned char cardIndex;
329 unsigned char scanIndex;
330 unsigned char globalFlags;
331 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 PNVRamInfo pNvRamInfo;
333 PSCCB discQ_Tbl[QUEUE_DEPTH];
334
335}SCCBCARD;
336
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
339
340#define F_TAG_STARTED 0x01
341#define F_CONLUN_IO 0x02
342#define F_DO_RENEGO 0x04
343#define F_NO_FILTER 0x08
344#define F_GREEN_PC 0x10
345#define F_HOST_XFER_ACT 0x20
346#define F_NEW_SCCB_CMD 0x40
347#define F_UPDATE_EEPROM 0x80
348
349
350#define ID_STRING_LENGTH 32
351#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
354#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
355
356#define ASSIGN_ID 0x00
357#define SET_P_FLAG 0x01
358#define CFG_CMPLT 0x03
359#define DOM_MSTR 0x0F
360#define SYNC_PTRN 0x1F
361
362#define ID_0_7 0x18
363#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364#define MISC_CODE 0x14
365#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367
368
369#define INIT_SELTD 0x01
370#define LEVEL2_TAR 0x02
371
372
373enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
374 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
375 CLR_PRIORITY,NO_ID_AVAIL };
376
377typedef struct SCCBscam_info {
378
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800379 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 enum scam_id_st state;
381
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800382} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386#define SCSI_READ 0x08
387#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389#define SCSI_READ_EXTENDED 0x28
390#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
393
394
395#define SSGOOD 0x00
396#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397#define SSQ_FULL 0x28
398
399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
401
402#define SMCMD_COMP 0x00
403#define SMEXT 0x01
404#define SMSAVE_DATA_PTR 0x02
405#define SMREST_DATA_PTR 0x03
406#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407#define SMABORT 0x06
408#define SMREJECT 0x07
409#define SMNO_OP 0x08
410#define SMPARITY 0x09
411#define SMDEV_RESET 0x0C
412#define SMABORT_TAG 0x0D
413#define SMINIT_RECOVERY 0x0F
414#define SMREL_RECOVERY 0x10
415
416#define SMIDENT 0x80
417#define DISC_PRIV 0x40
418
419
420#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421#define SMWDTR 0x03
422#define SM8BIT 0x00
423#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424#define SMIGNORWR 0x23 /* Ignore Wide Residue */
425
426
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
428
429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431
432
433#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434#define TWELVE_BYTE_CMD 0x0C
435
436#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
438
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
440#define EEPROM_WD_CNT 256
441
442#define EEPROM_CHECK_SUM 0
443#define FW_SIGNATURE 2
444#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447#define SYSTEM_CONFIG 16
448#define SCSI_CONFIG 17
449#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450#define SCAM_CONFIG 20
451#define ADAPTER_SCSI_ID 24
452
453
454#define IGNORE_B_SCAN 32
455#define SEND_START_ENA 34
456#define DEVICE_ENABLE 36
457
458#define SYNC_RATE_TBL 38
459#define SYNC_RATE_TBL01 38
460#define SYNC_RATE_TBL23 40
461#define SYNC_RATE_TBL45 42
462#define SYNC_RATE_TBL67 44
463#define SYNC_RATE_TBL89 46
464#define SYNC_RATE_TBLab 48
465#define SYNC_RATE_TBLcd 50
466#define SYNC_RATE_TBLef 52
467
468
469
470#define EE_SCAMBASE 256
471
472
473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 #define SCAM_ENABLED BIT(2)
475 #define SCAM_LEVEL2 BIT(3)
476
477
478 #define RENEGO_ENA BITW(10)
479 #define CONNIO_ENA BITW(11)
480 #define GREEN_PC_ENA BITW(12)
481
482
483 #define AUTO_RATE_00 00
484 #define AUTO_RATE_05 01
485 #define AUTO_RATE_10 02
486 #define AUTO_RATE_20 03
487
488 #define WIDE_NEGO_BIT BIT(7)
489 #define DISC_ENABLE_BIT BIT(6)
490
491
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 #define hp_vendor_id_0 0x00 /* LSB */
494 #define ORION_VEND_0 0x4B
495
496 #define hp_vendor_id_1 0x01 /* MSB */
497 #define ORION_VEND_1 0x10
498
499 #define hp_device_id_0 0x02 /* LSB */
500 #define ORION_DEV_0 0x30
501
502 #define hp_device_id_1 0x03 /* MSB */
503 #define ORION_DEV_1 0x81
504
505 /* Sub Vendor ID and Sub Device ID only available in
506 Harpoon Version 2 and higher */
507
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 #define hp_semaphore 0x0C
513 #define SCCB_MGR_ACTIVE BIT(0)
514 #define TICKLE_ME BIT(1)
515 #define SCCB_MGR_PRESENT BIT(3)
516 #define BIOS_IN_USE BIT(4)
517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520 #define hp_sys_ctrl 0x0F
521
522 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
523 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
524 #define HALT_MACH BIT(3) /*Halt State Machine */
525 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
527
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800531
532
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534
535 #define hp_host_blk_cnt 0x13
536
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
538
539 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
540
541
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
543 #define hp_int_mask 0x17
544
545 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
546 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548
549 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 #define hp_xfer_cnt_hi 0x1A
551 #define hp_xfer_cmd 0x1B
552
553 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
554 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
556
557 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560
561 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
562
563 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
564 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565
566 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 #define hp_ee_ctrl 0x22
570
571 #define EXT_ARB_ACK BIT(7)
572 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
573 #define SEE_MS BIT(5)
574 #define SEE_CS BIT(3)
575 #define SEE_CLK BIT(2)
576 #define SEE_DO BIT(1)
577 #define SEE_DI BIT(0)
578
579 #define EE_READ 0x06
580 #define EE_WRITE 0x05
581 #define EWEN 0x04
582 #define EWEN_ADDR 0x03C0
583 #define EWDS 0x04
584 #define EWDS_ADDR 0x0000
585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
589
590
591
592 #define hp_bm_ctrl 0x26
593
594 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
595 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
597 #define FAST_SINGLE BIT(6) /*?? */
598
599 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
600
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
602 #define hp_sg_addr 0x28
603 #define hp_page_ctrl 0x29
604
605 #define SCATTER_EN BIT(0)
606 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
608 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613 #define hp_pci_stat_cfg 0x2D
614
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
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
624 #define hp_rev_num 0x33
625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
627 #define hp_stack_data 0x34
628 #define hp_stack_addr 0x35
629
630 #define hp_ext_status 0x36
631
632 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
633 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
634 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 #define CMD_ABORTED BIT(4) /*Command aborted */
636 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
637 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
638 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
639 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
640 BM_PARITY_ERR | PIO_OVERRUN)
641
642 #define hp_int_status 0x37
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
645 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
648
649 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651
652
653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 #define hp_intena 0x40
655
656 #define RESET BITW(7)
657 #define PROG_HLT BITW(6)
658 #define PARITY BITW(5)
659 #define FIFO BITW(4)
660 #define SEL BITW(3)
661 #define SCAM_SEL BITW(2)
662 #define RSEL BITW(1)
663 #define TIMEOUT BITW(0)
664 #define BUS_FREE BITW(15)
665 #define XFER_CNT_0 BITW(14)
666 #define PHASE BITW(13)
667 #define IUNKWN BITW(12)
668 #define ICMD_COMP BITW(11)
669 #define ITICKLE BITW(10)
670 #define IDO_STRT BITW(9)
671 #define ITAR_DISC BITW(8)
672 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
673 #define CLR_ALL_INT 0xFFFF
674 #define CLR_ALL_INT_1 0xFF00
675
676 #define hp_intstat 0x42
677
678 #define hp_scsisig 0x44
679
680 #define SCSI_SEL BIT(7)
681 #define SCSI_BSY BIT(6)
682 #define SCSI_REQ BIT(5)
683 #define SCSI_ACK BIT(4)
684 #define SCSI_ATN BIT(3)
685 #define SCSI_CD BIT(2)
686 #define SCSI_MSG BIT(1)
687 #define SCSI_IOBIT BIT(0)
688
689 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
692 #define S_DATAI_PH ( BIT(0))
693 #define S_DATAO_PH 0x00
694 #define S_ILL_PH ( BIT(1) )
695
696 #define hp_scsictrl_0 0x45
697
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 #define SEL_TAR BIT(6)
699 #define ENA_ATN BIT(4)
700 #define ENA_RESEL BIT(2)
701 #define SCSI_RST BIT(1)
702 #define ENA_SCAM_SEL BIT(0)
703
704
705
706 #define hp_portctrl_0 0x46
707
708 #define SCSI_PORT BIT(7)
709 #define SCSI_INBIT BIT(6)
710 #define DMA_PORT BIT(5)
711 #define DMA_RD BIT(4)
712 #define HOST_PORT BIT(3)
713 #define HOST_WRT BIT(2)
714 #define SCSI_BUS_EN BIT(1)
715 #define START_TO BIT(0)
716
717 #define hp_scsireset 0x47
718
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 #define SCSI_INI BIT(6)
720 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 #define DMA_RESET BIT(3)
722 #define HPSCSI_RESET BIT(2)
723 #define PROG_RESET BIT(1)
724 #define FIFO_CLR BIT(0)
725
726 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
729 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 #define hp_addstat 0x4E
731
732 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 #define SCSI_MODE8 BIT(3)
734 #define SCSI_PAR_ERR BIT(0)
735
736 #define hp_prgmcnt_0 0x4F
737
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738
739 #define hp_selfid_0 0x50
740 #define hp_selfid_1 0x51
741 #define hp_arb_id 0x52
742
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743
744 #define hp_select_id 0x53
745
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746
747 #define hp_synctarg_base 0x54
748 #define hp_synctarg_12 0x54
749 #define hp_synctarg_13 0x55
750 #define hp_synctarg_14 0x56
751 #define hp_synctarg_15 0x57
752
753 #define hp_synctarg_8 0x58
754 #define hp_synctarg_9 0x59
755 #define hp_synctarg_10 0x5A
756 #define hp_synctarg_11 0x5B
757
758 #define hp_synctarg_4 0x5C
759 #define hp_synctarg_5 0x5D
760 #define hp_synctarg_6 0x5E
761 #define hp_synctarg_7 0x5F
762
763 #define hp_synctarg_0 0x60
764 #define hp_synctarg_1 0x61
765 #define hp_synctarg_2 0x62
766 #define hp_synctarg_3 0x63
767
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 #define DEFAULT_OFFSET 0x0F
770
771 #define hp_autostart_0 0x64
772 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 #define hp_autostart_3 0x67
774
775
776
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 #define AUTO_IMMED BIT(5)
778 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
781 #define hp_gp_reg_0 0x68
782 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 #define hp_gp_reg_3 0x6B
784
785 #define hp_seltimeout 0x6C
786
787
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 #define TO_4ms 0x67 /* 3.9959ms */
789
790 #define TO_5ms 0x03 /* 4.9152ms */
791 #define TO_10ms 0x07 /* 11.xxxms */
792 #define TO_250ms 0x99 /* 250.68ms */
793 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
795 #define hp_clkctrl_0 0x6D
796
797 #define PWR_DWN BIT(6)
798 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
802
803 #define hp_fiforead 0x6E
804 #define hp_fifowrite 0x6F
805
806 #define hp_offsetctr 0x70
807 #define hp_xferstat 0x71
808
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 #define hp_portctrl_1 0x72
812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 #define CHK_SCSI_P BIT(3)
814 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
816 #define hp_xfer_pad 0x73
817
818 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
820 #define hp_scsidata_0 0x74
821 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
825 #define hp_aramBase 0x80
826 #define BIOS_DATA_OFFSET 0x60
827 #define BIOS_RELATIVE_CARD 0x64
828
829
830
831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 #define AR3 (BITW(9) + BITW(8))
833 #define SDATA BITW(10)
834
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
836 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
837
838 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
839
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
843
844 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
845
846
847 #define ADATA_OUT 0x00
848 #define ADATA_IN BITW(8)
849 #define ACOMMAND BITW(10)
850 #define ASTATUS (BITW(10)+BITW(8))
851 #define AMSG_OUT (BITW(10)+BITW(9))
852 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853
854
855 #define BRH_OP BITW(13) /* Branch */
856
857
858 #define ALWAYS 0x00
859 #define EQUAL BITW(8)
860 #define NOT_EQ BITW(9)
861
862 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
863
864
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866
867
868 #define MPM_OP BITW(15) /* Match phase and move data */
869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
871 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
872
873
874 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
875
876
877 #define D_AR0 0x00
878 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
880
881
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
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
888
889 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
890
891 #define SSI_OP (BITW(15)+BITW(11))
892
893
894 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
895 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
897 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
898 #define SSI_ITICKLE (ITICKLE >> 8)
899
900 #define SSI_IUNKWN (IUNKWN >> 8)
901 #define SSI_INO_CC (IUNKWN >> 8)
902 #define SSI_IRFAIL (IUNKWN >> 8)
903
904
905 #define NP 0x10 /*Next Phase */
906 #define NTCMD 0x02 /*Non- Tagged Command start */
907 #define CMDPZ 0x04 /*Command phase */
908 #define DINT 0x12 /*Data Out/In interrupt */
909 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 #define DC 0x19 /*Disconnect Message */
911 #define ST 0x1D /*Status Phase */
912 #define UNKNWN 0x24 /*Unknown bus action */
913 #define CC 0x25 /*Command Completion failure */
914 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
916
917
918 #define ID_MSG_STRT hp_aramBase + 0x00
919 #define NON_TAG_ID_MSG hp_aramBase + 0x06
920 #define CMD_STRT hp_aramBase + 0x08
921 #define SYNC_MSGS hp_aramBase + 0x08
922
923
924
925
926
927 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 #define DISCONNECT_START 0x10/2
929 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 #define SELCHK_STRT SELCHK/2
932
933
934
935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936
937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800939
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
941#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
942/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
943 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800944 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800946#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800948 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800950 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 count >>= 16,\
952 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
954#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
955 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
956
957
958#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
959 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
960
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
964 WR_HARPOON(port+hp_scsireset, 0x00))
965
966#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
967 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
968
969#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
970 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
971
972#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
973 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
974
975#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
976 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
977
978
979
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800981static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
982static void FPT_ssel(ULONG port, unsigned char p_card);
983static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
984static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
985static void FPT_stsyncn(ULONG port, unsigned char p_card);
986static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
987static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500988 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800989static void FPT_sresb(ULONG port, unsigned char p_card);
990static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
991static void FPT_schkdd(ULONG port, unsigned char p_card);
992static unsigned char FPT_RdStack(ULONG port, unsigned char index);
993static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
994static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800996static void FPT_SendMsg(ULONG port, unsigned char message);
997static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
998 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001000static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001001static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001003static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1004static void FPT_stwidn(ULONG port, unsigned char p_card);
1005static void FPT_siwidr(ULONG port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006
1007
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001008static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1009static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001010static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001011 unsigned char p_card);
1012static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1013static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1014static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1015static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001016static void FPT_utilUpdateResidual(PSCCB p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001017static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001018static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019
1020
James Bottomley 47b5d692005-04-24 02:38:05 -05001021static void FPT_Wait1Second(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001022static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1023static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001024static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr);
1025static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr);
1026static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr);
1027static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
1029
1030
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001031static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1032static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1033static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1034static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1035static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1036static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1037static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001039static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1040static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1041static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
1043
1044
1045
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001046static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
James Bottomley 47b5d692005-04-24 02:38:05 -05001047static void FPT_BusMasterInit(ULONG p_port);
1048static void FPT_DiagEEPROM(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050
1051
1052
James Bottomley 47b5d692005-04-24 02:38:05 -05001053static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1054static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1055static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001056static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
James Bottomley 47b5d692005-04-24 02:38:05 -05001057static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001060static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001061 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
James Bottomley 47b5d692005-04-24 02:38:05 -05001063static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001064static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1065static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
1067
1068
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001069static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001071static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
James Bottomley 47b5d692005-04-24 02:38:05 -05001072static void FPT_scbusf(ULONG p_port);
1073static void FPT_scsel(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001074static void FPT_scasid(unsigned char p_card, ULONG p_port);
1075static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1076static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1077static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1078static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1079static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1080static unsigned char FPT_scvalq(unsigned char p_quintet);
1081static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
James Bottomley 47b5d692005-04-24 02:38:05 -05001082static void FPT_scwtsel(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001083static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1084static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1085static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086
1087
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001088static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001089static void FPT_autoLoadDefaultMap(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090
1091
1092
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
James Bottomley 47b5d692005-04-24 02:38:05 -05001094static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1095static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1096static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1097static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
1099
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001100static unsigned char FPT_mbCards = 0;
1101static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001102 ' ', 'B', 'T', '-', '9', '3', '0', \
1103 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1104 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001106static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
1108
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001109static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
1112/*---------------------------------------------------------------------
1113 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001114 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 *
1116 * Description: Setup and/or Search for cards and return info to caller.
1117 *
1118 *---------------------------------------------------------------------*/
1119
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001120static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001122 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001124 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001125 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 PNVRamInfo pCurrNvRam;
1128
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
1131
1132 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1133 return((int)FAILURE);
1134
1135 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1136 return((int)FAILURE);
1137
1138 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1139 return((int)FAILURE);
1140
1141 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1142 return((int)FAILURE);
1143
1144
1145 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1146
1147/* For new Harpoon then check for sub_device ID LSB
1148 the bits(0-3) must be all ZERO for compatible with
1149 current version of SCCBMgr, else skip this Harpoon
1150 device. */
1151
1152 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1153 return((int)FAILURE);
1154 }
1155
1156 if (first_time)
1157 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001158 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001160 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 }
1162
James Bottomley 47b5d692005-04-24 02:38:05 -05001163 if(FPT_RdStack(ioport, 0) != 0x00) {
1164 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 {
1166 pCurrNvRam = NULL;
1167 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001168 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1169 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 }
1171 else
1172 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001173 if(FPT_mbCards < MAX_MB_CARDS) {
1174 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1175 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001177 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 }else
1179 return((int) FAILURE);
1180 }
1181 }else
1182 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
1184 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1185 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1186
1187 if(pCurrNvRam)
1188 pCardInfo->si_id = pCurrNvRam->niAdapId;
1189 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001190 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1191 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
1193 pCardInfo->si_lun = 0x00;
1194 pCardInfo->si_fw_revision = ORION_FW_REV;
1195 temp2 = 0x0000;
1196 temp3 = 0x0000;
1197 temp4 = 0x0000;
1198 temp5 = 0x0000;
1199 temp6 = 0x0000;
1200
1201 for (id = 0; id < (16/2); id++) {
1202
1203 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001204 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1206 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1207 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001208 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209
1210 for (i = 0; i < 2; temp >>=8,i++) {
1211
1212 temp2 >>= 1;
1213 temp3 >>= 1;
1214 temp4 >>= 1;
1215 temp5 >>= 1;
1216 temp6 >>= 1;
1217 switch (temp & 0x3)
1218 {
1219 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1220 temp6 |= 0x8000; /* Fall through */
1221 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1222 temp5 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1224 temp2 |= 0x8000; /* Fall through */
1225 case AUTO_RATE_00: /* Asynchronous */
1226 break;
1227 }
1228
1229 if (temp & DISC_ENABLE_BIT)
1230 temp3 |= 0x8000;
1231
1232 if (temp & WIDE_NEGO_BIT)
1233 temp4 |= 0x8000;
1234
1235 }
1236 }
1237
1238 pCardInfo->si_per_targ_init_sync = temp2;
1239 pCardInfo->si_per_targ_no_disc = temp3;
1240 pCardInfo->si_per_targ_wide_nego = temp4;
1241 pCardInfo->si_per_targ_fast_nego = temp5;
1242 pCardInfo->si_per_targ_ultra_nego = temp6;
1243
1244 if(pCurrNvRam)
1245 i = pCurrNvRam->niSysConf;
1246 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001247 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248
1249 if(pCurrNvRam)
1250 ScamFlg = pCurrNvRam->niScamConf;
1251 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001252 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
1254 pCardInfo->si_flags = 0x0000;
1255
1256 if (i & 0x01)
1257 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1258
1259 if (!(i & 0x02))
1260 pCardInfo->si_flags |= SOFT_RESET;
1261
1262 if (i & 0x10)
1263 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1264
1265 if (ScamFlg & SCAM_ENABLED)
1266 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1267
1268 if (ScamFlg & SCAM_LEVEL2)
1269 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1270
1271 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1272 if (i & 0x04) {
1273 j |= SCSI_TERM_ENA_L;
1274 }
1275 WR_HARPOON(ioport+hp_bm_ctrl, j );
1276
1277 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1278 if (i & 0x08) {
1279 j |= SCSI_TERM_ENA_H;
1280 }
1281 WR_HARPOON(ioport+hp_ee_ctrl, j );
1282
1283 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1284
1285 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1286
1287 pCardInfo->si_card_family = HARPOON_FAMILY;
1288 pCardInfo->si_bustype = BUSTYPE_PCI;
1289
1290 if(pCurrNvRam){
1291 pCardInfo->si_card_model[0] = '9';
1292 switch(pCurrNvRam->niModel & 0x0f){
1293 case MODEL_LT:
1294 pCardInfo->si_card_model[1] = '3';
1295 pCardInfo->si_card_model[2] = '0';
1296 break;
1297 case MODEL_LW:
1298 pCardInfo->si_card_model[1] = '5';
1299 pCardInfo->si_card_model[2] = '0';
1300 break;
1301 case MODEL_DL:
1302 pCardInfo->si_card_model[1] = '3';
1303 pCardInfo->si_card_model[2] = '2';
1304 break;
1305 case MODEL_DW:
1306 pCardInfo->si_card_model[1] = '5';
1307 pCardInfo->si_card_model[2] = '2';
1308 break;
1309 }
1310 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001311 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001312 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001313 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001315 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1316 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 }
1318
1319 if (pCardInfo->si_card_model[1] == '3')
1320 {
1321 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1322 pCardInfo->si_flags |= LOW_BYTE_TERM;
1323 }
1324 else if (pCardInfo->si_card_model[2] == '0')
1325 {
1326 temp = RD_HARPOON(ioport+hp_xfer_pad);
1327 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1328 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1329 pCardInfo->si_flags |= LOW_BYTE_TERM;
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1331 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1332 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1333 WR_HARPOON(ioport+hp_xfer_pad, temp);
1334 }
1335 else
1336 {
1337 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1338 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1339 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1340 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1341 temp3 = 0;
1342 for (i = 0; i < 8; i++)
1343 {
1344 temp3 <<= 1;
1345 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1346 temp3 |= 1;
1347 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1348 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1349 }
1350 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1351 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1352 if (!(temp3 & BIT(7)))
1353 pCardInfo->si_flags |= LOW_BYTE_TERM;
1354 if (!(temp3 & BIT(6)))
1355 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1356 }
1357
1358
1359 ARAM_ACCESS(ioport);
1360
1361 for ( i = 0; i < 4; i++ ) {
1362
1363 pCardInfo->si_XlatInfo[i] =
1364 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1365 }
1366
1367 /* return with -1 if no sort, else return with
1368 logical card number sorted by BIOS (zero-based) */
1369
1370 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001371 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
1373 SGRAM_ACCESS(ioport);
1374
James Bottomley 47b5d692005-04-24 02:38:05 -05001375 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1376 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1377 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1378 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1379 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1380 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1381 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1382 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
1384 pCardInfo->si_present = 0x01;
1385
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 return(0);
1387}
1388
1389
1390/*---------------------------------------------------------------------
1391 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001392 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 *
1394 * Description: Setup adapter for normal operation (hard reset).
1395 *
1396 *---------------------------------------------------------------------*/
1397
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001398static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399{
1400 PSCCBcard CurrCard = NULL;
1401 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001402 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001403 unsigned short temp,sync_bit_map,id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1409
1410 if (thisCard == MAX_CARDS) {
1411
1412 return(FAILURE);
1413 }
1414
James Bottomley 47b5d692005-04-24 02:38:05 -05001415 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
James Bottomley 47b5d692005-04-24 02:38:05 -05001417 CurrCard = &FPT_BL_Card[thisCard];
1418 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 break;
1420 }
1421
James Bottomley 47b5d692005-04-24 02:38:05 -05001422 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423
James Bottomley 47b5d692005-04-24 02:38:05 -05001424 FPT_BL_Card[thisCard].ioPort = ioport;
1425 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
James Bottomley 47b5d692005-04-24 02:38:05 -05001427 if(FPT_mbCards)
1428 for(i = 0; i < FPT_mbCards; i++){
1429 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1430 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001432 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 CurrCard->cardIndex = thisCard;
1434 CurrCard->cardInfo = pCardInfo;
1435
1436 break;
1437 }
1438 }
1439
1440 pCurrNvRam = CurrCard->pNvRamInfo;
1441
1442 if(pCurrNvRam){
1443 ScamFlg = pCurrNvRam->niScamConf;
1444 }
1445 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001446 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 }
1448
1449
James Bottomley 47b5d692005-04-24 02:38:05 -05001450 FPT_BusMasterInit(ioport);
1451 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
James Bottomley 47b5d692005-04-24 02:38:05 -05001453 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
1455
1456 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1457
1458 WR_HARPOON(ioport+hp_selfid_0, id);
1459 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1460 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1461 CurrCard->ourId = pCardInfo->si_id;
1462
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001463 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 if (i & SCSI_PARITY_ENA)
1465 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1466
1467 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1468 if (i & LOW_BYTE_TERM)
1469 j |= SCSI_TERM_ENA_L;
1470 WR_HARPOON(ioport+hp_bm_ctrl, j);
1471
1472 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1473 if (i & HIGH_BYTE_TERM)
1474 j |= SCSI_TERM_ENA_H;
1475 WR_HARPOON(ioport+hp_ee_ctrl, j );
1476
1477
1478 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1479
James Bottomley 47b5d692005-04-24 02:38:05 -05001480 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
James Bottomley 47b5d692005-04-24 02:38:05 -05001482 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 }
1484
1485
1486
1487 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1488 CurrCard->globalFlags |= F_NO_FILTER;
1489
1490 if(pCurrNvRam){
1491 if(pCurrNvRam->niSysConf & 0x10)
1492 CurrCard->globalFlags |= F_GREEN_PC;
1493 }
1494 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001495 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 CurrCard->globalFlags |= F_GREEN_PC;
1497 }
1498
1499 /* Set global flag to indicate Re-Negotiation to be done on all
1500 ckeck condition */
1501 if(pCurrNvRam){
1502 if(pCurrNvRam->niScsiConf & 0x04)
1503 CurrCard->globalFlags |= F_DO_RENEGO;
1504 }
1505 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001506 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 CurrCard->globalFlags |= F_DO_RENEGO;
1508 }
1509
1510 if(pCurrNvRam){
1511 if(pCurrNvRam->niScsiConf & 0x08)
1512 CurrCard->globalFlags |= F_CONLUN_IO;
1513 }
1514 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001515 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 CurrCard->globalFlags |= F_CONLUN_IO;
1517 }
1518
1519
1520 temp = pCardInfo->si_per_targ_no_disc;
1521
1522 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1523
1524 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001525 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 }
1527
1528 sync_bit_map = 0x0001;
1529
1530 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1531
1532 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001533 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1535 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1536 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001537 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538
1539 for (i = 0; i < 2; temp >>=8,i++) {
1540
1541 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1542
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001543 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 }
1545
1546 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001547 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1548 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001549 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 }
1551
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1553 (id*2+i >= 8)){
1554*/
1555 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1556
James Bottomley 47b5d692005-04-24 02:38:05 -05001557 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
1559 }
1560
1561 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001562 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 }
1564
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
1566 sync_bit_map <<= 1;
1567
1568
1569
1570 }
1571 }
1572
1573 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001574 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 return((ULONG)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577}
1578
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001579static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001581 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 ULONG portBase;
1583 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 PNVRamInfo pCurrNvRam;
1587
1588 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1589
1590 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001591 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596
1597 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001598 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599
1600 portBase = pCurrNvRam->niBaseAddr;
1601
1602 for(i = 0; i < MAX_SCSI_TAR; i++){
1603 regOffset = hp_aramBase + 64 + i*4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 scamData = *pScamTbl;
1606 WR_HARP32(portBase, regOffset, scamData);
1607 }
1608
1609 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001610 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 }
1612}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613
1614
James Bottomley 47b5d692005-04-24 02:38:05 -05001615static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001617 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 ULONG portBase;
1619 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622
James Bottomley 47b5d692005-04-24 02:38:05 -05001623 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1624 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1625 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1626 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1627 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628
1629 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001630 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631
1632 portBase = pNvRamInfo->niBaseAddr;
1633
1634 for(i = 0; i < MAX_SCSI_TAR; i++){
1635 regOffset = hp_aramBase + 64 + i*4;
1636 RD_HARP32(portBase, regOffset, scamData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 *pScamTbl = scamData;
1639 }
1640
1641}
1642
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001643static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644{
1645 WR_HARPOON(portBase + hp_stack_addr, index);
1646 return(RD_HARPOON(portBase + hp_stack_data));
1647}
1648
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001649static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650{
1651 WR_HARPOON(portBase + hp_stack_addr, index);
1652 WR_HARPOON(portBase + hp_stack_data, data);
1653}
1654
1655
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001656static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657{
James Bottomley 47b5d692005-04-24 02:38:05 -05001658 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1659 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1661 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001662 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1664 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001665 return(1);
1666 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
1668}
1669/*---------------------------------------------------------------------
1670 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001671 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 *
1673 * Description: Start a command pointed to by p_Sccb. When the
1674 * command is completed it will be returned via the
1675 * callback function.
1676 *
1677 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001678static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 ULONG ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001681 unsigned char thisCard, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 PSCCB pSaveSccb;
1683 CALL_BK_FN callback;
1684
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1686 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1689 {
1690
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 p_Sccb->HostStatus = SCCB_COMPLETE;
1692 p_Sccb->SccbStatus = SCCB_ERROR;
1693 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1694 if (callback)
1695 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 return;
1698 }
1699
James Bottomley 47b5d692005-04-24 02:38:05 -05001700 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702
1703 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1704 {
1705 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1706 | SCCB_MGR_ACTIVE));
1707
1708 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1709 {
1710 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1711 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1712 }
1713 }
1714
1715 ((PSCCBcard)pCurrCard)->cmdCounter++;
1716
1717 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1718
1719 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1720 | TICKLE_ME));
1721 if(p_Sccb->OperationCode == RESET_COMMAND)
1722 {
1723 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1724 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001725 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1727 }
1728 else
1729 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001730 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 }
1732 }
1733
1734 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1735
1736 if(p_Sccb->OperationCode == RESET_COMMAND)
1737 {
1738 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1739 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001740 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1742 }
1743 else
1744 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001745 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 }
1747 }
1748
1749 else {
1750
1751 MDISABLE_INT(ioport);
1752
1753 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001754 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 lun = p_Sccb->Lun;
1756 else
1757 lun = 0;
1758 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001759 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1760 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1761 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
1763 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001764 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 }
1766
1767 else {
1768
1769 if(p_Sccb->OperationCode == RESET_COMMAND)
1770 {
1771 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1772 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001773 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1775 }
1776 else
1777 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001778 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 }
1780 }
1781
1782
1783 MENABLE_INT(ioport);
1784 }
1785
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786}
1787
1788
1789/*---------------------------------------------------------------------
1790 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001791 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 *
1793 * Description: Abort the command pointed to by p_Sccb. When the
1794 * command is completed it will be returned via the
1795 * callback function.
1796 *
1797 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001798static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001802 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001804 unsigned char TID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 PSCCB pSaveSCCB;
1806 PSCCBMgr_tar_info currTar_Info;
1807
1808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1810
1811 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1812
James Bottomley 47b5d692005-04-24 02:38:05 -05001813 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 {
1815
James Bottomley 47b5d692005-04-24 02:38:05 -05001816 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 {
1818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 ((PSCCBcard)pCurrCard)->cmdCounter--;
1820
1821 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1822 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001823 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 p_Sccb->SccbStatus = SCCB_ABORT;
1826 callback = p_Sccb->SccbCallback;
1827 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
1829 return(0);
1830 }
1831
1832 else
1833 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1835 {
1836 p_Sccb->SccbStatus = SCCB_ABORT;
1837 return(0);
1838
1839 }
1840
1841 else
1842 {
1843
1844 TID = p_Sccb->TargID;
1845
1846
1847 if(p_Sccb->Sccb_tag)
1848 {
1849 MDISABLE_INT(ioport);
1850 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1851 {
1852 p_Sccb->SccbStatus = SCCB_ABORT;
1853 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1855
1856 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1857 {
1858 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001859 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 }
1861 else
1862 {
1863 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1864 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001865 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1867 }
1868 }
1869 MENABLE_INT(ioport);
1870 return(0);
1871 }
1872 else
1873 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001874 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875
James Bottomley 47b5d692005-04-24 02:38:05 -05001876 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 == p_Sccb)
1878 {
1879 p_Sccb->SccbStatus = SCCB_ABORT;
1880 return(0);
1881 }
1882 }
1883 }
1884 }
1885 }
1886 return(-1);
1887}
1888
1889
1890/*---------------------------------------------------------------------
1891 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001892 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 *
1894 * Description: Do a quick check to determine if there is a pending
1895 * interrupt for this card and disable the IRQ Pin if so.
1896 *
1897 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001898static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901
1902 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1903
1904 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1905 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001906 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 }
1908
1909 else
1910
James Bottomley 47b5d692005-04-24 02:38:05 -05001911 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912}
1913
1914
1915
1916/*---------------------------------------------------------------------
1917 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001918 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 *
1920 * Description: This is our entry point when an interrupt is generated
1921 * by the card and the upper level driver passes it on to
1922 * us.
1923 *
1924 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001925static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926{
1927 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001928 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001929 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001930 unsigned char i, target;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932
1933 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1934 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1935
1936 MDISABLE_INT(ioport);
1937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001939 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 else
1941 bm_status = 0;
1942
1943 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1944
James Bottomley 47b5d692005-04-24 02:38:05 -05001945 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 bm_status)
1947 {
1948
1949 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1950
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001952 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1954 bm_status = 0;
1955
1956 if (result) {
1957
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 return(result);
1960 }
1961 }
1962
1963
1964 else if (hp_int & ICMD_COMP) {
1965
1966 if ( !(hp_int & BUS_FREE) ) {
1967 /* Wait for the BusFree before starting a new command. We
1968 must also check for being reselected since the BusFree
1969 may not show up if another device reselects us in 1.5us or
1970 less. SRR Wednesday, 3/8/1995.
1971 */
1972 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1973 }
1974
1975 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1976
James Bottomley 47b5d692005-04-24 02:38:05 -05001977 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
1979/* WRW_HARPOON((ioport+hp_intstat),
1980 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1981 */
1982
1983 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1984
James Bottomley 47b5d692005-04-24 02:38:05 -05001985 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986
1987 }
1988
1989
1990 else if (hp_int & ITAR_DISC)
1991 {
1992
1993 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1994
James Bottomley 47b5d692005-04-24 02:38:05 -05001995 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996
1997 }
1998
1999 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2000
2001 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2002 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2003
2004 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2005 }
2006
2007 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002008 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009
2010 /* Wait for the BusFree before starting a new command. We
2011 must also check for being reselected since the BusFree
2012 may not show up if another device reselects us in 1.5us or
2013 less. SRR Wednesday, 3/8/1995.
2014 */
2015 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2016 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2017 RD_HARPOON((ioport+hp_scsisig)) ==
2018 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2019
2020 /*
2021 The additional loop exit condition above detects a timing problem
2022 with the revision D/E harpoon chips. The caller should reset the
2023 host adapter to recover when 0xFE is returned.
2024 */
2025 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2026 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 return 0xFE;
2029 }
2030
2031 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2032
2033
2034 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2035
2036 }
2037
2038
2039 else if (hp_int & RSEL) {
2040
2041 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2042
2043 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2044 {
2045 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2046 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002047 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 }
2049
2050 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2051 {
2052 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2053 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2054 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2055 }
2056
2057 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2058 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002059 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060 }
2061
James Bottomley 47b5d692005-04-24 02:38:05 -05002062 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2063 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
2065 }
2066
2067
2068 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2069 {
2070
2071 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002072 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073
2074 }
2075
2076
2077 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2078 {
2079 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002080 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002082 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 }
2084 else
2085 {
2086 /* Harpoon problem some SCSI target device respond to selection
2087 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2088 to latch the correct Target ID into reg. x53.
2089 The work around require to correct this reg. But when write to this
2090 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2091 need to read this reg first then restore it later. After update to 0x53 */
2092
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002093 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2094 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2095 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2096 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2097 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 WR_HARPOON(ioport+hp_fifowrite, i);
2099 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2100 }
2101 }
2102
2103 else if (hp_int & XFER_CNT_0) {
2104
2105 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2106
James Bottomley 47b5d692005-04-24 02:38:05 -05002107 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108
2109 }
2110
2111
2112 else if (hp_int & BUS_FREE) {
2113
2114 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2115
2116 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2117
James Bottomley 47b5d692005-04-24 02:38:05 -05002118 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 }
2120
James Bottomley 47b5d692005-04-24 02:38:05 -05002121 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 }
2123
2124
2125 else if (hp_int & ITICKLE) {
2126
2127 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2128 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2129 }
2130
2131
2132
2133 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2134
2135
2136 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2137
2138
2139 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2140
James Bottomley 47b5d692005-04-24 02:38:05 -05002141 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 }
2143
2144 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2145 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002146 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 }
2148
2149 break;
2150
2151 }
2152
2153 } /*end while */
2154
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156
2157 return(0);
2158}
2159
2160/*---------------------------------------------------------------------
2161 *
2162 * Function: Sccb_bad_isr
2163 *
2164 * Description: Some type of interrupt has occurred which is slightly
2165 * out of the ordinary. We will now decode it fully, in
2166 * this routine. This is broken up in an attempt to save
2167 * processing time.
2168 *
2169 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002170static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002171 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002173 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002174 PSCCBMgr_tar_info currTar_Info;
2175 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176
2177
2178 if (RD_HARPOON(p_port+hp_ext_status) &
2179 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2180 {
2181
2182 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2183 {
2184
James Bottomley 47b5d692005-04-24 02:38:05 -05002185 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186 }
2187
2188 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2189
2190 {
2191 WR_HARPOON(p_port+hp_pci_stat_cfg,
2192 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2193
2194 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2195
2196 }
2197
2198 if (pCurrCard->currentSCCB != NULL)
2199 {
2200
2201 if (!pCurrCard->currentSCCB->HostStatus)
2202 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2203
James Bottomley 47b5d692005-04-24 02:38:05 -05002204 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002206 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002208 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2210
2211 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2212 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002213 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214 }
2215 }
2216 }
2217
2218
2219 else if (p_int & RESET)
2220 {
2221
2222 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2223 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2224 if (pCurrCard->currentSCCB != NULL) {
2225
2226 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2227
James Bottomley 47b5d692005-04-24 02:38:05 -05002228 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 }
2230
2231
2232 DISABLE_AUTO(p_port);
2233
James Bottomley 47b5d692005-04-24 02:38:05 -05002234 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
2236 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2237
2238 pCurrNvRam = pCurrCard->pNvRamInfo;
2239 if(pCurrNvRam){
2240 ScamFlg = pCurrNvRam->niScamConf;
2241 }
2242 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002243 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 }
2245
James Bottomley 47b5d692005-04-24 02:38:05 -05002246 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247
James Bottomley 47b5d692005-04-24 02:38:05 -05002248 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
2250 return(0xFF);
2251 }
2252
2253
2254 else if (p_int & FIFO) {
2255
2256 WRW_HARPOON((p_port+hp_intstat), FIFO);
2257
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002259 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 }
2261
2262 else if (p_int & TIMEOUT)
2263 {
2264
2265 DISABLE_AUTO(p_port);
2266
2267 WRW_HARPOON((p_port+hp_intstat),
2268 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2269
2270 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2271
2272
James Bottomley 47b5d692005-04-24 02:38:05 -05002273 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2275 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002276 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002278 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279
2280
2281 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2282 {
2283 currTar_Info->TarSyncCtrl = 0;
2284 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2285 }
2286
2287 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2288 {
2289 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2290 }
2291
James Bottomley 47b5d692005-04-24 02:38:05 -05002292 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
James Bottomley 47b5d692005-04-24 02:38:05 -05002294 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295
2296 }
2297
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 else if (p_int & SCAM_SEL)
2299 {
2300
James Bottomley 47b5d692005-04-24 02:38:05 -05002301 FPT_scarb(p_port,LEVEL2_TAR);
2302 FPT_scsel(p_port);
2303 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304
James Bottomley 47b5d692005-04-24 02:38:05 -05002305 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306
2307 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2308 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309
2310 return(0x00);
2311}
2312
2313
2314/*---------------------------------------------------------------------
2315 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 * Function: SccbMgrTableInit
2317 *
2318 * Description: Initialize all Sccb manager data structures.
2319 *
2320 *---------------------------------------------------------------------*/
2321
James Bottomley 47b5d692005-04-24 02:38:05 -05002322static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002324 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325
2326 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2327 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002328 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329
James Bottomley 47b5d692005-04-24 02:38:05 -05002330 FPT_BL_Card[thisCard].ioPort = 0x00;
2331 FPT_BL_Card[thisCard].cardInfo = NULL;
2332 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2333 FPT_BL_Card[thisCard].ourId = 0x00;
2334 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 }
2336}
2337
2338
2339/*---------------------------------------------------------------------
2340 *
2341 * Function: SccbMgrTableInit
2342 *
2343 * Description: Initialize all Sccb manager data structures.
2344 *
2345 *---------------------------------------------------------------------*/
2346
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002347static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002349 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350
2351 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2352 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002353 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 }
2355
2356 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2357 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002358 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2359 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2360 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 }
2362
2363 pCurrCard->scanIndex = 0x00;
2364 pCurrCard->currentSCCB = NULL;
2365 pCurrCard->globalFlags = 0x00;
2366 pCurrCard->cmdCounter = 0x00;
2367 pCurrCard->tagQ_Lst = 0x01;
2368 pCurrCard->discQCount = 0;
2369
2370
2371}
2372
2373
2374/*---------------------------------------------------------------------
2375 *
2376 * Function: SccbMgrTableInit
2377 *
2378 * Description: Initialize all Sccb manager data structures.
2379 *
2380 *---------------------------------------------------------------------*/
2381
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002382static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383{
2384
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002385 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386 PSCCBMgr_tar_info currTar_Info;
2387
James Bottomley 47b5d692005-04-24 02:38:05 -05002388 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
2390 currTar_Info->TarSelQ_Cnt = 0;
2391 currTar_Info->TarSyncCtrl = 0;
2392
2393 currTar_Info->TarSelQ_Head = NULL;
2394 currTar_Info->TarSelQ_Tail = NULL;
2395 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002396 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397
2398
2399 for (lun = 0; lun < MAX_LUN; lun++)
2400 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002401 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402 currTar_Info->LunDiscQ_Idx[lun] = 0;
2403 }
2404
2405 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2406 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002407 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002409 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002411 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2412 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 }
2414 }
2415 }
2416}
2417
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
2419/*---------------------------------------------------------------------
2420 *
2421 * Function: sfetm
2422 *
2423 * Description: Read in a message byte from the SCSI bus, and check
2424 * for a parity error.
2425 *
2426 *---------------------------------------------------------------------*/
2427
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002428static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002430 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002431 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432
2433 TimeOutLoop = 0;
2434 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2435 (TimeOutLoop++ < 20000) ){}
2436
2437
2438 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2439
2440 message = RD_HARPOON(port+hp_scsidata_0);
2441
2442 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2443
2444
2445 if (TimeOutLoop > 20000)
2446 message = 0x00; /* force message byte = 0 if Time Out on Req */
2447
2448 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2449 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2450 {
2451 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2452 WR_HARPOON(port+hp_xferstat, 0);
2453 WR_HARPOON(port+hp_fiforead, 0);
2454 WR_HARPOON(port+hp_fifowrite, 0);
2455 if (pCurrSCCB != NULL)
2456 {
2457 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2458 }
2459 message = 0x00;
2460 do
2461 {
2462 ACCEPT_MSG_ATN(port);
2463 TimeOutLoop = 0;
2464 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2465 (TimeOutLoop++ < 20000) ){}
2466 if (TimeOutLoop > 20000)
2467 {
2468 WRW_HARPOON((port+hp_intstat), PARITY);
2469 return(message);
2470 }
2471 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2472 {
2473 WRW_HARPOON((port+hp_intstat), PARITY);
2474 return(message);
2475 }
2476 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2477
2478 RD_HARPOON(port+hp_scsidata_0);
2479
2480 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2481
2482 }while(1);
2483
2484 }
2485 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2486 WR_HARPOON(port+hp_xferstat, 0);
2487 WR_HARPOON(port+hp_fiforead, 0);
2488 WR_HARPOON(port+hp_fifowrite, 0);
2489 return(message);
2490}
2491
2492
2493/*---------------------------------------------------------------------
2494 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002495 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 *
2497 * Description: Load up automation and select target device.
2498 *
2499 *---------------------------------------------------------------------*/
2500
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002501static void FPT_ssel(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502{
2503
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002504 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 PSCCBcard CurrCard;
2508 PSCCB currSCCB;
2509 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002510 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511
James Bottomley 47b5d692005-04-24 02:38:05 -05002512 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513 currSCCB = CurrCard->currentSCCB;
2514 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002515 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 lastTag = CurrCard->tagQ_Lst;
2517
2518 ARAM_ACCESS(port);
2519
2520
2521 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2522 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2523
2524 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2525 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2526
2527 lun = currSCCB->Lun;
2528 else
2529 lun = 0;
2530
2531
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 if (CurrCard->globalFlags & F_TAG_STARTED)
2533 {
2534 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2535 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002536 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2538 == TAG_Q_TRYING))
2539 {
2540
2541 if (currTar_Info->TarTagQ_Cnt !=0)
2542 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002543 currTar_Info->TarLUNBusy[lun] = 1;
2544 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545 SGRAM_ACCESS(port);
2546 return;
2547 }
2548
2549 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002550 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 }
2552
2553 } /*End non-tagged */
2554
2555 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002556 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 }
2558
2559 } /*!Use cmd Q Tagged */
2560
2561 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002562 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002564 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 SGRAM_ACCESS(port);
2566 return;
2567 }
2568
James Bottomley 47b5d692005-04-24 02:38:05 -05002569 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
2571 } /*else use cmd Q tagged */
2572
2573 } /*if glob tagged started */
2574
2575 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002576 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577 }
2578
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579
2580
2581 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2582 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2583 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2584 {
2585 if(CurrCard->discQCount >= QUEUE_DEPTH)
2586 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002587 currTar_Info->TarLUNBusy[lun] = 1;
2588 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589 SGRAM_ACCESS(port);
2590 return;
2591 }
2592 for (i = 1; i < QUEUE_DEPTH; i++)
2593 {
2594 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2595 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2596 {
2597 CurrCard->tagQ_Lst = lastTag;
2598 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2599 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2600 CurrCard->discQCount++;
2601 break;
2602 }
2603 }
2604 if(i == QUEUE_DEPTH)
2605 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002606 currTar_Info->TarLUNBusy[lun] = 1;
2607 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608 SGRAM_ACCESS(port);
2609 return;
2610 }
2611 }
2612
2613
2614
James Bottomley 47b5d692005-04-24 02:38:05 -05002615 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616
2617 WR_HARPOON(port+hp_select_id, target);
2618 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2619
2620 if (currSCCB->OperationCode == RESET_COMMAND) {
2621 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2622 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2623
2624 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2625
2626 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2627
2628 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002629 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2631
2632 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2633 {
2634 currTar_Info->TarSyncCtrl = 0;
2635 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2636 }
2637
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2639 {
2640 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2641 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642
James Bottomley 47b5d692005-04-24 02:38:05 -05002643 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2644 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
2646 }
2647
2648 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2649 {
2650 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2651 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2652
2653 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2654
2655 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002656 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2657 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 WRW_HARPOON((port+SYNC_MSGS+2),
2659 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2660 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2661
2662 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002663 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664
2665 }
2666
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002668 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2670 }
2671
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2673 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002674 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2676 }
2677
2678
2679 if (!auto_loaded)
2680 {
2681
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682 if (currSCCB->ControlByte & F_USE_CMD_Q)
2683 {
2684
2685 CurrCard->globalFlags |= F_TAG_STARTED;
2686
2687 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2688 == TAG_Q_REJECT)
2689 {
2690 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2691
2692 /* Fix up the start instruction with a jump to
2693 Non-Tag-CMD handling */
2694 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2695
2696 WRW_HARPOON((port+NON_TAG_ID_MSG),
2697 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2698
2699 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2700
2701 /* Setup our STATE so we know what happend when
2702 the wheels fall off. */
2703 currSCCB->Sccb_scsistat = SELECT_ST;
2704
James Bottomley 47b5d692005-04-24 02:38:05 -05002705 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706 }
2707
2708 else
2709 {
2710 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2711
2712 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002713 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2714 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
2716 for (i = 1; i < QUEUE_DEPTH; i++)
2717 {
2718 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2719 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2720 {
2721 WRW_HARPOON((port+ID_MSG_STRT+6),
2722 (MPM_OP+AMSG_OUT+lastTag));
2723 CurrCard->tagQ_Lst = lastTag;
2724 currSCCB->Sccb_tag = lastTag;
2725 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2726 CurrCard->discQCount++;
2727 break;
2728 }
2729 }
2730
2731
2732 if ( i == QUEUE_DEPTH )
2733 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002734 currTar_Info->TarLUNBusy[lun] = 1;
2735 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 SGRAM_ACCESS(port);
2737 return;
2738 }
2739
2740 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2741
2742 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2743 }
2744 }
2745
2746 else
2747 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748
2749 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2750
2751 WRW_HARPOON((port+NON_TAG_ID_MSG),
2752 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2753
2754 currSCCB->Sccb_scsistat = SELECT_ST;
2755
2756 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758
2759
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002760 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761
2762 cdb_reg = port + CMD_STRT;
2763
2764 for (i=0; i < currSCCB->CdbLength; i++)
2765 {
2766 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2767 cdb_reg +=2;
2768 theCCB++;
2769 }
2770
2771 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2772 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2773
2774 } /* auto_loaded */
2775
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002776 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778
2779 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2780
2781 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2782
2783
2784 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2785 {
2786 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2787 }
2788 else
2789 {
2790
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002791/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002792 auto_loaded |= AUTO_IMMED; */
2793 auto_loaded = AUTO_IMMED;
2794
2795 DISABLE_AUTO(port);
2796
2797 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2798 }
2799
2800 SGRAM_ACCESS(port);
2801}
2802
2803
2804/*---------------------------------------------------------------------
2805 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002806 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807 *
2808 * Description: Hookup the correct CCB and handle the incoming messages.
2809 *
2810 *---------------------------------------------------------------------*/
2811
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002812static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813{
2814
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002815 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816
2817
2818 PSCCBMgr_tar_info currTar_Info;
2819 PSCCB currSCCB;
2820
2821
2822
2823
2824 if(pCurrCard->currentSCCB != NULL)
2825 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002826 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 DISABLE_AUTO(port);
2828
2829
2830 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2831
2832
2833 currSCCB = pCurrCard->currentSCCB;
2834 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2835 {
2836 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2837 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2838 }
2839 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2840 {
2841 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2842 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2843 }
2844 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2845 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2846 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002847 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 if(currSCCB->Sccb_scsistat != ABORT_ST)
2849 {
2850 pCurrCard->discQCount--;
2851 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2852 = NULL;
2853 }
2854 }
2855 else
2856 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002857 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 if(currSCCB->Sccb_tag)
2859 {
2860 if(currSCCB->Sccb_scsistat != ABORT_ST)
2861 {
2862 pCurrCard->discQCount--;
2863 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2864 }
2865 }else
2866 {
2867 if(currSCCB->Sccb_scsistat != ABORT_ST)
2868 {
2869 pCurrCard->discQCount--;
2870 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2871 }
2872 }
2873 }
2874
James Bottomley 47b5d692005-04-24 02:38:05 -05002875 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 }
2877
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002878 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879
2880
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002881 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002882 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883
2884
2885 msgRetryCount = 0;
2886 do
2887 {
2888
James Bottomley 47b5d692005-04-24 02:38:05 -05002889 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 tag = 0;
2891
2892
2893 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2894 {
2895 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2896 {
2897
2898 WRW_HARPOON((port+hp_intstat), PHASE);
2899 return;
2900 }
2901 }
2902
2903 WRW_HARPOON((port+hp_intstat), PHASE);
2904 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2905 {
2906
James Bottomley 47b5d692005-04-24 02:38:05 -05002907 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 if (message)
2909 {
2910
2911 if (message <= (0x80 | LUN_MASK))
2912 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002913 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2916 {
2917 if (currTar_Info->TarTagQ_Cnt != 0)
2918 {
2919
2920 if (!(currTar_Info->TarLUN_CA))
2921 {
2922 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2923
2924
James Bottomley 47b5d692005-04-24 02:38:05 -05002925 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 if (message)
2927 {
2928 ACCEPT_MSG(port);
2929 }
2930
2931 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002932 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933
James Bottomley 47b5d692005-04-24 02:38:05 -05002934 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002936 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937
2938 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002939 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 }
2941
2942 } /*C.A. exists! */
2943
2944 } /*End Q cnt != 0 */
2945
2946 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947
2948 } /*End valid ID message. */
2949
2950 else
2951 {
2952
2953 ACCEPT_MSG_ATN(port);
2954 }
2955
2956 } /* End good id message. */
2957
2958 else
2959 {
2960
James Bottomley 47b5d692005-04-24 02:38:05 -05002961 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962 }
2963 }
2964 else
2965 {
2966 ACCEPT_MSG_ATN(port);
2967
2968 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2969 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2970 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2971
2972 return;
2973 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
James Bottomley 47b5d692005-04-24 02:38:05 -05002975 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 {
2977 msgRetryCount++;
2978 if(msgRetryCount == 1)
2979 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002980 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 }
2982 else
2983 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002984 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985
James Bottomley 47b5d692005-04-24 02:38:05 -05002986 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987
James Bottomley 47b5d692005-04-24 02:38:05 -05002988 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989 {
2990
James Bottomley 47b5d692005-04-24 02:38:05 -05002991 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992
2993 }
2994
James Bottomley 47b5d692005-04-24 02:38:05 -05002995 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996 {
2997
James Bottomley 47b5d692005-04-24 02:38:05 -05002998 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999 }
3000
3001
James Bottomley 47b5d692005-04-24 02:38:05 -05003002 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3003 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 return;
3005 }
3006 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003007 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008
3009
3010
3011 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3012 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3013 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003014 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3016 if(pCurrCard->currentSCCB != NULL)
3017 {
3018 ACCEPT_MSG(port);
3019 }
3020 else
3021 {
3022 ACCEPT_MSG_ATN(port);
3023 }
3024 }
3025 else
3026 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003027 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028
3029
3030 if (tag)
3031 {
3032 if (pCurrCard->discQ_Tbl[tag] != NULL)
3033 {
3034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3035 currTar_Info->TarTagQ_Cnt--;
3036 ACCEPT_MSG(port);
3037 }
3038 else
3039 {
3040 ACCEPT_MSG_ATN(port);
3041 }
3042 }else
3043 {
3044 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3045 if(pCurrCard->currentSCCB != NULL)
3046 {
3047 ACCEPT_MSG(port);
3048 }
3049 else
3050 {
3051 ACCEPT_MSG_ATN(port);
3052 }
3053 }
3054 }
3055
3056 if(pCurrCard->currentSCCB != NULL)
3057 {
3058 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3059 {
3060 /* During Abort Tag command, the target could have got re-selected
3061 and completed the command. Check the select Q and remove the CCB
3062 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003063 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 }
3065 }
3066
3067
3068 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3069 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3070 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3071}
3072
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003073static void FPT_SendMsg(ULONG port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074{
3075 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3076 {
3077 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3078 {
3079
3080 WRW_HARPOON((port+hp_intstat), PHASE);
3081 return;
3082 }
3083 }
3084
3085 WRW_HARPOON((port+hp_intstat), PHASE);
3086 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3087 {
3088 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3089
3090
3091 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3092
3093 WR_HARPOON(port+hp_scsidata_0,message);
3094
3095 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3096
3097 ACCEPT_MSG(port);
3098
3099 WR_HARPOON(port+hp_portctrl_0, 0x00);
3100
3101 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3102 (message == SMABORT_TAG) )
3103 {
3104 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3105
3106 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3107 {
3108 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3109 }
3110 }
3111 }
3112}
3113
3114/*---------------------------------------------------------------------
3115 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003116 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117 *
3118 * Description: Determine the proper responce to the message from the
3119 * target device.
3120 *
3121 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003122static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123{
3124 PSCCB currSCCB;
3125 PSCCBcard CurrCard;
3126 PSCCBMgr_tar_info currTar_Info;
3127
James Bottomley 47b5d692005-04-24 02:38:05 -05003128 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129 currSCCB = CurrCard->currentSCCB;
3130
James Bottomley 47b5d692005-04-24 02:38:05 -05003131 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132
3133 if (message == SMREST_DATA_PTR)
3134 {
3135 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3136 {
3137 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3138
James Bottomley 47b5d692005-04-24 02:38:05 -05003139 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 }
3141
3142 ACCEPT_MSG(port);
3143 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3144 }
3145
3146 else if (message == SMCMD_COMP)
3147 {
3148
3149
3150 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3151 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003152 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3153 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 }
3155
3156 ACCEPT_MSG(port);
3157
3158 }
3159
3160 else if ((message == SMNO_OP) || (message >= SMIDENT)
3161 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3162 {
3163
3164 ACCEPT_MSG(port);
3165 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3166 }
3167
3168 else if (message == SMREJECT)
3169 {
3170
3171 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3172 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3173 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3174 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3175
3176 {
3177 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3178
3179 ACCEPT_MSG(port);
3180
3181
3182 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3183 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3184
3185 if(currSCCB->Lun == 0x00)
3186 {
3187 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3188 {
3189
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003190 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191
3192 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3193 }
3194
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3196 {
3197
3198
3199 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3200 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3201
3202 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3203
3204 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003205
3206 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3207 {
3208 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003209 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210
3211
3212 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3213 CurrCard->discQCount--;
3214 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3215 currSCCB->Sccb_tag = 0x00;
3216
3217 }
3218 }
3219
3220 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3221 {
3222
3223
3224 if(currSCCB->Lun == 0x00)
3225 {
3226 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3227 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3228 }
3229 }
3230
3231 else
3232 {
3233
3234 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3235 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003236 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003238 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239
3240
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003241 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242
3243 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3244
3245 }
3246 }
3247
3248 else
3249 {
3250 ACCEPT_MSG(port);
3251
3252 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3253 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3254
3255 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3256 {
3257 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3258 }
3259 }
3260 }
3261
3262 else if (message == SMEXT)
3263 {
3264
3265 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003266 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003267 }
3268
3269 else if (message == SMIGNORWR)
3270 {
3271
3272 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3273
James Bottomley 47b5d692005-04-24 02:38:05 -05003274 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275
3276 if(currSCCB->Sccb_scsimsg != SMPARITY)
3277 ACCEPT_MSG(port);
3278 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3279 }
3280
3281
3282 else
3283 {
3284
3285 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3286 currSCCB->Sccb_scsimsg = SMREJECT;
3287
3288 ACCEPT_MSG_ATN(port);
3289 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3290 }
3291}
3292
3293
3294/*---------------------------------------------------------------------
3295 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003296 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003297 *
3298 * Description: Decide what to do with the extended message.
3299 *
3300 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003301static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003303 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304
James Bottomley 47b5d692005-04-24 02:38:05 -05003305 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306 if (length)
3307 {
3308
3309 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003310 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 if (message)
3312 {
3313
3314 if (message == SMSYNC)
3315 {
3316
3317 if (length == 0x03)
3318 {
3319
3320 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003321 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003322 }
3323 else
3324 {
3325
3326 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3327 ACCEPT_MSG_ATN(port);
3328 }
3329 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330 else if (message == SMWDTR)
3331 {
3332
3333 if (length == 0x02)
3334 {
3335
3336 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003337 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338 }
3339 else
3340 {
3341
3342 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3343 ACCEPT_MSG_ATN(port);
3344
3345 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3346 }
3347 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003348 else
3349 {
3350
3351 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3352 ACCEPT_MSG_ATN(port);
3353
3354 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3355 }
3356 }
3357 else
3358 {
3359 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3360 ACCEPT_MSG(port);
3361 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3362 }
3363 }else
3364 {
3365 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3366 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3367 }
3368}
3369
3370
3371/*---------------------------------------------------------------------
3372 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003373 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374 *
3375 * Description: Read in a message byte from the SCSI bus, and check
3376 * for a parity error.
3377 *
3378 *---------------------------------------------------------------------*/
3379
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003380static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003381{
3382 PSCCB currSCCB;
3383 PSCCBMgr_tar_info currTar_Info;
3384
James Bottomley 47b5d692005-04-24 02:38:05 -05003385 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3386 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387
3388 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3389
3390
3391 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003392 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393
3394 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3395
3396 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3397 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3398 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3399
3400
3401 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3402
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3404
3405 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3406
3407 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3408
3409 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3410
3411 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3412
3413 else
3414 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3415
3416
3417 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3418 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3419 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3420
3421
James Bottomley 47b5d692005-04-24 02:38:05 -05003422 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 {
3424 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3425 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003426 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 }
3428 else
3429 {
3430 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3431 }
3432
3433
James Bottomley 47b5d692005-04-24 02:38:05 -05003434 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003435 }
3436
3437 else {
3438
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003439 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003441 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 }
3443}
3444
3445
3446
3447/*---------------------------------------------------------------------
3448 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003449 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450 *
3451 * Description: The has sent us a Sync Nego message so handle it as
3452 * necessary.
3453 *
3454 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003455static void FPT_stsyncn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003457 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003458 PSCCB currSCCB;
3459 PSCCBMgr_tar_info currTar_Info;
3460
James Bottomley 47b5d692005-04-24 02:38:05 -05003461 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3462 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463
James Bottomley 47b5d692005-04-24 02:38:05 -05003464 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003465
3466 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3467 {
3468 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3469 return;
3470 }
3471
3472 ACCEPT_MSG(port);
3473
3474
James Bottomley 47b5d692005-04-24 02:38:05 -05003475 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476
3477 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3478 {
3479 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3480 return;
3481 }
3482
3483 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3484
3485 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3486
3487 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3488
3489 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3490
3491 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3492
3493 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3494 else
3495
3496 our_sync_msg = 0; /* Message = Async */
3497
3498 if (sync_msg < our_sync_msg) {
3499 sync_msg = our_sync_msg; /*if faster, then set to max. */
3500 }
3501
3502 if (offset == ASYNC)
3503 sync_msg = ASYNC;
3504
3505 if (offset > MAX_OFFSET)
3506 offset = MAX_OFFSET;
3507
3508 sync_reg = 0x00;
3509
3510 if (sync_msg > 12)
3511
3512 sync_reg = 0x20; /* Use 10MB/s */
3513
3514 if (sync_msg > 25)
3515
3516 sync_reg = 0x40; /* Use 6.6MB/s */
3517
3518 if (sync_msg > 38)
3519
3520 sync_reg = 0x60; /* Use 5MB/s */
3521
3522 if (sync_msg > 50)
3523
3524 sync_reg = 0x80; /* Use 4MB/s */
3525
3526 if (sync_msg > 62)
3527
3528 sync_reg = 0xA0; /* Use 3.33MB/s */
3529
3530 if (sync_msg > 75)
3531
3532 sync_reg = 0xC0; /* Use 2.85MB/s */
3533
3534 if (sync_msg > 87)
3535
3536 sync_reg = 0xE0; /* Use 2.5MB/s */
3537
3538 if (sync_msg > 100) {
3539
3540 sync_reg = 0x00; /* Use ASYNC */
3541 offset = 0x00;
3542 }
3543
3544
Linus Torvalds1da177e2005-04-16 15:20:36 -07003545 if (currTar_Info->TarStatus & WIDE_ENABLED)
3546
3547 sync_reg |= offset;
3548
3549 else
3550
3551 sync_reg |= (offset | NARROW_SCSI);
3552
James Bottomley 47b5d692005-04-24 02:38:05 -05003553 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003554
3555
3556 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3557
3558
3559 ACCEPT_MSG(port);
3560
3561 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003562 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003563
3564 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3565 }
3566
3567 else {
3568
3569
3570 ACCEPT_MSG_ATN(port);
3571
James Bottomley 47b5d692005-04-24 02:38:05 -05003572 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573
3574 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003575 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576 }
3577}
3578
3579
3580/*---------------------------------------------------------------------
3581 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003582 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003583 *
3584 * Description: Answer the targets sync message.
3585 *
3586 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003587static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003588{
3589 ARAM_ACCESS(port);
3590 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3591 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3592 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3593 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3594 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3595 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3596 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3597 SGRAM_ACCESS(port);
3598
3599 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3600 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3601
3602 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3603
3604 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3605}
3606
3607
3608
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609/*---------------------------------------------------------------------
3610 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003611 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612 *
3613 * Description: Read in a message byte from the SCSI bus, and check
3614 * for a parity error.
3615 *
3616 *---------------------------------------------------------------------*/
3617
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003618static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619{
3620 PSCCB currSCCB;
3621 PSCCBMgr_tar_info currTar_Info;
3622
James Bottomley 47b5d692005-04-24 02:38:05 -05003623 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3624 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003625
3626 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3627
3628
3629 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003630 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631
3632 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3633
3634 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3635 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3636 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3637 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3638 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3639 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3640
3641 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3642
3643
3644 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003645 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646
James Bottomley 47b5d692005-04-24 02:38:05 -05003647 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003648 }
3649
3650 else {
3651
3652 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003653 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654
3655 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003656 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003657 }
3658}
3659
3660
3661
3662/*---------------------------------------------------------------------
3663 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003664 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 *
3666 * Description: The has sent us a Wide Nego message so handle it as
3667 * necessary.
3668 *
3669 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003670static void FPT_stwidn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003672 unsigned char width;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673 PSCCB currSCCB;
3674 PSCCBMgr_tar_info currTar_Info;
3675
James Bottomley 47b5d692005-04-24 02:38:05 -05003676 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3677 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678
James Bottomley 47b5d692005-04-24 02:38:05 -05003679 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003680
3681 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3682 {
3683 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3684 return;
3685 }
3686
3687
3688 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3689 width = 0;
3690
3691 if (width) {
3692 currTar_Info->TarStatus |= WIDE_ENABLED;
3693 width = 0;
3694 }
3695 else {
3696 width = NARROW_SCSI;
3697 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3698 }
3699
3700
James Bottomley 47b5d692005-04-24 02:38:05 -05003701 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702
3703
3704 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3705 {
3706
3707
3708
3709 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3710
3711 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3712 {
3713 ACCEPT_MSG_ATN(port);
3714 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003715 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3717 SGRAM_ACCESS(port);
3718 }
3719 else
3720 {
3721 ACCEPT_MSG(port);
3722 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3723 }
3724 }
3725
3726 else {
3727
3728
3729 ACCEPT_MSG_ATN(port);
3730
3731 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3732 width = SM16BIT;
3733 else
3734 width = SM8BIT;
3735
James Bottomley 47b5d692005-04-24 02:38:05 -05003736 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003737
3738 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3739 }
3740}
3741
3742
3743/*---------------------------------------------------------------------
3744 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003745 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003746 *
3747 * Description: Answer the targets Wide nego message.
3748 *
3749 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003750static void FPT_siwidr(ULONG port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003751{
3752 ARAM_ACCESS(port);
3753 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3754 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3755 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3756 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3757 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3758 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3759 SGRAM_ACCESS(port);
3760
3761 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3762 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3763
3764 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3765
3766 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3767}
3768
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769
3770
3771/*---------------------------------------------------------------------
3772 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003773 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003774 *
3775 * Description: Write the desired value to the Sync Register for the
3776 * ID specified.
3777 *
3778 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003779static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003780 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003782 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003783
3784 index = p_id;
3785
3786 switch (index) {
3787
3788 case 0:
3789 index = 12; /* hp_synctarg_0 */
3790 break;
3791 case 1:
3792 index = 13; /* hp_synctarg_1 */
3793 break;
3794 case 2:
3795 index = 14; /* hp_synctarg_2 */
3796 break;
3797 case 3:
3798 index = 15; /* hp_synctarg_3 */
3799 break;
3800 case 4:
3801 index = 8; /* hp_synctarg_4 */
3802 break;
3803 case 5:
3804 index = 9; /* hp_synctarg_5 */
3805 break;
3806 case 6:
3807 index = 10; /* hp_synctarg_6 */
3808 break;
3809 case 7:
3810 index = 11; /* hp_synctarg_7 */
3811 break;
3812 case 8:
3813 index = 4; /* hp_synctarg_8 */
3814 break;
3815 case 9:
3816 index = 5; /* hp_synctarg_9 */
3817 break;
3818 case 10:
3819 index = 6; /* hp_synctarg_10 */
3820 break;
3821 case 11:
3822 index = 7; /* hp_synctarg_11 */
3823 break;
3824 case 12:
3825 index = 0; /* hp_synctarg_12 */
3826 break;
3827 case 13:
3828 index = 1; /* hp_synctarg_13 */
3829 break;
3830 case 14:
3831 index = 2; /* hp_synctarg_14 */
3832 break;
3833 case 15:
3834 index = 3; /* hp_synctarg_15 */
3835
3836 }
3837
3838 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3839
3840 currTar_Info->TarSyncCtrl = p_sync_value;
3841}
3842
3843
3844/*---------------------------------------------------------------------
3845 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003846 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003847 *
3848 * Description: Reset the desired card's SCSI bus.
3849 *
3850 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003851static void FPT_sresb(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003853 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003854
3855 PSCCBMgr_tar_info currTar_Info;
3856
3857 WR_HARPOON(port+hp_page_ctrl,
3858 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3859 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3860
3861 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3862
3863 scsiID = RD_HARPOON(port+hp_seltimeout);
3864 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3865 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3866
3867 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3868
3869 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3870
3871 WR_HARPOON(port+hp_seltimeout,scsiID);
3872
3873 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3874
James Bottomley 47b5d692005-04-24 02:38:05 -05003875 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876
3877 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3878
3879 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3880
3881 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3882 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003883 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884
3885 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3886 {
3887 currTar_Info->TarSyncCtrl = 0;
3888 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3889 }
3890
3891 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3892 {
3893 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3894 }
3895
James Bottomley 47b5d692005-04-24 02:38:05 -05003896 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897
James Bottomley 47b5d692005-04-24 02:38:05 -05003898 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899 }
3900
James Bottomley 47b5d692005-04-24 02:38:05 -05003901 FPT_BL_Card[p_card].scanIndex = 0x00;
3902 FPT_BL_Card[p_card].currentSCCB = NULL;
3903 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003904 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003905 FPT_BL_Card[p_card].cmdCounter = 0x00;
3906 FPT_BL_Card[p_card].discQCount = 0x00;
3907 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908
3909 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003910 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911
3912 WR_HARPOON(port+hp_page_ctrl,
3913 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3914
3915}
3916
3917/*---------------------------------------------------------------------
3918 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003919 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003920 *
3921 * Description: Setup for the Auto Sense command.
3922 *
3923 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003924static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003926 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927 PSCCB currSCCB;
3928
3929 currSCCB = pCurrCard->currentSCCB;
3930
3931
3932 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3933
3934 for (i = 0; i < 6; i++) {
3935
3936 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3937 }
3938
3939 currSCCB->CdbLength = SIX_BYTE_CMD;
3940 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003941 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 currSCCB->Cdb[2] = 0x00;
3943 currSCCB->Cdb[3] = 0x00;
3944 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3945 currSCCB->Cdb[5] = 0x00;
3946
3947 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3948
3949 currSCCB->Sccb_ATC = 0x00;
3950
3951 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3952
3953 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3954
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003955 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956
3957 currSCCB->ControlByte = 0x00;
3958
3959 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3960}
3961
3962
3963
3964/*---------------------------------------------------------------------
3965 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003966 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003967 *
3968 * Description: Transfer data into the bit bucket until the device
3969 * decides to switch phase.
3970 *
3971 *---------------------------------------------------------------------*/
3972
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003973static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003975 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003976
3977
3978 DISABLE_AUTO(p_port);
3979
James Bottomley 47b5d692005-04-24 02:38:05 -05003980 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981
James Bottomley 47b5d692005-04-24 02:38:05 -05003982 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983
3984 }
3985
3986 /* If the Automation handled the end of the transfer then do not
3987 match the phase or we will get out of sync with the ISR. */
3988
3989 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3990 return;
3991
3992 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3993
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003994 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995
3996 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3997
3998
3999 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4000
4001 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004002 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004004 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004005 {
4006 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4007
4008 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4009 {
4010 RD_HARPOON(p_port+hp_fifodata_0);
4011 }
4012 }
4013 else
4014 {
4015 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4016 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4017 {
4018 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4019 }
4020 }
4021 } /* End of While loop for padding data I/O phase */
4022
4023 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4024 {
4025 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4026 break;
4027 }
4028
4029 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4030 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4031 {
4032 RD_HARPOON(p_port+hp_fifodata_0);
4033 }
4034
4035 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4036 {
4037 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4038 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4039
4040 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4041 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4042 }
4043}
4044
4045
4046/*---------------------------------------------------------------------
4047 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004048 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049 *
4050 * Description: Make sure data has been flushed from both FIFOs and abort
4051 * the operations if necessary.
4052 *
4053 *---------------------------------------------------------------------*/
4054
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004055static void FPT_schkdd(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004056{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004057 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004058 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059
4060 PSCCB currSCCB;
4061
James Bottomley 47b5d692005-04-24 02:38:05 -05004062 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004063
4064
4065 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4066 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4067 return;
4068 }
4069
4070
4071
4072 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4073 {
4074
4075 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4076
4077 currSCCB->Sccb_XferCnt = 1;
4078
4079 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004080 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004081 WR_HARPOON(port+hp_xferstat, 0x00);
4082 }
4083
4084 else
4085 {
4086
4087 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4088
4089 currSCCB->Sccb_XferCnt = 0;
4090 }
4091
4092 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4093 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4094
4095 currSCCB->HostStatus = SCCB_PARITY_ERR;
4096 WRW_HARPOON((port+hp_intstat), PARITY);
4097 }
4098
4099
James Bottomley 47b5d692005-04-24 02:38:05 -05004100 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101
4102
4103 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4104
4105 TimeOutLoop = 0;
4106
4107 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4108 {
4109 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4110 return;
4111 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004112 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113 break;
4114 }
4115 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4116 return;
4117 }
4118 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4119 break;
4120 }
4121
4122 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4123 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004124 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4126 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4127 {
4128
4129 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4130
4131 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4132 {
4133 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004134 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004135 }
4136
4137 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004138 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 }
4140 }
4141 else
4142 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004143 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004144 if (!(RDW_HARPOON((port+hp_intstat)) &
4145 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4146 {
4147 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004148 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004149 }
4150 }
4151
4152 }
4153
4154 else {
4155 WR_HARPOON(port+hp_portctrl_0, 0x00);
4156 }
4157}
4158
4159
4160/*---------------------------------------------------------------------
4161 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004162 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163 *
4164 * Description: Setup SCCB manager fields in this SCCB.
4165 *
4166 *---------------------------------------------------------------------*/
4167
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004168static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004169{
4170 PSCCBMgr_tar_info currTar_Info;
4171
4172 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4173 {
4174 return;
4175 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004176 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004177
4178 p_sccb->Sccb_XferState = 0x00;
4179 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4180
4181 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4182 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4183
4184 p_sccb->Sccb_SGoffset = 0;
4185 p_sccb->Sccb_XferState = F_SG_XFER;
4186 p_sccb->Sccb_XferCnt = 0x00;
4187 }
4188
4189 if (p_sccb->DataLength == 0x00)
4190
4191 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4192
4193 if (p_sccb->ControlByte & F_USE_CMD_Q)
4194 {
4195 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4196 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4197
4198 else
4199 currTar_Info->TarStatus |= TAG_Q_TRYING;
4200 }
4201
4202/* For !single SCSI device in system & device allow Disconnect
4203 or command is tag_q type then send Cmd with Disconnect Enable
4204 else send Cmd with Disconnect Disable */
4205
4206/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004207 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004208 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4209 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4210*/
4211 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4212 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004213 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214 }
4215
4216 else {
4217
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004218 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004219 }
4220
4221 p_sccb->HostStatus = 0x00;
4222 p_sccb->TargetStatus = 0x00;
4223 p_sccb->Sccb_tag = 0x00;
4224 p_sccb->Sccb_MGRFlags = 0x00;
4225 p_sccb->Sccb_sgseg = 0x00;
4226 p_sccb->Sccb_ATC = 0x00;
4227 p_sccb->Sccb_savedATC = 0x00;
4228/*
4229 p_sccb->SccbVirtDataPtr = 0x00;
4230 p_sccb->Sccb_forwardlink = NULL;
4231 p_sccb->Sccb_backlink = NULL;
4232 */
4233 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4234 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4235 p_sccb->Sccb_scsimsg = SMNO_OP;
4236
4237}
4238
4239
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240/*---------------------------------------------------------------------
4241 *
4242 * Function: Phase Decode
4243 *
4244 * Description: Determine the phase and call the appropriate function.
4245 *
4246 *---------------------------------------------------------------------*/
4247
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004248static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249{
4250 unsigned char phase_ref;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004251 void (*phase) (ULONG, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252
4253
4254 DISABLE_AUTO(p_port);
4255
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004256 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257
James Bottomley 47b5d692005-04-24 02:38:05 -05004258 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
4260 (*phase)(p_port, p_card); /* Call the correct phase func */
4261}
4262
4263
4264
4265/*---------------------------------------------------------------------
4266 *
4267 * Function: Data Out Phase
4268 *
4269 * Description: Start up both the BusMaster and Xbow.
4270 *
4271 *---------------------------------------------------------------------*/
4272
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004273static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004274{
4275
4276 PSCCB currSCCB;
4277
James Bottomley 47b5d692005-04-24 02:38:05 -05004278 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004279 if (currSCCB == NULL)
4280 {
4281 return; /* Exit if No SCCB record */
4282 }
4283
4284 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4285 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4286
4287 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4288
4289 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4290
4291 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4292
James Bottomley 47b5d692005-04-24 02:38:05 -05004293 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294
4295 if (currSCCB->Sccb_XferCnt == 0) {
4296
4297
4298 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4299 (currSCCB->HostStatus == SCCB_COMPLETE))
4300 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4301
James Bottomley 47b5d692005-04-24 02:38:05 -05004302 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004304 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305 }
4306}
4307
4308
4309/*---------------------------------------------------------------------
4310 *
4311 * Function: Data In Phase
4312 *
4313 * Description: Startup the BusMaster and the XBOW.
4314 *
4315 *---------------------------------------------------------------------*/
4316
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004317static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004318{
4319
4320 PSCCB currSCCB;
4321
James Bottomley 47b5d692005-04-24 02:38:05 -05004322 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004323
4324 if (currSCCB == NULL)
4325 {
4326 return; /* Exit if No SCCB record */
4327 }
4328
4329
4330 currSCCB->Sccb_scsistat = DATA_IN_ST;
4331 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4332 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4333
4334 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4335
4336 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4337
4338 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4339
James Bottomley 47b5d692005-04-24 02:38:05 -05004340 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341
4342 if (currSCCB->Sccb_XferCnt == 0) {
4343
4344
4345 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4346 (currSCCB->HostStatus == SCCB_COMPLETE))
4347 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4348
James Bottomley 47b5d692005-04-24 02:38:05 -05004349 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004351 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352
4353 }
4354}
4355
4356/*---------------------------------------------------------------------
4357 *
4358 * Function: Command Phase
4359 *
4360 * Description: Load the CDB into the automation and start it up.
4361 *
4362 *---------------------------------------------------------------------*/
4363
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004364static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365{
4366 PSCCB currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367 ULONG cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004368 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369
James Bottomley 47b5d692005-04-24 02:38:05 -05004370 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371
4372 if (currSCCB->OperationCode == RESET_COMMAND) {
4373
4374 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4375 currSCCB->CdbLength = SIX_BYTE_CMD;
4376 }
4377
4378 WR_HARPOON(p_port+hp_scsisig, 0x00);
4379
4380 ARAM_ACCESS(p_port);
4381
4382
4383 cdb_reg = p_port + CMD_STRT;
4384
4385 for (i=0; i < currSCCB->CdbLength; i++) {
4386
4387 if (currSCCB->OperationCode == RESET_COMMAND)
4388
4389 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4390
4391 else
4392 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4393 cdb_reg +=2;
4394 }
4395
4396 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4397 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4398
4399 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4400
4401 currSCCB->Sccb_scsistat = COMMAND_ST;
4402
4403 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4404 SGRAM_ACCESS(p_port);
4405}
4406
4407
4408/*---------------------------------------------------------------------
4409 *
4410 * Function: Status phase
4411 *
4412 * Description: Bring in the status and command complete message bytes
4413 *
4414 *---------------------------------------------------------------------*/
4415
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004416static void FPT_phaseStatus(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004417{
4418 /* Start-up the automation to finish off this command and let the
4419 isr handle the interrupt for command complete when it comes in.
4420 We could wait here for the interrupt to be generated?
4421 */
4422
4423 WR_HARPOON(port+hp_scsisig, 0x00);
4424
4425 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4426}
4427
4428
4429/*---------------------------------------------------------------------
4430 *
4431 * Function: Phase Message Out
4432 *
4433 * Description: Send out our message (if we have one) and handle whatever
4434 * else is involed.
4435 *
4436 *---------------------------------------------------------------------*/
4437
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004438static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004440 unsigned char message,scsiID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004441 PSCCB currSCCB;
4442 PSCCBMgr_tar_info currTar_Info;
4443
James Bottomley 47b5d692005-04-24 02:38:05 -05004444 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004445
4446 if (currSCCB != NULL) {
4447
4448 message = currSCCB->Sccb_scsimsg;
4449 scsiID = currSCCB->TargID;
4450
4451 if (message == SMDEV_RESET)
4452 {
4453
4454
James Bottomley 47b5d692005-04-24 02:38:05 -05004455 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004456 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004457 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458
James Bottomley 47b5d692005-04-24 02:38:05 -05004459 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460 {
4461
James Bottomley 47b5d692005-04-24 02:38:05 -05004462 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463
4464 }
4465
James Bottomley 47b5d692005-04-24 02:38:05 -05004466 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467 {
4468
James Bottomley 47b5d692005-04-24 02:38:05 -05004469 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 }
4471
4472
James Bottomley 47b5d692005-04-24 02:38:05 -05004473 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4474 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 }
4476 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4477 {
4478 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004479 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004480 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004481 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4482 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 }
4484
4485 }
4486
4487 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4488 {
4489
4490
4491 if(message == SMNO_OP)
4492 {
4493 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4494
James Bottomley 47b5d692005-04-24 02:38:05 -05004495 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496 return;
4497 }
4498 }
4499 else
4500 {
4501
4502
4503 if (message == SMABORT)
4504
James Bottomley 47b5d692005-04-24 02:38:05 -05004505 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506 }
4507
4508 }
4509 else
4510 {
4511 message = SMABORT;
4512 }
4513
4514 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4515
4516
4517 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4518
4519 WR_HARPOON(port+hp_scsidata_0,message);
4520
4521 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4522
4523 ACCEPT_MSG(port);
4524
4525 WR_HARPOON(port+hp_portctrl_0, 0x00);
4526
4527 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4528 (message == SMABORT_TAG) )
4529 {
4530
4531 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4532
4533 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4534 {
4535 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4536
4537 if (currSCCB != NULL)
4538 {
4539
James Bottomley 47b5d692005-04-24 02:38:05 -05004540 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4541 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4542 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004544 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545
James Bottomley 47b5d692005-04-24 02:38:05 -05004546 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547 }
4548
4549 else
4550 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004551 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004552 }
4553 }
4554
4555 else
4556 {
4557
James Bottomley 47b5d692005-04-24 02:38:05 -05004558 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004559 }
4560 }
4561
4562 else
4563 {
4564
4565 if(message == SMPARITY)
4566 {
4567 currSCCB->Sccb_scsimsg = SMNO_OP;
4568 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4569 }
4570 else
4571 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004572 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004573 }
4574 }
4575}
4576
4577
4578/*---------------------------------------------------------------------
4579 *
4580 * Function: Message In phase
4581 *
4582 * Description: Bring in the message and determine what to do with it.
4583 *
4584 *---------------------------------------------------------------------*/
4585
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004586static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004588 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589 PSCCB currSCCB;
4590
James Bottomley 47b5d692005-04-24 02:38:05 -05004591 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592
James Bottomley 47b5d692005-04-24 02:38:05 -05004593 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004594 {
4595
James Bottomley 47b5d692005-04-24 02:38:05 -05004596 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597 }
4598
4599 message = RD_HARPOON(port+hp_scsidata_0);
4600 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4601 {
4602
4603 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4604
4605 }
4606
4607 else
4608 {
4609
James Bottomley 47b5d692005-04-24 02:38:05 -05004610 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611 if (message)
4612 {
4613
4614
James Bottomley 47b5d692005-04-24 02:38:05 -05004615 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004616
4617 }
4618 else
4619 {
4620 if(currSCCB->Sccb_scsimsg != SMPARITY)
4621 ACCEPT_MSG(port);
4622 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4623 }
4624 }
4625
4626}
4627
4628
4629/*---------------------------------------------------------------------
4630 *
4631 * Function: Illegal phase
4632 *
4633 * Description: Target switched to some illegal phase, so all we can do
4634 * is report an error back to the host (if that is possible)
4635 * and send an ABORT message to the misbehaving target.
4636 *
4637 *---------------------------------------------------------------------*/
4638
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004639static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004640{
4641 PSCCB currSCCB;
4642
James Bottomley 47b5d692005-04-24 02:38:05 -05004643 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004644
4645 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4646 if (currSCCB != NULL) {
4647
4648 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4649 currSCCB->Sccb_scsistat = ABORT_ST;
4650 currSCCB->Sccb_scsimsg = SMABORT;
4651 }
4652
4653 ACCEPT_MSG_ATN(port);
4654}
4655
4656
4657
4658/*---------------------------------------------------------------------
4659 *
4660 * Function: Phase Check FIFO
4661 *
4662 * Description: Make sure data has been flushed from both FIFOs and abort
4663 * the operations if necessary.
4664 *
4665 *---------------------------------------------------------------------*/
4666
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004667static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668{
4669 ULONG xfercnt;
4670 PSCCB currSCCB;
4671
James Bottomley 47b5d692005-04-24 02:38:05 -05004672 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004673
4674 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4675 {
4676
4677 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4678 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4679
4680
4681 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4682 {
4683 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4684
4685 currSCCB->Sccb_XferCnt = 0;
4686
4687 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4688 (currSCCB->HostStatus == SCCB_COMPLETE))
4689 {
4690 currSCCB->HostStatus = SCCB_PARITY_ERR;
4691 WRW_HARPOON((port+hp_intstat), PARITY);
4692 }
4693
James Bottomley 47b5d692005-04-24 02:38:05 -05004694 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695
James Bottomley 47b5d692005-04-24 02:38:05 -05004696 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004697
4698 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4699 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4700
4701 }
4702 } /*End Data In specific code. */
4703
4704
4705
Linus Torvalds1da177e2005-04-16 15:20:36 -07004706 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004707
4708
4709 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4710
4711
4712 WR_HARPOON(port+hp_portctrl_0, 0x00);
4713
4714 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4715
4716 currSCCB->Sccb_XferCnt = xfercnt;
4717
4718 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4719 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4720
4721 currSCCB->HostStatus = SCCB_PARITY_ERR;
4722 WRW_HARPOON((port+hp_intstat), PARITY);
4723 }
4724
4725
James Bottomley 47b5d692005-04-24 02:38:05 -05004726 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004727
4728
4729 WR_HARPOON(port+hp_fifowrite, 0x00);
4730 WR_HARPOON(port+hp_fiforead, 0x00);
4731 WR_HARPOON(port+hp_xferstat, 0x00);
4732
4733 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4734}
4735
4736
4737/*---------------------------------------------------------------------
4738 *
4739 * Function: Phase Bus Free
4740 *
4741 * Description: We just went bus free so figure out if it was
4742 * because of command complete or from a disconnect.
4743 *
4744 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004745static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004746{
4747 PSCCB currSCCB;
4748
James Bottomley 47b5d692005-04-24 02:38:05 -05004749 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004750
4751 if (currSCCB != NULL)
4752 {
4753
4754 DISABLE_AUTO(port);
4755
4756
4757 if (currSCCB->OperationCode == RESET_COMMAND)
4758 {
4759
James Bottomley 47b5d692005-04-24 02:38:05 -05004760 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4761 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004763 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004765
James Bottomley 47b5d692005-04-24 02:38:05 -05004766 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004767
James Bottomley 47b5d692005-04-24 02:38:05 -05004768 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004769
4770 }
4771
4772 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4773 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004775 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004776 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004777 }
4778
4779 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4780 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004781 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4782 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004783 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4784
James Bottomley 47b5d692005-04-24 02:38:05 -05004785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786 }
4787
Linus Torvalds1da177e2005-04-16 15:20:36 -07004788 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4789 {
4790 /* Make sure this is not a phony BUS_FREE. If we were
4791 reselected or if BUSY is NOT on then this is a
4792 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4793
4794 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4795 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4796 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004797 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4798 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004799 }
4800
4801 else
4802 {
4803 return;
4804 }
4805 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004806
4807 else
4808 {
4809
4810 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4811
4812 if (!currSCCB->HostStatus)
4813 {
4814 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4815 }
4816
James Bottomley 47b5d692005-04-24 02:38:05 -05004817 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4818 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4819 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004820 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004821 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004822
James Bottomley 47b5d692005-04-24 02:38:05 -05004823 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004824 return;
4825 }
4826
4827
James Bottomley 47b5d692005-04-24 02:38:05 -05004828 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004829
4830 } /*end if !=null */
4831}
4832
4833
4834
4835
Linus Torvalds1da177e2005-04-16 15:20:36 -07004836/*---------------------------------------------------------------------
4837 *
4838 * Function: Auto Load Default Map
4839 *
4840 * Description: Load the Automation RAM with the defualt map values.
4841 *
4842 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004843static void FPT_autoLoadDefaultMap(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004844{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004845 ULONG map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004846
4847 ARAM_ACCESS(p_port);
4848 map_addr = p_port + hp_aramBase;
4849
4850 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4851 map_addr +=2;
4852 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4873 map_addr +=2;
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4875 map_addr +=2;
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4877 map_addr +=2;
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4883 map_addr +=2;
4884 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4885 map_addr +=2; /*This means AYNC DATA IN */
4886 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4887 map_addr +=2;
4888 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4909 map_addr +=2;
4910 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4911 map_addr +=2;
4912 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4913 map_addr +=2;
4914 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4917 map_addr +=2;
4918 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4919 map_addr +=2;
4920 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4921 map_addr +=2;
4922
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4924 map_addr +=2;
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4926 map_addr +=2;
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4928 map_addr +=2;
4929 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4930 map_addr +=2; /* DIDN'T GET ONE */
4931 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4932 map_addr +=2;
4933 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4934 map_addr +=2;
4935 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4936
4937
4938
4939 SGRAM_ACCESS(p_port);
4940}
4941
4942/*---------------------------------------------------------------------
4943 *
4944 * Function: Auto Command Complete
4945 *
4946 * Description: Post command back to host and find another command
4947 * to execute.
4948 *
4949 *---------------------------------------------------------------------*/
4950
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004951static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004952{
4953 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004954 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004955
James Bottomley 47b5d692005-04-24 02:38:05 -05004956 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004957
4958 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4959
James Bottomley 47b5d692005-04-24 02:38:05 -05004960 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004961
4962 if (status_byte != SSGOOD) {
4963
4964 if (status_byte == SSQ_FULL) {
4965
4966
James Bottomley 47b5d692005-04-24 02:38:05 -05004967 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4968 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004969 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004970 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4971 if(FPT_BL_Card[p_card].discQCount != 0)
4972 FPT_BL_Card[p_card].discQCount--;
4973 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 -07004974 }
4975 else
4976 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004977 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004978 if(currSCCB->Sccb_tag)
4979 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004980 if(FPT_BL_Card[p_card].discQCount != 0)
4981 FPT_BL_Card[p_card].discQCount--;
4982 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004983 }else
4984 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004985 if(FPT_BL_Card[p_card].discQCount != 0)
4986 FPT_BL_Card[p_card].discQCount--;
4987 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004988 }
4989 }
4990
4991 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4992
James Bottomley 47b5d692005-04-24 02:38:05 -05004993 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004994
4995 return;
4996 }
4997
4998 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4999 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005000 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005001 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005002
James Bottomley 47b5d692005-04-24 02:38:05 -05005003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5004 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005005
James Bottomley 47b5d692005-04-24 02:38:05 -05005006 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5007 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005008 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005009 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5010 if(FPT_BL_Card[p_card].discQCount != 0)
5011 FPT_BL_Card[p_card].discQCount--;
5012 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 -07005013 }
5014 else
5015 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005016 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005017 if(currSCCB->Sccb_tag)
5018 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005019 if(FPT_BL_Card[p_card].discQCount != 0)
5020 FPT_BL_Card[p_card].discQCount--;
5021 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005022 }else
5023 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005024 if(FPT_BL_Card[p_card].discQCount != 0)
5025 FPT_BL_Card[p_card].discQCount--;
5026 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005027 }
5028 }
5029 return;
5030
5031 }
5032
5033 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5034 {
5035
James Bottomley 47b5d692005-04-24 02:38:05 -05005036 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5037 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005038 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5039
James Bottomley 47b5d692005-04-24 02:38:05 -05005040 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5041 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005042
James Bottomley 47b5d692005-04-24 02:38:05 -05005043 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5044 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005045 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005046 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5047 if(FPT_BL_Card[p_card].discQCount != 0)
5048 FPT_BL_Card[p_card].discQCount--;
5049 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 -07005050 }
5051 else
5052 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005053 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005054 if(currSCCB->Sccb_tag)
5055 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005056 if(FPT_BL_Card[p_card].discQCount != 0)
5057 FPT_BL_Card[p_card].discQCount--;
5058 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005059 }else
5060 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005061 if(FPT_BL_Card[p_card].discQCount != 0)
5062 FPT_BL_Card[p_card].discQCount--;
5063 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005064 }
5065 }
5066 return;
5067
5068 }
5069
5070 if (status_byte == SSCHECK)
5071 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005072 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005073 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005074 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005075 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005076 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005077 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005078 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005079 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005080 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005081 }
5082 }
5083 }
5084
5085 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5086
5087 currSCCB->SccbStatus = SCCB_ERROR;
5088 currSCCB->TargetStatus = status_byte;
5089
5090 if (status_byte == SSCHECK) {
5091
James Bottomley 47b5d692005-04-24 02:38:05 -05005092 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5093 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005094
5095
Linus Torvalds1da177e2005-04-16 15:20:36 -07005096 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5097
5098 if (currSCCB->RequestSenseLength == 0)
5099 currSCCB->RequestSenseLength = 14;
5100
James Bottomley 47b5d692005-04-24 02:38:05 -05005101 FPT_ssenss(&FPT_BL_Card[p_card]);
5102 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005103
James Bottomley 47b5d692005-04-24 02:38:05 -05005104 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5105 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005106 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005107 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5108 if(FPT_BL_Card[p_card].discQCount != 0)
5109 FPT_BL_Card[p_card].discQCount--;
5110 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 -07005111 }
5112 else
5113 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005114 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005115 if(currSCCB->Sccb_tag)
5116 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005117 if(FPT_BL_Card[p_card].discQCount != 0)
5118 FPT_BL_Card[p_card].discQCount--;
5119 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005120 }else
5121 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005122 if(FPT_BL_Card[p_card].discQCount != 0)
5123 FPT_BL_Card[p_card].discQCount--;
5124 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005125 }
5126 }
5127 return;
5128 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005129 }
5130 }
5131 }
5132
5133
James Bottomley 47b5d692005-04-24 02:38:05 -05005134 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5135 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5136 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005137 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005138 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005139
5140
James Bottomley 47b5d692005-04-24 02:38:05 -05005141 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005142}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005143
5144#define SHORT_WAIT 0x0000000F
5145#define LONG_WAIT 0x0000FFFFL
5146
Linus Torvalds1da177e2005-04-16 15:20:36 -07005147
5148/*---------------------------------------------------------------------
5149 *
5150 * Function: Data Transfer Processor
5151 *
5152 * Description: This routine performs two tasks.
5153 * (1) Start data transfer by calling HOST_DATA_XFER_START
5154 * function. Once data transfer is started, (2) Depends
5155 * on the type of data transfer mode Scatter/Gather mode
5156 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5157 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5158 * data transfer done. In Scatter/Gather mode, this routine
5159 * checks bus master command complete and dual rank busy
5160 * bit to keep chaining SC transfer command. Similarly,
5161 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5162 * (F_HOST_XFER_ACT bit) for data transfer done.
5163 *
5164 *---------------------------------------------------------------------*/
5165
James Bottomley 47b5d692005-04-24 02:38:05 -05005166static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005167{
5168 PSCCB currSCCB;
5169
5170 currSCCB = pCurrCard->currentSCCB;
5171
5172 if (currSCCB->Sccb_XferState & F_SG_XFER)
5173 {
5174 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5175
5176 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005177 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005178 currSCCB->Sccb_SGoffset = 0x00;
5179 }
5180 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5181
James Bottomley 47b5d692005-04-24 02:38:05 -05005182 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005183 }
5184
5185 else
5186 {
5187 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5188 {
5189 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5190
James Bottomley 47b5d692005-04-24 02:38:05 -05005191 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005192 }
5193 }
5194}
5195
5196
5197/*---------------------------------------------------------------------
5198 *
5199 * Function: BusMaster Scatter Gather Data Transfer Start
5200 *
5201 * Description:
5202 *
5203 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005204static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005205{
5206 ULONG count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005207 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005208 unsigned char sg_count, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209 ULONG reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005210
5211
5212 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5213
5214 count = ((ULONG) HOST_RD_CMD)<<24;
5215 }
5216
5217 else {
5218 count = ((ULONG) HOST_WRT_CMD)<<24;
5219 }
5220
5221 sg_count = 0;
5222 tmpSGCnt = 0;
5223 sg_index = pcurrSCCB->Sccb_sgseg;
5224 reg_offset = hp_aramBase;
5225
5226
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005227 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005228
5229
5230 WR_HARPOON(p_port+hp_page_ctrl, i);
5231
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005232 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyance793212006-03-08 00:14:26 -08005233 ((ULONG)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234
Linus Torvalds1da177e2005-04-16 15:20:36 -07005235 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5236 (sg_index * 2));
5237
5238 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5239 (sg_index * 2));
5240
5241 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5242 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005243
5244
5245 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5246
5247 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5248 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5249
5250 tmpSGCnt = count & 0x00FFFFFFL;
5251 }
5252
5253 WR_HARP32(p_port,reg_offset,addr);
5254 reg_offset +=4;
5255
5256 WR_HARP32(p_port,reg_offset,count);
5257 reg_offset +=4;
5258
5259 count &= 0xFF000000L;
5260 sg_index++;
5261 sg_count++;
5262
5263 } /*End While */
5264
5265 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5266
5267 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5268
5269 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5270
5271 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5272
5273
5274 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5275 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5276 }
5277
5278 else {
5279
5280
5281 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5282 (tmpSGCnt & 0x000000001))
5283 {
5284
5285 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5286 tmpSGCnt--;
5287 }
5288
5289
5290 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5291
5292 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5293 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5294 }
5295
5296
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005297 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005298
5299}
5300
5301
5302/*---------------------------------------------------------------------
5303 *
5304 * Function: BusMaster Data Transfer Start
5305 *
5306 * Description:
5307 *
5308 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005309static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005310{
5311 ULONG addr,count;
5312
5313 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5314
5315 count = pcurrSCCB->Sccb_XferCnt;
5316
5317 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5318 }
5319
5320 else {
5321 addr = pcurrSCCB->SensePointer;
5322 count = pcurrSCCB->RequestSenseLength;
5323
5324 }
5325
Linus Torvalds1da177e2005-04-16 15:20:36 -07005326 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005327
5328
5329 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5330
5331 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5332 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5333
5334 WR_HARPOON(p_port+hp_xfer_cmd,
5335 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5336 }
5337
5338 else {
5339
5340 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5341 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5342
5343 WR_HARPOON(p_port+hp_xfer_cmd,
5344 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5345
5346 }
5347}
5348
5349
5350/*---------------------------------------------------------------------
5351 *
5352 * Function: BusMaster Timeout Handler
5353 *
5354 * Description: This function is called after a bus master command busy time
5355 * out is detected. This routines issue halt state machine
5356 * with a software time out for command busy. If command busy
5357 * is still asserted at the end of the time out, it issues
5358 * hard abort with another software time out. It hard abort
5359 * command busy is also time out, it'll just give up.
5360 *
5361 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005362static unsigned char FPT_busMstrTimeOut(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363{
5364 ULONG timeout;
5365
5366 timeout = LONG_WAIT;
5367
5368 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5369
5370 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5371
5372
5373
5374 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5375 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5376
5377 timeout = LONG_WAIT;
5378 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5379 }
5380
5381 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5382
5383 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005384 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005385 }
5386
5387 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005388 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389 }
5390}
5391
5392
5393/*---------------------------------------------------------------------
5394 *
5395 * Function: Host Data Transfer Abort
5396 *
5397 * Description: Abort any in progress transfer.
5398 *
5399 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005400static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005401{
5402
5403 ULONG timeout;
5404 ULONG remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005405 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005406
James Bottomley 47b5d692005-04-24 02:38:05 -05005407 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005408
5409 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5410
5411
5412 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5413
5414 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5415 timeout = LONG_WAIT;
5416
5417 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5418
5419 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5420
5421 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5422
James Bottomley 47b5d692005-04-24 02:38:05 -05005423 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005424
5425 if (pCurrSCCB->HostStatus == 0x00)
5426
5427 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5428
5429 }
5430
5431 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5432
5433 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5434
5435 if (pCurrSCCB->HostStatus == 0x00)
5436
5437 {
5438 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005439 }
5440 }
5441 }
5442 }
5443
5444 else if (pCurrSCCB->Sccb_XferCnt) {
5445
5446 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5447
5448
5449 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5450 ~SCATTER_EN));
5451
5452 WR_HARPOON(port+hp_sg_addr,0x00);
5453
5454 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5455
Alexey Dobriyance793212006-03-08 00:14:26 -08005456 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005457
Alexey Dobriyance793212006-03-08 00:14:26 -08005458 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005459 }
5460
5461 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5462
5463 while (remain_cnt < 0x01000000L) {
5464
5465 sg_ptr--;
5466
Linus Torvalds1da177e2005-04-16 15:20:36 -07005467 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5468 DataPointer) + (sg_ptr * 2)))) {
5469
5470 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5471 DataPointer) + (sg_ptr * 2)));
5472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005473
5474 else {
5475
5476 break;
5477 }
5478 }
5479
5480
5481
5482 if (remain_cnt < 0x01000000L) {
5483
5484
5485 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5486
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005487 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005488
5489
5490 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5491 && (remain_cnt == 0))
5492
5493 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5494 }
5495
5496 else {
5497
5498
5499 if (pCurrSCCB->HostStatus == 0x00) {
5500
5501 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5502 }
5503 }
5504 }
5505
5506
5507 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5508
5509
5510 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5511
James Bottomley 47b5d692005-04-24 02:38:05 -05005512 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005513 }
5514
5515 else {
5516
5517 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5518
5519 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5520
5521 if (pCurrSCCB->HostStatus == 0x00) {
5522
5523 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005524 }
5525 }
5526 }
5527
5528 }
5529 }
5530
5531 else {
5532
5533
5534 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5535
5536 timeout = SHORT_WAIT;
5537
5538 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5539 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5540 timeout--) {}
5541 }
5542
5543 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5544
5545 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5546 FLUSH_XFER_CNTR));
5547
5548 timeout = LONG_WAIT;
5549
5550 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5551 timeout--) {}
5552
5553 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5554 ~FLUSH_XFER_CNTR));
5555
5556
5557 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5558
5559 if (pCurrSCCB->HostStatus == 0x00) {
5560
5561 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5562 }
5563
James Bottomley 47b5d692005-04-24 02:38:05 -05005564 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005565 }
5566 }
5567
5568 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5569
5570 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5571
5572 if (pCurrSCCB->HostStatus == 0x00) {
5573
5574 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005575 }
5576 }
5577 }
5578 }
5579
5580 }
5581
5582 else {
5583
5584
5585 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5586
5587 timeout = LONG_WAIT;
5588
5589 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5590
5591 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5592
5593 if (pCurrSCCB->HostStatus == 0x00) {
5594
5595 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5596 }
5597
James Bottomley 47b5d692005-04-24 02:38:05 -05005598 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005599 }
5600 }
5601
5602
5603 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5604
5605 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5606
5607 if (pCurrSCCB->HostStatus == 0x00) {
5608
5609 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005610 }
5611 }
5612
5613 }
5614
5615 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5616
5617 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5618 ~SCATTER_EN));
5619
5620 WR_HARPOON(port+hp_sg_addr,0x00);
5621
5622 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5623
5624 pCurrSCCB->Sccb_SGoffset = 0x00;
5625
5626
5627 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5628 pCurrSCCB->DataLength) {
5629
5630 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5631
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005632 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005633
5634 }
5635 }
5636
5637 else {
5638
5639 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5640
5641 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5642 }
5643 }
5644
5645 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5646}
5647
5648
5649
5650/*---------------------------------------------------------------------
5651 *
5652 * Function: Host Data Transfer Restart
5653 *
5654 * Description: Reset the available count due to a restore data
5655 * pointers message.
5656 *
5657 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005658static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005659{
5660 ULONG data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005661 unsigned int sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005663
5664 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5665
5666 currSCCB->Sccb_XferCnt = 0;
5667
5668 sg_index = 0xffff; /*Index by long words into sg list. */
5669 data_count = 0; /*Running count of SG xfer counts. */
5670
Linus Torvalds1da177e2005-04-16 15:20:36 -07005671 sg_ptr = (ULONG *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005672
5673 while (data_count < currSCCB->Sccb_ATC) {
5674
5675 sg_index++;
5676 data_count += *(sg_ptr+(sg_index * 2));
5677 }
5678
5679 if (data_count == currSCCB->Sccb_ATC) {
5680
5681 currSCCB->Sccb_SGoffset = 0;
5682 sg_index++;
5683 }
5684
5685 else {
5686 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5687 }
5688
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005689 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005690 }
5691
5692 else {
5693 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5694 }
5695}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005696
5697
5698
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699/*---------------------------------------------------------------------
5700 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005701 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702 *
5703 * Description: Setup all data structures necessary for SCAM selection.
5704 *
5705 *---------------------------------------------------------------------*/
5706
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005707static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005708{
5709
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005710 unsigned char loser,assigned_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005711 ULONG p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005712
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005713 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005714 PSCCBcard currCard;
5715 PNVRamInfo pCurrNvRam;
5716
James Bottomley 47b5d692005-04-24 02:38:05 -05005717 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005718 p_port = currCard->ioPort;
5719 pCurrNvRam = currCard->pNvRamInfo;
5720
5721
5722 if(pCurrNvRam){
5723 ScamFlg = pCurrNvRam->niScamConf;
5724 i = pCurrNvRam->niSysConf;
5725 }
5726 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005727 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5728 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005729 }
5730 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5731 return;
5732
James Bottomley 47b5d692005-04-24 02:38:05 -05005733 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005734
5735 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5736 too slow to return to SCAM selection */
5737
5738 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005739 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005740 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005741 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742
James Bottomley 47b5d692005-04-24 02:38:05 -05005743 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005744
5745 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5746 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005747 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005748
James Bottomley 47b5d692005-04-24 02:38:05 -05005749 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005750
5751 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005752 FPT_scxferc(p_port,SYNC_PTRN);
5753 FPT_scxferc(p_port,DOM_MSTR);
5754 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005755 } while ( loser == 0xFF );
5756
James Bottomley 47b5d692005-04-24 02:38:05 -05005757 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005758
5759 if ((p_power_up) && (!loser))
5760 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005761 FPT_sresb(p_port,p_card);
5762 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763
James Bottomley 47b5d692005-04-24 02:38:05 -05005764 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005765
James Bottomley 47b5d692005-04-24 02:38:05 -05005766 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005767
5768 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005769 FPT_scxferc(p_port, SYNC_PTRN);
5770 FPT_scxferc(p_port, DOM_MSTR);
5771 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005772 id_string[0]);
5773 } while ( loser == 0xFF );
5774
James Bottomley 47b5d692005-04-24 02:38:05 -05005775 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005776 }
5777 }
5778
5779 else
5780 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005781 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005782 }
5783
5784
5785 if (!loser)
5786 {
5787
James Bottomley 47b5d692005-04-24 02:38:05 -05005788 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005789
5790
5791 if (ScamFlg & SCAM_ENABLED)
5792 {
5793
5794 for (i=0; i < MAX_SCSI_TAR; i++)
5795 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005796 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5797 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005798 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005799 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005800 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005801 FPT_scamInfo[i].state = LEGACY;
5802 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5803 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005804 {
5805
James Bottomley 47b5d692005-04-24 02:38:05 -05005806 FPT_scamInfo[i].id_string[0] = 0xFF;
5807 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005808 if(pCurrNvRam == NULL)
5809 currCard->globalFlags |= F_UPDATE_EEPROM;
5810 }
5811 }
5812 }
5813 }
5814
James Bottomley 47b5d692005-04-24 02:38:05 -05005815 FPT_sresb(p_port,p_card);
5816 FPT_Wait1Second(p_port);
5817 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5818 FPT_scsel(p_port);
5819 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005820 }
5821
Linus Torvalds1da177e2005-04-16 15:20:36 -07005822 }
5823
5824 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5825 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005826 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5827 assigned_id = 0;
5828 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829
5830 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005831 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005832
James Bottomley 47b5d692005-04-24 02:38:05 -05005833 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005834 if (i == ASSIGN_ID)
5835 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005836 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005837 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005838 i = FPT_scxferc(p_port,0x00);
5839 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005841 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005842
James Bottomley 47b5d692005-04-24 02:38:05 -05005843 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005844 {
5845 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005846 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005847 FPT_inisci(p_card, p_port, p_our_id);
5848 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5849 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005850 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005851 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005852 }
5853 }
5854 }
5855 }
5856
5857 else if (i == SET_P_FLAG)
5858 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005859 if (!(FPT_scsendi(p_port,
5860 &FPT_scamInfo[p_our_id].id_string[0])))
5861 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005862 }
5863 }while (!assigned_id);
5864
James Bottomley 47b5d692005-04-24 02:38:05 -05005865 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005866 }
5867
Linus Torvalds1da177e2005-04-16 15:20:36 -07005868 if (ScamFlg & SCAM_ENABLED)
5869 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005870 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005871 if (currCard->globalFlags & F_UPDATE_EEPROM)
5872 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005873 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005874 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5875 }
5876 }
5877
5878
Linus Torvalds1da177e2005-04-16 15:20:36 -07005879/*
5880 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5881 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005882 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5883 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005884 k++;
5885 }
5886
5887 if (k==2)
5888 currCard->globalFlags |= F_SINGLE_DEVICE;
5889 else
5890 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5891*/
5892}
5893
5894
5895/*---------------------------------------------------------------------
5896 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005897 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005898 *
5899 * Description: Gain control of the bus and wait SCAM select time (250ms)
5900 *
5901 *---------------------------------------------------------------------*/
5902
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005903static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005904{
5905 if (p_sel_type == INIT_SELTD)
5906 {
5907
5908 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5909
5910
5911 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005912 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005913
5914 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005915 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005916
5917 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5918
5919 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5920
5921 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5922 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005923 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005924 }
5925
5926
5927 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5928
5929 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5930
5931 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5932 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005933 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005934 }
5935 }
5936
5937
5938 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5939 & ~ACTdeassert));
5940 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5941 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005943 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5944
5945 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5946
5947 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5948 & ~SCSI_BSY));
5949
James Bottomley 47b5d692005-04-24 02:38:05 -05005950 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005951
James Bottomley 47b5d692005-04-24 02:38:05 -05005952 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005953}
5954
5955
5956/*---------------------------------------------------------------------
5957 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005958 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005959 *
5960 * Description: Release the SCSI bus and disable SCAM selection.
5961 *
5962 *---------------------------------------------------------------------*/
5963
James Bottomley 47b5d692005-04-24 02:38:05 -05005964static void FPT_scbusf(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005965{
5966 WR_HARPOON(p_port+hp_page_ctrl,
5967 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5968
5969
5970 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5971
5972 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5973 & ~SCSI_BUS_EN));
5974
5975 WR_HARPOON(p_port+hp_scsisig, 0x00);
5976
5977
5978 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5979 & ~SCAM_EN));
5980
5981 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5982 | ACTdeassert));
5983
Linus Torvalds1da177e2005-04-16 15:20:36 -07005984 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985
5986 WR_HARPOON(p_port+hp_page_ctrl,
5987 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5988}
5989
5990
5991
5992/*---------------------------------------------------------------------
5993 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005994 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005995 *
5996 * Description: Assign an ID to all the SCAM devices.
5997 *
5998 *---------------------------------------------------------------------*/
5999
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006000static void FPT_scasid(unsigned char p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006001{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006002 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006004 unsigned char i,k,scam_id;
6005 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006006 PNVRamInfo pCurrNvRam;
6007 ushort_ptr pCrcBytes;
6008
James Bottomley 47b5d692005-04-24 02:38:05 -05006009 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006010
James Bottomley 47b5d692005-04-24 02:38:05 -05006011 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006012
6013 while (!i)
6014 {
6015
6016 for (k=0; k < ID_STRING_LENGTH; k++)
6017 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006018 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006019 }
6020
James Bottomley 47b5d692005-04-24 02:38:05 -05006021 FPT_scxferc(p_port,SYNC_PTRN);
6022 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006023
James Bottomley 47b5d692005-04-24 02:38:05 -05006024 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025 {
6026 if(pCurrNvRam){
6027 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006028 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6029 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006030 temp_id_string[1] = crcBytes[2];
6031 temp_id_string[2] = crcBytes[0];
6032 temp_id_string[3] = crcBytes[1];
6033 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006034 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006035 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006036 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006037
6038 if (i == CLR_PRIORITY)
6039 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006040 FPT_scxferc(p_port,MISC_CODE);
6041 FPT_scxferc(p_port,CLR_P_FLAG);
6042 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006043 }
6044
6045 else if (i != NO_ID_AVAIL)
6046 {
6047 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006048 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006050 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006052 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006053
6054
6055 for (k=1; k < 0x08; k <<= 1)
6056 if (!( k & i ))
6057 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6058
James Bottomley 47b5d692005-04-24 02:38:05 -05006059 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006060
James Bottomley 47b5d692005-04-24 02:38:05 -05006061 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006062 }
6063 }
6064
6065 else
6066 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006067 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006068 }
6069
6070 } /*End while */
6071
James Bottomley 47b5d692005-04-24 02:38:05 -05006072 FPT_scxferc(p_port,SYNC_PTRN);
6073 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006074}
6075
6076
6077
6078
6079
6080/*---------------------------------------------------------------------
6081 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006082 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006083 *
6084 * Description: Select all the SCAM devices.
6085 *
6086 *---------------------------------------------------------------------*/
6087
James Bottomley 47b5d692005-04-24 02:38:05 -05006088static void FPT_scsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006089{
6090
6091 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006092 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006093
6094 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6095
6096
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006098 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6099 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006100
6101
6102 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006103 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006104
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006105 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6106 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006107 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006108
6109 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6110}
6111
6112
6113
6114/*---------------------------------------------------------------------
6115 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006116 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006117 *
6118 * Description: Handshake the p_data (DB4-0) across the bus.
6119 *
6120 *---------------------------------------------------------------------*/
6121
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006122static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006123{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006124 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006125
6126 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6127
6128 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6129
6130 curr_data &= ~BIT(7);
6131
6132 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133
James Bottomley 47b5d692005-04-24 02:38:05 -05006134 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006135 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6136
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006137 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138
6139 curr_data |= BIT(6);
6140
6141 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6142
6143 curr_data &= ~BIT(5);
6144
6145 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146
James Bottomley 47b5d692005-04-24 02:38:05 -05006147 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006148
6149 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6150 curr_data |= BIT(7);
6151
6152 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6153
6154 curr_data &= ~BIT(6);
6155
6156 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6157
James Bottomley 47b5d692005-04-24 02:38:05 -05006158 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159
6160 return(ret_data);
6161}
6162
6163
6164/*---------------------------------------------------------------------
6165 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006166 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006167 *
6168 * Description: Transfer our Identification string to determine if we
6169 * will be the dominant master.
6170 *
6171 *---------------------------------------------------------------------*/
6172
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006173static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006174{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006175 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176
James Bottomley 47b5d692005-04-24 02:38:05 -05006177 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006178
6179 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6180
6181 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6182
6183 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006184 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185
6186 else if (p_id_string[byte_cnt] & bit_cnt)
6187
James Bottomley 47b5d692005-04-24 02:38:05 -05006188 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006189
6190 else {
6191
James Bottomley 47b5d692005-04-24 02:38:05 -05006192 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006193 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006194 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006195 }
6196
6197 if ((ret_data & 0x1C) == 0x10)
6198 return(0x00); /*End of isolation stage, we won! */
6199
6200 if (ret_data & 0x1C)
6201 return(0xFF);
6202
6203 if ((defer) && (!(ret_data & 0x1F)))
6204 return(0x01); /*End of isolation stage, we lost. */
6205
6206 } /*bit loop */
6207
6208 } /*byte loop */
6209
6210 if (defer)
6211 return(0x01); /*We lost */
6212 else
6213 return(0); /*We WON! Yeeessss! */
6214}
6215
6216
6217
6218/*---------------------------------------------------------------------
6219 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006220 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006221 *
6222 * Description: Transfer the Identification string.
6223 *
6224 *---------------------------------------------------------------------*/
6225
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006226static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006227{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006228 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006229
6230 the_data = 0;
6231
6232 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6233
6234 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6235
James Bottomley 47b5d692005-04-24 02:38:05 -05006236 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006237
6238 if (ret_data & 0xFC)
6239 return(0xFF);
6240
6241 else {
6242
6243 the_data <<= 1;
6244 if (ret_data & BIT(1)) {
6245 the_data |= 1;
6246 }
6247 }
6248
6249 if ((ret_data & 0x1F) == 0)
6250 {
6251/*
6252 if(bit_cnt != 0 || bit_cnt != 8)
6253 {
6254 byte_cnt = 0;
6255 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006256 FPT_scxferc(p_port, SYNC_PTRN);
6257 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006258 continue;
6259 }
6260*/
6261 if (byte_cnt)
6262 return(0x00);
6263 else
6264 return(0xFF);
6265 }
6266
6267 } /*bit loop */
6268
6269 p_id_string[byte_cnt] = the_data;
6270
6271 } /*byte loop */
6272
6273 return(0);
6274}
6275
6276
6277
6278/*---------------------------------------------------------------------
6279 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006280 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006281 *
6282 * Description: Sample the SCSI data bus making sure the signal has been
6283 * deasserted for the correct number of consecutive samples.
6284 *
6285 *---------------------------------------------------------------------*/
6286
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006287static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006288{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006289 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006290
6291 i = 0;
6292 while ( i < MAX_SCSI_TAR ) {
6293
6294 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6295
6296 i = 0;
6297
6298 else
6299
6300 i++;
6301
6302 }
6303}
6304
6305
6306
6307/*---------------------------------------------------------------------
6308 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006309 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006310 *
6311 * Description: Sample the SCSI Signal lines making sure the signal has been
6312 * deasserted for the correct number of consecutive samples.
6313 *
6314 *---------------------------------------------------------------------*/
6315
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006316static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006317{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006318 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006319
6320 i = 0;
6321 while ( i < MAX_SCSI_TAR ) {
6322
6323 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6324
6325 i = 0;
6326
6327 else
6328
6329 i++;
6330
6331 }
6332}
6333
6334
6335/*---------------------------------------------------------------------
6336 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006337 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006338 *
6339 * Description: Make sure we received a valid data byte.
6340 *
6341 *---------------------------------------------------------------------*/
6342
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006343static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006344{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006345 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346
6347 for (count=1; count < 0x08; count<<=1) {
6348 if (!(p_quintet & count))
6349 p_quintet -= 0x80;
6350 }
6351
6352 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006353 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006354
6355 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006356 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006357}
6358
6359
6360/*---------------------------------------------------------------------
6361 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006362 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363 *
6364 * Description: Select the specified device ID using a selection timeout
6365 * less than 4ms. If somebody responds then it is a legacy
6366 * drive and this ID must be marked as such.
6367 *
6368 *---------------------------------------------------------------------*/
6369
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006370static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006371{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372 ULONG i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373
6374 WR_HARPOON(p_port+hp_page_ctrl,
6375 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6376
6377 ARAM_ACCESS(p_port);
6378
6379 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6380 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6381
6382
6383 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6384 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6385 }
6386 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6387
6388 WRW_HARPOON((p_port+hp_intstat),
6389 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6390
6391 WR_HARPOON(p_port+hp_select_id, targ_id);
6392
6393 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6394 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6395 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6396
6397
6398 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6399 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6400
6401 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006402 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006403
6404 DISABLE_AUTO(p_port);
6405
6406 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6407 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6408
6409 SGRAM_ACCESS(p_port);
6410
6411 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6412
6413 WRW_HARPOON((p_port+hp_intstat),
6414 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6415
6416 WR_HARPOON(p_port+hp_page_ctrl,
6417 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6418
James Bottomley 47b5d692005-04-24 02:38:05 -05006419 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006420 }
6421
6422 else {
6423
6424 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6425 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6426 {
6427 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6428 ACCEPT_MSG(p_port);
6429 }
6430 }
6431
6432 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6433
6434 WR_HARPOON(p_port+hp_page_ctrl,
6435 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6436
James Bottomley 47b5d692005-04-24 02:38:05 -05006437 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006438 }
6439}
6440
Linus Torvalds1da177e2005-04-16 15:20:36 -07006441/*---------------------------------------------------------------------
6442 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006443 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006444 *
6445 * Description: Wait to be selected by another SCAM initiator.
6446 *
6447 *---------------------------------------------------------------------*/
6448
James Bottomley 47b5d692005-04-24 02:38:05 -05006449static void FPT_scwtsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006450{
6451 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6452}
6453
6454
6455/*---------------------------------------------------------------------
6456 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006457 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458 *
6459 * Description: Setup the data Structure with the info from the EEPROM.
6460 *
6461 *---------------------------------------------------------------------*/
6462
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006463static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006464{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006465 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006466 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467 PNVRamInfo pCurrNvRam;
6468
James Bottomley 47b5d692005-04-24 02:38:05 -05006469 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470
6471 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6472 max_id = 0x08;
6473
6474 else
6475 max_id = 0x10;
6476
6477 if(pCurrNvRam){
6478 for(i = 0; i < max_id; i++){
6479
6480 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006481 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006482 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006483 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006484
James Bottomley 47b5d692005-04-24 02:38:05 -05006485 if(FPT_scamInfo[i].id_string[0] == 0x00)
6486 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006488 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489
6490 }
6491 }else {
6492 for (i=0; i < max_id; i++)
6493 {
6494 for (k=0; k < ID_STRING_LENGTH; k+=2)
6495 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006496 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6497 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006498 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006500 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 }
6502
James Bottomley 47b5d692005-04-24 02:38:05 -05006503 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6504 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505
James Bottomley 47b5d692005-04-24 02:38:05 -05006506 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006507
6508 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006509 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510
6511 }
6512 }
6513 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006514 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006515
6516}
6517
6518/*---------------------------------------------------------------------
6519 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006520 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006521 *
6522 * Description: Match the Device ID string with our values stored in
6523 * the EEPROM.
6524 *
6525 *---------------------------------------------------------------------*/
6526
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006527static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528{
6529
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006530 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006531
6532
6533 for (i=0; i < MAX_SCSI_TAR; i++) {
6534
James Bottomley 47b5d692005-04-24 02:38:05 -05006535 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536
6537 for (k=0; k < ID_STRING_LENGTH; k++)
6538 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006539 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6540 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006541 }
6542
6543 if (match)
6544 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006545 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006546 return(i);
6547 }
6548
Linus Torvalds1da177e2005-04-16 15:20:36 -07006549 }
6550
6551
6552
6553 if (p_id_string[0] & BIT(5))
6554 i = 8;
6555 else
6556 i = MAX_SCSI_TAR;
6557
6558 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006559 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 else
6561 match = 7;
6562
6563 while (i > 0)
6564 {
6565 i--;
6566
James Bottomley 47b5d692005-04-24 02:38:05 -05006567 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568 {
6569 for (k=0; k < ID_STRING_LENGTH; k++)
6570 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006571 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006572 }
6573
James Bottomley 47b5d692005-04-24 02:38:05 -05006574 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006575
James Bottomley 47b5d692005-04-24 02:38:05 -05006576 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6577 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578 return(match);
6579
6580 }
6581
6582
6583 match--;
6584
6585 if (match == 0xFF)
6586 {
6587 if (p_id_string[0] & BIT(5))
6588 match = 7;
6589 else
6590 match = MAX_SCSI_TAR-1;
6591 }
6592 }
6593
6594
6595
6596 if (p_id_string[0] & BIT(7))
6597 {
6598 return(CLR_PRIORITY);
6599 }
6600
6601
6602 if (p_id_string[0] & BIT(5))
6603 i = 8;
6604 else
6605 i = MAX_SCSI_TAR;
6606
6607 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006608 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006609 else
6610 match = 7;
6611
6612 while (i > 0)
6613 {
6614
6615 i--;
6616
James Bottomley 47b5d692005-04-24 02:38:05 -05006617 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006618 {
6619 for (k=0; k < ID_STRING_LENGTH; k++)
6620 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006621 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006622 }
6623
James Bottomley 47b5d692005-04-24 02:38:05 -05006624 FPT_scamInfo[match].id_string[0] |= BIT(7);
6625 FPT_scamInfo[match].state = ID_ASSIGNED;
6626 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6627 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006628 return(match);
6629
6630 }
6631
6632
6633 match--;
6634
6635 if (match == 0xFF)
6636 {
6637 if (p_id_string[0] & BIT(5))
6638 match = 7;
6639 else
6640 match = MAX_SCSI_TAR-1;
6641 }
6642 }
6643
6644 return(NO_ID_AVAIL);
6645}
6646
6647
6648/*---------------------------------------------------------------------
6649 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006650 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006651 *
6652 * Description: Save off the device SCAM ID strings.
6653 *
6654 *---------------------------------------------------------------------*/
6655
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006656static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006657{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006658 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006659 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006660
6661
6662 sum_data = 0x0000;
6663
6664 for (i = 1; i < EE_SCAMBASE/2; i++)
6665 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006666 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006667 }
6668
6669
James Bottomley 47b5d692005-04-24 02:38:05 -05006670 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006671
6672 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6673 max_id = 0x08;
6674
6675 else
6676 max_id = 0x10;
6677
6678 for (i=0; i < max_id; i++)
6679 {
6680
6681 for (k=0; k < ID_STRING_LENGTH; k+=2)
6682 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006683 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006685 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006687 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6688 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006689 }
6690 }
6691
6692
James Bottomley 47b5d692005-04-24 02:38:05 -05006693 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6694 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006695}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006696
6697/*---------------------------------------------------------------------
6698 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006699 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006700 *
6701 * Description: Setup the Xbow for normal operation.
6702 *
6703 *---------------------------------------------------------------------*/
6704
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006705static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006706{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006707unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006708
6709 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006710 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006711
6712 WR_HARPOON(port+hp_scsireset,0x00);
6713 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6714
6715 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6716 FIFO_CLR));
6717
6718 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6719
6720 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6721
6722 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6723 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6724
6725 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6726
James Bottomley 47b5d692005-04-24 02:38:05 -05006727 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006728 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6729
6730 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006731 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732
James Bottomley 47b5d692005-04-24 02:38:05 -05006733 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006734
6735 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6736
6737 /* Turn on SCSI_MODE8 for narrow cards to fix the
6738 strapping issue with the DUAL CHANNEL card */
6739 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6740 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6741
Linus Torvalds1da177e2005-04-16 15:20:36 -07006742 WR_HARPOON(port+hp_page_ctrl, i);
6743
6744}
6745
6746
6747/*---------------------------------------------------------------------
6748 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006749 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006750 *
6751 * Description: Initialize the BusMaster for normal operations.
6752 *
6753 *---------------------------------------------------------------------*/
6754
James Bottomley 47b5d692005-04-24 02:38:05 -05006755static void FPT_BusMasterInit(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006756{
6757
6758
6759 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6760 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6761
6762 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6763
6764
6765 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6766
6767 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6768
6769
Linus Torvalds1da177e2005-04-16 15:20:36 -07006770 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6771 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6772 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6773 ~SCATTER_EN));
6774}
6775
6776
6777/*---------------------------------------------------------------------
6778 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006779 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006780 *
6781 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6782 * necessary.
6783 *
6784 *---------------------------------------------------------------------*/
6785
James Bottomley 47b5d692005-04-24 02:38:05 -05006786static void FPT_DiagEEPROM(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006788 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789
6790 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6791 max_wd_cnt = EEPROM_WD_CNT;
6792 else
6793 max_wd_cnt = EEPROM_WD_CNT * 2;
6794
James Bottomley 47b5d692005-04-24 02:38:05 -05006795 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796
6797 if (temp == 0x4641) {
6798
6799 for (index = 2; index < max_wd_cnt; index++) {
6800
James Bottomley 47b5d692005-04-24 02:38:05 -05006801 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006802
6803 }
6804
James Bottomley 47b5d692005-04-24 02:38:05 -05006805 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806
6807 return; /*EEPROM is Okay so return now! */
6808 }
6809 }
6810
6811
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006812 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813
6814 for (index = 0; index < max_wd_cnt; index++) {
6815
James Bottomley 47b5d692005-04-24 02:38:05 -05006816 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817 }
6818
6819 temp = 0;
6820
James Bottomley 47b5d692005-04-24 02:38:05 -05006821 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006823 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006825 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006827 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006829 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006833 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006835 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 temp += 0x0007;
6837
James Bottomley 47b5d692005-04-24 02:38:05 -05006838 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006840 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/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, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843 temp += 0x0000;
6844
James Bottomley 47b5d692005-04-24 02:38:05 -05006845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/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_TBL45/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_TBL67/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_TBL89/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_TBLab/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_TBLcd/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_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860 temp += 0x4242;
6861
6862
James Bottomley 47b5d692005-04-24 02:38:05 -05006863 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006864 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006866 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006867 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006868 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006869 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006871 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006873 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006875 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006877 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006878 temp += 0x2020;
6879
6880 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006881 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006882 temp += (0x0700+TYPE_CODE0);
6883 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006884 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 temp += 0x5542; /* BUSLOGIC */
6886 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006887 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006888 temp += 0x4C53;
6889 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006890 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 temp += 0x474F;
6892 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006893 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006894 temp += 0x4349;
6895 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006896 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006897 temp += 0x5442; /* BT- 930 */
6898 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006899 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900 temp += 0x202D;
6901 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006902 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006903 temp += 0x3339;
6904 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006905 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006906 temp += 0x2030;
6907 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006908 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909 temp += 0x5453;
6910 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006911 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912 temp += 0x5645;
6913 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006914 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006915 temp += 0x2045;
6916 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006917 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006918 temp += 0x202F;
6919 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006920 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006921 temp += 0x4F4A;
6922 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006923 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924 temp += 0x204E;
6925 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006926 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006927 temp += 0x3539;
6928
6929
6930
James Bottomley 47b5d692005-04-24 02:38:05 -05006931 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006932
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006933 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934
6935}
6936
Linus Torvalds1da177e2005-04-16 15:20:36 -07006937
6938/*---------------------------------------------------------------------
6939 *
6940 * Function: Queue Search Select
6941 *
6942 * Description: Try to find a new command to execute.
6943 *
6944 *---------------------------------------------------------------------*/
6945
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006946static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006947{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006948 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006949 PSCCBMgr_tar_info currTar_Info;
6950 PSCCB pOldSccb;
6951
6952 scan_ptr = pCurrCard->scanIndex;
6953 do
6954 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006955 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006956 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6957 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6958 {
6959 if (currTar_Info->TarSelQ_Cnt != 0)
6960 {
6961
6962 scan_ptr++;
6963 if (scan_ptr == MAX_SCSI_TAR)
6964 scan_ptr = 0;
6965
6966 for(lun=0; lun < MAX_LUN; lun++)
6967 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006968 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006969 {
6970
6971 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6972 pOldSccb = NULL;
6973
6974 while((pCurrCard->currentSCCB != NULL) &&
6975 (lun != pCurrCard->currentSCCB->Lun))
6976 {
6977 pOldSccb = pCurrCard->currentSCCB;
6978 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6979 Sccb_forwardlink;
6980 }
6981 if(pCurrCard->currentSCCB == NULL)
6982 continue;
6983 if(pOldSccb != NULL)
6984 {
6985 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6986 Sccb_forwardlink;
6987 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6988 Sccb_backlink;
6989 currTar_Info->TarSelQ_Cnt--;
6990 }
6991 else
6992 {
6993 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6994
6995 if (currTar_Info->TarSelQ_Head == NULL)
6996 {
6997 currTar_Info->TarSelQ_Tail = NULL;
6998 currTar_Info->TarSelQ_Cnt = 0;
6999 }
7000 else
7001 {
7002 currTar_Info->TarSelQ_Cnt--;
7003 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7004 }
7005 }
7006 pCurrCard->scanIndex = scan_ptr;
7007
7008 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7009
7010 break;
7011 }
7012 }
7013 }
7014
7015 else
7016 {
7017 scan_ptr++;
7018 if (scan_ptr == MAX_SCSI_TAR) {
7019 scan_ptr = 0;
7020 }
7021 }
7022
7023 }
7024 else
7025 {
7026 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007027 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007028 {
7029
7030 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7031
7032 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7033
7034 if (currTar_Info->TarSelQ_Head == NULL)
7035 {
7036 currTar_Info->TarSelQ_Tail = NULL;
7037 currTar_Info->TarSelQ_Cnt = 0;
7038 }
7039 else
7040 {
7041 currTar_Info->TarSelQ_Cnt--;
7042 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7043 }
7044
7045 scan_ptr++;
7046 if (scan_ptr == MAX_SCSI_TAR)
7047 scan_ptr = 0;
7048
7049 pCurrCard->scanIndex = scan_ptr;
7050
7051 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7052
7053 break;
7054 }
7055
7056 else
7057 {
7058 scan_ptr++;
7059 if (scan_ptr == MAX_SCSI_TAR)
7060 {
7061 scan_ptr = 0;
7062 }
7063 }
7064 }
7065 } while (scan_ptr != pCurrCard->scanIndex);
7066}
7067
7068
7069/*---------------------------------------------------------------------
7070 *
7071 * Function: Queue Select Fail
7072 *
7073 * Description: Add the current SCCB to the head of the Queue.
7074 *
7075 *---------------------------------------------------------------------*/
7076
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007077static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007078{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007079 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007080 PSCCBMgr_tar_info currTar_Info;
7081
7082 if (pCurrCard->currentSCCB != NULL)
7083 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007084 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007085 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007086
7087 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7088
7089 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7090
7091 if (currTar_Info->TarSelQ_Cnt == 0)
7092 {
7093 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7094 }
7095
7096 else
7097 {
7098 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7099 }
7100
7101
7102 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7103
7104 pCurrCard->currentSCCB = NULL;
7105 currTar_Info->TarSelQ_Cnt++;
7106 }
7107}
7108/*---------------------------------------------------------------------
7109 *
7110 * Function: Queue Command Complete
7111 *
7112 * Description: Call the callback function with the current SCCB.
7113 *
7114 *---------------------------------------------------------------------*/
7115
James Bottomley 47b5d692005-04-24 02:38:05 -05007116static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007117 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007118{
7119
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007120 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007121 CALL_BK_FN callback;
7122 PSCCBMgr_tar_info currTar_Info;
7123
7124 SCSIcmd = p_sccb->Cdb[0];
7125
7126
7127 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7128
7129 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7130 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7131 (p_sccb->TargetStatus != SSCHECK))
7132
7133 if ((SCSIcmd == SCSI_READ) ||
7134 (SCSIcmd == SCSI_WRITE) ||
7135 (SCSIcmd == SCSI_READ_EXTENDED) ||
7136 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7137 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7138 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7139 (pCurrCard->globalFlags & F_NO_FILTER)
7140 )
7141 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7142 }
7143
7144
7145 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7146 {
7147 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7148 p_sccb->SccbStatus = SCCB_ERROR;
7149 else
7150 p_sccb->SccbStatus = SCCB_SUCCESS;
7151 }
7152
7153 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7154
7155 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7156 for (i=0; i < 6; i++) {
7157 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7158 }
7159 }
7160
7161 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7162 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7163
James Bottomley 47b5d692005-04-24 02:38:05 -05007164 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007165 }
7166
7167 pCurrCard->cmdCounter--;
7168 if (!pCurrCard->cmdCounter) {
7169
7170 if (pCurrCard->globalFlags & F_GREEN_PC) {
7171 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7172 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7173 }
7174
7175 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7176 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7177
7178 }
7179
7180 if(pCurrCard->discQCount != 0)
7181 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007182 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007183 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7184 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7185 {
7186 pCurrCard->discQCount--;
7187 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7188 }
7189 else
7190 {
7191 if(p_sccb->Sccb_tag)
7192 {
7193 pCurrCard->discQCount--;
7194 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7195 }else
7196 {
7197 pCurrCard->discQCount--;
7198 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7199 }
7200 }
7201
7202 }
7203
7204 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7205 callback(p_sccb);
7206 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7207 pCurrCard->currentSCCB = NULL;
7208}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007209
7210
7211/*---------------------------------------------------------------------
7212 *
7213 * Function: Queue Disconnect
7214 *
7215 * Description: Add SCCB to our disconnect array.
7216 *
7217 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007218static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007219{
7220 PSCCBMgr_tar_info currTar_Info;
7221
James Bottomley 47b5d692005-04-24 02:38:05 -05007222 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007223
James Bottomley 47b5d692005-04-24 02:38:05 -05007224 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007225 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7226 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007227 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007228 }
7229 else
7230 {
7231 if (p_sccb->Sccb_tag)
7232 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007233 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7234 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7235 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007236 }else
7237 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007238 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007239 }
7240 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007241 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007242}
7243
7244
7245/*---------------------------------------------------------------------
7246 *
7247 * Function: Queue Flush SCCB
7248 *
7249 * Description: Flush all SCCB's back to the host driver for this target.
7250 *
7251 *---------------------------------------------------------------------*/
7252
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007253static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007254{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007255 unsigned char qtag,thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007256 PSCCB currSCCB;
7257 PSCCBMgr_tar_info currTar_Info;
7258
James Bottomley 47b5d692005-04-24 02:38:05 -05007259 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007260 if(currSCCB != NULL)
7261 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007262 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007263 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007264
7265 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7266
James Bottomley 47b5d692005-04-24 02:38:05 -05007267 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7268 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007269 {
7270
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007271 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007272
James Bottomley 47b5d692005-04-24 02:38:05 -05007273 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007274
James Bottomley 47b5d692005-04-24 02:38:05 -05007275 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007276 currTar_Info->TarTagQ_Cnt--;
7277
7278 }
7279 }
7280 }
7281
7282}
7283
7284/*---------------------------------------------------------------------
7285 *
7286 * Function: Queue Flush Target SCCB
7287 *
7288 * Description: Flush all SCCB's back to the host driver for this target.
7289 *
7290 *---------------------------------------------------------------------*/
7291
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007292static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7293 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007294{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007295 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296 PSCCBMgr_tar_info currTar_Info;
7297
James Bottomley 47b5d692005-04-24 02:38:05 -05007298 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299
7300 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7301
James Bottomley 47b5d692005-04-24 02:38:05 -05007302 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7303 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007304 {
7305
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007306 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007307
James Bottomley 47b5d692005-04-24 02:38:05 -05007308 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007309
James Bottomley 47b5d692005-04-24 02:38:05 -05007310 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007311 currTar_Info->TarTagQ_Cnt--;
7312
7313 }
7314 }
7315
7316}
7317
7318
7319
7320
7321
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007322static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007323{
7324 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007325 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007326
7327 p_SCCB->Sccb_forwardlink = NULL;
7328
7329 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7330
7331 if (currTar_Info->TarSelQ_Cnt == 0) {
7332
7333 currTar_Info->TarSelQ_Head = p_SCCB;
7334 }
7335
7336 else {
7337
7338 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7339 }
7340
7341
7342 currTar_Info->TarSelQ_Tail = p_SCCB;
7343 currTar_Info->TarSelQ_Cnt++;
7344}
7345
7346
7347/*---------------------------------------------------------------------
7348 *
7349 * Function: Queue Find SCCB
7350 *
7351 * Description: Search the target select Queue for this SCCB, and
7352 * remove it if found.
7353 *
7354 *---------------------------------------------------------------------*/
7355
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007356static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007357{
7358 PSCCB q_ptr;
7359 PSCCBMgr_tar_info currTar_Info;
7360
James Bottomley 47b5d692005-04-24 02:38:05 -05007361 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007362
7363 q_ptr = currTar_Info->TarSelQ_Head;
7364
7365 while(q_ptr != NULL) {
7366
7367 if (q_ptr == p_SCCB) {
7368
7369
7370 if (currTar_Info->TarSelQ_Head == q_ptr) {
7371
7372 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7373 }
7374
7375 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7376
7377 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7378 }
7379
7380 if (q_ptr->Sccb_forwardlink != NULL) {
7381 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7382 }
7383
7384 if (q_ptr->Sccb_backlink != NULL) {
7385 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7386 }
7387
7388 currTar_Info->TarSelQ_Cnt--;
7389
James Bottomley 47b5d692005-04-24 02:38:05 -05007390 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007391 }
7392
7393 else {
7394 q_ptr = q_ptr->Sccb_forwardlink;
7395 }
7396 }
7397
7398
James Bottomley 47b5d692005-04-24 02:38:05 -05007399 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007400
7401}
7402
7403
7404/*---------------------------------------------------------------------
7405 *
7406 * Function: Utility Update Residual Count
7407 *
7408 * Description: Update the XferCnt to the remaining byte count.
7409 * If we transferred all the data then just write zero.
7410 * If Non-SG transfer then report Total Cnt - Actual Transfer
7411 * Cnt. For SG transfers add the count fields of all
7412 * remaining SG elements, as well as any partial remaining
7413 * element.
7414 *
7415 *---------------------------------------------------------------------*/
7416
James Bottomley 47b5d692005-04-24 02:38:05 -05007417static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007418{
7419 ULONG partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007420 unsigned int sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007421 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007422
7423 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7424
7425 p_SCCB->DataLength = 0x0000;
7426 }
7427
7428 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7429
7430 partial_cnt = 0x0000;
7431
7432 sg_index = p_SCCB->Sccb_sgseg;
7433
Linus Torvalds1da177e2005-04-16 15:20:36 -07007434 sg_ptr = (ULONG *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007435
7436 if (p_SCCB->Sccb_SGoffset) {
7437
7438 partial_cnt = p_SCCB->Sccb_SGoffset;
7439 sg_index++;
7440 }
7441
7442 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7443 p_SCCB->DataLength ) {
7444
7445 partial_cnt += *(sg_ptr+(sg_index * 2));
7446 sg_index++;
7447 }
7448
7449 p_SCCB->DataLength = partial_cnt;
7450 }
7451
7452 else {
7453
7454 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7455 }
7456}
7457
7458
7459/*---------------------------------------------------------------------
7460 *
7461 * Function: Wait 1 Second
7462 *
7463 * Description: Wait for 1 second.
7464 *
7465 *---------------------------------------------------------------------*/
7466
James Bottomley 47b5d692005-04-24 02:38:05 -05007467static void FPT_Wait1Second(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007468{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007469 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007470
7471 for(i=0; i < 4; i++) {
7472
James Bottomley 47b5d692005-04-24 02:38:05 -05007473 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007474
7475 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7476 break;
7477
7478 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7479 break;
7480 }
7481}
7482
7483
7484/*---------------------------------------------------------------------
7485 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007486 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007487 *
7488 * Description: Wait the desired delay.
7489 *
7490 *---------------------------------------------------------------------*/
7491
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007492static void FPT_Wait(ULONG p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007493{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007494 unsigned char old_timer;
7495 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007496
7497 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7498
7499 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7500 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7501
7502 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7503 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007504 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007505
7506
7507 WR_HARPOON(p_port+hp_portctrl_0,
7508 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7509
7510 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7511
7512 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7513 break;
7514
7515 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7516 break;
7517 }
7518
7519 WR_HARPOON(p_port+hp_portctrl_0,
7520 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7521
7522 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007523 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007524
7525 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7526
7527 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7528}
7529
7530
7531/*---------------------------------------------------------------------
7532 *
7533 * Function: Enable/Disable Write to EEPROM
7534 *
7535 * Description: The EEPROM must first be enabled for writes
7536 * A total of 9 clocks are needed.
7537 *
7538 *---------------------------------------------------------------------*/
7539
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007540static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007541{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007542 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007543
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007544 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 -07007545
7546 if (p_mode)
7547
James Bottomley 47b5d692005-04-24 02:38:05 -05007548 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007549
7550 else
7551
7552
James Bottomley 47b5d692005-04-24 02:38:05 -05007553 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007554
7555 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7556 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7557}
7558
7559
7560/*---------------------------------------------------------------------
7561 *
7562 * Function: Write EEPROM
7563 *
7564 * Description: Write a word to the EEPROM at the specified
7565 * address.
7566 *
7567 *---------------------------------------------------------------------*/
7568
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007569static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007570{
7571
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007572 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007573 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007574
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007575 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 -07007576 (SEE_MS | SEE_CS));
7577
7578
7579
James Bottomley 47b5d692005-04-24 02:38:05 -05007580 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007581
7582
7583 ee_value |= (SEE_MS + SEE_CS);
7584
7585 for(i = 0x8000; i != 0; i>>=1) {
7586
7587 if (i & ee_data)
7588 ee_value |= SEE_DO;
7589 else
7590 ee_value &= ~SEE_DO;
7591
7592 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 ee_value |= SEE_CLK; /* Clock data! */
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 ee_value &= ~SEE_CLK;
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 }
7601 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7602 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7603
James Bottomley 47b5d692005-04-24 02:38:05 -05007604 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007605
7606 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7607 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7608 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7609}
7610
7611/*---------------------------------------------------------------------
7612 *
7613 * Function: Read EEPROM
7614 *
7615 * Description: Read a word from the EEPROM at the desired
7616 * address.
7617 *
7618 *---------------------------------------------------------------------*/
7619
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007620static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007621{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007622 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007623
7624 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007625 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007626 do
7627 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007628 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007629
7630 if(ee_data1 == ee_data2)
7631 return(ee_data1);
7632
7633 ee_data1 = ee_data2;
7634 i++;
7635
7636 }while(i < 4);
7637
7638 return(ee_data1);
7639}
7640
7641/*---------------------------------------------------------------------
7642 *
7643 * Function: Read EEPROM Original
7644 *
7645 * Description: Read a word from the EEPROM at the desired
7646 * address.
7647 *
7648 *---------------------------------------------------------------------*/
7649
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007650static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007651{
7652
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007653 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007654 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007655
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007656 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 -07007657 (SEE_MS | SEE_CS));
7658
7659
James Bottomley 47b5d692005-04-24 02:38:05 -05007660 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007661
7662
7663 ee_value |= (SEE_MS + SEE_CS);
7664 ee_data = 0;
7665
7666 for(i = 1; i <= 16; i++) {
7667
7668 ee_value |= SEE_CLK; /* Clock data! */
7669 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 ee_value &= ~SEE_CLK;
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674
7675 ee_data <<= 1;
7676
7677 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7678 ee_data |= 1;
7679 }
7680
7681 ee_value &= ~(SEE_MS + SEE_CS);
7682 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7683 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7684
7685 return(ee_data);
7686}
7687
7688
7689/*---------------------------------------------------------------------
7690 *
7691 * Function: Send EE command and Address to the EEPROM
7692 *
7693 * Description: Transfers the correct command and sends the address
7694 * to the eeprom.
7695 *
7696 *---------------------------------------------------------------------*/
7697
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007698static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007699{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007700 unsigned char ee_value;
7701 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007702
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007703 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007704
7705
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007706 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007707
7708
7709 ee_value = SEE_MS;
7710 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7711
7712 ee_value |= SEE_CS; /* Set CS to EEPROM */
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714
7715
7716 for(i = 0x04; i != 0; i>>=1) {
7717
7718 if (i & ee_cmd)
7719 ee_value |= SEE_DO;
7720 else
7721 ee_value &= ~SEE_DO;
7722
7723 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 ee_value |= SEE_CLK; /* Clock data! */
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 ee_value &= ~SEE_CLK;
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 }
7732
7733
7734 if (narrow_flg)
7735 i = 0x0080;
7736
7737 else
7738 i = 0x0200;
7739
7740
7741 while (i != 0) {
7742
7743 if (i & ee_addr)
7744 ee_value |= SEE_DO;
7745 else
7746 ee_value &= ~SEE_DO;
7747
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 ee_value |= SEE_CLK; /* Clock data! */
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 ee_value &= ~SEE_CLK;
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756
7757 i >>= 1;
7758 }
7759}
7760
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007761static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007762{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007763 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007764 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007765 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007766 for (i=0; i < ID_STRING_LENGTH; i++)
7767 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007768 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007769 for(j=0; j < 8; j++)
7770 {
7771 if ((crc ^ ch) & 1)
7772 crc = (crc >> 1) ^ CRCMASK;
7773 else
7774 crc >>= 1;
7775 ch >>= 1;
7776 }
7777 }
7778 return(crc);
7779}
7780
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007781static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007782{
7783 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007784 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007785 lrc = 0;
7786 for(i = 0; i < ID_STRING_LENGTH; i++)
7787 lrc ^= buffer[i];
7788 return(lrc);
7789}
7790
7791
7792
7793/*
7794 The following inline definitions avoid type conflicts.
7795*/
7796
7797static inline unsigned char
7798FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7799{
7800 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7801}
7802
7803
7804static inline FlashPoint_CardHandle_T
7805FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7806{
7807 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7808}
7809
7810static inline void
7811FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7812{
7813 FlashPoint_ReleaseHostAdapter(CardHandle);
7814}
7815
7816
7817static inline void
7818FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7819{
7820 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7821}
7822
7823
7824static inline void
7825FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7826{
7827 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7828}
7829
7830
7831static inline boolean
7832FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7833{
7834 return FlashPoint_InterruptPending(CardHandle);
7835}
7836
7837
7838static inline int
7839FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7840{
7841 return FlashPoint_HandleInterrupt(CardHandle);
7842}
7843
7844
7845#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7846#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7847#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7848#define FlashPoint_StartCCB FlashPoint__StartCCB
7849#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7850#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7851#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7852
7853
Linus Torvalds1da177e2005-04-16 15:20:36 -07007854#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7855
7856
7857/*
7858 Define prototypes for the FlashPoint SCCB Manager Functions.
7859*/
7860
7861extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7862extern FlashPoint_CardHandle_T
7863 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7864extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7865extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7866extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7867extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7868extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007869
7870
7871#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */