blob: 022a4c0da7e1fc1dec998df14dfdad417fb113fc [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080051#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080052#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
54
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
James Bottomley 47b5d692005-04-24 02:38:05 -050057typedef struct _SCCB *PSCCB;
58typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60
61typedef struct SCCBMgr_info {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080062 unsigned long si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080063 unsigned char si_present;
64 unsigned char si_intvect;
65 unsigned char si_id;
66 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080067 unsigned short si_fw_revision;
68 unsigned short si_per_targ_init_sync;
69 unsigned short si_per_targ_fast_nego;
70 unsigned short si_per_targ_ultra_nego;
71 unsigned short si_per_targ_no_disc;
72 unsigned short si_per_targ_wide_nego;
73 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080074 unsigned char si_card_family;
75 unsigned char si_bustype;
76 unsigned char si_card_model[3];
77 unsigned char si_relative_cardnum;
78 unsigned char si_reserved[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080079 unsigned long si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080080 unsigned char si_XlatInfo[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080081 unsigned long si_reserved2[5];
82 unsigned long si_secondary_range;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083} SCCBMGR_INFO;
84
James Bottomley 47b5d692005-04-24 02:38:05 -050085typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87
James Bottomley 47b5d692005-04-24 02:38:05 -050088#define SCSI_PARITY_ENA 0x0001
89#define LOW_BYTE_TERM 0x0010
90#define HIGH_BYTE_TERM 0x0020
91#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93#define SUPPORT_16TAR_32LUN 0x0002
94#define SOFT_RESET 0x0004
95#define EXTENDED_TRANSLATION 0x0008
96#define POST_ALL_UNDERRRUNS 0x0040
97#define FLAG_SCAM_ENABLED 0x0080
98#define FLAG_SCAM_LEVEL2 0x0100
99
100
101
102
103#define HARPOON_FAMILY 0x02
104
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
Alexey Dobriyan323579882006-01-15 02:12:54 +0100107/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 * The UCB Manager treats the SCCB as it's 'native hardware structure'
109 */
110
111
112#pragma pack(1)
113typedef struct _SCCB {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800114 unsigned char OperationCode;
115 unsigned char ControlByte;
116 unsigned char CdbLength;
117 unsigned char RequestSenseLength;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800118 unsigned long DataLength;
119 unsigned long DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800120 unsigned char CcbRes[2];
121 unsigned char HostStatus;
122 unsigned char TargetStatus;
123 unsigned char TargID;
124 unsigned char Lun;
125 unsigned char Cdb[12];
126 unsigned char CcbRes1;
127 unsigned char Reserved1;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800128 unsigned long Reserved2;
129 unsigned long SensePointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
131
132 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800133 unsigned long SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800134 unsigned char SccbStatus;
135 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800136 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
138
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800139 unsigned long Sccb_XferCnt; /* actual transfer count */
140 unsigned long Sccb_ATC;
141 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
142 unsigned long Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800143 unsigned short Sccb_MGRFlags;
144 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800145 unsigned char Sccb_scsimsg; /* identify msg for selection */
146 unsigned char Sccb_tag;
147 unsigned char Sccb_scsistat;
148 unsigned char Sccb_idmsg; /* image of last msg in */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 PSCCB Sccb_forwardlink;
150 PSCCB Sccb_backlink;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800151 unsigned long Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800152 unsigned char Save_Cdb[6];
153 unsigned char Save_CdbLen;
154 unsigned char Sccb_XferState;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800155 unsigned long Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 } SCCB;
157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
159#pragma pack()
160
161
162
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163#define SCATTER_GATHER_COMMAND 0x02
164#define RESIDUAL_COMMAND 0x03
165#define RESIDUAL_SG_COMMAND 0x04
166#define RESET_COMMAND 0x81
167
168
169#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
170#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171#define SCCB_DATA_XFER_OUT 0x10 /* Write */
172#define SCCB_DATA_XFER_IN 0x08 /* Read */
173
174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
176
177
178#define BUS_FREE_ST 0
179#define SELECT_ST 1
180#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
181#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
182#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
183#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
184#define COMMAND_ST 6
185#define DATA_OUT_ST 7
186#define DATA_IN_ST 8
187#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190
191#define F_HOST_XFER_DIR 0x01
192#define F_ALL_XFERRED 0x02
193#define F_SG_XFER 0x04
194#define F_AUTO_SENSE 0x08
195#define F_ODD_BALL_CNT 0x10
196#define F_NO_DATA_YET 0x80
197
198
199#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200#define F_DEV_SELECTED 0x04
201
202
203#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
204#define SCCB_DATA_UNDER_RUN 0x0C
205#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
206#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
210#define SCCB_BM_ERR 0x30 /* BusMaster error. */
211#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
212
213
214
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216
217#define SCCB_IN_PROCESS 0x00
218#define SCCB_SUCCESS 0x01
219#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222
223
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224#define ORION_FW_REV 3110
225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
231
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
James Bottomley 47b5d692005-04-24 02:38:05 -0500233#define MAX_SCSI_TAR 16
234#define MAX_LUN 32
235#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240
241
Alexey Dobriyanad0e1d92006-03-08 00:14:28 -0800242#define RD_HARPOON(ioport) inb((u32)ioport)
243#define RDW_HARPOON(ioport) inw((u32)ioport)
244#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
245#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
246#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
247#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249
250#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251#define SYNC_TRYING BIT(6)
252#define SYNC_SUPPORTED (BIT(7)+BIT(6))
253
254#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255#define WIDE_ENABLED BIT(4)
256#define WIDE_NEGOCIATED BIT(5)
257
258#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259#define TAG_Q_TRYING BIT(2)
260#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261
262#define TAR_ALLOW_DISC BIT(0)
263
264
265#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266#define EE_SYNC_5MB BIT(0)
267#define EE_SYNC_10MB BIT(1)
268#define EE_SYNC_20MB (BIT(0)+BIT(1))
269
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270#define EE_WIDE_SCSI BIT(7)
271
272
James Bottomley 47b5d692005-04-24 02:38:05 -0500273typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
275
276typedef struct SCCBMgr_tar_info {
277
278 PSCCB TarSelQ_Head;
279 PSCCB TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800280 unsigned char TarLUN_CA; /*Contingent Allgiance */
281 unsigned char TarTagQ_Cnt;
282 unsigned char TarSelQ_Cnt;
283 unsigned char TarStatus;
284 unsigned char TarEEValue;
285 unsigned char TarSyncCtrl;
286 unsigned char TarReserved[2]; /* for alignment */
287 unsigned char LunDiscQ_Idx[MAX_LUN];
288 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289} SCCBMGR_TAR_INFO;
290
291typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800292 unsigned char niModel; /* Model No. of card */
293 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800294 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800295 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
296 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
297 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
298 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
299 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
300 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301}NVRAMINFO;
302
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304
305#define MODEL_LT 1
306#define MODEL_DL 2
307#define MODEL_LW 3
308#define MODEL_DW 4
309
310
311typedef struct SCCBcard {
312 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800315 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800317 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800318 unsigned char discQCount;
319 unsigned char tagQ_Lst;
320 unsigned char cardIndex;
321 unsigned char scanIndex;
322 unsigned char globalFlags;
323 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 PNVRamInfo pNvRamInfo;
325 PSCCB discQ_Tbl[QUEUE_DEPTH];
326
327}SCCBCARD;
328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
331
332#define F_TAG_STARTED 0x01
333#define F_CONLUN_IO 0x02
334#define F_DO_RENEGO 0x04
335#define F_NO_FILTER 0x08
336#define F_GREEN_PC 0x10
337#define F_HOST_XFER_ACT 0x20
338#define F_NEW_SCCB_CMD 0x40
339#define F_UPDATE_EEPROM 0x80
340
341
342#define ID_STRING_LENGTH 32
343#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
344
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345
346#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
347
348#define ASSIGN_ID 0x00
349#define SET_P_FLAG 0x01
350#define CFG_CMPLT 0x03
351#define DOM_MSTR 0x0F
352#define SYNC_PTRN 0x1F
353
354#define ID_0_7 0x18
355#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356#define MISC_CODE 0x14
357#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
360
361#define INIT_SELTD 0x01
362#define LEVEL2_TAR 0x02
363
364
365enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
366 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
367 CLR_PRIORITY,NO_ID_AVAIL };
368
369typedef struct SCCBscam_info {
370
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800371 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 enum scam_id_st state;
373
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800374} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378#define SCSI_READ 0x08
379#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381#define SCSI_READ_EXTENDED 0x28
382#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
385
386
387#define SSGOOD 0x00
388#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389#define SSQ_FULL 0x28
390
391
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
393
394#define SMCMD_COMP 0x00
395#define SMEXT 0x01
396#define SMSAVE_DATA_PTR 0x02
397#define SMREST_DATA_PTR 0x03
398#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399#define SMABORT 0x06
400#define SMREJECT 0x07
401#define SMNO_OP 0x08
402#define SMPARITY 0x09
403#define SMDEV_RESET 0x0C
404#define SMABORT_TAG 0x0D
405#define SMINIT_RECOVERY 0x0F
406#define SMREL_RECOVERY 0x10
407
408#define SMIDENT 0x80
409#define DISC_PRIV 0x40
410
411
412#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413#define SMWDTR 0x03
414#define SM8BIT 0x00
415#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416#define SMIGNORWR 0x23 /* Ignore Wide Residue */
417
418
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420
421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
423
424
425#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426#define TWELVE_BYTE_CMD 0x0C
427
428#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
430
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431
432#define EEPROM_WD_CNT 256
433
434#define EEPROM_CHECK_SUM 0
435#define FW_SIGNATURE 2
436#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439#define SYSTEM_CONFIG 16
440#define SCSI_CONFIG 17
441#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442#define SCAM_CONFIG 20
443#define ADAPTER_SCSI_ID 24
444
445
446#define IGNORE_B_SCAN 32
447#define SEND_START_ENA 34
448#define DEVICE_ENABLE 36
449
450#define SYNC_RATE_TBL 38
451#define SYNC_RATE_TBL01 38
452#define SYNC_RATE_TBL23 40
453#define SYNC_RATE_TBL45 42
454#define SYNC_RATE_TBL67 44
455#define SYNC_RATE_TBL89 46
456#define SYNC_RATE_TBLab 48
457#define SYNC_RATE_TBLcd 50
458#define SYNC_RATE_TBLef 52
459
460
461
462#define EE_SCAMBASE 256
463
464
465
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 #define SCAM_ENABLED BIT(2)
467 #define SCAM_LEVEL2 BIT(3)
468
469
470 #define RENEGO_ENA BITW(10)
471 #define CONNIO_ENA BITW(11)
472 #define GREEN_PC_ENA BITW(12)
473
474
475 #define AUTO_RATE_00 00
476 #define AUTO_RATE_05 01
477 #define AUTO_RATE_10 02
478 #define AUTO_RATE_20 03
479
480 #define WIDE_NEGO_BIT BIT(7)
481 #define DISC_ENABLE_BIT BIT(6)
482
483
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
485 #define hp_vendor_id_0 0x00 /* LSB */
486 #define ORION_VEND_0 0x4B
487
488 #define hp_vendor_id_1 0x01 /* MSB */
489 #define ORION_VEND_1 0x10
490
491 #define hp_device_id_0 0x02 /* LSB */
492 #define ORION_DEV_0 0x30
493
494 #define hp_device_id_1 0x03 /* MSB */
495 #define ORION_DEV_1 0x81
496
497 /* Sub Vendor ID and Sub Device ID only available in
498 Harpoon Version 2 and higher */
499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501
502
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
504 #define hp_semaphore 0x0C
505 #define SCCB_MGR_ACTIVE BIT(0)
506 #define TICKLE_ME BIT(1)
507 #define SCCB_MGR_PRESENT BIT(3)
508 #define BIOS_IN_USE BIT(4)
509
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 #define hp_sys_ctrl 0x0F
513
514 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
515 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
516 #define HALT_MACH BIT(3) /*Halt State Machine */
517 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800523
524
525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
527 #define hp_host_blk_cnt 0x13
528
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
530
531 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
532
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534
535 #define hp_int_mask 0x17
536
537 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
538 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540
541 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 #define hp_xfer_cnt_hi 0x1A
543 #define hp_xfer_cmd 0x1B
544
545 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
546 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548
549 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
551 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
553 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
554
555 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
556 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
558 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 #define hp_ee_ctrl 0x22
562
563 #define EXT_ARB_ACK BIT(7)
564 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
565 #define SEE_MS BIT(5)
566 #define SEE_CS BIT(3)
567 #define SEE_CLK BIT(2)
568 #define SEE_DO BIT(1)
569 #define SEE_DI BIT(0)
570
571 #define EE_READ 0x06
572 #define EE_WRITE 0x05
573 #define EWEN 0x04
574 #define EWEN_ADDR 0x03C0
575 #define EWDS 0x04
576 #define EWDS_ADDR 0x0000
577
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580
581
582
583
584 #define hp_bm_ctrl 0x26
585
586 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
587 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
589 #define FAST_SINGLE BIT(6) /*?? */
590
591 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
592
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593
594 #define hp_sg_addr 0x28
595 #define hp_page_ctrl 0x29
596
597 #define SCATTER_EN BIT(0)
598 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
600 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
605 #define hp_pci_stat_cfg 0x2D
606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
616 #define hp_rev_num 0x33
617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
619 #define hp_stack_data 0x34
620 #define hp_stack_addr 0x35
621
622 #define hp_ext_status 0x36
623
624 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
625 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
626 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 #define CMD_ABORTED BIT(4) /*Command aborted */
628 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
629 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
630 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
631 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
632 BM_PARITY_ERR | PIO_OVERRUN)
633
634 #define hp_int_status 0x37
635
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
637 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640
641 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
644
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 #define hp_intena 0x40
647
648 #define RESET BITW(7)
649 #define PROG_HLT BITW(6)
650 #define PARITY BITW(5)
651 #define FIFO BITW(4)
652 #define SEL BITW(3)
653 #define SCAM_SEL BITW(2)
654 #define RSEL BITW(1)
655 #define TIMEOUT BITW(0)
656 #define BUS_FREE BITW(15)
657 #define XFER_CNT_0 BITW(14)
658 #define PHASE BITW(13)
659 #define IUNKWN BITW(12)
660 #define ICMD_COMP BITW(11)
661 #define ITICKLE BITW(10)
662 #define IDO_STRT BITW(9)
663 #define ITAR_DISC BITW(8)
664 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
665 #define CLR_ALL_INT 0xFFFF
666 #define CLR_ALL_INT_1 0xFF00
667
668 #define hp_intstat 0x42
669
670 #define hp_scsisig 0x44
671
672 #define SCSI_SEL BIT(7)
673 #define SCSI_BSY BIT(6)
674 #define SCSI_REQ BIT(5)
675 #define SCSI_ACK BIT(4)
676 #define SCSI_ATN BIT(3)
677 #define SCSI_CD BIT(2)
678 #define SCSI_MSG BIT(1)
679 #define SCSI_IOBIT BIT(0)
680
681 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
684 #define S_DATAI_PH ( BIT(0))
685 #define S_DATAO_PH 0x00
686 #define S_ILL_PH ( BIT(1) )
687
688 #define hp_scsictrl_0 0x45
689
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 #define SEL_TAR BIT(6)
691 #define ENA_ATN BIT(4)
692 #define ENA_RESEL BIT(2)
693 #define SCSI_RST BIT(1)
694 #define ENA_SCAM_SEL BIT(0)
695
696
697
698 #define hp_portctrl_0 0x46
699
700 #define SCSI_PORT BIT(7)
701 #define SCSI_INBIT BIT(6)
702 #define DMA_PORT BIT(5)
703 #define DMA_RD BIT(4)
704 #define HOST_PORT BIT(3)
705 #define HOST_WRT BIT(2)
706 #define SCSI_BUS_EN BIT(1)
707 #define START_TO BIT(0)
708
709 #define hp_scsireset 0x47
710
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 #define SCSI_INI BIT(6)
712 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 #define DMA_RESET BIT(3)
714 #define HPSCSI_RESET BIT(2)
715 #define PROG_RESET BIT(1)
716 #define FIFO_CLR BIT(0)
717
718 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 #define hp_addstat 0x4E
723
724 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 #define SCSI_MODE8 BIT(3)
726 #define SCSI_PAR_ERR BIT(0)
727
728 #define hp_prgmcnt_0 0x4F
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 #define hp_selfid_0 0x50
732 #define hp_selfid_1 0x51
733 #define hp_arb_id 0x52
734
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
736 #define hp_select_id 0x53
737
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738
739 #define hp_synctarg_base 0x54
740 #define hp_synctarg_12 0x54
741 #define hp_synctarg_13 0x55
742 #define hp_synctarg_14 0x56
743 #define hp_synctarg_15 0x57
744
745 #define hp_synctarg_8 0x58
746 #define hp_synctarg_9 0x59
747 #define hp_synctarg_10 0x5A
748 #define hp_synctarg_11 0x5B
749
750 #define hp_synctarg_4 0x5C
751 #define hp_synctarg_5 0x5D
752 #define hp_synctarg_6 0x5E
753 #define hp_synctarg_7 0x5F
754
755 #define hp_synctarg_0 0x60
756 #define hp_synctarg_1 0x61
757 #define hp_synctarg_2 0x62
758 #define hp_synctarg_3 0x63
759
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 #define DEFAULT_OFFSET 0x0F
762
763 #define hp_autostart_0 0x64
764 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 #define hp_autostart_3 0x67
766
767
768
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 #define AUTO_IMMED BIT(5)
770 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772
773 #define hp_gp_reg_0 0x68
774 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 #define hp_gp_reg_3 0x6B
776
777 #define hp_seltimeout 0x6C
778
779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 #define TO_4ms 0x67 /* 3.9959ms */
781
782 #define TO_5ms 0x03 /* 4.9152ms */
783 #define TO_10ms 0x07 /* 11.xxxms */
784 #define TO_250ms 0x99 /* 250.68ms */
785 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
787 #define hp_clkctrl_0 0x6D
788
789 #define PWR_DWN BIT(6)
790 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792
793 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
794
795 #define hp_fiforead 0x6E
796 #define hp_fifowrite 0x6F
797
798 #define hp_offsetctr 0x70
799 #define hp_xferstat 0x71
800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 #define hp_portctrl_1 0x72
804
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 #define CHK_SCSI_P BIT(3)
806 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807
808 #define hp_xfer_pad 0x73
809
810 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 #define hp_scsidata_0 0x74
813 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816
817 #define hp_aramBase 0x80
818 #define BIOS_DATA_OFFSET 0x60
819 #define BIOS_RELATIVE_CARD 0x64
820
821
822
823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 #define AR3 (BITW(9) + BITW(8))
825 #define SDATA BITW(10)
826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
829
830 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
834 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
835
836 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
837
838
839 #define ADATA_OUT 0x00
840 #define ADATA_IN BITW(8)
841 #define ACOMMAND BITW(10)
842 #define ASTATUS (BITW(10)+BITW(8))
843 #define AMSG_OUT (BITW(10)+BITW(9))
844 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845
846
847 #define BRH_OP BITW(13) /* Branch */
848
849
850 #define ALWAYS 0x00
851 #define EQUAL BITW(8)
852 #define NOT_EQ BITW(9)
853
854 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
855
856
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
859
860 #define MPM_OP BITW(15) /* Match phase and move data */
861
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862
863 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
864
865
866 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
867
868
869 #define D_AR0 0x00
870 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
872
873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
880
881 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
882
883 #define SSI_OP (BITW(15)+BITW(11))
884
885
886 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
887 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
889 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
890 #define SSI_ITICKLE (ITICKLE >> 8)
891
892 #define SSI_IUNKWN (IUNKWN >> 8)
893 #define SSI_INO_CC (IUNKWN >> 8)
894 #define SSI_IRFAIL (IUNKWN >> 8)
895
896
897 #define NP 0x10 /*Next Phase */
898 #define NTCMD 0x02 /*Non- Tagged Command start */
899 #define CMDPZ 0x04 /*Command phase */
900 #define DINT 0x12 /*Data Out/In interrupt */
901 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 #define DC 0x19 /*Disconnect Message */
903 #define ST 0x1D /*Status Phase */
904 #define UNKNWN 0x24 /*Unknown bus action */
905 #define CC 0x25 /*Command Completion failure */
906 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
908
909
910 #define ID_MSG_STRT hp_aramBase + 0x00
911 #define NON_TAG_ID_MSG hp_aramBase + 0x06
912 #define CMD_STRT hp_aramBase + 0x08
913 #define SYNC_MSGS hp_aramBase + 0x08
914
915
916
917
918
919 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 #define DISCONNECT_START 0x10/2
921 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 #define SELCHK_STRT SELCHK/2
924
925
926
927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
929
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800931
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932
933#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
934/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
935 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800936 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800938#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 -0700939 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800940 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800942 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 count >>= 16,\
944 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
946#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
947 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
948
949
950#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
951 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
952
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
955#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
956 WR_HARPOON(port+hp_scsireset, 0x00))
957
958#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
959 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
960
961#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
962 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
963
964#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
965 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
966
967#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
968 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
969
970
971
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800973static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
974static void FPT_ssel(unsigned long port, unsigned char p_card);
975static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
976static void FPT_shandem(unsigned long port, unsigned char p_card,PSCCB pCurrSCCB);
977static void FPT_stsyncn(unsigned long port, unsigned char p_card);
978static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
979static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500980 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800981static void FPT_sresb(unsigned long port, unsigned char p_card);
982static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
983static void FPT_schkdd(unsigned long port, unsigned char p_card);
984static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
985static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
986static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800988static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800989static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
990 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800992static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -0500993static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800995static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
996static void FPT_stwidn(unsigned long port, unsigned char p_card);
997static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
999
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001000static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1001static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001002static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001003 unsigned char p_card);
1004static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1005static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1006static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1007static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -05001008static void FPT_utilUpdateResidual(PSCCB p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001009static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001010static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011
1012
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001013static void FPT_Wait1Second(unsigned long p_port);
1014static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1015static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1016static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1017static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1018static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1019static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
1021
1022
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001023static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1024static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1025static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1026static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1027static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1028static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1029static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001031static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1032static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1033static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034
1035
1036
1037
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001038static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1039static void FPT_BusMasterInit(unsigned long p_port);
1040static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
1042
1043
1044
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001045static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1046static void FPT_busMstrSGDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1047static void FPT_busMstrDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1048static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB);
James Bottomley 47b5d692005-04-24 02:38:05 -05001049static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001052static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001053 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
James Bottomley 47b5d692005-04-24 02:38:05 -05001055static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001056static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1057static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059
1060
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001061static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001063static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1064static void FPT_scbusf(unsigned long p_port);
1065static void FPT_scsel(unsigned long p_port);
1066static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1067static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1068static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1069static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1070static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1071static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001072static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001073static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1074static void FPT_scwtsel(unsigned long p_port);
1075static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1076static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001077static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
1079
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001080static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1081static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
1083
1084
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
James Bottomley 47b5d692005-04-24 02:38:05 -05001086static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1087static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1088static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1089static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090
1091
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001092static unsigned char FPT_mbCards = 0;
1093static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001094 ' ', 'B', 'T', '-', '9', '3', '0', \
1095 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1096 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001098static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
1100
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001101static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
1104/*---------------------------------------------------------------------
1105 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001106 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 *
1108 * Description: Setup and/or Search for cards and return info to caller.
1109 *
1110 *---------------------------------------------------------------------*/
1111
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001112static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001114 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001116 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001117 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001118 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 PNVRamInfo pCurrNvRam;
1120
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122
1123
1124 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1125 return((int)FAILURE);
1126
1127 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1128 return((int)FAILURE);
1129
1130 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1131 return((int)FAILURE);
1132
1133 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1134 return((int)FAILURE);
1135
1136
1137 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1138
1139/* For new Harpoon then check for sub_device ID LSB
1140 the bits(0-3) must be all ZERO for compatible with
1141 current version of SCCBMgr, else skip this Harpoon
1142 device. */
1143
1144 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1145 return((int)FAILURE);
1146 }
1147
1148 if (first_time)
1149 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001150 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001152 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 }
1154
James Bottomley 47b5d692005-04-24 02:38:05 -05001155 if(FPT_RdStack(ioport, 0) != 0x00) {
1156 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 {
1158 pCurrNvRam = NULL;
1159 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001160 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1161 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 }
1163 else
1164 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001165 if(FPT_mbCards < MAX_MB_CARDS) {
1166 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1167 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001169 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 }else
1171 return((int) FAILURE);
1172 }
1173 }else
1174 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175
1176 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1177 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1178
1179 if(pCurrNvRam)
1180 pCardInfo->si_id = pCurrNvRam->niAdapId;
1181 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001182 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1183 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 pCardInfo->si_lun = 0x00;
1186 pCardInfo->si_fw_revision = ORION_FW_REV;
1187 temp2 = 0x0000;
1188 temp3 = 0x0000;
1189 temp4 = 0x0000;
1190 temp5 = 0x0000;
1191 temp6 = 0x0000;
1192
1193 for (id = 0; id < (16/2); id++) {
1194
1195 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001196 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1198 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1199 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001200 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
1202 for (i = 0; i < 2; temp >>=8,i++) {
1203
1204 temp2 >>= 1;
1205 temp3 >>= 1;
1206 temp4 >>= 1;
1207 temp5 >>= 1;
1208 temp6 >>= 1;
1209 switch (temp & 0x3)
1210 {
1211 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1212 temp6 |= 0x8000; /* Fall through */
1213 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1214 temp5 |= 0x8000; /* Fall through */
1215 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1216 temp2 |= 0x8000; /* Fall through */
1217 case AUTO_RATE_00: /* Asynchronous */
1218 break;
1219 }
1220
1221 if (temp & DISC_ENABLE_BIT)
1222 temp3 |= 0x8000;
1223
1224 if (temp & WIDE_NEGO_BIT)
1225 temp4 |= 0x8000;
1226
1227 }
1228 }
1229
1230 pCardInfo->si_per_targ_init_sync = temp2;
1231 pCardInfo->si_per_targ_no_disc = temp3;
1232 pCardInfo->si_per_targ_wide_nego = temp4;
1233 pCardInfo->si_per_targ_fast_nego = temp5;
1234 pCardInfo->si_per_targ_ultra_nego = temp6;
1235
1236 if(pCurrNvRam)
1237 i = pCurrNvRam->niSysConf;
1238 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001239 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
1241 if(pCurrNvRam)
1242 ScamFlg = pCurrNvRam->niScamConf;
1243 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001244 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245
1246 pCardInfo->si_flags = 0x0000;
1247
1248 if (i & 0x01)
1249 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1250
1251 if (!(i & 0x02))
1252 pCardInfo->si_flags |= SOFT_RESET;
1253
1254 if (i & 0x10)
1255 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1256
1257 if (ScamFlg & SCAM_ENABLED)
1258 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1259
1260 if (ScamFlg & SCAM_LEVEL2)
1261 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1262
1263 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1264 if (i & 0x04) {
1265 j |= SCSI_TERM_ENA_L;
1266 }
1267 WR_HARPOON(ioport+hp_bm_ctrl, j );
1268
1269 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1270 if (i & 0x08) {
1271 j |= SCSI_TERM_ENA_H;
1272 }
1273 WR_HARPOON(ioport+hp_ee_ctrl, j );
1274
1275 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1276
1277 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1278
1279 pCardInfo->si_card_family = HARPOON_FAMILY;
1280 pCardInfo->si_bustype = BUSTYPE_PCI;
1281
1282 if(pCurrNvRam){
1283 pCardInfo->si_card_model[0] = '9';
1284 switch(pCurrNvRam->niModel & 0x0f){
1285 case MODEL_LT:
1286 pCardInfo->si_card_model[1] = '3';
1287 pCardInfo->si_card_model[2] = '0';
1288 break;
1289 case MODEL_LW:
1290 pCardInfo->si_card_model[1] = '5';
1291 pCardInfo->si_card_model[2] = '0';
1292 break;
1293 case MODEL_DL:
1294 pCardInfo->si_card_model[1] = '3';
1295 pCardInfo->si_card_model[2] = '2';
1296 break;
1297 case MODEL_DW:
1298 pCardInfo->si_card_model[1] = '5';
1299 pCardInfo->si_card_model[2] = '2';
1300 break;
1301 }
1302 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001303 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001304 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001305 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001307 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1308 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 }
1310
1311 if (pCardInfo->si_card_model[1] == '3')
1312 {
1313 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1314 pCardInfo->si_flags |= LOW_BYTE_TERM;
1315 }
1316 else if (pCardInfo->si_card_model[2] == '0')
1317 {
1318 temp = RD_HARPOON(ioport+hp_xfer_pad);
1319 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1320 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1321 pCardInfo->si_flags |= LOW_BYTE_TERM;
1322 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1323 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1324 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1325 WR_HARPOON(ioport+hp_xfer_pad, temp);
1326 }
1327 else
1328 {
1329 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1330 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1331 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1332 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1333 temp3 = 0;
1334 for (i = 0; i < 8; i++)
1335 {
1336 temp3 <<= 1;
1337 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1338 temp3 |= 1;
1339 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1340 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1341 }
1342 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1343 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1344 if (!(temp3 & BIT(7)))
1345 pCardInfo->si_flags |= LOW_BYTE_TERM;
1346 if (!(temp3 & BIT(6)))
1347 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1348 }
1349
1350
1351 ARAM_ACCESS(ioport);
1352
1353 for ( i = 0; i < 4; i++ ) {
1354
1355 pCardInfo->si_XlatInfo[i] =
1356 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1357 }
1358
1359 /* return with -1 if no sort, else return with
1360 logical card number sorted by BIOS (zero-based) */
1361
1362 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001363 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
1365 SGRAM_ACCESS(ioport);
1366
James Bottomley 47b5d692005-04-24 02:38:05 -05001367 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1368 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1369 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1370 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1371 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1372 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1373 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1374 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375
1376 pCardInfo->si_present = 0x01;
1377
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 return(0);
1379}
1380
1381
1382/*---------------------------------------------------------------------
1383 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001384 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 *
1386 * Description: Setup adapter for normal operation (hard reset).
1387 *
1388 *---------------------------------------------------------------------*/
1389
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001390static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391{
1392 PSCCBcard CurrCard = NULL;
1393 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001394 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001395 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001396 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399
1400 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1401
1402 if (thisCard == MAX_CARDS) {
1403
1404 return(FAILURE);
1405 }
1406
James Bottomley 47b5d692005-04-24 02:38:05 -05001407 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
James Bottomley 47b5d692005-04-24 02:38:05 -05001409 CurrCard = &FPT_BL_Card[thisCard];
1410 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 break;
1412 }
1413
James Bottomley 47b5d692005-04-24 02:38:05 -05001414 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
James Bottomley 47b5d692005-04-24 02:38:05 -05001416 FPT_BL_Card[thisCard].ioPort = ioport;
1417 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
James Bottomley 47b5d692005-04-24 02:38:05 -05001419 if(FPT_mbCards)
1420 for(i = 0; i < FPT_mbCards; i++){
1421 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1422 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001424 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 CurrCard->cardIndex = thisCard;
1426 CurrCard->cardInfo = pCardInfo;
1427
1428 break;
1429 }
1430 }
1431
1432 pCurrNvRam = CurrCard->pNvRamInfo;
1433
1434 if(pCurrNvRam){
1435 ScamFlg = pCurrNvRam->niScamConf;
1436 }
1437 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001438 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 }
1440
1441
James Bottomley 47b5d692005-04-24 02:38:05 -05001442 FPT_BusMasterInit(ioport);
1443 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
James Bottomley 47b5d692005-04-24 02:38:05 -05001445 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
1447
1448 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1449
1450 WR_HARPOON(ioport+hp_selfid_0, id);
1451 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1452 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1453 CurrCard->ourId = pCardInfo->si_id;
1454
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001455 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 if (i & SCSI_PARITY_ENA)
1457 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1458
1459 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1460 if (i & LOW_BYTE_TERM)
1461 j |= SCSI_TERM_ENA_L;
1462 WR_HARPOON(ioport+hp_bm_ctrl, j);
1463
1464 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1465 if (i & HIGH_BYTE_TERM)
1466 j |= SCSI_TERM_ENA_H;
1467 WR_HARPOON(ioport+hp_ee_ctrl, j );
1468
1469
1470 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1471
James Bottomley 47b5d692005-04-24 02:38:05 -05001472 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
James Bottomley 47b5d692005-04-24 02:38:05 -05001474 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 }
1476
1477
1478
1479 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1480 CurrCard->globalFlags |= F_NO_FILTER;
1481
1482 if(pCurrNvRam){
1483 if(pCurrNvRam->niSysConf & 0x10)
1484 CurrCard->globalFlags |= F_GREEN_PC;
1485 }
1486 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001487 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 CurrCard->globalFlags |= F_GREEN_PC;
1489 }
1490
1491 /* Set global flag to indicate Re-Negotiation to be done on all
1492 ckeck condition */
1493 if(pCurrNvRam){
1494 if(pCurrNvRam->niScsiConf & 0x04)
1495 CurrCard->globalFlags |= F_DO_RENEGO;
1496 }
1497 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001498 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 CurrCard->globalFlags |= F_DO_RENEGO;
1500 }
1501
1502 if(pCurrNvRam){
1503 if(pCurrNvRam->niScsiConf & 0x08)
1504 CurrCard->globalFlags |= F_CONLUN_IO;
1505 }
1506 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001507 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 CurrCard->globalFlags |= F_CONLUN_IO;
1509 }
1510
1511
1512 temp = pCardInfo->si_per_targ_no_disc;
1513
1514 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1515
1516 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001517 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 }
1519
1520 sync_bit_map = 0x0001;
1521
1522 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1523
1524 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001525 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1527 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1528 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001529 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
1531 for (i = 0; i < 2; temp >>=8,i++) {
1532
1533 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1534
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001535 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 }
1537
1538 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001539 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1540 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001541 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 }
1543
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1545 (id*2+i >= 8)){
1546*/
1547 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1548
James Bottomley 47b5d692005-04-24 02:38:05 -05001549 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550
1551 }
1552
1553 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001554 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 }
1556
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 sync_bit_map <<= 1;
1559
1560
1561
1562 }
1563 }
1564
1565 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001566 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001568 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569}
1570
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001571static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001573 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001574 unsigned long portBase;
1575 unsigned long regOffset;
1576 unsigned long scamData;
1577 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 PNVRamInfo pCurrNvRam;
1579
1580 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1581
1582 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001583 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1585 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1586 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1587 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588
1589 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001590 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591
1592 portBase = pCurrNvRam->niBaseAddr;
1593
1594 for(i = 0; i < MAX_SCSI_TAR; i++){
1595 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001596 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 scamData = *pScamTbl;
1598 WR_HARP32(portBase, regOffset, scamData);
1599 }
1600
1601 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001602 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 }
1604}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
1606
James Bottomley 47b5d692005-04-24 02:38:05 -05001607static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001609 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001610 unsigned long portBase;
1611 unsigned long regOffset;
1612 unsigned long scamData;
1613 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
James Bottomley 47b5d692005-04-24 02:38:05 -05001615 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1616 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1617 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1618 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1619 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
1621 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001622 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
1624 portBase = pNvRamInfo->niBaseAddr;
1625
1626 for(i = 0; i < MAX_SCSI_TAR; i++){
1627 regOffset = hp_aramBase + 64 + i*4;
1628 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001629 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 *pScamTbl = scamData;
1631 }
1632
1633}
1634
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001635static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636{
1637 WR_HARPOON(portBase + hp_stack_addr, index);
1638 return(RD_HARPOON(portBase + hp_stack_data));
1639}
1640
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001641static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642{
1643 WR_HARPOON(portBase + hp_stack_addr, index);
1644 WR_HARPOON(portBase + hp_stack_data, data);
1645}
1646
1647
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001648static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649{
James Bottomley 47b5d692005-04-24 02:38:05 -05001650 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1651 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1653 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001654 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1656 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001657 return(1);
1658 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
1660}
1661/*---------------------------------------------------------------------
1662 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001663 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 *
1665 * Description: Start a command pointed to by p_Sccb. When the
1666 * command is completed it will be returned via the
1667 * callback function.
1668 *
1669 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001670static void FlashPoint_StartCCB(unsigned long pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001672 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001673 unsigned char thisCard, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 PSCCB pSaveSccb;
1675 CALL_BK_FN callback;
1676
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1678 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1679
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1681 {
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 p_Sccb->HostStatus = SCCB_COMPLETE;
1684 p_Sccb->SccbStatus = SCCB_ERROR;
1685 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1686 if (callback)
1687 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 return;
1690 }
1691
James Bottomley 47b5d692005-04-24 02:38:05 -05001692 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
1694
1695 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1696 {
1697 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1698 | SCCB_MGR_ACTIVE));
1699
1700 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1701 {
1702 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1703 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1704 }
1705 }
1706
1707 ((PSCCBcard)pCurrCard)->cmdCounter++;
1708
1709 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1710
1711 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1712 | TICKLE_ME));
1713 if(p_Sccb->OperationCode == RESET_COMMAND)
1714 {
1715 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1716 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001717 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1719 }
1720 else
1721 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001722 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 }
1724 }
1725
1726 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1727
1728 if(p_Sccb->OperationCode == RESET_COMMAND)
1729 {
1730 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1731 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001732 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1734 }
1735 else
1736 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001737 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 }
1739 }
1740
1741 else {
1742
1743 MDISABLE_INT(ioport);
1744
1745 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001746 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 lun = p_Sccb->Lun;
1748 else
1749 lun = 0;
1750 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001751 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1752 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1753 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754
1755 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001756 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 }
1758
1759 else {
1760
1761 if(p_Sccb->OperationCode == RESET_COMMAND)
1762 {
1763 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1764 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001765 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1767 }
1768 else
1769 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001770 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 }
1772 }
1773
1774
1775 MENABLE_INT(ioport);
1776 }
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778}
1779
1780
1781/*---------------------------------------------------------------------
1782 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001783 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 *
1785 * Description: Abort the command pointed to by p_Sccb. When the
1786 * command is completed it will be returned via the
1787 * callback function.
1788 *
1789 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001790static int FlashPoint_AbortCCB(unsigned long pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001792 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001794 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001796 unsigned char TID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 PSCCB pSaveSCCB;
1798 PSCCBMgr_tar_info currTar_Info;
1799
1800
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1802
1803 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1804
James Bottomley 47b5d692005-04-24 02:38:05 -05001805 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 {
1807
James Bottomley 47b5d692005-04-24 02:38:05 -05001808 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 {
1810
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 ((PSCCBcard)pCurrCard)->cmdCounter--;
1812
1813 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1814 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001815 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 p_Sccb->SccbStatus = SCCB_ABORT;
1818 callback = p_Sccb->SccbCallback;
1819 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 return(0);
1822 }
1823
1824 else
1825 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1827 {
1828 p_Sccb->SccbStatus = SCCB_ABORT;
1829 return(0);
1830
1831 }
1832
1833 else
1834 {
1835
1836 TID = p_Sccb->TargID;
1837
1838
1839 if(p_Sccb->Sccb_tag)
1840 {
1841 MDISABLE_INT(ioport);
1842 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1843 {
1844 p_Sccb->SccbStatus = SCCB_ABORT;
1845 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1847
1848 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1849 {
1850 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001851 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 }
1853 else
1854 {
1855 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1856 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001857 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1859 }
1860 }
1861 MENABLE_INT(ioport);
1862 return(0);
1863 }
1864 else
1865 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001866 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
James Bottomley 47b5d692005-04-24 02:38:05 -05001868 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 == p_Sccb)
1870 {
1871 p_Sccb->SccbStatus = SCCB_ABORT;
1872 return(0);
1873 }
1874 }
1875 }
1876 }
1877 }
1878 return(-1);
1879}
1880
1881
1882/*---------------------------------------------------------------------
1883 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001884 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 *
1886 * Description: Do a quick check to determine if there is a pending
1887 * interrupt for this card and disable the IRQ Pin if so.
1888 *
1889 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001890static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001892 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
1894 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1895
1896 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1897 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001898 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 }
1900
1901 else
1902
James Bottomley 47b5d692005-04-24 02:38:05 -05001903 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904}
1905
1906
1907
1908/*---------------------------------------------------------------------
1909 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001910 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 *
1912 * Description: This is our entry point when an interrupt is generated
1913 * by the card and the upper level driver passes it on to
1914 * us.
1915 *
1916 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001917static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918{
1919 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001920 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001921 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001922 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001923 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
1925 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1926 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1927
1928 MDISABLE_INT(ioport);
1929
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001931 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 else
1933 bm_status = 0;
1934
1935 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1936
James Bottomley 47b5d692005-04-24 02:38:05 -05001937 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 bm_status)
1939 {
1940
1941 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1942
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001944 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1946 bm_status = 0;
1947
1948 if (result) {
1949
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 return(result);
1952 }
1953 }
1954
1955
1956 else if (hp_int & ICMD_COMP) {
1957
1958 if ( !(hp_int & BUS_FREE) ) {
1959 /* Wait for the BusFree before starting a new command. We
1960 must also check for being reselected since the BusFree
1961 may not show up if another device reselects us in 1.5us or
1962 less. SRR Wednesday, 3/8/1995.
1963 */
1964 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1965 }
1966
1967 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1968
James Bottomley 47b5d692005-04-24 02:38:05 -05001969 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970
1971/* WRW_HARPOON((ioport+hp_intstat),
1972 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1973 */
1974
1975 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1976
James Bottomley 47b5d692005-04-24 02:38:05 -05001977 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
1979 }
1980
1981
1982 else if (hp_int & ITAR_DISC)
1983 {
1984
1985 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1986
James Bottomley 47b5d692005-04-24 02:38:05 -05001987 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
1989 }
1990
1991 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1992
1993 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1994 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1995
1996 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1997 }
1998
1999 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002000 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001
2002 /* Wait for the BusFree before starting a new command. We
2003 must also check for being reselected since the BusFree
2004 may not show up if another device reselects us in 1.5us or
2005 less. SRR Wednesday, 3/8/1995.
2006 */
2007 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2008 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2009 RD_HARPOON((ioport+hp_scsisig)) ==
2010 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2011
2012 /*
2013 The additional loop exit condition above detects a timing problem
2014 with the revision D/E harpoon chips. The caller should reset the
2015 host adapter to recover when 0xFE is returned.
2016 */
2017 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2018 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 return 0xFE;
2021 }
2022
2023 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2024
2025
2026 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2027
2028 }
2029
2030
2031 else if (hp_int & RSEL) {
2032
2033 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2034
2035 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2036 {
2037 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2038 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002039 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040 }
2041
2042 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2043 {
2044 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2045 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2046 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2047 }
2048
2049 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2050 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002051 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052 }
2053
James Bottomley 47b5d692005-04-24 02:38:05 -05002054 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2055 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056
2057 }
2058
2059
2060 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2061 {
2062
2063 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002064 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065
2066 }
2067
2068
2069 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2070 {
2071 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002072 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002074 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 }
2076 else
2077 {
2078 /* Harpoon problem some SCSI target device respond to selection
2079 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2080 to latch the correct Target ID into reg. x53.
2081 The work around require to correct this reg. But when write to this
2082 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2083 need to read this reg first then restore it later. After update to 0x53 */
2084
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002085 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2086 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2087 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2088 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2089 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 WR_HARPOON(ioport+hp_fifowrite, i);
2091 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2092 }
2093 }
2094
2095 else if (hp_int & XFER_CNT_0) {
2096
2097 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2098
James Bottomley 47b5d692005-04-24 02:38:05 -05002099 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
2101 }
2102
2103
2104 else if (hp_int & BUS_FREE) {
2105
2106 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2107
2108 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2109
James Bottomley 47b5d692005-04-24 02:38:05 -05002110 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 }
2112
James Bottomley 47b5d692005-04-24 02:38:05 -05002113 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114 }
2115
2116
2117 else if (hp_int & ITICKLE) {
2118
2119 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2120 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2121 }
2122
2123
2124
2125 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2126
2127
2128 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2129
2130
2131 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2132
James Bottomley 47b5d692005-04-24 02:38:05 -05002133 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134 }
2135
2136 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2137 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002138 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 }
2140
2141 break;
2142
2143 }
2144
2145 } /*end while */
2146
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148
2149 return(0);
2150}
2151
2152/*---------------------------------------------------------------------
2153 *
2154 * Function: Sccb_bad_isr
2155 *
2156 * Description: Some type of interrupt has occurred which is slightly
2157 * out of the ordinary. We will now decode it fully, in
2158 * this routine. This is broken up in an attempt to save
2159 * processing time.
2160 *
2161 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002162static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002163 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002165 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002166 PSCCBMgr_tar_info currTar_Info;
2167 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168
2169
2170 if (RD_HARPOON(p_port+hp_ext_status) &
2171 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2172 {
2173
2174 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2175 {
2176
James Bottomley 47b5d692005-04-24 02:38:05 -05002177 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178 }
2179
2180 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2181
2182 {
2183 WR_HARPOON(p_port+hp_pci_stat_cfg,
2184 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2185
2186 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2187
2188 }
2189
2190 if (pCurrCard->currentSCCB != NULL)
2191 {
2192
2193 if (!pCurrCard->currentSCCB->HostStatus)
2194 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2195
James Bottomley 47b5d692005-04-24 02:38:05 -05002196 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002198 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002200 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2202
2203 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2204 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002205 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 }
2207 }
2208 }
2209
2210
2211 else if (p_int & RESET)
2212 {
2213
2214 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2215 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2216 if (pCurrCard->currentSCCB != NULL) {
2217
2218 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2219
James Bottomley 47b5d692005-04-24 02:38:05 -05002220 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 }
2222
2223
2224 DISABLE_AUTO(p_port);
2225
James Bottomley 47b5d692005-04-24 02:38:05 -05002226 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227
2228 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2229
2230 pCurrNvRam = pCurrCard->pNvRamInfo;
2231 if(pCurrNvRam){
2232 ScamFlg = pCurrNvRam->niScamConf;
2233 }
2234 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002235 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 }
2237
James Bottomley 47b5d692005-04-24 02:38:05 -05002238 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239
James Bottomley 47b5d692005-04-24 02:38:05 -05002240 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241
2242 return(0xFF);
2243 }
2244
2245
2246 else if (p_int & FIFO) {
2247
2248 WRW_HARPOON((p_port+hp_intstat), FIFO);
2249
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002251 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 }
2253
2254 else if (p_int & TIMEOUT)
2255 {
2256
2257 DISABLE_AUTO(p_port);
2258
2259 WRW_HARPOON((p_port+hp_intstat),
2260 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2261
2262 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2263
2264
James Bottomley 47b5d692005-04-24 02:38:05 -05002265 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2267 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002268 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002270 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271
2272
2273 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2274 {
2275 currTar_Info->TarSyncCtrl = 0;
2276 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2277 }
2278
2279 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2280 {
2281 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2282 }
2283
James Bottomley 47b5d692005-04-24 02:38:05 -05002284 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285
James Bottomley 47b5d692005-04-24 02:38:05 -05002286 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287
2288 }
2289
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 else if (p_int & SCAM_SEL)
2291 {
2292
James Bottomley 47b5d692005-04-24 02:38:05 -05002293 FPT_scarb(p_port,LEVEL2_TAR);
2294 FPT_scsel(p_port);
2295 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
James Bottomley 47b5d692005-04-24 02:38:05 -05002297 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
2299 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2300 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301
2302 return(0x00);
2303}
2304
2305
2306/*---------------------------------------------------------------------
2307 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 * Function: SccbMgrTableInit
2309 *
2310 * Description: Initialize all Sccb manager data structures.
2311 *
2312 *---------------------------------------------------------------------*/
2313
James Bottomley 47b5d692005-04-24 02:38:05 -05002314static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002316 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317
2318 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2319 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002320 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321
James Bottomley 47b5d692005-04-24 02:38:05 -05002322 FPT_BL_Card[thisCard].ioPort = 0x00;
2323 FPT_BL_Card[thisCard].cardInfo = NULL;
2324 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2325 FPT_BL_Card[thisCard].ourId = 0x00;
2326 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 }
2328}
2329
2330
2331/*---------------------------------------------------------------------
2332 *
2333 * Function: SccbMgrTableInit
2334 *
2335 * Description: Initialize all Sccb manager data structures.
2336 *
2337 *---------------------------------------------------------------------*/
2338
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002339static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002341 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342
2343 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2344 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002345 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346 }
2347
2348 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2349 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002350 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2351 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2352 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353 }
2354
2355 pCurrCard->scanIndex = 0x00;
2356 pCurrCard->currentSCCB = NULL;
2357 pCurrCard->globalFlags = 0x00;
2358 pCurrCard->cmdCounter = 0x00;
2359 pCurrCard->tagQ_Lst = 0x01;
2360 pCurrCard->discQCount = 0;
2361
2362
2363}
2364
2365
2366/*---------------------------------------------------------------------
2367 *
2368 * Function: SccbMgrTableInit
2369 *
2370 * Description: Initialize all Sccb manager data structures.
2371 *
2372 *---------------------------------------------------------------------*/
2373
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002374static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375{
2376
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002377 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 PSCCBMgr_tar_info currTar_Info;
2379
James Bottomley 47b5d692005-04-24 02:38:05 -05002380 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002381
2382 currTar_Info->TarSelQ_Cnt = 0;
2383 currTar_Info->TarSyncCtrl = 0;
2384
2385 currTar_Info->TarSelQ_Head = NULL;
2386 currTar_Info->TarSelQ_Tail = NULL;
2387 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002388 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
2390
2391 for (lun = 0; lun < MAX_LUN; lun++)
2392 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002393 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 currTar_Info->LunDiscQ_Idx[lun] = 0;
2395 }
2396
2397 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2398 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002399 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002401 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002403 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2404 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 }
2406 }
2407 }
2408}
2409
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410
2411/*---------------------------------------------------------------------
2412 *
2413 * Function: sfetm
2414 *
2415 * Description: Read in a message byte from the SCSI bus, and check
2416 * for a parity error.
2417 *
2418 *---------------------------------------------------------------------*/
2419
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002420static unsigned char FPT_sfm(unsigned long port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002422 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002423 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424
2425 TimeOutLoop = 0;
2426 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2427 (TimeOutLoop++ < 20000) ){}
2428
2429
2430 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2431
2432 message = RD_HARPOON(port+hp_scsidata_0);
2433
2434 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2435
2436
2437 if (TimeOutLoop > 20000)
2438 message = 0x00; /* force message byte = 0 if Time Out on Req */
2439
2440 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2441 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2442 {
2443 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2444 WR_HARPOON(port+hp_xferstat, 0);
2445 WR_HARPOON(port+hp_fiforead, 0);
2446 WR_HARPOON(port+hp_fifowrite, 0);
2447 if (pCurrSCCB != NULL)
2448 {
2449 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2450 }
2451 message = 0x00;
2452 do
2453 {
2454 ACCEPT_MSG_ATN(port);
2455 TimeOutLoop = 0;
2456 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2457 (TimeOutLoop++ < 20000) ){}
2458 if (TimeOutLoop > 20000)
2459 {
2460 WRW_HARPOON((port+hp_intstat), PARITY);
2461 return(message);
2462 }
2463 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2464 {
2465 WRW_HARPOON((port+hp_intstat), PARITY);
2466 return(message);
2467 }
2468 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2469
2470 RD_HARPOON(port+hp_scsidata_0);
2471
2472 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2473
2474 }while(1);
2475
2476 }
2477 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2478 WR_HARPOON(port+hp_xferstat, 0);
2479 WR_HARPOON(port+hp_fiforead, 0);
2480 WR_HARPOON(port+hp_fifowrite, 0);
2481 return(message);
2482}
2483
2484
2485/*---------------------------------------------------------------------
2486 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002487 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 *
2489 * Description: Load up automation and select target device.
2490 *
2491 *---------------------------------------------------------------------*/
2492
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002493static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494{
2495
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002496 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002498 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 PSCCBcard CurrCard;
2500 PSCCB currSCCB;
2501 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002502 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503
James Bottomley 47b5d692005-04-24 02:38:05 -05002504 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 currSCCB = CurrCard->currentSCCB;
2506 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002507 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 lastTag = CurrCard->tagQ_Lst;
2509
2510 ARAM_ACCESS(port);
2511
2512
2513 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2514 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2515
2516 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2517 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2518
2519 lun = currSCCB->Lun;
2520 else
2521 lun = 0;
2522
2523
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524 if (CurrCard->globalFlags & F_TAG_STARTED)
2525 {
2526 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2527 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002528 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2530 == TAG_Q_TRYING))
2531 {
2532
2533 if (currTar_Info->TarTagQ_Cnt !=0)
2534 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002535 currTar_Info->TarLUNBusy[lun] = 1;
2536 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 SGRAM_ACCESS(port);
2538 return;
2539 }
2540
2541 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002542 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 }
2544
2545 } /*End non-tagged */
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 } /*!Use cmd Q Tagged */
2552
2553 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002554 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002556 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 SGRAM_ACCESS(port);
2558 return;
2559 }
2560
James Bottomley 47b5d692005-04-24 02:38:05 -05002561 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
2563 } /*else use cmd Q tagged */
2564
2565 } /*if glob tagged started */
2566
2567 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002568 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 }
2570
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
2572
2573 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2574 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2575 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2576 {
2577 if(CurrCard->discQCount >= QUEUE_DEPTH)
2578 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002579 currTar_Info->TarLUNBusy[lun] = 1;
2580 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581 SGRAM_ACCESS(port);
2582 return;
2583 }
2584 for (i = 1; i < QUEUE_DEPTH; i++)
2585 {
2586 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2587 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2588 {
2589 CurrCard->tagQ_Lst = lastTag;
2590 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2591 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2592 CurrCard->discQCount++;
2593 break;
2594 }
2595 }
2596 if(i == QUEUE_DEPTH)
2597 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002598 currTar_Info->TarLUNBusy[lun] = 1;
2599 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 SGRAM_ACCESS(port);
2601 return;
2602 }
2603 }
2604
2605
2606
James Bottomley 47b5d692005-04-24 02:38:05 -05002607 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608
2609 WR_HARPOON(port+hp_select_id, target);
2610 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2611
2612 if (currSCCB->OperationCode == RESET_COMMAND) {
2613 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2614 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2615
2616 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2617
2618 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2619
2620 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002621 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2623
2624 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2625 {
2626 currTar_Info->TarSyncCtrl = 0;
2627 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2628 }
2629
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2631 {
2632 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2633 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634
James Bottomley 47b5d692005-04-24 02:38:05 -05002635 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2636 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637
2638 }
2639
2640 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2641 {
2642 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2643 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2644
2645 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2646
2647 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002648 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2649 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 WRW_HARPOON((port+SYNC_MSGS+2),
2651 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2652 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2653
2654 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002655 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656
2657 }
2658
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002660 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2662 }
2663
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2665 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002666 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2668 }
2669
2670
2671 if (!auto_loaded)
2672 {
2673
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674 if (currSCCB->ControlByte & F_USE_CMD_Q)
2675 {
2676
2677 CurrCard->globalFlags |= F_TAG_STARTED;
2678
2679 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2680 == TAG_Q_REJECT)
2681 {
2682 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2683
2684 /* Fix up the start instruction with a jump to
2685 Non-Tag-CMD handling */
2686 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2687
2688 WRW_HARPOON((port+NON_TAG_ID_MSG),
2689 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2690
2691 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2692
2693 /* Setup our STATE so we know what happend when
2694 the wheels fall off. */
2695 currSCCB->Sccb_scsistat = SELECT_ST;
2696
James Bottomley 47b5d692005-04-24 02:38:05 -05002697 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 }
2699
2700 else
2701 {
2702 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2703
2704 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002705 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2706 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707
2708 for (i = 1; i < QUEUE_DEPTH; i++)
2709 {
2710 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2711 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2712 {
2713 WRW_HARPOON((port+ID_MSG_STRT+6),
2714 (MPM_OP+AMSG_OUT+lastTag));
2715 CurrCard->tagQ_Lst = lastTag;
2716 currSCCB->Sccb_tag = lastTag;
2717 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2718 CurrCard->discQCount++;
2719 break;
2720 }
2721 }
2722
2723
2724 if ( i == QUEUE_DEPTH )
2725 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002726 currTar_Info->TarLUNBusy[lun] = 1;
2727 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 SGRAM_ACCESS(port);
2729 return;
2730 }
2731
2732 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2733
2734 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2735 }
2736 }
2737
2738 else
2739 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740
2741 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2742
2743 WRW_HARPOON((port+NON_TAG_ID_MSG),
2744 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2745
2746 currSCCB->Sccb_scsistat = SELECT_ST;
2747
2748 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
2751
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002752 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753
2754 cdb_reg = port + CMD_STRT;
2755
2756 for (i=0; i < currSCCB->CdbLength; i++)
2757 {
2758 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2759 cdb_reg +=2;
2760 theCCB++;
2761 }
2762
2763 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2764 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2765
2766 } /* auto_loaded */
2767
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002768 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770
2771 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2772
2773 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2774
2775
2776 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2777 {
2778 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2779 }
2780 else
2781 {
2782
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002783/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 auto_loaded |= AUTO_IMMED; */
2785 auto_loaded = AUTO_IMMED;
2786
2787 DISABLE_AUTO(port);
2788
2789 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2790 }
2791
2792 SGRAM_ACCESS(port);
2793}
2794
2795
2796/*---------------------------------------------------------------------
2797 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002798 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799 *
2800 * Description: Hookup the correct CCB and handle the incoming messages.
2801 *
2802 *---------------------------------------------------------------------*/
2803
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002804static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805{
2806
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002807 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808
2809
2810 PSCCBMgr_tar_info currTar_Info;
2811 PSCCB currSCCB;
2812
2813
2814
2815
2816 if(pCurrCard->currentSCCB != NULL)
2817 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002818 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 DISABLE_AUTO(port);
2820
2821
2822 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2823
2824
2825 currSCCB = pCurrCard->currentSCCB;
2826 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2827 {
2828 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2829 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2830 }
2831 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2832 {
2833 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2834 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2835 }
2836 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2837 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2838 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002839 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 if(currSCCB->Sccb_scsistat != ABORT_ST)
2841 {
2842 pCurrCard->discQCount--;
2843 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2844 = NULL;
2845 }
2846 }
2847 else
2848 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002849 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 if(currSCCB->Sccb_tag)
2851 {
2852 if(currSCCB->Sccb_scsistat != ABORT_ST)
2853 {
2854 pCurrCard->discQCount--;
2855 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2856 }
2857 }else
2858 {
2859 if(currSCCB->Sccb_scsistat != ABORT_ST)
2860 {
2861 pCurrCard->discQCount--;
2862 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2863 }
2864 }
2865 }
2866
James Bottomley 47b5d692005-04-24 02:38:05 -05002867 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 }
2869
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002870 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
2872
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002873 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002874 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
2876
2877 msgRetryCount = 0;
2878 do
2879 {
2880
James Bottomley 47b5d692005-04-24 02:38:05 -05002881 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882 tag = 0;
2883
2884
2885 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2886 {
2887 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2888 {
2889
2890 WRW_HARPOON((port+hp_intstat), PHASE);
2891 return;
2892 }
2893 }
2894
2895 WRW_HARPOON((port+hp_intstat), PHASE);
2896 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2897 {
2898
James Bottomley 47b5d692005-04-24 02:38:05 -05002899 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 if (message)
2901 {
2902
2903 if (message <= (0x80 | LUN_MASK))
2904 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002905 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2908 {
2909 if (currTar_Info->TarTagQ_Cnt != 0)
2910 {
2911
2912 if (!(currTar_Info->TarLUN_CA))
2913 {
2914 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2915
2916
James Bottomley 47b5d692005-04-24 02:38:05 -05002917 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 if (message)
2919 {
2920 ACCEPT_MSG(port);
2921 }
2922
2923 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002924 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
James Bottomley 47b5d692005-04-24 02:38:05 -05002926 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002928 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929
2930 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002931 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 }
2933
2934 } /*C.A. exists! */
2935
2936 } /*End Q cnt != 0 */
2937
2938 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939
2940 } /*End valid ID message. */
2941
2942 else
2943 {
2944
2945 ACCEPT_MSG_ATN(port);
2946 }
2947
2948 } /* End good id message. */
2949
2950 else
2951 {
2952
James Bottomley 47b5d692005-04-24 02:38:05 -05002953 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 }
2955 }
2956 else
2957 {
2958 ACCEPT_MSG_ATN(port);
2959
2960 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2961 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2962 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2963
2964 return;
2965 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966
James Bottomley 47b5d692005-04-24 02:38:05 -05002967 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 {
2969 msgRetryCount++;
2970 if(msgRetryCount == 1)
2971 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002972 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973 }
2974 else
2975 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002976 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977
James Bottomley 47b5d692005-04-24 02:38:05 -05002978 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979
James Bottomley 47b5d692005-04-24 02:38:05 -05002980 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 {
2982
James Bottomley 47b5d692005-04-24 02:38:05 -05002983 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984
2985 }
2986
James Bottomley 47b5d692005-04-24 02:38:05 -05002987 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 {
2989
James Bottomley 47b5d692005-04-24 02:38:05 -05002990 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991 }
2992
2993
James Bottomley 47b5d692005-04-24 02:38:05 -05002994 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2995 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996 return;
2997 }
2998 }
James Bottomley 47b5d692005-04-24 02:38:05 -05002999 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000
3001
3002
3003 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3004 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3005 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003006 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3008 if(pCurrCard->currentSCCB != NULL)
3009 {
3010 ACCEPT_MSG(port);
3011 }
3012 else
3013 {
3014 ACCEPT_MSG_ATN(port);
3015 }
3016 }
3017 else
3018 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003019 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020
3021
3022 if (tag)
3023 {
3024 if (pCurrCard->discQ_Tbl[tag] != NULL)
3025 {
3026 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3027 currTar_Info->TarTagQ_Cnt--;
3028 ACCEPT_MSG(port);
3029 }
3030 else
3031 {
3032 ACCEPT_MSG_ATN(port);
3033 }
3034 }else
3035 {
3036 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3037 if(pCurrCard->currentSCCB != NULL)
3038 {
3039 ACCEPT_MSG(port);
3040 }
3041 else
3042 {
3043 ACCEPT_MSG_ATN(port);
3044 }
3045 }
3046 }
3047
3048 if(pCurrCard->currentSCCB != NULL)
3049 {
3050 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3051 {
3052 /* During Abort Tag command, the target could have got re-selected
3053 and completed the command. Check the select Q and remove the CCB
3054 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003055 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056 }
3057 }
3058
3059
3060 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3061 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3062 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3063}
3064
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003065static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066{
3067 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3068 {
3069 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3070 {
3071
3072 WRW_HARPOON((port+hp_intstat), PHASE);
3073 return;
3074 }
3075 }
3076
3077 WRW_HARPOON((port+hp_intstat), PHASE);
3078 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3079 {
3080 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3081
3082
3083 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3084
3085 WR_HARPOON(port+hp_scsidata_0,message);
3086
3087 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3088
3089 ACCEPT_MSG(port);
3090
3091 WR_HARPOON(port+hp_portctrl_0, 0x00);
3092
3093 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3094 (message == SMABORT_TAG) )
3095 {
3096 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3097
3098 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3099 {
3100 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3101 }
3102 }
3103 }
3104}
3105
3106/*---------------------------------------------------------------------
3107 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003108 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 *
3110 * Description: Determine the proper responce to the message from the
3111 * target device.
3112 *
3113 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003114static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115{
3116 PSCCB currSCCB;
3117 PSCCBcard CurrCard;
3118 PSCCBMgr_tar_info currTar_Info;
3119
James Bottomley 47b5d692005-04-24 02:38:05 -05003120 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121 currSCCB = CurrCard->currentSCCB;
3122
James Bottomley 47b5d692005-04-24 02:38:05 -05003123 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124
3125 if (message == SMREST_DATA_PTR)
3126 {
3127 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3128 {
3129 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3130
James Bottomley 47b5d692005-04-24 02:38:05 -05003131 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132 }
3133
3134 ACCEPT_MSG(port);
3135 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3136 }
3137
3138 else if (message == SMCMD_COMP)
3139 {
3140
3141
3142 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3143 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003144 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3145 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146 }
3147
3148 ACCEPT_MSG(port);
3149
3150 }
3151
3152 else if ((message == SMNO_OP) || (message >= SMIDENT)
3153 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3154 {
3155
3156 ACCEPT_MSG(port);
3157 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3158 }
3159
3160 else if (message == SMREJECT)
3161 {
3162
3163 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3164 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3165 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3166 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3167
3168 {
3169 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3170
3171 ACCEPT_MSG(port);
3172
3173
3174 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3175 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3176
3177 if(currSCCB->Lun == 0x00)
3178 {
3179 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3180 {
3181
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003182 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183
3184 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3185 }
3186
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3188 {
3189
3190
3191 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3192 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3193
3194 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3195
3196 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197
3198 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3199 {
3200 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003201 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003202
3203
3204 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3205 CurrCard->discQCount--;
3206 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3207 currSCCB->Sccb_tag = 0x00;
3208
3209 }
3210 }
3211
3212 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3213 {
3214
3215
3216 if(currSCCB->Lun == 0x00)
3217 {
3218 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3219 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3220 }
3221 }
3222
3223 else
3224 {
3225
3226 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3227 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003228 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003230 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231
3232
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003233 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003234
3235 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3236
3237 }
3238 }
3239
3240 else
3241 {
3242 ACCEPT_MSG(port);
3243
3244 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3245 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3246
3247 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3248 {
3249 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3250 }
3251 }
3252 }
3253
3254 else if (message == SMEXT)
3255 {
3256
3257 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003258 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003259 }
3260
3261 else if (message == SMIGNORWR)
3262 {
3263
3264 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3265
James Bottomley 47b5d692005-04-24 02:38:05 -05003266 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003267
3268 if(currSCCB->Sccb_scsimsg != SMPARITY)
3269 ACCEPT_MSG(port);
3270 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3271 }
3272
3273
3274 else
3275 {
3276
3277 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3278 currSCCB->Sccb_scsimsg = SMREJECT;
3279
3280 ACCEPT_MSG_ATN(port);
3281 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3282 }
3283}
3284
3285
3286/*---------------------------------------------------------------------
3287 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003288 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003289 *
3290 * Description: Decide what to do with the extended message.
3291 *
3292 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003293static void FPT_shandem(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003295 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296
James Bottomley 47b5d692005-04-24 02:38:05 -05003297 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298 if (length)
3299 {
3300
3301 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003302 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003303 if (message)
3304 {
3305
3306 if (message == SMSYNC)
3307 {
3308
3309 if (length == 0x03)
3310 {
3311
3312 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003313 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003314 }
3315 else
3316 {
3317
3318 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3319 ACCEPT_MSG_ATN(port);
3320 }
3321 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003322 else if (message == SMWDTR)
3323 {
3324
3325 if (length == 0x02)
3326 {
3327
3328 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003329 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330 }
3331 else
3332 {
3333
3334 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3335 ACCEPT_MSG_ATN(port);
3336
3337 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3338 }
3339 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003340 else
3341 {
3342
3343 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3344 ACCEPT_MSG_ATN(port);
3345
3346 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3347 }
3348 }
3349 else
3350 {
3351 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3352 ACCEPT_MSG(port);
3353 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3354 }
3355 }else
3356 {
3357 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3358 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3359 }
3360}
3361
3362
3363/*---------------------------------------------------------------------
3364 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003365 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366 *
3367 * Description: Read in a message byte from the SCSI bus, and check
3368 * for a parity error.
3369 *
3370 *---------------------------------------------------------------------*/
3371
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003372static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373{
3374 PSCCB currSCCB;
3375 PSCCBMgr_tar_info currTar_Info;
3376
James Bottomley 47b5d692005-04-24 02:38:05 -05003377 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3378 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003379
3380 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3381
3382
3383 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003384 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003385
3386 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3387
3388 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3389 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3390 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3391
3392
3393 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3394
3395 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3396
3397 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3398
3399 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3400
3401 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3402
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3404
3405 else
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3407
3408
3409 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3410 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3411 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3412
3413
James Bottomley 47b5d692005-04-24 02:38:05 -05003414 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 {
3416 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3417 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003418 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 }
3420 else
3421 {
3422 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3423 }
3424
3425
James Bottomley 47b5d692005-04-24 02:38:05 -05003426 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 }
3428
3429 else {
3430
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003431 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003433 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 }
3435}
3436
3437
3438
3439/*---------------------------------------------------------------------
3440 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003441 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 *
3443 * Description: The has sent us a Sync Nego message so handle it as
3444 * necessary.
3445 *
3446 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003447static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003449 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450 PSCCB currSCCB;
3451 PSCCBMgr_tar_info currTar_Info;
3452
James Bottomley 47b5d692005-04-24 02:38:05 -05003453 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3454 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455
James Bottomley 47b5d692005-04-24 02:38:05 -05003456 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003457
3458 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3459 {
3460 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3461 return;
3462 }
3463
3464 ACCEPT_MSG(port);
3465
3466
James Bottomley 47b5d692005-04-24 02:38:05 -05003467 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468
3469 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3470 {
3471 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3472 return;
3473 }
3474
3475 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3476
3477 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3478
3479 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3480
3481 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3482
3483 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3484
3485 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3486 else
3487
3488 our_sync_msg = 0; /* Message = Async */
3489
3490 if (sync_msg < our_sync_msg) {
3491 sync_msg = our_sync_msg; /*if faster, then set to max. */
3492 }
3493
3494 if (offset == ASYNC)
3495 sync_msg = ASYNC;
3496
3497 if (offset > MAX_OFFSET)
3498 offset = MAX_OFFSET;
3499
3500 sync_reg = 0x00;
3501
3502 if (sync_msg > 12)
3503
3504 sync_reg = 0x20; /* Use 10MB/s */
3505
3506 if (sync_msg > 25)
3507
3508 sync_reg = 0x40; /* Use 6.6MB/s */
3509
3510 if (sync_msg > 38)
3511
3512 sync_reg = 0x60; /* Use 5MB/s */
3513
3514 if (sync_msg > 50)
3515
3516 sync_reg = 0x80; /* Use 4MB/s */
3517
3518 if (sync_msg > 62)
3519
3520 sync_reg = 0xA0; /* Use 3.33MB/s */
3521
3522 if (sync_msg > 75)
3523
3524 sync_reg = 0xC0; /* Use 2.85MB/s */
3525
3526 if (sync_msg > 87)
3527
3528 sync_reg = 0xE0; /* Use 2.5MB/s */
3529
3530 if (sync_msg > 100) {
3531
3532 sync_reg = 0x00; /* Use ASYNC */
3533 offset = 0x00;
3534 }
3535
3536
Linus Torvalds1da177e2005-04-16 15:20:36 -07003537 if (currTar_Info->TarStatus & WIDE_ENABLED)
3538
3539 sync_reg |= offset;
3540
3541 else
3542
3543 sync_reg |= (offset | NARROW_SCSI);
3544
James Bottomley 47b5d692005-04-24 02:38:05 -05003545 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546
3547
3548 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3549
3550
3551 ACCEPT_MSG(port);
3552
3553 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003554 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003555
3556 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3557 }
3558
3559 else {
3560
3561
3562 ACCEPT_MSG_ATN(port);
3563
James Bottomley 47b5d692005-04-24 02:38:05 -05003564 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565
3566 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003567 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568 }
3569}
3570
3571
3572/*---------------------------------------------------------------------
3573 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003574 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575 *
3576 * Description: Answer the targets sync message.
3577 *
3578 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003579static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003580{
3581 ARAM_ACCESS(port);
3582 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3583 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3584 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3585 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3586 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3587 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3588 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3589 SGRAM_ACCESS(port);
3590
3591 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3592 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3593
3594 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3595
3596 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3597}
3598
3599
3600
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601/*---------------------------------------------------------------------
3602 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003603 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003604 *
3605 * Description: Read in a message byte from the SCSI bus, and check
3606 * for a parity error.
3607 *
3608 *---------------------------------------------------------------------*/
3609
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003610static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611{
3612 PSCCB currSCCB;
3613 PSCCBMgr_tar_info currTar_Info;
3614
James Bottomley 47b5d692005-04-24 02:38:05 -05003615 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3616 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003617
3618 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3619
3620
3621 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003622 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003623
3624 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3625
3626 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3627 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3628 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3629 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3630 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3631 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3632
3633 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3634
3635
3636 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003637 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638
James Bottomley 47b5d692005-04-24 02:38:05 -05003639 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 }
3641
3642 else {
3643
3644 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003645 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646
3647 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003648 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003649 }
3650}
3651
3652
3653
3654/*---------------------------------------------------------------------
3655 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003656 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003657 *
3658 * Description: The has sent us a Wide Nego message so handle it as
3659 * necessary.
3660 *
3661 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003662static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003664 unsigned char width;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665 PSCCB currSCCB;
3666 PSCCBMgr_tar_info currTar_Info;
3667
James Bottomley 47b5d692005-04-24 02:38:05 -05003668 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3669 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670
James Bottomley 47b5d692005-04-24 02:38:05 -05003671 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003672
3673 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3674 {
3675 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3676 return;
3677 }
3678
3679
3680 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3681 width = 0;
3682
3683 if (width) {
3684 currTar_Info->TarStatus |= WIDE_ENABLED;
3685 width = 0;
3686 }
3687 else {
3688 width = NARROW_SCSI;
3689 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3690 }
3691
3692
James Bottomley 47b5d692005-04-24 02:38:05 -05003693 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694
3695
3696 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3697 {
3698
3699
3700
3701 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3702
3703 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3704 {
3705 ACCEPT_MSG_ATN(port);
3706 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003707 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3709 SGRAM_ACCESS(port);
3710 }
3711 else
3712 {
3713 ACCEPT_MSG(port);
3714 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3715 }
3716 }
3717
3718 else {
3719
3720
3721 ACCEPT_MSG_ATN(port);
3722
3723 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3724 width = SM16BIT;
3725 else
3726 width = SM8BIT;
3727
James Bottomley 47b5d692005-04-24 02:38:05 -05003728 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003729
3730 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3731 }
3732}
3733
3734
3735/*---------------------------------------------------------------------
3736 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003737 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738 *
3739 * Description: Answer the targets Wide nego message.
3740 *
3741 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003742static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743{
3744 ARAM_ACCESS(port);
3745 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3746 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3747 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3748 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3749 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3750 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3751 SGRAM_ACCESS(port);
3752
3753 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3754 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3755
3756 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3757
3758 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3759}
3760
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761
3762
3763/*---------------------------------------------------------------------
3764 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003765 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003766 *
3767 * Description: Write the desired value to the Sync Register for the
3768 * ID specified.
3769 *
3770 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003771static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003772 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003774 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003775
3776 index = p_id;
3777
3778 switch (index) {
3779
3780 case 0:
3781 index = 12; /* hp_synctarg_0 */
3782 break;
3783 case 1:
3784 index = 13; /* hp_synctarg_1 */
3785 break;
3786 case 2:
3787 index = 14; /* hp_synctarg_2 */
3788 break;
3789 case 3:
3790 index = 15; /* hp_synctarg_3 */
3791 break;
3792 case 4:
3793 index = 8; /* hp_synctarg_4 */
3794 break;
3795 case 5:
3796 index = 9; /* hp_synctarg_5 */
3797 break;
3798 case 6:
3799 index = 10; /* hp_synctarg_6 */
3800 break;
3801 case 7:
3802 index = 11; /* hp_synctarg_7 */
3803 break;
3804 case 8:
3805 index = 4; /* hp_synctarg_8 */
3806 break;
3807 case 9:
3808 index = 5; /* hp_synctarg_9 */
3809 break;
3810 case 10:
3811 index = 6; /* hp_synctarg_10 */
3812 break;
3813 case 11:
3814 index = 7; /* hp_synctarg_11 */
3815 break;
3816 case 12:
3817 index = 0; /* hp_synctarg_12 */
3818 break;
3819 case 13:
3820 index = 1; /* hp_synctarg_13 */
3821 break;
3822 case 14:
3823 index = 2; /* hp_synctarg_14 */
3824 break;
3825 case 15:
3826 index = 3; /* hp_synctarg_15 */
3827
3828 }
3829
3830 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3831
3832 currTar_Info->TarSyncCtrl = p_sync_value;
3833}
3834
3835
3836/*---------------------------------------------------------------------
3837 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003838 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839 *
3840 * Description: Reset the desired card's SCSI bus.
3841 *
3842 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003843static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003845 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003846
3847 PSCCBMgr_tar_info currTar_Info;
3848
3849 WR_HARPOON(port+hp_page_ctrl,
3850 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3851 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3852
3853 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3854
3855 scsiID = RD_HARPOON(port+hp_seltimeout);
3856 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3857 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3858
3859 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3860
3861 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3862
3863 WR_HARPOON(port+hp_seltimeout,scsiID);
3864
3865 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3866
James Bottomley 47b5d692005-04-24 02:38:05 -05003867 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003868
3869 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3870
3871 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3872
3873 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3874 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003875 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003876
3877 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3878 {
3879 currTar_Info->TarSyncCtrl = 0;
3880 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3881 }
3882
3883 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3884 {
3885 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3886 }
3887
James Bottomley 47b5d692005-04-24 02:38:05 -05003888 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889
James Bottomley 47b5d692005-04-24 02:38:05 -05003890 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 }
3892
James Bottomley 47b5d692005-04-24 02:38:05 -05003893 FPT_BL_Card[p_card].scanIndex = 0x00;
3894 FPT_BL_Card[p_card].currentSCCB = NULL;
3895 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003897 FPT_BL_Card[p_card].cmdCounter = 0x00;
3898 FPT_BL_Card[p_card].discQCount = 0x00;
3899 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900
3901 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003902 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003903
3904 WR_HARPOON(port+hp_page_ctrl,
3905 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3906
3907}
3908
3909/*---------------------------------------------------------------------
3910 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003911 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912 *
3913 * Description: Setup for the Auto Sense command.
3914 *
3915 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003916static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003918 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919 PSCCB currSCCB;
3920
3921 currSCCB = pCurrCard->currentSCCB;
3922
3923
3924 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3925
3926 for (i = 0; i < 6; i++) {
3927
3928 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3929 }
3930
3931 currSCCB->CdbLength = SIX_BYTE_CMD;
3932 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003933 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934 currSCCB->Cdb[2] = 0x00;
3935 currSCCB->Cdb[3] = 0x00;
3936 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3937 currSCCB->Cdb[5] = 0x00;
3938
3939 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3940
3941 currSCCB->Sccb_ATC = 0x00;
3942
3943 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3944
3945 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3946
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003947 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003948
3949 currSCCB->ControlByte = 0x00;
3950
3951 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3952}
3953
3954
3955
3956/*---------------------------------------------------------------------
3957 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003958 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959 *
3960 * Description: Transfer data into the bit bucket until the device
3961 * decides to switch phase.
3962 *
3963 *---------------------------------------------------------------------*/
3964
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003965static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003967 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968
3969
3970 DISABLE_AUTO(p_port);
3971
James Bottomley 47b5d692005-04-24 02:38:05 -05003972 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973
James Bottomley 47b5d692005-04-24 02:38:05 -05003974 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003975
3976 }
3977
3978 /* If the Automation handled the end of the transfer then do not
3979 match the phase or we will get out of sync with the ISR. */
3980
3981 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3982 return;
3983
3984 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3985
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003986 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987
3988 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3989
3990
3991 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3992
3993 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003994 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003996 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003997 {
3998 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3999
4000 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4001 {
4002 RD_HARPOON(p_port+hp_fifodata_0);
4003 }
4004 }
4005 else
4006 {
4007 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4008 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4009 {
4010 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4011 }
4012 }
4013 } /* End of While loop for padding data I/O phase */
4014
4015 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4016 {
4017 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4018 break;
4019 }
4020
4021 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4022 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4023 {
4024 RD_HARPOON(p_port+hp_fifodata_0);
4025 }
4026
4027 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4028 {
4029 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4030 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4031
4032 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4033 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4034 }
4035}
4036
4037
4038/*---------------------------------------------------------------------
4039 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004040 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004041 *
4042 * Description: Make sure data has been flushed from both FIFOs and abort
4043 * the operations if necessary.
4044 *
4045 *---------------------------------------------------------------------*/
4046
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004047static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004049 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004050 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
4052 PSCCB currSCCB;
4053
James Bottomley 47b5d692005-04-24 02:38:05 -05004054 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004055
4056
4057 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4058 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4059 return;
4060 }
4061
4062
4063
4064 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4065 {
4066
4067 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4068
4069 currSCCB->Sccb_XferCnt = 1;
4070
4071 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004072 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004073 WR_HARPOON(port+hp_xferstat, 0x00);
4074 }
4075
4076 else
4077 {
4078
4079 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4080
4081 currSCCB->Sccb_XferCnt = 0;
4082 }
4083
4084 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4085 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4086
4087 currSCCB->HostStatus = SCCB_PARITY_ERR;
4088 WRW_HARPOON((port+hp_intstat), PARITY);
4089 }
4090
4091
James Bottomley 47b5d692005-04-24 02:38:05 -05004092 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004093
4094
4095 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4096
4097 TimeOutLoop = 0;
4098
4099 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4100 {
4101 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4102 return;
4103 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004104 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004105 break;
4106 }
4107 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4108 return;
4109 }
4110 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4111 break;
4112 }
4113
4114 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4115 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004116 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004117 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4118 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4119 {
4120
4121 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4122
4123 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4124 {
4125 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004126 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127 }
4128
4129 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004130 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131 }
4132 }
4133 else
4134 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004135 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 if (!(RDW_HARPOON((port+hp_intstat)) &
4137 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4138 {
4139 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004140 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141 }
4142 }
4143
4144 }
4145
4146 else {
4147 WR_HARPOON(port+hp_portctrl_0, 0x00);
4148 }
4149}
4150
4151
4152/*---------------------------------------------------------------------
4153 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004154 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004155 *
4156 * Description: Setup SCCB manager fields in this SCCB.
4157 *
4158 *---------------------------------------------------------------------*/
4159
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004160static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004161{
4162 PSCCBMgr_tar_info currTar_Info;
4163
4164 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4165 {
4166 return;
4167 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004168 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004169
4170 p_sccb->Sccb_XferState = 0x00;
4171 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4172
4173 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4174 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4175
4176 p_sccb->Sccb_SGoffset = 0;
4177 p_sccb->Sccb_XferState = F_SG_XFER;
4178 p_sccb->Sccb_XferCnt = 0x00;
4179 }
4180
4181 if (p_sccb->DataLength == 0x00)
4182
4183 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4184
4185 if (p_sccb->ControlByte & F_USE_CMD_Q)
4186 {
4187 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4188 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4189
4190 else
4191 currTar_Info->TarStatus |= TAG_Q_TRYING;
4192 }
4193
4194/* For !single SCSI device in system & device allow Disconnect
4195 or command is tag_q type then send Cmd with Disconnect Enable
4196 else send Cmd with Disconnect Disable */
4197
4198/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004199 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004200 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4201 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4202*/
4203 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4204 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004205 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206 }
4207
4208 else {
4209
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004210 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211 }
4212
4213 p_sccb->HostStatus = 0x00;
4214 p_sccb->TargetStatus = 0x00;
4215 p_sccb->Sccb_tag = 0x00;
4216 p_sccb->Sccb_MGRFlags = 0x00;
4217 p_sccb->Sccb_sgseg = 0x00;
4218 p_sccb->Sccb_ATC = 0x00;
4219 p_sccb->Sccb_savedATC = 0x00;
4220/*
4221 p_sccb->SccbVirtDataPtr = 0x00;
4222 p_sccb->Sccb_forwardlink = NULL;
4223 p_sccb->Sccb_backlink = NULL;
4224 */
4225 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4226 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4227 p_sccb->Sccb_scsimsg = SMNO_OP;
4228
4229}
4230
4231
Linus Torvalds1da177e2005-04-16 15:20:36 -07004232/*---------------------------------------------------------------------
4233 *
4234 * Function: Phase Decode
4235 *
4236 * Description: Determine the phase and call the appropriate function.
4237 *
4238 *---------------------------------------------------------------------*/
4239
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004240static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241{
4242 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004243 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244
4245
4246 DISABLE_AUTO(p_port);
4247
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004248 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249
James Bottomley 47b5d692005-04-24 02:38:05 -05004250 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004251
4252 (*phase)(p_port, p_card); /* Call the correct phase func */
4253}
4254
4255
4256
4257/*---------------------------------------------------------------------
4258 *
4259 * Function: Data Out Phase
4260 *
4261 * Description: Start up both the BusMaster and Xbow.
4262 *
4263 *---------------------------------------------------------------------*/
4264
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004265static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266{
4267
4268 PSCCB currSCCB;
4269
James Bottomley 47b5d692005-04-24 02:38:05 -05004270 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271 if (currSCCB == NULL)
4272 {
4273 return; /* Exit if No SCCB record */
4274 }
4275
4276 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4277 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4278
4279 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4280
4281 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4282
4283 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4284
James Bottomley 47b5d692005-04-24 02:38:05 -05004285 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004286
4287 if (currSCCB->Sccb_XferCnt == 0) {
4288
4289
4290 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4291 (currSCCB->HostStatus == SCCB_COMPLETE))
4292 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4293
James Bottomley 47b5d692005-04-24 02:38:05 -05004294 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004296 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297 }
4298}
4299
4300
4301/*---------------------------------------------------------------------
4302 *
4303 * Function: Data In Phase
4304 *
4305 * Description: Startup the BusMaster and the XBOW.
4306 *
4307 *---------------------------------------------------------------------*/
4308
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004309static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310{
4311
4312 PSCCB currSCCB;
4313
James Bottomley 47b5d692005-04-24 02:38:05 -05004314 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004315
4316 if (currSCCB == NULL)
4317 {
4318 return; /* Exit if No SCCB record */
4319 }
4320
4321
4322 currSCCB->Sccb_scsistat = DATA_IN_ST;
4323 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4324 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4325
4326 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4327
4328 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4329
4330 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4331
James Bottomley 47b5d692005-04-24 02:38:05 -05004332 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333
4334 if (currSCCB->Sccb_XferCnt == 0) {
4335
4336
4337 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4338 (currSCCB->HostStatus == SCCB_COMPLETE))
4339 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4340
James Bottomley 47b5d692005-04-24 02:38:05 -05004341 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004343 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344
4345 }
4346}
4347
4348/*---------------------------------------------------------------------
4349 *
4350 * Function: Command Phase
4351 *
4352 * Description: Load the CDB into the automation and start it up.
4353 *
4354 *---------------------------------------------------------------------*/
4355
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004356static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357{
4358 PSCCB currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004359 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004360 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361
James Bottomley 47b5d692005-04-24 02:38:05 -05004362 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004363
4364 if (currSCCB->OperationCode == RESET_COMMAND) {
4365
4366 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4367 currSCCB->CdbLength = SIX_BYTE_CMD;
4368 }
4369
4370 WR_HARPOON(p_port+hp_scsisig, 0x00);
4371
4372 ARAM_ACCESS(p_port);
4373
4374
4375 cdb_reg = p_port + CMD_STRT;
4376
4377 for (i=0; i < currSCCB->CdbLength; i++) {
4378
4379 if (currSCCB->OperationCode == RESET_COMMAND)
4380
4381 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4382
4383 else
4384 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4385 cdb_reg +=2;
4386 }
4387
4388 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4389 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4390
4391 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4392
4393 currSCCB->Sccb_scsistat = COMMAND_ST;
4394
4395 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4396 SGRAM_ACCESS(p_port);
4397}
4398
4399
4400/*---------------------------------------------------------------------
4401 *
4402 * Function: Status phase
4403 *
4404 * Description: Bring in the status and command complete message bytes
4405 *
4406 *---------------------------------------------------------------------*/
4407
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004408static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004409{
4410 /* Start-up the automation to finish off this command and let the
4411 isr handle the interrupt for command complete when it comes in.
4412 We could wait here for the interrupt to be generated?
4413 */
4414
4415 WR_HARPOON(port+hp_scsisig, 0x00);
4416
4417 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4418}
4419
4420
4421/*---------------------------------------------------------------------
4422 *
4423 * Function: Phase Message Out
4424 *
4425 * Description: Send out our message (if we have one) and handle whatever
4426 * else is involed.
4427 *
4428 *---------------------------------------------------------------------*/
4429
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004430static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004432 unsigned char message,scsiID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433 PSCCB currSCCB;
4434 PSCCBMgr_tar_info currTar_Info;
4435
James Bottomley 47b5d692005-04-24 02:38:05 -05004436 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437
4438 if (currSCCB != NULL) {
4439
4440 message = currSCCB->Sccb_scsimsg;
4441 scsiID = currSCCB->TargID;
4442
4443 if (message == SMDEV_RESET)
4444 {
4445
4446
James Bottomley 47b5d692005-04-24 02:38:05 -05004447 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004449 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450
James Bottomley 47b5d692005-04-24 02:38:05 -05004451 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452 {
4453
James Bottomley 47b5d692005-04-24 02:38:05 -05004454 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455
4456 }
4457
James Bottomley 47b5d692005-04-24 02:38:05 -05004458 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 {
4460
James Bottomley 47b5d692005-04-24 02:38:05 -05004461 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462 }
4463
4464
James Bottomley 47b5d692005-04-24 02:38:05 -05004465 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4466 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467 }
4468 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4469 {
4470 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004471 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004473 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4474 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 }
4476
4477 }
4478
4479 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4480 {
4481
4482
4483 if(message == SMNO_OP)
4484 {
4485 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4486
James Bottomley 47b5d692005-04-24 02:38:05 -05004487 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004488 return;
4489 }
4490 }
4491 else
4492 {
4493
4494
4495 if (message == SMABORT)
4496
James Bottomley 47b5d692005-04-24 02:38:05 -05004497 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004498 }
4499
4500 }
4501 else
4502 {
4503 message = SMABORT;
4504 }
4505
4506 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4507
4508
4509 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4510
4511 WR_HARPOON(port+hp_scsidata_0,message);
4512
4513 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4514
4515 ACCEPT_MSG(port);
4516
4517 WR_HARPOON(port+hp_portctrl_0, 0x00);
4518
4519 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4520 (message == SMABORT_TAG) )
4521 {
4522
4523 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4524
4525 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4526 {
4527 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4528
4529 if (currSCCB != NULL)
4530 {
4531
James Bottomley 47b5d692005-04-24 02:38:05 -05004532 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4533 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4534 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004536 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537
James Bottomley 47b5d692005-04-24 02:38:05 -05004538 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539 }
4540
4541 else
4542 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004543 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544 }
4545 }
4546
4547 else
4548 {
4549
James Bottomley 47b5d692005-04-24 02:38:05 -05004550 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004551 }
4552 }
4553
4554 else
4555 {
4556
4557 if(message == SMPARITY)
4558 {
4559 currSCCB->Sccb_scsimsg = SMNO_OP;
4560 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4561 }
4562 else
4563 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004564 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004565 }
4566 }
4567}
4568
4569
4570/*---------------------------------------------------------------------
4571 *
4572 * Function: Message In phase
4573 *
4574 * Description: Bring in the message and determine what to do with it.
4575 *
4576 *---------------------------------------------------------------------*/
4577
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004578static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004580 unsigned char message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581 PSCCB currSCCB;
4582
James Bottomley 47b5d692005-04-24 02:38:05 -05004583 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584
James Bottomley 47b5d692005-04-24 02:38:05 -05004585 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004586 {
4587
James Bottomley 47b5d692005-04-24 02:38:05 -05004588 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004589 }
4590
4591 message = RD_HARPOON(port+hp_scsidata_0);
4592 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4593 {
4594
4595 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4596
4597 }
4598
4599 else
4600 {
4601
James Bottomley 47b5d692005-04-24 02:38:05 -05004602 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603 if (message)
4604 {
4605
4606
James Bottomley 47b5d692005-04-24 02:38:05 -05004607 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004608
4609 }
4610 else
4611 {
4612 if(currSCCB->Sccb_scsimsg != SMPARITY)
4613 ACCEPT_MSG(port);
4614 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4615 }
4616 }
4617
4618}
4619
4620
4621/*---------------------------------------------------------------------
4622 *
4623 * Function: Illegal phase
4624 *
4625 * Description: Target switched to some illegal phase, so all we can do
4626 * is report an error back to the host (if that is possible)
4627 * and send an ABORT message to the misbehaving target.
4628 *
4629 *---------------------------------------------------------------------*/
4630
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004631static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632{
4633 PSCCB currSCCB;
4634
James Bottomley 47b5d692005-04-24 02:38:05 -05004635 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004636
4637 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4638 if (currSCCB != NULL) {
4639
4640 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4641 currSCCB->Sccb_scsistat = ABORT_ST;
4642 currSCCB->Sccb_scsimsg = SMABORT;
4643 }
4644
4645 ACCEPT_MSG_ATN(port);
4646}
4647
4648
4649
4650/*---------------------------------------------------------------------
4651 *
4652 * Function: Phase Check FIFO
4653 *
4654 * Description: Make sure data has been flushed from both FIFOs and abort
4655 * the operations if necessary.
4656 *
4657 *---------------------------------------------------------------------*/
4658
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004659static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004661 unsigned long xfercnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662 PSCCB currSCCB;
4663
James Bottomley 47b5d692005-04-24 02:38:05 -05004664 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004665
4666 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4667 {
4668
4669 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4670 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4671
4672
4673 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4674 {
4675 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4676
4677 currSCCB->Sccb_XferCnt = 0;
4678
4679 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4680 (currSCCB->HostStatus == SCCB_COMPLETE))
4681 {
4682 currSCCB->HostStatus = SCCB_PARITY_ERR;
4683 WRW_HARPOON((port+hp_intstat), PARITY);
4684 }
4685
James Bottomley 47b5d692005-04-24 02:38:05 -05004686 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687
James Bottomley 47b5d692005-04-24 02:38:05 -05004688 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004689
4690 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4691 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4692
4693 }
4694 } /*End Data In specific code. */
4695
4696
4697
Linus Torvalds1da177e2005-04-16 15:20:36 -07004698 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004699
4700
4701 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4702
4703
4704 WR_HARPOON(port+hp_portctrl_0, 0x00);
4705
4706 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4707
4708 currSCCB->Sccb_XferCnt = xfercnt;
4709
4710 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4711 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4712
4713 currSCCB->HostStatus = SCCB_PARITY_ERR;
4714 WRW_HARPOON((port+hp_intstat), PARITY);
4715 }
4716
4717
James Bottomley 47b5d692005-04-24 02:38:05 -05004718 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004719
4720
4721 WR_HARPOON(port+hp_fifowrite, 0x00);
4722 WR_HARPOON(port+hp_fiforead, 0x00);
4723 WR_HARPOON(port+hp_xferstat, 0x00);
4724
4725 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4726}
4727
4728
4729/*---------------------------------------------------------------------
4730 *
4731 * Function: Phase Bus Free
4732 *
4733 * Description: We just went bus free so figure out if it was
4734 * because of command complete or from a disconnect.
4735 *
4736 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004737static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004738{
4739 PSCCB currSCCB;
4740
James Bottomley 47b5d692005-04-24 02:38:05 -05004741 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004742
4743 if (currSCCB != NULL)
4744 {
4745
4746 DISABLE_AUTO(port);
4747
4748
4749 if (currSCCB->OperationCode == RESET_COMMAND)
4750 {
4751
James Bottomley 47b5d692005-04-24 02:38:05 -05004752 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4753 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4754 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004755 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004756 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004757
James Bottomley 47b5d692005-04-24 02:38:05 -05004758 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004759
James Bottomley 47b5d692005-04-24 02:38:05 -05004760 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004761
4762 }
4763
4764 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4765 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004766 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004767 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004768 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004769 }
4770
4771 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4772 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004773 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4774 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004775 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4776
James Bottomley 47b5d692005-04-24 02:38:05 -05004777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778 }
4779
Linus Torvalds1da177e2005-04-16 15:20:36 -07004780 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4781 {
4782 /* Make sure this is not a phony BUS_FREE. If we were
4783 reselected or if BUSY is NOT on then this is a
4784 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4785
4786 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4787 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4788 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004789 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4790 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004791 }
4792
4793 else
4794 {
4795 return;
4796 }
4797 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004798
4799 else
4800 {
4801
4802 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4803
4804 if (!currSCCB->HostStatus)
4805 {
4806 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4807 }
4808
James Bottomley 47b5d692005-04-24 02:38:05 -05004809 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4810 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4811 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004812 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004813 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004814
James Bottomley 47b5d692005-04-24 02:38:05 -05004815 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004816 return;
4817 }
4818
4819
James Bottomley 47b5d692005-04-24 02:38:05 -05004820 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004821
4822 } /*end if !=null */
4823}
4824
4825
4826
4827
Linus Torvalds1da177e2005-04-16 15:20:36 -07004828/*---------------------------------------------------------------------
4829 *
4830 * Function: Auto Load Default Map
4831 *
4832 * Description: Load the Automation RAM with the defualt map values.
4833 *
4834 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004835static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004836{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004837 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004838
4839 ARAM_ACCESS(p_port);
4840 map_addr = p_port + hp_aramBase;
4841
4842 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4843 map_addr +=2;
4844 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4845 map_addr +=2;
4846 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4847 map_addr +=2;
4848 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4849 map_addr +=2;
4850 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4851 map_addr +=2;
4852 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4873 map_addr +=2;
4874 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4875 map_addr +=2;
4876 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4877 map_addr +=2; /*This means AYNC DATA IN */
4878 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4883 map_addr +=2;
4884 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4885 map_addr +=2;
4886 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4887 map_addr +=2;
4888 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4909 map_addr +=2;
4910 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4911 map_addr +=2;
4912 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4913 map_addr +=2;
4914
4915 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4920 map_addr +=2;
4921 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4922 map_addr +=2; /* DIDN'T GET ONE */
4923 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4924 map_addr +=2;
4925 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4926 map_addr +=2;
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4928
4929
4930
4931 SGRAM_ACCESS(p_port);
4932}
4933
4934/*---------------------------------------------------------------------
4935 *
4936 * Function: Auto Command Complete
4937 *
4938 * Description: Post command back to host and find another command
4939 * to execute.
4940 *
4941 *---------------------------------------------------------------------*/
4942
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004943static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004944{
4945 PSCCB currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004946 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004947
James Bottomley 47b5d692005-04-24 02:38:05 -05004948 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004949
4950 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4951
James Bottomley 47b5d692005-04-24 02:38:05 -05004952 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004953
4954 if (status_byte != SSGOOD) {
4955
4956 if (status_byte == SSQ_FULL) {
4957
4958
James Bottomley 47b5d692005-04-24 02:38:05 -05004959 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4960 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004961 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004962 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4963 if(FPT_BL_Card[p_card].discQCount != 0)
4964 FPT_BL_Card[p_card].discQCount--;
4965 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 -07004966 }
4967 else
4968 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004969 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004970 if(currSCCB->Sccb_tag)
4971 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004972 if(FPT_BL_Card[p_card].discQCount != 0)
4973 FPT_BL_Card[p_card].discQCount--;
4974 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004975 }else
4976 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004977 if(FPT_BL_Card[p_card].discQCount != 0)
4978 FPT_BL_Card[p_card].discQCount--;
4979 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004980 }
4981 }
4982
4983 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4984
James Bottomley 47b5d692005-04-24 02:38:05 -05004985 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004986
4987 return;
4988 }
4989
4990 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4991 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004992 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004993 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004994
James Bottomley 47b5d692005-04-24 02:38:05 -05004995 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4996 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004997
James Bottomley 47b5d692005-04-24 02:38:05 -05004998 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4999 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005000 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005001 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5002 if(FPT_BL_Card[p_card].discQCount != 0)
5003 FPT_BL_Card[p_card].discQCount--;
5004 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 -07005005 }
5006 else
5007 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005008 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005009 if(currSCCB->Sccb_tag)
5010 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005011 if(FPT_BL_Card[p_card].discQCount != 0)
5012 FPT_BL_Card[p_card].discQCount--;
5013 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005014 }else
5015 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005016 if(FPT_BL_Card[p_card].discQCount != 0)
5017 FPT_BL_Card[p_card].discQCount--;
5018 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005019 }
5020 }
5021 return;
5022
5023 }
5024
5025 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5026 {
5027
James Bottomley 47b5d692005-04-24 02:38:05 -05005028 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5029 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005030 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5031
James Bottomley 47b5d692005-04-24 02:38:05 -05005032 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5033 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005034
James Bottomley 47b5d692005-04-24 02:38:05 -05005035 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5036 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005037 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005038 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5039 if(FPT_BL_Card[p_card].discQCount != 0)
5040 FPT_BL_Card[p_card].discQCount--;
5041 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 -07005042 }
5043 else
5044 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005045 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005046 if(currSCCB->Sccb_tag)
5047 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005048 if(FPT_BL_Card[p_card].discQCount != 0)
5049 FPT_BL_Card[p_card].discQCount--;
5050 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005051 }else
5052 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005053 if(FPT_BL_Card[p_card].discQCount != 0)
5054 FPT_BL_Card[p_card].discQCount--;
5055 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005056 }
5057 }
5058 return;
5059
5060 }
5061
5062 if (status_byte == SSCHECK)
5063 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005064 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005065 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005066 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005067 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005068 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005069 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005070 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005071 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005072 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005073 }
5074 }
5075 }
5076
5077 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5078
5079 currSCCB->SccbStatus = SCCB_ERROR;
5080 currSCCB->TargetStatus = status_byte;
5081
5082 if (status_byte == SSCHECK) {
5083
James Bottomley 47b5d692005-04-24 02:38:05 -05005084 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5085 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005086
5087
Linus Torvalds1da177e2005-04-16 15:20:36 -07005088 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5089
5090 if (currSCCB->RequestSenseLength == 0)
5091 currSCCB->RequestSenseLength = 14;
5092
James Bottomley 47b5d692005-04-24 02:38:05 -05005093 FPT_ssenss(&FPT_BL_Card[p_card]);
5094 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005095
James Bottomley 47b5d692005-04-24 02:38:05 -05005096 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5097 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005098 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005099 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5100 if(FPT_BL_Card[p_card].discQCount != 0)
5101 FPT_BL_Card[p_card].discQCount--;
5102 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 -07005103 }
5104 else
5105 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005106 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005107 if(currSCCB->Sccb_tag)
5108 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005109 if(FPT_BL_Card[p_card].discQCount != 0)
5110 FPT_BL_Card[p_card].discQCount--;
5111 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005112 }else
5113 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005114 if(FPT_BL_Card[p_card].discQCount != 0)
5115 FPT_BL_Card[p_card].discQCount--;
5116 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005117 }
5118 }
5119 return;
5120 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005121 }
5122 }
5123 }
5124
5125
James Bottomley 47b5d692005-04-24 02:38:05 -05005126 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5127 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5128 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005129 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005130 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005131
5132
James Bottomley 47b5d692005-04-24 02:38:05 -05005133 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005134}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005135
5136#define SHORT_WAIT 0x0000000F
5137#define LONG_WAIT 0x0000FFFFL
5138
Linus Torvalds1da177e2005-04-16 15:20:36 -07005139
5140/*---------------------------------------------------------------------
5141 *
5142 * Function: Data Transfer Processor
5143 *
5144 * Description: This routine performs two tasks.
5145 * (1) Start data transfer by calling HOST_DATA_XFER_START
5146 * function. Once data transfer is started, (2) Depends
5147 * on the type of data transfer mode Scatter/Gather mode
5148 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5149 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5150 * data transfer done. In Scatter/Gather mode, this routine
5151 * checks bus master command complete and dual rank busy
5152 * bit to keep chaining SC transfer command. Similarly,
5153 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5154 * (F_HOST_XFER_ACT bit) for data transfer done.
5155 *
5156 *---------------------------------------------------------------------*/
5157
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005158static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005159{
5160 PSCCB currSCCB;
5161
5162 currSCCB = pCurrCard->currentSCCB;
5163
5164 if (currSCCB->Sccb_XferState & F_SG_XFER)
5165 {
5166 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5167
5168 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005169 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005170 currSCCB->Sccb_SGoffset = 0x00;
5171 }
5172 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5173
James Bottomley 47b5d692005-04-24 02:38:05 -05005174 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005175 }
5176
5177 else
5178 {
5179 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5180 {
5181 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5182
James Bottomley 47b5d692005-04-24 02:38:05 -05005183 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005184 }
5185 }
5186}
5187
5188
5189/*---------------------------------------------------------------------
5190 *
5191 * Function: BusMaster Scatter Gather Data Transfer Start
5192 *
5193 * Description:
5194 *
5195 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005196static void FPT_busMstrSGDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005197{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005198 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005199 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005200 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005201 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005202
5203
5204 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5205
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005206 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005207 }
5208
5209 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005210 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005211 }
5212
5213 sg_count = 0;
5214 tmpSGCnt = 0;
5215 sg_index = pcurrSCCB->Sccb_sgseg;
5216 reg_offset = hp_aramBase;
5217
5218
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005219 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005220
5221
5222 WR_HARPOON(p_port+hp_page_ctrl, i);
5223
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005224 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005225 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005227 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005228 (sg_index * 2));
5229
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005230 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005231 (sg_index * 2));
5232
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005233 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005234 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005235
5236
5237 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5238
5239 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5240 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5241
5242 tmpSGCnt = count & 0x00FFFFFFL;
5243 }
5244
5245 WR_HARP32(p_port,reg_offset,addr);
5246 reg_offset +=4;
5247
5248 WR_HARP32(p_port,reg_offset,count);
5249 reg_offset +=4;
5250
5251 count &= 0xFF000000L;
5252 sg_index++;
5253 sg_count++;
5254
5255 } /*End While */
5256
5257 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5258
5259 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5260
5261 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5262
5263 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5264
5265
5266 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5267 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5268 }
5269
5270 else {
5271
5272
5273 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5274 (tmpSGCnt & 0x000000001))
5275 {
5276
5277 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5278 tmpSGCnt--;
5279 }
5280
5281
5282 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5283
5284 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5285 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5286 }
5287
5288
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005289 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005290
5291}
5292
5293
5294/*---------------------------------------------------------------------
5295 *
5296 * Function: BusMaster Data Transfer Start
5297 *
5298 * Description:
5299 *
5300 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005301static void FPT_busMstrDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005302{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005303 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005304
5305 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5306
5307 count = pcurrSCCB->Sccb_XferCnt;
5308
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005309 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005310 }
5311
5312 else {
5313 addr = pcurrSCCB->SensePointer;
5314 count = pcurrSCCB->RequestSenseLength;
5315
5316 }
5317
Linus Torvalds1da177e2005-04-16 15:20:36 -07005318 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005319
5320
5321 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5322
5323 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5324 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5325
5326 WR_HARPOON(p_port+hp_xfer_cmd,
5327 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5328 }
5329
5330 else {
5331
5332 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5333 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5334
5335 WR_HARPOON(p_port+hp_xfer_cmd,
5336 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5337
5338 }
5339}
5340
5341
5342/*---------------------------------------------------------------------
5343 *
5344 * Function: BusMaster Timeout Handler
5345 *
5346 * Description: This function is called after a bus master command busy time
5347 * out is detected. This routines issue halt state machine
5348 * with a software time out for command busy. If command busy
5349 * is still asserted at the end of the time out, it issues
5350 * hard abort with another software time out. It hard abort
5351 * command busy is also time out, it'll just give up.
5352 *
5353 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005354static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005355{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005356 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005357
5358 timeout = LONG_WAIT;
5359
5360 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5361
5362 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5363
5364
5365
5366 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5367 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5368
5369 timeout = LONG_WAIT;
5370 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5371 }
5372
5373 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5374
5375 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005376 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 }
5378
5379 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005380 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005381 }
5382}
5383
5384
5385/*---------------------------------------------------------------------
5386 *
5387 * Function: Host Data Transfer Abort
5388 *
5389 * Description: Abort any in progress transfer.
5390 *
5391 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005392static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393{
5394
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005395 unsigned long timeout;
5396 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005397 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005398
James Bottomley 47b5d692005-04-24 02:38:05 -05005399 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400
5401 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5402
5403
5404 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5405
5406 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5407 timeout = LONG_WAIT;
5408
5409 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5410
5411 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5412
5413 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5414
James Bottomley 47b5d692005-04-24 02:38:05 -05005415 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416
5417 if (pCurrSCCB->HostStatus == 0x00)
5418
5419 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5420
5421 }
5422
5423 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5424
5425 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5426
5427 if (pCurrSCCB->HostStatus == 0x00)
5428
5429 {
5430 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005431 }
5432 }
5433 }
5434 }
5435
5436 else if (pCurrSCCB->Sccb_XferCnt) {
5437
5438 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5439
5440
5441 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5442 ~SCATTER_EN));
5443
5444 WR_HARPOON(port+hp_sg_addr,0x00);
5445
5446 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5447
Alexey Dobriyance793212006-03-08 00:14:26 -08005448 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005449
Alexey Dobriyance793212006-03-08 00:14:26 -08005450 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005451 }
5452
5453 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5454
5455 while (remain_cnt < 0x01000000L) {
5456
5457 sg_ptr--;
5458
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005459 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005460 DataPointer) + (sg_ptr * 2)))) {
5461
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005462 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005463 DataPointer) + (sg_ptr * 2)));
5464 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005465
5466 else {
5467
5468 break;
5469 }
5470 }
5471
5472
5473
5474 if (remain_cnt < 0x01000000L) {
5475
5476
5477 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5478
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005479 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005480
5481
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005482 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005483 && (remain_cnt == 0))
5484
5485 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5486 }
5487
5488 else {
5489
5490
5491 if (pCurrSCCB->HostStatus == 0x00) {
5492
5493 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5494 }
5495 }
5496 }
5497
5498
5499 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5500
5501
5502 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5503
James Bottomley 47b5d692005-04-24 02:38:05 -05005504 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005505 }
5506
5507 else {
5508
5509 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5510
5511 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5512
5513 if (pCurrSCCB->HostStatus == 0x00) {
5514
5515 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005516 }
5517 }
5518 }
5519
5520 }
5521 }
5522
5523 else {
5524
5525
5526 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5527
5528 timeout = SHORT_WAIT;
5529
5530 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5531 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5532 timeout--) {}
5533 }
5534
5535 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5536
5537 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5538 FLUSH_XFER_CNTR));
5539
5540 timeout = LONG_WAIT;
5541
5542 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5543 timeout--) {}
5544
5545 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5546 ~FLUSH_XFER_CNTR));
5547
5548
5549 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5550
5551 if (pCurrSCCB->HostStatus == 0x00) {
5552
5553 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5554 }
5555
James Bottomley 47b5d692005-04-24 02:38:05 -05005556 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005557 }
5558 }
5559
5560 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5561
5562 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5563
5564 if (pCurrSCCB->HostStatus == 0x00) {
5565
5566 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005567 }
5568 }
5569 }
5570 }
5571
5572 }
5573
5574 else {
5575
5576
5577 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5578
5579 timeout = LONG_WAIT;
5580
5581 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5582
5583 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5584
5585 if (pCurrSCCB->HostStatus == 0x00) {
5586
5587 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5588 }
5589
James Bottomley 47b5d692005-04-24 02:38:05 -05005590 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005591 }
5592 }
5593
5594
5595 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5596
5597 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5598
5599 if (pCurrSCCB->HostStatus == 0x00) {
5600
5601 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005602 }
5603 }
5604
5605 }
5606
5607 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5608
5609 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5610 ~SCATTER_EN));
5611
5612 WR_HARPOON(port+hp_sg_addr,0x00);
5613
5614 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5615
5616 pCurrSCCB->Sccb_SGoffset = 0x00;
5617
5618
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005619 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620 pCurrSCCB->DataLength) {
5621
5622 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5623
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005624 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005625
5626 }
5627 }
5628
5629 else {
5630
5631 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5632
5633 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5634 }
5635 }
5636
5637 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5638}
5639
5640
5641
5642/*---------------------------------------------------------------------
5643 *
5644 * Function: Host Data Transfer Restart
5645 *
5646 * Description: Reset the available count due to a restore data
5647 * pointers message.
5648 *
5649 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005650static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005652 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005653 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005654 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005655
5656 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5657
5658 currSCCB->Sccb_XferCnt = 0;
5659
5660 sg_index = 0xffff; /*Index by long words into sg list. */
5661 data_count = 0; /*Running count of SG xfer counts. */
5662
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005663 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005664
5665 while (data_count < currSCCB->Sccb_ATC) {
5666
5667 sg_index++;
5668 data_count += *(sg_ptr+(sg_index * 2));
5669 }
5670
5671 if (data_count == currSCCB->Sccb_ATC) {
5672
5673 currSCCB->Sccb_SGoffset = 0;
5674 sg_index++;
5675 }
5676
5677 else {
5678 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5679 }
5680
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005681 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005682 }
5683
5684 else {
5685 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5686 }
5687}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005688
5689
5690
Linus Torvalds1da177e2005-04-16 15:20:36 -07005691/*---------------------------------------------------------------------
5692 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005693 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005694 *
5695 * Description: Setup all data structures necessary for SCAM selection.
5696 *
5697 *---------------------------------------------------------------------*/
5698
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005699static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005700{
5701
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005702 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005703 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005704
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005705 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005706 PSCCBcard currCard;
5707 PNVRamInfo pCurrNvRam;
5708
James Bottomley 47b5d692005-04-24 02:38:05 -05005709 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005710 p_port = currCard->ioPort;
5711 pCurrNvRam = currCard->pNvRamInfo;
5712
5713
5714 if(pCurrNvRam){
5715 ScamFlg = pCurrNvRam->niScamConf;
5716 i = pCurrNvRam->niSysConf;
5717 }
5718 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005719 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5720 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005721 }
5722 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5723 return;
5724
James Bottomley 47b5d692005-04-24 02:38:05 -05005725 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005726
5727 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5728 too slow to return to SCAM selection */
5729
5730 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005731 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005733 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005734
James Bottomley 47b5d692005-04-24 02:38:05 -05005735 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005736
5737 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5738 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005739 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005740
James Bottomley 47b5d692005-04-24 02:38:05 -05005741 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742
5743 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005744 FPT_scxferc(p_port,SYNC_PTRN);
5745 FPT_scxferc(p_port,DOM_MSTR);
5746 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005747 } while ( loser == 0xFF );
5748
James Bottomley 47b5d692005-04-24 02:38:05 -05005749 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005750
5751 if ((p_power_up) && (!loser))
5752 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005753 FPT_sresb(p_port,p_card);
5754 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005755
James Bottomley 47b5d692005-04-24 02:38:05 -05005756 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005757
James Bottomley 47b5d692005-04-24 02:38:05 -05005758 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759
5760 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005761 FPT_scxferc(p_port, SYNC_PTRN);
5762 FPT_scxferc(p_port, DOM_MSTR);
5763 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005764 id_string[0]);
5765 } while ( loser == 0xFF );
5766
James Bottomley 47b5d692005-04-24 02:38:05 -05005767 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005768 }
5769 }
5770
5771 else
5772 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005773 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005774 }
5775
5776
5777 if (!loser)
5778 {
5779
James Bottomley 47b5d692005-04-24 02:38:05 -05005780 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005781
5782
5783 if (ScamFlg & SCAM_ENABLED)
5784 {
5785
5786 for (i=0; i < MAX_SCSI_TAR; i++)
5787 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005788 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5789 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005790 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005791 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005792 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005793 FPT_scamInfo[i].state = LEGACY;
5794 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5795 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005796 {
5797
James Bottomley 47b5d692005-04-24 02:38:05 -05005798 FPT_scamInfo[i].id_string[0] = 0xFF;
5799 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005800 if(pCurrNvRam == NULL)
5801 currCard->globalFlags |= F_UPDATE_EEPROM;
5802 }
5803 }
5804 }
5805 }
5806
James Bottomley 47b5d692005-04-24 02:38:05 -05005807 FPT_sresb(p_port,p_card);
5808 FPT_Wait1Second(p_port);
5809 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5810 FPT_scsel(p_port);
5811 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005812 }
5813
Linus Torvalds1da177e2005-04-16 15:20:36 -07005814 }
5815
5816 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5817 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005818 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5819 assigned_id = 0;
5820 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821
5822 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005823 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005824
James Bottomley 47b5d692005-04-24 02:38:05 -05005825 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005826 if (i == ASSIGN_ID)
5827 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005828 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005830 i = FPT_scxferc(p_port,0x00);
5831 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005832 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005833 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005834
James Bottomley 47b5d692005-04-24 02:38:05 -05005835 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005836 {
5837 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005838 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005839 FPT_inisci(p_card, p_port, p_our_id);
5840 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5841 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005842 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005843 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005844 }
5845 }
5846 }
5847 }
5848
5849 else if (i == SET_P_FLAG)
5850 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005851 if (!(FPT_scsendi(p_port,
5852 &FPT_scamInfo[p_our_id].id_string[0])))
5853 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854 }
5855 }while (!assigned_id);
5856
James Bottomley 47b5d692005-04-24 02:38:05 -05005857 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005858 }
5859
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860 if (ScamFlg & SCAM_ENABLED)
5861 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005862 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 if (currCard->globalFlags & F_UPDATE_EEPROM)
5864 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005865 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005866 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5867 }
5868 }
5869
5870
Linus Torvalds1da177e2005-04-16 15:20:36 -07005871/*
5872 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5873 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005874 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5875 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005876 k++;
5877 }
5878
5879 if (k==2)
5880 currCard->globalFlags |= F_SINGLE_DEVICE;
5881 else
5882 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5883*/
5884}
5885
5886
5887/*---------------------------------------------------------------------
5888 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005889 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005890 *
5891 * Description: Gain control of the bus and wait SCAM select time (250ms)
5892 *
5893 *---------------------------------------------------------------------*/
5894
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005895static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005896{
5897 if (p_sel_type == INIT_SELTD)
5898 {
5899
5900 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5901
5902
5903 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005904 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005905
5906 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005907 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005908
5909 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5910
5911 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5912
5913 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5914 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005915 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005916 }
5917
5918
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5920
5921 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5922
5923 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5924 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005925 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005926 }
5927 }
5928
5929
5930 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5931 & ~ACTdeassert));
5932 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5933 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005934 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005935 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5936
5937 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5938
5939 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5940 & ~SCSI_BSY));
5941
James Bottomley 47b5d692005-04-24 02:38:05 -05005942 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005943
James Bottomley 47b5d692005-04-24 02:38:05 -05005944 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005945}
5946
5947
5948/*---------------------------------------------------------------------
5949 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005950 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005951 *
5952 * Description: Release the SCSI bus and disable SCAM selection.
5953 *
5954 *---------------------------------------------------------------------*/
5955
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005956static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005957{
5958 WR_HARPOON(p_port+hp_page_ctrl,
5959 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5960
5961
5962 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5963
5964 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5965 & ~SCSI_BUS_EN));
5966
5967 WR_HARPOON(p_port+hp_scsisig, 0x00);
5968
5969
5970 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5971 & ~SCAM_EN));
5972
5973 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5974 | ACTdeassert));
5975
Linus Torvalds1da177e2005-04-16 15:20:36 -07005976 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005977
5978 WR_HARPOON(p_port+hp_page_ctrl,
5979 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5980}
5981
5982
5983
5984/*---------------------------------------------------------------------
5985 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005986 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005987 *
5988 * Description: Assign an ID to all the SCAM devices.
5989 *
5990 *---------------------------------------------------------------------*/
5991
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005992static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005993{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005994 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005995
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005996 unsigned char i,k,scam_id;
5997 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005998 PNVRamInfo pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08005999 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006000
James Bottomley 47b5d692005-04-24 02:38:05 -05006001 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006002
James Bottomley 47b5d692005-04-24 02:38:05 -05006003 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006004
6005 while (!i)
6006 {
6007
6008 for (k=0; k < ID_STRING_LENGTH; k++)
6009 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006010 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006011 }
6012
James Bottomley 47b5d692005-04-24 02:38:05 -05006013 FPT_scxferc(p_port,SYNC_PTRN);
6014 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006015
James Bottomley 47b5d692005-04-24 02:38:05 -05006016 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006017 {
6018 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006019 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006020 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6021 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006022 temp_id_string[1] = crcBytes[2];
6023 temp_id_string[2] = crcBytes[0];
6024 temp_id_string[3] = crcBytes[1];
6025 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006026 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006027 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006028 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006029
6030 if (i == CLR_PRIORITY)
6031 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006032 FPT_scxferc(p_port,MISC_CODE);
6033 FPT_scxferc(p_port,CLR_P_FLAG);
6034 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006035 }
6036
6037 else if (i != NO_ID_AVAIL)
6038 {
6039 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006040 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006041 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006042 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006043
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006044 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006045
6046
6047 for (k=1; k < 0x08; k <<= 1)
6048 if (!( k & i ))
6049 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6050
James Bottomley 47b5d692005-04-24 02:38:05 -05006051 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006052
James Bottomley 47b5d692005-04-24 02:38:05 -05006053 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006054 }
6055 }
6056
6057 else
6058 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006059 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006060 }
6061
6062 } /*End while */
6063
James Bottomley 47b5d692005-04-24 02:38:05 -05006064 FPT_scxferc(p_port,SYNC_PTRN);
6065 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006066}
6067
6068
6069
6070
6071
6072/*---------------------------------------------------------------------
6073 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006074 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006075 *
6076 * Description: Select all the SCAM devices.
6077 *
6078 *---------------------------------------------------------------------*/
6079
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006080static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006081{
6082
6083 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006084 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006085
6086 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6087
6088
6089 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006090 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6091 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006092
6093
6094 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006095 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006096
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006097 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6098 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006099 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006100
6101 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6102}
6103
6104
6105
6106/*---------------------------------------------------------------------
6107 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006108 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006109 *
6110 * Description: Handshake the p_data (DB4-0) across the bus.
6111 *
6112 *---------------------------------------------------------------------*/
6113
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006114static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006115{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006116 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006117
6118 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6119
6120 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6121
6122 curr_data &= ~BIT(7);
6123
6124 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6125
James Bottomley 47b5d692005-04-24 02:38:05 -05006126 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6128
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006129 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006130
6131 curr_data |= BIT(6);
6132
6133 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6134
6135 curr_data &= ~BIT(5);
6136
6137 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6138
James Bottomley 47b5d692005-04-24 02:38:05 -05006139 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006140
6141 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6142 curr_data |= BIT(7);
6143
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145
6146 curr_data &= ~BIT(6);
6147
6148 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6149
James Bottomley 47b5d692005-04-24 02:38:05 -05006150 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151
6152 return(ret_data);
6153}
6154
6155
6156/*---------------------------------------------------------------------
6157 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006158 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006159 *
6160 * Description: Transfer our Identification string to determine if we
6161 * will be the dominant master.
6162 *
6163 *---------------------------------------------------------------------*/
6164
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006165static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006166{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006167 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006168
James Bottomley 47b5d692005-04-24 02:38:05 -05006169 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006170
6171 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6172
6173 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6174
6175 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006176 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177
6178 else if (p_id_string[byte_cnt] & bit_cnt)
6179
James Bottomley 47b5d692005-04-24 02:38:05 -05006180 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006181
6182 else {
6183
James Bottomley 47b5d692005-04-24 02:38:05 -05006184 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006186 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006187 }
6188
6189 if ((ret_data & 0x1C) == 0x10)
6190 return(0x00); /*End of isolation stage, we won! */
6191
6192 if (ret_data & 0x1C)
6193 return(0xFF);
6194
6195 if ((defer) && (!(ret_data & 0x1F)))
6196 return(0x01); /*End of isolation stage, we lost. */
6197
6198 } /*bit loop */
6199
6200 } /*byte loop */
6201
6202 if (defer)
6203 return(0x01); /*We lost */
6204 else
6205 return(0); /*We WON! Yeeessss! */
6206}
6207
6208
6209
6210/*---------------------------------------------------------------------
6211 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006212 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006213 *
6214 * Description: Transfer the Identification string.
6215 *
6216 *---------------------------------------------------------------------*/
6217
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006218static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006219{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006220 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006221
6222 the_data = 0;
6223
6224 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6225
6226 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6227
James Bottomley 47b5d692005-04-24 02:38:05 -05006228 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006229
6230 if (ret_data & 0xFC)
6231 return(0xFF);
6232
6233 else {
6234
6235 the_data <<= 1;
6236 if (ret_data & BIT(1)) {
6237 the_data |= 1;
6238 }
6239 }
6240
6241 if ((ret_data & 0x1F) == 0)
6242 {
6243/*
6244 if(bit_cnt != 0 || bit_cnt != 8)
6245 {
6246 byte_cnt = 0;
6247 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006248 FPT_scxferc(p_port, SYNC_PTRN);
6249 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006250 continue;
6251 }
6252*/
6253 if (byte_cnt)
6254 return(0x00);
6255 else
6256 return(0xFF);
6257 }
6258
6259 } /*bit loop */
6260
6261 p_id_string[byte_cnt] = the_data;
6262
6263 } /*byte loop */
6264
6265 return(0);
6266}
6267
6268
6269
6270/*---------------------------------------------------------------------
6271 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006272 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006273 *
6274 * Description: Sample the SCSI data bus making sure the signal has been
6275 * deasserted for the correct number of consecutive samples.
6276 *
6277 *---------------------------------------------------------------------*/
6278
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006279static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006280{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006281 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006282
6283 i = 0;
6284 while ( i < MAX_SCSI_TAR ) {
6285
6286 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6287
6288 i = 0;
6289
6290 else
6291
6292 i++;
6293
6294 }
6295}
6296
6297
6298
6299/*---------------------------------------------------------------------
6300 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006301 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006302 *
6303 * Description: Sample the SCSI Signal lines making sure the signal has been
6304 * deasserted for the correct number of consecutive samples.
6305 *
6306 *---------------------------------------------------------------------*/
6307
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006308static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006309{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006310 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006311
6312 i = 0;
6313 while ( i < MAX_SCSI_TAR ) {
6314
6315 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6316
6317 i = 0;
6318
6319 else
6320
6321 i++;
6322
6323 }
6324}
6325
6326
6327/*---------------------------------------------------------------------
6328 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006329 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006330 *
6331 * Description: Make sure we received a valid data byte.
6332 *
6333 *---------------------------------------------------------------------*/
6334
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006335static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006337 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006338
6339 for (count=1; count < 0x08; count<<=1) {
6340 if (!(p_quintet & count))
6341 p_quintet -= 0x80;
6342 }
6343
6344 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006345 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346
6347 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006348 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006349}
6350
6351
6352/*---------------------------------------------------------------------
6353 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006354 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006355 *
6356 * Description: Select the specified device ID using a selection timeout
6357 * less than 4ms. If somebody responds then it is a legacy
6358 * drive and this ID must be marked as such.
6359 *
6360 *---------------------------------------------------------------------*/
6361
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006362static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006364 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006365
6366 WR_HARPOON(p_port+hp_page_ctrl,
6367 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6368
6369 ARAM_ACCESS(p_port);
6370
6371 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6372 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6373
6374
6375 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6376 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6377 }
6378 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6379
6380 WRW_HARPOON((p_port+hp_intstat),
6381 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6382
6383 WR_HARPOON(p_port+hp_select_id, targ_id);
6384
6385 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6386 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6387 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6388
6389
6390 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6391 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6392
6393 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006394 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006395
6396 DISABLE_AUTO(p_port);
6397
6398 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6399 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6400
6401 SGRAM_ACCESS(p_port);
6402
6403 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6404
6405 WRW_HARPOON((p_port+hp_intstat),
6406 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6407
6408 WR_HARPOON(p_port+hp_page_ctrl,
6409 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6410
James Bottomley 47b5d692005-04-24 02:38:05 -05006411 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006412 }
6413
6414 else {
6415
6416 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6417 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6418 {
6419 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6420 ACCEPT_MSG(p_port);
6421 }
6422 }
6423
6424 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6425
6426 WR_HARPOON(p_port+hp_page_ctrl,
6427 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6428
James Bottomley 47b5d692005-04-24 02:38:05 -05006429 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006430 }
6431}
6432
Linus Torvalds1da177e2005-04-16 15:20:36 -07006433/*---------------------------------------------------------------------
6434 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006435 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436 *
6437 * Description: Wait to be selected by another SCAM initiator.
6438 *
6439 *---------------------------------------------------------------------*/
6440
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006441static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442{
6443 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6444}
6445
6446
6447/*---------------------------------------------------------------------
6448 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006449 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006450 *
6451 * Description: Setup the data Structure with the info from the EEPROM.
6452 *
6453 *---------------------------------------------------------------------*/
6454
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006455static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006457 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006458 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006459 PNVRamInfo pCurrNvRam;
6460
James Bottomley 47b5d692005-04-24 02:38:05 -05006461 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006462
6463 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6464 max_id = 0x08;
6465
6466 else
6467 max_id = 0x10;
6468
6469 if(pCurrNvRam){
6470 for(i = 0; i < max_id; i++){
6471
6472 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006473 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006474 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006475 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006476
James Bottomley 47b5d692005-04-24 02:38:05 -05006477 if(FPT_scamInfo[i].id_string[0] == 0x00)
6478 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006479 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006480 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006481
6482 }
6483 }else {
6484 for (i=0; i < max_id; i++)
6485 {
6486 for (k=0; k < ID_STRING_LENGTH; k+=2)
6487 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006488 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6489 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006490 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006491 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006492 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006493 }
6494
James Bottomley 47b5d692005-04-24 02:38:05 -05006495 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6496 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497
James Bottomley 47b5d692005-04-24 02:38:05 -05006498 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499
6500 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006501 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
6503 }
6504 }
6505 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006506 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006507
6508}
6509
6510/*---------------------------------------------------------------------
6511 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006512 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006513 *
6514 * Description: Match the Device ID string with our values stored in
6515 * the EEPROM.
6516 *
6517 *---------------------------------------------------------------------*/
6518
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006519static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520{
6521
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006522 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006523
6524
6525 for (i=0; i < MAX_SCSI_TAR; i++) {
6526
James Bottomley 47b5d692005-04-24 02:38:05 -05006527 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528
6529 for (k=0; k < ID_STRING_LENGTH; k++)
6530 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006531 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6532 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006533 }
6534
6535 if (match)
6536 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006537 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538 return(i);
6539 }
6540
Linus Torvalds1da177e2005-04-16 15:20:36 -07006541 }
6542
6543
6544
6545 if (p_id_string[0] & BIT(5))
6546 i = 8;
6547 else
6548 i = MAX_SCSI_TAR;
6549
6550 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006551 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006552 else
6553 match = 7;
6554
6555 while (i > 0)
6556 {
6557 i--;
6558
James Bottomley 47b5d692005-04-24 02:38:05 -05006559 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 {
6561 for (k=0; k < ID_STRING_LENGTH; k++)
6562 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006563 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006564 }
6565
James Bottomley 47b5d692005-04-24 02:38:05 -05006566 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567
James Bottomley 47b5d692005-04-24 02:38:05 -05006568 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6569 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006570 return(match);
6571
6572 }
6573
6574
6575 match--;
6576
6577 if (match == 0xFF)
6578 {
6579 if (p_id_string[0] & BIT(5))
6580 match = 7;
6581 else
6582 match = MAX_SCSI_TAR-1;
6583 }
6584 }
6585
6586
6587
6588 if (p_id_string[0] & BIT(7))
6589 {
6590 return(CLR_PRIORITY);
6591 }
6592
6593
6594 if (p_id_string[0] & BIT(5))
6595 i = 8;
6596 else
6597 i = MAX_SCSI_TAR;
6598
6599 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006600 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006601 else
6602 match = 7;
6603
6604 while (i > 0)
6605 {
6606
6607 i--;
6608
James Bottomley 47b5d692005-04-24 02:38:05 -05006609 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006610 {
6611 for (k=0; k < ID_STRING_LENGTH; k++)
6612 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006613 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006614 }
6615
James Bottomley 47b5d692005-04-24 02:38:05 -05006616 FPT_scamInfo[match].id_string[0] |= BIT(7);
6617 FPT_scamInfo[match].state = ID_ASSIGNED;
6618 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6619 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006620 return(match);
6621
6622 }
6623
6624
6625 match--;
6626
6627 if (match == 0xFF)
6628 {
6629 if (p_id_string[0] & BIT(5))
6630 match = 7;
6631 else
6632 match = MAX_SCSI_TAR-1;
6633 }
6634 }
6635
6636 return(NO_ID_AVAIL);
6637}
6638
6639
6640/*---------------------------------------------------------------------
6641 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006642 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006643 *
6644 * Description: Save off the device SCAM ID strings.
6645 *
6646 *---------------------------------------------------------------------*/
6647
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006648static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006649{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006650 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006651 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006652
6653
6654 sum_data = 0x0000;
6655
6656 for (i = 1; i < EE_SCAMBASE/2; i++)
6657 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006658 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659 }
6660
6661
James Bottomley 47b5d692005-04-24 02:38:05 -05006662 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006663
6664 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6665 max_id = 0x08;
6666
6667 else
6668 max_id = 0x10;
6669
6670 for (i=0; i < max_id; i++)
6671 {
6672
6673 for (k=0; k < ID_STRING_LENGTH; k+=2)
6674 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006675 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006677 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006678 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006679 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6680 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006681 }
6682 }
6683
6684
James Bottomley 47b5d692005-04-24 02:38:05 -05006685 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6686 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006688
6689/*---------------------------------------------------------------------
6690 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006691 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006692 *
6693 * Description: Setup the Xbow for normal operation.
6694 *
6695 *---------------------------------------------------------------------*/
6696
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006697static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006699unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006700
6701 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006702 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006703
6704 WR_HARPOON(port+hp_scsireset,0x00);
6705 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6706
6707 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6708 FIFO_CLR));
6709
6710 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6711
6712 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6713
6714 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6715 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6716
6717 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6718
James Bottomley 47b5d692005-04-24 02:38:05 -05006719 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6721
6722 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006723 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724
James Bottomley 47b5d692005-04-24 02:38:05 -05006725 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006726
6727 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6728
6729 /* Turn on SCSI_MODE8 for narrow cards to fix the
6730 strapping issue with the DUAL CHANNEL card */
6731 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6732 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6733
Linus Torvalds1da177e2005-04-16 15:20:36 -07006734 WR_HARPOON(port+hp_page_ctrl, i);
6735
6736}
6737
6738
6739/*---------------------------------------------------------------------
6740 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006741 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006742 *
6743 * Description: Initialize the BusMaster for normal operations.
6744 *
6745 *---------------------------------------------------------------------*/
6746
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006747static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006748{
6749
6750
6751 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6752 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6753
6754 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6755
6756
6757 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6758
6759 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6760
6761
Linus Torvalds1da177e2005-04-16 15:20:36 -07006762 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6763 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6764 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6765 ~SCATTER_EN));
6766}
6767
6768
6769/*---------------------------------------------------------------------
6770 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006771 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006772 *
6773 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6774 * necessary.
6775 *
6776 *---------------------------------------------------------------------*/
6777
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006778static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006779{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006780 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006781
6782 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6783 max_wd_cnt = EEPROM_WD_CNT;
6784 else
6785 max_wd_cnt = EEPROM_WD_CNT * 2;
6786
James Bottomley 47b5d692005-04-24 02:38:05 -05006787 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006788
6789 if (temp == 0x4641) {
6790
6791 for (index = 2; index < max_wd_cnt; index++) {
6792
James Bottomley 47b5d692005-04-24 02:38:05 -05006793 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006794
6795 }
6796
James Bottomley 47b5d692005-04-24 02:38:05 -05006797 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006798
6799 return; /*EEPROM is Okay so return now! */
6800 }
6801 }
6802
6803
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006804 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006805
6806 for (index = 0; index < max_wd_cnt; index++) {
6807
James Bottomley 47b5d692005-04-24 02:38:05 -05006808 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006809 }
6810
6811 temp = 0;
6812
James Bottomley 47b5d692005-04-24 02:38:05 -05006813 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006815 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006817 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006818 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006819 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006821 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006823 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006825 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006827 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 temp += 0x0007;
6829
James Bottomley 47b5d692005-04-24 02:38:05 -05006830 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006832 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006834 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006835 temp += 0x0000;
6836
James Bottomley 47b5d692005-04-24 02:38:05 -05006837 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006839 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006841 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/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_TBL89/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_TBLab/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_TBLcd/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_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006852 temp += 0x4242;
6853
6854
James Bottomley 47b5d692005-04-24 02:38:05 -05006855 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006857 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006859 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006861 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006863 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006864 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006866 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006867 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006868 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006869 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870 temp += 0x2020;
6871
6872 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006873 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874 temp += (0x0700+TYPE_CODE0);
6875 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877 temp += 0x5542; /* BUSLOGIC */
6878 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006879 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006880 temp += 0x4C53;
6881 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006882 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 temp += 0x474F;
6884 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006885 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886 temp += 0x4349;
6887 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006888 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889 temp += 0x5442; /* BT- 930 */
6890 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006891 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892 temp += 0x202D;
6893 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006894 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895 temp += 0x3339;
6896 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006897 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898 temp += 0x2030;
6899 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006900 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006901 temp += 0x5453;
6902 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006903 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006904 temp += 0x5645;
6905 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006906 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006907 temp += 0x2045;
6908 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006909 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910 temp += 0x202F;
6911 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006912 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006913 temp += 0x4F4A;
6914 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006915 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006916 temp += 0x204E;
6917 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006918 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006919 temp += 0x3539;
6920
6921
6922
James Bottomley 47b5d692005-04-24 02:38:05 -05006923 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006925 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006926
6927}
6928
Linus Torvalds1da177e2005-04-16 15:20:36 -07006929
6930/*---------------------------------------------------------------------
6931 *
6932 * Function: Queue Search Select
6933 *
6934 * Description: Try to find a new command to execute.
6935 *
6936 *---------------------------------------------------------------------*/
6937
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006938static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006939{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006940 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006941 PSCCBMgr_tar_info currTar_Info;
6942 PSCCB pOldSccb;
6943
6944 scan_ptr = pCurrCard->scanIndex;
6945 do
6946 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006947 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006948 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6949 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6950 {
6951 if (currTar_Info->TarSelQ_Cnt != 0)
6952 {
6953
6954 scan_ptr++;
6955 if (scan_ptr == MAX_SCSI_TAR)
6956 scan_ptr = 0;
6957
6958 for(lun=0; lun < MAX_LUN; lun++)
6959 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006960 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006961 {
6962
6963 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6964 pOldSccb = NULL;
6965
6966 while((pCurrCard->currentSCCB != NULL) &&
6967 (lun != pCurrCard->currentSCCB->Lun))
6968 {
6969 pOldSccb = pCurrCard->currentSCCB;
6970 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6971 Sccb_forwardlink;
6972 }
6973 if(pCurrCard->currentSCCB == NULL)
6974 continue;
6975 if(pOldSccb != NULL)
6976 {
6977 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6978 Sccb_forwardlink;
6979 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6980 Sccb_backlink;
6981 currTar_Info->TarSelQ_Cnt--;
6982 }
6983 else
6984 {
6985 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6986
6987 if (currTar_Info->TarSelQ_Head == NULL)
6988 {
6989 currTar_Info->TarSelQ_Tail = NULL;
6990 currTar_Info->TarSelQ_Cnt = 0;
6991 }
6992 else
6993 {
6994 currTar_Info->TarSelQ_Cnt--;
6995 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
6996 }
6997 }
6998 pCurrCard->scanIndex = scan_ptr;
6999
7000 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7001
7002 break;
7003 }
7004 }
7005 }
7006
7007 else
7008 {
7009 scan_ptr++;
7010 if (scan_ptr == MAX_SCSI_TAR) {
7011 scan_ptr = 0;
7012 }
7013 }
7014
7015 }
7016 else
7017 {
7018 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007019 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007020 {
7021
7022 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7023
7024 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7025
7026 if (currTar_Info->TarSelQ_Head == NULL)
7027 {
7028 currTar_Info->TarSelQ_Tail = NULL;
7029 currTar_Info->TarSelQ_Cnt = 0;
7030 }
7031 else
7032 {
7033 currTar_Info->TarSelQ_Cnt--;
7034 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7035 }
7036
7037 scan_ptr++;
7038 if (scan_ptr == MAX_SCSI_TAR)
7039 scan_ptr = 0;
7040
7041 pCurrCard->scanIndex = scan_ptr;
7042
7043 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7044
7045 break;
7046 }
7047
7048 else
7049 {
7050 scan_ptr++;
7051 if (scan_ptr == MAX_SCSI_TAR)
7052 {
7053 scan_ptr = 0;
7054 }
7055 }
7056 }
7057 } while (scan_ptr != pCurrCard->scanIndex);
7058}
7059
7060
7061/*---------------------------------------------------------------------
7062 *
7063 * Function: Queue Select Fail
7064 *
7065 * Description: Add the current SCCB to the head of the Queue.
7066 *
7067 *---------------------------------------------------------------------*/
7068
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007069static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007071 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007072 PSCCBMgr_tar_info currTar_Info;
7073
7074 if (pCurrCard->currentSCCB != NULL)
7075 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007076 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007077 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007078
7079 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7080
7081 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7082
7083 if (currTar_Info->TarSelQ_Cnt == 0)
7084 {
7085 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7086 }
7087
7088 else
7089 {
7090 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7091 }
7092
7093
7094 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7095
7096 pCurrCard->currentSCCB = NULL;
7097 currTar_Info->TarSelQ_Cnt++;
7098 }
7099}
7100/*---------------------------------------------------------------------
7101 *
7102 * Function: Queue Command Complete
7103 *
7104 * Description: Call the callback function with the current SCCB.
7105 *
7106 *---------------------------------------------------------------------*/
7107
James Bottomley 47b5d692005-04-24 02:38:05 -05007108static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007109 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007110{
7111
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007112 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007113 CALL_BK_FN callback;
7114 PSCCBMgr_tar_info currTar_Info;
7115
7116 SCSIcmd = p_sccb->Cdb[0];
7117
7118
7119 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7120
7121 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7122 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7123 (p_sccb->TargetStatus != SSCHECK))
7124
7125 if ((SCSIcmd == SCSI_READ) ||
7126 (SCSIcmd == SCSI_WRITE) ||
7127 (SCSIcmd == SCSI_READ_EXTENDED) ||
7128 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7129 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7130 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7131 (pCurrCard->globalFlags & F_NO_FILTER)
7132 )
7133 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7134 }
7135
7136
7137 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7138 {
7139 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7140 p_sccb->SccbStatus = SCCB_ERROR;
7141 else
7142 p_sccb->SccbStatus = SCCB_SUCCESS;
7143 }
7144
7145 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7146
7147 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7148 for (i=0; i < 6; i++) {
7149 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7150 }
7151 }
7152
7153 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7154 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7155
James Bottomley 47b5d692005-04-24 02:38:05 -05007156 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007157 }
7158
7159 pCurrCard->cmdCounter--;
7160 if (!pCurrCard->cmdCounter) {
7161
7162 if (pCurrCard->globalFlags & F_GREEN_PC) {
7163 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7164 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7165 }
7166
7167 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7168 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7169
7170 }
7171
7172 if(pCurrCard->discQCount != 0)
7173 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007174 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007175 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7176 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7177 {
7178 pCurrCard->discQCount--;
7179 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7180 }
7181 else
7182 {
7183 if(p_sccb->Sccb_tag)
7184 {
7185 pCurrCard->discQCount--;
7186 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7187 }else
7188 {
7189 pCurrCard->discQCount--;
7190 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7191 }
7192 }
7193
7194 }
7195
7196 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7197 callback(p_sccb);
7198 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7199 pCurrCard->currentSCCB = NULL;
7200}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007201
7202
7203/*---------------------------------------------------------------------
7204 *
7205 * Function: Queue Disconnect
7206 *
7207 * Description: Add SCCB to our disconnect array.
7208 *
7209 *---------------------------------------------------------------------*/
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007210static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007211{
7212 PSCCBMgr_tar_info currTar_Info;
7213
James Bottomley 47b5d692005-04-24 02:38:05 -05007214 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007215
James Bottomley 47b5d692005-04-24 02:38:05 -05007216 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7218 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007219 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007220 }
7221 else
7222 {
7223 if (p_sccb->Sccb_tag)
7224 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007225 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7226 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7227 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007228 }else
7229 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007230 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007231 }
7232 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007233 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007234}
7235
7236
7237/*---------------------------------------------------------------------
7238 *
7239 * Function: Queue Flush SCCB
7240 *
7241 * Description: Flush all SCCB's back to the host driver for this target.
7242 *
7243 *---------------------------------------------------------------------*/
7244
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007245static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007246{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007247 unsigned char qtag,thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007248 PSCCB currSCCB;
7249 PSCCBMgr_tar_info currTar_Info;
7250
James Bottomley 47b5d692005-04-24 02:38:05 -05007251 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007252 if(currSCCB != NULL)
7253 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007254 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007255 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007256
7257 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7258
James Bottomley 47b5d692005-04-24 02:38:05 -05007259 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7260 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007261 {
7262
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007263 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007264
James Bottomley 47b5d692005-04-24 02:38:05 -05007265 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007266
James Bottomley 47b5d692005-04-24 02:38:05 -05007267 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007268 currTar_Info->TarTagQ_Cnt--;
7269
7270 }
7271 }
7272 }
7273
7274}
7275
7276/*---------------------------------------------------------------------
7277 *
7278 * Function: Queue Flush Target SCCB
7279 *
7280 * Description: Flush all SCCB's back to the host driver for this target.
7281 *
7282 *---------------------------------------------------------------------*/
7283
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007284static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7285 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007286{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007287 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007288 PSCCBMgr_tar_info currTar_Info;
7289
James Bottomley 47b5d692005-04-24 02:38:05 -05007290 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007291
7292 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7293
James Bottomley 47b5d692005-04-24 02:38:05 -05007294 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7295 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296 {
7297
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007298 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299
James Bottomley 47b5d692005-04-24 02:38:05 -05007300 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007301
James Bottomley 47b5d692005-04-24 02:38:05 -05007302 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007303 currTar_Info->TarTagQ_Cnt--;
7304
7305 }
7306 }
7307
7308}
7309
7310
7311
7312
7313
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007314static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007315{
7316 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007317 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007318
7319 p_SCCB->Sccb_forwardlink = NULL;
7320
7321 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7322
7323 if (currTar_Info->TarSelQ_Cnt == 0) {
7324
7325 currTar_Info->TarSelQ_Head = p_SCCB;
7326 }
7327
7328 else {
7329
7330 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7331 }
7332
7333
7334 currTar_Info->TarSelQ_Tail = p_SCCB;
7335 currTar_Info->TarSelQ_Cnt++;
7336}
7337
7338
7339/*---------------------------------------------------------------------
7340 *
7341 * Function: Queue Find SCCB
7342 *
7343 * Description: Search the target select Queue for this SCCB, and
7344 * remove it if found.
7345 *
7346 *---------------------------------------------------------------------*/
7347
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007348static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007349{
7350 PSCCB q_ptr;
7351 PSCCBMgr_tar_info currTar_Info;
7352
James Bottomley 47b5d692005-04-24 02:38:05 -05007353 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007354
7355 q_ptr = currTar_Info->TarSelQ_Head;
7356
7357 while(q_ptr != NULL) {
7358
7359 if (q_ptr == p_SCCB) {
7360
7361
7362 if (currTar_Info->TarSelQ_Head == q_ptr) {
7363
7364 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7365 }
7366
7367 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7368
7369 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7370 }
7371
7372 if (q_ptr->Sccb_forwardlink != NULL) {
7373 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7374 }
7375
7376 if (q_ptr->Sccb_backlink != NULL) {
7377 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7378 }
7379
7380 currTar_Info->TarSelQ_Cnt--;
7381
James Bottomley 47b5d692005-04-24 02:38:05 -05007382 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007383 }
7384
7385 else {
7386 q_ptr = q_ptr->Sccb_forwardlink;
7387 }
7388 }
7389
7390
James Bottomley 47b5d692005-04-24 02:38:05 -05007391 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007392
7393}
7394
7395
7396/*---------------------------------------------------------------------
7397 *
7398 * Function: Utility Update Residual Count
7399 *
7400 * Description: Update the XferCnt to the remaining byte count.
7401 * If we transferred all the data then just write zero.
7402 * If Non-SG transfer then report Total Cnt - Actual Transfer
7403 * Cnt. For SG transfers add the count fields of all
7404 * remaining SG elements, as well as any partial remaining
7405 * element.
7406 *
7407 *---------------------------------------------------------------------*/
7408
James Bottomley 47b5d692005-04-24 02:38:05 -05007409static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007410{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007411 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007412 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007413 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007414
7415 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7416
7417 p_SCCB->DataLength = 0x0000;
7418 }
7419
7420 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7421
7422 partial_cnt = 0x0000;
7423
7424 sg_index = p_SCCB->Sccb_sgseg;
7425
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007426 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007427
7428 if (p_SCCB->Sccb_SGoffset) {
7429
7430 partial_cnt = p_SCCB->Sccb_SGoffset;
7431 sg_index++;
7432 }
7433
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007434 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007435 p_SCCB->DataLength ) {
7436
7437 partial_cnt += *(sg_ptr+(sg_index * 2));
7438 sg_index++;
7439 }
7440
7441 p_SCCB->DataLength = partial_cnt;
7442 }
7443
7444 else {
7445
7446 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7447 }
7448}
7449
7450
7451/*---------------------------------------------------------------------
7452 *
7453 * Function: Wait 1 Second
7454 *
7455 * Description: Wait for 1 second.
7456 *
7457 *---------------------------------------------------------------------*/
7458
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007459static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007460{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007461 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007462
7463 for(i=0; i < 4; i++) {
7464
James Bottomley 47b5d692005-04-24 02:38:05 -05007465 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007466
7467 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7468 break;
7469
7470 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7471 break;
7472 }
7473}
7474
7475
7476/*---------------------------------------------------------------------
7477 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007478 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007479 *
7480 * Description: Wait the desired delay.
7481 *
7482 *---------------------------------------------------------------------*/
7483
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007484static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007485{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007486 unsigned char old_timer;
7487 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007488
7489 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7490
7491 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7492 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7493
7494 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7495 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007496 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007497
7498
7499 WR_HARPOON(p_port+hp_portctrl_0,
7500 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7501
7502 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7503
7504 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7505 break;
7506
7507 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7508 break;
7509 }
7510
7511 WR_HARPOON(p_port+hp_portctrl_0,
7512 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7513
7514 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007515 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007516
7517 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7518
7519 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7520}
7521
7522
7523/*---------------------------------------------------------------------
7524 *
7525 * Function: Enable/Disable Write to EEPROM
7526 *
7527 * Description: The EEPROM must first be enabled for writes
7528 * A total of 9 clocks are needed.
7529 *
7530 *---------------------------------------------------------------------*/
7531
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007532static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007533{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007534 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007535
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007536 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 -07007537
7538 if (p_mode)
7539
James Bottomley 47b5d692005-04-24 02:38:05 -05007540 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007541
7542 else
7543
7544
James Bottomley 47b5d692005-04-24 02:38:05 -05007545 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007546
7547 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7548 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7549}
7550
7551
7552/*---------------------------------------------------------------------
7553 *
7554 * Function: Write EEPROM
7555 *
7556 * Description: Write a word to the EEPROM at the specified
7557 * address.
7558 *
7559 *---------------------------------------------------------------------*/
7560
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007561static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007562{
7563
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007564 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007565 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007566
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007567 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 -07007568 (SEE_MS | SEE_CS));
7569
7570
7571
James Bottomley 47b5d692005-04-24 02:38:05 -05007572 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007573
7574
7575 ee_value |= (SEE_MS + SEE_CS);
7576
7577 for(i = 0x8000; i != 0; i>>=1) {
7578
7579 if (i & ee_data)
7580 ee_value |= SEE_DO;
7581 else
7582 ee_value &= ~SEE_DO;
7583
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 ee_value |= SEE_CLK; /* Clock data! */
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7589 ee_value &= ~SEE_CLK;
7590 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7591 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7592 }
7593 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7594 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7595
James Bottomley 47b5d692005-04-24 02:38:05 -05007596 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007597
7598 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7599 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7600 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7601}
7602
7603/*---------------------------------------------------------------------
7604 *
7605 * Function: Read EEPROM
7606 *
7607 * Description: Read a word from the EEPROM at the desired
7608 * address.
7609 *
7610 *---------------------------------------------------------------------*/
7611
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007612static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007613{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007614 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007615
7616 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007617 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007618 do
7619 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007620 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007621
7622 if(ee_data1 == ee_data2)
7623 return(ee_data1);
7624
7625 ee_data1 = ee_data2;
7626 i++;
7627
7628 }while(i < 4);
7629
7630 return(ee_data1);
7631}
7632
7633/*---------------------------------------------------------------------
7634 *
7635 * Function: Read EEPROM Original
7636 *
7637 * Description: Read a word from the EEPROM at the desired
7638 * address.
7639 *
7640 *---------------------------------------------------------------------*/
7641
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007642static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007643{
7644
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007645 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007646 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007647
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007648 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 -07007649 (SEE_MS | SEE_CS));
7650
7651
James Bottomley 47b5d692005-04-24 02:38:05 -05007652 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007653
7654
7655 ee_value |= (SEE_MS + SEE_CS);
7656 ee_data = 0;
7657
7658 for(i = 1; i <= 16; i++) {
7659
7660 ee_value |= SEE_CLK; /* Clock data! */
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7662 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7663 ee_value &= ~SEE_CLK;
7664 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7665 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7666
7667 ee_data <<= 1;
7668
7669 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7670 ee_data |= 1;
7671 }
7672
7673 ee_value &= ~(SEE_MS + SEE_CS);
7674 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7676
7677 return(ee_data);
7678}
7679
7680
7681/*---------------------------------------------------------------------
7682 *
7683 * Function: Send EE command and Address to the EEPROM
7684 *
7685 * Description: Transfers the correct command and sends the address
7686 * to the eeprom.
7687 *
7688 *---------------------------------------------------------------------*/
7689
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007690static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007691{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007692 unsigned char ee_value;
7693 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007694
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007695 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007696
7697
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007698 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007699
7700
7701 ee_value = SEE_MS;
7702 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7703
7704 ee_value |= SEE_CS; /* Set CS to EEPROM */
7705 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7706
7707
7708 for(i = 0x04; i != 0; i>>=1) {
7709
7710 if (i & ee_cmd)
7711 ee_value |= SEE_DO;
7712 else
7713 ee_value &= ~SEE_DO;
7714
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 ee_value |= SEE_CLK; /* Clock data! */
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7720 ee_value &= ~SEE_CLK;
7721 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7722 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7723 }
7724
7725
7726 if (narrow_flg)
7727 i = 0x0080;
7728
7729 else
7730 i = 0x0200;
7731
7732
7733 while (i != 0) {
7734
7735 if (i & ee_addr)
7736 ee_value |= SEE_DO;
7737 else
7738 ee_value &= ~SEE_DO;
7739
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 ee_value |= SEE_CLK; /* Clock data! */
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7745 ee_value &= ~SEE_CLK;
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748
7749 i >>= 1;
7750 }
7751}
7752
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007753static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007754{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007755 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007756 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007757 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007758 for (i=0; i < ID_STRING_LENGTH; i++)
7759 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007760 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007761 for(j=0; j < 8; j++)
7762 {
7763 if ((crc ^ ch) & 1)
7764 crc = (crc >> 1) ^ CRCMASK;
7765 else
7766 crc >>= 1;
7767 ch >>= 1;
7768 }
7769 }
7770 return(crc);
7771}
7772
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007773static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007774{
7775 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007776 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007777 lrc = 0;
7778 for(i = 0; i < ID_STRING_LENGTH; i++)
7779 lrc ^= buffer[i];
7780 return(lrc);
7781}
7782
7783
7784
7785/*
7786 The following inline definitions avoid type conflicts.
7787*/
7788
7789static inline unsigned char
7790FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7791{
7792 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7793}
7794
7795
7796static inline FlashPoint_CardHandle_T
7797FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7798{
7799 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7800}
7801
7802static inline void
7803FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7804{
7805 FlashPoint_ReleaseHostAdapter(CardHandle);
7806}
7807
7808
7809static inline void
7810FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7811{
7812 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7813}
7814
7815
7816static inline void
7817FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7818{
7819 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7820}
7821
7822
7823static inline boolean
7824FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7825{
7826 return FlashPoint_InterruptPending(CardHandle);
7827}
7828
7829
7830static inline int
7831FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7832{
7833 return FlashPoint_HandleInterrupt(CardHandle);
7834}
7835
7836
7837#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7838#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7839#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7840#define FlashPoint_StartCCB FlashPoint__StartCCB
7841#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7842#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7843#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7844
7845
Linus Torvalds1da177e2005-04-16 15:20:36 -07007846#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7847
7848
7849/*
7850 Define prototypes for the FlashPoint SCCB Manager Functions.
7851*/
7852
7853extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7854extern FlashPoint_CardHandle_T
7855 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7856extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7857extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7858extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7859extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7860extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007861
7862
7863#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */