blob: 6089af0031300828734eab257f14062525aefb52 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#define CRCMASK 0xA001
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define FAILURE 0xFFFFFFFFL
41
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#define s08bits char
48#define s16bits short
49#define s32bits long
50
51#define u08bits unsigned s08bits
52#define u16bits unsigned s16bits
53#define u32bits unsigned s32bits
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080057#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080058#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60
61
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
James Bottomley 47b5d692005-04-24 02:38:05 -050063typedef struct _SCCB *PSCCB;
64typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070065
66
67typedef struct SCCBMgr_info {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080068 unsigned long si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080069 unsigned char si_present;
70 unsigned char si_intvect;
71 unsigned char si_id;
72 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080073 unsigned short si_fw_revision;
74 unsigned short si_per_targ_init_sync;
75 unsigned short si_per_targ_fast_nego;
76 unsigned short si_per_targ_ultra_nego;
77 unsigned short si_per_targ_no_disc;
78 unsigned short si_per_targ_wide_nego;
79 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080080 unsigned char si_card_family;
81 unsigned char si_bustype;
82 unsigned char si_card_model[3];
83 unsigned char si_relative_cardnum;
84 unsigned char si_reserved[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080085 unsigned long si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080086 unsigned char si_XlatInfo[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080087 unsigned long si_reserved2[5];
88 unsigned long si_secondary_range;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089} SCCBMGR_INFO;
90
James Bottomley 47b5d692005-04-24 02:38:05 -050091typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93
James Bottomley 47b5d692005-04-24 02:38:05 -050094#define SCSI_PARITY_ENA 0x0001
95#define LOW_BYTE_TERM 0x0010
96#define HIGH_BYTE_TERM 0x0020
97#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
99#define SUPPORT_16TAR_32LUN 0x0002
100#define SOFT_RESET 0x0004
101#define EXTENDED_TRANSLATION 0x0008
102#define POST_ALL_UNDERRRUNS 0x0040
103#define FLAG_SCAM_ENABLED 0x0080
104#define FLAG_SCAM_LEVEL2 0x0100
105
106
107
108
109#define HARPOON_FAMILY 0x02
110
111
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
Alexey Dobriyan323579882006-01-15 02:12:54 +0100113/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114 * The UCB Manager treats the SCCB as it's 'native hardware structure'
115 */
116
117
118#pragma pack(1)
119typedef struct _SCCB {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800120 unsigned char OperationCode;
121 unsigned char ControlByte;
122 unsigned char CdbLength;
123 unsigned char RequestSenseLength;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800124 unsigned long DataLength;
125 unsigned long DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800126 unsigned char CcbRes[2];
127 unsigned char HostStatus;
128 unsigned char TargetStatus;
129 unsigned char TargID;
130 unsigned char Lun;
131 unsigned char Cdb[12];
132 unsigned char CcbRes1;
133 unsigned char Reserved1;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800134 unsigned long Reserved2;
135 unsigned long SensePointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136
137
138 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800139 unsigned long SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800140 unsigned char SccbStatus;
141 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800142 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
144
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800145 unsigned long Sccb_XferCnt; /* actual transfer count */
146 unsigned long Sccb_ATC;
147 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
148 unsigned long Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800149 unsigned short Sccb_MGRFlags;
150 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800151 unsigned char Sccb_scsimsg; /* identify msg for selection */
152 unsigned char Sccb_tag;
153 unsigned char Sccb_scsistat;
154 unsigned char Sccb_idmsg; /* image of last msg in */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 PSCCB Sccb_forwardlink;
156 PSCCB Sccb_backlink;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800157 unsigned long Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800158 unsigned char Save_Cdb[6];
159 unsigned char Save_CdbLen;
160 unsigned char Sccb_XferState;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800161 unsigned long Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 } SCCB;
163
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
165#pragma pack()
166
167
168
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169#define SCATTER_GATHER_COMMAND 0x02
170#define RESIDUAL_COMMAND 0x03
171#define RESIDUAL_SG_COMMAND 0x04
172#define RESET_COMMAND 0x81
173
174
175#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
176#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177#define SCCB_DATA_XFER_OUT 0x10 /* Write */
178#define SCCB_DATA_XFER_IN 0x08 /* Read */
179
180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
182
183
184#define BUS_FREE_ST 0
185#define SELECT_ST 1
186#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
187#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
188#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
189#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
190#define COMMAND_ST 6
191#define DATA_OUT_ST 7
192#define DATA_IN_ST 8
193#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
196
197#define F_HOST_XFER_DIR 0x01
198#define F_ALL_XFERRED 0x02
199#define F_SG_XFER 0x04
200#define F_AUTO_SENSE 0x08
201#define F_ODD_BALL_CNT 0x10
202#define F_NO_DATA_YET 0x80
203
204
205#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206#define F_DEV_SELECTED 0x04
207
208
209#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
210#define SCCB_DATA_UNDER_RUN 0x0C
211#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
212#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
214
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
216#define SCCB_BM_ERR 0x30 /* BusMaster error. */
217#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
218
219
220
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221
222
223#define SCCB_IN_PROCESS 0x00
224#define SCCB_SUCCESS 0x01
225#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230#define ORION_FW_REV 3110
231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
236#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
237
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
James Bottomley 47b5d692005-04-24 02:38:05 -0500239#define MAX_SCSI_TAR 16
240#define MAX_LUN 32
241#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244
245#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -0800248#define RD_HARPOON(ioport) inb((u32bits)ioport)
249#define RDW_HARPOON(ioport) inw((u32bits)ioport)
250#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
251#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
252#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
253#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254
255
256#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257#define SYNC_TRYING BIT(6)
258#define SYNC_SUPPORTED (BIT(7)+BIT(6))
259
260#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261#define WIDE_ENABLED BIT(4)
262#define WIDE_NEGOCIATED BIT(5)
263
264#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265#define TAG_Q_TRYING BIT(2)
266#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
268#define TAR_ALLOW_DISC BIT(0)
269
270
271#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272#define EE_SYNC_5MB BIT(0)
273#define EE_SYNC_10MB BIT(1)
274#define EE_SYNC_20MB (BIT(0)+BIT(1))
275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276#define EE_WIDE_SCSI BIT(7)
277
278
James Bottomley 47b5d692005-04-24 02:38:05 -0500279typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280
281
282typedef struct SCCBMgr_tar_info {
283
284 PSCCB TarSelQ_Head;
285 PSCCB TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800286 unsigned char TarLUN_CA; /*Contingent Allgiance */
287 unsigned char TarTagQ_Cnt;
288 unsigned char TarSelQ_Cnt;
289 unsigned char TarStatus;
290 unsigned char TarEEValue;
291 unsigned char TarSyncCtrl;
292 unsigned char TarReserved[2]; /* for alignment */
293 unsigned char LunDiscQ_Idx[MAX_LUN];
294 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295} SCCBMGR_TAR_INFO;
296
297typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800298 unsigned char niModel; /* Model No. of card */
299 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800300 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800301 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
302 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
303 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
304 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
305 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
306 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307}NVRAMINFO;
308
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
311#define MODEL_LT 1
312#define MODEL_DL 2
313#define MODEL_LW 3
314#define MODEL_DW 4
315
316
317typedef struct SCCBcard {
318 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800321 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800323 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800324 unsigned char discQCount;
325 unsigned char tagQ_Lst;
326 unsigned char cardIndex;
327 unsigned char scanIndex;
328 unsigned char globalFlags;
329 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 PNVRamInfo pNvRamInfo;
331 PSCCB discQ_Tbl[QUEUE_DEPTH];
332
333}SCCBCARD;
334
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336
337
338#define F_TAG_STARTED 0x01
339#define F_CONLUN_IO 0x02
340#define F_DO_RENEGO 0x04
341#define F_NO_FILTER 0x08
342#define F_GREEN_PC 0x10
343#define F_HOST_XFER_ACT 0x20
344#define F_NEW_SCCB_CMD 0x40
345#define F_UPDATE_EEPROM 0x80
346
347
348#define ID_STRING_LENGTH 32
349#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
350
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351
352#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
353
354#define ASSIGN_ID 0x00
355#define SET_P_FLAG 0x01
356#define CFG_CMPLT 0x03
357#define DOM_MSTR 0x0F
358#define SYNC_PTRN 0x1F
359
360#define ID_0_7 0x18
361#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362#define MISC_CODE 0x14
363#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
366
367#define INIT_SELTD 0x01
368#define LEVEL2_TAR 0x02
369
370
371enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
372 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
373 CLR_PRIORITY,NO_ID_AVAIL };
374
375typedef struct SCCBscam_info {
376
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800377 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 enum scam_id_st state;
379
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800380} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384#define SCSI_READ 0x08
385#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387#define SCSI_READ_EXTENDED 0x28
388#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
391
392
393#define SSGOOD 0x00
394#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395#define SSQ_FULL 0x28
396
397
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
399
400#define SMCMD_COMP 0x00
401#define SMEXT 0x01
402#define SMSAVE_DATA_PTR 0x02
403#define SMREST_DATA_PTR 0x03
404#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405#define SMABORT 0x06
406#define SMREJECT 0x07
407#define SMNO_OP 0x08
408#define SMPARITY 0x09
409#define SMDEV_RESET 0x0C
410#define SMABORT_TAG 0x0D
411#define SMINIT_RECOVERY 0x0F
412#define SMREL_RECOVERY 0x10
413
414#define SMIDENT 0x80
415#define DISC_PRIV 0x40
416
417
418#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419#define SMWDTR 0x03
420#define SM8BIT 0x00
421#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422#define SMIGNORWR 0x23 /* Ignore Wide Residue */
423
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
426
427
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429
430
431#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432#define TWELVE_BYTE_CMD 0x0C
433
434#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
436
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437
438#define EEPROM_WD_CNT 256
439
440#define EEPROM_CHECK_SUM 0
441#define FW_SIGNATURE 2
442#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445#define SYSTEM_CONFIG 16
446#define SCSI_CONFIG 17
447#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448#define SCAM_CONFIG 20
449#define ADAPTER_SCSI_ID 24
450
451
452#define IGNORE_B_SCAN 32
453#define SEND_START_ENA 34
454#define DEVICE_ENABLE 36
455
456#define SYNC_RATE_TBL 38
457#define SYNC_RATE_TBL01 38
458#define SYNC_RATE_TBL23 40
459#define SYNC_RATE_TBL45 42
460#define SYNC_RATE_TBL67 44
461#define SYNC_RATE_TBL89 46
462#define SYNC_RATE_TBLab 48
463#define SYNC_RATE_TBLcd 50
464#define SYNC_RATE_TBLef 52
465
466
467
468#define EE_SCAMBASE 256
469
470
471
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 #define SCAM_ENABLED BIT(2)
473 #define SCAM_LEVEL2 BIT(3)
474
475
476 #define RENEGO_ENA BITW(10)
477 #define CONNIO_ENA BITW(11)
478 #define GREEN_PC_ENA BITW(12)
479
480
481 #define AUTO_RATE_00 00
482 #define AUTO_RATE_05 01
483 #define AUTO_RATE_10 02
484 #define AUTO_RATE_20 03
485
486 #define WIDE_NEGO_BIT BIT(7)
487 #define DISC_ENABLE_BIT BIT(6)
488
489
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
491 #define hp_vendor_id_0 0x00 /* LSB */
492 #define ORION_VEND_0 0x4B
493
494 #define hp_vendor_id_1 0x01 /* MSB */
495 #define ORION_VEND_1 0x10
496
497 #define hp_device_id_0 0x02 /* LSB */
498 #define ORION_DEV_0 0x30
499
500 #define hp_device_id_1 0x03 /* MSB */
501 #define ORION_DEV_1 0x81
502
503 /* Sub Vendor ID and Sub Device ID only available in
504 Harpoon Version 2 and higher */
505
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
510 #define hp_semaphore 0x0C
511 #define SCCB_MGR_ACTIVE BIT(0)
512 #define TICKLE_ME BIT(1)
513 #define SCCB_MGR_PRESENT BIT(3)
514 #define BIOS_IN_USE BIT(4)
515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
518 #define hp_sys_ctrl 0x0F
519
520 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
521 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
522 #define HALT_MACH BIT(3) /*Halt State Machine */
523 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800529
530
531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
533 #define hp_host_blk_cnt 0x13
534
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
536
537 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
538
539
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540
541 #define hp_int_mask 0x17
542
543 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
544 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
546
547 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 #define hp_xfer_cnt_hi 0x1A
549 #define hp_xfer_cmd 0x1B
550
551 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
552 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553
554
555 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
557 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
560
561 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
562 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563
564 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 #define hp_ee_ctrl 0x22
568
569 #define EXT_ARB_ACK BIT(7)
570 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
571 #define SEE_MS BIT(5)
572 #define SEE_CS BIT(3)
573 #define SEE_CLK BIT(2)
574 #define SEE_DO BIT(1)
575 #define SEE_DI BIT(0)
576
577 #define EE_READ 0x06
578 #define EE_WRITE 0x05
579 #define EWEN 0x04
580 #define EWEN_ADDR 0x03C0
581 #define EWDS 0x04
582 #define EWDS_ADDR 0x0000
583
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
587
588
589
590 #define hp_bm_ctrl 0x26
591
592 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
593 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
595 #define FAST_SINGLE BIT(6) /*?? */
596
597 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
600 #define hp_sg_addr 0x28
601 #define hp_page_ctrl 0x29
602
603 #define SCATTER_EN BIT(0)
604 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
606 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 #define hp_pci_stat_cfg 0x2D
612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
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
622 #define hp_rev_num 0x33
623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
625 #define hp_stack_data 0x34
626 #define hp_stack_addr 0x35
627
628 #define hp_ext_status 0x36
629
630 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
631 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
632 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 #define CMD_ABORTED BIT(4) /*Command aborted */
634 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
635 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
636 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
637 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
638 BM_PARITY_ERR | PIO_OVERRUN)
639
640 #define hp_int_status 0x37
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
643 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
646
647 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649
650
651
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 #define hp_intena 0x40
653
654 #define RESET BITW(7)
655 #define PROG_HLT BITW(6)
656 #define PARITY BITW(5)
657 #define FIFO BITW(4)
658 #define SEL BITW(3)
659 #define SCAM_SEL BITW(2)
660 #define RSEL BITW(1)
661 #define TIMEOUT BITW(0)
662 #define BUS_FREE BITW(15)
663 #define XFER_CNT_0 BITW(14)
664 #define PHASE BITW(13)
665 #define IUNKWN BITW(12)
666 #define ICMD_COMP BITW(11)
667 #define ITICKLE BITW(10)
668 #define IDO_STRT BITW(9)
669 #define ITAR_DISC BITW(8)
670 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
671 #define CLR_ALL_INT 0xFFFF
672 #define CLR_ALL_INT_1 0xFF00
673
674 #define hp_intstat 0x42
675
676 #define hp_scsisig 0x44
677
678 #define SCSI_SEL BIT(7)
679 #define SCSI_BSY BIT(6)
680 #define SCSI_REQ BIT(5)
681 #define SCSI_ACK BIT(4)
682 #define SCSI_ATN BIT(3)
683 #define SCSI_CD BIT(2)
684 #define SCSI_MSG BIT(1)
685 #define SCSI_IOBIT BIT(0)
686
687 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
690 #define S_DATAI_PH ( BIT(0))
691 #define S_DATAO_PH 0x00
692 #define S_ILL_PH ( BIT(1) )
693
694 #define hp_scsictrl_0 0x45
695
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 #define SEL_TAR BIT(6)
697 #define ENA_ATN BIT(4)
698 #define ENA_RESEL BIT(2)
699 #define SCSI_RST BIT(1)
700 #define ENA_SCAM_SEL BIT(0)
701
702
703
704 #define hp_portctrl_0 0x46
705
706 #define SCSI_PORT BIT(7)
707 #define SCSI_INBIT BIT(6)
708 #define DMA_PORT BIT(5)
709 #define DMA_RD BIT(4)
710 #define HOST_PORT BIT(3)
711 #define HOST_WRT BIT(2)
712 #define SCSI_BUS_EN BIT(1)
713 #define START_TO BIT(0)
714
715 #define hp_scsireset 0x47
716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 #define SCSI_INI BIT(6)
718 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 #define DMA_RESET BIT(3)
720 #define HPSCSI_RESET BIT(2)
721 #define PROG_RESET BIT(1)
722 #define FIFO_CLR BIT(0)
723
724 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
727 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 #define hp_addstat 0x4E
729
730 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 #define SCSI_MODE8 BIT(3)
732 #define SCSI_PAR_ERR BIT(0)
733
734 #define hp_prgmcnt_0 0x4F
735
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736
737 #define hp_selfid_0 0x50
738 #define hp_selfid_1 0x51
739 #define hp_arb_id 0x52
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 #define hp_select_id 0x53
743
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744
745 #define hp_synctarg_base 0x54
746 #define hp_synctarg_12 0x54
747 #define hp_synctarg_13 0x55
748 #define hp_synctarg_14 0x56
749 #define hp_synctarg_15 0x57
750
751 #define hp_synctarg_8 0x58
752 #define hp_synctarg_9 0x59
753 #define hp_synctarg_10 0x5A
754 #define hp_synctarg_11 0x5B
755
756 #define hp_synctarg_4 0x5C
757 #define hp_synctarg_5 0x5D
758 #define hp_synctarg_6 0x5E
759 #define hp_synctarg_7 0x5F
760
761 #define hp_synctarg_0 0x60
762 #define hp_synctarg_1 0x61
763 #define hp_synctarg_2 0x62
764 #define hp_synctarg_3 0x63
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 #define DEFAULT_OFFSET 0x0F
768
769 #define hp_autostart_0 0x64
770 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 #define hp_autostart_3 0x67
772
773
774
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 #define AUTO_IMMED BIT(5)
776 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
779 #define hp_gp_reg_0 0x68
780 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 #define hp_gp_reg_3 0x6B
782
783 #define hp_seltimeout 0x6C
784
785
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 #define TO_4ms 0x67 /* 3.9959ms */
787
788 #define TO_5ms 0x03 /* 4.9152ms */
789 #define TO_10ms 0x07 /* 11.xxxms */
790 #define TO_250ms 0x99 /* 250.68ms */
791 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792
793 #define hp_clkctrl_0 0x6D
794
795 #define PWR_DWN BIT(6)
796 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
799 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
800
801 #define hp_fiforead 0x6E
802 #define hp_fifowrite 0x6F
803
804 #define hp_offsetctr 0x70
805 #define hp_xferstat 0x71
806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
809 #define hp_portctrl_1 0x72
810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 #define CHK_SCSI_P BIT(3)
812 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 #define hp_xfer_pad 0x73
815
816 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817
818 #define hp_scsidata_0 0x74
819 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 #define hp_aramBase 0x80
824 #define BIOS_DATA_OFFSET 0x60
825 #define BIOS_RELATIVE_CARD 0x64
826
827
828
829
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 #define AR3 (BITW(9) + BITW(8))
831 #define SDATA BITW(10)
832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
834 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
835
836 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
837
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839
840 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
841
842 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
843
844
845 #define ADATA_OUT 0x00
846 #define ADATA_IN BITW(8)
847 #define ACOMMAND BITW(10)
848 #define ASTATUS (BITW(10)+BITW(8))
849 #define AMSG_OUT (BITW(10)+BITW(9))
850 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851
852
853 #define BRH_OP BITW(13) /* Branch */
854
855
856 #define ALWAYS 0x00
857 #define EQUAL BITW(8)
858 #define NOT_EQ BITW(9)
859
860 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
861
862
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864
865
866 #define MPM_OP BITW(15) /* Match phase and move data */
867
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
869 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
870
871
872 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
873
874
875 #define D_AR0 0x00
876 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
878
879
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880
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
886
887 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
888
889 #define SSI_OP (BITW(15)+BITW(11))
890
891
892 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
893 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
895 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
896 #define SSI_ITICKLE (ITICKLE >> 8)
897
898 #define SSI_IUNKWN (IUNKWN >> 8)
899 #define SSI_INO_CC (IUNKWN >> 8)
900 #define SSI_IRFAIL (IUNKWN >> 8)
901
902
903 #define NP 0x10 /*Next Phase */
904 #define NTCMD 0x02 /*Non- Tagged Command start */
905 #define CMDPZ 0x04 /*Command phase */
906 #define DINT 0x12 /*Data Out/In interrupt */
907 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 #define DC 0x19 /*Disconnect Message */
909 #define ST 0x1D /*Status Phase */
910 #define UNKNWN 0x24 /*Unknown bus action */
911 #define CC 0x25 /*Command Completion failure */
912 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
914
915
916 #define ID_MSG_STRT hp_aramBase + 0x00
917 #define NON_TAG_ID_MSG hp_aramBase + 0x06
918 #define CMD_STRT hp_aramBase + 0x08
919 #define SYNC_MSGS hp_aramBase + 0x08
920
921
922
923
924
925 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 #define DISCONNECT_START 0x10/2
927 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 #define SELCHK_STRT SELCHK/2
930
931
932
933
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
939#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
940/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
941 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800942 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800944#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 -0700945 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800946 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800948 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 count >>= 16,\
950 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
952#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
953 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
954
955
956#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
957 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
958
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960
961#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
962 WR_HARPOON(port+hp_scsireset, 0x00))
963
964#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
965 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
966
967#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
968 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
969
970#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
971 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
972
973#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
974 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
975
976
977
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800979static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
980static void FPT_ssel(unsigned long port, unsigned char p_card);
981static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
982static void FPT_shandem(unsigned long port, unsigned char p_card,PSCCB pCurrSCCB);
983static void FPT_stsyncn(unsigned long port, unsigned char p_card);
984static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
985static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500986 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800987static void FPT_sresb(unsigned long port, unsigned char p_card);
988static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
989static void FPT_schkdd(unsigned long port, unsigned char p_card);
990static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
991static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
992static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800994static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800995static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
996 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800998static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -0500999static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001001static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
1002static void FPT_stwidn(unsigned long port, unsigned char p_card);
1003static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004
1005
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001006static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1007static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001008static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001009 unsigned char p_card);
1010static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1011static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1012static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1013static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001014static void FPT_utilUpdateResidual(PSCCB p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001015static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001016static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
1018
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001019static void FPT_Wait1Second(unsigned long p_port);
1020static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1021static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1022static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1023static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1024static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1025static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026
1027
1028
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001029static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1030static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1031static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1032static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1033static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1034static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1035static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001037static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1038static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1039static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
1041
1042
1043
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001044static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1045static void FPT_BusMasterInit(unsigned long p_port);
1046static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
1048
1049
1050
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001051static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1052static void FPT_busMstrSGDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1053static void FPT_busMstrDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1054static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB);
James Bottomley 47b5d692005-04-24 02:38:05 -05001055static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
1057
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001058static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001059 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
James Bottomley 47b5d692005-04-24 02:38:05 -05001061static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001062static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1063static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
1065
1066
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001067static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001069static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1070static void FPT_scbusf(unsigned long p_port);
1071static void FPT_scsel(unsigned long p_port);
1072static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1073static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1074static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1075static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1076static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1077static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001078static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001079static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1080static void FPT_scwtsel(unsigned long p_port);
1081static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1082static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001083static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
1085
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001086static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1087static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089
1090
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
James Bottomley 47b5d692005-04-24 02:38:05 -05001092static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1093static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1094static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1095static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
1097
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001098static unsigned char FPT_mbCards = 0;
1099static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001100 ' ', 'B', 'T', '-', '9', '3', '0', \
1101 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1102 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001104static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
1106
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001107static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
1110/*---------------------------------------------------------------------
1111 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001112 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 *
1114 * Description: Setup and/or Search for cards and return info to caller.
1115 *
1116 *---------------------------------------------------------------------*/
1117
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001118static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001120 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001122 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001123 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001124 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 PNVRamInfo pCurrNvRam;
1126
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
1129
1130 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1131 return((int)FAILURE);
1132
1133 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1134 return((int)FAILURE);
1135
1136 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1137 return((int)FAILURE);
1138
1139 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1140 return((int)FAILURE);
1141
1142
1143 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1144
1145/* For new Harpoon then check for sub_device ID LSB
1146 the bits(0-3) must be all ZERO for compatible with
1147 current version of SCCBMgr, else skip this Harpoon
1148 device. */
1149
1150 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1151 return((int)FAILURE);
1152 }
1153
1154 if (first_time)
1155 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001156 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001158 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 }
1160
James Bottomley 47b5d692005-04-24 02:38:05 -05001161 if(FPT_RdStack(ioport, 0) != 0x00) {
1162 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 {
1164 pCurrNvRam = NULL;
1165 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001166 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1167 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 }
1169 else
1170 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001171 if(FPT_mbCards < MAX_MB_CARDS) {
1172 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1173 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001175 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 }else
1177 return((int) FAILURE);
1178 }
1179 }else
1180 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181
1182 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1183 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1184
1185 if(pCurrNvRam)
1186 pCardInfo->si_id = pCurrNvRam->niAdapId;
1187 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001188 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1189 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
1191 pCardInfo->si_lun = 0x00;
1192 pCardInfo->si_fw_revision = ORION_FW_REV;
1193 temp2 = 0x0000;
1194 temp3 = 0x0000;
1195 temp4 = 0x0000;
1196 temp5 = 0x0000;
1197 temp6 = 0x0000;
1198
1199 for (id = 0; id < (16/2); id++) {
1200
1201 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001202 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1204 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1205 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001206 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
1208 for (i = 0; i < 2; temp >>=8,i++) {
1209
1210 temp2 >>= 1;
1211 temp3 >>= 1;
1212 temp4 >>= 1;
1213 temp5 >>= 1;
1214 temp6 >>= 1;
1215 switch (temp & 0x3)
1216 {
1217 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1218 temp6 |= 0x8000; /* Fall through */
1219 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1220 temp5 |= 0x8000; /* Fall through */
1221 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1222 temp2 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_00: /* Asynchronous */
1224 break;
1225 }
1226
1227 if (temp & DISC_ENABLE_BIT)
1228 temp3 |= 0x8000;
1229
1230 if (temp & WIDE_NEGO_BIT)
1231 temp4 |= 0x8000;
1232
1233 }
1234 }
1235
1236 pCardInfo->si_per_targ_init_sync = temp2;
1237 pCardInfo->si_per_targ_no_disc = temp3;
1238 pCardInfo->si_per_targ_wide_nego = temp4;
1239 pCardInfo->si_per_targ_fast_nego = temp5;
1240 pCardInfo->si_per_targ_ultra_nego = temp6;
1241
1242 if(pCurrNvRam)
1243 i = pCurrNvRam->niSysConf;
1244 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001245 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246
1247 if(pCurrNvRam)
1248 ScamFlg = pCurrNvRam->niScamConf;
1249 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001250 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
1252 pCardInfo->si_flags = 0x0000;
1253
1254 if (i & 0x01)
1255 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1256
1257 if (!(i & 0x02))
1258 pCardInfo->si_flags |= SOFT_RESET;
1259
1260 if (i & 0x10)
1261 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1262
1263 if (ScamFlg & SCAM_ENABLED)
1264 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1265
1266 if (ScamFlg & SCAM_LEVEL2)
1267 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1268
1269 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1270 if (i & 0x04) {
1271 j |= SCSI_TERM_ENA_L;
1272 }
1273 WR_HARPOON(ioport+hp_bm_ctrl, j );
1274
1275 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1276 if (i & 0x08) {
1277 j |= SCSI_TERM_ENA_H;
1278 }
1279 WR_HARPOON(ioport+hp_ee_ctrl, j );
1280
1281 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1282
1283 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1284
1285 pCardInfo->si_card_family = HARPOON_FAMILY;
1286 pCardInfo->si_bustype = BUSTYPE_PCI;
1287
1288 if(pCurrNvRam){
1289 pCardInfo->si_card_model[0] = '9';
1290 switch(pCurrNvRam->niModel & 0x0f){
1291 case MODEL_LT:
1292 pCardInfo->si_card_model[1] = '3';
1293 pCardInfo->si_card_model[2] = '0';
1294 break;
1295 case MODEL_LW:
1296 pCardInfo->si_card_model[1] = '5';
1297 pCardInfo->si_card_model[2] = '0';
1298 break;
1299 case MODEL_DL:
1300 pCardInfo->si_card_model[1] = '3';
1301 pCardInfo->si_card_model[2] = '2';
1302 break;
1303 case MODEL_DW:
1304 pCardInfo->si_card_model[1] = '5';
1305 pCardInfo->si_card_model[2] = '2';
1306 break;
1307 }
1308 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001309 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001310 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001311 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001313 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1314 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 }
1316
1317 if (pCardInfo->si_card_model[1] == '3')
1318 {
1319 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1320 pCardInfo->si_flags |= LOW_BYTE_TERM;
1321 }
1322 else if (pCardInfo->si_card_model[2] == '0')
1323 {
1324 temp = RD_HARPOON(ioport+hp_xfer_pad);
1325 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1326 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1327 pCardInfo->si_flags |= LOW_BYTE_TERM;
1328 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1329 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1330 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1331 WR_HARPOON(ioport+hp_xfer_pad, temp);
1332 }
1333 else
1334 {
1335 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1336 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1337 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1338 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1339 temp3 = 0;
1340 for (i = 0; i < 8; i++)
1341 {
1342 temp3 <<= 1;
1343 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1344 temp3 |= 1;
1345 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1346 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1347 }
1348 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1349 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1350 if (!(temp3 & BIT(7)))
1351 pCardInfo->si_flags |= LOW_BYTE_TERM;
1352 if (!(temp3 & BIT(6)))
1353 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1354 }
1355
1356
1357 ARAM_ACCESS(ioport);
1358
1359 for ( i = 0; i < 4; i++ ) {
1360
1361 pCardInfo->si_XlatInfo[i] =
1362 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1363 }
1364
1365 /* return with -1 if no sort, else return with
1366 logical card number sorted by BIOS (zero-based) */
1367
1368 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001369 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370
1371 SGRAM_ACCESS(ioport);
1372
James Bottomley 47b5d692005-04-24 02:38:05 -05001373 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1374 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1375 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1376 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1377 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1378 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1379 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1380 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
1382 pCardInfo->si_present = 0x01;
1383
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 return(0);
1385}
1386
1387
1388/*---------------------------------------------------------------------
1389 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001390 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 *
1392 * Description: Setup adapter for normal operation (hard reset).
1393 *
1394 *---------------------------------------------------------------------*/
1395
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001396static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397{
1398 PSCCBcard CurrCard = NULL;
1399 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001400 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001401 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001402 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
1406 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1407
1408 if (thisCard == MAX_CARDS) {
1409
1410 return(FAILURE);
1411 }
1412
James Bottomley 47b5d692005-04-24 02:38:05 -05001413 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
James Bottomley 47b5d692005-04-24 02:38:05 -05001415 CurrCard = &FPT_BL_Card[thisCard];
1416 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 break;
1418 }
1419
James Bottomley 47b5d692005-04-24 02:38:05 -05001420 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
James Bottomley 47b5d692005-04-24 02:38:05 -05001422 FPT_BL_Card[thisCard].ioPort = ioport;
1423 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
James Bottomley 47b5d692005-04-24 02:38:05 -05001425 if(FPT_mbCards)
1426 for(i = 0; i < FPT_mbCards; i++){
1427 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1428 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001430 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 CurrCard->cardIndex = thisCard;
1432 CurrCard->cardInfo = pCardInfo;
1433
1434 break;
1435 }
1436 }
1437
1438 pCurrNvRam = CurrCard->pNvRamInfo;
1439
1440 if(pCurrNvRam){
1441 ScamFlg = pCurrNvRam->niScamConf;
1442 }
1443 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001444 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 }
1446
1447
James Bottomley 47b5d692005-04-24 02:38:05 -05001448 FPT_BusMasterInit(ioport);
1449 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450
James Bottomley 47b5d692005-04-24 02:38:05 -05001451 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
1453
1454 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1455
1456 WR_HARPOON(ioport+hp_selfid_0, id);
1457 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1458 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1459 CurrCard->ourId = pCardInfo->si_id;
1460
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001461 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 if (i & SCSI_PARITY_ENA)
1463 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1464
1465 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1466 if (i & LOW_BYTE_TERM)
1467 j |= SCSI_TERM_ENA_L;
1468 WR_HARPOON(ioport+hp_bm_ctrl, j);
1469
1470 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1471 if (i & HIGH_BYTE_TERM)
1472 j |= SCSI_TERM_ENA_H;
1473 WR_HARPOON(ioport+hp_ee_ctrl, j );
1474
1475
1476 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1477
James Bottomley 47b5d692005-04-24 02:38:05 -05001478 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
James Bottomley 47b5d692005-04-24 02:38:05 -05001480 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 }
1482
1483
1484
1485 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1486 CurrCard->globalFlags |= F_NO_FILTER;
1487
1488 if(pCurrNvRam){
1489 if(pCurrNvRam->niSysConf & 0x10)
1490 CurrCard->globalFlags |= F_GREEN_PC;
1491 }
1492 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001493 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 CurrCard->globalFlags |= F_GREEN_PC;
1495 }
1496
1497 /* Set global flag to indicate Re-Negotiation to be done on all
1498 ckeck condition */
1499 if(pCurrNvRam){
1500 if(pCurrNvRam->niScsiConf & 0x04)
1501 CurrCard->globalFlags |= F_DO_RENEGO;
1502 }
1503 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001504 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 CurrCard->globalFlags |= F_DO_RENEGO;
1506 }
1507
1508 if(pCurrNvRam){
1509 if(pCurrNvRam->niScsiConf & 0x08)
1510 CurrCard->globalFlags |= F_CONLUN_IO;
1511 }
1512 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001513 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 CurrCard->globalFlags |= F_CONLUN_IO;
1515 }
1516
1517
1518 temp = pCardInfo->si_per_targ_no_disc;
1519
1520 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1521
1522 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001523 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 }
1525
1526 sync_bit_map = 0x0001;
1527
1528 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1529
1530 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001531 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1533 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1534 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001535 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
1537 for (i = 0; i < 2; temp >>=8,i++) {
1538
1539 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1540
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001541 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 }
1543
1544 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001545 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001547 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 }
1549
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1551 (id*2+i >= 8)){
1552*/
1553 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1554
James Bottomley 47b5d692005-04-24 02:38:05 -05001555 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
1557 }
1558
1559 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001560 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 }
1562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563
1564 sync_bit_map <<= 1;
1565
1566
1567
1568 }
1569 }
1570
1571 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001572 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001574 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575}
1576
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001577static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001579 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001580 unsigned long portBase;
1581 unsigned long regOffset;
1582 unsigned long scamData;
1583 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 PNVRamInfo pCurrNvRam;
1585
1586 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1587
1588 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001589 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1590 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1591 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
1595 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001596 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597
1598 portBase = pCurrNvRam->niBaseAddr;
1599
1600 for(i = 0; i < MAX_SCSI_TAR; i++){
1601 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001602 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 scamData = *pScamTbl;
1604 WR_HARP32(portBase, regOffset, scamData);
1605 }
1606
1607 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001608 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 }
1610}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
1612
James Bottomley 47b5d692005-04-24 02:38:05 -05001613static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001615 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001616 unsigned long portBase;
1617 unsigned long regOffset;
1618 unsigned long scamData;
1619 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
James Bottomley 47b5d692005-04-24 02:38:05 -05001621 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1622 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1623 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1624 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1625 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626
1627 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001628 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
1630 portBase = pNvRamInfo->niBaseAddr;
1631
1632 for(i = 0; i < MAX_SCSI_TAR; i++){
1633 regOffset = hp_aramBase + 64 + i*4;
1634 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001635 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 *pScamTbl = scamData;
1637 }
1638
1639}
1640
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001641static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642{
1643 WR_HARPOON(portBase + hp_stack_addr, index);
1644 return(RD_HARPOON(portBase + hp_stack_data));
1645}
1646
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001647static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648{
1649 WR_HARPOON(portBase + hp_stack_addr, index);
1650 WR_HARPOON(portBase + hp_stack_data, data);
1651}
1652
1653
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001654static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655{
James Bottomley 47b5d692005-04-24 02:38:05 -05001656 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1657 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1659 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001660 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1662 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001663 return(1);
1664 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
1666}
1667/*---------------------------------------------------------------------
1668 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001669 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 *
1671 * Description: Start a command pointed to by p_Sccb. When the
1672 * command is completed it will be returned via the
1673 * callback function.
1674 *
1675 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001676static void FlashPoint_StartCCB(unsigned long pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001678 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001679 unsigned char thisCard, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 PSCCB pSaveSccb;
1681 CALL_BK_FN callback;
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1684 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1687 {
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 p_Sccb->HostStatus = SCCB_COMPLETE;
1690 p_Sccb->SccbStatus = SCCB_ERROR;
1691 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1692 if (callback)
1693 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 return;
1696 }
1697
James Bottomley 47b5d692005-04-24 02:38:05 -05001698 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
1700
1701 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1702 {
1703 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1704 | SCCB_MGR_ACTIVE));
1705
1706 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1707 {
1708 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1709 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1710 }
1711 }
1712
1713 ((PSCCBcard)pCurrCard)->cmdCounter++;
1714
1715 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1716
1717 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1718 | TICKLE_ME));
1719 if(p_Sccb->OperationCode == RESET_COMMAND)
1720 {
1721 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1722 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001723 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1725 }
1726 else
1727 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001728 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 }
1730 }
1731
1732 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1733
1734 if(p_Sccb->OperationCode == RESET_COMMAND)
1735 {
1736 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1737 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001738 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1740 }
1741 else
1742 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001743 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 }
1745 }
1746
1747 else {
1748
1749 MDISABLE_INT(ioport);
1750
1751 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001752 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 lun = p_Sccb->Lun;
1754 else
1755 lun = 0;
1756 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001757 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1758 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1759 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
1761 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001762 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 }
1764
1765 else {
1766
1767 if(p_Sccb->OperationCode == RESET_COMMAND)
1768 {
1769 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1770 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001771 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1773 }
1774 else
1775 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001776 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 }
1778 }
1779
1780
1781 MENABLE_INT(ioport);
1782 }
1783
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784}
1785
1786
1787/*---------------------------------------------------------------------
1788 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001789 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 *
1791 * Description: Abort the command pointed to by p_Sccb. When the
1792 * command is completed it will be returned via the
1793 * callback function.
1794 *
1795 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001796static int FlashPoint_AbortCCB(unsigned long pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001798 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001800 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001802 unsigned char TID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 PSCCB pSaveSCCB;
1804 PSCCBMgr_tar_info currTar_Info;
1805
1806
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1808
1809 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1810
James Bottomley 47b5d692005-04-24 02:38:05 -05001811 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 {
1813
James Bottomley 47b5d692005-04-24 02:38:05 -05001814 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 {
1816
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 ((PSCCBcard)pCurrCard)->cmdCounter--;
1818
1819 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1820 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001821 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 p_Sccb->SccbStatus = SCCB_ABORT;
1824 callback = p_Sccb->SccbCallback;
1825 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
1827 return(0);
1828 }
1829
1830 else
1831 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1833 {
1834 p_Sccb->SccbStatus = SCCB_ABORT;
1835 return(0);
1836
1837 }
1838
1839 else
1840 {
1841
1842 TID = p_Sccb->TargID;
1843
1844
1845 if(p_Sccb->Sccb_tag)
1846 {
1847 MDISABLE_INT(ioport);
1848 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1849 {
1850 p_Sccb->SccbStatus = SCCB_ABORT;
1851 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1853
1854 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1855 {
1856 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001857 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 }
1859 else
1860 {
1861 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1862 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001863 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1865 }
1866 }
1867 MENABLE_INT(ioport);
1868 return(0);
1869 }
1870 else
1871 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001872 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
James Bottomley 47b5d692005-04-24 02:38:05 -05001874 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 == p_Sccb)
1876 {
1877 p_Sccb->SccbStatus = SCCB_ABORT;
1878 return(0);
1879 }
1880 }
1881 }
1882 }
1883 }
1884 return(-1);
1885}
1886
1887
1888/*---------------------------------------------------------------------
1889 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001890 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 *
1892 * Description: Do a quick check to determine if there is a pending
1893 * interrupt for this card and disable the IRQ Pin if so.
1894 *
1895 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001896static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001898 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
1900 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1901
1902 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1903 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001904 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 }
1906
1907 else
1908
James Bottomley 47b5d692005-04-24 02:38:05 -05001909 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910}
1911
1912
1913
1914/*---------------------------------------------------------------------
1915 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001916 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 *
1918 * Description: This is our entry point when an interrupt is generated
1919 * by the card and the upper level driver passes it on to
1920 * us.
1921 *
1922 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001923static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924{
1925 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001926 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001927 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001928 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001929 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930
1931 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1932 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1933
1934 MDISABLE_INT(ioport);
1935
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001937 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 else
1939 bm_status = 0;
1940
1941 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1942
James Bottomley 47b5d692005-04-24 02:38:05 -05001943 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 bm_status)
1945 {
1946
1947 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1948
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001950 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1952 bm_status = 0;
1953
1954 if (result) {
1955
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 return(result);
1958 }
1959 }
1960
1961
1962 else if (hp_int & ICMD_COMP) {
1963
1964 if ( !(hp_int & BUS_FREE) ) {
1965 /* Wait for the BusFree before starting a new command. We
1966 must also check for being reselected since the BusFree
1967 may not show up if another device reselects us in 1.5us or
1968 less. SRR Wednesday, 3/8/1995.
1969 */
1970 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1971 }
1972
1973 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1974
James Bottomley 47b5d692005-04-24 02:38:05 -05001975 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
1977/* WRW_HARPOON((ioport+hp_intstat),
1978 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1979 */
1980
1981 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1982
James Bottomley 47b5d692005-04-24 02:38:05 -05001983 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
1985 }
1986
1987
1988 else if (hp_int & ITAR_DISC)
1989 {
1990
1991 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1992
James Bottomley 47b5d692005-04-24 02:38:05 -05001993 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
1995 }
1996
1997 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1998
1999 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2000 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2001
2002 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2003 }
2004
2005 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002006 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007
2008 /* Wait for the BusFree before starting a new command. We
2009 must also check for being reselected since the BusFree
2010 may not show up if another device reselects us in 1.5us or
2011 less. SRR Wednesday, 3/8/1995.
2012 */
2013 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2014 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2015 RD_HARPOON((ioport+hp_scsisig)) ==
2016 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2017
2018 /*
2019 The additional loop exit condition above detects a timing problem
2020 with the revision D/E harpoon chips. The caller should reset the
2021 host adapter to recover when 0xFE is returned.
2022 */
2023 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2024 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 return 0xFE;
2027 }
2028
2029 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2030
2031
2032 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2033
2034 }
2035
2036
2037 else if (hp_int & RSEL) {
2038
2039 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2040
2041 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2042 {
2043 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2044 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002045 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 }
2047
2048 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2049 {
2050 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2051 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2052 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2053 }
2054
2055 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2056 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002057 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 }
2059
James Bottomley 47b5d692005-04-24 02:38:05 -05002060 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2061 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
2063 }
2064
2065
2066 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2067 {
2068
2069 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002070 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071
2072 }
2073
2074
2075 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2076 {
2077 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002078 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002080 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081 }
2082 else
2083 {
2084 /* Harpoon problem some SCSI target device respond to selection
2085 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2086 to latch the correct Target ID into reg. x53.
2087 The work around require to correct this reg. But when write to this
2088 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2089 need to read this reg first then restore it later. After update to 0x53 */
2090
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002091 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2092 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2093 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2094 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2095 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096 WR_HARPOON(ioport+hp_fifowrite, i);
2097 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2098 }
2099 }
2100
2101 else if (hp_int & XFER_CNT_0) {
2102
2103 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2104
James Bottomley 47b5d692005-04-24 02:38:05 -05002105 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106
2107 }
2108
2109
2110 else if (hp_int & BUS_FREE) {
2111
2112 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2113
2114 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2115
James Bottomley 47b5d692005-04-24 02:38:05 -05002116 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117 }
2118
James Bottomley 47b5d692005-04-24 02:38:05 -05002119 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 }
2121
2122
2123 else if (hp_int & ITICKLE) {
2124
2125 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2126 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2127 }
2128
2129
2130
2131 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2132
2133
2134 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2135
2136
2137 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2138
James Bottomley 47b5d692005-04-24 02:38:05 -05002139 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 }
2141
2142 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2143 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002144 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 }
2146
2147 break;
2148
2149 }
2150
2151 } /*end while */
2152
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154
2155 return(0);
2156}
2157
2158/*---------------------------------------------------------------------
2159 *
2160 * Function: Sccb_bad_isr
2161 *
2162 * Description: Some type of interrupt has occurred which is slightly
2163 * out of the ordinary. We will now decode it fully, in
2164 * this routine. This is broken up in an attempt to save
2165 * processing time.
2166 *
2167 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002168static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002169 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002171 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002172 PSCCBMgr_tar_info currTar_Info;
2173 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174
2175
2176 if (RD_HARPOON(p_port+hp_ext_status) &
2177 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2178 {
2179
2180 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2181 {
2182
James Bottomley 47b5d692005-04-24 02:38:05 -05002183 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184 }
2185
2186 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2187
2188 {
2189 WR_HARPOON(p_port+hp_pci_stat_cfg,
2190 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2191
2192 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2193
2194 }
2195
2196 if (pCurrCard->currentSCCB != NULL)
2197 {
2198
2199 if (!pCurrCard->currentSCCB->HostStatus)
2200 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2201
James Bottomley 47b5d692005-04-24 02:38:05 -05002202 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002204 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002206 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2208
2209 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2210 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002211 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 }
2213 }
2214 }
2215
2216
2217 else if (p_int & RESET)
2218 {
2219
2220 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2221 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2222 if (pCurrCard->currentSCCB != NULL) {
2223
2224 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2225
James Bottomley 47b5d692005-04-24 02:38:05 -05002226 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 }
2228
2229
2230 DISABLE_AUTO(p_port);
2231
James Bottomley 47b5d692005-04-24 02:38:05 -05002232 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233
2234 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2235
2236 pCurrNvRam = pCurrCard->pNvRamInfo;
2237 if(pCurrNvRam){
2238 ScamFlg = pCurrNvRam->niScamConf;
2239 }
2240 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002241 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 }
2243
James Bottomley 47b5d692005-04-24 02:38:05 -05002244 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245
James Bottomley 47b5d692005-04-24 02:38:05 -05002246 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247
2248 return(0xFF);
2249 }
2250
2251
2252 else if (p_int & FIFO) {
2253
2254 WRW_HARPOON((p_port+hp_intstat), FIFO);
2255
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002257 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 }
2259
2260 else if (p_int & TIMEOUT)
2261 {
2262
2263 DISABLE_AUTO(p_port);
2264
2265 WRW_HARPOON((p_port+hp_intstat),
2266 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2267
2268 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2269
2270
James Bottomley 47b5d692005-04-24 02:38:05 -05002271 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2273 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002274 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002276 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277
2278
2279 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2280 {
2281 currTar_Info->TarSyncCtrl = 0;
2282 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2283 }
2284
2285 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2286 {
2287 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2288 }
2289
James Bottomley 47b5d692005-04-24 02:38:05 -05002290 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291
James Bottomley 47b5d692005-04-24 02:38:05 -05002292 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
2294 }
2295
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296 else if (p_int & SCAM_SEL)
2297 {
2298
James Bottomley 47b5d692005-04-24 02:38:05 -05002299 FPT_scarb(p_port,LEVEL2_TAR);
2300 FPT_scsel(p_port);
2301 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302
James Bottomley 47b5d692005-04-24 02:38:05 -05002303 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304
2305 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2306 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
2308 return(0x00);
2309}
2310
2311
2312/*---------------------------------------------------------------------
2313 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314 * Function: SccbMgrTableInit
2315 *
2316 * Description: Initialize all Sccb manager data structures.
2317 *
2318 *---------------------------------------------------------------------*/
2319
James Bottomley 47b5d692005-04-24 02:38:05 -05002320static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002322 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323
2324 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2325 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002326 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327
James Bottomley 47b5d692005-04-24 02:38:05 -05002328 FPT_BL_Card[thisCard].ioPort = 0x00;
2329 FPT_BL_Card[thisCard].cardInfo = NULL;
2330 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2331 FPT_BL_Card[thisCard].ourId = 0x00;
2332 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 }
2334}
2335
2336
2337/*---------------------------------------------------------------------
2338 *
2339 * Function: SccbMgrTableInit
2340 *
2341 * Description: Initialize all Sccb manager data structures.
2342 *
2343 *---------------------------------------------------------------------*/
2344
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002345static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002347 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348
2349 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2350 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002351 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 }
2353
2354 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2355 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002356 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2357 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2358 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 }
2360
2361 pCurrCard->scanIndex = 0x00;
2362 pCurrCard->currentSCCB = NULL;
2363 pCurrCard->globalFlags = 0x00;
2364 pCurrCard->cmdCounter = 0x00;
2365 pCurrCard->tagQ_Lst = 0x01;
2366 pCurrCard->discQCount = 0;
2367
2368
2369}
2370
2371
2372/*---------------------------------------------------------------------
2373 *
2374 * Function: SccbMgrTableInit
2375 *
2376 * Description: Initialize all Sccb manager data structures.
2377 *
2378 *---------------------------------------------------------------------*/
2379
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002380static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002381{
2382
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002383 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384 PSCCBMgr_tar_info currTar_Info;
2385
James Bottomley 47b5d692005-04-24 02:38:05 -05002386 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002387
2388 currTar_Info->TarSelQ_Cnt = 0;
2389 currTar_Info->TarSyncCtrl = 0;
2390
2391 currTar_Info->TarSelQ_Head = NULL;
2392 currTar_Info->TarSelQ_Tail = NULL;
2393 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002394 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395
2396
2397 for (lun = 0; lun < MAX_LUN; lun++)
2398 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002399 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400 currTar_Info->LunDiscQ_Idx[lun] = 0;
2401 }
2402
2403 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2404 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002405 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002407 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002409 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2410 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 }
2412 }
2413 }
2414}
2415
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416
2417/*---------------------------------------------------------------------
2418 *
2419 * Function: sfetm
2420 *
2421 * Description: Read in a message byte from the SCSI bus, and check
2422 * for a parity error.
2423 *
2424 *---------------------------------------------------------------------*/
2425
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002426static unsigned char FPT_sfm(unsigned long port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002428 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002429 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430
2431 TimeOutLoop = 0;
2432 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2433 (TimeOutLoop++ < 20000) ){}
2434
2435
2436 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2437
2438 message = RD_HARPOON(port+hp_scsidata_0);
2439
2440 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2441
2442
2443 if (TimeOutLoop > 20000)
2444 message = 0x00; /* force message byte = 0 if Time Out on Req */
2445
2446 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2447 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2448 {
2449 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2450 WR_HARPOON(port+hp_xferstat, 0);
2451 WR_HARPOON(port+hp_fiforead, 0);
2452 WR_HARPOON(port+hp_fifowrite, 0);
2453 if (pCurrSCCB != NULL)
2454 {
2455 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2456 }
2457 message = 0x00;
2458 do
2459 {
2460 ACCEPT_MSG_ATN(port);
2461 TimeOutLoop = 0;
2462 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2463 (TimeOutLoop++ < 20000) ){}
2464 if (TimeOutLoop > 20000)
2465 {
2466 WRW_HARPOON((port+hp_intstat), PARITY);
2467 return(message);
2468 }
2469 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2470 {
2471 WRW_HARPOON((port+hp_intstat), PARITY);
2472 return(message);
2473 }
2474 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2475
2476 RD_HARPOON(port+hp_scsidata_0);
2477
2478 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2479
2480 }while(1);
2481
2482 }
2483 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2484 WR_HARPOON(port+hp_xferstat, 0);
2485 WR_HARPOON(port+hp_fiforead, 0);
2486 WR_HARPOON(port+hp_fifowrite, 0);
2487 return(message);
2488}
2489
2490
2491/*---------------------------------------------------------------------
2492 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002493 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494 *
2495 * Description: Load up automation and select target device.
2496 *
2497 *---------------------------------------------------------------------*/
2498
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002499static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500{
2501
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002502 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002504 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 PSCCBcard CurrCard;
2506 PSCCB currSCCB;
2507 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002508 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509
James Bottomley 47b5d692005-04-24 02:38:05 -05002510 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511 currSCCB = CurrCard->currentSCCB;
2512 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002513 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 lastTag = CurrCard->tagQ_Lst;
2515
2516 ARAM_ACCESS(port);
2517
2518
2519 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2520 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2521
2522 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2523 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2524
2525 lun = currSCCB->Lun;
2526 else
2527 lun = 0;
2528
2529
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 if (CurrCard->globalFlags & F_TAG_STARTED)
2531 {
2532 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2533 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002534 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2536 == TAG_Q_TRYING))
2537 {
2538
2539 if (currTar_Info->TarTagQ_Cnt !=0)
2540 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002541 currTar_Info->TarLUNBusy[lun] = 1;
2542 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 SGRAM_ACCESS(port);
2544 return;
2545 }
2546
2547 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002548 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 }
2550
2551 } /*End non-tagged */
2552
2553 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002554 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 }
2556
2557 } /*!Use cmd Q Tagged */
2558
2559 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002560 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002562 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563 SGRAM_ACCESS(port);
2564 return;
2565 }
2566
James Bottomley 47b5d692005-04-24 02:38:05 -05002567 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568
2569 } /*else use cmd Q tagged */
2570
2571 } /*if glob tagged started */
2572
2573 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002574 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575 }
2576
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
2578
2579 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2580 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2581 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2582 {
2583 if(CurrCard->discQCount >= QUEUE_DEPTH)
2584 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002585 currTar_Info->TarLUNBusy[lun] = 1;
2586 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 SGRAM_ACCESS(port);
2588 return;
2589 }
2590 for (i = 1; i < QUEUE_DEPTH; i++)
2591 {
2592 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2593 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2594 {
2595 CurrCard->tagQ_Lst = lastTag;
2596 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2597 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2598 CurrCard->discQCount++;
2599 break;
2600 }
2601 }
2602 if(i == QUEUE_DEPTH)
2603 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002604 currTar_Info->TarLUNBusy[lun] = 1;
2605 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 SGRAM_ACCESS(port);
2607 return;
2608 }
2609 }
2610
2611
2612
James Bottomley 47b5d692005-04-24 02:38:05 -05002613 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614
2615 WR_HARPOON(port+hp_select_id, target);
2616 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2617
2618 if (currSCCB->OperationCode == RESET_COMMAND) {
2619 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2620 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2621
2622 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2623
2624 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2625
2626 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002627 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2629
2630 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2631 {
2632 currTar_Info->TarSyncCtrl = 0;
2633 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2634 }
2635
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2637 {
2638 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2639 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640
James Bottomley 47b5d692005-04-24 02:38:05 -05002641 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2642 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643
2644 }
2645
2646 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2647 {
2648 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2649 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2650
2651 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2652
2653 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002654 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2655 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656 WRW_HARPOON((port+SYNC_MSGS+2),
2657 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2658 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2659
2660 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002661 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662
2663 }
2664
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002666 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2668 }
2669
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2671 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002672 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2674 }
2675
2676
2677 if (!auto_loaded)
2678 {
2679
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680 if (currSCCB->ControlByte & F_USE_CMD_Q)
2681 {
2682
2683 CurrCard->globalFlags |= F_TAG_STARTED;
2684
2685 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2686 == TAG_Q_REJECT)
2687 {
2688 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2689
2690 /* Fix up the start instruction with a jump to
2691 Non-Tag-CMD handling */
2692 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2693
2694 WRW_HARPOON((port+NON_TAG_ID_MSG),
2695 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2696
2697 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2698
2699 /* Setup our STATE so we know what happend when
2700 the wheels fall off. */
2701 currSCCB->Sccb_scsistat = SELECT_ST;
2702
James Bottomley 47b5d692005-04-24 02:38:05 -05002703 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 }
2705
2706 else
2707 {
2708 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2709
2710 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002711 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2712 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002713
2714 for (i = 1; i < QUEUE_DEPTH; i++)
2715 {
2716 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2717 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2718 {
2719 WRW_HARPOON((port+ID_MSG_STRT+6),
2720 (MPM_OP+AMSG_OUT+lastTag));
2721 CurrCard->tagQ_Lst = lastTag;
2722 currSCCB->Sccb_tag = lastTag;
2723 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2724 CurrCard->discQCount++;
2725 break;
2726 }
2727 }
2728
2729
2730 if ( i == QUEUE_DEPTH )
2731 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002732 currTar_Info->TarLUNBusy[lun] = 1;
2733 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734 SGRAM_ACCESS(port);
2735 return;
2736 }
2737
2738 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2739
2740 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2741 }
2742 }
2743
2744 else
2745 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746
2747 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2748
2749 WRW_HARPOON((port+NON_TAG_ID_MSG),
2750 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2751
2752 currSCCB->Sccb_scsistat = SELECT_ST;
2753
2754 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756
2757
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002758 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759
2760 cdb_reg = port + CMD_STRT;
2761
2762 for (i=0; i < currSCCB->CdbLength; i++)
2763 {
2764 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2765 cdb_reg +=2;
2766 theCCB++;
2767 }
2768
2769 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2770 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2771
2772 } /* auto_loaded */
2773
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002774 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776
2777 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2778
2779 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2780
2781
2782 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2783 {
2784 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2785 }
2786 else
2787 {
2788
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002789/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790 auto_loaded |= AUTO_IMMED; */
2791 auto_loaded = AUTO_IMMED;
2792
2793 DISABLE_AUTO(port);
2794
2795 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2796 }
2797
2798 SGRAM_ACCESS(port);
2799}
2800
2801
2802/*---------------------------------------------------------------------
2803 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002804 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805 *
2806 * Description: Hookup the correct CCB and handle the incoming messages.
2807 *
2808 *---------------------------------------------------------------------*/
2809
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002810static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811{
2812
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002813 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814
2815
2816 PSCCBMgr_tar_info currTar_Info;
2817 PSCCB currSCCB;
2818
2819
2820
2821
2822 if(pCurrCard->currentSCCB != NULL)
2823 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002824 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825 DISABLE_AUTO(port);
2826
2827
2828 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2829
2830
2831 currSCCB = pCurrCard->currentSCCB;
2832 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2833 {
2834 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2835 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2836 }
2837 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2838 {
2839 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2840 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2841 }
2842 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2843 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2844 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002845 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 if(currSCCB->Sccb_scsistat != ABORT_ST)
2847 {
2848 pCurrCard->discQCount--;
2849 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2850 = NULL;
2851 }
2852 }
2853 else
2854 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002855 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 if(currSCCB->Sccb_tag)
2857 {
2858 if(currSCCB->Sccb_scsistat != ABORT_ST)
2859 {
2860 pCurrCard->discQCount--;
2861 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2862 }
2863 }else
2864 {
2865 if(currSCCB->Sccb_scsistat != ABORT_ST)
2866 {
2867 pCurrCard->discQCount--;
2868 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2869 }
2870 }
2871 }
2872
James Bottomley 47b5d692005-04-24 02:38:05 -05002873 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874 }
2875
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002876 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877
2878
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002879 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002880 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881
2882
2883 msgRetryCount = 0;
2884 do
2885 {
2886
James Bottomley 47b5d692005-04-24 02:38:05 -05002887 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888 tag = 0;
2889
2890
2891 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2892 {
2893 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2894 {
2895
2896 WRW_HARPOON((port+hp_intstat), PHASE);
2897 return;
2898 }
2899 }
2900
2901 WRW_HARPOON((port+hp_intstat), PHASE);
2902 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2903 {
2904
James Bottomley 47b5d692005-04-24 02:38:05 -05002905 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906 if (message)
2907 {
2908
2909 if (message <= (0x80 | LUN_MASK))
2910 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002911 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2914 {
2915 if (currTar_Info->TarTagQ_Cnt != 0)
2916 {
2917
2918 if (!(currTar_Info->TarLUN_CA))
2919 {
2920 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2921
2922
James Bottomley 47b5d692005-04-24 02:38:05 -05002923 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 if (message)
2925 {
2926 ACCEPT_MSG(port);
2927 }
2928
2929 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002930 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931
James Bottomley 47b5d692005-04-24 02:38:05 -05002932 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002934 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935
2936 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002937 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 }
2939
2940 } /*C.A. exists! */
2941
2942 } /*End Q cnt != 0 */
2943
2944 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945
2946 } /*End valid ID message. */
2947
2948 else
2949 {
2950
2951 ACCEPT_MSG_ATN(port);
2952 }
2953
2954 } /* End good id message. */
2955
2956 else
2957 {
2958
James Bottomley 47b5d692005-04-24 02:38:05 -05002959 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 }
2961 }
2962 else
2963 {
2964 ACCEPT_MSG_ATN(port);
2965
2966 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2967 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2968 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2969
2970 return;
2971 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972
James Bottomley 47b5d692005-04-24 02:38:05 -05002973 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 {
2975 msgRetryCount++;
2976 if(msgRetryCount == 1)
2977 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002978 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 }
2980 else
2981 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002982 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983
James Bottomley 47b5d692005-04-24 02:38:05 -05002984 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985
James Bottomley 47b5d692005-04-24 02:38:05 -05002986 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 {
2988
James Bottomley 47b5d692005-04-24 02:38:05 -05002989 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990
2991 }
2992
James Bottomley 47b5d692005-04-24 02:38:05 -05002993 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 {
2995
James Bottomley 47b5d692005-04-24 02:38:05 -05002996 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 }
2998
2999
James Bottomley 47b5d692005-04-24 02:38:05 -05003000 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3001 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 return;
3003 }
3004 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003005 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006
3007
3008
3009 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3010 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3011 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003012 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3014 if(pCurrCard->currentSCCB != NULL)
3015 {
3016 ACCEPT_MSG(port);
3017 }
3018 else
3019 {
3020 ACCEPT_MSG_ATN(port);
3021 }
3022 }
3023 else
3024 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003025 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026
3027
3028 if (tag)
3029 {
3030 if (pCurrCard->discQ_Tbl[tag] != NULL)
3031 {
3032 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3033 currTar_Info->TarTagQ_Cnt--;
3034 ACCEPT_MSG(port);
3035 }
3036 else
3037 {
3038 ACCEPT_MSG_ATN(port);
3039 }
3040 }else
3041 {
3042 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3043 if(pCurrCard->currentSCCB != NULL)
3044 {
3045 ACCEPT_MSG(port);
3046 }
3047 else
3048 {
3049 ACCEPT_MSG_ATN(port);
3050 }
3051 }
3052 }
3053
3054 if(pCurrCard->currentSCCB != NULL)
3055 {
3056 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3057 {
3058 /* During Abort Tag command, the target could have got re-selected
3059 and completed the command. Check the select Q and remove the CCB
3060 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003061 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 }
3063 }
3064
3065
3066 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3067 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3068 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3069}
3070
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003071static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072{
3073 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3074 {
3075 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3076 {
3077
3078 WRW_HARPOON((port+hp_intstat), PHASE);
3079 return;
3080 }
3081 }
3082
3083 WRW_HARPOON((port+hp_intstat), PHASE);
3084 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3085 {
3086 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3087
3088
3089 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3090
3091 WR_HARPOON(port+hp_scsidata_0,message);
3092
3093 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3094
3095 ACCEPT_MSG(port);
3096
3097 WR_HARPOON(port+hp_portctrl_0, 0x00);
3098
3099 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3100 (message == SMABORT_TAG) )
3101 {
3102 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3103
3104 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3105 {
3106 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3107 }
3108 }
3109 }
3110}
3111
3112/*---------------------------------------------------------------------
3113 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003114 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 *
3116 * Description: Determine the proper responce to the message from the
3117 * target device.
3118 *
3119 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003120static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121{
3122 PSCCB currSCCB;
3123 PSCCBcard CurrCard;
3124 PSCCBMgr_tar_info currTar_Info;
3125
James Bottomley 47b5d692005-04-24 02:38:05 -05003126 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 currSCCB = CurrCard->currentSCCB;
3128
James Bottomley 47b5d692005-04-24 02:38:05 -05003129 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130
3131 if (message == SMREST_DATA_PTR)
3132 {
3133 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3134 {
3135 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3136
James Bottomley 47b5d692005-04-24 02:38:05 -05003137 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 }
3139
3140 ACCEPT_MSG(port);
3141 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3142 }
3143
3144 else if (message == SMCMD_COMP)
3145 {
3146
3147
3148 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3149 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003150 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3151 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152 }
3153
3154 ACCEPT_MSG(port);
3155
3156 }
3157
3158 else if ((message == SMNO_OP) || (message >= SMIDENT)
3159 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3160 {
3161
3162 ACCEPT_MSG(port);
3163 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3164 }
3165
3166 else if (message == SMREJECT)
3167 {
3168
3169 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3170 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3171 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3172 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3173
3174 {
3175 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3176
3177 ACCEPT_MSG(port);
3178
3179
3180 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3181 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3182
3183 if(currSCCB->Lun == 0x00)
3184 {
3185 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3186 {
3187
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003188 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189
3190 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3191 }
3192
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3194 {
3195
3196
3197 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3198 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3199
3200 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3201
3202 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203
3204 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3205 {
3206 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003207 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208
3209
3210 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3211 CurrCard->discQCount--;
3212 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3213 currSCCB->Sccb_tag = 0x00;
3214
3215 }
3216 }
3217
3218 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3219 {
3220
3221
3222 if(currSCCB->Lun == 0x00)
3223 {
3224 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3225 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3226 }
3227 }
3228
3229 else
3230 {
3231
3232 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3233 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003234 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003236 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237
3238
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003239 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240
3241 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3242
3243 }
3244 }
3245
3246 else
3247 {
3248 ACCEPT_MSG(port);
3249
3250 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3251 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3252
3253 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3254 {
3255 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3256 }
3257 }
3258 }
3259
3260 else if (message == SMEXT)
3261 {
3262
3263 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003264 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003265 }
3266
3267 else if (message == SMIGNORWR)
3268 {
3269
3270 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3271
James Bottomley 47b5d692005-04-24 02:38:05 -05003272 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273
3274 if(currSCCB->Sccb_scsimsg != SMPARITY)
3275 ACCEPT_MSG(port);
3276 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3277 }
3278
3279
3280 else
3281 {
3282
3283 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3284 currSCCB->Sccb_scsimsg = SMREJECT;
3285
3286 ACCEPT_MSG_ATN(port);
3287 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3288 }
3289}
3290
3291
3292/*---------------------------------------------------------------------
3293 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003294 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295 *
3296 * Description: Decide what to do with the extended message.
3297 *
3298 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003299static void FPT_shandem(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003301 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302
James Bottomley 47b5d692005-04-24 02:38:05 -05003303 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304 if (length)
3305 {
3306
3307 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003308 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309 if (message)
3310 {
3311
3312 if (message == SMSYNC)
3313 {
3314
3315 if (length == 0x03)
3316 {
3317
3318 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003319 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003320 }
3321 else
3322 {
3323
3324 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3325 ACCEPT_MSG_ATN(port);
3326 }
3327 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003328 else if (message == SMWDTR)
3329 {
3330
3331 if (length == 0x02)
3332 {
3333
3334 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003335 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 }
3337 else
3338 {
3339
3340 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3341 ACCEPT_MSG_ATN(port);
3342
3343 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3344 }
3345 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003346 else
3347 {
3348
3349 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3350 ACCEPT_MSG_ATN(port);
3351
3352 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3353 }
3354 }
3355 else
3356 {
3357 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3358 ACCEPT_MSG(port);
3359 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3360 }
3361 }else
3362 {
3363 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3365 }
3366}
3367
3368
3369/*---------------------------------------------------------------------
3370 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003371 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372 *
3373 * Description: Read in a message byte from the SCSI bus, and check
3374 * for a parity error.
3375 *
3376 *---------------------------------------------------------------------*/
3377
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003378static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379{
3380 PSCCB currSCCB;
3381 PSCCBMgr_tar_info currTar_Info;
3382
James Bottomley 47b5d692005-04-24 02:38:05 -05003383 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3384 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003385
3386 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3387
3388
3389 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003390 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003391
3392 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3393
3394 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3395 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3396 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3397
3398
3399 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3400
3401 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3402
3403 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3404
3405 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3406
3407 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3408
3409 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3410
3411 else
3412 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3413
3414
3415 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3416 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3417 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3418
3419
James Bottomley 47b5d692005-04-24 02:38:05 -05003420 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421 {
3422 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3423 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003424 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425 }
3426 else
3427 {
3428 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3429 }
3430
3431
James Bottomley 47b5d692005-04-24 02:38:05 -05003432 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003433 }
3434
3435 else {
3436
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003437 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003438 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003439 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440 }
3441}
3442
3443
3444
3445/*---------------------------------------------------------------------
3446 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003447 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448 *
3449 * Description: The has sent us a Sync Nego message so handle it as
3450 * necessary.
3451 *
3452 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003453static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003455 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003456 PSCCB currSCCB;
3457 PSCCBMgr_tar_info currTar_Info;
3458
James Bottomley 47b5d692005-04-24 02:38:05 -05003459 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3460 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003461
James Bottomley 47b5d692005-04-24 02:38:05 -05003462 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463
3464 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3465 {
3466 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3467 return;
3468 }
3469
3470 ACCEPT_MSG(port);
3471
3472
James Bottomley 47b5d692005-04-24 02:38:05 -05003473 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003474
3475 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3476 {
3477 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3478 return;
3479 }
3480
3481 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3482
3483 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3484
3485 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3486
3487 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3488
3489 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3490
3491 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3492 else
3493
3494 our_sync_msg = 0; /* Message = Async */
3495
3496 if (sync_msg < our_sync_msg) {
3497 sync_msg = our_sync_msg; /*if faster, then set to max. */
3498 }
3499
3500 if (offset == ASYNC)
3501 sync_msg = ASYNC;
3502
3503 if (offset > MAX_OFFSET)
3504 offset = MAX_OFFSET;
3505
3506 sync_reg = 0x00;
3507
3508 if (sync_msg > 12)
3509
3510 sync_reg = 0x20; /* Use 10MB/s */
3511
3512 if (sync_msg > 25)
3513
3514 sync_reg = 0x40; /* Use 6.6MB/s */
3515
3516 if (sync_msg > 38)
3517
3518 sync_reg = 0x60; /* Use 5MB/s */
3519
3520 if (sync_msg > 50)
3521
3522 sync_reg = 0x80; /* Use 4MB/s */
3523
3524 if (sync_msg > 62)
3525
3526 sync_reg = 0xA0; /* Use 3.33MB/s */
3527
3528 if (sync_msg > 75)
3529
3530 sync_reg = 0xC0; /* Use 2.85MB/s */
3531
3532 if (sync_msg > 87)
3533
3534 sync_reg = 0xE0; /* Use 2.5MB/s */
3535
3536 if (sync_msg > 100) {
3537
3538 sync_reg = 0x00; /* Use ASYNC */
3539 offset = 0x00;
3540 }
3541
3542
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543 if (currTar_Info->TarStatus & WIDE_ENABLED)
3544
3545 sync_reg |= offset;
3546
3547 else
3548
3549 sync_reg |= (offset | NARROW_SCSI);
3550
James Bottomley 47b5d692005-04-24 02:38:05 -05003551 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003552
3553
3554 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3555
3556
3557 ACCEPT_MSG(port);
3558
3559 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003560 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561
3562 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3563 }
3564
3565 else {
3566
3567
3568 ACCEPT_MSG_ATN(port);
3569
James Bottomley 47b5d692005-04-24 02:38:05 -05003570 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003571
3572 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003573 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003574 }
3575}
3576
3577
3578/*---------------------------------------------------------------------
3579 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003580 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003581 *
3582 * Description: Answer the targets sync message.
3583 *
3584 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003585static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586{
3587 ARAM_ACCESS(port);
3588 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3589 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3590 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3591 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3592 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3593 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3594 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3595 SGRAM_ACCESS(port);
3596
3597 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3598 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3599
3600 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3601
3602 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3603}
3604
3605
3606
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607/*---------------------------------------------------------------------
3608 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003609 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610 *
3611 * Description: Read in a message byte from the SCSI bus, and check
3612 * for a parity error.
3613 *
3614 *---------------------------------------------------------------------*/
3615
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003616static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617{
3618 PSCCB currSCCB;
3619 PSCCBMgr_tar_info currTar_Info;
3620
James Bottomley 47b5d692005-04-24 02:38:05 -05003621 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3622 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623
3624 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3625
3626
3627 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003628 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629
3630 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3631
3632 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3633 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3634 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3635 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3636 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3637 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3638
3639 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3640
3641
3642 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003643 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644
James Bottomley 47b5d692005-04-24 02:38:05 -05003645 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 }
3647
3648 else {
3649
3650 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003651 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652
3653 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003654 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655 }
3656}
3657
3658
3659
3660/*---------------------------------------------------------------------
3661 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003662 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663 *
3664 * Description: The has sent us a Wide Nego message so handle it as
3665 * necessary.
3666 *
3667 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003668static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003670 unsigned char width;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671 PSCCB currSCCB;
3672 PSCCBMgr_tar_info currTar_Info;
3673
James Bottomley 47b5d692005-04-24 02:38:05 -05003674 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3675 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676
James Bottomley 47b5d692005-04-24 02:38:05 -05003677 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678
3679 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3680 {
3681 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3682 return;
3683 }
3684
3685
3686 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3687 width = 0;
3688
3689 if (width) {
3690 currTar_Info->TarStatus |= WIDE_ENABLED;
3691 width = 0;
3692 }
3693 else {
3694 width = NARROW_SCSI;
3695 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3696 }
3697
3698
James Bottomley 47b5d692005-04-24 02:38:05 -05003699 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700
3701
3702 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3703 {
3704
3705
3706
3707 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3708
3709 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3710 {
3711 ACCEPT_MSG_ATN(port);
3712 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003713 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3715 SGRAM_ACCESS(port);
3716 }
3717 else
3718 {
3719 ACCEPT_MSG(port);
3720 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3721 }
3722 }
3723
3724 else {
3725
3726
3727 ACCEPT_MSG_ATN(port);
3728
3729 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3730 width = SM16BIT;
3731 else
3732 width = SM8BIT;
3733
James Bottomley 47b5d692005-04-24 02:38:05 -05003734 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735
3736 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3737 }
3738}
3739
3740
3741/*---------------------------------------------------------------------
3742 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003743 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003744 *
3745 * Description: Answer the targets Wide nego message.
3746 *
3747 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003748static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749{
3750 ARAM_ACCESS(port);
3751 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3752 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3753 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3754 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3755 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3756 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3757 SGRAM_ACCESS(port);
3758
3759 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3760 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3761
3762 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3763
3764 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3765}
3766
Linus Torvalds1da177e2005-04-16 15:20:36 -07003767
3768
3769/*---------------------------------------------------------------------
3770 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003771 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772 *
3773 * Description: Write the desired value to the Sync Register for the
3774 * ID specified.
3775 *
3776 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003777static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003778 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003779{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003780 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781
3782 index = p_id;
3783
3784 switch (index) {
3785
3786 case 0:
3787 index = 12; /* hp_synctarg_0 */
3788 break;
3789 case 1:
3790 index = 13; /* hp_synctarg_1 */
3791 break;
3792 case 2:
3793 index = 14; /* hp_synctarg_2 */
3794 break;
3795 case 3:
3796 index = 15; /* hp_synctarg_3 */
3797 break;
3798 case 4:
3799 index = 8; /* hp_synctarg_4 */
3800 break;
3801 case 5:
3802 index = 9; /* hp_synctarg_5 */
3803 break;
3804 case 6:
3805 index = 10; /* hp_synctarg_6 */
3806 break;
3807 case 7:
3808 index = 11; /* hp_synctarg_7 */
3809 break;
3810 case 8:
3811 index = 4; /* hp_synctarg_8 */
3812 break;
3813 case 9:
3814 index = 5; /* hp_synctarg_9 */
3815 break;
3816 case 10:
3817 index = 6; /* hp_synctarg_10 */
3818 break;
3819 case 11:
3820 index = 7; /* hp_synctarg_11 */
3821 break;
3822 case 12:
3823 index = 0; /* hp_synctarg_12 */
3824 break;
3825 case 13:
3826 index = 1; /* hp_synctarg_13 */
3827 break;
3828 case 14:
3829 index = 2; /* hp_synctarg_14 */
3830 break;
3831 case 15:
3832 index = 3; /* hp_synctarg_15 */
3833
3834 }
3835
3836 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3837
3838 currTar_Info->TarSyncCtrl = p_sync_value;
3839}
3840
3841
3842/*---------------------------------------------------------------------
3843 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003844 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845 *
3846 * Description: Reset the desired card's SCSI bus.
3847 *
3848 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003849static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003851 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003852
3853 PSCCBMgr_tar_info currTar_Info;
3854
3855 WR_HARPOON(port+hp_page_ctrl,
3856 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3857 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3858
3859 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3860
3861 scsiID = RD_HARPOON(port+hp_seltimeout);
3862 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3863 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3864
3865 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3866
3867 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3868
3869 WR_HARPOON(port+hp_seltimeout,scsiID);
3870
3871 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3872
James Bottomley 47b5d692005-04-24 02:38:05 -05003873 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874
3875 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3876
3877 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3878
3879 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3880 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003881 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882
3883 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3884 {
3885 currTar_Info->TarSyncCtrl = 0;
3886 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3887 }
3888
3889 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3890 {
3891 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3892 }
3893
James Bottomley 47b5d692005-04-24 02:38:05 -05003894 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895
James Bottomley 47b5d692005-04-24 02:38:05 -05003896 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897 }
3898
James Bottomley 47b5d692005-04-24 02:38:05 -05003899 FPT_BL_Card[p_card].scanIndex = 0x00;
3900 FPT_BL_Card[p_card].currentSCCB = NULL;
3901 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003903 FPT_BL_Card[p_card].cmdCounter = 0x00;
3904 FPT_BL_Card[p_card].discQCount = 0x00;
3905 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906
3907 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003908 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909
3910 WR_HARPOON(port+hp_page_ctrl,
3911 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3912
3913}
3914
3915/*---------------------------------------------------------------------
3916 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003917 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 *
3919 * Description: Setup for the Auto Sense command.
3920 *
3921 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003922static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003924 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 PSCCB currSCCB;
3926
3927 currSCCB = pCurrCard->currentSCCB;
3928
3929
3930 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3931
3932 for (i = 0; i < 6; i++) {
3933
3934 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3935 }
3936
3937 currSCCB->CdbLength = SIX_BYTE_CMD;
3938 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003939 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003940 currSCCB->Cdb[2] = 0x00;
3941 currSCCB->Cdb[3] = 0x00;
3942 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3943 currSCCB->Cdb[5] = 0x00;
3944
3945 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3946
3947 currSCCB->Sccb_ATC = 0x00;
3948
3949 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3950
3951 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3952
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003953 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954
3955 currSCCB->ControlByte = 0x00;
3956
3957 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3958}
3959
3960
3961
3962/*---------------------------------------------------------------------
3963 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003964 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965 *
3966 * Description: Transfer data into the bit bucket until the device
3967 * decides to switch phase.
3968 *
3969 *---------------------------------------------------------------------*/
3970
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003971static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003973 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974
3975
3976 DISABLE_AUTO(p_port);
3977
James Bottomley 47b5d692005-04-24 02:38:05 -05003978 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979
James Bottomley 47b5d692005-04-24 02:38:05 -05003980 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981
3982 }
3983
3984 /* If the Automation handled the end of the transfer then do not
3985 match the phase or we will get out of sync with the ISR. */
3986
3987 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3988 return;
3989
3990 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3991
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003992 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993
3994 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3995
3996
3997 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3998
3999 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004000 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07004001 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004002 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004003 {
4004 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4005
4006 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4007 {
4008 RD_HARPOON(p_port+hp_fifodata_0);
4009 }
4010 }
4011 else
4012 {
4013 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4014 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4015 {
4016 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4017 }
4018 }
4019 } /* End of While loop for padding data I/O phase */
4020
4021 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4022 {
4023 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4024 break;
4025 }
4026
4027 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4028 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4029 {
4030 RD_HARPOON(p_port+hp_fifodata_0);
4031 }
4032
4033 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4034 {
4035 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4036 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4037
4038 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4039 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4040 }
4041}
4042
4043
4044/*---------------------------------------------------------------------
4045 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004046 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047 *
4048 * Description: Make sure data has been flushed from both FIFOs and abort
4049 * the operations if necessary.
4050 *
4051 *---------------------------------------------------------------------*/
4052
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004053static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004054{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004055 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004056 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004057
4058 PSCCB currSCCB;
4059
James Bottomley 47b5d692005-04-24 02:38:05 -05004060 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004061
4062
4063 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4064 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4065 return;
4066 }
4067
4068
4069
4070 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4071 {
4072
4073 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4074
4075 currSCCB->Sccb_XferCnt = 1;
4076
4077 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004078 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004079 WR_HARPOON(port+hp_xferstat, 0x00);
4080 }
4081
4082 else
4083 {
4084
4085 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4086
4087 currSCCB->Sccb_XferCnt = 0;
4088 }
4089
4090 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4091 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4092
4093 currSCCB->HostStatus = SCCB_PARITY_ERR;
4094 WRW_HARPOON((port+hp_intstat), PARITY);
4095 }
4096
4097
James Bottomley 47b5d692005-04-24 02:38:05 -05004098 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099
4100
4101 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4102
4103 TimeOutLoop = 0;
4104
4105 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4106 {
4107 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4108 return;
4109 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004110 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004111 break;
4112 }
4113 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4114 return;
4115 }
4116 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4117 break;
4118 }
4119
4120 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4121 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004122 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4124 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4125 {
4126
4127 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4128
4129 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4130 {
4131 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004132 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133 }
4134
4135 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004136 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 }
4138 }
4139 else
4140 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004141 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 if (!(RDW_HARPOON((port+hp_intstat)) &
4143 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4144 {
4145 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004146 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004147 }
4148 }
4149
4150 }
4151
4152 else {
4153 WR_HARPOON(port+hp_portctrl_0, 0x00);
4154 }
4155}
4156
4157
4158/*---------------------------------------------------------------------
4159 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004160 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161 *
4162 * Description: Setup SCCB manager fields in this SCCB.
4163 *
4164 *---------------------------------------------------------------------*/
4165
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004166static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167{
4168 PSCCBMgr_tar_info currTar_Info;
4169
4170 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4171 {
4172 return;
4173 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004174 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004175
4176 p_sccb->Sccb_XferState = 0x00;
4177 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4178
4179 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4180 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4181
4182 p_sccb->Sccb_SGoffset = 0;
4183 p_sccb->Sccb_XferState = F_SG_XFER;
4184 p_sccb->Sccb_XferCnt = 0x00;
4185 }
4186
4187 if (p_sccb->DataLength == 0x00)
4188
4189 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4190
4191 if (p_sccb->ControlByte & F_USE_CMD_Q)
4192 {
4193 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4194 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4195
4196 else
4197 currTar_Info->TarStatus |= TAG_Q_TRYING;
4198 }
4199
4200/* For !single SCSI device in system & device allow Disconnect
4201 or command is tag_q type then send Cmd with Disconnect Enable
4202 else send Cmd with Disconnect Disable */
4203
4204/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004205 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4207 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4208*/
4209 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4210 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004211 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004212 }
4213
4214 else {
4215
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004216 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004217 }
4218
4219 p_sccb->HostStatus = 0x00;
4220 p_sccb->TargetStatus = 0x00;
4221 p_sccb->Sccb_tag = 0x00;
4222 p_sccb->Sccb_MGRFlags = 0x00;
4223 p_sccb->Sccb_sgseg = 0x00;
4224 p_sccb->Sccb_ATC = 0x00;
4225 p_sccb->Sccb_savedATC = 0x00;
4226/*
4227 p_sccb->SccbVirtDataPtr = 0x00;
4228 p_sccb->Sccb_forwardlink = NULL;
4229 p_sccb->Sccb_backlink = NULL;
4230 */
4231 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4232 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4233 p_sccb->Sccb_scsimsg = SMNO_OP;
4234
4235}
4236
4237
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238/*---------------------------------------------------------------------
4239 *
4240 * Function: Phase Decode
4241 *
4242 * Description: Determine the phase and call the appropriate function.
4243 *
4244 *---------------------------------------------------------------------*/
4245
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004246static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247{
4248 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004249 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004250
4251
4252 DISABLE_AUTO(p_port);
4253
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004254 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
James Bottomley 47b5d692005-04-24 02:38:05 -05004256 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004257
4258 (*phase)(p_port, p_card); /* Call the correct phase func */
4259}
4260
4261
4262
4263/*---------------------------------------------------------------------
4264 *
4265 * Function: Data Out Phase
4266 *
4267 * Description: Start up both the BusMaster and Xbow.
4268 *
4269 *---------------------------------------------------------------------*/
4270
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004271static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004272{
4273
4274 PSCCB currSCCB;
4275
James Bottomley 47b5d692005-04-24 02:38:05 -05004276 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277 if (currSCCB == NULL)
4278 {
4279 return; /* Exit if No SCCB record */
4280 }
4281
4282 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4283 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4284
4285 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4286
4287 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4288
4289 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4290
James Bottomley 47b5d692005-04-24 02:38:05 -05004291 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292
4293 if (currSCCB->Sccb_XferCnt == 0) {
4294
4295
4296 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4297 (currSCCB->HostStatus == SCCB_COMPLETE))
4298 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4299
James Bottomley 47b5d692005-04-24 02:38:05 -05004300 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004301 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004302 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004303 }
4304}
4305
4306
4307/*---------------------------------------------------------------------
4308 *
4309 * Function: Data In Phase
4310 *
4311 * Description: Startup the BusMaster and the XBOW.
4312 *
4313 *---------------------------------------------------------------------*/
4314
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004315static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004316{
4317
4318 PSCCB currSCCB;
4319
James Bottomley 47b5d692005-04-24 02:38:05 -05004320 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321
4322 if (currSCCB == NULL)
4323 {
4324 return; /* Exit if No SCCB record */
4325 }
4326
4327
4328 currSCCB->Sccb_scsistat = DATA_IN_ST;
4329 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4330 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4331
4332 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4333
4334 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4335
4336 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4337
James Bottomley 47b5d692005-04-24 02:38:05 -05004338 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339
4340 if (currSCCB->Sccb_XferCnt == 0) {
4341
4342
4343 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4344 (currSCCB->HostStatus == SCCB_COMPLETE))
4345 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4346
James Bottomley 47b5d692005-04-24 02:38:05 -05004347 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004348 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004349 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004350
4351 }
4352}
4353
4354/*---------------------------------------------------------------------
4355 *
4356 * Function: Command Phase
4357 *
4358 * Description: Load the CDB into the automation and start it up.
4359 *
4360 *---------------------------------------------------------------------*/
4361
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004362static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363{
4364 PSCCB currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004365 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004366 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367
James Bottomley 47b5d692005-04-24 02:38:05 -05004368 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369
4370 if (currSCCB->OperationCode == RESET_COMMAND) {
4371
4372 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4373 currSCCB->CdbLength = SIX_BYTE_CMD;
4374 }
4375
4376 WR_HARPOON(p_port+hp_scsisig, 0x00);
4377
4378 ARAM_ACCESS(p_port);
4379
4380
4381 cdb_reg = p_port + CMD_STRT;
4382
4383 for (i=0; i < currSCCB->CdbLength; i++) {
4384
4385 if (currSCCB->OperationCode == RESET_COMMAND)
4386
4387 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4388
4389 else
4390 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4391 cdb_reg +=2;
4392 }
4393
4394 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4395 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4396
4397 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4398
4399 currSCCB->Sccb_scsistat = COMMAND_ST;
4400
4401 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4402 SGRAM_ACCESS(p_port);
4403}
4404
4405
4406/*---------------------------------------------------------------------
4407 *
4408 * Function: Status phase
4409 *
4410 * Description: Bring in the status and command complete message bytes
4411 *
4412 *---------------------------------------------------------------------*/
4413
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004414static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415{
4416 /* Start-up the automation to finish off this command and let the
4417 isr handle the interrupt for command complete when it comes in.
4418 We could wait here for the interrupt to be generated?
4419 */
4420
4421 WR_HARPOON(port+hp_scsisig, 0x00);
4422
4423 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4424}
4425
4426
4427/*---------------------------------------------------------------------
4428 *
4429 * Function: Phase Message Out
4430 *
4431 * Description: Send out our message (if we have one) and handle whatever
4432 * else is involed.
4433 *
4434 *---------------------------------------------------------------------*/
4435
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004436static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004438 unsigned char message,scsiID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004439 PSCCB currSCCB;
4440 PSCCBMgr_tar_info currTar_Info;
4441
James Bottomley 47b5d692005-04-24 02:38:05 -05004442 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443
4444 if (currSCCB != NULL) {
4445
4446 message = currSCCB->Sccb_scsimsg;
4447 scsiID = currSCCB->TargID;
4448
4449 if (message == SMDEV_RESET)
4450 {
4451
4452
James Bottomley 47b5d692005-04-24 02:38:05 -05004453 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004455 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004456
James Bottomley 47b5d692005-04-24 02:38:05 -05004457 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 {
4459
James Bottomley 47b5d692005-04-24 02:38:05 -05004460 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461
4462 }
4463
James Bottomley 47b5d692005-04-24 02:38:05 -05004464 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465 {
4466
James Bottomley 47b5d692005-04-24 02:38:05 -05004467 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468 }
4469
4470
James Bottomley 47b5d692005-04-24 02:38:05 -05004471 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4472 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 }
4474 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4475 {
4476 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004477 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004479 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4480 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004481 }
4482
4483 }
4484
4485 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4486 {
4487
4488
4489 if(message == SMNO_OP)
4490 {
4491 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4492
James Bottomley 47b5d692005-04-24 02:38:05 -05004493 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 return;
4495 }
4496 }
4497 else
4498 {
4499
4500
4501 if (message == SMABORT)
4502
James Bottomley 47b5d692005-04-24 02:38:05 -05004503 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004504 }
4505
4506 }
4507 else
4508 {
4509 message = SMABORT;
4510 }
4511
4512 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4513
4514
4515 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4516
4517 WR_HARPOON(port+hp_scsidata_0,message);
4518
4519 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4520
4521 ACCEPT_MSG(port);
4522
4523 WR_HARPOON(port+hp_portctrl_0, 0x00);
4524
4525 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4526 (message == SMABORT_TAG) )
4527 {
4528
4529 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4530
4531 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4532 {
4533 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4534
4535 if (currSCCB != NULL)
4536 {
4537
James Bottomley 47b5d692005-04-24 02:38:05 -05004538 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4539 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4540 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004541 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004542 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004543
James Bottomley 47b5d692005-04-24 02:38:05 -05004544 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004545 }
4546
4547 else
4548 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004549 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 }
4551 }
4552
4553 else
4554 {
4555
James Bottomley 47b5d692005-04-24 02:38:05 -05004556 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004557 }
4558 }
4559
4560 else
4561 {
4562
4563 if(message == SMPARITY)
4564 {
4565 currSCCB->Sccb_scsimsg = SMNO_OP;
4566 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4567 }
4568 else
4569 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004570 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004571 }
4572 }
4573}
4574
4575
4576/*---------------------------------------------------------------------
4577 *
4578 * Function: Message In phase
4579 *
4580 * Description: Bring in the message and determine what to do with it.
4581 *
4582 *---------------------------------------------------------------------*/
4583
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004584static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004586 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587 PSCCB currSCCB;
4588
James Bottomley 47b5d692005-04-24 02:38:05 -05004589 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004590
James Bottomley 47b5d692005-04-24 02:38:05 -05004591 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592 {
4593
James Bottomley 47b5d692005-04-24 02:38:05 -05004594 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595 }
4596
4597 message = RD_HARPOON(port+hp_scsidata_0);
4598 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4599 {
4600
4601 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4602
4603 }
4604
4605 else
4606 {
4607
James Bottomley 47b5d692005-04-24 02:38:05 -05004608 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004609 if (message)
4610 {
4611
4612
James Bottomley 47b5d692005-04-24 02:38:05 -05004613 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004614
4615 }
4616 else
4617 {
4618 if(currSCCB->Sccb_scsimsg != SMPARITY)
4619 ACCEPT_MSG(port);
4620 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4621 }
4622 }
4623
4624}
4625
4626
4627/*---------------------------------------------------------------------
4628 *
4629 * Function: Illegal phase
4630 *
4631 * Description: Target switched to some illegal phase, so all we can do
4632 * is report an error back to the host (if that is possible)
4633 * and send an ABORT message to the misbehaving target.
4634 *
4635 *---------------------------------------------------------------------*/
4636
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004637static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004638{
4639 PSCCB currSCCB;
4640
James Bottomley 47b5d692005-04-24 02:38:05 -05004641 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004642
4643 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4644 if (currSCCB != NULL) {
4645
4646 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4647 currSCCB->Sccb_scsistat = ABORT_ST;
4648 currSCCB->Sccb_scsimsg = SMABORT;
4649 }
4650
4651 ACCEPT_MSG_ATN(port);
4652}
4653
4654
4655
4656/*---------------------------------------------------------------------
4657 *
4658 * Function: Phase Check FIFO
4659 *
4660 * Description: Make sure data has been flushed from both FIFOs and abort
4661 * the operations if necessary.
4662 *
4663 *---------------------------------------------------------------------*/
4664
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004665static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004666{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004667 unsigned long xfercnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004668 PSCCB currSCCB;
4669
James Bottomley 47b5d692005-04-24 02:38:05 -05004670 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004671
4672 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4673 {
4674
4675 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4676 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4677
4678
4679 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4680 {
4681 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4682
4683 currSCCB->Sccb_XferCnt = 0;
4684
4685 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4686 (currSCCB->HostStatus == SCCB_COMPLETE))
4687 {
4688 currSCCB->HostStatus = SCCB_PARITY_ERR;
4689 WRW_HARPOON((port+hp_intstat), PARITY);
4690 }
4691
James Bottomley 47b5d692005-04-24 02:38:05 -05004692 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004693
James Bottomley 47b5d692005-04-24 02:38:05 -05004694 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695
4696 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4697 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4698
4699 }
4700 } /*End Data In specific code. */
4701
4702
4703
Linus Torvalds1da177e2005-04-16 15:20:36 -07004704 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004705
4706
4707 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4708
4709
4710 WR_HARPOON(port+hp_portctrl_0, 0x00);
4711
4712 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4713
4714 currSCCB->Sccb_XferCnt = xfercnt;
4715
4716 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4717 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4718
4719 currSCCB->HostStatus = SCCB_PARITY_ERR;
4720 WRW_HARPOON((port+hp_intstat), PARITY);
4721 }
4722
4723
James Bottomley 47b5d692005-04-24 02:38:05 -05004724 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004725
4726
4727 WR_HARPOON(port+hp_fifowrite, 0x00);
4728 WR_HARPOON(port+hp_fiforead, 0x00);
4729 WR_HARPOON(port+hp_xferstat, 0x00);
4730
4731 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4732}
4733
4734
4735/*---------------------------------------------------------------------
4736 *
4737 * Function: Phase Bus Free
4738 *
4739 * Description: We just went bus free so figure out if it was
4740 * because of command complete or from a disconnect.
4741 *
4742 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004743static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004744{
4745 PSCCB currSCCB;
4746
James Bottomley 47b5d692005-04-24 02:38:05 -05004747 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004748
4749 if (currSCCB != NULL)
4750 {
4751
4752 DISABLE_AUTO(port);
4753
4754
4755 if (currSCCB->OperationCode == RESET_COMMAND)
4756 {
4757
James Bottomley 47b5d692005-04-24 02:38:05 -05004758 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4759 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4760 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004761 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004763
James Bottomley 47b5d692005-04-24 02:38:05 -05004764 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004765
James Bottomley 47b5d692005-04-24 02:38:05 -05004766 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004767
4768 }
4769
4770 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4771 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004772 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004773 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004775 }
4776
4777 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4778 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004779 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4780 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004781 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4782
James Bottomley 47b5d692005-04-24 02:38:05 -05004783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004784 }
4785
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4787 {
4788 /* Make sure this is not a phony BUS_FREE. If we were
4789 reselected or if BUSY is NOT on then this is a
4790 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4791
4792 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4793 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4794 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004795 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4796 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004797 }
4798
4799 else
4800 {
4801 return;
4802 }
4803 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004804
4805 else
4806 {
4807
4808 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4809
4810 if (!currSCCB->HostStatus)
4811 {
4812 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4813 }
4814
James Bottomley 47b5d692005-04-24 02:38:05 -05004815 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4816 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4817 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004818 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004819 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004820
James Bottomley 47b5d692005-04-24 02:38:05 -05004821 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004822 return;
4823 }
4824
4825
James Bottomley 47b5d692005-04-24 02:38:05 -05004826 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827
4828 } /*end if !=null */
4829}
4830
4831
4832
4833
Linus Torvalds1da177e2005-04-16 15:20:36 -07004834/*---------------------------------------------------------------------
4835 *
4836 * Function: Auto Load Default Map
4837 *
4838 * Description: Load the Automation RAM with the defualt map values.
4839 *
4840 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004841static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004842{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004843 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004844
4845 ARAM_ACCESS(p_port);
4846 map_addr = p_port + hp_aramBase;
4847
4848 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4849 map_addr +=2;
4850 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4851 map_addr +=2;
4852 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4873 map_addr +=2;
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4875 map_addr +=2;
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4877 map_addr +=2;
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4883 map_addr +=2; /*This means AYNC DATA IN */
4884 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4885 map_addr +=2;
4886 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4887 map_addr +=2;
4888 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4909 map_addr +=2;
4910 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4911 map_addr +=2;
4912 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4913 map_addr +=2;
4914 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4917 map_addr +=2;
4918 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4919 map_addr +=2;
4920
4921 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4922 map_addr +=2;
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4924 map_addr +=2;
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4926 map_addr +=2;
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4928 map_addr +=2; /* DIDN'T GET ONE */
4929 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4930 map_addr +=2;
4931 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4932 map_addr +=2;
4933 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4934
4935
4936
4937 SGRAM_ACCESS(p_port);
4938}
4939
4940/*---------------------------------------------------------------------
4941 *
4942 * Function: Auto Command Complete
4943 *
4944 * Description: Post command back to host and find another command
4945 * to execute.
4946 *
4947 *---------------------------------------------------------------------*/
4948
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004949static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004950{
4951 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004952 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004953
James Bottomley 47b5d692005-04-24 02:38:05 -05004954 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004955
4956 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4957
James Bottomley 47b5d692005-04-24 02:38:05 -05004958 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004959
4960 if (status_byte != SSGOOD) {
4961
4962 if (status_byte == SSQ_FULL) {
4963
4964
James Bottomley 47b5d692005-04-24 02:38:05 -05004965 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4966 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004967 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004968 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4969 if(FPT_BL_Card[p_card].discQCount != 0)
4970 FPT_BL_Card[p_card].discQCount--;
4971 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 -07004972 }
4973 else
4974 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004975 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004976 if(currSCCB->Sccb_tag)
4977 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004978 if(FPT_BL_Card[p_card].discQCount != 0)
4979 FPT_BL_Card[p_card].discQCount--;
4980 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004981 }else
4982 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004983 if(FPT_BL_Card[p_card].discQCount != 0)
4984 FPT_BL_Card[p_card].discQCount--;
4985 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004986 }
4987 }
4988
4989 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4990
James Bottomley 47b5d692005-04-24 02:38:05 -05004991 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004992
4993 return;
4994 }
4995
4996 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4997 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004998 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004999 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005000
James Bottomley 47b5d692005-04-24 02:38:05 -05005001 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5002 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005003
James Bottomley 47b5d692005-04-24 02:38:05 -05005004 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5005 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005006 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005007 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5008 if(FPT_BL_Card[p_card].discQCount != 0)
5009 FPT_BL_Card[p_card].discQCount--;
5010 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 -07005011 }
5012 else
5013 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005014 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005015 if(currSCCB->Sccb_tag)
5016 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005017 if(FPT_BL_Card[p_card].discQCount != 0)
5018 FPT_BL_Card[p_card].discQCount--;
5019 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005020 }else
5021 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005022 if(FPT_BL_Card[p_card].discQCount != 0)
5023 FPT_BL_Card[p_card].discQCount--;
5024 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005025 }
5026 }
5027 return;
5028
5029 }
5030
5031 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5032 {
5033
James Bottomley 47b5d692005-04-24 02:38:05 -05005034 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5035 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005036 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5037
James Bottomley 47b5d692005-04-24 02:38:05 -05005038 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5039 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005040
James Bottomley 47b5d692005-04-24 02:38:05 -05005041 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5042 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005043 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005044 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5045 if(FPT_BL_Card[p_card].discQCount != 0)
5046 FPT_BL_Card[p_card].discQCount--;
5047 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 -07005048 }
5049 else
5050 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005051 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005052 if(currSCCB->Sccb_tag)
5053 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005054 if(FPT_BL_Card[p_card].discQCount != 0)
5055 FPT_BL_Card[p_card].discQCount--;
5056 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005057 }else
5058 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005059 if(FPT_BL_Card[p_card].discQCount != 0)
5060 FPT_BL_Card[p_card].discQCount--;
5061 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005062 }
5063 }
5064 return;
5065
5066 }
5067
5068 if (status_byte == SSCHECK)
5069 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005070 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005071 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005072 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005073 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005074 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005075 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005076 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005077 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005078 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005079 }
5080 }
5081 }
5082
5083 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5084
5085 currSCCB->SccbStatus = SCCB_ERROR;
5086 currSCCB->TargetStatus = status_byte;
5087
5088 if (status_byte == SSCHECK) {
5089
James Bottomley 47b5d692005-04-24 02:38:05 -05005090 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5091 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005092
5093
Linus Torvalds1da177e2005-04-16 15:20:36 -07005094 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5095
5096 if (currSCCB->RequestSenseLength == 0)
5097 currSCCB->RequestSenseLength = 14;
5098
James Bottomley 47b5d692005-04-24 02:38:05 -05005099 FPT_ssenss(&FPT_BL_Card[p_card]);
5100 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005101
James Bottomley 47b5d692005-04-24 02:38:05 -05005102 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5103 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005104 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005105 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5106 if(FPT_BL_Card[p_card].discQCount != 0)
5107 FPT_BL_Card[p_card].discQCount--;
5108 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 -07005109 }
5110 else
5111 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005112 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005113 if(currSCCB->Sccb_tag)
5114 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005115 if(FPT_BL_Card[p_card].discQCount != 0)
5116 FPT_BL_Card[p_card].discQCount--;
5117 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005118 }else
5119 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005120 if(FPT_BL_Card[p_card].discQCount != 0)
5121 FPT_BL_Card[p_card].discQCount--;
5122 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005123 }
5124 }
5125 return;
5126 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005127 }
5128 }
5129 }
5130
5131
James Bottomley 47b5d692005-04-24 02:38:05 -05005132 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5133 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5134 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005135 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005136 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005137
5138
James Bottomley 47b5d692005-04-24 02:38:05 -05005139 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005140}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005141
5142#define SHORT_WAIT 0x0000000F
5143#define LONG_WAIT 0x0000FFFFL
5144
Linus Torvalds1da177e2005-04-16 15:20:36 -07005145
5146/*---------------------------------------------------------------------
5147 *
5148 * Function: Data Transfer Processor
5149 *
5150 * Description: This routine performs two tasks.
5151 * (1) Start data transfer by calling HOST_DATA_XFER_START
5152 * function. Once data transfer is started, (2) Depends
5153 * on the type of data transfer mode Scatter/Gather mode
5154 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5155 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5156 * data transfer done. In Scatter/Gather mode, this routine
5157 * checks bus master command complete and dual rank busy
5158 * bit to keep chaining SC transfer command. Similarly,
5159 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5160 * (F_HOST_XFER_ACT bit) for data transfer done.
5161 *
5162 *---------------------------------------------------------------------*/
5163
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005164static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005165{
5166 PSCCB currSCCB;
5167
5168 currSCCB = pCurrCard->currentSCCB;
5169
5170 if (currSCCB->Sccb_XferState & F_SG_XFER)
5171 {
5172 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5173
5174 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005175 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005176 currSCCB->Sccb_SGoffset = 0x00;
5177 }
5178 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5179
James Bottomley 47b5d692005-04-24 02:38:05 -05005180 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005181 }
5182
5183 else
5184 {
5185 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5186 {
5187 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5188
James Bottomley 47b5d692005-04-24 02:38:05 -05005189 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005190 }
5191 }
5192}
5193
5194
5195/*---------------------------------------------------------------------
5196 *
5197 * Function: BusMaster Scatter Gather Data Transfer Start
5198 *
5199 * Description:
5200 *
5201 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005202static void FPT_busMstrSGDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005203{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005204 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005205 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005206 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005207 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005208
5209
5210 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5211
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005212 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005213 }
5214
5215 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005216 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005217 }
5218
5219 sg_count = 0;
5220 tmpSGCnt = 0;
5221 sg_index = pcurrSCCB->Sccb_sgseg;
5222 reg_offset = hp_aramBase;
5223
5224
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005225 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226
5227
5228 WR_HARPOON(p_port+hp_page_ctrl, i);
5229
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005230 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005231 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005232
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005233 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234 (sg_index * 2));
5235
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005236 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005237 (sg_index * 2));
5238
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005239 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005240 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005241
5242
5243 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5244
5245 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5246 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5247
5248 tmpSGCnt = count & 0x00FFFFFFL;
5249 }
5250
5251 WR_HARP32(p_port,reg_offset,addr);
5252 reg_offset +=4;
5253
5254 WR_HARP32(p_port,reg_offset,count);
5255 reg_offset +=4;
5256
5257 count &= 0xFF000000L;
5258 sg_index++;
5259 sg_count++;
5260
5261 } /*End While */
5262
5263 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5264
5265 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5266
5267 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5268
5269 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5270
5271
5272 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5273 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5274 }
5275
5276 else {
5277
5278
5279 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5280 (tmpSGCnt & 0x000000001))
5281 {
5282
5283 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5284 tmpSGCnt--;
5285 }
5286
5287
5288 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5289
5290 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5291 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5292 }
5293
5294
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005295 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005296
5297}
5298
5299
5300/*---------------------------------------------------------------------
5301 *
5302 * Function: BusMaster Data Transfer Start
5303 *
5304 * Description:
5305 *
5306 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005307static void FPT_busMstrDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005308{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005309 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005310
5311 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5312
5313 count = pcurrSCCB->Sccb_XferCnt;
5314
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005315 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005316 }
5317
5318 else {
5319 addr = pcurrSCCB->SensePointer;
5320 count = pcurrSCCB->RequestSenseLength;
5321
5322 }
5323
Linus Torvalds1da177e2005-04-16 15:20:36 -07005324 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325
5326
5327 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5328
5329 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5330 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5331
5332 WR_HARPOON(p_port+hp_xfer_cmd,
5333 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5334 }
5335
5336 else {
5337
5338 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5339 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5340
5341 WR_HARPOON(p_port+hp_xfer_cmd,
5342 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5343
5344 }
5345}
5346
5347
5348/*---------------------------------------------------------------------
5349 *
5350 * Function: BusMaster Timeout Handler
5351 *
5352 * Description: This function is called after a bus master command busy time
5353 * out is detected. This routines issue halt state machine
5354 * with a software time out for command busy. If command busy
5355 * is still asserted at the end of the time out, it issues
5356 * hard abort with another software time out. It hard abort
5357 * command busy is also time out, it'll just give up.
5358 *
5359 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005360static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005361{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005362 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363
5364 timeout = LONG_WAIT;
5365
5366 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5367
5368 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5369
5370
5371
5372 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5373 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5374
5375 timeout = LONG_WAIT;
5376 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5377 }
5378
5379 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5380
5381 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005382 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005383 }
5384
5385 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005386 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005387 }
5388}
5389
5390
5391/*---------------------------------------------------------------------
5392 *
5393 * Function: Host Data Transfer Abort
5394 *
5395 * Description: Abort any in progress transfer.
5396 *
5397 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005398static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005399{
5400
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005401 unsigned long timeout;
5402 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005403 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404
James Bottomley 47b5d692005-04-24 02:38:05 -05005405 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005406
5407 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5408
5409
5410 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5411
5412 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5413 timeout = LONG_WAIT;
5414
5415 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5416
5417 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5418
5419 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5420
James Bottomley 47b5d692005-04-24 02:38:05 -05005421 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005422
5423 if (pCurrSCCB->HostStatus == 0x00)
5424
5425 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5426
5427 }
5428
5429 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5430
5431 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5432
5433 if (pCurrSCCB->HostStatus == 0x00)
5434
5435 {
5436 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005437 }
5438 }
5439 }
5440 }
5441
5442 else if (pCurrSCCB->Sccb_XferCnt) {
5443
5444 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5445
5446
5447 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5448 ~SCATTER_EN));
5449
5450 WR_HARPOON(port+hp_sg_addr,0x00);
5451
5452 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5453
Alexey Dobriyance793212006-03-08 00:14:26 -08005454 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005455
Alexey Dobriyance793212006-03-08 00:14:26 -08005456 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005457 }
5458
5459 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5460
5461 while (remain_cnt < 0x01000000L) {
5462
5463 sg_ptr--;
5464
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005465 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005466 DataPointer) + (sg_ptr * 2)))) {
5467
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005468 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005469 DataPointer) + (sg_ptr * 2)));
5470 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005471
5472 else {
5473
5474 break;
5475 }
5476 }
5477
5478
5479
5480 if (remain_cnt < 0x01000000L) {
5481
5482
5483 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5484
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005485 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005486
5487
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005488 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005489 && (remain_cnt == 0))
5490
5491 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5492 }
5493
5494 else {
5495
5496
5497 if (pCurrSCCB->HostStatus == 0x00) {
5498
5499 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5500 }
5501 }
5502 }
5503
5504
5505 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5506
5507
5508 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5509
James Bottomley 47b5d692005-04-24 02:38:05 -05005510 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005511 }
5512
5513 else {
5514
5515 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5516
5517 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5518
5519 if (pCurrSCCB->HostStatus == 0x00) {
5520
5521 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005522 }
5523 }
5524 }
5525
5526 }
5527 }
5528
5529 else {
5530
5531
5532 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5533
5534 timeout = SHORT_WAIT;
5535
5536 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5537 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5538 timeout--) {}
5539 }
5540
5541 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5542
5543 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5544 FLUSH_XFER_CNTR));
5545
5546 timeout = LONG_WAIT;
5547
5548 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5549 timeout--) {}
5550
5551 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5552 ~FLUSH_XFER_CNTR));
5553
5554
5555 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5556
5557 if (pCurrSCCB->HostStatus == 0x00) {
5558
5559 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5560 }
5561
James Bottomley 47b5d692005-04-24 02:38:05 -05005562 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005563 }
5564 }
5565
5566 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5567
5568 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5569
5570 if (pCurrSCCB->HostStatus == 0x00) {
5571
5572 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005573 }
5574 }
5575 }
5576 }
5577
5578 }
5579
5580 else {
5581
5582
5583 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5584
5585 timeout = LONG_WAIT;
5586
5587 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5588
5589 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5590
5591 if (pCurrSCCB->HostStatus == 0x00) {
5592
5593 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5594 }
5595
James Bottomley 47b5d692005-04-24 02:38:05 -05005596 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005597 }
5598 }
5599
5600
5601 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5602
5603 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5604
5605 if (pCurrSCCB->HostStatus == 0x00) {
5606
5607 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005608 }
5609 }
5610
5611 }
5612
5613 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5614
5615 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5616 ~SCATTER_EN));
5617
5618 WR_HARPOON(port+hp_sg_addr,0x00);
5619
5620 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5621
5622 pCurrSCCB->Sccb_SGoffset = 0x00;
5623
5624
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005625 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005626 pCurrSCCB->DataLength) {
5627
5628 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5629
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005630 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005631
5632 }
5633 }
5634
5635 else {
5636
5637 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5638
5639 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5640 }
5641 }
5642
5643 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5644}
5645
5646
5647
5648/*---------------------------------------------------------------------
5649 *
5650 * Function: Host Data Transfer Restart
5651 *
5652 * Description: Reset the available count due to a restore data
5653 * pointers message.
5654 *
5655 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005656static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005657{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005658 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005659 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005660 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661
5662 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5663
5664 currSCCB->Sccb_XferCnt = 0;
5665
5666 sg_index = 0xffff; /*Index by long words into sg list. */
5667 data_count = 0; /*Running count of SG xfer counts. */
5668
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005669 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005670
5671 while (data_count < currSCCB->Sccb_ATC) {
5672
5673 sg_index++;
5674 data_count += *(sg_ptr+(sg_index * 2));
5675 }
5676
5677 if (data_count == currSCCB->Sccb_ATC) {
5678
5679 currSCCB->Sccb_SGoffset = 0;
5680 sg_index++;
5681 }
5682
5683 else {
5684 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5685 }
5686
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005687 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005688 }
5689
5690 else {
5691 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5692 }
5693}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005694
5695
5696
Linus Torvalds1da177e2005-04-16 15:20:36 -07005697/*---------------------------------------------------------------------
5698 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005699 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005700 *
5701 * Description: Setup all data structures necessary for SCAM selection.
5702 *
5703 *---------------------------------------------------------------------*/
5704
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005705static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005706{
5707
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005708 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005709 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005710
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005711 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005712 PSCCBcard currCard;
5713 PNVRamInfo pCurrNvRam;
5714
James Bottomley 47b5d692005-04-24 02:38:05 -05005715 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716 p_port = currCard->ioPort;
5717 pCurrNvRam = currCard->pNvRamInfo;
5718
5719
5720 if(pCurrNvRam){
5721 ScamFlg = pCurrNvRam->niScamConf;
5722 i = pCurrNvRam->niSysConf;
5723 }
5724 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005725 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5726 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727 }
5728 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5729 return;
5730
James Bottomley 47b5d692005-04-24 02:38:05 -05005731 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732
5733 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5734 too slow to return to SCAM selection */
5735
5736 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005737 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005738 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005739 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005740
James Bottomley 47b5d692005-04-24 02:38:05 -05005741 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742
5743 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5744 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005745 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005746
James Bottomley 47b5d692005-04-24 02:38:05 -05005747 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005748
5749 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005750 FPT_scxferc(p_port,SYNC_PTRN);
5751 FPT_scxferc(p_port,DOM_MSTR);
5752 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753 } while ( loser == 0xFF );
5754
James Bottomley 47b5d692005-04-24 02:38:05 -05005755 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756
5757 if ((p_power_up) && (!loser))
5758 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005759 FPT_sresb(p_port,p_card);
5760 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761
James Bottomley 47b5d692005-04-24 02:38:05 -05005762 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763
James Bottomley 47b5d692005-04-24 02:38:05 -05005764 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005765
5766 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005767 FPT_scxferc(p_port, SYNC_PTRN);
5768 FPT_scxferc(p_port, DOM_MSTR);
5769 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005770 id_string[0]);
5771 } while ( loser == 0xFF );
5772
James Bottomley 47b5d692005-04-24 02:38:05 -05005773 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005774 }
5775 }
5776
5777 else
5778 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005779 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005780 }
5781
5782
5783 if (!loser)
5784 {
5785
James Bottomley 47b5d692005-04-24 02:38:05 -05005786 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005787
5788
5789 if (ScamFlg & SCAM_ENABLED)
5790 {
5791
5792 for (i=0; i < MAX_SCSI_TAR; i++)
5793 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005794 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5795 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005796 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005797 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005798 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005799 FPT_scamInfo[i].state = LEGACY;
5800 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5801 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005802 {
5803
James Bottomley 47b5d692005-04-24 02:38:05 -05005804 FPT_scamInfo[i].id_string[0] = 0xFF;
5805 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005806 if(pCurrNvRam == NULL)
5807 currCard->globalFlags |= F_UPDATE_EEPROM;
5808 }
5809 }
5810 }
5811 }
5812
James Bottomley 47b5d692005-04-24 02:38:05 -05005813 FPT_sresb(p_port,p_card);
5814 FPT_Wait1Second(p_port);
5815 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5816 FPT_scsel(p_port);
5817 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005818 }
5819
Linus Torvalds1da177e2005-04-16 15:20:36 -07005820 }
5821
5822 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5823 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005824 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5825 assigned_id = 0;
5826 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005827
5828 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005829 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005830
James Bottomley 47b5d692005-04-24 02:38:05 -05005831 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005832 if (i == ASSIGN_ID)
5833 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005834 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005836 i = FPT_scxferc(p_port,0x00);
5837 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005838 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005839 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840
James Bottomley 47b5d692005-04-24 02:38:05 -05005841 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005842 {
5843 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005844 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005845 FPT_inisci(p_card, p_port, p_our_id);
5846 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5847 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005848 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005849 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005850 }
5851 }
5852 }
5853 }
5854
5855 else if (i == SET_P_FLAG)
5856 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005857 if (!(FPT_scsendi(p_port,
5858 &FPT_scamInfo[p_our_id].id_string[0])))
5859 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860 }
5861 }while (!assigned_id);
5862
James Bottomley 47b5d692005-04-24 02:38:05 -05005863 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005864 }
5865
Linus Torvalds1da177e2005-04-16 15:20:36 -07005866 if (ScamFlg & SCAM_ENABLED)
5867 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005868 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005869 if (currCard->globalFlags & F_UPDATE_EEPROM)
5870 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005871 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005872 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5873 }
5874 }
5875
5876
Linus Torvalds1da177e2005-04-16 15:20:36 -07005877/*
5878 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5879 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005880 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5881 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005882 k++;
5883 }
5884
5885 if (k==2)
5886 currCard->globalFlags |= F_SINGLE_DEVICE;
5887 else
5888 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5889*/
5890}
5891
5892
5893/*---------------------------------------------------------------------
5894 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005895 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005896 *
5897 * Description: Gain control of the bus and wait SCAM select time (250ms)
5898 *
5899 *---------------------------------------------------------------------*/
5900
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005901static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005902{
5903 if (p_sel_type == INIT_SELTD)
5904 {
5905
5906 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5907
5908
5909 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005910 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005911
5912 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005913 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005914
5915 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5916
5917 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5918
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5920 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005921 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005922 }
5923
5924
5925 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5926
5927 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5928
5929 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5930 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005931 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 }
5933 }
5934
5935
5936 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5937 & ~ACTdeassert));
5938 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5939 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005940 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005941 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5942
5943 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5944
5945 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5946 & ~SCSI_BSY));
5947
James Bottomley 47b5d692005-04-24 02:38:05 -05005948 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005949
James Bottomley 47b5d692005-04-24 02:38:05 -05005950 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005951}
5952
5953
5954/*---------------------------------------------------------------------
5955 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005956 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005957 *
5958 * Description: Release the SCSI bus and disable SCAM selection.
5959 *
5960 *---------------------------------------------------------------------*/
5961
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005962static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005963{
5964 WR_HARPOON(p_port+hp_page_ctrl,
5965 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5966
5967
5968 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5969
5970 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5971 & ~SCSI_BUS_EN));
5972
5973 WR_HARPOON(p_port+hp_scsisig, 0x00);
5974
5975
5976 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5977 & ~SCAM_EN));
5978
5979 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5980 | ACTdeassert));
5981
Linus Torvalds1da177e2005-04-16 15:20:36 -07005982 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005983
5984 WR_HARPOON(p_port+hp_page_ctrl,
5985 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5986}
5987
5988
5989
5990/*---------------------------------------------------------------------
5991 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005992 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005993 *
5994 * Description: Assign an ID to all the SCAM devices.
5995 *
5996 *---------------------------------------------------------------------*/
5997
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005998static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005999{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006000 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006001
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006002 unsigned char i,k,scam_id;
6003 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006004 PNVRamInfo pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006005 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006006
James Bottomley 47b5d692005-04-24 02:38:05 -05006007 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006008
James Bottomley 47b5d692005-04-24 02:38:05 -05006009 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006010
6011 while (!i)
6012 {
6013
6014 for (k=0; k < ID_STRING_LENGTH; k++)
6015 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006016 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006017 }
6018
James Bottomley 47b5d692005-04-24 02:38:05 -05006019 FPT_scxferc(p_port,SYNC_PTRN);
6020 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021
James Bottomley 47b5d692005-04-24 02:38:05 -05006022 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006023 {
6024 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006025 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006026 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6027 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006028 temp_id_string[1] = crcBytes[2];
6029 temp_id_string[2] = crcBytes[0];
6030 temp_id_string[3] = crcBytes[1];
6031 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006032 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006033 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006034 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006035
6036 if (i == CLR_PRIORITY)
6037 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006038 FPT_scxferc(p_port,MISC_CODE);
6039 FPT_scxferc(p_port,CLR_P_FLAG);
6040 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006041 }
6042
6043 else if (i != NO_ID_AVAIL)
6044 {
6045 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006046 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006047 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006048 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006050 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051
6052
6053 for (k=1; k < 0x08; k <<= 1)
6054 if (!( k & i ))
6055 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6056
James Bottomley 47b5d692005-04-24 02:38:05 -05006057 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006058
James Bottomley 47b5d692005-04-24 02:38:05 -05006059 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006060 }
6061 }
6062
6063 else
6064 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006065 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006066 }
6067
6068 } /*End while */
6069
James Bottomley 47b5d692005-04-24 02:38:05 -05006070 FPT_scxferc(p_port,SYNC_PTRN);
6071 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006072}
6073
6074
6075
6076
6077
6078/*---------------------------------------------------------------------
6079 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006080 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006081 *
6082 * Description: Select all the SCAM devices.
6083 *
6084 *---------------------------------------------------------------------*/
6085
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006086static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006087{
6088
6089 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006090 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006091
6092 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6093
6094
6095 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006096 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6097 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006098
6099
6100 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006101 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006102
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006103 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6104 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006105 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006106
6107 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6108}
6109
6110
6111
6112/*---------------------------------------------------------------------
6113 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006114 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006115 *
6116 * Description: Handshake the p_data (DB4-0) across the bus.
6117 *
6118 *---------------------------------------------------------------------*/
6119
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006120static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006121{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006122 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006123
6124 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6125
6126 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6127
6128 curr_data &= ~BIT(7);
6129
6130 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6131
James Bottomley 47b5d692005-04-24 02:38:05 -05006132 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006133 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6134
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006135 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006136
6137 curr_data |= BIT(6);
6138
6139 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6140
6141 curr_data &= ~BIT(5);
6142
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6144
James Bottomley 47b5d692005-04-24 02:38:05 -05006145 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006146
6147 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6148 curr_data |= BIT(7);
6149
6150 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6151
6152 curr_data &= ~BIT(6);
6153
6154 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6155
James Bottomley 47b5d692005-04-24 02:38:05 -05006156 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006157
6158 return(ret_data);
6159}
6160
6161
6162/*---------------------------------------------------------------------
6163 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006164 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006165 *
6166 * Description: Transfer our Identification string to determine if we
6167 * will be the dominant master.
6168 *
6169 *---------------------------------------------------------------------*/
6170
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006171static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006172{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006173 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006174
James Bottomley 47b5d692005-04-24 02:38:05 -05006175 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176
6177 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6178
6179 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6180
6181 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006182 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006183
6184 else if (p_id_string[byte_cnt] & bit_cnt)
6185
James Bottomley 47b5d692005-04-24 02:38:05 -05006186 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006187
6188 else {
6189
James Bottomley 47b5d692005-04-24 02:38:05 -05006190 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006191 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006192 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006193 }
6194
6195 if ((ret_data & 0x1C) == 0x10)
6196 return(0x00); /*End of isolation stage, we won! */
6197
6198 if (ret_data & 0x1C)
6199 return(0xFF);
6200
6201 if ((defer) && (!(ret_data & 0x1F)))
6202 return(0x01); /*End of isolation stage, we lost. */
6203
6204 } /*bit loop */
6205
6206 } /*byte loop */
6207
6208 if (defer)
6209 return(0x01); /*We lost */
6210 else
6211 return(0); /*We WON! Yeeessss! */
6212}
6213
6214
6215
6216/*---------------------------------------------------------------------
6217 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006218 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006219 *
6220 * Description: Transfer the Identification string.
6221 *
6222 *---------------------------------------------------------------------*/
6223
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006224static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006225{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006226 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006227
6228 the_data = 0;
6229
6230 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6231
6232 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6233
James Bottomley 47b5d692005-04-24 02:38:05 -05006234 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006235
6236 if (ret_data & 0xFC)
6237 return(0xFF);
6238
6239 else {
6240
6241 the_data <<= 1;
6242 if (ret_data & BIT(1)) {
6243 the_data |= 1;
6244 }
6245 }
6246
6247 if ((ret_data & 0x1F) == 0)
6248 {
6249/*
6250 if(bit_cnt != 0 || bit_cnt != 8)
6251 {
6252 byte_cnt = 0;
6253 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006254 FPT_scxferc(p_port, SYNC_PTRN);
6255 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006256 continue;
6257 }
6258*/
6259 if (byte_cnt)
6260 return(0x00);
6261 else
6262 return(0xFF);
6263 }
6264
6265 } /*bit loop */
6266
6267 p_id_string[byte_cnt] = the_data;
6268
6269 } /*byte loop */
6270
6271 return(0);
6272}
6273
6274
6275
6276/*---------------------------------------------------------------------
6277 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006278 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006279 *
6280 * Description: Sample the SCSI data bus making sure the signal has been
6281 * deasserted for the correct number of consecutive samples.
6282 *
6283 *---------------------------------------------------------------------*/
6284
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006285static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006286{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006287 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006288
6289 i = 0;
6290 while ( i < MAX_SCSI_TAR ) {
6291
6292 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6293
6294 i = 0;
6295
6296 else
6297
6298 i++;
6299
6300 }
6301}
6302
6303
6304
6305/*---------------------------------------------------------------------
6306 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006307 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006308 *
6309 * Description: Sample the SCSI Signal lines making sure the signal has been
6310 * deasserted for the correct number of consecutive samples.
6311 *
6312 *---------------------------------------------------------------------*/
6313
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006314static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006315{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006316 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006317
6318 i = 0;
6319 while ( i < MAX_SCSI_TAR ) {
6320
6321 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6322
6323 i = 0;
6324
6325 else
6326
6327 i++;
6328
6329 }
6330}
6331
6332
6333/*---------------------------------------------------------------------
6334 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006335 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336 *
6337 * Description: Make sure we received a valid data byte.
6338 *
6339 *---------------------------------------------------------------------*/
6340
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006341static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006342{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006343 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006344
6345 for (count=1; count < 0x08; count<<=1) {
6346 if (!(p_quintet & count))
6347 p_quintet -= 0x80;
6348 }
6349
6350 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006351 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006352
6353 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006354 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006355}
6356
6357
6358/*---------------------------------------------------------------------
6359 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006360 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006361 *
6362 * Description: Select the specified device ID using a selection timeout
6363 * less than 4ms. If somebody responds then it is a legacy
6364 * drive and this ID must be marked as such.
6365 *
6366 *---------------------------------------------------------------------*/
6367
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006368static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006369{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006370 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006371
6372 WR_HARPOON(p_port+hp_page_ctrl,
6373 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6374
6375 ARAM_ACCESS(p_port);
6376
6377 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6378 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6379
6380
6381 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6382 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6383 }
6384 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6385
6386 WRW_HARPOON((p_port+hp_intstat),
6387 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6388
6389 WR_HARPOON(p_port+hp_select_id, targ_id);
6390
6391 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6392 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6393 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6394
6395
6396 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6397 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6398
6399 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006400 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006401
6402 DISABLE_AUTO(p_port);
6403
6404 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6405 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6406
6407 SGRAM_ACCESS(p_port);
6408
6409 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6410
6411 WRW_HARPOON((p_port+hp_intstat),
6412 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6413
6414 WR_HARPOON(p_port+hp_page_ctrl,
6415 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6416
James Bottomley 47b5d692005-04-24 02:38:05 -05006417 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006418 }
6419
6420 else {
6421
6422 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6423 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6424 {
6425 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6426 ACCEPT_MSG(p_port);
6427 }
6428 }
6429
6430 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6431
6432 WR_HARPOON(p_port+hp_page_ctrl,
6433 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6434
James Bottomley 47b5d692005-04-24 02:38:05 -05006435 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436 }
6437}
6438
Linus Torvalds1da177e2005-04-16 15:20:36 -07006439/*---------------------------------------------------------------------
6440 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006441 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 *
6443 * Description: Wait to be selected by another SCAM initiator.
6444 *
6445 *---------------------------------------------------------------------*/
6446
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006447static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006448{
6449 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6450}
6451
6452
6453/*---------------------------------------------------------------------
6454 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006455 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456 *
6457 * Description: Setup the data Structure with the info from the EEPROM.
6458 *
6459 *---------------------------------------------------------------------*/
6460
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006461static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006462{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006463 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006464 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006465 PNVRamInfo pCurrNvRam;
6466
James Bottomley 47b5d692005-04-24 02:38:05 -05006467 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006468
6469 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6470 max_id = 0x08;
6471
6472 else
6473 max_id = 0x10;
6474
6475 if(pCurrNvRam){
6476 for(i = 0; i < max_id; i++){
6477
6478 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006479 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006480 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006481 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006482
James Bottomley 47b5d692005-04-24 02:38:05 -05006483 if(FPT_scamInfo[i].id_string[0] == 0x00)
6484 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006486 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487
6488 }
6489 }else {
6490 for (i=0; i < max_id; i++)
6491 {
6492 for (k=0; k < ID_STRING_LENGTH; k+=2)
6493 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006494 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6495 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006496 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006498 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499 }
6500
James Bottomley 47b5d692005-04-24 02:38:05 -05006501 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6502 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503
James Bottomley 47b5d692005-04-24 02:38:05 -05006504 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505
6506 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006507 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508
6509 }
6510 }
6511 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006512 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006513
6514}
6515
6516/*---------------------------------------------------------------------
6517 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006518 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006519 *
6520 * Description: Match the Device ID string with our values stored in
6521 * the EEPROM.
6522 *
6523 *---------------------------------------------------------------------*/
6524
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006525static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526{
6527
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006528 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529
6530
6531 for (i=0; i < MAX_SCSI_TAR; i++) {
6532
James Bottomley 47b5d692005-04-24 02:38:05 -05006533 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534
6535 for (k=0; k < ID_STRING_LENGTH; k++)
6536 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006537 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6538 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006539 }
6540
6541 if (match)
6542 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006543 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006544 return(i);
6545 }
6546
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547 }
6548
6549
6550
6551 if (p_id_string[0] & BIT(5))
6552 i = 8;
6553 else
6554 i = MAX_SCSI_TAR;
6555
6556 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006557 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006558 else
6559 match = 7;
6560
6561 while (i > 0)
6562 {
6563 i--;
6564
James Bottomley 47b5d692005-04-24 02:38:05 -05006565 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566 {
6567 for (k=0; k < ID_STRING_LENGTH; k++)
6568 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006569 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006570 }
6571
James Bottomley 47b5d692005-04-24 02:38:05 -05006572 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006573
James Bottomley 47b5d692005-04-24 02:38:05 -05006574 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6575 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006576 return(match);
6577
6578 }
6579
6580
6581 match--;
6582
6583 if (match == 0xFF)
6584 {
6585 if (p_id_string[0] & BIT(5))
6586 match = 7;
6587 else
6588 match = MAX_SCSI_TAR-1;
6589 }
6590 }
6591
6592
6593
6594 if (p_id_string[0] & BIT(7))
6595 {
6596 return(CLR_PRIORITY);
6597 }
6598
6599
6600 if (p_id_string[0] & BIT(5))
6601 i = 8;
6602 else
6603 i = MAX_SCSI_TAR;
6604
6605 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006606 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006607 else
6608 match = 7;
6609
6610 while (i > 0)
6611 {
6612
6613 i--;
6614
James Bottomley 47b5d692005-04-24 02:38:05 -05006615 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006616 {
6617 for (k=0; k < ID_STRING_LENGTH; k++)
6618 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006619 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006620 }
6621
James Bottomley 47b5d692005-04-24 02:38:05 -05006622 FPT_scamInfo[match].id_string[0] |= BIT(7);
6623 FPT_scamInfo[match].state = ID_ASSIGNED;
6624 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6625 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006626 return(match);
6627
6628 }
6629
6630
6631 match--;
6632
6633 if (match == 0xFF)
6634 {
6635 if (p_id_string[0] & BIT(5))
6636 match = 7;
6637 else
6638 match = MAX_SCSI_TAR-1;
6639 }
6640 }
6641
6642 return(NO_ID_AVAIL);
6643}
6644
6645
6646/*---------------------------------------------------------------------
6647 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006648 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006649 *
6650 * Description: Save off the device SCAM ID strings.
6651 *
6652 *---------------------------------------------------------------------*/
6653
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006654static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006656 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006657 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006658
6659
6660 sum_data = 0x0000;
6661
6662 for (i = 1; i < EE_SCAMBASE/2; i++)
6663 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006664 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006665 }
6666
6667
James Bottomley 47b5d692005-04-24 02:38:05 -05006668 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006669
6670 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6671 max_id = 0x08;
6672
6673 else
6674 max_id = 0x10;
6675
6676 for (i=0; i < max_id; i++)
6677 {
6678
6679 for (k=0; k < ID_STRING_LENGTH; k+=2)
6680 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006681 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006682 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006683 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006685 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6686 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687 }
6688 }
6689
6690
James Bottomley 47b5d692005-04-24 02:38:05 -05006691 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6692 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006693}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694
6695/*---------------------------------------------------------------------
6696 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006697 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698 *
6699 * Description: Setup the Xbow for normal operation.
6700 *
6701 *---------------------------------------------------------------------*/
6702
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006703static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006704{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006705unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006706
6707 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006708 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006709
6710 WR_HARPOON(port+hp_scsireset,0x00);
6711 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6712
6713 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6714 FIFO_CLR));
6715
6716 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6717
6718 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6719
6720 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6721 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6722
6723 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6724
James Bottomley 47b5d692005-04-24 02:38:05 -05006725 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006726 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6727
6728 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006729 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006730
James Bottomley 47b5d692005-04-24 02:38:05 -05006731 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732
6733 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6734
6735 /* Turn on SCSI_MODE8 for narrow cards to fix the
6736 strapping issue with the DUAL CHANNEL card */
6737 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6738 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6739
Linus Torvalds1da177e2005-04-16 15:20:36 -07006740 WR_HARPOON(port+hp_page_ctrl, i);
6741
6742}
6743
6744
6745/*---------------------------------------------------------------------
6746 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006747 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006748 *
6749 * Description: Initialize the BusMaster for normal operations.
6750 *
6751 *---------------------------------------------------------------------*/
6752
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006753static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006754{
6755
6756
6757 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6758 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6759
6760 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6761
6762
6763 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6764
6765 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6766
6767
Linus Torvalds1da177e2005-04-16 15:20:36 -07006768 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6769 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6770 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6771 ~SCATTER_EN));
6772}
6773
6774
6775/*---------------------------------------------------------------------
6776 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006777 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778 *
6779 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6780 * necessary.
6781 *
6782 *---------------------------------------------------------------------*/
6783
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006784static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006785{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006786 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006787
6788 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6789 max_wd_cnt = EEPROM_WD_CNT;
6790 else
6791 max_wd_cnt = EEPROM_WD_CNT * 2;
6792
James Bottomley 47b5d692005-04-24 02:38:05 -05006793 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006794
6795 if (temp == 0x4641) {
6796
6797 for (index = 2; index < max_wd_cnt; index++) {
6798
James Bottomley 47b5d692005-04-24 02:38:05 -05006799 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006800
6801 }
6802
James Bottomley 47b5d692005-04-24 02:38:05 -05006803 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006804
6805 return; /*EEPROM is Okay so return now! */
6806 }
6807 }
6808
6809
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006810 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811
6812 for (index = 0; index < max_wd_cnt; index++) {
6813
James Bottomley 47b5d692005-04-24 02:38:05 -05006814 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 }
6816
6817 temp = 0;
6818
James Bottomley 47b5d692005-04-24 02:38:05 -05006819 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006821 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006823 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006825 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006827 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006829 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006833 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 temp += 0x0007;
6835
James Bottomley 47b5d692005-04-24 02:38:05 -05006836 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006838 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006840 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 temp += 0x0000;
6842
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006852 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006853 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006855 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006857 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858 temp += 0x4242;
6859
6860
James Bottomley 47b5d692005-04-24 02:38:05 -05006861 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006863 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006864 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006866 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006867 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006868 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006869 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006871 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006873 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006875 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 temp += 0x2020;
6877
6878 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006879 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006880 temp += (0x0700+TYPE_CODE0);
6881 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006882 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 temp += 0x5542; /* BUSLOGIC */
6884 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006885 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886 temp += 0x4C53;
6887 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006888 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889 temp += 0x474F;
6890 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006891 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892 temp += 0x4349;
6893 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006894 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895 temp += 0x5442; /* BT- 930 */
6896 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006897 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898 temp += 0x202D;
6899 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006900 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006901 temp += 0x3339;
6902 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006903 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006904 temp += 0x2030;
6905 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006906 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006907 temp += 0x5453;
6908 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006909 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910 temp += 0x5645;
6911 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006912 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006913 temp += 0x2045;
6914 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006915 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006916 temp += 0x202F;
6917 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006918 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006919 temp += 0x4F4A;
6920 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006921 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006922 temp += 0x204E;
6923 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006924 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006925 temp += 0x3539;
6926
6927
6928
James Bottomley 47b5d692005-04-24 02:38:05 -05006929 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006930
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006931 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006932
6933}
6934
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935
6936/*---------------------------------------------------------------------
6937 *
6938 * Function: Queue Search Select
6939 *
6940 * Description: Try to find a new command to execute.
6941 *
6942 *---------------------------------------------------------------------*/
6943
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006944static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006945{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006946 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006947 PSCCBMgr_tar_info currTar_Info;
6948 PSCCB pOldSccb;
6949
6950 scan_ptr = pCurrCard->scanIndex;
6951 do
6952 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006953 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006954 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6955 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6956 {
6957 if (currTar_Info->TarSelQ_Cnt != 0)
6958 {
6959
6960 scan_ptr++;
6961 if (scan_ptr == MAX_SCSI_TAR)
6962 scan_ptr = 0;
6963
6964 for(lun=0; lun < MAX_LUN; lun++)
6965 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006966 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006967 {
6968
6969 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6970 pOldSccb = NULL;
6971
6972 while((pCurrCard->currentSCCB != NULL) &&
6973 (lun != pCurrCard->currentSCCB->Lun))
6974 {
6975 pOldSccb = pCurrCard->currentSCCB;
6976 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6977 Sccb_forwardlink;
6978 }
6979 if(pCurrCard->currentSCCB == NULL)
6980 continue;
6981 if(pOldSccb != NULL)
6982 {
6983 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6984 Sccb_forwardlink;
6985 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6986 Sccb_backlink;
6987 currTar_Info->TarSelQ_Cnt--;
6988 }
6989 else
6990 {
6991 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6992
6993 if (currTar_Info->TarSelQ_Head == NULL)
6994 {
6995 currTar_Info->TarSelQ_Tail = NULL;
6996 currTar_Info->TarSelQ_Cnt = 0;
6997 }
6998 else
6999 {
7000 currTar_Info->TarSelQ_Cnt--;
7001 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7002 }
7003 }
7004 pCurrCard->scanIndex = scan_ptr;
7005
7006 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7007
7008 break;
7009 }
7010 }
7011 }
7012
7013 else
7014 {
7015 scan_ptr++;
7016 if (scan_ptr == MAX_SCSI_TAR) {
7017 scan_ptr = 0;
7018 }
7019 }
7020
7021 }
7022 else
7023 {
7024 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007025 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007026 {
7027
7028 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7029
7030 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7031
7032 if (currTar_Info->TarSelQ_Head == NULL)
7033 {
7034 currTar_Info->TarSelQ_Tail = NULL;
7035 currTar_Info->TarSelQ_Cnt = 0;
7036 }
7037 else
7038 {
7039 currTar_Info->TarSelQ_Cnt--;
7040 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7041 }
7042
7043 scan_ptr++;
7044 if (scan_ptr == MAX_SCSI_TAR)
7045 scan_ptr = 0;
7046
7047 pCurrCard->scanIndex = scan_ptr;
7048
7049 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7050
7051 break;
7052 }
7053
7054 else
7055 {
7056 scan_ptr++;
7057 if (scan_ptr == MAX_SCSI_TAR)
7058 {
7059 scan_ptr = 0;
7060 }
7061 }
7062 }
7063 } while (scan_ptr != pCurrCard->scanIndex);
7064}
7065
7066
7067/*---------------------------------------------------------------------
7068 *
7069 * Function: Queue Select Fail
7070 *
7071 * Description: Add the current SCCB to the head of the Queue.
7072 *
7073 *---------------------------------------------------------------------*/
7074
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007075static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007077 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007078 PSCCBMgr_tar_info currTar_Info;
7079
7080 if (pCurrCard->currentSCCB != NULL)
7081 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007082 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007083 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007084
7085 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7086
7087 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7088
7089 if (currTar_Info->TarSelQ_Cnt == 0)
7090 {
7091 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7092 }
7093
7094 else
7095 {
7096 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7097 }
7098
7099
7100 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7101
7102 pCurrCard->currentSCCB = NULL;
7103 currTar_Info->TarSelQ_Cnt++;
7104 }
7105}
7106/*---------------------------------------------------------------------
7107 *
7108 * Function: Queue Command Complete
7109 *
7110 * Description: Call the callback function with the current SCCB.
7111 *
7112 *---------------------------------------------------------------------*/
7113
James Bottomley 47b5d692005-04-24 02:38:05 -05007114static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007115 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007116{
7117
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007118 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007119 CALL_BK_FN callback;
7120 PSCCBMgr_tar_info currTar_Info;
7121
7122 SCSIcmd = p_sccb->Cdb[0];
7123
7124
7125 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7126
7127 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7128 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7129 (p_sccb->TargetStatus != SSCHECK))
7130
7131 if ((SCSIcmd == SCSI_READ) ||
7132 (SCSIcmd == SCSI_WRITE) ||
7133 (SCSIcmd == SCSI_READ_EXTENDED) ||
7134 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7135 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7136 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7137 (pCurrCard->globalFlags & F_NO_FILTER)
7138 )
7139 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7140 }
7141
7142
7143 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7144 {
7145 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7146 p_sccb->SccbStatus = SCCB_ERROR;
7147 else
7148 p_sccb->SccbStatus = SCCB_SUCCESS;
7149 }
7150
7151 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7152
7153 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7154 for (i=0; i < 6; i++) {
7155 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7156 }
7157 }
7158
7159 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7160 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7161
James Bottomley 47b5d692005-04-24 02:38:05 -05007162 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007163 }
7164
7165 pCurrCard->cmdCounter--;
7166 if (!pCurrCard->cmdCounter) {
7167
7168 if (pCurrCard->globalFlags & F_GREEN_PC) {
7169 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7170 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7171 }
7172
7173 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7174 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7175
7176 }
7177
7178 if(pCurrCard->discQCount != 0)
7179 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007180 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007181 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7182 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7183 {
7184 pCurrCard->discQCount--;
7185 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7186 }
7187 else
7188 {
7189 if(p_sccb->Sccb_tag)
7190 {
7191 pCurrCard->discQCount--;
7192 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7193 }else
7194 {
7195 pCurrCard->discQCount--;
7196 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7197 }
7198 }
7199
7200 }
7201
7202 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7203 callback(p_sccb);
7204 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7205 pCurrCard->currentSCCB = NULL;
7206}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007207
7208
7209/*---------------------------------------------------------------------
7210 *
7211 * Function: Queue Disconnect
7212 *
7213 * Description: Add SCCB to our disconnect array.
7214 *
7215 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007216static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217{
7218 PSCCBMgr_tar_info currTar_Info;
7219
James Bottomley 47b5d692005-04-24 02:38:05 -05007220 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007221
James Bottomley 47b5d692005-04-24 02:38:05 -05007222 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007223 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7224 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007225 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007226 }
7227 else
7228 {
7229 if (p_sccb->Sccb_tag)
7230 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007231 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7232 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7233 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007234 }else
7235 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007236 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007237 }
7238 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007239 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007240}
7241
7242
7243/*---------------------------------------------------------------------
7244 *
7245 * Function: Queue Flush SCCB
7246 *
7247 * Description: Flush all SCCB's back to the host driver for this target.
7248 *
7249 *---------------------------------------------------------------------*/
7250
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007251static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007252{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007253 unsigned char qtag,thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007254 PSCCB currSCCB;
7255 PSCCBMgr_tar_info currTar_Info;
7256
James Bottomley 47b5d692005-04-24 02:38:05 -05007257 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007258 if(currSCCB != NULL)
7259 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007260 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007261 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007262
7263 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7264
James Bottomley 47b5d692005-04-24 02:38:05 -05007265 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7266 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007267 {
7268
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007269 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007270
James Bottomley 47b5d692005-04-24 02:38:05 -05007271 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007272
James Bottomley 47b5d692005-04-24 02:38:05 -05007273 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007274 currTar_Info->TarTagQ_Cnt--;
7275
7276 }
7277 }
7278 }
7279
7280}
7281
7282/*---------------------------------------------------------------------
7283 *
7284 * Function: Queue Flush Target SCCB
7285 *
7286 * Description: Flush all SCCB's back to the host driver for this target.
7287 *
7288 *---------------------------------------------------------------------*/
7289
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007290static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7291 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007293 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007294 PSCCBMgr_tar_info currTar_Info;
7295
James Bottomley 47b5d692005-04-24 02:38:05 -05007296 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297
7298 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7299
James Bottomley 47b5d692005-04-24 02:38:05 -05007300 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7301 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007302 {
7303
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007304 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007305
James Bottomley 47b5d692005-04-24 02:38:05 -05007306 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007307
James Bottomley 47b5d692005-04-24 02:38:05 -05007308 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007309 currTar_Info->TarTagQ_Cnt--;
7310
7311 }
7312 }
7313
7314}
7315
7316
7317
7318
7319
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007320static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007321{
7322 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007323 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007324
7325 p_SCCB->Sccb_forwardlink = NULL;
7326
7327 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7328
7329 if (currTar_Info->TarSelQ_Cnt == 0) {
7330
7331 currTar_Info->TarSelQ_Head = p_SCCB;
7332 }
7333
7334 else {
7335
7336 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7337 }
7338
7339
7340 currTar_Info->TarSelQ_Tail = p_SCCB;
7341 currTar_Info->TarSelQ_Cnt++;
7342}
7343
7344
7345/*---------------------------------------------------------------------
7346 *
7347 * Function: Queue Find SCCB
7348 *
7349 * Description: Search the target select Queue for this SCCB, and
7350 * remove it if found.
7351 *
7352 *---------------------------------------------------------------------*/
7353
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007354static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007355{
7356 PSCCB q_ptr;
7357 PSCCBMgr_tar_info currTar_Info;
7358
James Bottomley 47b5d692005-04-24 02:38:05 -05007359 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007360
7361 q_ptr = currTar_Info->TarSelQ_Head;
7362
7363 while(q_ptr != NULL) {
7364
7365 if (q_ptr == p_SCCB) {
7366
7367
7368 if (currTar_Info->TarSelQ_Head == q_ptr) {
7369
7370 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7371 }
7372
7373 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7374
7375 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7376 }
7377
7378 if (q_ptr->Sccb_forwardlink != NULL) {
7379 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7380 }
7381
7382 if (q_ptr->Sccb_backlink != NULL) {
7383 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7384 }
7385
7386 currTar_Info->TarSelQ_Cnt--;
7387
James Bottomley 47b5d692005-04-24 02:38:05 -05007388 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007389 }
7390
7391 else {
7392 q_ptr = q_ptr->Sccb_forwardlink;
7393 }
7394 }
7395
7396
James Bottomley 47b5d692005-04-24 02:38:05 -05007397 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007398
7399}
7400
7401
7402/*---------------------------------------------------------------------
7403 *
7404 * Function: Utility Update Residual Count
7405 *
7406 * Description: Update the XferCnt to the remaining byte count.
7407 * If we transferred all the data then just write zero.
7408 * If Non-SG transfer then report Total Cnt - Actual Transfer
7409 * Cnt. For SG transfers add the count fields of all
7410 * remaining SG elements, as well as any partial remaining
7411 * element.
7412 *
7413 *---------------------------------------------------------------------*/
7414
James Bottomley 47b5d692005-04-24 02:38:05 -05007415static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007416{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007417 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007418 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007419 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007420
7421 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7422
7423 p_SCCB->DataLength = 0x0000;
7424 }
7425
7426 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7427
7428 partial_cnt = 0x0000;
7429
7430 sg_index = p_SCCB->Sccb_sgseg;
7431
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007432 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007433
7434 if (p_SCCB->Sccb_SGoffset) {
7435
7436 partial_cnt = p_SCCB->Sccb_SGoffset;
7437 sg_index++;
7438 }
7439
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007440 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007441 p_SCCB->DataLength ) {
7442
7443 partial_cnt += *(sg_ptr+(sg_index * 2));
7444 sg_index++;
7445 }
7446
7447 p_SCCB->DataLength = partial_cnt;
7448 }
7449
7450 else {
7451
7452 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7453 }
7454}
7455
7456
7457/*---------------------------------------------------------------------
7458 *
7459 * Function: Wait 1 Second
7460 *
7461 * Description: Wait for 1 second.
7462 *
7463 *---------------------------------------------------------------------*/
7464
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007465static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007466{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007467 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007468
7469 for(i=0; i < 4; i++) {
7470
James Bottomley 47b5d692005-04-24 02:38:05 -05007471 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007472
7473 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7474 break;
7475
7476 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7477 break;
7478 }
7479}
7480
7481
7482/*---------------------------------------------------------------------
7483 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007484 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007485 *
7486 * Description: Wait the desired delay.
7487 *
7488 *---------------------------------------------------------------------*/
7489
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007490static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007491{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007492 unsigned char old_timer;
7493 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007494
7495 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7496
7497 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7498 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7499
7500 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7501 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007502 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007503
7504
7505 WR_HARPOON(p_port+hp_portctrl_0,
7506 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7507
7508 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7509
7510 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7511 break;
7512
7513 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7514 break;
7515 }
7516
7517 WR_HARPOON(p_port+hp_portctrl_0,
7518 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7519
7520 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007521 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007522
7523 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7524
7525 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7526}
7527
7528
7529/*---------------------------------------------------------------------
7530 *
7531 * Function: Enable/Disable Write to EEPROM
7532 *
7533 * Description: The EEPROM must first be enabled for writes
7534 * A total of 9 clocks are needed.
7535 *
7536 *---------------------------------------------------------------------*/
7537
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007538static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007539{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007540 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007541
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007542 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 -07007543
7544 if (p_mode)
7545
James Bottomley 47b5d692005-04-24 02:38:05 -05007546 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007547
7548 else
7549
7550
James Bottomley 47b5d692005-04-24 02:38:05 -05007551 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007552
7553 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7554 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7555}
7556
7557
7558/*---------------------------------------------------------------------
7559 *
7560 * Function: Write EEPROM
7561 *
7562 * Description: Write a word to the EEPROM at the specified
7563 * address.
7564 *
7565 *---------------------------------------------------------------------*/
7566
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007567static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007568{
7569
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007570 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007571 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007572
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007573 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 -07007574 (SEE_MS | SEE_CS));
7575
7576
7577
James Bottomley 47b5d692005-04-24 02:38:05 -05007578 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007579
7580
7581 ee_value |= (SEE_MS + SEE_CS);
7582
7583 for(i = 0x8000; i != 0; i>>=1) {
7584
7585 if (i & ee_data)
7586 ee_value |= SEE_DO;
7587 else
7588 ee_value &= ~SEE_DO;
7589
7590 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7591 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7592 ee_value |= SEE_CLK; /* Clock data! */
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 ee_value &= ~SEE_CLK;
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 }
7599 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7600 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7601
James Bottomley 47b5d692005-04-24 02:38:05 -05007602 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007603
7604 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7606 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7607}
7608
7609/*---------------------------------------------------------------------
7610 *
7611 * Function: Read EEPROM
7612 *
7613 * Description: Read a word from the EEPROM at the desired
7614 * address.
7615 *
7616 *---------------------------------------------------------------------*/
7617
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007618static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007619{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007620 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007621
7622 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007623 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007624 do
7625 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007626 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007627
7628 if(ee_data1 == ee_data2)
7629 return(ee_data1);
7630
7631 ee_data1 = ee_data2;
7632 i++;
7633
7634 }while(i < 4);
7635
7636 return(ee_data1);
7637}
7638
7639/*---------------------------------------------------------------------
7640 *
7641 * Function: Read EEPROM Original
7642 *
7643 * Description: Read a word from the EEPROM at the desired
7644 * address.
7645 *
7646 *---------------------------------------------------------------------*/
7647
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007648static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007649{
7650
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007651 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007652 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007653
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007654 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 -07007655 (SEE_MS | SEE_CS));
7656
7657
James Bottomley 47b5d692005-04-24 02:38:05 -05007658 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007659
7660
7661 ee_value |= (SEE_MS + SEE_CS);
7662 ee_data = 0;
7663
7664 for(i = 1; i <= 16; i++) {
7665
7666 ee_value |= SEE_CLK; /* Clock data! */
7667 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7668 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7669 ee_value &= ~SEE_CLK;
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672
7673 ee_data <<= 1;
7674
7675 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7676 ee_data |= 1;
7677 }
7678
7679 ee_value &= ~(SEE_MS + SEE_CS);
7680 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7681 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7682
7683 return(ee_data);
7684}
7685
7686
7687/*---------------------------------------------------------------------
7688 *
7689 * Function: Send EE command and Address to the EEPROM
7690 *
7691 * Description: Transfers the correct command and sends the address
7692 * to the eeprom.
7693 *
7694 *---------------------------------------------------------------------*/
7695
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007696static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007697{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007698 unsigned char ee_value;
7699 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007700
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007701 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007702
7703
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007704 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007705
7706
7707 ee_value = SEE_MS;
7708 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7709
7710 ee_value |= SEE_CS; /* Set CS to EEPROM */
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712
7713
7714 for(i = 0x04; i != 0; i>>=1) {
7715
7716 if (i & ee_cmd)
7717 ee_value |= SEE_DO;
7718 else
7719 ee_value &= ~SEE_DO;
7720
7721 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7722 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7723 ee_value |= SEE_CLK; /* Clock data! */
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 ee_value &= ~SEE_CLK;
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 }
7730
7731
7732 if (narrow_flg)
7733 i = 0x0080;
7734
7735 else
7736 i = 0x0200;
7737
7738
7739 while (i != 0) {
7740
7741 if (i & ee_addr)
7742 ee_value |= SEE_DO;
7743 else
7744 ee_value &= ~SEE_DO;
7745
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748 ee_value |= SEE_CLK; /* Clock data! */
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 ee_value &= ~SEE_CLK;
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754
7755 i >>= 1;
7756 }
7757}
7758
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007759static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007760{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007761 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007762 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007763 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007764 for (i=0; i < ID_STRING_LENGTH; i++)
7765 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007766 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007767 for(j=0; j < 8; j++)
7768 {
7769 if ((crc ^ ch) & 1)
7770 crc = (crc >> 1) ^ CRCMASK;
7771 else
7772 crc >>= 1;
7773 ch >>= 1;
7774 }
7775 }
7776 return(crc);
7777}
7778
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007779static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007780{
7781 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007782 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007783 lrc = 0;
7784 for(i = 0; i < ID_STRING_LENGTH; i++)
7785 lrc ^= buffer[i];
7786 return(lrc);
7787}
7788
7789
7790
7791/*
7792 The following inline definitions avoid type conflicts.
7793*/
7794
7795static inline unsigned char
7796FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7797{
7798 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7799}
7800
7801
7802static inline FlashPoint_CardHandle_T
7803FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7804{
7805 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7806}
7807
7808static inline void
7809FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7810{
7811 FlashPoint_ReleaseHostAdapter(CardHandle);
7812}
7813
7814
7815static inline void
7816FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7817{
7818 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7819}
7820
7821
7822static inline void
7823FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7824{
7825 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7826}
7827
7828
7829static inline boolean
7830FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7831{
7832 return FlashPoint_InterruptPending(CardHandle);
7833}
7834
7835
7836static inline int
7837FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7838{
7839 return FlashPoint_HandleInterrupt(CardHandle);
7840}
7841
7842
7843#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7844#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7845#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7846#define FlashPoint_StartCCB FlashPoint__StartCCB
7847#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7848#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7849#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7850
7851
Linus Torvalds1da177e2005-04-16 15:20:36 -07007852#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7853
7854
7855/*
7856 Define prototypes for the FlashPoint SCCB Manager Functions.
7857*/
7858
7859extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7860extern FlashPoint_CardHandle_T
7861 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7862extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7863extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7864extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7865extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7866extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007867
7868
7869#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */