blob: d877a6a12aca48b9ca60567d06210c031ae6f41f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#define CRCMASK 0xA001
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define FAILURE 0xFFFFFFFFL
41
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045typedef unsigned short * ushort_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#define s08bits char
49#define s16bits short
50#define s32bits long
51
52#define u08bits unsigned s08bits
53#define u16bits unsigned s16bits
54#define u32bits unsigned s32bits
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080058#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080059#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
61
62
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
James Bottomley 47b5d692005-04-24 02:38:05 -050064typedef struct _SCCB *PSCCB;
65typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67
68typedef struct SCCBMgr_info {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080069 unsigned long si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080070 unsigned char si_present;
71 unsigned char si_intvect;
72 unsigned char si_id;
73 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080074 unsigned short si_fw_revision;
75 unsigned short si_per_targ_init_sync;
76 unsigned short si_per_targ_fast_nego;
77 unsigned short si_per_targ_ultra_nego;
78 unsigned short si_per_targ_no_disc;
79 unsigned short si_per_targ_wide_nego;
80 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080081 unsigned char si_card_family;
82 unsigned char si_bustype;
83 unsigned char si_card_model[3];
84 unsigned char si_relative_cardnum;
85 unsigned char si_reserved[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080086 unsigned long si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080087 unsigned char si_XlatInfo[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080088 unsigned long si_reserved2[5];
89 unsigned long si_secondary_range;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090} SCCBMGR_INFO;
91
James Bottomley 47b5d692005-04-24 02:38:05 -050092typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94
James Bottomley 47b5d692005-04-24 02:38:05 -050095#define SCSI_PARITY_ENA 0x0001
96#define LOW_BYTE_TERM 0x0010
97#define HIGH_BYTE_TERM 0x0020
98#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100#define SUPPORT_16TAR_32LUN 0x0002
101#define SOFT_RESET 0x0004
102#define EXTENDED_TRANSLATION 0x0008
103#define POST_ALL_UNDERRRUNS 0x0040
104#define FLAG_SCAM_ENABLED 0x0080
105#define FLAG_SCAM_LEVEL2 0x0100
106
107
108
109
110#define HARPOON_FAMILY 0x02
111
112
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
Alexey Dobriyan323579882006-01-15 02:12:54 +0100114/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 * The UCB Manager treats the SCCB as it's 'native hardware structure'
116 */
117
118
119#pragma pack(1)
120typedef struct _SCCB {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800121 unsigned char OperationCode;
122 unsigned char ControlByte;
123 unsigned char CdbLength;
124 unsigned char RequestSenseLength;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800125 unsigned long DataLength;
126 unsigned long DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800127 unsigned char CcbRes[2];
128 unsigned char HostStatus;
129 unsigned char TargetStatus;
130 unsigned char TargID;
131 unsigned char Lun;
132 unsigned char Cdb[12];
133 unsigned char CcbRes1;
134 unsigned char Reserved1;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800135 unsigned long Reserved2;
136 unsigned long SensePointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
138
139 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800140 unsigned long SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800141 unsigned char SccbStatus;
142 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800143 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
145
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800146 unsigned long Sccb_XferCnt; /* actual transfer count */
147 unsigned long Sccb_ATC;
148 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
149 unsigned long Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800150 unsigned short Sccb_MGRFlags;
151 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800152 unsigned char Sccb_scsimsg; /* identify msg for selection */
153 unsigned char Sccb_tag;
154 unsigned char Sccb_scsistat;
155 unsigned char Sccb_idmsg; /* image of last msg in */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 PSCCB Sccb_forwardlink;
157 PSCCB Sccb_backlink;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800158 unsigned long Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800159 unsigned char Save_Cdb[6];
160 unsigned char Save_CdbLen;
161 unsigned char Sccb_XferState;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800162 unsigned long Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 } SCCB;
164
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
166#pragma pack()
167
168
169
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170#define SCATTER_GATHER_COMMAND 0x02
171#define RESIDUAL_COMMAND 0x03
172#define RESIDUAL_SG_COMMAND 0x04
173#define RESET_COMMAND 0x81
174
175
176#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
177#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178#define SCCB_DATA_XFER_OUT 0x10 /* Write */
179#define SCCB_DATA_XFER_IN 0x08 /* Read */
180
181
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
183
184
185#define BUS_FREE_ST 0
186#define SELECT_ST 1
187#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
188#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
189#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
190#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
191#define COMMAND_ST 6
192#define DATA_OUT_ST 7
193#define DATA_IN_ST 8
194#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197
198#define F_HOST_XFER_DIR 0x01
199#define F_ALL_XFERRED 0x02
200#define F_SG_XFER 0x04
201#define F_AUTO_SENSE 0x08
202#define F_ODD_BALL_CNT 0x10
203#define F_NO_DATA_YET 0x80
204
205
206#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207#define F_DEV_SELECTED 0x04
208
209
210#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
211#define SCCB_DATA_UNDER_RUN 0x0C
212#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
213#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
215
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
217#define SCCB_BM_ERR 0x30 /* BusMaster error. */
218#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
219
220
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222
223
224#define SCCB_IN_PROCESS 0x00
225#define SCCB_SUCCESS 0x01
226#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231#define ORION_FW_REV 3110
232
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233
234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
237#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
James Bottomley 47b5d692005-04-24 02:38:05 -0500240#define MAX_SCSI_TAR 16
241#define MAX_LUN 32
242#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
246#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -0800249#define RD_HARPOON(ioport) inb((u32bits)ioport)
250#define RDW_HARPOON(ioport) inw((u32bits)ioport)
251#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
252#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
253#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
254#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255
256
257#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258#define SYNC_TRYING BIT(6)
259#define SYNC_SUPPORTED (BIT(7)+BIT(6))
260
261#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262#define WIDE_ENABLED BIT(4)
263#define WIDE_NEGOCIATED BIT(5)
264
265#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266#define TAG_Q_TRYING BIT(2)
267#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
269#define TAR_ALLOW_DISC BIT(0)
270
271
272#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273#define EE_SYNC_5MB BIT(0)
274#define EE_SYNC_10MB BIT(1)
275#define EE_SYNC_20MB (BIT(0)+BIT(1))
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277#define EE_WIDE_SCSI BIT(7)
278
279
James Bottomley 47b5d692005-04-24 02:38:05 -0500280typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281
282
283typedef struct SCCBMgr_tar_info {
284
285 PSCCB TarSelQ_Head;
286 PSCCB TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800287 unsigned char TarLUN_CA; /*Contingent Allgiance */
288 unsigned char TarTagQ_Cnt;
289 unsigned char TarSelQ_Cnt;
290 unsigned char TarStatus;
291 unsigned char TarEEValue;
292 unsigned char TarSyncCtrl;
293 unsigned char TarReserved[2]; /* for alignment */
294 unsigned char LunDiscQ_Idx[MAX_LUN];
295 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296} SCCBMGR_TAR_INFO;
297
298typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800299 unsigned char niModel; /* Model No. of card */
300 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800301 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800302 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
303 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
304 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
305 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
306 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
307 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308}NVRAMINFO;
309
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311
312#define MODEL_LT 1
313#define MODEL_DL 2
314#define MODEL_LW 3
315#define MODEL_DW 4
316
317
318typedef struct SCCBcard {
319 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800322 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800324 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800325 unsigned char discQCount;
326 unsigned char tagQ_Lst;
327 unsigned char cardIndex;
328 unsigned char scanIndex;
329 unsigned char globalFlags;
330 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 PNVRamInfo pNvRamInfo;
332 PSCCB discQ_Tbl[QUEUE_DEPTH];
333
334}SCCBCARD;
335
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
338
339#define F_TAG_STARTED 0x01
340#define F_CONLUN_IO 0x02
341#define F_DO_RENEGO 0x04
342#define F_NO_FILTER 0x08
343#define F_GREEN_PC 0x10
344#define F_HOST_XFER_ACT 0x20
345#define F_NEW_SCCB_CMD 0x40
346#define F_UPDATE_EEPROM 0x80
347
348
349#define ID_STRING_LENGTH 32
350#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
351
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352
353#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
354
355#define ASSIGN_ID 0x00
356#define SET_P_FLAG 0x01
357#define CFG_CMPLT 0x03
358#define DOM_MSTR 0x0F
359#define SYNC_PTRN 0x1F
360
361#define ID_0_7 0x18
362#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363#define MISC_CODE 0x14
364#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366
367
368#define INIT_SELTD 0x01
369#define LEVEL2_TAR 0x02
370
371
372enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
373 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
374 CLR_PRIORITY,NO_ID_AVAIL };
375
376typedef struct SCCBscam_info {
377
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800378 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 enum scam_id_st state;
380
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800381} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385#define SCSI_READ 0x08
386#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388#define SCSI_READ_EXTENDED 0x28
389#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391
392
393
394#define SSGOOD 0x00
395#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396#define SSQ_FULL 0x28
397
398
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
400
401#define SMCMD_COMP 0x00
402#define SMEXT 0x01
403#define SMSAVE_DATA_PTR 0x02
404#define SMREST_DATA_PTR 0x03
405#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406#define SMABORT 0x06
407#define SMREJECT 0x07
408#define SMNO_OP 0x08
409#define SMPARITY 0x09
410#define SMDEV_RESET 0x0C
411#define SMABORT_TAG 0x0D
412#define SMINIT_RECOVERY 0x0F
413#define SMREL_RECOVERY 0x10
414
415#define SMIDENT 0x80
416#define DISC_PRIV 0x40
417
418
419#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420#define SMWDTR 0x03
421#define SM8BIT 0x00
422#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423#define SMIGNORWR 0x23 /* Ignore Wide Residue */
424
425
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427
428
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430
431
432#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433#define TWELVE_BYTE_CMD 0x0C
434
435#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438
439#define EEPROM_WD_CNT 256
440
441#define EEPROM_CHECK_SUM 0
442#define FW_SIGNATURE 2
443#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446#define SYSTEM_CONFIG 16
447#define SCSI_CONFIG 17
448#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449#define SCAM_CONFIG 20
450#define ADAPTER_SCSI_ID 24
451
452
453#define IGNORE_B_SCAN 32
454#define SEND_START_ENA 34
455#define DEVICE_ENABLE 36
456
457#define SYNC_RATE_TBL 38
458#define SYNC_RATE_TBL01 38
459#define SYNC_RATE_TBL23 40
460#define SYNC_RATE_TBL45 42
461#define SYNC_RATE_TBL67 44
462#define SYNC_RATE_TBL89 46
463#define SYNC_RATE_TBLab 48
464#define SYNC_RATE_TBLcd 50
465#define SYNC_RATE_TBLef 52
466
467
468
469#define EE_SCAMBASE 256
470
471
472
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 #define SCAM_ENABLED BIT(2)
474 #define SCAM_LEVEL2 BIT(3)
475
476
477 #define RENEGO_ENA BITW(10)
478 #define CONNIO_ENA BITW(11)
479 #define GREEN_PC_ENA BITW(12)
480
481
482 #define AUTO_RATE_00 00
483 #define AUTO_RATE_05 01
484 #define AUTO_RATE_10 02
485 #define AUTO_RATE_20 03
486
487 #define WIDE_NEGO_BIT BIT(7)
488 #define DISC_ENABLE_BIT BIT(6)
489
490
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
492 #define hp_vendor_id_0 0x00 /* LSB */
493 #define ORION_VEND_0 0x4B
494
495 #define hp_vendor_id_1 0x01 /* MSB */
496 #define ORION_VEND_1 0x10
497
498 #define hp_device_id_0 0x02 /* LSB */
499 #define ORION_DEV_0 0x30
500
501 #define hp_device_id_1 0x03 /* MSB */
502 #define ORION_DEV_1 0x81
503
504 /* Sub Vendor ID and Sub Device ID only available in
505 Harpoon Version 2 and higher */
506
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
509
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
511 #define hp_semaphore 0x0C
512 #define SCCB_MGR_ACTIVE BIT(0)
513 #define TICKLE_ME BIT(1)
514 #define SCCB_MGR_PRESENT BIT(3)
515 #define BIOS_IN_USE BIT(4)
516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
519 #define hp_sys_ctrl 0x0F
520
521 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
522 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
523 #define HALT_MACH BIT(3) /*Halt State Machine */
524 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800530
531
532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
534 #define hp_host_blk_cnt 0x13
535
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
537
538 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
539
540
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541
542 #define hp_int_mask 0x17
543
544 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
545 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547
548 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 #define hp_xfer_cnt_hi 0x1A
550 #define hp_xfer_cmd 0x1B
551
552 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
553 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554
555
556 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
558 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
560 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
561
562 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
563 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
565 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 #define hp_ee_ctrl 0x22
569
570 #define EXT_ARB_ACK BIT(7)
571 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
572 #define SEE_MS BIT(5)
573 #define SEE_CS BIT(3)
574 #define SEE_CLK BIT(2)
575 #define SEE_DO BIT(1)
576 #define SEE_DI BIT(0)
577
578 #define EE_READ 0x06
579 #define EE_WRITE 0x05
580 #define EWEN 0x04
581 #define EWEN_ADDR 0x03C0
582 #define EWDS 0x04
583 #define EWDS_ADDR 0x0000
584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
588
589
590
591 #define hp_bm_ctrl 0x26
592
593 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
594 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
596 #define FAST_SINGLE BIT(6) /*?? */
597
598 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601 #define hp_sg_addr 0x28
602 #define hp_page_ctrl 0x29
603
604 #define SCATTER_EN BIT(0)
605 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
607 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 #define hp_pci_stat_cfg 0x2D
613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
623 #define hp_rev_num 0x33
624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625
626 #define hp_stack_data 0x34
627 #define hp_stack_addr 0x35
628
629 #define hp_ext_status 0x36
630
631 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
632 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
633 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 #define CMD_ABORTED BIT(4) /*Command aborted */
635 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
636 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
637 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
638 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
639 BM_PARITY_ERR | PIO_OVERRUN)
640
641 #define hp_int_status 0x37
642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
644 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
647
648 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651
652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 #define hp_intena 0x40
654
655 #define RESET BITW(7)
656 #define PROG_HLT BITW(6)
657 #define PARITY BITW(5)
658 #define FIFO BITW(4)
659 #define SEL BITW(3)
660 #define SCAM_SEL BITW(2)
661 #define RSEL BITW(1)
662 #define TIMEOUT BITW(0)
663 #define BUS_FREE BITW(15)
664 #define XFER_CNT_0 BITW(14)
665 #define PHASE BITW(13)
666 #define IUNKWN BITW(12)
667 #define ICMD_COMP BITW(11)
668 #define ITICKLE BITW(10)
669 #define IDO_STRT BITW(9)
670 #define ITAR_DISC BITW(8)
671 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
672 #define CLR_ALL_INT 0xFFFF
673 #define CLR_ALL_INT_1 0xFF00
674
675 #define hp_intstat 0x42
676
677 #define hp_scsisig 0x44
678
679 #define SCSI_SEL BIT(7)
680 #define SCSI_BSY BIT(6)
681 #define SCSI_REQ BIT(5)
682 #define SCSI_ACK BIT(4)
683 #define SCSI_ATN BIT(3)
684 #define SCSI_CD BIT(2)
685 #define SCSI_MSG BIT(1)
686 #define SCSI_IOBIT BIT(0)
687
688 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
691 #define S_DATAI_PH ( BIT(0))
692 #define S_DATAO_PH 0x00
693 #define S_ILL_PH ( BIT(1) )
694
695 #define hp_scsictrl_0 0x45
696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 #define SEL_TAR BIT(6)
698 #define ENA_ATN BIT(4)
699 #define ENA_RESEL BIT(2)
700 #define SCSI_RST BIT(1)
701 #define ENA_SCAM_SEL BIT(0)
702
703
704
705 #define hp_portctrl_0 0x46
706
707 #define SCSI_PORT BIT(7)
708 #define SCSI_INBIT BIT(6)
709 #define DMA_PORT BIT(5)
710 #define DMA_RD BIT(4)
711 #define HOST_PORT BIT(3)
712 #define HOST_WRT BIT(2)
713 #define SCSI_BUS_EN BIT(1)
714 #define START_TO BIT(0)
715
716 #define hp_scsireset 0x47
717
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 #define SCSI_INI BIT(6)
719 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 #define DMA_RESET BIT(3)
721 #define HPSCSI_RESET BIT(2)
722 #define PROG_RESET BIT(1)
723 #define FIFO_CLR BIT(0)
724
725 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727
728 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 #define hp_addstat 0x4E
730
731 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 #define SCSI_MODE8 BIT(3)
733 #define SCSI_PAR_ERR BIT(0)
734
735 #define hp_prgmcnt_0 0x4F
736
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737
738 #define hp_selfid_0 0x50
739 #define hp_selfid_1 0x51
740 #define hp_arb_id 0x52
741
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742
743 #define hp_select_id 0x53
744
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745
746 #define hp_synctarg_base 0x54
747 #define hp_synctarg_12 0x54
748 #define hp_synctarg_13 0x55
749 #define hp_synctarg_14 0x56
750 #define hp_synctarg_15 0x57
751
752 #define hp_synctarg_8 0x58
753 #define hp_synctarg_9 0x59
754 #define hp_synctarg_10 0x5A
755 #define hp_synctarg_11 0x5B
756
757 #define hp_synctarg_4 0x5C
758 #define hp_synctarg_5 0x5D
759 #define hp_synctarg_6 0x5E
760 #define hp_synctarg_7 0x5F
761
762 #define hp_synctarg_0 0x60
763 #define hp_synctarg_1 0x61
764 #define hp_synctarg_2 0x62
765 #define hp_synctarg_3 0x63
766
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 #define DEFAULT_OFFSET 0x0F
769
770 #define hp_autostart_0 0x64
771 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 #define hp_autostart_3 0x67
773
774
775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 #define AUTO_IMMED BIT(5)
777 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780 #define hp_gp_reg_0 0x68
781 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 #define hp_gp_reg_3 0x6B
783
784 #define hp_seltimeout 0x6C
785
786
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 #define TO_4ms 0x67 /* 3.9959ms */
788
789 #define TO_5ms 0x03 /* 4.9152ms */
790 #define TO_10ms 0x07 /* 11.xxxms */
791 #define TO_250ms 0x99 /* 250.68ms */
792 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
794 #define hp_clkctrl_0 0x6D
795
796 #define PWR_DWN BIT(6)
797 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
800 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
801
802 #define hp_fiforead 0x6E
803 #define hp_fifowrite 0x6F
804
805 #define hp_offsetctr 0x70
806 #define hp_xferstat 0x71
807
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
810 #define hp_portctrl_1 0x72
811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 #define CHK_SCSI_P BIT(3)
813 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
815 #define hp_xfer_pad 0x73
816
817 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818
819 #define hp_scsidata_0 0x74
820 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
824 #define hp_aramBase 0x80
825 #define BIOS_DATA_OFFSET 0x60
826 #define BIOS_RELATIVE_CARD 0x64
827
828
829
830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 #define AR3 (BITW(9) + BITW(8))
832 #define SDATA BITW(10)
833
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834
835 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
836
837 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
838
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
841 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
842
843 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
844
845
846 #define ADATA_OUT 0x00
847 #define ADATA_IN BITW(8)
848 #define ACOMMAND BITW(10)
849 #define ASTATUS (BITW(10)+BITW(8))
850 #define AMSG_OUT (BITW(10)+BITW(9))
851 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
853
854 #define BRH_OP BITW(13) /* Branch */
855
856
857 #define ALWAYS 0x00
858 #define EQUAL BITW(8)
859 #define NOT_EQ BITW(9)
860
861 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
862
863
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865
866
867 #define MPM_OP BITW(15) /* Match phase and move data */
868
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869
870 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
871
872
873 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
874
875
876 #define D_AR0 0x00
877 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
879
880
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887
888 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
889
890 #define SSI_OP (BITW(15)+BITW(11))
891
892
893 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
894 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
897 #define SSI_ITICKLE (ITICKLE >> 8)
898
899 #define SSI_IUNKWN (IUNKWN >> 8)
900 #define SSI_INO_CC (IUNKWN >> 8)
901 #define SSI_IRFAIL (IUNKWN >> 8)
902
903
904 #define NP 0x10 /*Next Phase */
905 #define NTCMD 0x02 /*Non- Tagged Command start */
906 #define CMDPZ 0x04 /*Command phase */
907 #define DINT 0x12 /*Data Out/In interrupt */
908 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 #define DC 0x19 /*Disconnect Message */
910 #define ST 0x1D /*Status Phase */
911 #define UNKNWN 0x24 /*Unknown bus action */
912 #define CC 0x25 /*Command Completion failure */
913 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
915
916
917 #define ID_MSG_STRT hp_aramBase + 0x00
918 #define NON_TAG_ID_MSG hp_aramBase + 0x06
919 #define CMD_STRT hp_aramBase + 0x08
920 #define SYNC_MSGS hp_aramBase + 0x08
921
922
923
924
925
926 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 #define DISCONNECT_START 0x10/2
928 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 #define SELCHK_STRT SELCHK/2
931
932
933
934
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935
936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800938
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939
940#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
941/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
942 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800943 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800945#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 -0700946 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800947 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800949 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 count >>= 16,\
951 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
953#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
954 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
955
956
957#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
958 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
959
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961
962#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
963 WR_HARPOON(port+hp_scsireset, 0x00))
964
965#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
966 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
967
968#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
969 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
970
971#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
972 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
973
974#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
975 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
976
977
978
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800980static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
981static void FPT_ssel(unsigned long port, unsigned char p_card);
982static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
983static void FPT_shandem(unsigned long port, unsigned char p_card,PSCCB pCurrSCCB);
984static void FPT_stsyncn(unsigned long port, unsigned char p_card);
985static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
986static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500987 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800988static void FPT_sresb(unsigned long port, unsigned char p_card);
989static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
990static void FPT_schkdd(unsigned long port, unsigned char p_card);
991static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
992static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
993static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800995static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800996static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
997 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800999static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001000static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001002static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
1003static void FPT_stwidn(unsigned long port, unsigned char p_card);
1004static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
1006
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001007static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1008static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001009static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001010 unsigned char p_card);
1011static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1012static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1013static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1014static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001015static void FPT_utilUpdateResidual(PSCCB p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001016static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001017static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001020static void FPT_Wait1Second(unsigned long p_port);
1021static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1022static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1023static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1024static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1025static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1026static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
1028
1029
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001030static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1031static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1032static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1033static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1034static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1035static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1036static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001038static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1039static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1040static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
1042
1043
1044
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001045static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1046static void FPT_BusMasterInit(unsigned long p_port);
1047static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049
1050
1051
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001052static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1053static void FPT_busMstrSGDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1054static void FPT_busMstrDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1055static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB);
James Bottomley 47b5d692005-04-24 02:38:05 -05001056static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
1058
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001059static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001060 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
James Bottomley 47b5d692005-04-24 02:38:05 -05001062static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001063static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1064static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
1066
1067
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001068static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001070static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1071static void FPT_scbusf(unsigned long p_port);
1072static void FPT_scsel(unsigned long p_port);
1073static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1074static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1075static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1076static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1077static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1078static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001079static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001080static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1081static void FPT_scwtsel(unsigned long p_port);
1082static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1083static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001084static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
1086
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001087static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1088static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
1090
1091
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
James Bottomley 47b5d692005-04-24 02:38:05 -05001093static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1094static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1095static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1096static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
1098
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001099static unsigned char FPT_mbCards = 0;
1100static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001101 ' ', 'B', 'T', '-', '9', '3', '0', \
1102 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1103 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001105static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106
1107
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001108static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
1111/*---------------------------------------------------------------------
1112 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001113 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 *
1115 * Description: Setup and/or Search for cards and return info to caller.
1116 *
1117 *---------------------------------------------------------------------*/
1118
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001119static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001121 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001123 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001124 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001125 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 PNVRamInfo pCurrNvRam;
1127
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129
1130
1131 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1132 return((int)FAILURE);
1133
1134 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1135 return((int)FAILURE);
1136
1137 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1138 return((int)FAILURE);
1139
1140 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1141 return((int)FAILURE);
1142
1143
1144 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1145
1146/* For new Harpoon then check for sub_device ID LSB
1147 the bits(0-3) must be all ZERO for compatible with
1148 current version of SCCBMgr, else skip this Harpoon
1149 device. */
1150
1151 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1152 return((int)FAILURE);
1153 }
1154
1155 if (first_time)
1156 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001157 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001159 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 }
1161
James Bottomley 47b5d692005-04-24 02:38:05 -05001162 if(FPT_RdStack(ioport, 0) != 0x00) {
1163 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 {
1165 pCurrNvRam = NULL;
1166 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001167 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1168 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 }
1170 else
1171 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001172 if(FPT_mbCards < MAX_MB_CARDS) {
1173 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1174 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001176 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 }else
1178 return((int) FAILURE);
1179 }
1180 }else
1181 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
1183 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1184 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1185
1186 if(pCurrNvRam)
1187 pCardInfo->si_id = pCurrNvRam->niAdapId;
1188 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001189 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1190 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
1192 pCardInfo->si_lun = 0x00;
1193 pCardInfo->si_fw_revision = ORION_FW_REV;
1194 temp2 = 0x0000;
1195 temp3 = 0x0000;
1196 temp4 = 0x0000;
1197 temp5 = 0x0000;
1198 temp6 = 0x0000;
1199
1200 for (id = 0; id < (16/2); id++) {
1201
1202 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001203 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1205 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1206 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001207 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
1209 for (i = 0; i < 2; temp >>=8,i++) {
1210
1211 temp2 >>= 1;
1212 temp3 >>= 1;
1213 temp4 >>= 1;
1214 temp5 >>= 1;
1215 temp6 >>= 1;
1216 switch (temp & 0x3)
1217 {
1218 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1219 temp6 |= 0x8000; /* Fall through */
1220 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1221 temp5 |= 0x8000; /* Fall through */
1222 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1223 temp2 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_00: /* Asynchronous */
1225 break;
1226 }
1227
1228 if (temp & DISC_ENABLE_BIT)
1229 temp3 |= 0x8000;
1230
1231 if (temp & WIDE_NEGO_BIT)
1232 temp4 |= 0x8000;
1233
1234 }
1235 }
1236
1237 pCardInfo->si_per_targ_init_sync = temp2;
1238 pCardInfo->si_per_targ_no_disc = temp3;
1239 pCardInfo->si_per_targ_wide_nego = temp4;
1240 pCardInfo->si_per_targ_fast_nego = temp5;
1241 pCardInfo->si_per_targ_ultra_nego = temp6;
1242
1243 if(pCurrNvRam)
1244 i = pCurrNvRam->niSysConf;
1245 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001246 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
1248 if(pCurrNvRam)
1249 ScamFlg = pCurrNvRam->niScamConf;
1250 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001251 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
1253 pCardInfo->si_flags = 0x0000;
1254
1255 if (i & 0x01)
1256 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1257
1258 if (!(i & 0x02))
1259 pCardInfo->si_flags |= SOFT_RESET;
1260
1261 if (i & 0x10)
1262 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1263
1264 if (ScamFlg & SCAM_ENABLED)
1265 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1266
1267 if (ScamFlg & SCAM_LEVEL2)
1268 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1269
1270 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1271 if (i & 0x04) {
1272 j |= SCSI_TERM_ENA_L;
1273 }
1274 WR_HARPOON(ioport+hp_bm_ctrl, j );
1275
1276 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1277 if (i & 0x08) {
1278 j |= SCSI_TERM_ENA_H;
1279 }
1280 WR_HARPOON(ioport+hp_ee_ctrl, j );
1281
1282 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1283
1284 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1285
1286 pCardInfo->si_card_family = HARPOON_FAMILY;
1287 pCardInfo->si_bustype = BUSTYPE_PCI;
1288
1289 if(pCurrNvRam){
1290 pCardInfo->si_card_model[0] = '9';
1291 switch(pCurrNvRam->niModel & 0x0f){
1292 case MODEL_LT:
1293 pCardInfo->si_card_model[1] = '3';
1294 pCardInfo->si_card_model[2] = '0';
1295 break;
1296 case MODEL_LW:
1297 pCardInfo->si_card_model[1] = '5';
1298 pCardInfo->si_card_model[2] = '0';
1299 break;
1300 case MODEL_DL:
1301 pCardInfo->si_card_model[1] = '3';
1302 pCardInfo->si_card_model[2] = '2';
1303 break;
1304 case MODEL_DW:
1305 pCardInfo->si_card_model[1] = '5';
1306 pCardInfo->si_card_model[2] = '2';
1307 break;
1308 }
1309 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001310 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001311 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001312 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001314 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1315 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 }
1317
1318 if (pCardInfo->si_card_model[1] == '3')
1319 {
1320 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1321 pCardInfo->si_flags |= LOW_BYTE_TERM;
1322 }
1323 else if (pCardInfo->si_card_model[2] == '0')
1324 {
1325 temp = RD_HARPOON(ioport+hp_xfer_pad);
1326 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1327 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1328 pCardInfo->si_flags |= LOW_BYTE_TERM;
1329 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1330 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1331 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1332 WR_HARPOON(ioport+hp_xfer_pad, temp);
1333 }
1334 else
1335 {
1336 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1337 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1338 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1339 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1340 temp3 = 0;
1341 for (i = 0; i < 8; i++)
1342 {
1343 temp3 <<= 1;
1344 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1345 temp3 |= 1;
1346 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1347 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1348 }
1349 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1350 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1351 if (!(temp3 & BIT(7)))
1352 pCardInfo->si_flags |= LOW_BYTE_TERM;
1353 if (!(temp3 & BIT(6)))
1354 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1355 }
1356
1357
1358 ARAM_ACCESS(ioport);
1359
1360 for ( i = 0; i < 4; i++ ) {
1361
1362 pCardInfo->si_XlatInfo[i] =
1363 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1364 }
1365
1366 /* return with -1 if no sort, else return with
1367 logical card number sorted by BIOS (zero-based) */
1368
1369 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001370 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
1372 SGRAM_ACCESS(ioport);
1373
James Bottomley 47b5d692005-04-24 02:38:05 -05001374 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1375 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1376 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1377 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1378 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1379 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1380 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1381 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382
1383 pCardInfo->si_present = 0x01;
1384
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 return(0);
1386}
1387
1388
1389/*---------------------------------------------------------------------
1390 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001391 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 *
1393 * Description: Setup adapter for normal operation (hard reset).
1394 *
1395 *---------------------------------------------------------------------*/
1396
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001397static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398{
1399 PSCCBcard CurrCard = NULL;
1400 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001401 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001402 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001403 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
1407 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1408
1409 if (thisCard == MAX_CARDS) {
1410
1411 return(FAILURE);
1412 }
1413
James Bottomley 47b5d692005-04-24 02:38:05 -05001414 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
James Bottomley 47b5d692005-04-24 02:38:05 -05001416 CurrCard = &FPT_BL_Card[thisCard];
1417 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 break;
1419 }
1420
James Bottomley 47b5d692005-04-24 02:38:05 -05001421 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
James Bottomley 47b5d692005-04-24 02:38:05 -05001423 FPT_BL_Card[thisCard].ioPort = ioport;
1424 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
James Bottomley 47b5d692005-04-24 02:38:05 -05001426 if(FPT_mbCards)
1427 for(i = 0; i < FPT_mbCards; i++){
1428 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1429 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001431 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 CurrCard->cardIndex = thisCard;
1433 CurrCard->cardInfo = pCardInfo;
1434
1435 break;
1436 }
1437 }
1438
1439 pCurrNvRam = CurrCard->pNvRamInfo;
1440
1441 if(pCurrNvRam){
1442 ScamFlg = pCurrNvRam->niScamConf;
1443 }
1444 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001445 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 }
1447
1448
James Bottomley 47b5d692005-04-24 02:38:05 -05001449 FPT_BusMasterInit(ioport);
1450 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451
James Bottomley 47b5d692005-04-24 02:38:05 -05001452 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
1454
1455 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1456
1457 WR_HARPOON(ioport+hp_selfid_0, id);
1458 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1459 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1460 CurrCard->ourId = pCardInfo->si_id;
1461
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001462 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 if (i & SCSI_PARITY_ENA)
1464 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1465
1466 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1467 if (i & LOW_BYTE_TERM)
1468 j |= SCSI_TERM_ENA_L;
1469 WR_HARPOON(ioport+hp_bm_ctrl, j);
1470
1471 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1472 if (i & HIGH_BYTE_TERM)
1473 j |= SCSI_TERM_ENA_H;
1474 WR_HARPOON(ioport+hp_ee_ctrl, j );
1475
1476
1477 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1478
James Bottomley 47b5d692005-04-24 02:38:05 -05001479 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
James Bottomley 47b5d692005-04-24 02:38:05 -05001481 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 }
1483
1484
1485
1486 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1487 CurrCard->globalFlags |= F_NO_FILTER;
1488
1489 if(pCurrNvRam){
1490 if(pCurrNvRam->niSysConf & 0x10)
1491 CurrCard->globalFlags |= F_GREEN_PC;
1492 }
1493 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001494 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 CurrCard->globalFlags |= F_GREEN_PC;
1496 }
1497
1498 /* Set global flag to indicate Re-Negotiation to be done on all
1499 ckeck condition */
1500 if(pCurrNvRam){
1501 if(pCurrNvRam->niScsiConf & 0x04)
1502 CurrCard->globalFlags |= F_DO_RENEGO;
1503 }
1504 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001505 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 CurrCard->globalFlags |= F_DO_RENEGO;
1507 }
1508
1509 if(pCurrNvRam){
1510 if(pCurrNvRam->niScsiConf & 0x08)
1511 CurrCard->globalFlags |= F_CONLUN_IO;
1512 }
1513 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001514 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 CurrCard->globalFlags |= F_CONLUN_IO;
1516 }
1517
1518
1519 temp = pCardInfo->si_per_targ_no_disc;
1520
1521 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1522
1523 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001524 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 }
1526
1527 sync_bit_map = 0x0001;
1528
1529 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1530
1531 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001532 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1534 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1535 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001536 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
1538 for (i = 0; i < 2; temp >>=8,i++) {
1539
1540 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1541
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001542 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 }
1544
1545 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001546 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1547 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001548 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 }
1550
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1552 (id*2+i >= 8)){
1553*/
1554 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1555
James Bottomley 47b5d692005-04-24 02:38:05 -05001556 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 }
1559
1560 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001561 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 }
1563
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564
1565 sync_bit_map <<= 1;
1566
1567
1568
1569 }
1570 }
1571
1572 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001573 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001575 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576}
1577
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001578static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001580 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001581 unsigned long portBase;
1582 unsigned long regOffset;
1583 unsigned long scamData;
1584 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 PNVRamInfo pCurrNvRam;
1586
1587 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1588
1589 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001590 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1591 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595
1596 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001597 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
1599 portBase = pCurrNvRam->niBaseAddr;
1600
1601 for(i = 0; i < MAX_SCSI_TAR; i++){
1602 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001603 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 scamData = *pScamTbl;
1605 WR_HARP32(portBase, regOffset, scamData);
1606 }
1607
1608 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001609 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 }
1611}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612
1613
James Bottomley 47b5d692005-04-24 02:38:05 -05001614static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001616 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001617 unsigned long portBase;
1618 unsigned long regOffset;
1619 unsigned long scamData;
1620 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
James Bottomley 47b5d692005-04-24 02:38:05 -05001622 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1623 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1624 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1625 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1626 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627
1628 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001629 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630
1631 portBase = pNvRamInfo->niBaseAddr;
1632
1633 for(i = 0; i < MAX_SCSI_TAR; i++){
1634 regOffset = hp_aramBase + 64 + i*4;
1635 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001636 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 *pScamTbl = scamData;
1638 }
1639
1640}
1641
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001642static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643{
1644 WR_HARPOON(portBase + hp_stack_addr, index);
1645 return(RD_HARPOON(portBase + hp_stack_data));
1646}
1647
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001648static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649{
1650 WR_HARPOON(portBase + hp_stack_addr, index);
1651 WR_HARPOON(portBase + hp_stack_data, data);
1652}
1653
1654
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001655static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656{
James Bottomley 47b5d692005-04-24 02:38:05 -05001657 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1658 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1660 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001661 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1663 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001664 return(1);
1665 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
1667}
1668/*---------------------------------------------------------------------
1669 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001670 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 *
1672 * Description: Start a command pointed to by p_Sccb. When the
1673 * command is completed it will be returned via the
1674 * callback function.
1675 *
1676 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001677static void FlashPoint_StartCCB(unsigned long pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001679 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001680 unsigned char thisCard, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 PSCCB pSaveSccb;
1682 CALL_BK_FN callback;
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1685 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1688 {
1689
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 p_Sccb->HostStatus = SCCB_COMPLETE;
1691 p_Sccb->SccbStatus = SCCB_ERROR;
1692 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1693 if (callback)
1694 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 return;
1697 }
1698
James Bottomley 47b5d692005-04-24 02:38:05 -05001699 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
1701
1702 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1703 {
1704 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1705 | SCCB_MGR_ACTIVE));
1706
1707 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1708 {
1709 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1710 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1711 }
1712 }
1713
1714 ((PSCCBcard)pCurrCard)->cmdCounter++;
1715
1716 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1717
1718 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1719 | TICKLE_ME));
1720 if(p_Sccb->OperationCode == RESET_COMMAND)
1721 {
1722 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1723 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001724 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1726 }
1727 else
1728 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001729 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 }
1731 }
1732
1733 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1734
1735 if(p_Sccb->OperationCode == RESET_COMMAND)
1736 {
1737 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1738 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001739 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1741 }
1742 else
1743 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001744 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 }
1746 }
1747
1748 else {
1749
1750 MDISABLE_INT(ioport);
1751
1752 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001753 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 lun = p_Sccb->Lun;
1755 else
1756 lun = 0;
1757 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001758 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1759 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1760 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761
1762 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001763 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 }
1765
1766 else {
1767
1768 if(p_Sccb->OperationCode == RESET_COMMAND)
1769 {
1770 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1771 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001772 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1774 }
1775 else
1776 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001777 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 }
1779 }
1780
1781
1782 MENABLE_INT(ioport);
1783 }
1784
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785}
1786
1787
1788/*---------------------------------------------------------------------
1789 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001790 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 *
1792 * Description: Abort the command pointed to by p_Sccb. When the
1793 * command is completed it will be returned via the
1794 * callback function.
1795 *
1796 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001797static int FlashPoint_AbortCCB(unsigned long pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001799 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001801 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001803 unsigned char TID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 PSCCB pSaveSCCB;
1805 PSCCBMgr_tar_info currTar_Info;
1806
1807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1809
1810 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1811
James Bottomley 47b5d692005-04-24 02:38:05 -05001812 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 {
1814
James Bottomley 47b5d692005-04-24 02:38:05 -05001815 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 {
1817
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 ((PSCCBcard)pCurrCard)->cmdCounter--;
1819
1820 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1821 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001822 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 p_Sccb->SccbStatus = SCCB_ABORT;
1825 callback = p_Sccb->SccbCallback;
1826 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827
1828 return(0);
1829 }
1830
1831 else
1832 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1834 {
1835 p_Sccb->SccbStatus = SCCB_ABORT;
1836 return(0);
1837
1838 }
1839
1840 else
1841 {
1842
1843 TID = p_Sccb->TargID;
1844
1845
1846 if(p_Sccb->Sccb_tag)
1847 {
1848 MDISABLE_INT(ioport);
1849 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1850 {
1851 p_Sccb->SccbStatus = SCCB_ABORT;
1852 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1854
1855 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1856 {
1857 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001858 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 }
1860 else
1861 {
1862 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1863 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001864 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1866 }
1867 }
1868 MENABLE_INT(ioport);
1869 return(0);
1870 }
1871 else
1872 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001873 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874
James Bottomley 47b5d692005-04-24 02:38:05 -05001875 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 == p_Sccb)
1877 {
1878 p_Sccb->SccbStatus = SCCB_ABORT;
1879 return(0);
1880 }
1881 }
1882 }
1883 }
1884 }
1885 return(-1);
1886}
1887
1888
1889/*---------------------------------------------------------------------
1890 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001891 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 *
1893 * Description: Do a quick check to determine if there is a pending
1894 * interrupt for this card and disable the IRQ Pin if so.
1895 *
1896 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001897static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001899 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
1901 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1902
1903 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1904 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001905 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 }
1907
1908 else
1909
James Bottomley 47b5d692005-04-24 02:38:05 -05001910 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911}
1912
1913
1914
1915/*---------------------------------------------------------------------
1916 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001917 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 *
1919 * Description: This is our entry point when an interrupt is generated
1920 * by the card and the upper level driver passes it on to
1921 * us.
1922 *
1923 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001924static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925{
1926 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001927 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001928 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001929 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001930 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
1932 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1933 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1934
1935 MDISABLE_INT(ioport);
1936
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001938 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 else
1940 bm_status = 0;
1941
1942 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1943
James Bottomley 47b5d692005-04-24 02:38:05 -05001944 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 bm_status)
1946 {
1947
1948 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1949
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001951 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1953 bm_status = 0;
1954
1955 if (result) {
1956
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 return(result);
1959 }
1960 }
1961
1962
1963 else if (hp_int & ICMD_COMP) {
1964
1965 if ( !(hp_int & BUS_FREE) ) {
1966 /* Wait for the BusFree before starting a new command. We
1967 must also check for being reselected since the BusFree
1968 may not show up if another device reselects us in 1.5us or
1969 less. SRR Wednesday, 3/8/1995.
1970 */
1971 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1972 }
1973
1974 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1975
James Bottomley 47b5d692005-04-24 02:38:05 -05001976 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
1978/* WRW_HARPOON((ioport+hp_intstat),
1979 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1980 */
1981
1982 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1983
James Bottomley 47b5d692005-04-24 02:38:05 -05001984 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
1986 }
1987
1988
1989 else if (hp_int & ITAR_DISC)
1990 {
1991
1992 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1993
James Bottomley 47b5d692005-04-24 02:38:05 -05001994 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995
1996 }
1997
1998 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1999
2000 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2001 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2002
2003 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2004 }
2005
2006 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002007 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008
2009 /* Wait for the BusFree before starting a new command. We
2010 must also check for being reselected since the BusFree
2011 may not show up if another device reselects us in 1.5us or
2012 less. SRR Wednesday, 3/8/1995.
2013 */
2014 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2015 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2016 RD_HARPOON((ioport+hp_scsisig)) ==
2017 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2018
2019 /*
2020 The additional loop exit condition above detects a timing problem
2021 with the revision D/E harpoon chips. The caller should reset the
2022 host adapter to recover when 0xFE is returned.
2023 */
2024 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2025 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 return 0xFE;
2028 }
2029
2030 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2031
2032
2033 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2034
2035 }
2036
2037
2038 else if (hp_int & RSEL) {
2039
2040 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2041
2042 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2043 {
2044 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2045 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002046 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 }
2048
2049 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2050 {
2051 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2052 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2053 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2054 }
2055
2056 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2057 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002058 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059 }
2060
James Bottomley 47b5d692005-04-24 02:38:05 -05002061 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2062 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
2064 }
2065
2066
2067 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2068 {
2069
2070 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002071 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072
2073 }
2074
2075
2076 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2077 {
2078 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002079 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002081 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 }
2083 else
2084 {
2085 /* Harpoon problem some SCSI target device respond to selection
2086 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2087 to latch the correct Target ID into reg. x53.
2088 The work around require to correct this reg. But when write to this
2089 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2090 need to read this reg first then restore it later. After update to 0x53 */
2091
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002092 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2093 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2094 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2095 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2096 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 WR_HARPOON(ioport+hp_fifowrite, i);
2098 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2099 }
2100 }
2101
2102 else if (hp_int & XFER_CNT_0) {
2103
2104 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2105
James Bottomley 47b5d692005-04-24 02:38:05 -05002106 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107
2108 }
2109
2110
2111 else if (hp_int & BUS_FREE) {
2112
2113 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2114
2115 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2116
James Bottomley 47b5d692005-04-24 02:38:05 -05002117 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 }
2119
James Bottomley 47b5d692005-04-24 02:38:05 -05002120 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002121 }
2122
2123
2124 else if (hp_int & ITICKLE) {
2125
2126 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2127 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2128 }
2129
2130
2131
2132 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2133
2134
2135 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2136
2137
2138 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2139
James Bottomley 47b5d692005-04-24 02:38:05 -05002140 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 }
2142
2143 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2144 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002145 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146 }
2147
2148 break;
2149
2150 }
2151
2152 } /*end while */
2153
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155
2156 return(0);
2157}
2158
2159/*---------------------------------------------------------------------
2160 *
2161 * Function: Sccb_bad_isr
2162 *
2163 * Description: Some type of interrupt has occurred which is slightly
2164 * out of the ordinary. We will now decode it fully, in
2165 * this routine. This is broken up in an attempt to save
2166 * processing time.
2167 *
2168 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002169static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002170 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002172 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002173 PSCCBMgr_tar_info currTar_Info;
2174 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
2176
2177 if (RD_HARPOON(p_port+hp_ext_status) &
2178 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2179 {
2180
2181 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2182 {
2183
James Bottomley 47b5d692005-04-24 02:38:05 -05002184 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185 }
2186
2187 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2188
2189 {
2190 WR_HARPOON(p_port+hp_pci_stat_cfg,
2191 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2192
2193 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2194
2195 }
2196
2197 if (pCurrCard->currentSCCB != NULL)
2198 {
2199
2200 if (!pCurrCard->currentSCCB->HostStatus)
2201 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2202
James Bottomley 47b5d692005-04-24 02:38:05 -05002203 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002205 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002207 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2209
2210 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2211 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002212 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213 }
2214 }
2215 }
2216
2217
2218 else if (p_int & RESET)
2219 {
2220
2221 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2222 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2223 if (pCurrCard->currentSCCB != NULL) {
2224
2225 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2226
James Bottomley 47b5d692005-04-24 02:38:05 -05002227 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 }
2229
2230
2231 DISABLE_AUTO(p_port);
2232
James Bottomley 47b5d692005-04-24 02:38:05 -05002233 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234
2235 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2236
2237 pCurrNvRam = pCurrCard->pNvRamInfo;
2238 if(pCurrNvRam){
2239 ScamFlg = pCurrNvRam->niScamConf;
2240 }
2241 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002242 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 }
2244
James Bottomley 47b5d692005-04-24 02:38:05 -05002245 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246
James Bottomley 47b5d692005-04-24 02:38:05 -05002247 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248
2249 return(0xFF);
2250 }
2251
2252
2253 else if (p_int & FIFO) {
2254
2255 WRW_HARPOON((p_port+hp_intstat), FIFO);
2256
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002258 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 }
2260
2261 else if (p_int & TIMEOUT)
2262 {
2263
2264 DISABLE_AUTO(p_port);
2265
2266 WRW_HARPOON((p_port+hp_intstat),
2267 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2268
2269 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2270
2271
James Bottomley 47b5d692005-04-24 02:38:05 -05002272 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2274 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002275 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002277 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
2279
2280 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2281 {
2282 currTar_Info->TarSyncCtrl = 0;
2283 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2284 }
2285
2286 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2287 {
2288 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2289 }
2290
James Bottomley 47b5d692005-04-24 02:38:05 -05002291 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
James Bottomley 47b5d692005-04-24 02:38:05 -05002293 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
2295 }
2296
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297 else if (p_int & SCAM_SEL)
2298 {
2299
James Bottomley 47b5d692005-04-24 02:38:05 -05002300 FPT_scarb(p_port,LEVEL2_TAR);
2301 FPT_scsel(p_port);
2302 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303
James Bottomley 47b5d692005-04-24 02:38:05 -05002304 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305
2306 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2307 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308
2309 return(0x00);
2310}
2311
2312
2313/*---------------------------------------------------------------------
2314 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 * Function: SccbMgrTableInit
2316 *
2317 * Description: Initialize all Sccb manager data structures.
2318 *
2319 *---------------------------------------------------------------------*/
2320
James Bottomley 47b5d692005-04-24 02:38:05 -05002321static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002323 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324
2325 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2326 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002327 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
James Bottomley 47b5d692005-04-24 02:38:05 -05002329 FPT_BL_Card[thisCard].ioPort = 0x00;
2330 FPT_BL_Card[thisCard].cardInfo = NULL;
2331 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2332 FPT_BL_Card[thisCard].ourId = 0x00;
2333 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 }
2335}
2336
2337
2338/*---------------------------------------------------------------------
2339 *
2340 * Function: SccbMgrTableInit
2341 *
2342 * Description: Initialize all Sccb manager data structures.
2343 *
2344 *---------------------------------------------------------------------*/
2345
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002346static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002348 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349
2350 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2351 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002352 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353 }
2354
2355 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2356 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002357 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2358 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2359 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 }
2361
2362 pCurrCard->scanIndex = 0x00;
2363 pCurrCard->currentSCCB = NULL;
2364 pCurrCard->globalFlags = 0x00;
2365 pCurrCard->cmdCounter = 0x00;
2366 pCurrCard->tagQ_Lst = 0x01;
2367 pCurrCard->discQCount = 0;
2368
2369
2370}
2371
2372
2373/*---------------------------------------------------------------------
2374 *
2375 * Function: SccbMgrTableInit
2376 *
2377 * Description: Initialize all Sccb manager data structures.
2378 *
2379 *---------------------------------------------------------------------*/
2380
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002381static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382{
2383
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002384 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385 PSCCBMgr_tar_info currTar_Info;
2386
James Bottomley 47b5d692005-04-24 02:38:05 -05002387 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388
2389 currTar_Info->TarSelQ_Cnt = 0;
2390 currTar_Info->TarSyncCtrl = 0;
2391
2392 currTar_Info->TarSelQ_Head = NULL;
2393 currTar_Info->TarSelQ_Tail = NULL;
2394 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002395 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396
2397
2398 for (lun = 0; lun < MAX_LUN; lun++)
2399 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002400 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 currTar_Info->LunDiscQ_Idx[lun] = 0;
2402 }
2403
2404 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2405 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002406 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002408 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002410 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2411 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 }
2413 }
2414 }
2415}
2416
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417
2418/*---------------------------------------------------------------------
2419 *
2420 * Function: sfetm
2421 *
2422 * Description: Read in a message byte from the SCSI bus, and check
2423 * for a parity error.
2424 *
2425 *---------------------------------------------------------------------*/
2426
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002427static unsigned char FPT_sfm(unsigned long port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002429 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002430 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002431
2432 TimeOutLoop = 0;
2433 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2434 (TimeOutLoop++ < 20000) ){}
2435
2436
2437 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2438
2439 message = RD_HARPOON(port+hp_scsidata_0);
2440
2441 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2442
2443
2444 if (TimeOutLoop > 20000)
2445 message = 0x00; /* force message byte = 0 if Time Out on Req */
2446
2447 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2448 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2449 {
2450 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2451 WR_HARPOON(port+hp_xferstat, 0);
2452 WR_HARPOON(port+hp_fiforead, 0);
2453 WR_HARPOON(port+hp_fifowrite, 0);
2454 if (pCurrSCCB != NULL)
2455 {
2456 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2457 }
2458 message = 0x00;
2459 do
2460 {
2461 ACCEPT_MSG_ATN(port);
2462 TimeOutLoop = 0;
2463 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2464 (TimeOutLoop++ < 20000) ){}
2465 if (TimeOutLoop > 20000)
2466 {
2467 WRW_HARPOON((port+hp_intstat), PARITY);
2468 return(message);
2469 }
2470 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2471 {
2472 WRW_HARPOON((port+hp_intstat), PARITY);
2473 return(message);
2474 }
2475 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2476
2477 RD_HARPOON(port+hp_scsidata_0);
2478
2479 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2480
2481 }while(1);
2482
2483 }
2484 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2485 WR_HARPOON(port+hp_xferstat, 0);
2486 WR_HARPOON(port+hp_fiforead, 0);
2487 WR_HARPOON(port+hp_fifowrite, 0);
2488 return(message);
2489}
2490
2491
2492/*---------------------------------------------------------------------
2493 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002494 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 *
2496 * Description: Load up automation and select target device.
2497 *
2498 *---------------------------------------------------------------------*/
2499
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002500static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501{
2502
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002503 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002505 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 PSCCBcard CurrCard;
2507 PSCCB currSCCB;
2508 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002509 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510
James Bottomley 47b5d692005-04-24 02:38:05 -05002511 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512 currSCCB = CurrCard->currentSCCB;
2513 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002514 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 lastTag = CurrCard->tagQ_Lst;
2516
2517 ARAM_ACCESS(port);
2518
2519
2520 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2521 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2522
2523 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2524 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2525
2526 lun = currSCCB->Lun;
2527 else
2528 lun = 0;
2529
2530
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 if (CurrCard->globalFlags & F_TAG_STARTED)
2532 {
2533 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2534 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002535 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2537 == TAG_Q_TRYING))
2538 {
2539
2540 if (currTar_Info->TarTagQ_Cnt !=0)
2541 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002542 currTar_Info->TarLUNBusy[lun] = 1;
2543 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 SGRAM_ACCESS(port);
2545 return;
2546 }
2547
2548 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002549 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 }
2551
2552 } /*End non-tagged */
2553
2554 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002555 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556 }
2557
2558 } /*!Use cmd Q Tagged */
2559
2560 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002561 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002563 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 SGRAM_ACCESS(port);
2565 return;
2566 }
2567
James Bottomley 47b5d692005-04-24 02:38:05 -05002568 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
2570 } /*else use cmd Q tagged */
2571
2572 } /*if glob tagged started */
2573
2574 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002575 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 }
2577
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
2579
2580 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2581 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2582 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2583 {
2584 if(CurrCard->discQCount >= QUEUE_DEPTH)
2585 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002586 currTar_Info->TarLUNBusy[lun] = 1;
2587 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588 SGRAM_ACCESS(port);
2589 return;
2590 }
2591 for (i = 1; i < QUEUE_DEPTH; i++)
2592 {
2593 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2594 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2595 {
2596 CurrCard->tagQ_Lst = lastTag;
2597 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2598 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2599 CurrCard->discQCount++;
2600 break;
2601 }
2602 }
2603 if(i == QUEUE_DEPTH)
2604 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002605 currTar_Info->TarLUNBusy[lun] = 1;
2606 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 SGRAM_ACCESS(port);
2608 return;
2609 }
2610 }
2611
2612
2613
James Bottomley 47b5d692005-04-24 02:38:05 -05002614 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615
2616 WR_HARPOON(port+hp_select_id, target);
2617 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2618
2619 if (currSCCB->OperationCode == RESET_COMMAND) {
2620 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2621 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2622
2623 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2624
2625 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2626
2627 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002628 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2630
2631 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2632 {
2633 currTar_Info->TarSyncCtrl = 0;
2634 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2635 }
2636
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2638 {
2639 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2640 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641
James Bottomley 47b5d692005-04-24 02:38:05 -05002642 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2643 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644
2645 }
2646
2647 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2648 {
2649 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2650 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2651
2652 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2653
2654 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002655 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2656 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657 WRW_HARPOON((port+SYNC_MSGS+2),
2658 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2659 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2660
2661 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002662 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663
2664 }
2665
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002667 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2669 }
2670
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2672 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002673 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2675 }
2676
2677
2678 if (!auto_loaded)
2679 {
2680
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 if (currSCCB->ControlByte & F_USE_CMD_Q)
2682 {
2683
2684 CurrCard->globalFlags |= F_TAG_STARTED;
2685
2686 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2687 == TAG_Q_REJECT)
2688 {
2689 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2690
2691 /* Fix up the start instruction with a jump to
2692 Non-Tag-CMD handling */
2693 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2694
2695 WRW_HARPOON((port+NON_TAG_ID_MSG),
2696 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2697
2698 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2699
2700 /* Setup our STATE so we know what happend when
2701 the wheels fall off. */
2702 currSCCB->Sccb_scsistat = SELECT_ST;
2703
James Bottomley 47b5d692005-04-24 02:38:05 -05002704 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 }
2706
2707 else
2708 {
2709 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2710
2711 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002712 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2713 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714
2715 for (i = 1; i < QUEUE_DEPTH; i++)
2716 {
2717 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2718 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2719 {
2720 WRW_HARPOON((port+ID_MSG_STRT+6),
2721 (MPM_OP+AMSG_OUT+lastTag));
2722 CurrCard->tagQ_Lst = lastTag;
2723 currSCCB->Sccb_tag = lastTag;
2724 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2725 CurrCard->discQCount++;
2726 break;
2727 }
2728 }
2729
2730
2731 if ( i == QUEUE_DEPTH )
2732 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002733 currTar_Info->TarLUNBusy[lun] = 1;
2734 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735 SGRAM_ACCESS(port);
2736 return;
2737 }
2738
2739 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2740
2741 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2742 }
2743 }
2744
2745 else
2746 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747
2748 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2749
2750 WRW_HARPOON((port+NON_TAG_ID_MSG),
2751 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2752
2753 currSCCB->Sccb_scsistat = SELECT_ST;
2754
2755 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757
2758
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002759 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760
2761 cdb_reg = port + CMD_STRT;
2762
2763 for (i=0; i < currSCCB->CdbLength; i++)
2764 {
2765 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2766 cdb_reg +=2;
2767 theCCB++;
2768 }
2769
2770 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2771 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2772
2773 } /* auto_loaded */
2774
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002775 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777
2778 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2779
2780 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2781
2782
2783 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2784 {
2785 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2786 }
2787 else
2788 {
2789
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002790/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791 auto_loaded |= AUTO_IMMED; */
2792 auto_loaded = AUTO_IMMED;
2793
2794 DISABLE_AUTO(port);
2795
2796 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2797 }
2798
2799 SGRAM_ACCESS(port);
2800}
2801
2802
2803/*---------------------------------------------------------------------
2804 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002805 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806 *
2807 * Description: Hookup the correct CCB and handle the incoming messages.
2808 *
2809 *---------------------------------------------------------------------*/
2810
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002811static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812{
2813
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002814 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815
2816
2817 PSCCBMgr_tar_info currTar_Info;
2818 PSCCB currSCCB;
2819
2820
2821
2822
2823 if(pCurrCard->currentSCCB != NULL)
2824 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002825 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 DISABLE_AUTO(port);
2827
2828
2829 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2830
2831
2832 currSCCB = pCurrCard->currentSCCB;
2833 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2834 {
2835 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2836 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2837 }
2838 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2839 {
2840 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2841 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2842 }
2843 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2844 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2845 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002846 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 if(currSCCB->Sccb_scsistat != ABORT_ST)
2848 {
2849 pCurrCard->discQCount--;
2850 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2851 = NULL;
2852 }
2853 }
2854 else
2855 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002856 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 if(currSCCB->Sccb_tag)
2858 {
2859 if(currSCCB->Sccb_scsistat != ABORT_ST)
2860 {
2861 pCurrCard->discQCount--;
2862 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2863 }
2864 }else
2865 {
2866 if(currSCCB->Sccb_scsistat != ABORT_ST)
2867 {
2868 pCurrCard->discQCount--;
2869 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2870 }
2871 }
2872 }
2873
James Bottomley 47b5d692005-04-24 02:38:05 -05002874 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 }
2876
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002877 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878
2879
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002880 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002881 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882
2883
2884 msgRetryCount = 0;
2885 do
2886 {
2887
James Bottomley 47b5d692005-04-24 02:38:05 -05002888 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 tag = 0;
2890
2891
2892 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2893 {
2894 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2895 {
2896
2897 WRW_HARPOON((port+hp_intstat), PHASE);
2898 return;
2899 }
2900 }
2901
2902 WRW_HARPOON((port+hp_intstat), PHASE);
2903 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2904 {
2905
James Bottomley 47b5d692005-04-24 02:38:05 -05002906 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 if (message)
2908 {
2909
2910 if (message <= (0x80 | LUN_MASK))
2911 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002912 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2915 {
2916 if (currTar_Info->TarTagQ_Cnt != 0)
2917 {
2918
2919 if (!(currTar_Info->TarLUN_CA))
2920 {
2921 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2922
2923
James Bottomley 47b5d692005-04-24 02:38:05 -05002924 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 if (message)
2926 {
2927 ACCEPT_MSG(port);
2928 }
2929
2930 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002931 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932
James Bottomley 47b5d692005-04-24 02:38:05 -05002933 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002935 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936
2937 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002938 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 }
2940
2941 } /*C.A. exists! */
2942
2943 } /*End Q cnt != 0 */
2944
2945 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 } /*End valid ID message. */
2948
2949 else
2950 {
2951
2952 ACCEPT_MSG_ATN(port);
2953 }
2954
2955 } /* End good id message. */
2956
2957 else
2958 {
2959
James Bottomley 47b5d692005-04-24 02:38:05 -05002960 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 }
2962 }
2963 else
2964 {
2965 ACCEPT_MSG_ATN(port);
2966
2967 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2968 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2969 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2970
2971 return;
2972 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973
James Bottomley 47b5d692005-04-24 02:38:05 -05002974 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 {
2976 msgRetryCount++;
2977 if(msgRetryCount == 1)
2978 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002979 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 }
2981 else
2982 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002983 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984
James Bottomley 47b5d692005-04-24 02:38:05 -05002985 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986
James Bottomley 47b5d692005-04-24 02:38:05 -05002987 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 {
2989
James Bottomley 47b5d692005-04-24 02:38:05 -05002990 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991
2992 }
2993
James Bottomley 47b5d692005-04-24 02:38:05 -05002994 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 {
2996
James Bottomley 47b5d692005-04-24 02:38:05 -05002997 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 }
2999
3000
James Bottomley 47b5d692005-04-24 02:38:05 -05003001 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3002 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 return;
3004 }
3005 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003006 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007
3008
3009
3010 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3011 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3012 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003013 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3015 if(pCurrCard->currentSCCB != NULL)
3016 {
3017 ACCEPT_MSG(port);
3018 }
3019 else
3020 {
3021 ACCEPT_MSG_ATN(port);
3022 }
3023 }
3024 else
3025 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003026 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027
3028
3029 if (tag)
3030 {
3031 if (pCurrCard->discQ_Tbl[tag] != NULL)
3032 {
3033 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3034 currTar_Info->TarTagQ_Cnt--;
3035 ACCEPT_MSG(port);
3036 }
3037 else
3038 {
3039 ACCEPT_MSG_ATN(port);
3040 }
3041 }else
3042 {
3043 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3044 if(pCurrCard->currentSCCB != NULL)
3045 {
3046 ACCEPT_MSG(port);
3047 }
3048 else
3049 {
3050 ACCEPT_MSG_ATN(port);
3051 }
3052 }
3053 }
3054
3055 if(pCurrCard->currentSCCB != NULL)
3056 {
3057 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3058 {
3059 /* During Abort Tag command, the target could have got re-selected
3060 and completed the command. Check the select Q and remove the CCB
3061 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003062 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063 }
3064 }
3065
3066
3067 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3068 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3069 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3070}
3071
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003072static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073{
3074 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3075 {
3076 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3077 {
3078
3079 WRW_HARPOON((port+hp_intstat), PHASE);
3080 return;
3081 }
3082 }
3083
3084 WRW_HARPOON((port+hp_intstat), PHASE);
3085 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3086 {
3087 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3088
3089
3090 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3091
3092 WR_HARPOON(port+hp_scsidata_0,message);
3093
3094 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3095
3096 ACCEPT_MSG(port);
3097
3098 WR_HARPOON(port+hp_portctrl_0, 0x00);
3099
3100 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3101 (message == SMABORT_TAG) )
3102 {
3103 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3104
3105 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3106 {
3107 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3108 }
3109 }
3110 }
3111}
3112
3113/*---------------------------------------------------------------------
3114 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003115 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116 *
3117 * Description: Determine the proper responce to the message from the
3118 * target device.
3119 *
3120 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003121static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122{
3123 PSCCB currSCCB;
3124 PSCCBcard CurrCard;
3125 PSCCBMgr_tar_info currTar_Info;
3126
James Bottomley 47b5d692005-04-24 02:38:05 -05003127 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128 currSCCB = CurrCard->currentSCCB;
3129
James Bottomley 47b5d692005-04-24 02:38:05 -05003130 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131
3132 if (message == SMREST_DATA_PTR)
3133 {
3134 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3135 {
3136 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3137
James Bottomley 47b5d692005-04-24 02:38:05 -05003138 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 }
3140
3141 ACCEPT_MSG(port);
3142 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3143 }
3144
3145 else if (message == SMCMD_COMP)
3146 {
3147
3148
3149 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3150 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003151 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3152 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153 }
3154
3155 ACCEPT_MSG(port);
3156
3157 }
3158
3159 else if ((message == SMNO_OP) || (message >= SMIDENT)
3160 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3161 {
3162
3163 ACCEPT_MSG(port);
3164 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3165 }
3166
3167 else if (message == SMREJECT)
3168 {
3169
3170 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3171 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3172 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3173 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3174
3175 {
3176 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3177
3178 ACCEPT_MSG(port);
3179
3180
3181 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3182 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3183
3184 if(currSCCB->Lun == 0x00)
3185 {
3186 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3187 {
3188
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003189 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190
3191 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3192 }
3193
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3195 {
3196
3197
3198 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3199 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3200
3201 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3202
3203 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204
3205 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3206 {
3207 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003208 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209
3210
3211 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3212 CurrCard->discQCount--;
3213 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3214 currSCCB->Sccb_tag = 0x00;
3215
3216 }
3217 }
3218
3219 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3220 {
3221
3222
3223 if(currSCCB->Lun == 0x00)
3224 {
3225 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3226 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3227 }
3228 }
3229
3230 else
3231 {
3232
3233 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3234 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003235 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003237 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238
3239
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003240 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241
3242 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3243
3244 }
3245 }
3246
3247 else
3248 {
3249 ACCEPT_MSG(port);
3250
3251 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3252 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3253
3254 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3255 {
3256 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3257 }
3258 }
3259 }
3260
3261 else if (message == SMEXT)
3262 {
3263
3264 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003265 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003266 }
3267
3268 else if (message == SMIGNORWR)
3269 {
3270
3271 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3272
James Bottomley 47b5d692005-04-24 02:38:05 -05003273 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274
3275 if(currSCCB->Sccb_scsimsg != SMPARITY)
3276 ACCEPT_MSG(port);
3277 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3278 }
3279
3280
3281 else
3282 {
3283
3284 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3285 currSCCB->Sccb_scsimsg = SMREJECT;
3286
3287 ACCEPT_MSG_ATN(port);
3288 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3289 }
3290}
3291
3292
3293/*---------------------------------------------------------------------
3294 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003295 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296 *
3297 * Description: Decide what to do with the extended message.
3298 *
3299 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003300static void FPT_shandem(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003302 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003303
James Bottomley 47b5d692005-04-24 02:38:05 -05003304 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305 if (length)
3306 {
3307
3308 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003309 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310 if (message)
3311 {
3312
3313 if (message == SMSYNC)
3314 {
3315
3316 if (length == 0x03)
3317 {
3318
3319 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003320 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321 }
3322 else
3323 {
3324
3325 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3326 ACCEPT_MSG_ATN(port);
3327 }
3328 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003329 else if (message == SMWDTR)
3330 {
3331
3332 if (length == 0x02)
3333 {
3334
3335 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003336 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 }
3338 else
3339 {
3340
3341 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3342 ACCEPT_MSG_ATN(port);
3343
3344 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3345 }
3346 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347 else
3348 {
3349
3350 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3351 ACCEPT_MSG_ATN(port);
3352
3353 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3354 }
3355 }
3356 else
3357 {
3358 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3359 ACCEPT_MSG(port);
3360 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3361 }
3362 }else
3363 {
3364 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3365 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3366 }
3367}
3368
3369
3370/*---------------------------------------------------------------------
3371 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003372 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373 *
3374 * Description: Read in a message byte from the SCSI bus, and check
3375 * for a parity error.
3376 *
3377 *---------------------------------------------------------------------*/
3378
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003379static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380{
3381 PSCCB currSCCB;
3382 PSCCBMgr_tar_info currTar_Info;
3383
James Bottomley 47b5d692005-04-24 02:38:05 -05003384 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3385 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003386
3387 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3388
3389
3390 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003391 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392
3393 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3394
3395 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3396 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3397 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3398
3399
3400 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3401
3402 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3403
3404 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3405
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3407
3408 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3409
3410 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3411
3412 else
3413 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3414
3415
3416 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3417 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3418 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3419
3420
James Bottomley 47b5d692005-04-24 02:38:05 -05003421 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 {
3423 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3424 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003425 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 }
3427 else
3428 {
3429 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3430 }
3431
3432
James Bottomley 47b5d692005-04-24 02:38:05 -05003433 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 }
3435
3436 else {
3437
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003438 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003440 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003441 }
3442}
3443
3444
3445
3446/*---------------------------------------------------------------------
3447 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003448 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 *
3450 * Description: The has sent us a Sync Nego message so handle it as
3451 * necessary.
3452 *
3453 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003454static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003456 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457 PSCCB currSCCB;
3458 PSCCBMgr_tar_info currTar_Info;
3459
James Bottomley 47b5d692005-04-24 02:38:05 -05003460 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3461 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003462
James Bottomley 47b5d692005-04-24 02:38:05 -05003463 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464
3465 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3466 {
3467 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3468 return;
3469 }
3470
3471 ACCEPT_MSG(port);
3472
3473
James Bottomley 47b5d692005-04-24 02:38:05 -05003474 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475
3476 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3477 {
3478 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3479 return;
3480 }
3481
3482 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3483
3484 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3485
3486 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3487
3488 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3489
3490 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3491
3492 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3493 else
3494
3495 our_sync_msg = 0; /* Message = Async */
3496
3497 if (sync_msg < our_sync_msg) {
3498 sync_msg = our_sync_msg; /*if faster, then set to max. */
3499 }
3500
3501 if (offset == ASYNC)
3502 sync_msg = ASYNC;
3503
3504 if (offset > MAX_OFFSET)
3505 offset = MAX_OFFSET;
3506
3507 sync_reg = 0x00;
3508
3509 if (sync_msg > 12)
3510
3511 sync_reg = 0x20; /* Use 10MB/s */
3512
3513 if (sync_msg > 25)
3514
3515 sync_reg = 0x40; /* Use 6.6MB/s */
3516
3517 if (sync_msg > 38)
3518
3519 sync_reg = 0x60; /* Use 5MB/s */
3520
3521 if (sync_msg > 50)
3522
3523 sync_reg = 0x80; /* Use 4MB/s */
3524
3525 if (sync_msg > 62)
3526
3527 sync_reg = 0xA0; /* Use 3.33MB/s */
3528
3529 if (sync_msg > 75)
3530
3531 sync_reg = 0xC0; /* Use 2.85MB/s */
3532
3533 if (sync_msg > 87)
3534
3535 sync_reg = 0xE0; /* Use 2.5MB/s */
3536
3537 if (sync_msg > 100) {
3538
3539 sync_reg = 0x00; /* Use ASYNC */
3540 offset = 0x00;
3541 }
3542
3543
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544 if (currTar_Info->TarStatus & WIDE_ENABLED)
3545
3546 sync_reg |= offset;
3547
3548 else
3549
3550 sync_reg |= (offset | NARROW_SCSI);
3551
James Bottomley 47b5d692005-04-24 02:38:05 -05003552 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553
3554
3555 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3556
3557
3558 ACCEPT_MSG(port);
3559
3560 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003561 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562
3563 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3564 }
3565
3566 else {
3567
3568
3569 ACCEPT_MSG_ATN(port);
3570
James Bottomley 47b5d692005-04-24 02:38:05 -05003571 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572
3573 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003574 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575 }
3576}
3577
3578
3579/*---------------------------------------------------------------------
3580 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003581 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003582 *
3583 * Description: Answer the targets sync message.
3584 *
3585 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003586static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003587{
3588 ARAM_ACCESS(port);
3589 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3590 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3591 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3592 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3593 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3594 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3595 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3596 SGRAM_ACCESS(port);
3597
3598 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3599 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3600
3601 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3602
3603 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3604}
3605
3606
3607
Linus Torvalds1da177e2005-04-16 15:20:36 -07003608/*---------------------------------------------------------------------
3609 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003610 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611 *
3612 * Description: Read in a message byte from the SCSI bus, and check
3613 * for a parity error.
3614 *
3615 *---------------------------------------------------------------------*/
3616
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003617static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618{
3619 PSCCB currSCCB;
3620 PSCCBMgr_tar_info currTar_Info;
3621
James Bottomley 47b5d692005-04-24 02:38:05 -05003622 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3623 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003624
3625 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3626
3627
3628 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003629 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630
3631 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3632
3633 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3634 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3635 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3636 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3637 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3638 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3639
3640 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3641
3642
3643 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003644 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645
James Bottomley 47b5d692005-04-24 02:38:05 -05003646 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647 }
3648
3649 else {
3650
3651 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003652 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653
3654 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003655 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656 }
3657}
3658
3659
3660
3661/*---------------------------------------------------------------------
3662 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003663 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 *
3665 * Description: The has sent us a Wide Nego message so handle it as
3666 * necessary.
3667 *
3668 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003669static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003671 unsigned char width;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672 PSCCB currSCCB;
3673 PSCCBMgr_tar_info currTar_Info;
3674
James Bottomley 47b5d692005-04-24 02:38:05 -05003675 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3676 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677
James Bottomley 47b5d692005-04-24 02:38:05 -05003678 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003679
3680 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3681 {
3682 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3683 return;
3684 }
3685
3686
3687 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3688 width = 0;
3689
3690 if (width) {
3691 currTar_Info->TarStatus |= WIDE_ENABLED;
3692 width = 0;
3693 }
3694 else {
3695 width = NARROW_SCSI;
3696 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3697 }
3698
3699
James Bottomley 47b5d692005-04-24 02:38:05 -05003700 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003701
3702
3703 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3704 {
3705
3706
3707
3708 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3709
3710 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3711 {
3712 ACCEPT_MSG_ATN(port);
3713 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003714 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003715 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3716 SGRAM_ACCESS(port);
3717 }
3718 else
3719 {
3720 ACCEPT_MSG(port);
3721 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3722 }
3723 }
3724
3725 else {
3726
3727
3728 ACCEPT_MSG_ATN(port);
3729
3730 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3731 width = SM16BIT;
3732 else
3733 width = SM8BIT;
3734
James Bottomley 47b5d692005-04-24 02:38:05 -05003735 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736
3737 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3738 }
3739}
3740
3741
3742/*---------------------------------------------------------------------
3743 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003744 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 *
3746 * Description: Answer the targets Wide nego message.
3747 *
3748 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003749static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750{
3751 ARAM_ACCESS(port);
3752 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3753 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3754 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3755 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3756 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3757 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3758 SGRAM_ACCESS(port);
3759
3760 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3761 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3762
3763 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3764
3765 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3766}
3767
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768
3769
3770/*---------------------------------------------------------------------
3771 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003772 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773 *
3774 * Description: Write the desired value to the Sync Register for the
3775 * ID specified.
3776 *
3777 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003778static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003779 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003781 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003782
3783 index = p_id;
3784
3785 switch (index) {
3786
3787 case 0:
3788 index = 12; /* hp_synctarg_0 */
3789 break;
3790 case 1:
3791 index = 13; /* hp_synctarg_1 */
3792 break;
3793 case 2:
3794 index = 14; /* hp_synctarg_2 */
3795 break;
3796 case 3:
3797 index = 15; /* hp_synctarg_3 */
3798 break;
3799 case 4:
3800 index = 8; /* hp_synctarg_4 */
3801 break;
3802 case 5:
3803 index = 9; /* hp_synctarg_5 */
3804 break;
3805 case 6:
3806 index = 10; /* hp_synctarg_6 */
3807 break;
3808 case 7:
3809 index = 11; /* hp_synctarg_7 */
3810 break;
3811 case 8:
3812 index = 4; /* hp_synctarg_8 */
3813 break;
3814 case 9:
3815 index = 5; /* hp_synctarg_9 */
3816 break;
3817 case 10:
3818 index = 6; /* hp_synctarg_10 */
3819 break;
3820 case 11:
3821 index = 7; /* hp_synctarg_11 */
3822 break;
3823 case 12:
3824 index = 0; /* hp_synctarg_12 */
3825 break;
3826 case 13:
3827 index = 1; /* hp_synctarg_13 */
3828 break;
3829 case 14:
3830 index = 2; /* hp_synctarg_14 */
3831 break;
3832 case 15:
3833 index = 3; /* hp_synctarg_15 */
3834
3835 }
3836
3837 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3838
3839 currTar_Info->TarSyncCtrl = p_sync_value;
3840}
3841
3842
3843/*---------------------------------------------------------------------
3844 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003845 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846 *
3847 * Description: Reset the desired card's SCSI bus.
3848 *
3849 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003850static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003851{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003852 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003853
3854 PSCCBMgr_tar_info currTar_Info;
3855
3856 WR_HARPOON(port+hp_page_ctrl,
3857 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3858 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3859
3860 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3861
3862 scsiID = RD_HARPOON(port+hp_seltimeout);
3863 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3864 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3865
3866 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3867
3868 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3869
3870 WR_HARPOON(port+hp_seltimeout,scsiID);
3871
3872 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3873
James Bottomley 47b5d692005-04-24 02:38:05 -05003874 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003875
3876 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3877
3878 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3879
3880 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3881 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003882 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003883
3884 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3885 {
3886 currTar_Info->TarSyncCtrl = 0;
3887 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3888 }
3889
3890 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3891 {
3892 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3893 }
3894
James Bottomley 47b5d692005-04-24 02:38:05 -05003895 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896
James Bottomley 47b5d692005-04-24 02:38:05 -05003897 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898 }
3899
James Bottomley 47b5d692005-04-24 02:38:05 -05003900 FPT_BL_Card[p_card].scanIndex = 0x00;
3901 FPT_BL_Card[p_card].currentSCCB = NULL;
3902 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003903 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003904 FPT_BL_Card[p_card].cmdCounter = 0x00;
3905 FPT_BL_Card[p_card].discQCount = 0x00;
3906 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907
3908 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003909 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910
3911 WR_HARPOON(port+hp_page_ctrl,
3912 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3913
3914}
3915
3916/*---------------------------------------------------------------------
3917 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003918 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 *
3920 * Description: Setup for the Auto Sense command.
3921 *
3922 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003923static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003924{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003925 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003926 PSCCB currSCCB;
3927
3928 currSCCB = pCurrCard->currentSCCB;
3929
3930
3931 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3932
3933 for (i = 0; i < 6; i++) {
3934
3935 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3936 }
3937
3938 currSCCB->CdbLength = SIX_BYTE_CMD;
3939 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003940 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003941 currSCCB->Cdb[2] = 0x00;
3942 currSCCB->Cdb[3] = 0x00;
3943 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3944 currSCCB->Cdb[5] = 0x00;
3945
3946 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3947
3948 currSCCB->Sccb_ATC = 0x00;
3949
3950 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3951
3952 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3953
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003954 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955
3956 currSCCB->ControlByte = 0x00;
3957
3958 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3959}
3960
3961
3962
3963/*---------------------------------------------------------------------
3964 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003965 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966 *
3967 * Description: Transfer data into the bit bucket until the device
3968 * decides to switch phase.
3969 *
3970 *---------------------------------------------------------------------*/
3971
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003972static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003974 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975
3976
3977 DISABLE_AUTO(p_port);
3978
James Bottomley 47b5d692005-04-24 02:38:05 -05003979 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003980
James Bottomley 47b5d692005-04-24 02:38:05 -05003981 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982
3983 }
3984
3985 /* If the Automation handled the end of the transfer then do not
3986 match the phase or we will get out of sync with the ISR. */
3987
3988 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3989 return;
3990
3991 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3992
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003993 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003994
3995 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3996
3997
3998 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3999
4000 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004001 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004003 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 {
4005 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4006
4007 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4008 {
4009 RD_HARPOON(p_port+hp_fifodata_0);
4010 }
4011 }
4012 else
4013 {
4014 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4015 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4016 {
4017 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4018 }
4019 }
4020 } /* End of While loop for padding data I/O phase */
4021
4022 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4023 {
4024 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4025 break;
4026 }
4027
4028 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4029 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4030 {
4031 RD_HARPOON(p_port+hp_fifodata_0);
4032 }
4033
4034 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4035 {
4036 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4037 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4038
4039 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4040 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4041 }
4042}
4043
4044
4045/*---------------------------------------------------------------------
4046 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004047 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048 *
4049 * Description: Make sure data has been flushed from both FIFOs and abort
4050 * the operations if necessary.
4051 *
4052 *---------------------------------------------------------------------*/
4053
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004054static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004056 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004057 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058
4059 PSCCB currSCCB;
4060
James Bottomley 47b5d692005-04-24 02:38:05 -05004061 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004062
4063
4064 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4065 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4066 return;
4067 }
4068
4069
4070
4071 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4072 {
4073
4074 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4075
4076 currSCCB->Sccb_XferCnt = 1;
4077
4078 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004079 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004080 WR_HARPOON(port+hp_xferstat, 0x00);
4081 }
4082
4083 else
4084 {
4085
4086 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4087
4088 currSCCB->Sccb_XferCnt = 0;
4089 }
4090
4091 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4092 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4093
4094 currSCCB->HostStatus = SCCB_PARITY_ERR;
4095 WRW_HARPOON((port+hp_intstat), PARITY);
4096 }
4097
4098
James Bottomley 47b5d692005-04-24 02:38:05 -05004099 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100
4101
4102 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4103
4104 TimeOutLoop = 0;
4105
4106 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4107 {
4108 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4109 return;
4110 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004111 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112 break;
4113 }
4114 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4115 return;
4116 }
4117 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4118 break;
4119 }
4120
4121 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4122 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004123 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4125 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4126 {
4127
4128 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4129
4130 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4131 {
4132 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004133 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004134 }
4135
4136 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004137 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138 }
4139 }
4140 else
4141 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004142 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143 if (!(RDW_HARPOON((port+hp_intstat)) &
4144 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4145 {
4146 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004147 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004148 }
4149 }
4150
4151 }
4152
4153 else {
4154 WR_HARPOON(port+hp_portctrl_0, 0x00);
4155 }
4156}
4157
4158
4159/*---------------------------------------------------------------------
4160 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004161 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004162 *
4163 * Description: Setup SCCB manager fields in this SCCB.
4164 *
4165 *---------------------------------------------------------------------*/
4166
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004167static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004168{
4169 PSCCBMgr_tar_info currTar_Info;
4170
4171 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4172 {
4173 return;
4174 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004175 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004176
4177 p_sccb->Sccb_XferState = 0x00;
4178 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4179
4180 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4181 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4182
4183 p_sccb->Sccb_SGoffset = 0;
4184 p_sccb->Sccb_XferState = F_SG_XFER;
4185 p_sccb->Sccb_XferCnt = 0x00;
4186 }
4187
4188 if (p_sccb->DataLength == 0x00)
4189
4190 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4191
4192 if (p_sccb->ControlByte & F_USE_CMD_Q)
4193 {
4194 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4195 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4196
4197 else
4198 currTar_Info->TarStatus |= TAG_Q_TRYING;
4199 }
4200
4201/* For !single SCSI device in system & device allow Disconnect
4202 or command is tag_q type then send Cmd with Disconnect Enable
4203 else send Cmd with Disconnect Disable */
4204
4205/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004206 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4208 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4209*/
4210 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4211 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004212 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004213 }
4214
4215 else {
4216
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004217 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004218 }
4219
4220 p_sccb->HostStatus = 0x00;
4221 p_sccb->TargetStatus = 0x00;
4222 p_sccb->Sccb_tag = 0x00;
4223 p_sccb->Sccb_MGRFlags = 0x00;
4224 p_sccb->Sccb_sgseg = 0x00;
4225 p_sccb->Sccb_ATC = 0x00;
4226 p_sccb->Sccb_savedATC = 0x00;
4227/*
4228 p_sccb->SccbVirtDataPtr = 0x00;
4229 p_sccb->Sccb_forwardlink = NULL;
4230 p_sccb->Sccb_backlink = NULL;
4231 */
4232 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4233 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4234 p_sccb->Sccb_scsimsg = SMNO_OP;
4235
4236}
4237
4238
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239/*---------------------------------------------------------------------
4240 *
4241 * Function: Phase Decode
4242 *
4243 * Description: Determine the phase and call the appropriate function.
4244 *
4245 *---------------------------------------------------------------------*/
4246
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004247static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248{
4249 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004250 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251
4252
4253 DISABLE_AUTO(p_port);
4254
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004255 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004256
James Bottomley 47b5d692005-04-24 02:38:05 -05004257 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004258
4259 (*phase)(p_port, p_card); /* Call the correct phase func */
4260}
4261
4262
4263
4264/*---------------------------------------------------------------------
4265 *
4266 * Function: Data Out Phase
4267 *
4268 * Description: Start up both the BusMaster and Xbow.
4269 *
4270 *---------------------------------------------------------------------*/
4271
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004272static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273{
4274
4275 PSCCB currSCCB;
4276
James Bottomley 47b5d692005-04-24 02:38:05 -05004277 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278 if (currSCCB == NULL)
4279 {
4280 return; /* Exit if No SCCB record */
4281 }
4282
4283 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4284 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4285
4286 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4287
4288 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4289
4290 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4291
James Bottomley 47b5d692005-04-24 02:38:05 -05004292 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293
4294 if (currSCCB->Sccb_XferCnt == 0) {
4295
4296
4297 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4298 (currSCCB->HostStatus == SCCB_COMPLETE))
4299 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4300
James Bottomley 47b5d692005-04-24 02:38:05 -05004301 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004302 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004303 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 }
4305}
4306
4307
4308/*---------------------------------------------------------------------
4309 *
4310 * Function: Data In Phase
4311 *
4312 * Description: Startup the BusMaster and the XBOW.
4313 *
4314 *---------------------------------------------------------------------*/
4315
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004316static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317{
4318
4319 PSCCB currSCCB;
4320
James Bottomley 47b5d692005-04-24 02:38:05 -05004321 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322
4323 if (currSCCB == NULL)
4324 {
4325 return; /* Exit if No SCCB record */
4326 }
4327
4328
4329 currSCCB->Sccb_scsistat = DATA_IN_ST;
4330 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4331 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4332
4333 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4334
4335 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4336
4337 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4338
James Bottomley 47b5d692005-04-24 02:38:05 -05004339 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340
4341 if (currSCCB->Sccb_XferCnt == 0) {
4342
4343
4344 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4345 (currSCCB->HostStatus == SCCB_COMPLETE))
4346 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4347
James Bottomley 47b5d692005-04-24 02:38:05 -05004348 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004349 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004350 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004351
4352 }
4353}
4354
4355/*---------------------------------------------------------------------
4356 *
4357 * Function: Command Phase
4358 *
4359 * Description: Load the CDB into the automation and start it up.
4360 *
4361 *---------------------------------------------------------------------*/
4362
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004363static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004364{
4365 PSCCB currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004366 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004367 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368
James Bottomley 47b5d692005-04-24 02:38:05 -05004369 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370
4371 if (currSCCB->OperationCode == RESET_COMMAND) {
4372
4373 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4374 currSCCB->CdbLength = SIX_BYTE_CMD;
4375 }
4376
4377 WR_HARPOON(p_port+hp_scsisig, 0x00);
4378
4379 ARAM_ACCESS(p_port);
4380
4381
4382 cdb_reg = p_port + CMD_STRT;
4383
4384 for (i=0; i < currSCCB->CdbLength; i++) {
4385
4386 if (currSCCB->OperationCode == RESET_COMMAND)
4387
4388 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4389
4390 else
4391 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4392 cdb_reg +=2;
4393 }
4394
4395 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4396 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4397
4398 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4399
4400 currSCCB->Sccb_scsistat = COMMAND_ST;
4401
4402 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4403 SGRAM_ACCESS(p_port);
4404}
4405
4406
4407/*---------------------------------------------------------------------
4408 *
4409 * Function: Status phase
4410 *
4411 * Description: Bring in the status and command complete message bytes
4412 *
4413 *---------------------------------------------------------------------*/
4414
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004415static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004416{
4417 /* Start-up the automation to finish off this command and let the
4418 isr handle the interrupt for command complete when it comes in.
4419 We could wait here for the interrupt to be generated?
4420 */
4421
4422 WR_HARPOON(port+hp_scsisig, 0x00);
4423
4424 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4425}
4426
4427
4428/*---------------------------------------------------------------------
4429 *
4430 * Function: Phase Message Out
4431 *
4432 * Description: Send out our message (if we have one) and handle whatever
4433 * else is involed.
4434 *
4435 *---------------------------------------------------------------------*/
4436
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004437static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004438{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004439 unsigned char message,scsiID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004440 PSCCB currSCCB;
4441 PSCCBMgr_tar_info currTar_Info;
4442
James Bottomley 47b5d692005-04-24 02:38:05 -05004443 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444
4445 if (currSCCB != NULL) {
4446
4447 message = currSCCB->Sccb_scsimsg;
4448 scsiID = currSCCB->TargID;
4449
4450 if (message == SMDEV_RESET)
4451 {
4452
4453
James Bottomley 47b5d692005-04-24 02:38:05 -05004454 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004456 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457
James Bottomley 47b5d692005-04-24 02:38:05 -05004458 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 {
4460
James Bottomley 47b5d692005-04-24 02:38:05 -05004461 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462
4463 }
4464
James Bottomley 47b5d692005-04-24 02:38:05 -05004465 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466 {
4467
James Bottomley 47b5d692005-04-24 02:38:05 -05004468 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469 }
4470
4471
James Bottomley 47b5d692005-04-24 02:38:05 -05004472 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4473 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004474 }
4475 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4476 {
4477 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004478 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004480 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4481 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482 }
4483
4484 }
4485
4486 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4487 {
4488
4489
4490 if(message == SMNO_OP)
4491 {
4492 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4493
James Bottomley 47b5d692005-04-24 02:38:05 -05004494 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004495 return;
4496 }
4497 }
4498 else
4499 {
4500
4501
4502 if (message == SMABORT)
4503
James Bottomley 47b5d692005-04-24 02:38:05 -05004504 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004505 }
4506
4507 }
4508 else
4509 {
4510 message = SMABORT;
4511 }
4512
4513 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4514
4515
4516 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4517
4518 WR_HARPOON(port+hp_scsidata_0,message);
4519
4520 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4521
4522 ACCEPT_MSG(port);
4523
4524 WR_HARPOON(port+hp_portctrl_0, 0x00);
4525
4526 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4527 (message == SMABORT_TAG) )
4528 {
4529
4530 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4531
4532 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4533 {
4534 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4535
4536 if (currSCCB != NULL)
4537 {
4538
James Bottomley 47b5d692005-04-24 02:38:05 -05004539 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4540 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4541 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004543 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544
James Bottomley 47b5d692005-04-24 02:38:05 -05004545 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 }
4547
4548 else
4549 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004550 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 }
4552 }
4553
4554 else
4555 {
4556
James Bottomley 47b5d692005-04-24 02:38:05 -05004557 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004558 }
4559 }
4560
4561 else
4562 {
4563
4564 if(message == SMPARITY)
4565 {
4566 currSCCB->Sccb_scsimsg = SMNO_OP;
4567 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4568 }
4569 else
4570 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004571 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004572 }
4573 }
4574}
4575
4576
4577/*---------------------------------------------------------------------
4578 *
4579 * Function: Message In phase
4580 *
4581 * Description: Bring in the message and determine what to do with it.
4582 *
4583 *---------------------------------------------------------------------*/
4584
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004585static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004586{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004587 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004588 PSCCB currSCCB;
4589
James Bottomley 47b5d692005-04-24 02:38:05 -05004590 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004591
James Bottomley 47b5d692005-04-24 02:38:05 -05004592 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004593 {
4594
James Bottomley 47b5d692005-04-24 02:38:05 -05004595 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004596 }
4597
4598 message = RD_HARPOON(port+hp_scsidata_0);
4599 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4600 {
4601
4602 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4603
4604 }
4605
4606 else
4607 {
4608
James Bottomley 47b5d692005-04-24 02:38:05 -05004609 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004610 if (message)
4611 {
4612
4613
James Bottomley 47b5d692005-04-24 02:38:05 -05004614 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004615
4616 }
4617 else
4618 {
4619 if(currSCCB->Sccb_scsimsg != SMPARITY)
4620 ACCEPT_MSG(port);
4621 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4622 }
4623 }
4624
4625}
4626
4627
4628/*---------------------------------------------------------------------
4629 *
4630 * Function: Illegal phase
4631 *
4632 * Description: Target switched to some illegal phase, so all we can do
4633 * is report an error back to the host (if that is possible)
4634 * and send an ABORT message to the misbehaving target.
4635 *
4636 *---------------------------------------------------------------------*/
4637
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004638static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004639{
4640 PSCCB currSCCB;
4641
James Bottomley 47b5d692005-04-24 02:38:05 -05004642 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004643
4644 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4645 if (currSCCB != NULL) {
4646
4647 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4648 currSCCB->Sccb_scsistat = ABORT_ST;
4649 currSCCB->Sccb_scsimsg = SMABORT;
4650 }
4651
4652 ACCEPT_MSG_ATN(port);
4653}
4654
4655
4656
4657/*---------------------------------------------------------------------
4658 *
4659 * Function: Phase Check FIFO
4660 *
4661 * Description: Make sure data has been flushed from both FIFOs and abort
4662 * the operations if necessary.
4663 *
4664 *---------------------------------------------------------------------*/
4665
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004666static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004667{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004668 unsigned long xfercnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004669 PSCCB currSCCB;
4670
James Bottomley 47b5d692005-04-24 02:38:05 -05004671 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004672
4673 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4674 {
4675
4676 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4677 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4678
4679
4680 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4681 {
4682 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4683
4684 currSCCB->Sccb_XferCnt = 0;
4685
4686 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4687 (currSCCB->HostStatus == SCCB_COMPLETE))
4688 {
4689 currSCCB->HostStatus = SCCB_PARITY_ERR;
4690 WRW_HARPOON((port+hp_intstat), PARITY);
4691 }
4692
James Bottomley 47b5d692005-04-24 02:38:05 -05004693 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004694
James Bottomley 47b5d692005-04-24 02:38:05 -05004695 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004696
4697 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4698 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4699
4700 }
4701 } /*End Data In specific code. */
4702
4703
4704
Linus Torvalds1da177e2005-04-16 15:20:36 -07004705 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004706
4707
4708 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4709
4710
4711 WR_HARPOON(port+hp_portctrl_0, 0x00);
4712
4713 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4714
4715 currSCCB->Sccb_XferCnt = xfercnt;
4716
4717 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4718 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4719
4720 currSCCB->HostStatus = SCCB_PARITY_ERR;
4721 WRW_HARPOON((port+hp_intstat), PARITY);
4722 }
4723
4724
James Bottomley 47b5d692005-04-24 02:38:05 -05004725 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004726
4727
4728 WR_HARPOON(port+hp_fifowrite, 0x00);
4729 WR_HARPOON(port+hp_fiforead, 0x00);
4730 WR_HARPOON(port+hp_xferstat, 0x00);
4731
4732 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4733}
4734
4735
4736/*---------------------------------------------------------------------
4737 *
4738 * Function: Phase Bus Free
4739 *
4740 * Description: We just went bus free so figure out if it was
4741 * because of command complete or from a disconnect.
4742 *
4743 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004744static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004745{
4746 PSCCB currSCCB;
4747
James Bottomley 47b5d692005-04-24 02:38:05 -05004748 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004749
4750 if (currSCCB != NULL)
4751 {
4752
4753 DISABLE_AUTO(port);
4754
4755
4756 if (currSCCB->OperationCode == RESET_COMMAND)
4757 {
4758
James Bottomley 47b5d692005-04-24 02:38:05 -05004759 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4760 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4761 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004762 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004764
James Bottomley 47b5d692005-04-24 02:38:05 -05004765 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004766
James Bottomley 47b5d692005-04-24 02:38:05 -05004767 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004768
4769 }
4770
4771 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4772 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004773 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004774 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004775 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004776 }
4777
4778 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4779 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004780 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4781 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004782 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4783
James Bottomley 47b5d692005-04-24 02:38:05 -05004784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004785 }
4786
Linus Torvalds1da177e2005-04-16 15:20:36 -07004787 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4788 {
4789 /* Make sure this is not a phony BUS_FREE. If we were
4790 reselected or if BUSY is NOT on then this is a
4791 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4792
4793 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4794 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4795 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004796 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4797 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004798 }
4799
4800 else
4801 {
4802 return;
4803 }
4804 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004805
4806 else
4807 {
4808
4809 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4810
4811 if (!currSCCB->HostStatus)
4812 {
4813 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4814 }
4815
James Bottomley 47b5d692005-04-24 02:38:05 -05004816 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4817 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4818 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004819 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004820 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004821
James Bottomley 47b5d692005-04-24 02:38:05 -05004822 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823 return;
4824 }
4825
4826
James Bottomley 47b5d692005-04-24 02:38:05 -05004827 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004828
4829 } /*end if !=null */
4830}
4831
4832
4833
4834
Linus Torvalds1da177e2005-04-16 15:20:36 -07004835/*---------------------------------------------------------------------
4836 *
4837 * Function: Auto Load Default Map
4838 *
4839 * Description: Load the Automation RAM with the defualt map values.
4840 *
4841 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004842static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004843{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004844 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004845
4846 ARAM_ACCESS(p_port);
4847 map_addr = p_port + hp_aramBase;
4848
4849 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4850 map_addr +=2;
4851 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4852 map_addr +=2;
4853 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4884 map_addr +=2; /*This means AYNC DATA IN */
4885 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4888 map_addr +=2;
4889 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4910 map_addr +=2;
4911 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4912 map_addr +=2;
4913 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4920 map_addr +=2;
4921
4922 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4923 map_addr +=2;
4924 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4925 map_addr +=2;
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4927 map_addr +=2;
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4929 map_addr +=2; /* DIDN'T GET ONE */
4930 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4931 map_addr +=2;
4932 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4933 map_addr +=2;
4934 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4935
4936
4937
4938 SGRAM_ACCESS(p_port);
4939}
4940
4941/*---------------------------------------------------------------------
4942 *
4943 * Function: Auto Command Complete
4944 *
4945 * Description: Post command back to host and find another command
4946 * to execute.
4947 *
4948 *---------------------------------------------------------------------*/
4949
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004950static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004951{
4952 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004953 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004954
James Bottomley 47b5d692005-04-24 02:38:05 -05004955 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004956
4957 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4958
James Bottomley 47b5d692005-04-24 02:38:05 -05004959 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004960
4961 if (status_byte != SSGOOD) {
4962
4963 if (status_byte == SSQ_FULL) {
4964
4965
James Bottomley 47b5d692005-04-24 02:38:05 -05004966 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4967 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004968 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004969 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4970 if(FPT_BL_Card[p_card].discQCount != 0)
4971 FPT_BL_Card[p_card].discQCount--;
4972 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 -07004973 }
4974 else
4975 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004976 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004977 if(currSCCB->Sccb_tag)
4978 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004979 if(FPT_BL_Card[p_card].discQCount != 0)
4980 FPT_BL_Card[p_card].discQCount--;
4981 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004982 }else
4983 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004984 if(FPT_BL_Card[p_card].discQCount != 0)
4985 FPT_BL_Card[p_card].discQCount--;
4986 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004987 }
4988 }
4989
4990 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4991
James Bottomley 47b5d692005-04-24 02:38:05 -05004992 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004993
4994 return;
4995 }
4996
4997 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4998 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004999 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005000 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005001
James Bottomley 47b5d692005-04-24 02:38:05 -05005002 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5003 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005004
James Bottomley 47b5d692005-04-24 02:38:05 -05005005 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5006 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005007 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005008 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5009 if(FPT_BL_Card[p_card].discQCount != 0)
5010 FPT_BL_Card[p_card].discQCount--;
5011 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 -07005012 }
5013 else
5014 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005015 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005016 if(currSCCB->Sccb_tag)
5017 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005018 if(FPT_BL_Card[p_card].discQCount != 0)
5019 FPT_BL_Card[p_card].discQCount--;
5020 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005021 }else
5022 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005023 if(FPT_BL_Card[p_card].discQCount != 0)
5024 FPT_BL_Card[p_card].discQCount--;
5025 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005026 }
5027 }
5028 return;
5029
5030 }
5031
5032 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5033 {
5034
James Bottomley 47b5d692005-04-24 02:38:05 -05005035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5036 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005037 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5038
James Bottomley 47b5d692005-04-24 02:38:05 -05005039 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5040 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005041
James Bottomley 47b5d692005-04-24 02:38:05 -05005042 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5043 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005044 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005045 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5046 if(FPT_BL_Card[p_card].discQCount != 0)
5047 FPT_BL_Card[p_card].discQCount--;
5048 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 -07005049 }
5050 else
5051 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005052 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005053 if(currSCCB->Sccb_tag)
5054 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005055 if(FPT_BL_Card[p_card].discQCount != 0)
5056 FPT_BL_Card[p_card].discQCount--;
5057 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005058 }else
5059 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005060 if(FPT_BL_Card[p_card].discQCount != 0)
5061 FPT_BL_Card[p_card].discQCount--;
5062 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005063 }
5064 }
5065 return;
5066
5067 }
5068
5069 if (status_byte == SSCHECK)
5070 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005071 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005072 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005073 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005074 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005075 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005076 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005077 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005078 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005080 }
5081 }
5082 }
5083
5084 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5085
5086 currSCCB->SccbStatus = SCCB_ERROR;
5087 currSCCB->TargetStatus = status_byte;
5088
5089 if (status_byte == SSCHECK) {
5090
James Bottomley 47b5d692005-04-24 02:38:05 -05005091 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5092 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005093
5094
Linus Torvalds1da177e2005-04-16 15:20:36 -07005095 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5096
5097 if (currSCCB->RequestSenseLength == 0)
5098 currSCCB->RequestSenseLength = 14;
5099
James Bottomley 47b5d692005-04-24 02:38:05 -05005100 FPT_ssenss(&FPT_BL_Card[p_card]);
5101 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005102
James Bottomley 47b5d692005-04-24 02:38:05 -05005103 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5104 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005105 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005106 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5107 if(FPT_BL_Card[p_card].discQCount != 0)
5108 FPT_BL_Card[p_card].discQCount--;
5109 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 -07005110 }
5111 else
5112 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005113 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005114 if(currSCCB->Sccb_tag)
5115 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005116 if(FPT_BL_Card[p_card].discQCount != 0)
5117 FPT_BL_Card[p_card].discQCount--;
5118 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005119 }else
5120 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005121 if(FPT_BL_Card[p_card].discQCount != 0)
5122 FPT_BL_Card[p_card].discQCount--;
5123 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005124 }
5125 }
5126 return;
5127 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005128 }
5129 }
5130 }
5131
5132
James Bottomley 47b5d692005-04-24 02:38:05 -05005133 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5134 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5135 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005136 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005137 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005138
5139
James Bottomley 47b5d692005-04-24 02:38:05 -05005140 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005141}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005142
5143#define SHORT_WAIT 0x0000000F
5144#define LONG_WAIT 0x0000FFFFL
5145
Linus Torvalds1da177e2005-04-16 15:20:36 -07005146
5147/*---------------------------------------------------------------------
5148 *
5149 * Function: Data Transfer Processor
5150 *
5151 * Description: This routine performs two tasks.
5152 * (1) Start data transfer by calling HOST_DATA_XFER_START
5153 * function. Once data transfer is started, (2) Depends
5154 * on the type of data transfer mode Scatter/Gather mode
5155 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5156 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5157 * data transfer done. In Scatter/Gather mode, this routine
5158 * checks bus master command complete and dual rank busy
5159 * bit to keep chaining SC transfer command. Similarly,
5160 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5161 * (F_HOST_XFER_ACT bit) for data transfer done.
5162 *
5163 *---------------------------------------------------------------------*/
5164
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005165static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005166{
5167 PSCCB currSCCB;
5168
5169 currSCCB = pCurrCard->currentSCCB;
5170
5171 if (currSCCB->Sccb_XferState & F_SG_XFER)
5172 {
5173 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5174
5175 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005176 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005177 currSCCB->Sccb_SGoffset = 0x00;
5178 }
5179 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5180
James Bottomley 47b5d692005-04-24 02:38:05 -05005181 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005182 }
5183
5184 else
5185 {
5186 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5187 {
5188 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5189
James Bottomley 47b5d692005-04-24 02:38:05 -05005190 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005191 }
5192 }
5193}
5194
5195
5196/*---------------------------------------------------------------------
5197 *
5198 * Function: BusMaster Scatter Gather Data Transfer Start
5199 *
5200 * Description:
5201 *
5202 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005203static void FPT_busMstrSGDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005204{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005205 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005206 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005207 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005208 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209
5210
5211 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5212
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005213 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005214 }
5215
5216 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005217 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005218 }
5219
5220 sg_count = 0;
5221 tmpSGCnt = 0;
5222 sg_index = pcurrSCCB->Sccb_sgseg;
5223 reg_offset = hp_aramBase;
5224
5225
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005226 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005227
5228
5229 WR_HARPOON(p_port+hp_page_ctrl, i);
5230
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005231 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005232 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005233
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005234 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005235 (sg_index * 2));
5236
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005237 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005238 (sg_index * 2));
5239
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005240 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005241 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005242
5243
5244 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5245
5246 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5247 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5248
5249 tmpSGCnt = count & 0x00FFFFFFL;
5250 }
5251
5252 WR_HARP32(p_port,reg_offset,addr);
5253 reg_offset +=4;
5254
5255 WR_HARP32(p_port,reg_offset,count);
5256 reg_offset +=4;
5257
5258 count &= 0xFF000000L;
5259 sg_index++;
5260 sg_count++;
5261
5262 } /*End While */
5263
5264 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5265
5266 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5267
5268 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5269
5270 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5271
5272
5273 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5274 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5275 }
5276
5277 else {
5278
5279
5280 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5281 (tmpSGCnt & 0x000000001))
5282 {
5283
5284 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5285 tmpSGCnt--;
5286 }
5287
5288
5289 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5290
5291 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5292 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5293 }
5294
5295
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005296 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005297
5298}
5299
5300
5301/*---------------------------------------------------------------------
5302 *
5303 * Function: BusMaster Data Transfer Start
5304 *
5305 * Description:
5306 *
5307 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005308static void FPT_busMstrDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005309{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005310 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005311
5312 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5313
5314 count = pcurrSCCB->Sccb_XferCnt;
5315
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005316 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005317 }
5318
5319 else {
5320 addr = pcurrSCCB->SensePointer;
5321 count = pcurrSCCB->RequestSenseLength;
5322
5323 }
5324
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005326
5327
5328 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5329
5330 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5331 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5332
5333 WR_HARPOON(p_port+hp_xfer_cmd,
5334 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5335 }
5336
5337 else {
5338
5339 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5340 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5341
5342 WR_HARPOON(p_port+hp_xfer_cmd,
5343 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5344
5345 }
5346}
5347
5348
5349/*---------------------------------------------------------------------
5350 *
5351 * Function: BusMaster Timeout Handler
5352 *
5353 * Description: This function is called after a bus master command busy time
5354 * out is detected. This routines issue halt state machine
5355 * with a software time out for command busy. If command busy
5356 * is still asserted at the end of the time out, it issues
5357 * hard abort with another software time out. It hard abort
5358 * command busy is also time out, it'll just give up.
5359 *
5360 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005361static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005362{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005363 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005364
5365 timeout = LONG_WAIT;
5366
5367 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5368
5369 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5370
5371
5372
5373 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5374 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5375
5376 timeout = LONG_WAIT;
5377 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5378 }
5379
5380 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5381
5382 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005383 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384 }
5385
5386 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005387 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388 }
5389}
5390
5391
5392/*---------------------------------------------------------------------
5393 *
5394 * Function: Host Data Transfer Abort
5395 *
5396 * Description: Abort any in progress transfer.
5397 *
5398 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005399static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400{
5401
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005402 unsigned long timeout;
5403 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005404 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005405
James Bottomley 47b5d692005-04-24 02:38:05 -05005406 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407
5408 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5409
5410
5411 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5412
5413 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5414 timeout = LONG_WAIT;
5415
5416 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5417
5418 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5419
5420 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5421
James Bottomley 47b5d692005-04-24 02:38:05 -05005422 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005423
5424 if (pCurrSCCB->HostStatus == 0x00)
5425
5426 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5427
5428 }
5429
5430 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5431
5432 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5433
5434 if (pCurrSCCB->HostStatus == 0x00)
5435
5436 {
5437 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005438 }
5439 }
5440 }
5441 }
5442
5443 else if (pCurrSCCB->Sccb_XferCnt) {
5444
5445 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5446
5447
5448 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5449 ~SCATTER_EN));
5450
5451 WR_HARPOON(port+hp_sg_addr,0x00);
5452
5453 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5454
Alexey Dobriyance793212006-03-08 00:14:26 -08005455 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005456
Alexey Dobriyance793212006-03-08 00:14:26 -08005457 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458 }
5459
5460 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5461
5462 while (remain_cnt < 0x01000000L) {
5463
5464 sg_ptr--;
5465
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005466 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005467 DataPointer) + (sg_ptr * 2)))) {
5468
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005469 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005470 DataPointer) + (sg_ptr * 2)));
5471 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005472
5473 else {
5474
5475 break;
5476 }
5477 }
5478
5479
5480
5481 if (remain_cnt < 0x01000000L) {
5482
5483
5484 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5485
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005486 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005487
5488
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005489 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005490 && (remain_cnt == 0))
5491
5492 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5493 }
5494
5495 else {
5496
5497
5498 if (pCurrSCCB->HostStatus == 0x00) {
5499
5500 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5501 }
5502 }
5503 }
5504
5505
5506 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5507
5508
5509 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5510
James Bottomley 47b5d692005-04-24 02:38:05 -05005511 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005512 }
5513
5514 else {
5515
5516 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5517
5518 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5519
5520 if (pCurrSCCB->HostStatus == 0x00) {
5521
5522 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005523 }
5524 }
5525 }
5526
5527 }
5528 }
5529
5530 else {
5531
5532
5533 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5534
5535 timeout = SHORT_WAIT;
5536
5537 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5538 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5539 timeout--) {}
5540 }
5541
5542 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5543
5544 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5545 FLUSH_XFER_CNTR));
5546
5547 timeout = LONG_WAIT;
5548
5549 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5550 timeout--) {}
5551
5552 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5553 ~FLUSH_XFER_CNTR));
5554
5555
5556 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5557
5558 if (pCurrSCCB->HostStatus == 0x00) {
5559
5560 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5561 }
5562
James Bottomley 47b5d692005-04-24 02:38:05 -05005563 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005564 }
5565 }
5566
5567 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5568
5569 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5570
5571 if (pCurrSCCB->HostStatus == 0x00) {
5572
5573 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005574 }
5575 }
5576 }
5577 }
5578
5579 }
5580
5581 else {
5582
5583
5584 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5585
5586 timeout = LONG_WAIT;
5587
5588 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5589
5590 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5591
5592 if (pCurrSCCB->HostStatus == 0x00) {
5593
5594 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5595 }
5596
James Bottomley 47b5d692005-04-24 02:38:05 -05005597 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005598 }
5599 }
5600
5601
5602 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5603
5604 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5605
5606 if (pCurrSCCB->HostStatus == 0x00) {
5607
5608 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005609 }
5610 }
5611
5612 }
5613
5614 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5615
5616 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5617 ~SCATTER_EN));
5618
5619 WR_HARPOON(port+hp_sg_addr,0x00);
5620
5621 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5622
5623 pCurrSCCB->Sccb_SGoffset = 0x00;
5624
5625
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005626 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005627 pCurrSCCB->DataLength) {
5628
5629 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5630
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005631 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005632
5633 }
5634 }
5635
5636 else {
5637
5638 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5639
5640 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5641 }
5642 }
5643
5644 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5645}
5646
5647
5648
5649/*---------------------------------------------------------------------
5650 *
5651 * Function: Host Data Transfer Restart
5652 *
5653 * Description: Reset the available count due to a restore data
5654 * pointers message.
5655 *
5656 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005657static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005658{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005659 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005660 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005661 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662
5663 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5664
5665 currSCCB->Sccb_XferCnt = 0;
5666
5667 sg_index = 0xffff; /*Index by long words into sg list. */
5668 data_count = 0; /*Running count of SG xfer counts. */
5669
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005670 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005671
5672 while (data_count < currSCCB->Sccb_ATC) {
5673
5674 sg_index++;
5675 data_count += *(sg_ptr+(sg_index * 2));
5676 }
5677
5678 if (data_count == currSCCB->Sccb_ATC) {
5679
5680 currSCCB->Sccb_SGoffset = 0;
5681 sg_index++;
5682 }
5683
5684 else {
5685 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5686 }
5687
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005688 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689 }
5690
5691 else {
5692 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5693 }
5694}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005695
5696
5697
Linus Torvalds1da177e2005-04-16 15:20:36 -07005698/*---------------------------------------------------------------------
5699 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005700 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701 *
5702 * Description: Setup all data structures necessary for SCAM selection.
5703 *
5704 *---------------------------------------------------------------------*/
5705
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005706static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005707{
5708
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005709 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005710 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005711
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005712 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713 PSCCBcard currCard;
5714 PNVRamInfo pCurrNvRam;
5715
James Bottomley 47b5d692005-04-24 02:38:05 -05005716 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005717 p_port = currCard->ioPort;
5718 pCurrNvRam = currCard->pNvRamInfo;
5719
5720
5721 if(pCurrNvRam){
5722 ScamFlg = pCurrNvRam->niScamConf;
5723 i = pCurrNvRam->niSysConf;
5724 }
5725 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005726 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5727 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005728 }
5729 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5730 return;
5731
James Bottomley 47b5d692005-04-24 02:38:05 -05005732 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733
5734 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5735 too slow to return to SCAM selection */
5736
5737 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005738 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005739 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005740 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005741
James Bottomley 47b5d692005-04-24 02:38:05 -05005742 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005743
5744 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5745 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005746 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005747
James Bottomley 47b5d692005-04-24 02:38:05 -05005748 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005749
5750 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005751 FPT_scxferc(p_port,SYNC_PTRN);
5752 FPT_scxferc(p_port,DOM_MSTR);
5753 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005754 } while ( loser == 0xFF );
5755
James Bottomley 47b5d692005-04-24 02:38:05 -05005756 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005757
5758 if ((p_power_up) && (!loser))
5759 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005760 FPT_sresb(p_port,p_card);
5761 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005762
James Bottomley 47b5d692005-04-24 02:38:05 -05005763 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005764
James Bottomley 47b5d692005-04-24 02:38:05 -05005765 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005766
5767 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005768 FPT_scxferc(p_port, SYNC_PTRN);
5769 FPT_scxferc(p_port, DOM_MSTR);
5770 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005771 id_string[0]);
5772 } while ( loser == 0xFF );
5773
James Bottomley 47b5d692005-04-24 02:38:05 -05005774 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005775 }
5776 }
5777
5778 else
5779 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005780 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005781 }
5782
5783
5784 if (!loser)
5785 {
5786
James Bottomley 47b5d692005-04-24 02:38:05 -05005787 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005788
5789
5790 if (ScamFlg & SCAM_ENABLED)
5791 {
5792
5793 for (i=0; i < MAX_SCSI_TAR; i++)
5794 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005795 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5796 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005797 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005798 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005799 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005800 FPT_scamInfo[i].state = LEGACY;
5801 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5802 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005803 {
5804
James Bottomley 47b5d692005-04-24 02:38:05 -05005805 FPT_scamInfo[i].id_string[0] = 0xFF;
5806 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005807 if(pCurrNvRam == NULL)
5808 currCard->globalFlags |= F_UPDATE_EEPROM;
5809 }
5810 }
5811 }
5812 }
5813
James Bottomley 47b5d692005-04-24 02:38:05 -05005814 FPT_sresb(p_port,p_card);
5815 FPT_Wait1Second(p_port);
5816 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5817 FPT_scsel(p_port);
5818 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005819 }
5820
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821 }
5822
5823 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5824 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005825 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5826 assigned_id = 0;
5827 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005828
5829 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005830 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831
James Bottomley 47b5d692005-04-24 02:38:05 -05005832 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833 if (i == ASSIGN_ID)
5834 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005835 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005836 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005837 i = FPT_scxferc(p_port,0x00);
5838 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005839 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005840 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841
James Bottomley 47b5d692005-04-24 02:38:05 -05005842 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843 {
5844 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005845 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005846 FPT_inisci(p_card, p_port, p_our_id);
5847 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5848 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005849 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005850 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851 }
5852 }
5853 }
5854 }
5855
5856 else if (i == SET_P_FLAG)
5857 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005858 if (!(FPT_scsendi(p_port,
5859 &FPT_scamInfo[p_our_id].id_string[0])))
5860 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005861 }
5862 }while (!assigned_id);
5863
James Bottomley 47b5d692005-04-24 02:38:05 -05005864 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005865 }
5866
Linus Torvalds1da177e2005-04-16 15:20:36 -07005867 if (ScamFlg & SCAM_ENABLED)
5868 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005869 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005870 if (currCard->globalFlags & F_UPDATE_EEPROM)
5871 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005872 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5874 }
5875 }
5876
5877
Linus Torvalds1da177e2005-04-16 15:20:36 -07005878/*
5879 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5880 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005881 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5882 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005883 k++;
5884 }
5885
5886 if (k==2)
5887 currCard->globalFlags |= F_SINGLE_DEVICE;
5888 else
5889 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5890*/
5891}
5892
5893
5894/*---------------------------------------------------------------------
5895 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005896 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005897 *
5898 * Description: Gain control of the bus and wait SCAM select time (250ms)
5899 *
5900 *---------------------------------------------------------------------*/
5901
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005902static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005903{
5904 if (p_sel_type == INIT_SELTD)
5905 {
5906
5907 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5908
5909
5910 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005911 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005912
5913 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005914 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005915
5916 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5917
5918 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5919
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5921 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005922 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005923 }
5924
5925
5926 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5927
5928 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5929
5930 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5931 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005932 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005933 }
5934 }
5935
5936
5937 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5938 & ~ACTdeassert));
5939 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5940 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005941 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5943
5944 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5945
5946 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5947 & ~SCSI_BSY));
5948
James Bottomley 47b5d692005-04-24 02:38:05 -05005949 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005950
James Bottomley 47b5d692005-04-24 02:38:05 -05005951 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005952}
5953
5954
5955/*---------------------------------------------------------------------
5956 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005957 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005958 *
5959 * Description: Release the SCSI bus and disable SCAM selection.
5960 *
5961 *---------------------------------------------------------------------*/
5962
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005963static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005964{
5965 WR_HARPOON(p_port+hp_page_ctrl,
5966 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5967
5968
5969 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5970
5971 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5972 & ~SCSI_BUS_EN));
5973
5974 WR_HARPOON(p_port+hp_scsisig, 0x00);
5975
5976
5977 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5978 & ~SCAM_EN));
5979
5980 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5981 | ACTdeassert));
5982
Linus Torvalds1da177e2005-04-16 15:20:36 -07005983 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005984
5985 WR_HARPOON(p_port+hp_page_ctrl,
5986 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5987}
5988
5989
5990
5991/*---------------------------------------------------------------------
5992 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005993 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005994 *
5995 * Description: Assign an ID to all the SCAM devices.
5996 *
5997 *---------------------------------------------------------------------*/
5998
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005999static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006000{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006001 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006002
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006003 unsigned char i,k,scam_id;
6004 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006005 PNVRamInfo pCurrNvRam;
6006 ushort_ptr pCrcBytes;
6007
James Bottomley 47b5d692005-04-24 02:38:05 -05006008 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006009
James Bottomley 47b5d692005-04-24 02:38:05 -05006010 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006011
6012 while (!i)
6013 {
6014
6015 for (k=0; k < ID_STRING_LENGTH; k++)
6016 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006017 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006018 }
6019
James Bottomley 47b5d692005-04-24 02:38:05 -05006020 FPT_scxferc(p_port,SYNC_PTRN);
6021 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006022
James Bottomley 47b5d692005-04-24 02:38:05 -05006023 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006024 {
6025 if(pCurrNvRam){
6026 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006027 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6028 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006029 temp_id_string[1] = crcBytes[2];
6030 temp_id_string[2] = crcBytes[0];
6031 temp_id_string[3] = crcBytes[1];
6032 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006033 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006034 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006035 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036
6037 if (i == CLR_PRIORITY)
6038 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006039 FPT_scxferc(p_port,MISC_CODE);
6040 FPT_scxferc(p_port,CLR_P_FLAG);
6041 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042 }
6043
6044 else if (i != NO_ID_AVAIL)
6045 {
6046 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006047 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006048 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006049 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006050
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006051 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006052
6053
6054 for (k=1; k < 0x08; k <<= 1)
6055 if (!( k & i ))
6056 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6057
James Bottomley 47b5d692005-04-24 02:38:05 -05006058 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006059
James Bottomley 47b5d692005-04-24 02:38:05 -05006060 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006061 }
6062 }
6063
6064 else
6065 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006066 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006067 }
6068
6069 } /*End while */
6070
James Bottomley 47b5d692005-04-24 02:38:05 -05006071 FPT_scxferc(p_port,SYNC_PTRN);
6072 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006073}
6074
6075
6076
6077
6078
6079/*---------------------------------------------------------------------
6080 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006081 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006082 *
6083 * Description: Select all the SCAM devices.
6084 *
6085 *---------------------------------------------------------------------*/
6086
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006087static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006088{
6089
6090 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006091 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006092
6093 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6094
6095
6096 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006097 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6098 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006099
6100
6101 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006102 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006103
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006104 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6105 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006106 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006107
6108 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6109}
6110
6111
6112
6113/*---------------------------------------------------------------------
6114 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006115 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006116 *
6117 * Description: Handshake the p_data (DB4-0) across the bus.
6118 *
6119 *---------------------------------------------------------------------*/
6120
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006121static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006122{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006123 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006124
6125 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6126
6127 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6128
6129 curr_data &= ~BIT(7);
6130
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132
James Bottomley 47b5d692005-04-24 02:38:05 -05006133 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006134 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6135
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006136 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006137
6138 curr_data |= BIT(6);
6139
6140 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6141
6142 curr_data &= ~BIT(5);
6143
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145
James Bottomley 47b5d692005-04-24 02:38:05 -05006146 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006147
6148 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6149 curr_data |= BIT(7);
6150
6151 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6152
6153 curr_data &= ~BIT(6);
6154
6155 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6156
James Bottomley 47b5d692005-04-24 02:38:05 -05006157 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006158
6159 return(ret_data);
6160}
6161
6162
6163/*---------------------------------------------------------------------
6164 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006165 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006166 *
6167 * Description: Transfer our Identification string to determine if we
6168 * will be the dominant master.
6169 *
6170 *---------------------------------------------------------------------*/
6171
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006172static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006173{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006174 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006175
James Bottomley 47b5d692005-04-24 02:38:05 -05006176 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177
6178 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6179
6180 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6181
6182 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006183 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006184
6185 else if (p_id_string[byte_cnt] & bit_cnt)
6186
James Bottomley 47b5d692005-04-24 02:38:05 -05006187 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006188
6189 else {
6190
James Bottomley 47b5d692005-04-24 02:38:05 -05006191 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006192 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006193 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006194 }
6195
6196 if ((ret_data & 0x1C) == 0x10)
6197 return(0x00); /*End of isolation stage, we won! */
6198
6199 if (ret_data & 0x1C)
6200 return(0xFF);
6201
6202 if ((defer) && (!(ret_data & 0x1F)))
6203 return(0x01); /*End of isolation stage, we lost. */
6204
6205 } /*bit loop */
6206
6207 } /*byte loop */
6208
6209 if (defer)
6210 return(0x01); /*We lost */
6211 else
6212 return(0); /*We WON! Yeeessss! */
6213}
6214
6215
6216
6217/*---------------------------------------------------------------------
6218 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006219 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006220 *
6221 * Description: Transfer the Identification string.
6222 *
6223 *---------------------------------------------------------------------*/
6224
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006225static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006226{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006227 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006228
6229 the_data = 0;
6230
6231 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6232
6233 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6234
James Bottomley 47b5d692005-04-24 02:38:05 -05006235 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006236
6237 if (ret_data & 0xFC)
6238 return(0xFF);
6239
6240 else {
6241
6242 the_data <<= 1;
6243 if (ret_data & BIT(1)) {
6244 the_data |= 1;
6245 }
6246 }
6247
6248 if ((ret_data & 0x1F) == 0)
6249 {
6250/*
6251 if(bit_cnt != 0 || bit_cnt != 8)
6252 {
6253 byte_cnt = 0;
6254 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006255 FPT_scxferc(p_port, SYNC_PTRN);
6256 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006257 continue;
6258 }
6259*/
6260 if (byte_cnt)
6261 return(0x00);
6262 else
6263 return(0xFF);
6264 }
6265
6266 } /*bit loop */
6267
6268 p_id_string[byte_cnt] = the_data;
6269
6270 } /*byte loop */
6271
6272 return(0);
6273}
6274
6275
6276
6277/*---------------------------------------------------------------------
6278 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006279 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006280 *
6281 * Description: Sample the SCSI data bus making sure the signal has been
6282 * deasserted for the correct number of consecutive samples.
6283 *
6284 *---------------------------------------------------------------------*/
6285
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006286static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006287{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006288 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006289
6290 i = 0;
6291 while ( i < MAX_SCSI_TAR ) {
6292
6293 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6294
6295 i = 0;
6296
6297 else
6298
6299 i++;
6300
6301 }
6302}
6303
6304
6305
6306/*---------------------------------------------------------------------
6307 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006308 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006309 *
6310 * Description: Sample the SCSI Signal lines making sure the signal has been
6311 * deasserted for the correct number of consecutive samples.
6312 *
6313 *---------------------------------------------------------------------*/
6314
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006315static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006316{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006317 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006318
6319 i = 0;
6320 while ( i < MAX_SCSI_TAR ) {
6321
6322 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6323
6324 i = 0;
6325
6326 else
6327
6328 i++;
6329
6330 }
6331}
6332
6333
6334/*---------------------------------------------------------------------
6335 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006336 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006337 *
6338 * Description: Make sure we received a valid data byte.
6339 *
6340 *---------------------------------------------------------------------*/
6341
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006342static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006343{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006344 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006345
6346 for (count=1; count < 0x08; count<<=1) {
6347 if (!(p_quintet & count))
6348 p_quintet -= 0x80;
6349 }
6350
6351 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006352 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006353
6354 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006355 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006356}
6357
6358
6359/*---------------------------------------------------------------------
6360 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006361 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006362 *
6363 * Description: Select the specified device ID using a selection timeout
6364 * less than 4ms. If somebody responds then it is a legacy
6365 * drive and this ID must be marked as such.
6366 *
6367 *---------------------------------------------------------------------*/
6368
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006369static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006370{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006371 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372
6373 WR_HARPOON(p_port+hp_page_ctrl,
6374 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6375
6376 ARAM_ACCESS(p_port);
6377
6378 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6379 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6380
6381
6382 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6383 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6384 }
6385 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6386
6387 WRW_HARPOON((p_port+hp_intstat),
6388 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6389
6390 WR_HARPOON(p_port+hp_select_id, targ_id);
6391
6392 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6393 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6394 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6395
6396
6397 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6398 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6399
6400 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006401 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006402
6403 DISABLE_AUTO(p_port);
6404
6405 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6406 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6407
6408 SGRAM_ACCESS(p_port);
6409
6410 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6411
6412 WRW_HARPOON((p_port+hp_intstat),
6413 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6414
6415 WR_HARPOON(p_port+hp_page_ctrl,
6416 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6417
James Bottomley 47b5d692005-04-24 02:38:05 -05006418 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006419 }
6420
6421 else {
6422
6423 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6424 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6425 {
6426 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6427 ACCEPT_MSG(p_port);
6428 }
6429 }
6430
6431 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6432
6433 WR_HARPOON(p_port+hp_page_ctrl,
6434 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6435
James Bottomley 47b5d692005-04-24 02:38:05 -05006436 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006437 }
6438}
6439
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440/*---------------------------------------------------------------------
6441 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006442 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006443 *
6444 * Description: Wait to be selected by another SCAM initiator.
6445 *
6446 *---------------------------------------------------------------------*/
6447
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006448static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006449{
6450 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6451}
6452
6453
6454/*---------------------------------------------------------------------
6455 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006456 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457 *
6458 * Description: Setup the data Structure with the info from the EEPROM.
6459 *
6460 *---------------------------------------------------------------------*/
6461
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006462static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006463{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006464 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006465 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466 PNVRamInfo pCurrNvRam;
6467
James Bottomley 47b5d692005-04-24 02:38:05 -05006468 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006469
6470 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6471 max_id = 0x08;
6472
6473 else
6474 max_id = 0x10;
6475
6476 if(pCurrNvRam){
6477 for(i = 0; i < max_id; i++){
6478
6479 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006480 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006481 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006482 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006483
James Bottomley 47b5d692005-04-24 02:38:05 -05006484 if(FPT_scamInfo[i].id_string[0] == 0x00)
6485 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006486 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006487 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006488
6489 }
6490 }else {
6491 for (i=0; i < max_id; i++)
6492 {
6493 for (k=0; k < ID_STRING_LENGTH; k+=2)
6494 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006495 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6496 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006497 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006499 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500 }
6501
James Bottomley 47b5d692005-04-24 02:38:05 -05006502 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6503 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504
James Bottomley 47b5d692005-04-24 02:38:05 -05006505 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506
6507 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006508 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006509
6510 }
6511 }
6512 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006513 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006514
6515}
6516
6517/*---------------------------------------------------------------------
6518 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006519 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520 *
6521 * Description: Match the Device ID string with our values stored in
6522 * the EEPROM.
6523 *
6524 *---------------------------------------------------------------------*/
6525
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006526static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006527{
6528
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006529 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006530
6531
6532 for (i=0; i < MAX_SCSI_TAR; i++) {
6533
James Bottomley 47b5d692005-04-24 02:38:05 -05006534 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006535
6536 for (k=0; k < ID_STRING_LENGTH; k++)
6537 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006538 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6539 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540 }
6541
6542 if (match)
6543 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006544 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006545 return(i);
6546 }
6547
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 }
6549
6550
6551
6552 if (p_id_string[0] & BIT(5))
6553 i = 8;
6554 else
6555 i = MAX_SCSI_TAR;
6556
6557 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006558 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559 else
6560 match = 7;
6561
6562 while (i > 0)
6563 {
6564 i--;
6565
James Bottomley 47b5d692005-04-24 02:38:05 -05006566 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567 {
6568 for (k=0; k < ID_STRING_LENGTH; k++)
6569 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006570 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571 }
6572
James Bottomley 47b5d692005-04-24 02:38:05 -05006573 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006574
James Bottomley 47b5d692005-04-24 02:38:05 -05006575 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6576 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006577 return(match);
6578
6579 }
6580
6581
6582 match--;
6583
6584 if (match == 0xFF)
6585 {
6586 if (p_id_string[0] & BIT(5))
6587 match = 7;
6588 else
6589 match = MAX_SCSI_TAR-1;
6590 }
6591 }
6592
6593
6594
6595 if (p_id_string[0] & BIT(7))
6596 {
6597 return(CLR_PRIORITY);
6598 }
6599
6600
6601 if (p_id_string[0] & BIT(5))
6602 i = 8;
6603 else
6604 i = MAX_SCSI_TAR;
6605
6606 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006607 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006608 else
6609 match = 7;
6610
6611 while (i > 0)
6612 {
6613
6614 i--;
6615
James Bottomley 47b5d692005-04-24 02:38:05 -05006616 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006617 {
6618 for (k=0; k < ID_STRING_LENGTH; k++)
6619 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006620 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006621 }
6622
James Bottomley 47b5d692005-04-24 02:38:05 -05006623 FPT_scamInfo[match].id_string[0] |= BIT(7);
6624 FPT_scamInfo[match].state = ID_ASSIGNED;
6625 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6626 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006627 return(match);
6628
6629 }
6630
6631
6632 match--;
6633
6634 if (match == 0xFF)
6635 {
6636 if (p_id_string[0] & BIT(5))
6637 match = 7;
6638 else
6639 match = MAX_SCSI_TAR-1;
6640 }
6641 }
6642
6643 return(NO_ID_AVAIL);
6644}
6645
6646
6647/*---------------------------------------------------------------------
6648 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006649 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006650 *
6651 * Description: Save off the device SCAM ID strings.
6652 *
6653 *---------------------------------------------------------------------*/
6654
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006655static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006656{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006657 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006658 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659
6660
6661 sum_data = 0x0000;
6662
6663 for (i = 1; i < EE_SCAMBASE/2; i++)
6664 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006665 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006666 }
6667
6668
James Bottomley 47b5d692005-04-24 02:38:05 -05006669 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006670
6671 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6672 max_id = 0x08;
6673
6674 else
6675 max_id = 0x10;
6676
6677 for (i=0; i < max_id; i++)
6678 {
6679
6680 for (k=0; k < ID_STRING_LENGTH; k+=2)
6681 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006682 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006684 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006685 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006686 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6687 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006688 }
6689 }
6690
6691
James Bottomley 47b5d692005-04-24 02:38:05 -05006692 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6693 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006695
6696/*---------------------------------------------------------------------
6697 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006698 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006699 *
6700 * Description: Setup the Xbow for normal operation.
6701 *
6702 *---------------------------------------------------------------------*/
6703
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006704static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006705{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006706unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006707
6708 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006709 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006710
6711 WR_HARPOON(port+hp_scsireset,0x00);
6712 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6713
6714 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6715 FIFO_CLR));
6716
6717 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6718
6719 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6720
6721 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6722 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6723
6724 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6725
James Bottomley 47b5d692005-04-24 02:38:05 -05006726 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006727 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6728
6729 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006730 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006731
James Bottomley 47b5d692005-04-24 02:38:05 -05006732 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006733
6734 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6735
6736 /* Turn on SCSI_MODE8 for narrow cards to fix the
6737 strapping issue with the DUAL CHANNEL card */
6738 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6739 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6740
Linus Torvalds1da177e2005-04-16 15:20:36 -07006741 WR_HARPOON(port+hp_page_ctrl, i);
6742
6743}
6744
6745
6746/*---------------------------------------------------------------------
6747 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006748 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006749 *
6750 * Description: Initialize the BusMaster for normal operations.
6751 *
6752 *---------------------------------------------------------------------*/
6753
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006754static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006755{
6756
6757
6758 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6759 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6760
6761 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6762
6763
6764 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6765
6766 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6767
6768
Linus Torvalds1da177e2005-04-16 15:20:36 -07006769 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6770 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6771 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6772 ~SCATTER_EN));
6773}
6774
6775
6776/*---------------------------------------------------------------------
6777 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006778 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006779 *
6780 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6781 * necessary.
6782 *
6783 *---------------------------------------------------------------------*/
6784
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006785static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006787 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788
6789 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6790 max_wd_cnt = EEPROM_WD_CNT;
6791 else
6792 max_wd_cnt = EEPROM_WD_CNT * 2;
6793
James Bottomley 47b5d692005-04-24 02:38:05 -05006794 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795
6796 if (temp == 0x4641) {
6797
6798 for (index = 2; index < max_wd_cnt; index++) {
6799
James Bottomley 47b5d692005-04-24 02:38:05 -05006800 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006801
6802 }
6803
James Bottomley 47b5d692005-04-24 02:38:05 -05006804 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006805
6806 return; /*EEPROM is Okay so return now! */
6807 }
6808 }
6809
6810
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006811 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812
6813 for (index = 0; index < max_wd_cnt; index++) {
6814
James Bottomley 47b5d692005-04-24 02:38:05 -05006815 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 }
6817
6818 temp = 0;
6819
James Bottomley 47b5d692005-04-24 02:38:05 -05006820 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006822 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006823 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006824 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006826 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006828 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006830 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006832 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006834 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006835 temp += 0x0007;
6836
James Bottomley 47b5d692005-04-24 02:38:05 -05006837 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006839 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/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, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842 temp += 0x0000;
6843
James Bottomley 47b5d692005-04-24 02:38:05 -05006844 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/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_TBL45/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_TBL67/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_TBL89/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_TBLab/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_TBLcd/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_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 temp += 0x4242;
6860
6861
James Bottomley 47b5d692005-04-24 02:38:05 -05006862 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006863 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006864 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006866 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006870 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006872 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006874 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877 temp += 0x2020;
6878
6879 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006880 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881 temp += (0x0700+TYPE_CODE0);
6882 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006883 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006884 temp += 0x5542; /* BUSLOGIC */
6885 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006886 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887 temp += 0x4C53;
6888 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006889 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890 temp += 0x474F;
6891 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006892 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006893 temp += 0x4349;
6894 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006895 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006896 temp += 0x5442; /* BT- 930 */
6897 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006898 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006899 temp += 0x202D;
6900 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006901 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006902 temp += 0x3339;
6903 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006904 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006905 temp += 0x2030;
6906 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006907 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006908 temp += 0x5453;
6909 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006910 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911 temp += 0x5645;
6912 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006913 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006914 temp += 0x2045;
6915 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006916 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006917 temp += 0x202F;
6918 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006919 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006920 temp += 0x4F4A;
6921 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006922 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006923 temp += 0x204E;
6924 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006925 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006926 temp += 0x3539;
6927
6928
6929
James Bottomley 47b5d692005-04-24 02:38:05 -05006930 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006931
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006932 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006933
6934}
6935
Linus Torvalds1da177e2005-04-16 15:20:36 -07006936
6937/*---------------------------------------------------------------------
6938 *
6939 * Function: Queue Search Select
6940 *
6941 * Description: Try to find a new command to execute.
6942 *
6943 *---------------------------------------------------------------------*/
6944
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006945static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006946{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006947 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006948 PSCCBMgr_tar_info currTar_Info;
6949 PSCCB pOldSccb;
6950
6951 scan_ptr = pCurrCard->scanIndex;
6952 do
6953 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006954 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006955 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6956 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6957 {
6958 if (currTar_Info->TarSelQ_Cnt != 0)
6959 {
6960
6961 scan_ptr++;
6962 if (scan_ptr == MAX_SCSI_TAR)
6963 scan_ptr = 0;
6964
6965 for(lun=0; lun < MAX_LUN; lun++)
6966 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006967 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006968 {
6969
6970 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6971 pOldSccb = NULL;
6972
6973 while((pCurrCard->currentSCCB != NULL) &&
6974 (lun != pCurrCard->currentSCCB->Lun))
6975 {
6976 pOldSccb = pCurrCard->currentSCCB;
6977 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6978 Sccb_forwardlink;
6979 }
6980 if(pCurrCard->currentSCCB == NULL)
6981 continue;
6982 if(pOldSccb != NULL)
6983 {
6984 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6985 Sccb_forwardlink;
6986 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6987 Sccb_backlink;
6988 currTar_Info->TarSelQ_Cnt--;
6989 }
6990 else
6991 {
6992 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6993
6994 if (currTar_Info->TarSelQ_Head == NULL)
6995 {
6996 currTar_Info->TarSelQ_Tail = NULL;
6997 currTar_Info->TarSelQ_Cnt = 0;
6998 }
6999 else
7000 {
7001 currTar_Info->TarSelQ_Cnt--;
7002 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7003 }
7004 }
7005 pCurrCard->scanIndex = scan_ptr;
7006
7007 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7008
7009 break;
7010 }
7011 }
7012 }
7013
7014 else
7015 {
7016 scan_ptr++;
7017 if (scan_ptr == MAX_SCSI_TAR) {
7018 scan_ptr = 0;
7019 }
7020 }
7021
7022 }
7023 else
7024 {
7025 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007026 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007027 {
7028
7029 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7030
7031 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7032
7033 if (currTar_Info->TarSelQ_Head == NULL)
7034 {
7035 currTar_Info->TarSelQ_Tail = NULL;
7036 currTar_Info->TarSelQ_Cnt = 0;
7037 }
7038 else
7039 {
7040 currTar_Info->TarSelQ_Cnt--;
7041 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7042 }
7043
7044 scan_ptr++;
7045 if (scan_ptr == MAX_SCSI_TAR)
7046 scan_ptr = 0;
7047
7048 pCurrCard->scanIndex = scan_ptr;
7049
7050 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7051
7052 break;
7053 }
7054
7055 else
7056 {
7057 scan_ptr++;
7058 if (scan_ptr == MAX_SCSI_TAR)
7059 {
7060 scan_ptr = 0;
7061 }
7062 }
7063 }
7064 } while (scan_ptr != pCurrCard->scanIndex);
7065}
7066
7067
7068/*---------------------------------------------------------------------
7069 *
7070 * Function: Queue Select Fail
7071 *
7072 * Description: Add the current SCCB to the head of the Queue.
7073 *
7074 *---------------------------------------------------------------------*/
7075
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007076static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007077{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007078 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007079 PSCCBMgr_tar_info currTar_Info;
7080
7081 if (pCurrCard->currentSCCB != NULL)
7082 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007083 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007084 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007085
7086 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7087
7088 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7089
7090 if (currTar_Info->TarSelQ_Cnt == 0)
7091 {
7092 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7093 }
7094
7095 else
7096 {
7097 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7098 }
7099
7100
7101 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7102
7103 pCurrCard->currentSCCB = NULL;
7104 currTar_Info->TarSelQ_Cnt++;
7105 }
7106}
7107/*---------------------------------------------------------------------
7108 *
7109 * Function: Queue Command Complete
7110 *
7111 * Description: Call the callback function with the current SCCB.
7112 *
7113 *---------------------------------------------------------------------*/
7114
James Bottomley 47b5d692005-04-24 02:38:05 -05007115static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007116 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007117{
7118
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007119 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007120 CALL_BK_FN callback;
7121 PSCCBMgr_tar_info currTar_Info;
7122
7123 SCSIcmd = p_sccb->Cdb[0];
7124
7125
7126 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7127
7128 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7129 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7130 (p_sccb->TargetStatus != SSCHECK))
7131
7132 if ((SCSIcmd == SCSI_READ) ||
7133 (SCSIcmd == SCSI_WRITE) ||
7134 (SCSIcmd == SCSI_READ_EXTENDED) ||
7135 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7136 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7137 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7138 (pCurrCard->globalFlags & F_NO_FILTER)
7139 )
7140 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7141 }
7142
7143
7144 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7145 {
7146 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7147 p_sccb->SccbStatus = SCCB_ERROR;
7148 else
7149 p_sccb->SccbStatus = SCCB_SUCCESS;
7150 }
7151
7152 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7153
7154 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7155 for (i=0; i < 6; i++) {
7156 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7157 }
7158 }
7159
7160 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7161 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7162
James Bottomley 47b5d692005-04-24 02:38:05 -05007163 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007164 }
7165
7166 pCurrCard->cmdCounter--;
7167 if (!pCurrCard->cmdCounter) {
7168
7169 if (pCurrCard->globalFlags & F_GREEN_PC) {
7170 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7171 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7172 }
7173
7174 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7175 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7176
7177 }
7178
7179 if(pCurrCard->discQCount != 0)
7180 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007181 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007182 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7183 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7184 {
7185 pCurrCard->discQCount--;
7186 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7187 }
7188 else
7189 {
7190 if(p_sccb->Sccb_tag)
7191 {
7192 pCurrCard->discQCount--;
7193 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7194 }else
7195 {
7196 pCurrCard->discQCount--;
7197 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7198 }
7199 }
7200
7201 }
7202
7203 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7204 callback(p_sccb);
7205 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7206 pCurrCard->currentSCCB = NULL;
7207}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007208
7209
7210/*---------------------------------------------------------------------
7211 *
7212 * Function: Queue Disconnect
7213 *
7214 * Description: Add SCCB to our disconnect array.
7215 *
7216 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007217static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007218{
7219 PSCCBMgr_tar_info currTar_Info;
7220
James Bottomley 47b5d692005-04-24 02:38:05 -05007221 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007222
James Bottomley 47b5d692005-04-24 02:38:05 -05007223 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007224 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7225 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007226 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007227 }
7228 else
7229 {
7230 if (p_sccb->Sccb_tag)
7231 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007232 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7233 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7234 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007235 }else
7236 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007237 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007238 }
7239 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007240 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007241}
7242
7243
7244/*---------------------------------------------------------------------
7245 *
7246 * Function: Queue Flush SCCB
7247 *
7248 * Description: Flush all SCCB's back to the host driver for this target.
7249 *
7250 *---------------------------------------------------------------------*/
7251
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007252static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007253{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007254 unsigned char qtag,thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007255 PSCCB currSCCB;
7256 PSCCBMgr_tar_info currTar_Info;
7257
James Bottomley 47b5d692005-04-24 02:38:05 -05007258 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007259 if(currSCCB != NULL)
7260 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007261 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007262 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007263
7264 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7265
James Bottomley 47b5d692005-04-24 02:38:05 -05007266 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7267 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007268 {
7269
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007270 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007271
James Bottomley 47b5d692005-04-24 02:38:05 -05007272 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007273
James Bottomley 47b5d692005-04-24 02:38:05 -05007274 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007275 currTar_Info->TarTagQ_Cnt--;
7276
7277 }
7278 }
7279 }
7280
7281}
7282
7283/*---------------------------------------------------------------------
7284 *
7285 * Function: Queue Flush Target SCCB
7286 *
7287 * Description: Flush all SCCB's back to the host driver for this target.
7288 *
7289 *---------------------------------------------------------------------*/
7290
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007291static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7292 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007293{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007294 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007295 PSCCBMgr_tar_info currTar_Info;
7296
James Bottomley 47b5d692005-04-24 02:38:05 -05007297 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007298
7299 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7300
James Bottomley 47b5d692005-04-24 02:38:05 -05007301 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7302 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007303 {
7304
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007305 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007306
James Bottomley 47b5d692005-04-24 02:38:05 -05007307 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007308
James Bottomley 47b5d692005-04-24 02:38:05 -05007309 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007310 currTar_Info->TarTagQ_Cnt--;
7311
7312 }
7313 }
7314
7315}
7316
7317
7318
7319
7320
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007321static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007322{
7323 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007324 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007325
7326 p_SCCB->Sccb_forwardlink = NULL;
7327
7328 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7329
7330 if (currTar_Info->TarSelQ_Cnt == 0) {
7331
7332 currTar_Info->TarSelQ_Head = p_SCCB;
7333 }
7334
7335 else {
7336
7337 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7338 }
7339
7340
7341 currTar_Info->TarSelQ_Tail = p_SCCB;
7342 currTar_Info->TarSelQ_Cnt++;
7343}
7344
7345
7346/*---------------------------------------------------------------------
7347 *
7348 * Function: Queue Find SCCB
7349 *
7350 * Description: Search the target select Queue for this SCCB, and
7351 * remove it if found.
7352 *
7353 *---------------------------------------------------------------------*/
7354
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007355static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007356{
7357 PSCCB q_ptr;
7358 PSCCBMgr_tar_info currTar_Info;
7359
James Bottomley 47b5d692005-04-24 02:38:05 -05007360 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007361
7362 q_ptr = currTar_Info->TarSelQ_Head;
7363
7364 while(q_ptr != NULL) {
7365
7366 if (q_ptr == p_SCCB) {
7367
7368
7369 if (currTar_Info->TarSelQ_Head == q_ptr) {
7370
7371 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7372 }
7373
7374 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7375
7376 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7377 }
7378
7379 if (q_ptr->Sccb_forwardlink != NULL) {
7380 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7381 }
7382
7383 if (q_ptr->Sccb_backlink != NULL) {
7384 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7385 }
7386
7387 currTar_Info->TarSelQ_Cnt--;
7388
James Bottomley 47b5d692005-04-24 02:38:05 -05007389 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007390 }
7391
7392 else {
7393 q_ptr = q_ptr->Sccb_forwardlink;
7394 }
7395 }
7396
7397
James Bottomley 47b5d692005-04-24 02:38:05 -05007398 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007399
7400}
7401
7402
7403/*---------------------------------------------------------------------
7404 *
7405 * Function: Utility Update Residual Count
7406 *
7407 * Description: Update the XferCnt to the remaining byte count.
7408 * If we transferred all the data then just write zero.
7409 * If Non-SG transfer then report Total Cnt - Actual Transfer
7410 * Cnt. For SG transfers add the count fields of all
7411 * remaining SG elements, as well as any partial remaining
7412 * element.
7413 *
7414 *---------------------------------------------------------------------*/
7415
James Bottomley 47b5d692005-04-24 02:38:05 -05007416static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007417{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007418 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007419 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007420 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007421
7422 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7423
7424 p_SCCB->DataLength = 0x0000;
7425 }
7426
7427 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7428
7429 partial_cnt = 0x0000;
7430
7431 sg_index = p_SCCB->Sccb_sgseg;
7432
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007433 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007434
7435 if (p_SCCB->Sccb_SGoffset) {
7436
7437 partial_cnt = p_SCCB->Sccb_SGoffset;
7438 sg_index++;
7439 }
7440
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007441 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007442 p_SCCB->DataLength ) {
7443
7444 partial_cnt += *(sg_ptr+(sg_index * 2));
7445 sg_index++;
7446 }
7447
7448 p_SCCB->DataLength = partial_cnt;
7449 }
7450
7451 else {
7452
7453 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7454 }
7455}
7456
7457
7458/*---------------------------------------------------------------------
7459 *
7460 * Function: Wait 1 Second
7461 *
7462 * Description: Wait for 1 second.
7463 *
7464 *---------------------------------------------------------------------*/
7465
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007466static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007467{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007468 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007469
7470 for(i=0; i < 4; i++) {
7471
James Bottomley 47b5d692005-04-24 02:38:05 -05007472 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007473
7474 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7475 break;
7476
7477 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7478 break;
7479 }
7480}
7481
7482
7483/*---------------------------------------------------------------------
7484 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007485 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007486 *
7487 * Description: Wait the desired delay.
7488 *
7489 *---------------------------------------------------------------------*/
7490
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007491static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007492{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007493 unsigned char old_timer;
7494 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007495
7496 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7497
7498 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7499 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7500
7501 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7502 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007503 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007504
7505
7506 WR_HARPOON(p_port+hp_portctrl_0,
7507 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7508
7509 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7510
7511 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7512 break;
7513
7514 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7515 break;
7516 }
7517
7518 WR_HARPOON(p_port+hp_portctrl_0,
7519 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7520
7521 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007522 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007523
7524 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7525
7526 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7527}
7528
7529
7530/*---------------------------------------------------------------------
7531 *
7532 * Function: Enable/Disable Write to EEPROM
7533 *
7534 * Description: The EEPROM must first be enabled for writes
7535 * A total of 9 clocks are needed.
7536 *
7537 *---------------------------------------------------------------------*/
7538
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007539static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007540{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007541 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007542
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007543 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 -07007544
7545 if (p_mode)
7546
James Bottomley 47b5d692005-04-24 02:38:05 -05007547 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007548
7549 else
7550
7551
James Bottomley 47b5d692005-04-24 02:38:05 -05007552 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007553
7554 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7555 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7556}
7557
7558
7559/*---------------------------------------------------------------------
7560 *
7561 * Function: Write EEPROM
7562 *
7563 * Description: Write a word to the EEPROM at the specified
7564 * address.
7565 *
7566 *---------------------------------------------------------------------*/
7567
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007568static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007569{
7570
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007571 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007572 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007573
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007574 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 -07007575 (SEE_MS | SEE_CS));
7576
7577
7578
James Bottomley 47b5d692005-04-24 02:38:05 -05007579 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007580
7581
7582 ee_value |= (SEE_MS + SEE_CS);
7583
7584 for(i = 0x8000; i != 0; i>>=1) {
7585
7586 if (i & ee_data)
7587 ee_value |= SEE_DO;
7588 else
7589 ee_value &= ~SEE_DO;
7590
7591 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7592 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7593 ee_value |= SEE_CLK; /* Clock data! */
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 ee_value &= ~SEE_CLK;
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 }
7600 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7601 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7602
James Bottomley 47b5d692005-04-24 02:38:05 -05007603 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007604
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7606 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7607 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7608}
7609
7610/*---------------------------------------------------------------------
7611 *
7612 * Function: Read EEPROM
7613 *
7614 * Description: Read a word from the EEPROM at the desired
7615 * address.
7616 *
7617 *---------------------------------------------------------------------*/
7618
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007619static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007620{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007621 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007622
7623 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007624 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007625 do
7626 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007627 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007628
7629 if(ee_data1 == ee_data2)
7630 return(ee_data1);
7631
7632 ee_data1 = ee_data2;
7633 i++;
7634
7635 }while(i < 4);
7636
7637 return(ee_data1);
7638}
7639
7640/*---------------------------------------------------------------------
7641 *
7642 * Function: Read EEPROM Original
7643 *
7644 * Description: Read a word from the EEPROM at the desired
7645 * address.
7646 *
7647 *---------------------------------------------------------------------*/
7648
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007649static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007650{
7651
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007652 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007653 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007654
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007655 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 -07007656 (SEE_MS | SEE_CS));
7657
7658
James Bottomley 47b5d692005-04-24 02:38:05 -05007659 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007660
7661
7662 ee_value |= (SEE_MS + SEE_CS);
7663 ee_data = 0;
7664
7665 for(i = 1; i <= 16; i++) {
7666
7667 ee_value |= SEE_CLK; /* Clock data! */
7668 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7669 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7670 ee_value &= ~SEE_CLK;
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673
7674 ee_data <<= 1;
7675
7676 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7677 ee_data |= 1;
7678 }
7679
7680 ee_value &= ~(SEE_MS + SEE_CS);
7681 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7682 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7683
7684 return(ee_data);
7685}
7686
7687
7688/*---------------------------------------------------------------------
7689 *
7690 * Function: Send EE command and Address to the EEPROM
7691 *
7692 * Description: Transfers the correct command and sends the address
7693 * to the eeprom.
7694 *
7695 *---------------------------------------------------------------------*/
7696
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007697static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007698{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007699 unsigned char ee_value;
7700 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007701
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007702 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007703
7704
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007705 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007706
7707
7708 ee_value = SEE_MS;
7709 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7710
7711 ee_value |= SEE_CS; /* Set CS to EEPROM */
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713
7714
7715 for(i = 0x04; i != 0; i>>=1) {
7716
7717 if (i & ee_cmd)
7718 ee_value |= SEE_DO;
7719 else
7720 ee_value &= ~SEE_DO;
7721
7722 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7723 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7724 ee_value |= SEE_CLK; /* Clock data! */
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 ee_value &= ~SEE_CLK;
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 }
7731
7732
7733 if (narrow_flg)
7734 i = 0x0080;
7735
7736 else
7737 i = 0x0200;
7738
7739
7740 while (i != 0) {
7741
7742 if (i & ee_addr)
7743 ee_value |= SEE_DO;
7744 else
7745 ee_value &= ~SEE_DO;
7746
7747 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 ee_value |= SEE_CLK; /* Clock data! */
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 ee_value &= ~SEE_CLK;
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755
7756 i >>= 1;
7757 }
7758}
7759
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007760static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007761{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007762 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007763 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007764 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007765 for (i=0; i < ID_STRING_LENGTH; i++)
7766 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007767 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007768 for(j=0; j < 8; j++)
7769 {
7770 if ((crc ^ ch) & 1)
7771 crc = (crc >> 1) ^ CRCMASK;
7772 else
7773 crc >>= 1;
7774 ch >>= 1;
7775 }
7776 }
7777 return(crc);
7778}
7779
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007780static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007781{
7782 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007783 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007784 lrc = 0;
7785 for(i = 0; i < ID_STRING_LENGTH; i++)
7786 lrc ^= buffer[i];
7787 return(lrc);
7788}
7789
7790
7791
7792/*
7793 The following inline definitions avoid type conflicts.
7794*/
7795
7796static inline unsigned char
7797FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7798{
7799 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7800}
7801
7802
7803static inline FlashPoint_CardHandle_T
7804FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7805{
7806 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7807}
7808
7809static inline void
7810FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7811{
7812 FlashPoint_ReleaseHostAdapter(CardHandle);
7813}
7814
7815
7816static inline void
7817FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7818{
7819 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7820}
7821
7822
7823static inline void
7824FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7825{
7826 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7827}
7828
7829
7830static inline boolean
7831FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7832{
7833 return FlashPoint_InterruptPending(CardHandle);
7834}
7835
7836
7837static inline int
7838FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7839{
7840 return FlashPoint_HandleInterrupt(CardHandle);
7841}
7842
7843
7844#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7845#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7846#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7847#define FlashPoint_StartCCB FlashPoint__StartCCB
7848#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7849#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7850#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7851
7852
Linus Torvalds1da177e2005-04-16 15:20:36 -07007853#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7854
7855
7856/*
7857 Define prototypes for the FlashPoint SCCB Manager Functions.
7858*/
7859
7860extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7861extern FlashPoint_CardHandle_T
7862 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7863extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7864extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7865extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7866extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7867extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007868
7869
7870#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */