blob: 02af5fb73147180124bcf9745c246c4fc1639018 [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 int UINT;
44typedef unsigned long ULONG;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047typedef unsigned short * ushort_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#define s08bits char
51#define s16bits short
52#define s32bits long
53
54#define u08bits unsigned s08bits
55#define u16bits unsigned s16bits
56#define u32bits unsigned s32bits
57
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080060#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080061#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
63
64
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
James Bottomley 47b5d692005-04-24 02:38:05 -050066typedef struct _SCCB *PSCCB;
67typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068
69
70typedef struct SCCBMgr_info {
71 ULONG si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080072 unsigned char si_present;
73 unsigned char si_intvect;
74 unsigned char si_id;
75 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080076 unsigned short si_fw_revision;
77 unsigned short si_per_targ_init_sync;
78 unsigned short si_per_targ_fast_nego;
79 unsigned short si_per_targ_ultra_nego;
80 unsigned short si_per_targ_no_disc;
81 unsigned short si_per_targ_wide_nego;
82 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080083 unsigned char si_card_family;
84 unsigned char si_bustype;
85 unsigned char si_card_model[3];
86 unsigned char si_relative_cardnum;
87 unsigned char si_reserved[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 ULONG si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080089 unsigned char si_XlatInfo[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 ULONG si_reserved2[5];
91 ULONG si_secondary_range;
92} SCCBMGR_INFO;
93
James Bottomley 47b5d692005-04-24 02:38:05 -050094typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
96
James Bottomley 47b5d692005-04-24 02:38:05 -050097#define SCSI_PARITY_ENA 0x0001
98#define LOW_BYTE_TERM 0x0010
99#define HIGH_BYTE_TERM 0x0020
100#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
102#define SUPPORT_16TAR_32LUN 0x0002
103#define SOFT_RESET 0x0004
104#define EXTENDED_TRANSLATION 0x0008
105#define POST_ALL_UNDERRRUNS 0x0040
106#define FLAG_SCAM_ENABLED 0x0080
107#define FLAG_SCAM_LEVEL2 0x0100
108
109
110
111
112#define HARPOON_FAMILY 0x02
113
114
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Alexey Dobriyan323579882006-01-15 02:12:54 +0100116/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 * The UCB Manager treats the SCCB as it's 'native hardware structure'
118 */
119
120
121#pragma pack(1)
122typedef struct _SCCB {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800123 unsigned char OperationCode;
124 unsigned char ControlByte;
125 unsigned char CdbLength;
126 unsigned char RequestSenseLength;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 ULONG DataLength;
128 ULONG DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800129 unsigned char CcbRes[2];
130 unsigned char HostStatus;
131 unsigned char TargetStatus;
132 unsigned char TargID;
133 unsigned char Lun;
134 unsigned char Cdb[12];
135 unsigned char CcbRes1;
136 unsigned char Reserved1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 ULONG Reserved2;
138 ULONG SensePointer;
139
140
141 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
142 ULONG SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800143 unsigned char SccbStatus;
144 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800145 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
147
148 ULONG Sccb_XferCnt; /* actual transfer count */
149 ULONG Sccb_ATC;
150 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
151 ULONG Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800152 unsigned short Sccb_MGRFlags;
153 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800154 unsigned char Sccb_scsimsg; /* identify msg for selection */
155 unsigned char Sccb_tag;
156 unsigned char Sccb_scsistat;
157 unsigned char Sccb_idmsg; /* image of last msg in */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 PSCCB Sccb_forwardlink;
159 PSCCB Sccb_backlink;
160 ULONG Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800161 unsigned char Save_Cdb[6];
162 unsigned char Save_CdbLen;
163 unsigned char Sccb_XferState;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 ULONG Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 } SCCB;
166
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167
168#pragma pack()
169
170
171
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172#define SCATTER_GATHER_COMMAND 0x02
173#define RESIDUAL_COMMAND 0x03
174#define RESIDUAL_SG_COMMAND 0x04
175#define RESET_COMMAND 0x81
176
177
178#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
179#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180#define SCCB_DATA_XFER_OUT 0x10 /* Write */
181#define SCCB_DATA_XFER_IN 0x08 /* Read */
182
183
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
185
186
187#define BUS_FREE_ST 0
188#define SELECT_ST 1
189#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
190#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
191#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
192#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
193#define COMMAND_ST 6
194#define DATA_OUT_ST 7
195#define DATA_IN_ST 8
196#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
199
200#define F_HOST_XFER_DIR 0x01
201#define F_ALL_XFERRED 0x02
202#define F_SG_XFER 0x04
203#define F_AUTO_SENSE 0x08
204#define F_ODD_BALL_CNT 0x10
205#define F_NO_DATA_YET 0x80
206
207
208#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209#define F_DEV_SELECTED 0x04
210
211
212#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
213#define SCCB_DATA_UNDER_RUN 0x0C
214#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
215#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
217
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
219#define SCCB_BM_ERR 0x30 /* BusMaster error. */
220#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
221
222
223
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225
226#define SCCB_IN_PROCESS 0x00
227#define SCCB_SUCCESS 0x01
228#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
232
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233#define ORION_FW_REV 3110
234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
240
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
James Bottomley 47b5d692005-04-24 02:38:05 -0500242#define MAX_SCSI_TAR 16
243#define MAX_LUN 32
244#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
250
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -0800251#define RD_HARPOON(ioport) inb((u32bits)ioport)
252#define RDW_HARPOON(ioport) inw((u32bits)ioport)
253#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
254#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
255#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
256#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
258
259#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260#define SYNC_TRYING BIT(6)
261#define SYNC_SUPPORTED (BIT(7)+BIT(6))
262
263#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264#define WIDE_ENABLED BIT(4)
265#define WIDE_NEGOCIATED BIT(5)
266
267#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268#define TAG_Q_TRYING BIT(2)
269#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270
271#define TAR_ALLOW_DISC BIT(0)
272
273
274#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275#define EE_SYNC_5MB BIT(0)
276#define EE_SYNC_10MB BIT(1)
277#define EE_SYNC_20MB (BIT(0)+BIT(1))
278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279#define EE_WIDE_SCSI BIT(7)
280
281
James Bottomley 47b5d692005-04-24 02:38:05 -0500282typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283
284
285typedef struct SCCBMgr_tar_info {
286
287 PSCCB TarSelQ_Head;
288 PSCCB TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800289 unsigned char TarLUN_CA; /*Contingent Allgiance */
290 unsigned char TarTagQ_Cnt;
291 unsigned char TarSelQ_Cnt;
292 unsigned char TarStatus;
293 unsigned char TarEEValue;
294 unsigned char TarSyncCtrl;
295 unsigned char TarReserved[2]; /* for alignment */
296 unsigned char LunDiscQ_Idx[MAX_LUN];
297 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298} SCCBMGR_TAR_INFO;
299
300typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800301 unsigned char niModel; /* Model No. of card */
302 unsigned char niCardNo; /* Card no. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 ULONG niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800304 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
305 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
306 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
307 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
308 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
309 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310}NVRAMINFO;
311
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
314#define MODEL_LT 1
315#define MODEL_DL 2
316#define MODEL_LW 3
317#define MODEL_DW 4
318
319
320typedef struct SCCBcard {
321 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 ULONG ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800326 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800327 unsigned char discQCount;
328 unsigned char tagQ_Lst;
329 unsigned char cardIndex;
330 unsigned char scanIndex;
331 unsigned char globalFlags;
332 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 PNVRamInfo pNvRamInfo;
334 PSCCB discQ_Tbl[QUEUE_DEPTH];
335
336}SCCBCARD;
337
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339
340
341#define F_TAG_STARTED 0x01
342#define F_CONLUN_IO 0x02
343#define F_DO_RENEGO 0x04
344#define F_NO_FILTER 0x08
345#define F_GREEN_PC 0x10
346#define F_HOST_XFER_ACT 0x20
347#define F_NEW_SCCB_CMD 0x40
348#define F_UPDATE_EEPROM 0x80
349
350
351#define ID_STRING_LENGTH 32
352#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
353
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
356
357#define ASSIGN_ID 0x00
358#define SET_P_FLAG 0x01
359#define CFG_CMPLT 0x03
360#define DOM_MSTR 0x0F
361#define SYNC_PTRN 0x1F
362
363#define ID_0_7 0x18
364#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365#define MISC_CODE 0x14
366#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
369
370#define INIT_SELTD 0x01
371#define LEVEL2_TAR 0x02
372
373
374enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
375 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
376 CLR_PRIORITY,NO_ID_AVAIL };
377
378typedef struct SCCBscam_info {
379
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800380 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 enum scam_id_st state;
382
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800383} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387#define SCSI_READ 0x08
388#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390#define SCSI_READ_EXTENDED 0x28
391#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
394
395
396#define SSGOOD 0x00
397#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398#define SSQ_FULL 0x28
399
400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
402
403#define SMCMD_COMP 0x00
404#define SMEXT 0x01
405#define SMSAVE_DATA_PTR 0x02
406#define SMREST_DATA_PTR 0x03
407#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408#define SMABORT 0x06
409#define SMREJECT 0x07
410#define SMNO_OP 0x08
411#define SMPARITY 0x09
412#define SMDEV_RESET 0x0C
413#define SMABORT_TAG 0x0D
414#define SMINIT_RECOVERY 0x0F
415#define SMREL_RECOVERY 0x10
416
417#define SMIDENT 0x80
418#define DISC_PRIV 0x40
419
420
421#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422#define SMWDTR 0x03
423#define SM8BIT 0x00
424#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425#define SMIGNORWR 0x23 /* Ignore Wide Residue */
426
427
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429
430
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431
432
433
434#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435#define TWELVE_BYTE_CMD 0x0C
436
437#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
439
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440
441#define EEPROM_WD_CNT 256
442
443#define EEPROM_CHECK_SUM 0
444#define FW_SIGNATURE 2
445#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448#define SYSTEM_CONFIG 16
449#define SCSI_CONFIG 17
450#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451#define SCAM_CONFIG 20
452#define ADAPTER_SCSI_ID 24
453
454
455#define IGNORE_B_SCAN 32
456#define SEND_START_ENA 34
457#define DEVICE_ENABLE 36
458
459#define SYNC_RATE_TBL 38
460#define SYNC_RATE_TBL01 38
461#define SYNC_RATE_TBL23 40
462#define SYNC_RATE_TBL45 42
463#define SYNC_RATE_TBL67 44
464#define SYNC_RATE_TBL89 46
465#define SYNC_RATE_TBLab 48
466#define SYNC_RATE_TBLcd 50
467#define SYNC_RATE_TBLef 52
468
469
470
471#define EE_SCAMBASE 256
472
473
474
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 #define SCAM_ENABLED BIT(2)
476 #define SCAM_LEVEL2 BIT(3)
477
478
479 #define RENEGO_ENA BITW(10)
480 #define CONNIO_ENA BITW(11)
481 #define GREEN_PC_ENA BITW(12)
482
483
484 #define AUTO_RATE_00 00
485 #define AUTO_RATE_05 01
486 #define AUTO_RATE_10 02
487 #define AUTO_RATE_20 03
488
489 #define WIDE_NEGO_BIT BIT(7)
490 #define DISC_ENABLE_BIT BIT(6)
491
492
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
494 #define hp_vendor_id_0 0x00 /* LSB */
495 #define ORION_VEND_0 0x4B
496
497 #define hp_vendor_id_1 0x01 /* MSB */
498 #define ORION_VEND_1 0x10
499
500 #define hp_device_id_0 0x02 /* LSB */
501 #define ORION_DEV_0 0x30
502
503 #define hp_device_id_1 0x03 /* MSB */
504 #define ORION_DEV_1 0x81
505
506 /* Sub Vendor ID and Sub Device ID only available in
507 Harpoon Version 2 and higher */
508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
511
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512
513 #define hp_semaphore 0x0C
514 #define SCCB_MGR_ACTIVE BIT(0)
515 #define TICKLE_ME BIT(1)
516 #define SCCB_MGR_PRESENT BIT(3)
517 #define BIOS_IN_USE BIT(4)
518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
521 #define hp_sys_ctrl 0x0F
522
523 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
524 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
525 #define HALT_MACH BIT(3) /*Halt State Machine */
526 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
528
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800532
533
534
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535
536 #define hp_host_blk_cnt 0x13
537
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
539
540 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
541
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
544 #define hp_int_mask 0x17
545
546 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
547 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549
550 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 #define hp_xfer_cnt_hi 0x1A
552 #define hp_xfer_cmd 0x1B
553
554 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
555 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
557
558 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
560 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
563
564 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
565 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
567 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 #define hp_ee_ctrl 0x22
571
572 #define EXT_ARB_ACK BIT(7)
573 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
574 #define SEE_MS BIT(5)
575 #define SEE_CS BIT(3)
576 #define SEE_CLK BIT(2)
577 #define SEE_DO BIT(1)
578 #define SEE_DI BIT(0)
579
580 #define EE_READ 0x06
581 #define EE_WRITE 0x05
582 #define EWEN 0x04
583 #define EWEN_ADDR 0x03C0
584 #define EWDS 0x04
585 #define EWDS_ADDR 0x0000
586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590
591
592
593 #define hp_bm_ctrl 0x26
594
595 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
596 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
598 #define FAST_SINGLE BIT(6) /*?? */
599
600 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
603 #define hp_sg_addr 0x28
604 #define hp_page_ctrl 0x29
605
606 #define SCATTER_EN BIT(0)
607 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
609 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 #define hp_pci_stat_cfg 0x2D
615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
625 #define hp_rev_num 0x33
626
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628 #define hp_stack_data 0x34
629 #define hp_stack_addr 0x35
630
631 #define hp_ext_status 0x36
632
633 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
634 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
635 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 #define CMD_ABORTED BIT(4) /*Command aborted */
637 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
638 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
639 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
640 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
641 BM_PARITY_ERR | PIO_OVERRUN)
642
643 #define hp_int_status 0x37
644
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
646 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648
649
650 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652
653
654
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 #define hp_intena 0x40
656
657 #define RESET BITW(7)
658 #define PROG_HLT BITW(6)
659 #define PARITY BITW(5)
660 #define FIFO BITW(4)
661 #define SEL BITW(3)
662 #define SCAM_SEL BITW(2)
663 #define RSEL BITW(1)
664 #define TIMEOUT BITW(0)
665 #define BUS_FREE BITW(15)
666 #define XFER_CNT_0 BITW(14)
667 #define PHASE BITW(13)
668 #define IUNKWN BITW(12)
669 #define ICMD_COMP BITW(11)
670 #define ITICKLE BITW(10)
671 #define IDO_STRT BITW(9)
672 #define ITAR_DISC BITW(8)
673 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
674 #define CLR_ALL_INT 0xFFFF
675 #define CLR_ALL_INT_1 0xFF00
676
677 #define hp_intstat 0x42
678
679 #define hp_scsisig 0x44
680
681 #define SCSI_SEL BIT(7)
682 #define SCSI_BSY BIT(6)
683 #define SCSI_REQ BIT(5)
684 #define SCSI_ACK BIT(4)
685 #define SCSI_ATN BIT(3)
686 #define SCSI_CD BIT(2)
687 #define SCSI_MSG BIT(1)
688 #define SCSI_IOBIT BIT(0)
689
690 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
693 #define S_DATAI_PH ( BIT(0))
694 #define S_DATAO_PH 0x00
695 #define S_ILL_PH ( BIT(1) )
696
697 #define hp_scsictrl_0 0x45
698
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 #define SEL_TAR BIT(6)
700 #define ENA_ATN BIT(4)
701 #define ENA_RESEL BIT(2)
702 #define SCSI_RST BIT(1)
703 #define ENA_SCAM_SEL BIT(0)
704
705
706
707 #define hp_portctrl_0 0x46
708
709 #define SCSI_PORT BIT(7)
710 #define SCSI_INBIT BIT(6)
711 #define DMA_PORT BIT(5)
712 #define DMA_RD BIT(4)
713 #define HOST_PORT BIT(3)
714 #define HOST_WRT BIT(2)
715 #define SCSI_BUS_EN BIT(1)
716 #define START_TO BIT(0)
717
718 #define hp_scsireset 0x47
719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 #define SCSI_INI BIT(6)
721 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 #define DMA_RESET BIT(3)
723 #define HPSCSI_RESET BIT(2)
724 #define PROG_RESET BIT(1)
725 #define FIFO_CLR BIT(0)
726
727 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
730 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 #define hp_addstat 0x4E
732
733 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 #define SCSI_MODE8 BIT(3)
735 #define SCSI_PAR_ERR BIT(0)
736
737 #define hp_prgmcnt_0 0x4F
738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739
740 #define hp_selfid_0 0x50
741 #define hp_selfid_1 0x51
742 #define hp_arb_id 0x52
743
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744
745 #define hp_select_id 0x53
746
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747
748 #define hp_synctarg_base 0x54
749 #define hp_synctarg_12 0x54
750 #define hp_synctarg_13 0x55
751 #define hp_synctarg_14 0x56
752 #define hp_synctarg_15 0x57
753
754 #define hp_synctarg_8 0x58
755 #define hp_synctarg_9 0x59
756 #define hp_synctarg_10 0x5A
757 #define hp_synctarg_11 0x5B
758
759 #define hp_synctarg_4 0x5C
760 #define hp_synctarg_5 0x5D
761 #define hp_synctarg_6 0x5E
762 #define hp_synctarg_7 0x5F
763
764 #define hp_synctarg_0 0x60
765 #define hp_synctarg_1 0x61
766 #define hp_synctarg_2 0x62
767 #define hp_synctarg_3 0x63
768
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 #define DEFAULT_OFFSET 0x0F
771
772 #define hp_autostart_0 0x64
773 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 #define hp_autostart_3 0x67
775
776
777
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 #define AUTO_IMMED BIT(5)
779 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
782 #define hp_gp_reg_0 0x68
783 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 #define hp_gp_reg_3 0x6B
785
786 #define hp_seltimeout 0x6C
787
788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 #define TO_4ms 0x67 /* 3.9959ms */
790
791 #define TO_5ms 0x03 /* 4.9152ms */
792 #define TO_10ms 0x07 /* 11.xxxms */
793 #define TO_250ms 0x99 /* 250.68ms */
794 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795
796 #define hp_clkctrl_0 0x6D
797
798 #define PWR_DWN BIT(6)
799 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
803
804 #define hp_fiforead 0x6E
805 #define hp_fifowrite 0x6F
806
807 #define hp_offsetctr 0x70
808 #define hp_xferstat 0x71
809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 #define hp_portctrl_1 0x72
813
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 #define CHK_SCSI_P BIT(3)
815 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816
817 #define hp_xfer_pad 0x73
818
819 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
821 #define hp_scsidata_0 0x74
822 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
826 #define hp_aramBase 0x80
827 #define BIOS_DATA_OFFSET 0x60
828 #define BIOS_RELATIVE_CARD 0x64
829
830
831
832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 #define AR3 (BITW(9) + BITW(8))
834 #define SDATA BITW(10)
835
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836
837 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
838
839 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
840
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
843 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
844
845 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
846
847
848 #define ADATA_OUT 0x00
849 #define ADATA_IN BITW(8)
850 #define ACOMMAND BITW(10)
851 #define ASTATUS (BITW(10)+BITW(8))
852 #define AMSG_OUT (BITW(10)+BITW(9))
853 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
855
856 #define BRH_OP BITW(13) /* Branch */
857
858
859 #define ALWAYS 0x00
860 #define EQUAL BITW(8)
861 #define NOT_EQ BITW(9)
862
863 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
864
865
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
868
869 #define MPM_OP BITW(15) /* Match phase and move data */
870
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
872 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
873
874
875 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
876
877
878 #define D_AR0 0x00
879 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
881
882
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
889
890 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
891
892 #define SSI_OP (BITW(15)+BITW(11))
893
894
895 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
896 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
898 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
899 #define SSI_ITICKLE (ITICKLE >> 8)
900
901 #define SSI_IUNKWN (IUNKWN >> 8)
902 #define SSI_INO_CC (IUNKWN >> 8)
903 #define SSI_IRFAIL (IUNKWN >> 8)
904
905
906 #define NP 0x10 /*Next Phase */
907 #define NTCMD 0x02 /*Non- Tagged Command start */
908 #define CMDPZ 0x04 /*Command phase */
909 #define DINT 0x12 /*Data Out/In interrupt */
910 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 #define DC 0x19 /*Disconnect Message */
912 #define ST 0x1D /*Status Phase */
913 #define UNKNWN 0x24 /*Unknown bus action */
914 #define CC 0x25 /*Command Completion failure */
915 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
917
918
919 #define ID_MSG_STRT hp_aramBase + 0x00
920 #define NON_TAG_ID_MSG hp_aramBase + 0x06
921 #define CMD_STRT hp_aramBase + 0x08
922 #define SYNC_MSGS hp_aramBase + 0x08
923
924
925
926
927
928 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 #define DISCONNECT_START 0x10/2
930 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 #define SELCHK_STRT SELCHK/2
933
934
935
936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
938
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800940
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941
942#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
943/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
944 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800945 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800947#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 -0700948 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800949 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800951 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 count >>= 16,\
953 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
955#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
956 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
957
958
959#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
960 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
961
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
964#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
965 WR_HARPOON(port+hp_scsireset, 0x00))
966
967#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
968 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
969
970#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
971 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
972
973#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
974 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
975
976#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
977 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
978
979
980
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800982static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
983static void FPT_ssel(ULONG port, unsigned char p_card);
984static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
985static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
986static void FPT_stsyncn(ULONG port, unsigned char p_card);
987static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
988static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500989 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800990static void FPT_sresb(ULONG port, unsigned char p_card);
991static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
992static void FPT_schkdd(ULONG port, unsigned char p_card);
993static unsigned char FPT_RdStack(ULONG port, unsigned char index);
994static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
995static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800997static void FPT_SendMsg(ULONG port, unsigned char message);
998static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
999 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001001static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001002static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001004static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1005static void FPT_stwidn(ULONG port, unsigned char p_card);
1006static void FPT_siwidr(ULONG port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001009static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1010static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001011static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001012 unsigned char p_card);
1013static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1014static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1015static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1016static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001017static void FPT_utilUpdateResidual(PSCCB p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001018static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001019static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
1021
James Bottomley 47b5d692005-04-24 02:38:05 -05001022static void FPT_Wait1Second(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001023static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1024static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001025static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr);
1026static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr);
1027static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr);
1028static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
1030
1031
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001032static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1033static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1034static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1035static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1036static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1037static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1038static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001040static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1041static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1042static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
1044
1045
1046
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001047static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
James Bottomley 47b5d692005-04-24 02:38:05 -05001048static void FPT_BusMasterInit(ULONG p_port);
1049static void FPT_DiagEEPROM(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051
1052
1053
James Bottomley 47b5d692005-04-24 02:38:05 -05001054static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1055static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1056static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001057static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
James Bottomley 47b5d692005-04-24 02:38:05 -05001058static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001061static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001062 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063
James Bottomley 47b5d692005-04-24 02:38:05 -05001064static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001065static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1066static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067
1068
1069
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001070static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001072static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
James Bottomley 47b5d692005-04-24 02:38:05 -05001073static void FPT_scbusf(ULONG p_port);
1074static void FPT_scsel(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001075static void FPT_scasid(unsigned char p_card, ULONG p_port);
1076static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1077static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1078static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1079static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1080static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1081static unsigned char FPT_scvalq(unsigned char p_quintet);
1082static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
James Bottomley 47b5d692005-04-24 02:38:05 -05001083static void FPT_scwtsel(ULONG p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001084static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1085static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1086static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
1088
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001089static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001090static void FPT_autoLoadDefaultMap(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
1092
1093
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
James Bottomley 47b5d692005-04-24 02:38:05 -05001095static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1096static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1097static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1098static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
1100
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001101static unsigned char FPT_mbCards = 0;
1102static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001103 ' ', 'B', 'T', '-', '9', '3', '0', \
1104 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1105 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001107static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
1109
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001110static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
1113/*---------------------------------------------------------------------
1114 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001115 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 *
1117 * Description: Setup and/or Search for cards and return info to caller.
1118 *
1119 *---------------------------------------------------------------------*/
1120
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001121static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001123 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001125 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001126 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 PNVRamInfo pCurrNvRam;
1129
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131
1132
1133 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1134 return((int)FAILURE);
1135
1136 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1137 return((int)FAILURE);
1138
1139 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1140 return((int)FAILURE);
1141
1142 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1143 return((int)FAILURE);
1144
1145
1146 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1147
1148/* For new Harpoon then check for sub_device ID LSB
1149 the bits(0-3) must be all ZERO for compatible with
1150 current version of SCCBMgr, else skip this Harpoon
1151 device. */
1152
1153 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1154 return((int)FAILURE);
1155 }
1156
1157 if (first_time)
1158 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001159 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001161 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 }
1163
James Bottomley 47b5d692005-04-24 02:38:05 -05001164 if(FPT_RdStack(ioport, 0) != 0x00) {
1165 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 {
1167 pCurrNvRam = NULL;
1168 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001169 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1170 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 }
1172 else
1173 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001174 if(FPT_mbCards < MAX_MB_CARDS) {
1175 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1176 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001178 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 }else
1180 return((int) FAILURE);
1181 }
1182 }else
1183 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1186 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1187
1188 if(pCurrNvRam)
1189 pCardInfo->si_id = pCurrNvRam->niAdapId;
1190 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001191 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1192 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
1194 pCardInfo->si_lun = 0x00;
1195 pCardInfo->si_fw_revision = ORION_FW_REV;
1196 temp2 = 0x0000;
1197 temp3 = 0x0000;
1198 temp4 = 0x0000;
1199 temp5 = 0x0000;
1200 temp6 = 0x0000;
1201
1202 for (id = 0; id < (16/2); id++) {
1203
1204 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001205 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1207 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1208 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001209 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 for (i = 0; i < 2; temp >>=8,i++) {
1212
1213 temp2 >>= 1;
1214 temp3 >>= 1;
1215 temp4 >>= 1;
1216 temp5 >>= 1;
1217 temp6 >>= 1;
1218 switch (temp & 0x3)
1219 {
1220 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1221 temp6 |= 0x8000; /* Fall through */
1222 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1223 temp5 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1225 temp2 |= 0x8000; /* Fall through */
1226 case AUTO_RATE_00: /* Asynchronous */
1227 break;
1228 }
1229
1230 if (temp & DISC_ENABLE_BIT)
1231 temp3 |= 0x8000;
1232
1233 if (temp & WIDE_NEGO_BIT)
1234 temp4 |= 0x8000;
1235
1236 }
1237 }
1238
1239 pCardInfo->si_per_targ_init_sync = temp2;
1240 pCardInfo->si_per_targ_no_disc = temp3;
1241 pCardInfo->si_per_targ_wide_nego = temp4;
1242 pCardInfo->si_per_targ_fast_nego = temp5;
1243 pCardInfo->si_per_targ_ultra_nego = temp6;
1244
1245 if(pCurrNvRam)
1246 i = pCurrNvRam->niSysConf;
1247 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001248 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
1250 if(pCurrNvRam)
1251 ScamFlg = pCurrNvRam->niScamConf;
1252 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001253 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254
1255 pCardInfo->si_flags = 0x0000;
1256
1257 if (i & 0x01)
1258 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1259
1260 if (!(i & 0x02))
1261 pCardInfo->si_flags |= SOFT_RESET;
1262
1263 if (i & 0x10)
1264 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1265
1266 if (ScamFlg & SCAM_ENABLED)
1267 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1268
1269 if (ScamFlg & SCAM_LEVEL2)
1270 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1271
1272 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1273 if (i & 0x04) {
1274 j |= SCSI_TERM_ENA_L;
1275 }
1276 WR_HARPOON(ioport+hp_bm_ctrl, j );
1277
1278 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1279 if (i & 0x08) {
1280 j |= SCSI_TERM_ENA_H;
1281 }
1282 WR_HARPOON(ioport+hp_ee_ctrl, j );
1283
1284 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1285
1286 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1287
1288 pCardInfo->si_card_family = HARPOON_FAMILY;
1289 pCardInfo->si_bustype = BUSTYPE_PCI;
1290
1291 if(pCurrNvRam){
1292 pCardInfo->si_card_model[0] = '9';
1293 switch(pCurrNvRam->niModel & 0x0f){
1294 case MODEL_LT:
1295 pCardInfo->si_card_model[1] = '3';
1296 pCardInfo->si_card_model[2] = '0';
1297 break;
1298 case MODEL_LW:
1299 pCardInfo->si_card_model[1] = '5';
1300 pCardInfo->si_card_model[2] = '0';
1301 break;
1302 case MODEL_DL:
1303 pCardInfo->si_card_model[1] = '3';
1304 pCardInfo->si_card_model[2] = '2';
1305 break;
1306 case MODEL_DW:
1307 pCardInfo->si_card_model[1] = '5';
1308 pCardInfo->si_card_model[2] = '2';
1309 break;
1310 }
1311 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001312 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001313 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001314 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001316 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1317 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 }
1319
1320 if (pCardInfo->si_card_model[1] == '3')
1321 {
1322 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1323 pCardInfo->si_flags |= LOW_BYTE_TERM;
1324 }
1325 else if (pCardInfo->si_card_model[2] == '0')
1326 {
1327 temp = RD_HARPOON(ioport+hp_xfer_pad);
1328 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1329 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1330 pCardInfo->si_flags |= LOW_BYTE_TERM;
1331 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1332 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1333 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1334 WR_HARPOON(ioport+hp_xfer_pad, temp);
1335 }
1336 else
1337 {
1338 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1339 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1340 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1341 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1342 temp3 = 0;
1343 for (i = 0; i < 8; i++)
1344 {
1345 temp3 <<= 1;
1346 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1347 temp3 |= 1;
1348 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1349 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1350 }
1351 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1352 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1353 if (!(temp3 & BIT(7)))
1354 pCardInfo->si_flags |= LOW_BYTE_TERM;
1355 if (!(temp3 & BIT(6)))
1356 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1357 }
1358
1359
1360 ARAM_ACCESS(ioport);
1361
1362 for ( i = 0; i < 4; i++ ) {
1363
1364 pCardInfo->si_XlatInfo[i] =
1365 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1366 }
1367
1368 /* return with -1 if no sort, else return with
1369 logical card number sorted by BIOS (zero-based) */
1370
1371 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001372 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
1374 SGRAM_ACCESS(ioport);
1375
James Bottomley 47b5d692005-04-24 02:38:05 -05001376 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1377 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1378 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1379 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1380 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1381 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1382 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1383 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
1385 pCardInfo->si_present = 0x01;
1386
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 return(0);
1388}
1389
1390
1391/*---------------------------------------------------------------------
1392 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001393 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 *
1395 * Description: Setup adapter for normal operation (hard reset).
1396 *
1397 *---------------------------------------------------------------------*/
1398
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001399static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400{
1401 PSCCBcard CurrCard = NULL;
1402 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001403 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001404 unsigned short temp,sync_bit_map,id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
1409 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1410
1411 if (thisCard == MAX_CARDS) {
1412
1413 return(FAILURE);
1414 }
1415
James Bottomley 47b5d692005-04-24 02:38:05 -05001416 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
James Bottomley 47b5d692005-04-24 02:38:05 -05001418 CurrCard = &FPT_BL_Card[thisCard];
1419 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 break;
1421 }
1422
James Bottomley 47b5d692005-04-24 02:38:05 -05001423 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
James Bottomley 47b5d692005-04-24 02:38:05 -05001425 FPT_BL_Card[thisCard].ioPort = ioport;
1426 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427
James Bottomley 47b5d692005-04-24 02:38:05 -05001428 if(FPT_mbCards)
1429 for(i = 0; i < FPT_mbCards; i++){
1430 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1431 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001433 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 CurrCard->cardIndex = thisCard;
1435 CurrCard->cardInfo = pCardInfo;
1436
1437 break;
1438 }
1439 }
1440
1441 pCurrNvRam = CurrCard->pNvRamInfo;
1442
1443 if(pCurrNvRam){
1444 ScamFlg = pCurrNvRam->niScamConf;
1445 }
1446 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001447 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 }
1449
1450
James Bottomley 47b5d692005-04-24 02:38:05 -05001451 FPT_BusMasterInit(ioport);
1452 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
James Bottomley 47b5d692005-04-24 02:38:05 -05001454 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
1456
1457 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1458
1459 WR_HARPOON(ioport+hp_selfid_0, id);
1460 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1461 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1462 CurrCard->ourId = pCardInfo->si_id;
1463
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001464 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 if (i & SCSI_PARITY_ENA)
1466 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1467
1468 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1469 if (i & LOW_BYTE_TERM)
1470 j |= SCSI_TERM_ENA_L;
1471 WR_HARPOON(ioport+hp_bm_ctrl, j);
1472
1473 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1474 if (i & HIGH_BYTE_TERM)
1475 j |= SCSI_TERM_ENA_H;
1476 WR_HARPOON(ioport+hp_ee_ctrl, j );
1477
1478
1479 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1480
James Bottomley 47b5d692005-04-24 02:38:05 -05001481 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
James Bottomley 47b5d692005-04-24 02:38:05 -05001483 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 }
1485
1486
1487
1488 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1489 CurrCard->globalFlags |= F_NO_FILTER;
1490
1491 if(pCurrNvRam){
1492 if(pCurrNvRam->niSysConf & 0x10)
1493 CurrCard->globalFlags |= F_GREEN_PC;
1494 }
1495 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001496 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 CurrCard->globalFlags |= F_GREEN_PC;
1498 }
1499
1500 /* Set global flag to indicate Re-Negotiation to be done on all
1501 ckeck condition */
1502 if(pCurrNvRam){
1503 if(pCurrNvRam->niScsiConf & 0x04)
1504 CurrCard->globalFlags |= F_DO_RENEGO;
1505 }
1506 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001507 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 CurrCard->globalFlags |= F_DO_RENEGO;
1509 }
1510
1511 if(pCurrNvRam){
1512 if(pCurrNvRam->niScsiConf & 0x08)
1513 CurrCard->globalFlags |= F_CONLUN_IO;
1514 }
1515 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001516 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 CurrCard->globalFlags |= F_CONLUN_IO;
1518 }
1519
1520
1521 temp = pCardInfo->si_per_targ_no_disc;
1522
1523 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1524
1525 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001526 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 }
1528
1529 sync_bit_map = 0x0001;
1530
1531 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1532
1533 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001534 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1536 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1537 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001538 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
1540 for (i = 0; i < 2; temp >>=8,i++) {
1541
1542 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1543
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001544 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 }
1546
1547 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001548 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1549 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001550 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 }
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1554 (id*2+i >= 8)){
1555*/
1556 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1557
James Bottomley 47b5d692005-04-24 02:38:05 -05001558 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
1560 }
1561
1562 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001563 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 }
1565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
1567 sync_bit_map <<= 1;
1568
1569
1570
1571 }
1572 }
1573
1574 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001575 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 return((ULONG)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578}
1579
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001580static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001582 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 ULONG portBase;
1584 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 PNVRamInfo pCurrNvRam;
1588
1589 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1590
1591 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001592 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597
1598 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001599 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
1601 portBase = pCurrNvRam->niBaseAddr;
1602
1603 for(i = 0; i < MAX_SCSI_TAR; i++){
1604 regOffset = hp_aramBase + 64 + i*4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 scamData = *pScamTbl;
1607 WR_HARP32(portBase, regOffset, scamData);
1608 }
1609
1610 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001611 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 }
1613}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
1615
James Bottomley 47b5d692005-04-24 02:38:05 -05001616static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001618 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 ULONG portBase;
1620 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
James Bottomley 47b5d692005-04-24 02:38:05 -05001624 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1625 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1626 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1627 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1628 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
1630 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001631 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632
1633 portBase = pNvRamInfo->niBaseAddr;
1634
1635 for(i = 0; i < MAX_SCSI_TAR; i++){
1636 regOffset = hp_aramBase + 64 + i*4;
1637 RD_HARP32(portBase, regOffset, scamData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 *pScamTbl = scamData;
1640 }
1641
1642}
1643
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001644static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645{
1646 WR_HARPOON(portBase + hp_stack_addr, index);
1647 return(RD_HARPOON(portBase + hp_stack_data));
1648}
1649
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001650static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651{
1652 WR_HARPOON(portBase + hp_stack_addr, index);
1653 WR_HARPOON(portBase + hp_stack_data, data);
1654}
1655
1656
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001657static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658{
James Bottomley 47b5d692005-04-24 02:38:05 -05001659 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1660 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1662 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001663 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1665 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001666 return(1);
1667 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
1669}
1670/*---------------------------------------------------------------------
1671 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001672 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 *
1674 * Description: Start a command pointed to by p_Sccb. When the
1675 * command is completed it will be returned via the
1676 * callback function.
1677 *
1678 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001679static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 ULONG ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001682 unsigned char thisCard, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 PSCCB pSaveSccb;
1684 CALL_BK_FN callback;
1685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1687 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1690 {
1691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 p_Sccb->HostStatus = SCCB_COMPLETE;
1693 p_Sccb->SccbStatus = SCCB_ERROR;
1694 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1695 if (callback)
1696 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 return;
1699 }
1700
James Bottomley 47b5d692005-04-24 02:38:05 -05001701 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
1703
1704 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1705 {
1706 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1707 | SCCB_MGR_ACTIVE));
1708
1709 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1710 {
1711 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1712 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1713 }
1714 }
1715
1716 ((PSCCBcard)pCurrCard)->cmdCounter++;
1717
1718 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1719
1720 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1721 | TICKLE_ME));
1722 if(p_Sccb->OperationCode == RESET_COMMAND)
1723 {
1724 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1725 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001726 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1728 }
1729 else
1730 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001731 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 }
1733 }
1734
1735 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1736
1737 if(p_Sccb->OperationCode == RESET_COMMAND)
1738 {
1739 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1740 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001741 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1743 }
1744 else
1745 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001746 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 }
1748 }
1749
1750 else {
1751
1752 MDISABLE_INT(ioport);
1753
1754 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001755 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 lun = p_Sccb->Lun;
1757 else
1758 lun = 0;
1759 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001760 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1761 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1762 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
1764 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001765 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 }
1767
1768 else {
1769
1770 if(p_Sccb->OperationCode == RESET_COMMAND)
1771 {
1772 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1773 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001774 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1776 }
1777 else
1778 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001779 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 }
1781 }
1782
1783
1784 MENABLE_INT(ioport);
1785 }
1786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787}
1788
1789
1790/*---------------------------------------------------------------------
1791 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001792 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 *
1794 * Description: Abort the command pointed to by p_Sccb. When the
1795 * command is completed it will be returned via the
1796 * callback function.
1797 *
1798 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001799static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001803 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001805 unsigned char TID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 PSCCB pSaveSCCB;
1807 PSCCBMgr_tar_info currTar_Info;
1808
1809
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1811
1812 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1813
James Bottomley 47b5d692005-04-24 02:38:05 -05001814 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 {
1816
James Bottomley 47b5d692005-04-24 02:38:05 -05001817 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 {
1819
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 ((PSCCBcard)pCurrCard)->cmdCounter--;
1821
1822 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1823 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001824 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 p_Sccb->SccbStatus = SCCB_ABORT;
1827 callback = p_Sccb->SccbCallback;
1828 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 return(0);
1831 }
1832
1833 else
1834 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1836 {
1837 p_Sccb->SccbStatus = SCCB_ABORT;
1838 return(0);
1839
1840 }
1841
1842 else
1843 {
1844
1845 TID = p_Sccb->TargID;
1846
1847
1848 if(p_Sccb->Sccb_tag)
1849 {
1850 MDISABLE_INT(ioport);
1851 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1852 {
1853 p_Sccb->SccbStatus = SCCB_ABORT;
1854 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1856
1857 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1858 {
1859 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001860 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 }
1862 else
1863 {
1864 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1865 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001866 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1868 }
1869 }
1870 MENABLE_INT(ioport);
1871 return(0);
1872 }
1873 else
1874 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001875 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876
James Bottomley 47b5d692005-04-24 02:38:05 -05001877 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 == p_Sccb)
1879 {
1880 p_Sccb->SccbStatus = SCCB_ABORT;
1881 return(0);
1882 }
1883 }
1884 }
1885 }
1886 }
1887 return(-1);
1888}
1889
1890
1891/*---------------------------------------------------------------------
1892 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001893 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 *
1895 * Description: Do a quick check to determine if there is a pending
1896 * interrupt for this card and disable the IRQ Pin if so.
1897 *
1898 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001899static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902
1903 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1904
1905 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1906 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001907 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 }
1909
1910 else
1911
James Bottomley 47b5d692005-04-24 02:38:05 -05001912 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913}
1914
1915
1916
1917/*---------------------------------------------------------------------
1918 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001919 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 *
1921 * Description: This is our entry point when an interrupt is generated
1922 * by the card and the upper level driver passes it on to
1923 * us.
1924 *
1925 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001926static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927{
1928 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001929 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001930 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001931 unsigned char i, target;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1935 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1936
1937 MDISABLE_INT(ioport);
1938
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001940 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 else
1942 bm_status = 0;
1943
1944 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1945
James Bottomley 47b5d692005-04-24 02:38:05 -05001946 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 bm_status)
1948 {
1949
1950 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1951
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001953 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1955 bm_status = 0;
1956
1957 if (result) {
1958
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 return(result);
1961 }
1962 }
1963
1964
1965 else if (hp_int & ICMD_COMP) {
1966
1967 if ( !(hp_int & BUS_FREE) ) {
1968 /* Wait for the BusFree before starting a new command. We
1969 must also check for being reselected since the BusFree
1970 may not show up if another device reselects us in 1.5us or
1971 less. SRR Wednesday, 3/8/1995.
1972 */
1973 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1974 }
1975
1976 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1977
James Bottomley 47b5d692005-04-24 02:38:05 -05001978 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
1980/* WRW_HARPOON((ioport+hp_intstat),
1981 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1982 */
1983
1984 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1985
James Bottomley 47b5d692005-04-24 02:38:05 -05001986 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987
1988 }
1989
1990
1991 else if (hp_int & ITAR_DISC)
1992 {
1993
1994 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1995
James Bottomley 47b5d692005-04-24 02:38:05 -05001996 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
1998 }
1999
2000 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2001
2002 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2003 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2004
2005 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2006 }
2007
2008 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002009 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 /* Wait for the BusFree before starting a new command. We
2012 must also check for being reselected since the BusFree
2013 may not show up if another device reselects us in 1.5us or
2014 less. SRR Wednesday, 3/8/1995.
2015 */
2016 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2017 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2018 RD_HARPOON((ioport+hp_scsisig)) ==
2019 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2020
2021 /*
2022 The additional loop exit condition above detects a timing problem
2023 with the revision D/E harpoon chips. The caller should reset the
2024 host adapter to recover when 0xFE is returned.
2025 */
2026 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2027 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029 return 0xFE;
2030 }
2031
2032 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2033
2034
2035 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2036
2037 }
2038
2039
2040 else if (hp_int & RSEL) {
2041
2042 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2043
2044 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2045 {
2046 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2047 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002048 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 }
2050
2051 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2052 {
2053 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2054 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2055 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2056 }
2057
2058 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2059 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002060 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 }
2062
James Bottomley 47b5d692005-04-24 02:38:05 -05002063 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2064 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065
2066 }
2067
2068
2069 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2070 {
2071
2072 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002073 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
2075 }
2076
2077
2078 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2079 {
2080 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002081 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002083 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 }
2085 else
2086 {
2087 /* Harpoon problem some SCSI target device respond to selection
2088 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2089 to latch the correct Target ID into reg. x53.
2090 The work around require to correct this reg. But when write to this
2091 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2092 need to read this reg first then restore it later. After update to 0x53 */
2093
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002094 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2095 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2096 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2097 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2098 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 WR_HARPOON(ioport+hp_fifowrite, i);
2100 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2101 }
2102 }
2103
2104 else if (hp_int & XFER_CNT_0) {
2105
2106 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2107
James Bottomley 47b5d692005-04-24 02:38:05 -05002108 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109
2110 }
2111
2112
2113 else if (hp_int & BUS_FREE) {
2114
2115 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2116
2117 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2118
James Bottomley 47b5d692005-04-24 02:38:05 -05002119 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 }
2121
James Bottomley 47b5d692005-04-24 02:38:05 -05002122 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 }
2124
2125
2126 else if (hp_int & ITICKLE) {
2127
2128 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2129 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2130 }
2131
2132
2133
2134 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2135
2136
2137 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2138
2139
2140 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2141
James Bottomley 47b5d692005-04-24 02:38:05 -05002142 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 }
2144
2145 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2146 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002147 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 }
2149
2150 break;
2151
2152 }
2153
2154 } /*end while */
2155
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157
2158 return(0);
2159}
2160
2161/*---------------------------------------------------------------------
2162 *
2163 * Function: Sccb_bad_isr
2164 *
2165 * Description: Some type of interrupt has occurred which is slightly
2166 * out of the ordinary. We will now decode it fully, in
2167 * this routine. This is broken up in an attempt to save
2168 * processing time.
2169 *
2170 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002171static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002172 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002174 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002175 PSCCBMgr_tar_info currTar_Info;
2176 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177
2178
2179 if (RD_HARPOON(p_port+hp_ext_status) &
2180 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2181 {
2182
2183 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2184 {
2185
James Bottomley 47b5d692005-04-24 02:38:05 -05002186 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 }
2188
2189 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2190
2191 {
2192 WR_HARPOON(p_port+hp_pci_stat_cfg,
2193 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2194
2195 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2196
2197 }
2198
2199 if (pCurrCard->currentSCCB != NULL)
2200 {
2201
2202 if (!pCurrCard->currentSCCB->HostStatus)
2203 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2204
James Bottomley 47b5d692005-04-24 02:38:05 -05002205 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002207 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002209 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2211
2212 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2213 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002214 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215 }
2216 }
2217 }
2218
2219
2220 else if (p_int & RESET)
2221 {
2222
2223 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2224 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2225 if (pCurrCard->currentSCCB != NULL) {
2226
2227 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2228
James Bottomley 47b5d692005-04-24 02:38:05 -05002229 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 }
2231
2232
2233 DISABLE_AUTO(p_port);
2234
James Bottomley 47b5d692005-04-24 02:38:05 -05002235 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236
2237 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2238
2239 pCurrNvRam = pCurrCard->pNvRamInfo;
2240 if(pCurrNvRam){
2241 ScamFlg = pCurrNvRam->niScamConf;
2242 }
2243 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002244 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 }
2246
James Bottomley 47b5d692005-04-24 02:38:05 -05002247 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248
James Bottomley 47b5d692005-04-24 02:38:05 -05002249 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250
2251 return(0xFF);
2252 }
2253
2254
2255 else if (p_int & FIFO) {
2256
2257 WRW_HARPOON((p_port+hp_intstat), FIFO);
2258
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002260 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 }
2262
2263 else if (p_int & TIMEOUT)
2264 {
2265
2266 DISABLE_AUTO(p_port);
2267
2268 WRW_HARPOON((p_port+hp_intstat),
2269 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2270
2271 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2272
2273
James Bottomley 47b5d692005-04-24 02:38:05 -05002274 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2276 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002277 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002279 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
2281
2282 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2283 {
2284 currTar_Info->TarSyncCtrl = 0;
2285 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2286 }
2287
2288 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2289 {
2290 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2291 }
2292
James Bottomley 47b5d692005-04-24 02:38:05 -05002293 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
James Bottomley 47b5d692005-04-24 02:38:05 -05002295 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
2297 }
2298
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 else if (p_int & SCAM_SEL)
2300 {
2301
James Bottomley 47b5d692005-04-24 02:38:05 -05002302 FPT_scarb(p_port,LEVEL2_TAR);
2303 FPT_scsel(p_port);
2304 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305
James Bottomley 47b5d692005-04-24 02:38:05 -05002306 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
2308 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2309 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310
2311 return(0x00);
2312}
2313
2314
2315/*---------------------------------------------------------------------
2316 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 * Function: SccbMgrTableInit
2318 *
2319 * Description: Initialize all Sccb manager data structures.
2320 *
2321 *---------------------------------------------------------------------*/
2322
James Bottomley 47b5d692005-04-24 02:38:05 -05002323static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002325 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326
2327 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2328 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002329 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330
James Bottomley 47b5d692005-04-24 02:38:05 -05002331 FPT_BL_Card[thisCard].ioPort = 0x00;
2332 FPT_BL_Card[thisCard].cardInfo = NULL;
2333 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2334 FPT_BL_Card[thisCard].ourId = 0x00;
2335 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 }
2337}
2338
2339
2340/*---------------------------------------------------------------------
2341 *
2342 * Function: SccbMgrTableInit
2343 *
2344 * Description: Initialize all Sccb manager data structures.
2345 *
2346 *---------------------------------------------------------------------*/
2347
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002348static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002350 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351
2352 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2353 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002354 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 }
2356
2357 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2358 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002359 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2360 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2361 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 }
2363
2364 pCurrCard->scanIndex = 0x00;
2365 pCurrCard->currentSCCB = NULL;
2366 pCurrCard->globalFlags = 0x00;
2367 pCurrCard->cmdCounter = 0x00;
2368 pCurrCard->tagQ_Lst = 0x01;
2369 pCurrCard->discQCount = 0;
2370
2371
2372}
2373
2374
2375/*---------------------------------------------------------------------
2376 *
2377 * Function: SccbMgrTableInit
2378 *
2379 * Description: Initialize all Sccb manager data structures.
2380 *
2381 *---------------------------------------------------------------------*/
2382
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002383static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384{
2385
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002386 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002387 PSCCBMgr_tar_info currTar_Info;
2388
James Bottomley 47b5d692005-04-24 02:38:05 -05002389 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390
2391 currTar_Info->TarSelQ_Cnt = 0;
2392 currTar_Info->TarSyncCtrl = 0;
2393
2394 currTar_Info->TarSelQ_Head = NULL;
2395 currTar_Info->TarSelQ_Tail = NULL;
2396 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002397 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398
2399
2400 for (lun = 0; lun < MAX_LUN; lun++)
2401 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002402 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403 currTar_Info->LunDiscQ_Idx[lun] = 0;
2404 }
2405
2406 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2407 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002408 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002410 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002412 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2413 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 }
2415 }
2416 }
2417}
2418
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419
2420/*---------------------------------------------------------------------
2421 *
2422 * Function: sfetm
2423 *
2424 * Description: Read in a message byte from the SCSI bus, and check
2425 * for a parity error.
2426 *
2427 *---------------------------------------------------------------------*/
2428
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002429static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002431 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002432 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433
2434 TimeOutLoop = 0;
2435 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2436 (TimeOutLoop++ < 20000) ){}
2437
2438
2439 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2440
2441 message = RD_HARPOON(port+hp_scsidata_0);
2442
2443 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2444
2445
2446 if (TimeOutLoop > 20000)
2447 message = 0x00; /* force message byte = 0 if Time Out on Req */
2448
2449 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2450 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2451 {
2452 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2453 WR_HARPOON(port+hp_xferstat, 0);
2454 WR_HARPOON(port+hp_fiforead, 0);
2455 WR_HARPOON(port+hp_fifowrite, 0);
2456 if (pCurrSCCB != NULL)
2457 {
2458 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2459 }
2460 message = 0x00;
2461 do
2462 {
2463 ACCEPT_MSG_ATN(port);
2464 TimeOutLoop = 0;
2465 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2466 (TimeOutLoop++ < 20000) ){}
2467 if (TimeOutLoop > 20000)
2468 {
2469 WRW_HARPOON((port+hp_intstat), PARITY);
2470 return(message);
2471 }
2472 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2473 {
2474 WRW_HARPOON((port+hp_intstat), PARITY);
2475 return(message);
2476 }
2477 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2478
2479 RD_HARPOON(port+hp_scsidata_0);
2480
2481 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2482
2483 }while(1);
2484
2485 }
2486 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2487 WR_HARPOON(port+hp_xferstat, 0);
2488 WR_HARPOON(port+hp_fiforead, 0);
2489 WR_HARPOON(port+hp_fifowrite, 0);
2490 return(message);
2491}
2492
2493
2494/*---------------------------------------------------------------------
2495 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002496 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 *
2498 * Description: Load up automation and select target device.
2499 *
2500 *---------------------------------------------------------------------*/
2501
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002502static void FPT_ssel(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503{
2504
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002505 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 PSCCBcard CurrCard;
2509 PSCCB currSCCB;
2510 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002511 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512
James Bottomley 47b5d692005-04-24 02:38:05 -05002513 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 currSCCB = CurrCard->currentSCCB;
2515 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002516 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517 lastTag = CurrCard->tagQ_Lst;
2518
2519 ARAM_ACCESS(port);
2520
2521
2522 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2523 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2524
2525 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2526 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2527
2528 lun = currSCCB->Lun;
2529 else
2530 lun = 0;
2531
2532
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 if (CurrCard->globalFlags & F_TAG_STARTED)
2534 {
2535 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2536 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002537 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002538 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2539 == TAG_Q_TRYING))
2540 {
2541
2542 if (currTar_Info->TarTagQ_Cnt !=0)
2543 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002544 currTar_Info->TarLUNBusy[lun] = 1;
2545 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 SGRAM_ACCESS(port);
2547 return;
2548 }
2549
2550 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002551 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 }
2553
2554 } /*End non-tagged */
2555
2556 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002557 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558 }
2559
2560 } /*!Use cmd Q Tagged */
2561
2562 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002563 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002565 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 SGRAM_ACCESS(port);
2567 return;
2568 }
2569
James Bottomley 47b5d692005-04-24 02:38:05 -05002570 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
2572 } /*else use cmd Q tagged */
2573
2574 } /*if glob tagged started */
2575
2576 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002577 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578 }
2579
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580
2581
2582 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2583 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2584 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2585 {
2586 if(CurrCard->discQCount >= QUEUE_DEPTH)
2587 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002588 currTar_Info->TarLUNBusy[lun] = 1;
2589 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590 SGRAM_ACCESS(port);
2591 return;
2592 }
2593 for (i = 1; i < QUEUE_DEPTH; i++)
2594 {
2595 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2596 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2597 {
2598 CurrCard->tagQ_Lst = lastTag;
2599 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2600 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2601 CurrCard->discQCount++;
2602 break;
2603 }
2604 }
2605 if(i == QUEUE_DEPTH)
2606 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002607 currTar_Info->TarLUNBusy[lun] = 1;
2608 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 SGRAM_ACCESS(port);
2610 return;
2611 }
2612 }
2613
2614
2615
James Bottomley 47b5d692005-04-24 02:38:05 -05002616 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617
2618 WR_HARPOON(port+hp_select_id, target);
2619 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2620
2621 if (currSCCB->OperationCode == RESET_COMMAND) {
2622 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2623 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2624
2625 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2626
2627 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2628
2629 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002630 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2632
2633 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2634 {
2635 currTar_Info->TarSyncCtrl = 0;
2636 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2637 }
2638
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2640 {
2641 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2642 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643
James Bottomley 47b5d692005-04-24 02:38:05 -05002644 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2645 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646
2647 }
2648
2649 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2650 {
2651 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2652 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2653
2654 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2655
2656 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002657 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2658 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 WRW_HARPOON((port+SYNC_MSGS+2),
2660 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2661 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2662
2663 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002664 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665
2666 }
2667
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002669 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2671 }
2672
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2674 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002675 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2677 }
2678
2679
2680 if (!auto_loaded)
2681 {
2682
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 if (currSCCB->ControlByte & F_USE_CMD_Q)
2684 {
2685
2686 CurrCard->globalFlags |= F_TAG_STARTED;
2687
2688 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2689 == TAG_Q_REJECT)
2690 {
2691 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2692
2693 /* Fix up the start instruction with a jump to
2694 Non-Tag-CMD handling */
2695 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2696
2697 WRW_HARPOON((port+NON_TAG_ID_MSG),
2698 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2699
2700 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2701
2702 /* Setup our STATE so we know what happend when
2703 the wheels fall off. */
2704 currSCCB->Sccb_scsistat = SELECT_ST;
2705
James Bottomley 47b5d692005-04-24 02:38:05 -05002706 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707 }
2708
2709 else
2710 {
2711 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2712
2713 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002714 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2715 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
2717 for (i = 1; i < QUEUE_DEPTH; i++)
2718 {
2719 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2720 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2721 {
2722 WRW_HARPOON((port+ID_MSG_STRT+6),
2723 (MPM_OP+AMSG_OUT+lastTag));
2724 CurrCard->tagQ_Lst = lastTag;
2725 currSCCB->Sccb_tag = lastTag;
2726 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2727 CurrCard->discQCount++;
2728 break;
2729 }
2730 }
2731
2732
2733 if ( i == QUEUE_DEPTH )
2734 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002735 currTar_Info->TarLUNBusy[lun] = 1;
2736 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737 SGRAM_ACCESS(port);
2738 return;
2739 }
2740
2741 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2742
2743 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2744 }
2745 }
2746
2747 else
2748 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749
2750 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2751
2752 WRW_HARPOON((port+NON_TAG_ID_MSG),
2753 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2754
2755 currSCCB->Sccb_scsistat = SELECT_ST;
2756
2757 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002758 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759
2760
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002761 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002762
2763 cdb_reg = port + CMD_STRT;
2764
2765 for (i=0; i < currSCCB->CdbLength; i++)
2766 {
2767 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2768 cdb_reg +=2;
2769 theCCB++;
2770 }
2771
2772 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2773 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2774
2775 } /* auto_loaded */
2776
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002777 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779
2780 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2781
2782 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2783
2784
2785 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2786 {
2787 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2788 }
2789 else
2790 {
2791
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002792/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 auto_loaded |= AUTO_IMMED; */
2794 auto_loaded = AUTO_IMMED;
2795
2796 DISABLE_AUTO(port);
2797
2798 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2799 }
2800
2801 SGRAM_ACCESS(port);
2802}
2803
2804
2805/*---------------------------------------------------------------------
2806 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002807 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 *
2809 * Description: Hookup the correct CCB and handle the incoming messages.
2810 *
2811 *---------------------------------------------------------------------*/
2812
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002813static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814{
2815
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002816 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817
2818
2819 PSCCBMgr_tar_info currTar_Info;
2820 PSCCB currSCCB;
2821
2822
2823
2824
2825 if(pCurrCard->currentSCCB != NULL)
2826 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002827 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 DISABLE_AUTO(port);
2829
2830
2831 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2832
2833
2834 currSCCB = pCurrCard->currentSCCB;
2835 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2836 {
2837 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2838 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2839 }
2840 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2841 {
2842 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2843 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2844 }
2845 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2846 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2847 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002848 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 if(currSCCB->Sccb_scsistat != ABORT_ST)
2850 {
2851 pCurrCard->discQCount--;
2852 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2853 = NULL;
2854 }
2855 }
2856 else
2857 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002858 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 if(currSCCB->Sccb_tag)
2860 {
2861 if(currSCCB->Sccb_scsistat != ABORT_ST)
2862 {
2863 pCurrCard->discQCount--;
2864 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2865 }
2866 }else
2867 {
2868 if(currSCCB->Sccb_scsistat != ABORT_ST)
2869 {
2870 pCurrCard->discQCount--;
2871 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2872 }
2873 }
2874 }
2875
James Bottomley 47b5d692005-04-24 02:38:05 -05002876 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 }
2878
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002879 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880
2881
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002882 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002883 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884
2885
2886 msgRetryCount = 0;
2887 do
2888 {
2889
James Bottomley 47b5d692005-04-24 02:38:05 -05002890 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 tag = 0;
2892
2893
2894 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2895 {
2896 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2897 {
2898
2899 WRW_HARPOON((port+hp_intstat), PHASE);
2900 return;
2901 }
2902 }
2903
2904 WRW_HARPOON((port+hp_intstat), PHASE);
2905 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2906 {
2907
James Bottomley 47b5d692005-04-24 02:38:05 -05002908 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909 if (message)
2910 {
2911
2912 if (message <= (0x80 | LUN_MASK))
2913 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002914 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2917 {
2918 if (currTar_Info->TarTagQ_Cnt != 0)
2919 {
2920
2921 if (!(currTar_Info->TarLUN_CA))
2922 {
2923 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2924
2925
James Bottomley 47b5d692005-04-24 02:38:05 -05002926 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 if (message)
2928 {
2929 ACCEPT_MSG(port);
2930 }
2931
2932 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002933 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934
James Bottomley 47b5d692005-04-24 02:38:05 -05002935 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002937 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938
2939 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002940 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 }
2942
2943 } /*C.A. exists! */
2944
2945 } /*End Q cnt != 0 */
2946
2947 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948
2949 } /*End valid ID message. */
2950
2951 else
2952 {
2953
2954 ACCEPT_MSG_ATN(port);
2955 }
2956
2957 } /* End good id message. */
2958
2959 else
2960 {
2961
James Bottomley 47b5d692005-04-24 02:38:05 -05002962 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 }
2964 }
2965 else
2966 {
2967 ACCEPT_MSG_ATN(port);
2968
2969 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2970 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2971 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2972
2973 return;
2974 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975
James Bottomley 47b5d692005-04-24 02:38:05 -05002976 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 {
2978 msgRetryCount++;
2979 if(msgRetryCount == 1)
2980 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002981 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 }
2983 else
2984 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002985 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986
James Bottomley 47b5d692005-04-24 02:38:05 -05002987 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988
James Bottomley 47b5d692005-04-24 02:38:05 -05002989 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 {
2991
James Bottomley 47b5d692005-04-24 02:38:05 -05002992 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993
2994 }
2995
James Bottomley 47b5d692005-04-24 02:38:05 -05002996 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 {
2998
James Bottomley 47b5d692005-04-24 02:38:05 -05002999 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 }
3001
3002
James Bottomley 47b5d692005-04-24 02:38:05 -05003003 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3004 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 return;
3006 }
3007 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003008 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009
3010
3011
3012 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3013 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3014 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003015 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3017 if(pCurrCard->currentSCCB != NULL)
3018 {
3019 ACCEPT_MSG(port);
3020 }
3021 else
3022 {
3023 ACCEPT_MSG_ATN(port);
3024 }
3025 }
3026 else
3027 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003028 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
3030
3031 if (tag)
3032 {
3033 if (pCurrCard->discQ_Tbl[tag] != NULL)
3034 {
3035 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3036 currTar_Info->TarTagQ_Cnt--;
3037 ACCEPT_MSG(port);
3038 }
3039 else
3040 {
3041 ACCEPT_MSG_ATN(port);
3042 }
3043 }else
3044 {
3045 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3046 if(pCurrCard->currentSCCB != NULL)
3047 {
3048 ACCEPT_MSG(port);
3049 }
3050 else
3051 {
3052 ACCEPT_MSG_ATN(port);
3053 }
3054 }
3055 }
3056
3057 if(pCurrCard->currentSCCB != NULL)
3058 {
3059 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3060 {
3061 /* During Abort Tag command, the target could have got re-selected
3062 and completed the command. Check the select Q and remove the CCB
3063 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003064 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065 }
3066 }
3067
3068
3069 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3070 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3071 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3072}
3073
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003074static void FPT_SendMsg(ULONG port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075{
3076 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3077 {
3078 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3079 {
3080
3081 WRW_HARPOON((port+hp_intstat), PHASE);
3082 return;
3083 }
3084 }
3085
3086 WRW_HARPOON((port+hp_intstat), PHASE);
3087 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3088 {
3089 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3090
3091
3092 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3093
3094 WR_HARPOON(port+hp_scsidata_0,message);
3095
3096 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3097
3098 ACCEPT_MSG(port);
3099
3100 WR_HARPOON(port+hp_portctrl_0, 0x00);
3101
3102 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3103 (message == SMABORT_TAG) )
3104 {
3105 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3106
3107 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3108 {
3109 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3110 }
3111 }
3112 }
3113}
3114
3115/*---------------------------------------------------------------------
3116 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003117 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 *
3119 * Description: Determine the proper responce to the message from the
3120 * target device.
3121 *
3122 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003123static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124{
3125 PSCCB currSCCB;
3126 PSCCBcard CurrCard;
3127 PSCCBMgr_tar_info currTar_Info;
3128
James Bottomley 47b5d692005-04-24 02:38:05 -05003129 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 currSCCB = CurrCard->currentSCCB;
3131
James Bottomley 47b5d692005-04-24 02:38:05 -05003132 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133
3134 if (message == SMREST_DATA_PTR)
3135 {
3136 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3137 {
3138 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3139
James Bottomley 47b5d692005-04-24 02:38:05 -05003140 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 }
3142
3143 ACCEPT_MSG(port);
3144 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3145 }
3146
3147 else if (message == SMCMD_COMP)
3148 {
3149
3150
3151 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3152 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003153 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3154 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 }
3156
3157 ACCEPT_MSG(port);
3158
3159 }
3160
3161 else if ((message == SMNO_OP) || (message >= SMIDENT)
3162 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3163 {
3164
3165 ACCEPT_MSG(port);
3166 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3167 }
3168
3169 else if (message == SMREJECT)
3170 {
3171
3172 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3173 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3174 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3175 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3176
3177 {
3178 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3179
3180 ACCEPT_MSG(port);
3181
3182
3183 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3184 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3185
3186 if(currSCCB->Lun == 0x00)
3187 {
3188 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3189 {
3190
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003191 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192
3193 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3194 }
3195
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3197 {
3198
3199
3200 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3201 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3202
3203 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3204
3205 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206
3207 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3208 {
3209 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003210 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211
3212
3213 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3214 CurrCard->discQCount--;
3215 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3216 currSCCB->Sccb_tag = 0x00;
3217
3218 }
3219 }
3220
3221 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3222 {
3223
3224
3225 if(currSCCB->Lun == 0x00)
3226 {
3227 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3228 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3229 }
3230 }
3231
3232 else
3233 {
3234
3235 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3236 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003237 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003239 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240
3241
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003242 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243
3244 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3245
3246 }
3247 }
3248
3249 else
3250 {
3251 ACCEPT_MSG(port);
3252
3253 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3254 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3255
3256 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3257 {
3258 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3259 }
3260 }
3261 }
3262
3263 else if (message == SMEXT)
3264 {
3265
3266 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003267 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268 }
3269
3270 else if (message == SMIGNORWR)
3271 {
3272
3273 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3274
James Bottomley 47b5d692005-04-24 02:38:05 -05003275 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276
3277 if(currSCCB->Sccb_scsimsg != SMPARITY)
3278 ACCEPT_MSG(port);
3279 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3280 }
3281
3282
3283 else
3284 {
3285
3286 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3287 currSCCB->Sccb_scsimsg = SMREJECT;
3288
3289 ACCEPT_MSG_ATN(port);
3290 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3291 }
3292}
3293
3294
3295/*---------------------------------------------------------------------
3296 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003297 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298 *
3299 * Description: Decide what to do with the extended message.
3300 *
3301 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003302static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003303{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003304 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305
James Bottomley 47b5d692005-04-24 02:38:05 -05003306 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307 if (length)
3308 {
3309
3310 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003311 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312 if (message)
3313 {
3314
3315 if (message == SMSYNC)
3316 {
3317
3318 if (length == 0x03)
3319 {
3320
3321 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003322 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003323 }
3324 else
3325 {
3326
3327 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3328 ACCEPT_MSG_ATN(port);
3329 }
3330 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003331 else if (message == SMWDTR)
3332 {
3333
3334 if (length == 0x02)
3335 {
3336
3337 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003338 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 }
3340 else
3341 {
3342
3343 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3344 ACCEPT_MSG_ATN(port);
3345
3346 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3347 }
3348 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349 else
3350 {
3351
3352 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3353 ACCEPT_MSG_ATN(port);
3354
3355 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3356 }
3357 }
3358 else
3359 {
3360 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3361 ACCEPT_MSG(port);
3362 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3363 }
3364 }else
3365 {
3366 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3367 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3368 }
3369}
3370
3371
3372/*---------------------------------------------------------------------
3373 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003374 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375 *
3376 * Description: Read in a message byte from the SCSI bus, and check
3377 * for a parity error.
3378 *
3379 *---------------------------------------------------------------------*/
3380
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003381static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382{
3383 PSCCB currSCCB;
3384 PSCCBMgr_tar_info currTar_Info;
3385
James Bottomley 47b5d692005-04-24 02:38:05 -05003386 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3387 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003388
3389 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3390
3391
3392 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003393 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394
3395 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3396
3397 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3398 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3399 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3400
3401
3402 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3403
3404 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3405
3406 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3407
3408 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3409
3410 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3411
3412 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3413
3414 else
3415 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3416
3417
3418 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3419 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3420 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3421
3422
James Bottomley 47b5d692005-04-24 02:38:05 -05003423 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003424 {
3425 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3426 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003427 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 }
3429 else
3430 {
3431 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3432 }
3433
3434
James Bottomley 47b5d692005-04-24 02:38:05 -05003435 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436 }
3437
3438 else {
3439
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003440 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003442 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443 }
3444}
3445
3446
3447
3448/*---------------------------------------------------------------------
3449 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003450 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451 *
3452 * Description: The has sent us a Sync Nego message so handle it as
3453 * necessary.
3454 *
3455 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003456static void FPT_stsyncn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003458 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003459 PSCCB currSCCB;
3460 PSCCBMgr_tar_info currTar_Info;
3461
James Bottomley 47b5d692005-04-24 02:38:05 -05003462 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3463 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464
James Bottomley 47b5d692005-04-24 02:38:05 -05003465 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466
3467 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3468 {
3469 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3470 return;
3471 }
3472
3473 ACCEPT_MSG(port);
3474
3475
James Bottomley 47b5d692005-04-24 02:38:05 -05003476 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477
3478 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3479 {
3480 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3481 return;
3482 }
3483
3484 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3485
3486 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3487
3488 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3489
3490 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3491
3492 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3493
3494 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3495 else
3496
3497 our_sync_msg = 0; /* Message = Async */
3498
3499 if (sync_msg < our_sync_msg) {
3500 sync_msg = our_sync_msg; /*if faster, then set to max. */
3501 }
3502
3503 if (offset == ASYNC)
3504 sync_msg = ASYNC;
3505
3506 if (offset > MAX_OFFSET)
3507 offset = MAX_OFFSET;
3508
3509 sync_reg = 0x00;
3510
3511 if (sync_msg > 12)
3512
3513 sync_reg = 0x20; /* Use 10MB/s */
3514
3515 if (sync_msg > 25)
3516
3517 sync_reg = 0x40; /* Use 6.6MB/s */
3518
3519 if (sync_msg > 38)
3520
3521 sync_reg = 0x60; /* Use 5MB/s */
3522
3523 if (sync_msg > 50)
3524
3525 sync_reg = 0x80; /* Use 4MB/s */
3526
3527 if (sync_msg > 62)
3528
3529 sync_reg = 0xA0; /* Use 3.33MB/s */
3530
3531 if (sync_msg > 75)
3532
3533 sync_reg = 0xC0; /* Use 2.85MB/s */
3534
3535 if (sync_msg > 87)
3536
3537 sync_reg = 0xE0; /* Use 2.5MB/s */
3538
3539 if (sync_msg > 100) {
3540
3541 sync_reg = 0x00; /* Use ASYNC */
3542 offset = 0x00;
3543 }
3544
3545
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 if (currTar_Info->TarStatus & WIDE_ENABLED)
3547
3548 sync_reg |= offset;
3549
3550 else
3551
3552 sync_reg |= (offset | NARROW_SCSI);
3553
James Bottomley 47b5d692005-04-24 02:38:05 -05003554 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555
3556
3557 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3558
3559
3560 ACCEPT_MSG(port);
3561
3562 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003563 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564
3565 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3566 }
3567
3568 else {
3569
3570
3571 ACCEPT_MSG_ATN(port);
3572
James Bottomley 47b5d692005-04-24 02:38:05 -05003573 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574
3575 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003576 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577 }
3578}
3579
3580
3581/*---------------------------------------------------------------------
3582 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003583 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003584 *
3585 * Description: Answer the targets sync message.
3586 *
3587 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003588static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003589{
3590 ARAM_ACCESS(port);
3591 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3592 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3593 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3594 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3595 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3596 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3597 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3598 SGRAM_ACCESS(port);
3599
3600 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3601 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3602
3603 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3604
3605 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3606}
3607
3608
3609
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610/*---------------------------------------------------------------------
3611 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003612 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613 *
3614 * Description: Read in a message byte from the SCSI bus, and check
3615 * for a parity error.
3616 *
3617 *---------------------------------------------------------------------*/
3618
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003619static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003620{
3621 PSCCB currSCCB;
3622 PSCCBMgr_tar_info currTar_Info;
3623
James Bottomley 47b5d692005-04-24 02:38:05 -05003624 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3625 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003626
3627 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3628
3629
3630 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003631 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003632
3633 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3634
3635 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3636 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3637 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3638 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3639 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3640 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3641
3642 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3643
3644
3645 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003646 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647
James Bottomley 47b5d692005-04-24 02:38:05 -05003648 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649 }
3650
3651 else {
3652
3653 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003654 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655
3656 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003657 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658 }
3659}
3660
3661
3662
3663/*---------------------------------------------------------------------
3664 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003665 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666 *
3667 * Description: The has sent us a Wide Nego message so handle it as
3668 * necessary.
3669 *
3670 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003671static void FPT_stwidn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003673 unsigned char width;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674 PSCCB currSCCB;
3675 PSCCBMgr_tar_info currTar_Info;
3676
James Bottomley 47b5d692005-04-24 02:38:05 -05003677 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3678 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003679
James Bottomley 47b5d692005-04-24 02:38:05 -05003680 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681
3682 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3683 {
3684 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3685 return;
3686 }
3687
3688
3689 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3690 width = 0;
3691
3692 if (width) {
3693 currTar_Info->TarStatus |= WIDE_ENABLED;
3694 width = 0;
3695 }
3696 else {
3697 width = NARROW_SCSI;
3698 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3699 }
3700
3701
James Bottomley 47b5d692005-04-24 02:38:05 -05003702 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703
3704
3705 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3706 {
3707
3708
3709
3710 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3711
3712 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3713 {
3714 ACCEPT_MSG_ATN(port);
3715 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003716 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3718 SGRAM_ACCESS(port);
3719 }
3720 else
3721 {
3722 ACCEPT_MSG(port);
3723 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3724 }
3725 }
3726
3727 else {
3728
3729
3730 ACCEPT_MSG_ATN(port);
3731
3732 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3733 width = SM16BIT;
3734 else
3735 width = SM8BIT;
3736
James Bottomley 47b5d692005-04-24 02:38:05 -05003737 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738
3739 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3740 }
3741}
3742
3743
3744/*---------------------------------------------------------------------
3745 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003746 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003747 *
3748 * Description: Answer the targets Wide nego message.
3749 *
3750 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003751static void FPT_siwidr(ULONG port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752{
3753 ARAM_ACCESS(port);
3754 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3755 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3756 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3757 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3758 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3759 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3760 SGRAM_ACCESS(port);
3761
3762 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3763 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3764
3765 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3766
3767 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3768}
3769
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770
3771
3772/*---------------------------------------------------------------------
3773 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003774 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775 *
3776 * Description: Write the desired value to the Sync Register for the
3777 * ID specified.
3778 *
3779 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003780static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003781 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003783 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784
3785 index = p_id;
3786
3787 switch (index) {
3788
3789 case 0:
3790 index = 12; /* hp_synctarg_0 */
3791 break;
3792 case 1:
3793 index = 13; /* hp_synctarg_1 */
3794 break;
3795 case 2:
3796 index = 14; /* hp_synctarg_2 */
3797 break;
3798 case 3:
3799 index = 15; /* hp_synctarg_3 */
3800 break;
3801 case 4:
3802 index = 8; /* hp_synctarg_4 */
3803 break;
3804 case 5:
3805 index = 9; /* hp_synctarg_5 */
3806 break;
3807 case 6:
3808 index = 10; /* hp_synctarg_6 */
3809 break;
3810 case 7:
3811 index = 11; /* hp_synctarg_7 */
3812 break;
3813 case 8:
3814 index = 4; /* hp_synctarg_8 */
3815 break;
3816 case 9:
3817 index = 5; /* hp_synctarg_9 */
3818 break;
3819 case 10:
3820 index = 6; /* hp_synctarg_10 */
3821 break;
3822 case 11:
3823 index = 7; /* hp_synctarg_11 */
3824 break;
3825 case 12:
3826 index = 0; /* hp_synctarg_12 */
3827 break;
3828 case 13:
3829 index = 1; /* hp_synctarg_13 */
3830 break;
3831 case 14:
3832 index = 2; /* hp_synctarg_14 */
3833 break;
3834 case 15:
3835 index = 3; /* hp_synctarg_15 */
3836
3837 }
3838
3839 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3840
3841 currTar_Info->TarSyncCtrl = p_sync_value;
3842}
3843
3844
3845/*---------------------------------------------------------------------
3846 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003847 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848 *
3849 * Description: Reset the desired card's SCSI bus.
3850 *
3851 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003852static void FPT_sresb(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003854 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855
3856 PSCCBMgr_tar_info currTar_Info;
3857
3858 WR_HARPOON(port+hp_page_ctrl,
3859 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3860 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3861
3862 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3863
3864 scsiID = RD_HARPOON(port+hp_seltimeout);
3865 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3866 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3867
3868 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3869
3870 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3871
3872 WR_HARPOON(port+hp_seltimeout,scsiID);
3873
3874 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3875
James Bottomley 47b5d692005-04-24 02:38:05 -05003876 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003877
3878 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3879
3880 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3881
3882 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3883 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003884 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
3886 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3887 {
3888 currTar_Info->TarSyncCtrl = 0;
3889 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3890 }
3891
3892 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3893 {
3894 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3895 }
3896
James Bottomley 47b5d692005-04-24 02:38:05 -05003897 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898
James Bottomley 47b5d692005-04-24 02:38:05 -05003899 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900 }
3901
James Bottomley 47b5d692005-04-24 02:38:05 -05003902 FPT_BL_Card[p_card].scanIndex = 0x00;
3903 FPT_BL_Card[p_card].currentSCCB = NULL;
3904 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003905 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003906 FPT_BL_Card[p_card].cmdCounter = 0x00;
3907 FPT_BL_Card[p_card].discQCount = 0x00;
3908 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909
3910 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003911 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912
3913 WR_HARPOON(port+hp_page_ctrl,
3914 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3915
3916}
3917
3918/*---------------------------------------------------------------------
3919 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003920 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003921 *
3922 * Description: Setup for the Auto Sense command.
3923 *
3924 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003925static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003927 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928 PSCCB currSCCB;
3929
3930 currSCCB = pCurrCard->currentSCCB;
3931
3932
3933 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3934
3935 for (i = 0; i < 6; i++) {
3936
3937 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3938 }
3939
3940 currSCCB->CdbLength = SIX_BYTE_CMD;
3941 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003942 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943 currSCCB->Cdb[2] = 0x00;
3944 currSCCB->Cdb[3] = 0x00;
3945 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3946 currSCCB->Cdb[5] = 0x00;
3947
3948 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3949
3950 currSCCB->Sccb_ATC = 0x00;
3951
3952 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3953
3954 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3955
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003956 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003957
3958 currSCCB->ControlByte = 0x00;
3959
3960 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3961}
3962
3963
3964
3965/*---------------------------------------------------------------------
3966 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003967 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968 *
3969 * Description: Transfer data into the bit bucket until the device
3970 * decides to switch phase.
3971 *
3972 *---------------------------------------------------------------------*/
3973
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003974static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003976 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977
3978
3979 DISABLE_AUTO(p_port);
3980
James Bottomley 47b5d692005-04-24 02:38:05 -05003981 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982
James Bottomley 47b5d692005-04-24 02:38:05 -05003983 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984
3985 }
3986
3987 /* If the Automation handled the end of the transfer then do not
3988 match the phase or we will get out of sync with the ISR. */
3989
3990 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3991 return;
3992
3993 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3994
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003995 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003996
3997 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3998
3999
4000 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4001
4002 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004003 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004005 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004006 {
4007 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4008
4009 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4010 {
4011 RD_HARPOON(p_port+hp_fifodata_0);
4012 }
4013 }
4014 else
4015 {
4016 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4017 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4018 {
4019 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4020 }
4021 }
4022 } /* End of While loop for padding data I/O phase */
4023
4024 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4025 {
4026 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4027 break;
4028 }
4029
4030 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4031 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4032 {
4033 RD_HARPOON(p_port+hp_fifodata_0);
4034 }
4035
4036 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4037 {
4038 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4039 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4040
4041 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4042 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4043 }
4044}
4045
4046
4047/*---------------------------------------------------------------------
4048 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004049 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050 *
4051 * Description: Make sure data has been flushed from both FIFOs and abort
4052 * the operations if necessary.
4053 *
4054 *---------------------------------------------------------------------*/
4055
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004056static void FPT_schkdd(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004058 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004059 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004060
4061 PSCCB currSCCB;
4062
James Bottomley 47b5d692005-04-24 02:38:05 -05004063 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064
4065
4066 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4067 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4068 return;
4069 }
4070
4071
4072
4073 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4074 {
4075
4076 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4077
4078 currSCCB->Sccb_XferCnt = 1;
4079
4080 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004081 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082 WR_HARPOON(port+hp_xferstat, 0x00);
4083 }
4084
4085 else
4086 {
4087
4088 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4089
4090 currSCCB->Sccb_XferCnt = 0;
4091 }
4092
4093 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4094 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4095
4096 currSCCB->HostStatus = SCCB_PARITY_ERR;
4097 WRW_HARPOON((port+hp_intstat), PARITY);
4098 }
4099
4100
James Bottomley 47b5d692005-04-24 02:38:05 -05004101 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102
4103
4104 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4105
4106 TimeOutLoop = 0;
4107
4108 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4109 {
4110 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4111 return;
4112 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004113 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 break;
4115 }
4116 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4117 return;
4118 }
4119 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4120 break;
4121 }
4122
4123 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4124 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004125 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4127 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4128 {
4129
4130 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4131
4132 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4133 {
4134 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004135 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 }
4137
4138 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004139 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004140 }
4141 }
4142 else
4143 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004144 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004145 if (!(RDW_HARPOON((port+hp_intstat)) &
4146 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4147 {
4148 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004149 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150 }
4151 }
4152
4153 }
4154
4155 else {
4156 WR_HARPOON(port+hp_portctrl_0, 0x00);
4157 }
4158}
4159
4160
4161/*---------------------------------------------------------------------
4162 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004163 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164 *
4165 * Description: Setup SCCB manager fields in this SCCB.
4166 *
4167 *---------------------------------------------------------------------*/
4168
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004169static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004170{
4171 PSCCBMgr_tar_info currTar_Info;
4172
4173 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4174 {
4175 return;
4176 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004177 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004178
4179 p_sccb->Sccb_XferState = 0x00;
4180 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4181
4182 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4183 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4184
4185 p_sccb->Sccb_SGoffset = 0;
4186 p_sccb->Sccb_XferState = F_SG_XFER;
4187 p_sccb->Sccb_XferCnt = 0x00;
4188 }
4189
4190 if (p_sccb->DataLength == 0x00)
4191
4192 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4193
4194 if (p_sccb->ControlByte & F_USE_CMD_Q)
4195 {
4196 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4197 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4198
4199 else
4200 currTar_Info->TarStatus |= TAG_Q_TRYING;
4201 }
4202
4203/* For !single SCSI device in system & device allow Disconnect
4204 or command is tag_q type then send Cmd with Disconnect Enable
4205 else send Cmd with Disconnect Disable */
4206
4207/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004208 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4210 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4211*/
4212 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4213 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004214 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004215 }
4216
4217 else {
4218
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004219 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004220 }
4221
4222 p_sccb->HostStatus = 0x00;
4223 p_sccb->TargetStatus = 0x00;
4224 p_sccb->Sccb_tag = 0x00;
4225 p_sccb->Sccb_MGRFlags = 0x00;
4226 p_sccb->Sccb_sgseg = 0x00;
4227 p_sccb->Sccb_ATC = 0x00;
4228 p_sccb->Sccb_savedATC = 0x00;
4229/*
4230 p_sccb->SccbVirtDataPtr = 0x00;
4231 p_sccb->Sccb_forwardlink = NULL;
4232 p_sccb->Sccb_backlink = NULL;
4233 */
4234 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4235 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4236 p_sccb->Sccb_scsimsg = SMNO_OP;
4237
4238}
4239
4240
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241/*---------------------------------------------------------------------
4242 *
4243 * Function: Phase Decode
4244 *
4245 * Description: Determine the phase and call the appropriate function.
4246 *
4247 *---------------------------------------------------------------------*/
4248
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004249static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250{
4251 unsigned char phase_ref;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004252 void (*phase) (ULONG, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004253
4254
4255 DISABLE_AUTO(p_port);
4256
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004257 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258
James Bottomley 47b5d692005-04-24 02:38:05 -05004259 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004260
4261 (*phase)(p_port, p_card); /* Call the correct phase func */
4262}
4263
4264
4265
4266/*---------------------------------------------------------------------
4267 *
4268 * Function: Data Out Phase
4269 *
4270 * Description: Start up both the BusMaster and Xbow.
4271 *
4272 *---------------------------------------------------------------------*/
4273
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004274static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004275{
4276
4277 PSCCB currSCCB;
4278
James Bottomley 47b5d692005-04-24 02:38:05 -05004279 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004280 if (currSCCB == NULL)
4281 {
4282 return; /* Exit if No SCCB record */
4283 }
4284
4285 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4286 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4287
4288 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4289
4290 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4291
4292 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4293
James Bottomley 47b5d692005-04-24 02:38:05 -05004294 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295
4296 if (currSCCB->Sccb_XferCnt == 0) {
4297
4298
4299 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4300 (currSCCB->HostStatus == SCCB_COMPLETE))
4301 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4302
James Bottomley 47b5d692005-04-24 02:38:05 -05004303 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004305 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306 }
4307}
4308
4309
4310/*---------------------------------------------------------------------
4311 *
4312 * Function: Data In Phase
4313 *
4314 * Description: Startup the BusMaster and the XBOW.
4315 *
4316 *---------------------------------------------------------------------*/
4317
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004318static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319{
4320
4321 PSCCB currSCCB;
4322
James Bottomley 47b5d692005-04-24 02:38:05 -05004323 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324
4325 if (currSCCB == NULL)
4326 {
4327 return; /* Exit if No SCCB record */
4328 }
4329
4330
4331 currSCCB->Sccb_scsistat = DATA_IN_ST;
4332 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4333 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4334
4335 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4336
4337 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4338
4339 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4340
James Bottomley 47b5d692005-04-24 02:38:05 -05004341 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342
4343 if (currSCCB->Sccb_XferCnt == 0) {
4344
4345
4346 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4347 (currSCCB->HostStatus == SCCB_COMPLETE))
4348 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4349
James Bottomley 47b5d692005-04-24 02:38:05 -05004350 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004352 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353
4354 }
4355}
4356
4357/*---------------------------------------------------------------------
4358 *
4359 * Function: Command Phase
4360 *
4361 * Description: Load the CDB into the automation and start it up.
4362 *
4363 *---------------------------------------------------------------------*/
4364
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004365static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004366{
4367 PSCCB currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368 ULONG cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004369 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370
James Bottomley 47b5d692005-04-24 02:38:05 -05004371 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004372
4373 if (currSCCB->OperationCode == RESET_COMMAND) {
4374
4375 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4376 currSCCB->CdbLength = SIX_BYTE_CMD;
4377 }
4378
4379 WR_HARPOON(p_port+hp_scsisig, 0x00);
4380
4381 ARAM_ACCESS(p_port);
4382
4383
4384 cdb_reg = p_port + CMD_STRT;
4385
4386 for (i=0; i < currSCCB->CdbLength; i++) {
4387
4388 if (currSCCB->OperationCode == RESET_COMMAND)
4389
4390 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4391
4392 else
4393 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4394 cdb_reg +=2;
4395 }
4396
4397 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4398 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4399
4400 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4401
4402 currSCCB->Sccb_scsistat = COMMAND_ST;
4403
4404 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4405 SGRAM_ACCESS(p_port);
4406}
4407
4408
4409/*---------------------------------------------------------------------
4410 *
4411 * Function: Status phase
4412 *
4413 * Description: Bring in the status and command complete message bytes
4414 *
4415 *---------------------------------------------------------------------*/
4416
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004417static void FPT_phaseStatus(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418{
4419 /* Start-up the automation to finish off this command and let the
4420 isr handle the interrupt for command complete when it comes in.
4421 We could wait here for the interrupt to be generated?
4422 */
4423
4424 WR_HARPOON(port+hp_scsisig, 0x00);
4425
4426 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4427}
4428
4429
4430/*---------------------------------------------------------------------
4431 *
4432 * Function: Phase Message Out
4433 *
4434 * Description: Send out our message (if we have one) and handle whatever
4435 * else is involed.
4436 *
4437 *---------------------------------------------------------------------*/
4438
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004439static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004441 unsigned char message,scsiID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442 PSCCB currSCCB;
4443 PSCCBMgr_tar_info currTar_Info;
4444
James Bottomley 47b5d692005-04-24 02:38:05 -05004445 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446
4447 if (currSCCB != NULL) {
4448
4449 message = currSCCB->Sccb_scsimsg;
4450 scsiID = currSCCB->TargID;
4451
4452 if (message == SMDEV_RESET)
4453 {
4454
4455
James Bottomley 47b5d692005-04-24 02:38:05 -05004456 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004458 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459
James Bottomley 47b5d692005-04-24 02:38:05 -05004460 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461 {
4462
James Bottomley 47b5d692005-04-24 02:38:05 -05004463 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464
4465 }
4466
James Bottomley 47b5d692005-04-24 02:38:05 -05004467 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468 {
4469
James Bottomley 47b5d692005-04-24 02:38:05 -05004470 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 }
4472
4473
James Bottomley 47b5d692005-04-24 02:38:05 -05004474 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4475 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004476 }
4477 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4478 {
4479 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004480 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004481 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004482 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4483 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 }
4485
4486 }
4487
4488 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4489 {
4490
4491
4492 if(message == SMNO_OP)
4493 {
4494 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4495
James Bottomley 47b5d692005-04-24 02:38:05 -05004496 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 return;
4498 }
4499 }
4500 else
4501 {
4502
4503
4504 if (message == SMABORT)
4505
James Bottomley 47b5d692005-04-24 02:38:05 -05004506 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004507 }
4508
4509 }
4510 else
4511 {
4512 message = SMABORT;
4513 }
4514
4515 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4516
4517
4518 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4519
4520 WR_HARPOON(port+hp_scsidata_0,message);
4521
4522 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4523
4524 ACCEPT_MSG(port);
4525
4526 WR_HARPOON(port+hp_portctrl_0, 0x00);
4527
4528 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4529 (message == SMABORT_TAG) )
4530 {
4531
4532 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4533
4534 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4535 {
4536 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4537
4538 if (currSCCB != NULL)
4539 {
4540
James Bottomley 47b5d692005-04-24 02:38:05 -05004541 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4542 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4543 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004545 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546
James Bottomley 47b5d692005-04-24 02:38:05 -05004547 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548 }
4549
4550 else
4551 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004552 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004553 }
4554 }
4555
4556 else
4557 {
4558
James Bottomley 47b5d692005-04-24 02:38:05 -05004559 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560 }
4561 }
4562
4563 else
4564 {
4565
4566 if(message == SMPARITY)
4567 {
4568 currSCCB->Sccb_scsimsg = SMNO_OP;
4569 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4570 }
4571 else
4572 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004573 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004574 }
4575 }
4576}
4577
4578
4579/*---------------------------------------------------------------------
4580 *
4581 * Function: Message In phase
4582 *
4583 * Description: Bring in the message and determine what to do with it.
4584 *
4585 *---------------------------------------------------------------------*/
4586
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004587static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004589 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004590 PSCCB currSCCB;
4591
James Bottomley 47b5d692005-04-24 02:38:05 -05004592 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593
James Bottomley 47b5d692005-04-24 02:38:05 -05004594 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595 {
4596
James Bottomley 47b5d692005-04-24 02:38:05 -05004597 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598 }
4599
4600 message = RD_HARPOON(port+hp_scsidata_0);
4601 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4602 {
4603
4604 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4605
4606 }
4607
4608 else
4609 {
4610
James Bottomley 47b5d692005-04-24 02:38:05 -05004611 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004612 if (message)
4613 {
4614
4615
James Bottomley 47b5d692005-04-24 02:38:05 -05004616 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004617
4618 }
4619 else
4620 {
4621 if(currSCCB->Sccb_scsimsg != SMPARITY)
4622 ACCEPT_MSG(port);
4623 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4624 }
4625 }
4626
4627}
4628
4629
4630/*---------------------------------------------------------------------
4631 *
4632 * Function: Illegal phase
4633 *
4634 * Description: Target switched to some illegal phase, so all we can do
4635 * is report an error back to the host (if that is possible)
4636 * and send an ABORT message to the misbehaving target.
4637 *
4638 *---------------------------------------------------------------------*/
4639
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004640static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004641{
4642 PSCCB currSCCB;
4643
James Bottomley 47b5d692005-04-24 02:38:05 -05004644 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004645
4646 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4647 if (currSCCB != NULL) {
4648
4649 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4650 currSCCB->Sccb_scsistat = ABORT_ST;
4651 currSCCB->Sccb_scsimsg = SMABORT;
4652 }
4653
4654 ACCEPT_MSG_ATN(port);
4655}
4656
4657
4658
4659/*---------------------------------------------------------------------
4660 *
4661 * Function: Phase Check FIFO
4662 *
4663 * Description: Make sure data has been flushed from both FIFOs and abort
4664 * the operations if necessary.
4665 *
4666 *---------------------------------------------------------------------*/
4667
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004668static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669{
4670 ULONG xfercnt;
4671 PSCCB currSCCB;
4672
James Bottomley 47b5d692005-04-24 02:38:05 -05004673 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004674
4675 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4676 {
4677
4678 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4679 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4680
4681
4682 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4683 {
4684 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4685
4686 currSCCB->Sccb_XferCnt = 0;
4687
4688 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4689 (currSCCB->HostStatus == SCCB_COMPLETE))
4690 {
4691 currSCCB->HostStatus = SCCB_PARITY_ERR;
4692 WRW_HARPOON((port+hp_intstat), PARITY);
4693 }
4694
James Bottomley 47b5d692005-04-24 02:38:05 -05004695 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004696
James Bottomley 47b5d692005-04-24 02:38:05 -05004697 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004698
4699 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4700 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4701
4702 }
4703 } /*End Data In specific code. */
4704
4705
4706
Linus Torvalds1da177e2005-04-16 15:20:36 -07004707 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004708
4709
4710 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4711
4712
4713 WR_HARPOON(port+hp_portctrl_0, 0x00);
4714
4715 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4716
4717 currSCCB->Sccb_XferCnt = xfercnt;
4718
4719 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4720 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4721
4722 currSCCB->HostStatus = SCCB_PARITY_ERR;
4723 WRW_HARPOON((port+hp_intstat), PARITY);
4724 }
4725
4726
James Bottomley 47b5d692005-04-24 02:38:05 -05004727 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004728
4729
4730 WR_HARPOON(port+hp_fifowrite, 0x00);
4731 WR_HARPOON(port+hp_fiforead, 0x00);
4732 WR_HARPOON(port+hp_xferstat, 0x00);
4733
4734 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4735}
4736
4737
4738/*---------------------------------------------------------------------
4739 *
4740 * Function: Phase Bus Free
4741 *
4742 * Description: We just went bus free so figure out if it was
4743 * because of command complete or from a disconnect.
4744 *
4745 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004746static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004747{
4748 PSCCB currSCCB;
4749
James Bottomley 47b5d692005-04-24 02:38:05 -05004750 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004751
4752 if (currSCCB != NULL)
4753 {
4754
4755 DISABLE_AUTO(port);
4756
4757
4758 if (currSCCB->OperationCode == RESET_COMMAND)
4759 {
4760
James Bottomley 47b5d692005-04-24 02:38:05 -05004761 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4762 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004764 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004766
James Bottomley 47b5d692005-04-24 02:38:05 -05004767 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004768
James Bottomley 47b5d692005-04-24 02:38:05 -05004769 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004770
4771 }
4772
4773 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4774 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004775 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004776 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778 }
4779
4780 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4781 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004782 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4783 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004784 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4785
James Bottomley 47b5d692005-04-24 02:38:05 -05004786 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004787 }
4788
Linus Torvalds1da177e2005-04-16 15:20:36 -07004789 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4790 {
4791 /* Make sure this is not a phony BUS_FREE. If we were
4792 reselected or if BUSY is NOT on then this is a
4793 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4794
4795 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4796 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4797 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004798 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4799 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004800 }
4801
4802 else
4803 {
4804 return;
4805 }
4806 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004807
4808 else
4809 {
4810
4811 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4812
4813 if (!currSCCB->HostStatus)
4814 {
4815 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4816 }
4817
James Bottomley 47b5d692005-04-24 02:38:05 -05004818 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4819 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4820 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004821 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004822 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823
James Bottomley 47b5d692005-04-24 02:38:05 -05004824 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825 return;
4826 }
4827
4828
James Bottomley 47b5d692005-04-24 02:38:05 -05004829 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004830
4831 } /*end if !=null */
4832}
4833
4834
4835
4836
Linus Torvalds1da177e2005-04-16 15:20:36 -07004837/*---------------------------------------------------------------------
4838 *
4839 * Function: Auto Load Default Map
4840 *
4841 * Description: Load the Automation RAM with the defualt map values.
4842 *
4843 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004844static void FPT_autoLoadDefaultMap(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004845{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004846 ULONG map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004847
4848 ARAM_ACCESS(p_port);
4849 map_addr = p_port + hp_aramBase;
4850
4851 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4852 map_addr +=2;
4853 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4886 map_addr +=2; /*This means AYNC DATA IN */
4887 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4888 map_addr +=2;
4889 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4910 map_addr +=2;
4911 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4912 map_addr +=2;
4913 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4920 map_addr +=2;
4921 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4922 map_addr +=2;
4923
4924 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4925 map_addr +=2;
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4927 map_addr +=2;
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4929 map_addr +=2;
4930 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4931 map_addr +=2; /* DIDN'T GET ONE */
4932 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4933 map_addr +=2;
4934 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4935 map_addr +=2;
4936 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4937
4938
4939
4940 SGRAM_ACCESS(p_port);
4941}
4942
4943/*---------------------------------------------------------------------
4944 *
4945 * Function: Auto Command Complete
4946 *
4947 * Description: Post command back to host and find another command
4948 * to execute.
4949 *
4950 *---------------------------------------------------------------------*/
4951
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004952static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004953{
4954 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004955 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004956
James Bottomley 47b5d692005-04-24 02:38:05 -05004957 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004958
4959 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4960
James Bottomley 47b5d692005-04-24 02:38:05 -05004961 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004962
4963 if (status_byte != SSGOOD) {
4964
4965 if (status_byte == SSQ_FULL) {
4966
4967
James Bottomley 47b5d692005-04-24 02:38:05 -05004968 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4969 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004970 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004971 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4972 if(FPT_BL_Card[p_card].discQCount != 0)
4973 FPT_BL_Card[p_card].discQCount--;
4974 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 -07004975 }
4976 else
4977 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004978 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004979 if(currSCCB->Sccb_tag)
4980 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004981 if(FPT_BL_Card[p_card].discQCount != 0)
4982 FPT_BL_Card[p_card].discQCount--;
4983 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004984 }else
4985 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004986 if(FPT_BL_Card[p_card].discQCount != 0)
4987 FPT_BL_Card[p_card].discQCount--;
4988 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004989 }
4990 }
4991
4992 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4993
James Bottomley 47b5d692005-04-24 02:38:05 -05004994 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004995
4996 return;
4997 }
4998
4999 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5000 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005001 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005002 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005003
James Bottomley 47b5d692005-04-24 02:38:05 -05005004 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5005 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005006
James Bottomley 47b5d692005-04-24 02:38:05 -05005007 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5008 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005009 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005010 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5011 if(FPT_BL_Card[p_card].discQCount != 0)
5012 FPT_BL_Card[p_card].discQCount--;
5013 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 -07005014 }
5015 else
5016 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005017 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005018 if(currSCCB->Sccb_tag)
5019 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005020 if(FPT_BL_Card[p_card].discQCount != 0)
5021 FPT_BL_Card[p_card].discQCount--;
5022 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005023 }else
5024 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005025 if(FPT_BL_Card[p_card].discQCount != 0)
5026 FPT_BL_Card[p_card].discQCount--;
5027 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005028 }
5029 }
5030 return;
5031
5032 }
5033
5034 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5035 {
5036
James Bottomley 47b5d692005-04-24 02:38:05 -05005037 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5038 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005039 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5040
James Bottomley 47b5d692005-04-24 02:38:05 -05005041 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5042 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005043
James Bottomley 47b5d692005-04-24 02:38:05 -05005044 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5045 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005046 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005047 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5048 if(FPT_BL_Card[p_card].discQCount != 0)
5049 FPT_BL_Card[p_card].discQCount--;
5050 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 -07005051 }
5052 else
5053 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005054 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005055 if(currSCCB->Sccb_tag)
5056 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005057 if(FPT_BL_Card[p_card].discQCount != 0)
5058 FPT_BL_Card[p_card].discQCount--;
5059 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005060 }else
5061 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005062 if(FPT_BL_Card[p_card].discQCount != 0)
5063 FPT_BL_Card[p_card].discQCount--;
5064 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005065 }
5066 }
5067 return;
5068
5069 }
5070
5071 if (status_byte == SSCHECK)
5072 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005073 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005074 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005075 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005076 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005077 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005078 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005079 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005080 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005081 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005082 }
5083 }
5084 }
5085
5086 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5087
5088 currSCCB->SccbStatus = SCCB_ERROR;
5089 currSCCB->TargetStatus = status_byte;
5090
5091 if (status_byte == SSCHECK) {
5092
James Bottomley 47b5d692005-04-24 02:38:05 -05005093 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5094 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005095
5096
Linus Torvalds1da177e2005-04-16 15:20:36 -07005097 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5098
5099 if (currSCCB->RequestSenseLength == 0)
5100 currSCCB->RequestSenseLength = 14;
5101
James Bottomley 47b5d692005-04-24 02:38:05 -05005102 FPT_ssenss(&FPT_BL_Card[p_card]);
5103 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005104
James Bottomley 47b5d692005-04-24 02:38:05 -05005105 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5106 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005107 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005108 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5109 if(FPT_BL_Card[p_card].discQCount != 0)
5110 FPT_BL_Card[p_card].discQCount--;
5111 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 -07005112 }
5113 else
5114 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005115 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005116 if(currSCCB->Sccb_tag)
5117 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005118 if(FPT_BL_Card[p_card].discQCount != 0)
5119 FPT_BL_Card[p_card].discQCount--;
5120 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005121 }else
5122 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005123 if(FPT_BL_Card[p_card].discQCount != 0)
5124 FPT_BL_Card[p_card].discQCount--;
5125 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005126 }
5127 }
5128 return;
5129 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005130 }
5131 }
5132 }
5133
5134
James Bottomley 47b5d692005-04-24 02:38:05 -05005135 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5136 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5137 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005138 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005139 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005140
5141
James Bottomley 47b5d692005-04-24 02:38:05 -05005142 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005143}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005144
5145#define SHORT_WAIT 0x0000000F
5146#define LONG_WAIT 0x0000FFFFL
5147
Linus Torvalds1da177e2005-04-16 15:20:36 -07005148
5149/*---------------------------------------------------------------------
5150 *
5151 * Function: Data Transfer Processor
5152 *
5153 * Description: This routine performs two tasks.
5154 * (1) Start data transfer by calling HOST_DATA_XFER_START
5155 * function. Once data transfer is started, (2) Depends
5156 * on the type of data transfer mode Scatter/Gather mode
5157 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5158 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5159 * data transfer done. In Scatter/Gather mode, this routine
5160 * checks bus master command complete and dual rank busy
5161 * bit to keep chaining SC transfer command. Similarly,
5162 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5163 * (F_HOST_XFER_ACT bit) for data transfer done.
5164 *
5165 *---------------------------------------------------------------------*/
5166
James Bottomley 47b5d692005-04-24 02:38:05 -05005167static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005168{
5169 PSCCB currSCCB;
5170
5171 currSCCB = pCurrCard->currentSCCB;
5172
5173 if (currSCCB->Sccb_XferState & F_SG_XFER)
5174 {
5175 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5176
5177 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005178 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005179 currSCCB->Sccb_SGoffset = 0x00;
5180 }
5181 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5182
James Bottomley 47b5d692005-04-24 02:38:05 -05005183 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005184 }
5185
5186 else
5187 {
5188 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5189 {
5190 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5191
James Bottomley 47b5d692005-04-24 02:38:05 -05005192 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005193 }
5194 }
5195}
5196
5197
5198/*---------------------------------------------------------------------
5199 *
5200 * Function: BusMaster Scatter Gather Data Transfer Start
5201 *
5202 * Description:
5203 *
5204 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005205static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005206{
5207 ULONG count,addr,tmpSGCnt;
5208 UINT sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005209 unsigned char sg_count, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005210 ULONG reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005211
5212
5213 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5214
5215 count = ((ULONG) HOST_RD_CMD)<<24;
5216 }
5217
5218 else {
5219 count = ((ULONG) HOST_WRT_CMD)<<24;
5220 }
5221
5222 sg_count = 0;
5223 tmpSGCnt = 0;
5224 sg_index = pcurrSCCB->Sccb_sgseg;
5225 reg_offset = hp_aramBase;
5226
5227
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005228 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229
5230
5231 WR_HARPOON(p_port+hp_page_ctrl, i);
5232
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005233 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5235
Linus Torvalds1da177e2005-04-16 15:20:36 -07005236 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5237 (sg_index * 2));
5238
5239 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5240 (sg_index * 2));
5241
5242 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5243 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005244
5245
5246 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5247
5248 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5249 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5250
5251 tmpSGCnt = count & 0x00FFFFFFL;
5252 }
5253
5254 WR_HARP32(p_port,reg_offset,addr);
5255 reg_offset +=4;
5256
5257 WR_HARP32(p_port,reg_offset,count);
5258 reg_offset +=4;
5259
5260 count &= 0xFF000000L;
5261 sg_index++;
5262 sg_count++;
5263
5264 } /*End While */
5265
5266 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5267
5268 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5269
5270 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5271
5272 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5273
5274
5275 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5276 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5277 }
5278
5279 else {
5280
5281
5282 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5283 (tmpSGCnt & 0x000000001))
5284 {
5285
5286 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5287 tmpSGCnt--;
5288 }
5289
5290
5291 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5292
5293 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5294 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5295 }
5296
5297
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005298 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005299
5300}
5301
5302
5303/*---------------------------------------------------------------------
5304 *
5305 * Function: BusMaster Data Transfer Start
5306 *
5307 * Description:
5308 *
5309 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005310static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005311{
5312 ULONG addr,count;
5313
5314 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5315
5316 count = pcurrSCCB->Sccb_XferCnt;
5317
5318 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5319 }
5320
5321 else {
5322 addr = pcurrSCCB->SensePointer;
5323 count = pcurrSCCB->RequestSenseLength;
5324
5325 }
5326
Linus Torvalds1da177e2005-04-16 15:20:36 -07005327 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005328
5329
5330 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5331
5332 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5333 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5334
5335 WR_HARPOON(p_port+hp_xfer_cmd,
5336 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5337 }
5338
5339 else {
5340
5341 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5342 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5343
5344 WR_HARPOON(p_port+hp_xfer_cmd,
5345 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5346
5347 }
5348}
5349
5350
5351/*---------------------------------------------------------------------
5352 *
5353 * Function: BusMaster Timeout Handler
5354 *
5355 * Description: This function is called after a bus master command busy time
5356 * out is detected. This routines issue halt state machine
5357 * with a software time out for command busy. If command busy
5358 * is still asserted at the end of the time out, it issues
5359 * hard abort with another software time out. It hard abort
5360 * command busy is also time out, it'll just give up.
5361 *
5362 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005363static unsigned char FPT_busMstrTimeOut(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364{
5365 ULONG timeout;
5366
5367 timeout = LONG_WAIT;
5368
5369 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5370
5371 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5372
5373
5374
5375 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5376 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5377
5378 timeout = LONG_WAIT;
5379 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5380 }
5381
5382 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5383
5384 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005385 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005386 }
5387
5388 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005389 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005390 }
5391}
5392
5393
5394/*---------------------------------------------------------------------
5395 *
5396 * Function: Host Data Transfer Abort
5397 *
5398 * Description: Abort any in progress transfer.
5399 *
5400 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005401static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005402{
5403
5404 ULONG timeout;
5405 ULONG remain_cnt;
5406 UINT sg_ptr;
5407
James Bottomley 47b5d692005-04-24 02:38:05 -05005408 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005409
5410 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5411
5412
5413 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5414
5415 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5416 timeout = LONG_WAIT;
5417
5418 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5419
5420 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5421
5422 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5423
James Bottomley 47b5d692005-04-24 02:38:05 -05005424 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005425
5426 if (pCurrSCCB->HostStatus == 0x00)
5427
5428 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5429
5430 }
5431
5432 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5433
5434 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5435
5436 if (pCurrSCCB->HostStatus == 0x00)
5437
5438 {
5439 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005440 }
5441 }
5442 }
5443 }
5444
5445 else if (pCurrSCCB->Sccb_XferCnt) {
5446
5447 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5448
5449
5450 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5451 ~SCATTER_EN));
5452
5453 WR_HARPOON(port+hp_sg_addr,0x00);
5454
5455 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5456
5457 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5458
5459 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5460 }
5461
5462 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5463
5464 while (remain_cnt < 0x01000000L) {
5465
5466 sg_ptr--;
5467
Linus Torvalds1da177e2005-04-16 15:20:36 -07005468 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5469 DataPointer) + (sg_ptr * 2)))) {
5470
5471 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5472 DataPointer) + (sg_ptr * 2)));
5473 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005474
5475 else {
5476
5477 break;
5478 }
5479 }
5480
5481
5482
5483 if (remain_cnt < 0x01000000L) {
5484
5485
5486 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5487
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005488 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005489
5490
5491 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5492 && (remain_cnt == 0))
5493
5494 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5495 }
5496
5497 else {
5498
5499
5500 if (pCurrSCCB->HostStatus == 0x00) {
5501
5502 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5503 }
5504 }
5505 }
5506
5507
5508 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5509
5510
5511 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5512
James Bottomley 47b5d692005-04-24 02:38:05 -05005513 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005514 }
5515
5516 else {
5517
5518 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5519
5520 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5521
5522 if (pCurrSCCB->HostStatus == 0x00) {
5523
5524 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005525 }
5526 }
5527 }
5528
5529 }
5530 }
5531
5532 else {
5533
5534
5535 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5536
5537 timeout = SHORT_WAIT;
5538
5539 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5540 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5541 timeout--) {}
5542 }
5543
5544 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5545
5546 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5547 FLUSH_XFER_CNTR));
5548
5549 timeout = LONG_WAIT;
5550
5551 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5552 timeout--) {}
5553
5554 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5555 ~FLUSH_XFER_CNTR));
5556
5557
5558 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5559
5560 if (pCurrSCCB->HostStatus == 0x00) {
5561
5562 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5563 }
5564
James Bottomley 47b5d692005-04-24 02:38:05 -05005565 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005566 }
5567 }
5568
5569 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5570
5571 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5572
5573 if (pCurrSCCB->HostStatus == 0x00) {
5574
5575 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005576 }
5577 }
5578 }
5579 }
5580
5581 }
5582
5583 else {
5584
5585
5586 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5587
5588 timeout = LONG_WAIT;
5589
5590 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5591
5592 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5593
5594 if (pCurrSCCB->HostStatus == 0x00) {
5595
5596 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5597 }
5598
James Bottomley 47b5d692005-04-24 02:38:05 -05005599 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005600 }
5601 }
5602
5603
5604 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5605
5606 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5607
5608 if (pCurrSCCB->HostStatus == 0x00) {
5609
5610 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005611 }
5612 }
5613
5614 }
5615
5616 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5617
5618 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5619 ~SCATTER_EN));
5620
5621 WR_HARPOON(port+hp_sg_addr,0x00);
5622
5623 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5624
5625 pCurrSCCB->Sccb_SGoffset = 0x00;
5626
5627
5628 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5629 pCurrSCCB->DataLength) {
5630
5631 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5632
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005633 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005634
5635 }
5636 }
5637
5638 else {
5639
5640 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5641
5642 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5643 }
5644 }
5645
5646 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5647}
5648
5649
5650
5651/*---------------------------------------------------------------------
5652 *
5653 * Function: Host Data Transfer Restart
5654 *
5655 * Description: Reset the available count due to a restore data
5656 * pointers message.
5657 *
5658 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005659static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005660{
5661 ULONG data_count;
5662 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005663 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664
5665 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5666
5667 currSCCB->Sccb_XferCnt = 0;
5668
5669 sg_index = 0xffff; /*Index by long words into sg list. */
5670 data_count = 0; /*Running count of SG xfer counts. */
5671
Linus Torvalds1da177e2005-04-16 15:20:36 -07005672 sg_ptr = (ULONG *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005673
5674 while (data_count < currSCCB->Sccb_ATC) {
5675
5676 sg_index++;
5677 data_count += *(sg_ptr+(sg_index * 2));
5678 }
5679
5680 if (data_count == currSCCB->Sccb_ATC) {
5681
5682 currSCCB->Sccb_SGoffset = 0;
5683 sg_index++;
5684 }
5685
5686 else {
5687 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5688 }
5689
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005690 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005691 }
5692
5693 else {
5694 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5695 }
5696}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005697
5698
5699
Linus Torvalds1da177e2005-04-16 15:20:36 -07005700/*---------------------------------------------------------------------
5701 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005702 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005703 *
5704 * Description: Setup all data structures necessary for SCAM selection.
5705 *
5706 *---------------------------------------------------------------------*/
5707
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005708static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005709{
5710
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005711 unsigned char loser,assigned_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005712 ULONG p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005714 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005715 PSCCBcard currCard;
5716 PNVRamInfo pCurrNvRam;
5717
James Bottomley 47b5d692005-04-24 02:38:05 -05005718 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005719 p_port = currCard->ioPort;
5720 pCurrNvRam = currCard->pNvRamInfo;
5721
5722
5723 if(pCurrNvRam){
5724 ScamFlg = pCurrNvRam->niScamConf;
5725 i = pCurrNvRam->niSysConf;
5726 }
5727 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005728 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5729 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005730 }
5731 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5732 return;
5733
James Bottomley 47b5d692005-04-24 02:38:05 -05005734 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005735
5736 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5737 too slow to return to SCAM selection */
5738
5739 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005740 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005741 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005742 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005743
James Bottomley 47b5d692005-04-24 02:38:05 -05005744 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005745
5746 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5747 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005748 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005749
James Bottomley 47b5d692005-04-24 02:38:05 -05005750 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005751
5752 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005753 FPT_scxferc(p_port,SYNC_PTRN);
5754 FPT_scxferc(p_port,DOM_MSTR);
5755 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756 } while ( loser == 0xFF );
5757
James Bottomley 47b5d692005-04-24 02:38:05 -05005758 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759
5760 if ((p_power_up) && (!loser))
5761 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005762 FPT_sresb(p_port,p_card);
5763 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005764
James Bottomley 47b5d692005-04-24 02:38:05 -05005765 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005766
James Bottomley 47b5d692005-04-24 02:38:05 -05005767 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005768
5769 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005770 FPT_scxferc(p_port, SYNC_PTRN);
5771 FPT_scxferc(p_port, DOM_MSTR);
5772 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005773 id_string[0]);
5774 } while ( loser == 0xFF );
5775
James Bottomley 47b5d692005-04-24 02:38:05 -05005776 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005777 }
5778 }
5779
5780 else
5781 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005782 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005783 }
5784
5785
5786 if (!loser)
5787 {
5788
James Bottomley 47b5d692005-04-24 02:38:05 -05005789 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005790
5791
5792 if (ScamFlg & SCAM_ENABLED)
5793 {
5794
5795 for (i=0; i < MAX_SCSI_TAR; i++)
5796 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005797 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5798 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005799 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005800 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005801 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005802 FPT_scamInfo[i].state = LEGACY;
5803 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5804 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005805 {
5806
James Bottomley 47b5d692005-04-24 02:38:05 -05005807 FPT_scamInfo[i].id_string[0] = 0xFF;
5808 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005809 if(pCurrNvRam == NULL)
5810 currCard->globalFlags |= F_UPDATE_EEPROM;
5811 }
5812 }
5813 }
5814 }
5815
James Bottomley 47b5d692005-04-24 02:38:05 -05005816 FPT_sresb(p_port,p_card);
5817 FPT_Wait1Second(p_port);
5818 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5819 FPT_scsel(p_port);
5820 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821 }
5822
Linus Torvalds1da177e2005-04-16 15:20:36 -07005823 }
5824
5825 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5826 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005827 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5828 assigned_id = 0;
5829 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005830
5831 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005832 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833
James Bottomley 47b5d692005-04-24 02:38:05 -05005834 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835 if (i == ASSIGN_ID)
5836 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005837 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005838 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005839 i = FPT_scxferc(p_port,0x00);
5840 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005842 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843
James Bottomley 47b5d692005-04-24 02:38:05 -05005844 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005845 {
5846 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005847 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005848 FPT_inisci(p_card, p_port, p_our_id);
5849 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5850 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005852 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 }
5854 }
5855 }
5856 }
5857
5858 else if (i == SET_P_FLAG)
5859 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005860 if (!(FPT_scsendi(p_port,
5861 &FPT_scamInfo[p_our_id].id_string[0])))
5862 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 }
5864 }while (!assigned_id);
5865
James Bottomley 47b5d692005-04-24 02:38:05 -05005866 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005867 }
5868
Linus Torvalds1da177e2005-04-16 15:20:36 -07005869 if (ScamFlg & SCAM_ENABLED)
5870 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005871 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005872 if (currCard->globalFlags & F_UPDATE_EEPROM)
5873 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005874 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005875 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5876 }
5877 }
5878
5879
Linus Torvalds1da177e2005-04-16 15:20:36 -07005880/*
5881 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5882 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005883 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5884 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005885 k++;
5886 }
5887
5888 if (k==2)
5889 currCard->globalFlags |= F_SINGLE_DEVICE;
5890 else
5891 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5892*/
5893}
5894
5895
5896/*---------------------------------------------------------------------
5897 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005898 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005899 *
5900 * Description: Gain control of the bus and wait SCAM select time (250ms)
5901 *
5902 *---------------------------------------------------------------------*/
5903
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005904static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005905{
5906 if (p_sel_type == INIT_SELTD)
5907 {
5908
5909 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5910
5911
5912 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005913 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005914
5915 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005916 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005917
5918 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5919
5920 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5921
5922 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5923 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005924 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005925 }
5926
5927
5928 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5929
5930 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5931
5932 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5933 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005934 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005935 }
5936 }
5937
5938
5939 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5940 & ~ACTdeassert));
5941 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5942 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005943 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005944 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5945
5946 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5947
5948 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5949 & ~SCSI_BSY));
5950
James Bottomley 47b5d692005-04-24 02:38:05 -05005951 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005952
James Bottomley 47b5d692005-04-24 02:38:05 -05005953 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954}
5955
5956
5957/*---------------------------------------------------------------------
5958 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005959 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005960 *
5961 * Description: Release the SCSI bus and disable SCAM selection.
5962 *
5963 *---------------------------------------------------------------------*/
5964
James Bottomley 47b5d692005-04-24 02:38:05 -05005965static void FPT_scbusf(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005966{
5967 WR_HARPOON(p_port+hp_page_ctrl,
5968 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5969
5970
5971 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5972
5973 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5974 & ~SCSI_BUS_EN));
5975
5976 WR_HARPOON(p_port+hp_scsisig, 0x00);
5977
5978
5979 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5980 & ~SCAM_EN));
5981
5982 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5983 | ACTdeassert));
5984
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005986
5987 WR_HARPOON(p_port+hp_page_ctrl,
5988 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5989}
5990
5991
5992
5993/*---------------------------------------------------------------------
5994 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005995 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005996 *
5997 * Description: Assign an ID to all the SCAM devices.
5998 *
5999 *---------------------------------------------------------------------*/
6000
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006001static void FPT_scasid(unsigned char p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006002{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006003 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006004
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006005 unsigned char i,k,scam_id;
6006 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006007 PNVRamInfo pCurrNvRam;
6008 ushort_ptr pCrcBytes;
6009
James Bottomley 47b5d692005-04-24 02:38:05 -05006010 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006011
James Bottomley 47b5d692005-04-24 02:38:05 -05006012 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006013
6014 while (!i)
6015 {
6016
6017 for (k=0; k < ID_STRING_LENGTH; k++)
6018 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006019 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006020 }
6021
James Bottomley 47b5d692005-04-24 02:38:05 -05006022 FPT_scxferc(p_port,SYNC_PTRN);
6023 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006024
James Bottomley 47b5d692005-04-24 02:38:05 -05006025 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006026 {
6027 if(pCurrNvRam){
6028 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006029 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6030 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006031 temp_id_string[1] = crcBytes[2];
6032 temp_id_string[2] = crcBytes[0];
6033 temp_id_string[3] = crcBytes[1];
6034 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006035 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006037 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006038
6039 if (i == CLR_PRIORITY)
6040 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006041 FPT_scxferc(p_port,MISC_CODE);
6042 FPT_scxferc(p_port,CLR_P_FLAG);
6043 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006044 }
6045
6046 else if (i != NO_ID_AVAIL)
6047 {
6048 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006049 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006050 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006051 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006052
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006053 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006054
6055
6056 for (k=1; k < 0x08; k <<= 1)
6057 if (!( k & i ))
6058 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6059
James Bottomley 47b5d692005-04-24 02:38:05 -05006060 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006061
James Bottomley 47b5d692005-04-24 02:38:05 -05006062 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006063 }
6064 }
6065
6066 else
6067 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006068 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006069 }
6070
6071 } /*End while */
6072
James Bottomley 47b5d692005-04-24 02:38:05 -05006073 FPT_scxferc(p_port,SYNC_PTRN);
6074 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006075}
6076
6077
6078
6079
6080
6081/*---------------------------------------------------------------------
6082 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006083 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006084 *
6085 * Description: Select all the SCAM devices.
6086 *
6087 *---------------------------------------------------------------------*/
6088
James Bottomley 47b5d692005-04-24 02:38:05 -05006089static void FPT_scsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006090{
6091
6092 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006093 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006094
6095 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6096
6097
6098 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006099 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6100 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006101
6102
6103 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006104 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006105
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006106 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6107 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006108 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006109
6110 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6111}
6112
6113
6114
6115/*---------------------------------------------------------------------
6116 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006117 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006118 *
6119 * Description: Handshake the p_data (DB4-0) across the bus.
6120 *
6121 *---------------------------------------------------------------------*/
6122
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006123static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006124{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006125 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006126
6127 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6128
6129 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6130
6131 curr_data &= ~BIT(7);
6132
6133 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6134
James Bottomley 47b5d692005-04-24 02:38:05 -05006135 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006136 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6137
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006138 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006139
6140 curr_data |= BIT(6);
6141
6142 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6143
6144 curr_data &= ~BIT(5);
6145
6146 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6147
James Bottomley 47b5d692005-04-24 02:38:05 -05006148 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006149
6150 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6151 curr_data |= BIT(7);
6152
6153 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6154
6155 curr_data &= ~BIT(6);
6156
6157 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6158
James Bottomley 47b5d692005-04-24 02:38:05 -05006159 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006160
6161 return(ret_data);
6162}
6163
6164
6165/*---------------------------------------------------------------------
6166 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006167 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006168 *
6169 * Description: Transfer our Identification string to determine if we
6170 * will be the dominant master.
6171 *
6172 *---------------------------------------------------------------------*/
6173
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006174static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006175{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006176 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177
James Bottomley 47b5d692005-04-24 02:38:05 -05006178 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006179
6180 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6181
6182 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6183
6184 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006185 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006186
6187 else if (p_id_string[byte_cnt] & bit_cnt)
6188
James Bottomley 47b5d692005-04-24 02:38:05 -05006189 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006190
6191 else {
6192
James Bottomley 47b5d692005-04-24 02:38:05 -05006193 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006194 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006195 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006196 }
6197
6198 if ((ret_data & 0x1C) == 0x10)
6199 return(0x00); /*End of isolation stage, we won! */
6200
6201 if (ret_data & 0x1C)
6202 return(0xFF);
6203
6204 if ((defer) && (!(ret_data & 0x1F)))
6205 return(0x01); /*End of isolation stage, we lost. */
6206
6207 } /*bit loop */
6208
6209 } /*byte loop */
6210
6211 if (defer)
6212 return(0x01); /*We lost */
6213 else
6214 return(0); /*We WON! Yeeessss! */
6215}
6216
6217
6218
6219/*---------------------------------------------------------------------
6220 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006221 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006222 *
6223 * Description: Transfer the Identification string.
6224 *
6225 *---------------------------------------------------------------------*/
6226
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006227static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006228{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006229 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006230
6231 the_data = 0;
6232
6233 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6234
6235 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6236
James Bottomley 47b5d692005-04-24 02:38:05 -05006237 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006238
6239 if (ret_data & 0xFC)
6240 return(0xFF);
6241
6242 else {
6243
6244 the_data <<= 1;
6245 if (ret_data & BIT(1)) {
6246 the_data |= 1;
6247 }
6248 }
6249
6250 if ((ret_data & 0x1F) == 0)
6251 {
6252/*
6253 if(bit_cnt != 0 || bit_cnt != 8)
6254 {
6255 byte_cnt = 0;
6256 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006257 FPT_scxferc(p_port, SYNC_PTRN);
6258 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006259 continue;
6260 }
6261*/
6262 if (byte_cnt)
6263 return(0x00);
6264 else
6265 return(0xFF);
6266 }
6267
6268 } /*bit loop */
6269
6270 p_id_string[byte_cnt] = the_data;
6271
6272 } /*byte loop */
6273
6274 return(0);
6275}
6276
6277
6278
6279/*---------------------------------------------------------------------
6280 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006281 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006282 *
6283 * Description: Sample the SCSI data bus making sure the signal has been
6284 * deasserted for the correct number of consecutive samples.
6285 *
6286 *---------------------------------------------------------------------*/
6287
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006288static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006289{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006290 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006291
6292 i = 0;
6293 while ( i < MAX_SCSI_TAR ) {
6294
6295 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6296
6297 i = 0;
6298
6299 else
6300
6301 i++;
6302
6303 }
6304}
6305
6306
6307
6308/*---------------------------------------------------------------------
6309 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006310 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006311 *
6312 * Description: Sample the SCSI Signal lines making sure the signal has been
6313 * deasserted for the correct number of consecutive samples.
6314 *
6315 *---------------------------------------------------------------------*/
6316
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006317static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006318{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006319 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006320
6321 i = 0;
6322 while ( i < MAX_SCSI_TAR ) {
6323
6324 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6325
6326 i = 0;
6327
6328 else
6329
6330 i++;
6331
6332 }
6333}
6334
6335
6336/*---------------------------------------------------------------------
6337 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006338 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006339 *
6340 * Description: Make sure we received a valid data byte.
6341 *
6342 *---------------------------------------------------------------------*/
6343
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006344static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006345{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006346 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347
6348 for (count=1; count < 0x08; count<<=1) {
6349 if (!(p_quintet & count))
6350 p_quintet -= 0x80;
6351 }
6352
6353 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006354 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006355
6356 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006357 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006358}
6359
6360
6361/*---------------------------------------------------------------------
6362 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006363 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006364 *
6365 * Description: Select the specified device ID using a selection timeout
6366 * less than 4ms. If somebody responds then it is a legacy
6367 * drive and this ID must be marked as such.
6368 *
6369 *---------------------------------------------------------------------*/
6370
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006371static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373 ULONG i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374
6375 WR_HARPOON(p_port+hp_page_ctrl,
6376 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6377
6378 ARAM_ACCESS(p_port);
6379
6380 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6381 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6382
6383
6384 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6385 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6386 }
6387 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6388
6389 WRW_HARPOON((p_port+hp_intstat),
6390 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6391
6392 WR_HARPOON(p_port+hp_select_id, targ_id);
6393
6394 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6395 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6396 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6397
6398
6399 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6400 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6401
6402 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006403 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006404
6405 DISABLE_AUTO(p_port);
6406
6407 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6408 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6409
6410 SGRAM_ACCESS(p_port);
6411
6412 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6413
6414 WRW_HARPOON((p_port+hp_intstat),
6415 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6416
6417 WR_HARPOON(p_port+hp_page_ctrl,
6418 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6419
James Bottomley 47b5d692005-04-24 02:38:05 -05006420 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006421 }
6422
6423 else {
6424
6425 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6426 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6427 {
6428 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6429 ACCEPT_MSG(p_port);
6430 }
6431 }
6432
6433 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6434
6435 WR_HARPOON(p_port+hp_page_ctrl,
6436 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6437
James Bottomley 47b5d692005-04-24 02:38:05 -05006438 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006439 }
6440}
6441
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442/*---------------------------------------------------------------------
6443 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006444 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445 *
6446 * Description: Wait to be selected by another SCAM initiator.
6447 *
6448 *---------------------------------------------------------------------*/
6449
James Bottomley 47b5d692005-04-24 02:38:05 -05006450static void FPT_scwtsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451{
6452 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6453}
6454
6455
6456/*---------------------------------------------------------------------
6457 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006458 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006459 *
6460 * Description: Setup the data Structure with the info from the EEPROM.
6461 *
6462 *---------------------------------------------------------------------*/
6463
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006464static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006465{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006466 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006467 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006468 PNVRamInfo pCurrNvRam;
6469
James Bottomley 47b5d692005-04-24 02:38:05 -05006470 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471
6472 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6473 max_id = 0x08;
6474
6475 else
6476 max_id = 0x10;
6477
6478 if(pCurrNvRam){
6479 for(i = 0; i < max_id; i++){
6480
6481 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006482 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006483 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006484 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485
James Bottomley 47b5d692005-04-24 02:38:05 -05006486 if(FPT_scamInfo[i].id_string[0] == 0x00)
6487 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006488 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006489 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490
6491 }
6492 }else {
6493 for (i=0; i < max_id; i++)
6494 {
6495 for (k=0; k < ID_STRING_LENGTH; k+=2)
6496 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006497 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6498 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006499 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006501 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502 }
6503
James Bottomley 47b5d692005-04-24 02:38:05 -05006504 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6505 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506
James Bottomley 47b5d692005-04-24 02:38:05 -05006507 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508
6509 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006510 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006511
6512 }
6513 }
6514 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006515 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006516
6517}
6518
6519/*---------------------------------------------------------------------
6520 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006521 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006522 *
6523 * Description: Match the Device ID string with our values stored in
6524 * the EEPROM.
6525 *
6526 *---------------------------------------------------------------------*/
6527
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006528static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529{
6530
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006531 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006532
6533
6534 for (i=0; i < MAX_SCSI_TAR; i++) {
6535
James Bottomley 47b5d692005-04-24 02:38:05 -05006536 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537
6538 for (k=0; k < ID_STRING_LENGTH; k++)
6539 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006540 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6541 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006542 }
6543
6544 if (match)
6545 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006546 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547 return(i);
6548 }
6549
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550 }
6551
6552
6553
6554 if (p_id_string[0] & BIT(5))
6555 i = 8;
6556 else
6557 i = MAX_SCSI_TAR;
6558
6559 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006560 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006561 else
6562 match = 7;
6563
6564 while (i > 0)
6565 {
6566 i--;
6567
James Bottomley 47b5d692005-04-24 02:38:05 -05006568 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006569 {
6570 for (k=0; k < ID_STRING_LENGTH; k++)
6571 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006572 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006573 }
6574
James Bottomley 47b5d692005-04-24 02:38:05 -05006575 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006576
James Bottomley 47b5d692005-04-24 02:38:05 -05006577 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6578 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006579 return(match);
6580
6581 }
6582
6583
6584 match--;
6585
6586 if (match == 0xFF)
6587 {
6588 if (p_id_string[0] & BIT(5))
6589 match = 7;
6590 else
6591 match = MAX_SCSI_TAR-1;
6592 }
6593 }
6594
6595
6596
6597 if (p_id_string[0] & BIT(7))
6598 {
6599 return(CLR_PRIORITY);
6600 }
6601
6602
6603 if (p_id_string[0] & BIT(5))
6604 i = 8;
6605 else
6606 i = MAX_SCSI_TAR;
6607
6608 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006609 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006610 else
6611 match = 7;
6612
6613 while (i > 0)
6614 {
6615
6616 i--;
6617
James Bottomley 47b5d692005-04-24 02:38:05 -05006618 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006619 {
6620 for (k=0; k < ID_STRING_LENGTH; k++)
6621 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006622 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006623 }
6624
James Bottomley 47b5d692005-04-24 02:38:05 -05006625 FPT_scamInfo[match].id_string[0] |= BIT(7);
6626 FPT_scamInfo[match].state = ID_ASSIGNED;
6627 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6628 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006629 return(match);
6630
6631 }
6632
6633
6634 match--;
6635
6636 if (match == 0xFF)
6637 {
6638 if (p_id_string[0] & BIT(5))
6639 match = 7;
6640 else
6641 match = MAX_SCSI_TAR-1;
6642 }
6643 }
6644
6645 return(NO_ID_AVAIL);
6646}
6647
6648
6649/*---------------------------------------------------------------------
6650 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006651 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652 *
6653 * Description: Save off the device SCAM ID strings.
6654 *
6655 *---------------------------------------------------------------------*/
6656
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006657static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006658{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006659 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006660 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006661
6662
6663 sum_data = 0x0000;
6664
6665 for (i = 1; i < EE_SCAMBASE/2; i++)
6666 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006667 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006668 }
6669
6670
James Bottomley 47b5d692005-04-24 02:38:05 -05006671 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672
6673 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6674 max_id = 0x08;
6675
6676 else
6677 max_id = 0x10;
6678
6679 for (i=0; i < max_id; i++)
6680 {
6681
6682 for (k=0; k < ID_STRING_LENGTH; k+=2)
6683 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006684 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006685 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006686 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006688 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6689 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 }
6691 }
6692
6693
James Bottomley 47b5d692005-04-24 02:38:05 -05006694 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6695 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006696}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006697
6698/*---------------------------------------------------------------------
6699 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006700 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006701 *
6702 * Description: Setup the Xbow for normal operation.
6703 *
6704 *---------------------------------------------------------------------*/
6705
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006706static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006707{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006708unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006709
6710 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006711 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006712
6713 WR_HARPOON(port+hp_scsireset,0x00);
6714 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6715
6716 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6717 FIFO_CLR));
6718
6719 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6720
6721 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6722
6723 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6724 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6725
6726 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6727
James Bottomley 47b5d692005-04-24 02:38:05 -05006728 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006729 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6730
6731 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006732 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006733
James Bottomley 47b5d692005-04-24 02:38:05 -05006734 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735
6736 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6737
6738 /* Turn on SCSI_MODE8 for narrow cards to fix the
6739 strapping issue with the DUAL CHANNEL card */
6740 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6741 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6742
Linus Torvalds1da177e2005-04-16 15:20:36 -07006743 WR_HARPOON(port+hp_page_ctrl, i);
6744
6745}
6746
6747
6748/*---------------------------------------------------------------------
6749 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006750 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006751 *
6752 * Description: Initialize the BusMaster for normal operations.
6753 *
6754 *---------------------------------------------------------------------*/
6755
James Bottomley 47b5d692005-04-24 02:38:05 -05006756static void FPT_BusMasterInit(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006757{
6758
6759
6760 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6761 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6762
6763 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6764
6765
6766 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6767
6768 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6769
6770
Linus Torvalds1da177e2005-04-16 15:20:36 -07006771 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6772 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6773 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6774 ~SCATTER_EN));
6775}
6776
6777
6778/*---------------------------------------------------------------------
6779 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006780 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781 *
6782 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6783 * necessary.
6784 *
6785 *---------------------------------------------------------------------*/
6786
James Bottomley 47b5d692005-04-24 02:38:05 -05006787static void FPT_DiagEEPROM(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006789 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006790
6791 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6792 max_wd_cnt = EEPROM_WD_CNT;
6793 else
6794 max_wd_cnt = EEPROM_WD_CNT * 2;
6795
James Bottomley 47b5d692005-04-24 02:38:05 -05006796 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006797
6798 if (temp == 0x4641) {
6799
6800 for (index = 2; index < max_wd_cnt; index++) {
6801
James Bottomley 47b5d692005-04-24 02:38:05 -05006802 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803
6804 }
6805
James Bottomley 47b5d692005-04-24 02:38:05 -05006806 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006807
6808 return; /*EEPROM is Okay so return now! */
6809 }
6810 }
6811
6812
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006813 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814
6815 for (index = 0; index < max_wd_cnt; index++) {
6816
James Bottomley 47b5d692005-04-24 02:38:05 -05006817 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006818 }
6819
6820 temp = 0;
6821
James Bottomley 47b5d692005-04-24 02:38:05 -05006822 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006823 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006824 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006826 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006828 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006830 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006832 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006834 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006835 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006836 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837 temp += 0x0007;
6838
James Bottomley 47b5d692005-04-24 02:38:05 -05006839 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006841 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844 temp += 0x0000;
6845
James Bottomley 47b5d692005-04-24 02:38:05 -05006846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006847 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006849 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006852 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006854 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006856 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006858 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006860 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 temp += 0x4242;
6862
6863
James Bottomley 47b5d692005-04-24 02:38:05 -05006864 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006866 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006870 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006872 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006874 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006878 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879 temp += 0x2020;
6880
6881 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006882 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 temp += (0x0700+TYPE_CODE0);
6884 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006885 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886 temp += 0x5542; /* BUSLOGIC */
6887 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006888 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889 temp += 0x4C53;
6890 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006891 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892 temp += 0x474F;
6893 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006894 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895 temp += 0x4349;
6896 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006897 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898 temp += 0x5442; /* BT- 930 */
6899 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006900 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006901 temp += 0x202D;
6902 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006903 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006904 temp += 0x3339;
6905 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006906 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006907 temp += 0x2030;
6908 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006909 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910 temp += 0x5453;
6911 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006912 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006913 temp += 0x5645;
6914 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006915 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006916 temp += 0x2045;
6917 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006918 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006919 temp += 0x202F;
6920 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006921 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006922 temp += 0x4F4A;
6923 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006924 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006925 temp += 0x204E;
6926 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006927 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006928 temp += 0x3539;
6929
6930
6931
James Bottomley 47b5d692005-04-24 02:38:05 -05006932 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006933
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006934 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935
6936}
6937
Linus Torvalds1da177e2005-04-16 15:20:36 -07006938
6939/*---------------------------------------------------------------------
6940 *
6941 * Function: Queue Search Select
6942 *
6943 * Description: Try to find a new command to execute.
6944 *
6945 *---------------------------------------------------------------------*/
6946
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006947static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006948{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006949 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006950 PSCCBMgr_tar_info currTar_Info;
6951 PSCCB pOldSccb;
6952
6953 scan_ptr = pCurrCard->scanIndex;
6954 do
6955 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006956 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006957 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6958 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6959 {
6960 if (currTar_Info->TarSelQ_Cnt != 0)
6961 {
6962
6963 scan_ptr++;
6964 if (scan_ptr == MAX_SCSI_TAR)
6965 scan_ptr = 0;
6966
6967 for(lun=0; lun < MAX_LUN; lun++)
6968 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006969 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006970 {
6971
6972 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6973 pOldSccb = NULL;
6974
6975 while((pCurrCard->currentSCCB != NULL) &&
6976 (lun != pCurrCard->currentSCCB->Lun))
6977 {
6978 pOldSccb = pCurrCard->currentSCCB;
6979 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6980 Sccb_forwardlink;
6981 }
6982 if(pCurrCard->currentSCCB == NULL)
6983 continue;
6984 if(pOldSccb != NULL)
6985 {
6986 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6987 Sccb_forwardlink;
6988 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6989 Sccb_backlink;
6990 currTar_Info->TarSelQ_Cnt--;
6991 }
6992 else
6993 {
6994 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6995
6996 if (currTar_Info->TarSelQ_Head == NULL)
6997 {
6998 currTar_Info->TarSelQ_Tail = NULL;
6999 currTar_Info->TarSelQ_Cnt = 0;
7000 }
7001 else
7002 {
7003 currTar_Info->TarSelQ_Cnt--;
7004 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7005 }
7006 }
7007 pCurrCard->scanIndex = scan_ptr;
7008
7009 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7010
7011 break;
7012 }
7013 }
7014 }
7015
7016 else
7017 {
7018 scan_ptr++;
7019 if (scan_ptr == MAX_SCSI_TAR) {
7020 scan_ptr = 0;
7021 }
7022 }
7023
7024 }
7025 else
7026 {
7027 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007028 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007029 {
7030
7031 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7032
7033 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7034
7035 if (currTar_Info->TarSelQ_Head == NULL)
7036 {
7037 currTar_Info->TarSelQ_Tail = NULL;
7038 currTar_Info->TarSelQ_Cnt = 0;
7039 }
7040 else
7041 {
7042 currTar_Info->TarSelQ_Cnt--;
7043 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7044 }
7045
7046 scan_ptr++;
7047 if (scan_ptr == MAX_SCSI_TAR)
7048 scan_ptr = 0;
7049
7050 pCurrCard->scanIndex = scan_ptr;
7051
7052 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7053
7054 break;
7055 }
7056
7057 else
7058 {
7059 scan_ptr++;
7060 if (scan_ptr == MAX_SCSI_TAR)
7061 {
7062 scan_ptr = 0;
7063 }
7064 }
7065 }
7066 } while (scan_ptr != pCurrCard->scanIndex);
7067}
7068
7069
7070/*---------------------------------------------------------------------
7071 *
7072 * Function: Queue Select Fail
7073 *
7074 * Description: Add the current SCCB to the head of the Queue.
7075 *
7076 *---------------------------------------------------------------------*/
7077
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007078static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007079{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007080 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007081 PSCCBMgr_tar_info currTar_Info;
7082
7083 if (pCurrCard->currentSCCB != NULL)
7084 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007085 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007086 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007087
7088 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7089
7090 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7091
7092 if (currTar_Info->TarSelQ_Cnt == 0)
7093 {
7094 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7095 }
7096
7097 else
7098 {
7099 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7100 }
7101
7102
7103 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7104
7105 pCurrCard->currentSCCB = NULL;
7106 currTar_Info->TarSelQ_Cnt++;
7107 }
7108}
7109/*---------------------------------------------------------------------
7110 *
7111 * Function: Queue Command Complete
7112 *
7113 * Description: Call the callback function with the current SCCB.
7114 *
7115 *---------------------------------------------------------------------*/
7116
James Bottomley 47b5d692005-04-24 02:38:05 -05007117static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007118 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007119{
7120
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007121 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007122 CALL_BK_FN callback;
7123 PSCCBMgr_tar_info currTar_Info;
7124
7125 SCSIcmd = p_sccb->Cdb[0];
7126
7127
7128 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7129
7130 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7131 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7132 (p_sccb->TargetStatus != SSCHECK))
7133
7134 if ((SCSIcmd == SCSI_READ) ||
7135 (SCSIcmd == SCSI_WRITE) ||
7136 (SCSIcmd == SCSI_READ_EXTENDED) ||
7137 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7138 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7139 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7140 (pCurrCard->globalFlags & F_NO_FILTER)
7141 )
7142 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7143 }
7144
7145
7146 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7147 {
7148 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7149 p_sccb->SccbStatus = SCCB_ERROR;
7150 else
7151 p_sccb->SccbStatus = SCCB_SUCCESS;
7152 }
7153
7154 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7155
7156 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7157 for (i=0; i < 6; i++) {
7158 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7159 }
7160 }
7161
7162 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7163 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7164
James Bottomley 47b5d692005-04-24 02:38:05 -05007165 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007166 }
7167
7168 pCurrCard->cmdCounter--;
7169 if (!pCurrCard->cmdCounter) {
7170
7171 if (pCurrCard->globalFlags & F_GREEN_PC) {
7172 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7173 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7174 }
7175
7176 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7177 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7178
7179 }
7180
7181 if(pCurrCard->discQCount != 0)
7182 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007183 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007184 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7185 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7186 {
7187 pCurrCard->discQCount--;
7188 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7189 }
7190 else
7191 {
7192 if(p_sccb->Sccb_tag)
7193 {
7194 pCurrCard->discQCount--;
7195 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7196 }else
7197 {
7198 pCurrCard->discQCount--;
7199 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7200 }
7201 }
7202
7203 }
7204
7205 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7206 callback(p_sccb);
7207 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7208 pCurrCard->currentSCCB = NULL;
7209}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007210
7211
7212/*---------------------------------------------------------------------
7213 *
7214 * Function: Queue Disconnect
7215 *
7216 * Description: Add SCCB to our disconnect array.
7217 *
7218 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007219static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007220{
7221 PSCCBMgr_tar_info currTar_Info;
7222
James Bottomley 47b5d692005-04-24 02:38:05 -05007223 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007224
James Bottomley 47b5d692005-04-24 02:38:05 -05007225 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007226 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7227 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007228 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007229 }
7230 else
7231 {
7232 if (p_sccb->Sccb_tag)
7233 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007234 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7235 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7236 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007237 }else
7238 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007239 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007240 }
7241 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007242 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007243}
7244
7245
7246/*---------------------------------------------------------------------
7247 *
7248 * Function: Queue Flush SCCB
7249 *
7250 * Description: Flush all SCCB's back to the host driver for this target.
7251 *
7252 *---------------------------------------------------------------------*/
7253
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007254static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007255{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007256 unsigned char qtag,thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007257 PSCCB currSCCB;
7258 PSCCBMgr_tar_info currTar_Info;
7259
James Bottomley 47b5d692005-04-24 02:38:05 -05007260 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007261 if(currSCCB != NULL)
7262 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007263 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007264 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007265
7266 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7267
James Bottomley 47b5d692005-04-24 02:38:05 -05007268 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7269 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007270 {
7271
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007272 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007273
James Bottomley 47b5d692005-04-24 02:38:05 -05007274 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007275
James Bottomley 47b5d692005-04-24 02:38:05 -05007276 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007277 currTar_Info->TarTagQ_Cnt--;
7278
7279 }
7280 }
7281 }
7282
7283}
7284
7285/*---------------------------------------------------------------------
7286 *
7287 * Function: Queue Flush Target SCCB
7288 *
7289 * Description: Flush all SCCB's back to the host driver for this target.
7290 *
7291 *---------------------------------------------------------------------*/
7292
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007293static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7294 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007295{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007296 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297 PSCCBMgr_tar_info currTar_Info;
7298
James Bottomley 47b5d692005-04-24 02:38:05 -05007299 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007300
7301 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7302
James Bottomley 47b5d692005-04-24 02:38:05 -05007303 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7304 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007305 {
7306
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007307 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007308
James Bottomley 47b5d692005-04-24 02:38:05 -05007309 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007310
James Bottomley 47b5d692005-04-24 02:38:05 -05007311 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007312 currTar_Info->TarTagQ_Cnt--;
7313
7314 }
7315 }
7316
7317}
7318
7319
7320
7321
7322
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007323static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007324{
7325 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007326 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007327
7328 p_SCCB->Sccb_forwardlink = NULL;
7329
7330 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7331
7332 if (currTar_Info->TarSelQ_Cnt == 0) {
7333
7334 currTar_Info->TarSelQ_Head = p_SCCB;
7335 }
7336
7337 else {
7338
7339 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7340 }
7341
7342
7343 currTar_Info->TarSelQ_Tail = p_SCCB;
7344 currTar_Info->TarSelQ_Cnt++;
7345}
7346
7347
7348/*---------------------------------------------------------------------
7349 *
7350 * Function: Queue Find SCCB
7351 *
7352 * Description: Search the target select Queue for this SCCB, and
7353 * remove it if found.
7354 *
7355 *---------------------------------------------------------------------*/
7356
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007357static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007358{
7359 PSCCB q_ptr;
7360 PSCCBMgr_tar_info currTar_Info;
7361
James Bottomley 47b5d692005-04-24 02:38:05 -05007362 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007363
7364 q_ptr = currTar_Info->TarSelQ_Head;
7365
7366 while(q_ptr != NULL) {
7367
7368 if (q_ptr == p_SCCB) {
7369
7370
7371 if (currTar_Info->TarSelQ_Head == q_ptr) {
7372
7373 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7374 }
7375
7376 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7377
7378 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7379 }
7380
7381 if (q_ptr->Sccb_forwardlink != NULL) {
7382 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7383 }
7384
7385 if (q_ptr->Sccb_backlink != NULL) {
7386 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7387 }
7388
7389 currTar_Info->TarSelQ_Cnt--;
7390
James Bottomley 47b5d692005-04-24 02:38:05 -05007391 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007392 }
7393
7394 else {
7395 q_ptr = q_ptr->Sccb_forwardlink;
7396 }
7397 }
7398
7399
James Bottomley 47b5d692005-04-24 02:38:05 -05007400 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007401
7402}
7403
7404
7405/*---------------------------------------------------------------------
7406 *
7407 * Function: Utility Update Residual Count
7408 *
7409 * Description: Update the XferCnt to the remaining byte count.
7410 * If we transferred all the data then just write zero.
7411 * If Non-SG transfer then report Total Cnt - Actual Transfer
7412 * Cnt. For SG transfers add the count fields of all
7413 * remaining SG elements, as well as any partial remaining
7414 * element.
7415 *
7416 *---------------------------------------------------------------------*/
7417
James Bottomley 47b5d692005-04-24 02:38:05 -05007418static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007419{
7420 ULONG partial_cnt;
7421 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007422 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007423
7424 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7425
7426 p_SCCB->DataLength = 0x0000;
7427 }
7428
7429 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7430
7431 partial_cnt = 0x0000;
7432
7433 sg_index = p_SCCB->Sccb_sgseg;
7434
Linus Torvalds1da177e2005-04-16 15:20:36 -07007435 sg_ptr = (ULONG *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007436
7437 if (p_SCCB->Sccb_SGoffset) {
7438
7439 partial_cnt = p_SCCB->Sccb_SGoffset;
7440 sg_index++;
7441 }
7442
7443 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7444 p_SCCB->DataLength ) {
7445
7446 partial_cnt += *(sg_ptr+(sg_index * 2));
7447 sg_index++;
7448 }
7449
7450 p_SCCB->DataLength = partial_cnt;
7451 }
7452
7453 else {
7454
7455 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7456 }
7457}
7458
7459
7460/*---------------------------------------------------------------------
7461 *
7462 * Function: Wait 1 Second
7463 *
7464 * Description: Wait for 1 second.
7465 *
7466 *---------------------------------------------------------------------*/
7467
James Bottomley 47b5d692005-04-24 02:38:05 -05007468static void FPT_Wait1Second(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007469{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007470 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007471
7472 for(i=0; i < 4; i++) {
7473
James Bottomley 47b5d692005-04-24 02:38:05 -05007474 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007475
7476 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7477 break;
7478
7479 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7480 break;
7481 }
7482}
7483
7484
7485/*---------------------------------------------------------------------
7486 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007487 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007488 *
7489 * Description: Wait the desired delay.
7490 *
7491 *---------------------------------------------------------------------*/
7492
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007493static void FPT_Wait(ULONG p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007494{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007495 unsigned char old_timer;
7496 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007497
7498 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7499
7500 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7501 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7502
7503 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7504 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007505 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007506
7507
7508 WR_HARPOON(p_port+hp_portctrl_0,
7509 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7510
7511 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7512
7513 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7514 break;
7515
7516 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7517 break;
7518 }
7519
7520 WR_HARPOON(p_port+hp_portctrl_0,
7521 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7522
7523 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007524 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007525
7526 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7527
7528 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7529}
7530
7531
7532/*---------------------------------------------------------------------
7533 *
7534 * Function: Enable/Disable Write to EEPROM
7535 *
7536 * Description: The EEPROM must first be enabled for writes
7537 * A total of 9 clocks are needed.
7538 *
7539 *---------------------------------------------------------------------*/
7540
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007541static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007542{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007543 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007544
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007545 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 -07007546
7547 if (p_mode)
7548
James Bottomley 47b5d692005-04-24 02:38:05 -05007549 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007550
7551 else
7552
7553
James Bottomley 47b5d692005-04-24 02:38:05 -05007554 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007555
7556 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7557 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7558}
7559
7560
7561/*---------------------------------------------------------------------
7562 *
7563 * Function: Write EEPROM
7564 *
7565 * Description: Write a word to the EEPROM at the specified
7566 * address.
7567 *
7568 *---------------------------------------------------------------------*/
7569
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007570static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007571{
7572
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007573 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007574 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007575
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007576 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 -07007577 (SEE_MS | SEE_CS));
7578
7579
7580
James Bottomley 47b5d692005-04-24 02:38:05 -05007581 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007582
7583
7584 ee_value |= (SEE_MS + SEE_CS);
7585
7586 for(i = 0x8000; i != 0; i>>=1) {
7587
7588 if (i & ee_data)
7589 ee_value |= SEE_DO;
7590 else
7591 ee_value &= ~SEE_DO;
7592
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 ee_value |= SEE_CLK; /* Clock data! */
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 ee_value &= ~SEE_CLK;
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7601 }
7602 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7603 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7604
James Bottomley 47b5d692005-04-24 02:38:05 -05007605 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007606
7607 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7608 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7609 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7610}
7611
7612/*---------------------------------------------------------------------
7613 *
7614 * Function: Read EEPROM
7615 *
7616 * Description: Read a word from the EEPROM at the desired
7617 * address.
7618 *
7619 *---------------------------------------------------------------------*/
7620
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007621static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007622{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007623 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007624
7625 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007626 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007627 do
7628 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007629 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007630
7631 if(ee_data1 == ee_data2)
7632 return(ee_data1);
7633
7634 ee_data1 = ee_data2;
7635 i++;
7636
7637 }while(i < 4);
7638
7639 return(ee_data1);
7640}
7641
7642/*---------------------------------------------------------------------
7643 *
7644 * Function: Read EEPROM Original
7645 *
7646 * Description: Read a word from the EEPROM at the desired
7647 * address.
7648 *
7649 *---------------------------------------------------------------------*/
7650
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007651static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007652{
7653
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007654 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007655 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007656
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007657 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 -07007658 (SEE_MS | SEE_CS));
7659
7660
James Bottomley 47b5d692005-04-24 02:38:05 -05007661 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007662
7663
7664 ee_value |= (SEE_MS + SEE_CS);
7665 ee_data = 0;
7666
7667 for(i = 1; i <= 16; i++) {
7668
7669 ee_value |= SEE_CLK; /* Clock data! */
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672 ee_value &= ~SEE_CLK;
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7675
7676 ee_data <<= 1;
7677
7678 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7679 ee_data |= 1;
7680 }
7681
7682 ee_value &= ~(SEE_MS + SEE_CS);
7683 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7684 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7685
7686 return(ee_data);
7687}
7688
7689
7690/*---------------------------------------------------------------------
7691 *
7692 * Function: Send EE command and Address to the EEPROM
7693 *
7694 * Description: Transfers the correct command and sends the address
7695 * to the eeprom.
7696 *
7697 *---------------------------------------------------------------------*/
7698
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007699static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007700{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007701 unsigned char ee_value;
7702 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007703
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007704 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007705
7706
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007707 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007708
7709
7710 ee_value = SEE_MS;
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712
7713 ee_value |= SEE_CS; /* Set CS to EEPROM */
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715
7716
7717 for(i = 0x04; i != 0; i>>=1) {
7718
7719 if (i & ee_cmd)
7720 ee_value |= SEE_DO;
7721 else
7722 ee_value &= ~SEE_DO;
7723
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 ee_value |= SEE_CLK; /* Clock data! */
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 ee_value &= ~SEE_CLK;
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7732 }
7733
7734
7735 if (narrow_flg)
7736 i = 0x0080;
7737
7738 else
7739 i = 0x0200;
7740
7741
7742 while (i != 0) {
7743
7744 if (i & ee_addr)
7745 ee_value |= SEE_DO;
7746 else
7747 ee_value &= ~SEE_DO;
7748
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 ee_value |= SEE_CLK; /* Clock data! */
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754 ee_value &= ~SEE_CLK;
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7757
7758 i >>= 1;
7759 }
7760}
7761
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007762static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007763{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007764 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007765 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007766 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007767 for (i=0; i < ID_STRING_LENGTH; i++)
7768 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007769 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007770 for(j=0; j < 8; j++)
7771 {
7772 if ((crc ^ ch) & 1)
7773 crc = (crc >> 1) ^ CRCMASK;
7774 else
7775 crc >>= 1;
7776 ch >>= 1;
7777 }
7778 }
7779 return(crc);
7780}
7781
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007782static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007783{
7784 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007785 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007786 lrc = 0;
7787 for(i = 0; i < ID_STRING_LENGTH; i++)
7788 lrc ^= buffer[i];
7789 return(lrc);
7790}
7791
7792
7793
7794/*
7795 The following inline definitions avoid type conflicts.
7796*/
7797
7798static inline unsigned char
7799FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7800{
7801 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7802}
7803
7804
7805static inline FlashPoint_CardHandle_T
7806FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7807{
7808 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7809}
7810
7811static inline void
7812FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7813{
7814 FlashPoint_ReleaseHostAdapter(CardHandle);
7815}
7816
7817
7818static inline void
7819FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7820{
7821 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7822}
7823
7824
7825static inline void
7826FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7827{
7828 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7829}
7830
7831
7832static inline boolean
7833FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7834{
7835 return FlashPoint_InterruptPending(CardHandle);
7836}
7837
7838
7839static inline int
7840FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7841{
7842 return FlashPoint_HandleInterrupt(CardHandle);
7843}
7844
7845
7846#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7847#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7848#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7849#define FlashPoint_StartCCB FlashPoint__StartCCB
7850#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7851#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7852#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7853
7854
Linus Torvalds1da177e2005-04-16 15:20:36 -07007855#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7856
7857
7858/*
7859 Define prototypes for the FlashPoint SCCB Manager Functions.
7860*/
7861
7862extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7863extern FlashPoint_CardHandle_T
7864 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7865extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7866extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7867extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7868extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7869extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007870
7871
7872#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */