blob: 1d1e4413c8d1636937670d736ef1369c2ba7e30a [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
43typedef unsigned char UCHAR;
44typedef unsigned short USHORT;
45typedef unsigned int UINT;
46typedef unsigned long ULONG;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
48
Linus Torvalds1da177e2005-04-16 15:20:36 -070049typedef unsigned short * ushort_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
51
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#define s08bits char
53#define s16bits short
54#define s32bits long
55
56#define u08bits unsigned s08bits
57#define u16bits unsigned s16bits
58#define u32bits unsigned s32bits
59
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
62#define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
63#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
64
65
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
James Bottomley 47b5d692005-04-24 02:38:05 -050068typedef struct _SCCB *PSCCB;
69typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
71
72typedef struct SCCBMgr_info {
73 ULONG si_baseaddr;
74 UCHAR si_present;
75 UCHAR si_intvect;
76 UCHAR si_id;
77 UCHAR si_lun;
78 USHORT si_fw_revision;
79 USHORT si_per_targ_init_sync;
80 USHORT si_per_targ_fast_nego;
81 USHORT si_per_targ_ultra_nego;
82 USHORT si_per_targ_no_disc;
83 USHORT si_per_targ_wide_nego;
84 USHORT si_flags;
85 UCHAR si_card_family;
86 UCHAR si_bustype;
87 UCHAR si_card_model[3];
88 UCHAR si_relative_cardnum;
89 UCHAR si_reserved[4];
90 ULONG si_OS_reserved;
91 UCHAR si_XlatInfo[4];
92 ULONG si_reserved2[5];
93 ULONG si_secondary_range;
94} SCCBMGR_INFO;
95
James Bottomley 47b5d692005-04-24 02:38:05 -050096typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
98
James Bottomley 47b5d692005-04-24 02:38:05 -050099#define SCSI_PARITY_ENA 0x0001
100#define LOW_BYTE_TERM 0x0010
101#define HIGH_BYTE_TERM 0x0020
102#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104#define SUPPORT_16TAR_32LUN 0x0002
105#define SOFT_RESET 0x0004
106#define EXTENDED_TRANSLATION 0x0008
107#define POST_ALL_UNDERRRUNS 0x0040
108#define FLAG_SCAM_ENABLED 0x0080
109#define FLAG_SCAM_LEVEL2 0x0100
110
111
112
113
114#define HARPOON_FAMILY 0x02
115
116
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
Alexey Dobriyan323579882006-01-15 02:12:54 +0100118/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 * The UCB Manager treats the SCCB as it's 'native hardware structure'
120 */
121
122
123#pragma pack(1)
124typedef struct _SCCB {
125 UCHAR OperationCode;
126 UCHAR ControlByte;
127 UCHAR CdbLength;
128 UCHAR RequestSenseLength;
129 ULONG DataLength;
130 ULONG DataPointer;
131 UCHAR CcbRes[2];
132 UCHAR HostStatus;
133 UCHAR TargetStatus;
134 UCHAR TargID;
135 UCHAR Lun;
136 UCHAR Cdb[12];
137 UCHAR CcbRes1;
138 UCHAR Reserved1;
139 ULONG Reserved2;
140 ULONG SensePointer;
141
142
143 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
144 ULONG SccbIOPort; /* Identifies board base port */
145 UCHAR SccbStatus;
146 UCHAR SCCBRes2;
147 USHORT SccbOSFlags;
148
149
150 ULONG Sccb_XferCnt; /* actual transfer count */
151 ULONG Sccb_ATC;
152 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
153 ULONG Sccb_res1;
154 USHORT Sccb_MGRFlags;
155 USHORT Sccb_sgseg;
156 UCHAR Sccb_scsimsg; /* identify msg for selection */
157 UCHAR Sccb_tag;
158 UCHAR Sccb_scsistat;
159 UCHAR Sccb_idmsg; /* image of last msg in */
160 PSCCB Sccb_forwardlink;
161 PSCCB Sccb_backlink;
162 ULONG Sccb_savedATC;
163 UCHAR Save_Cdb[6];
164 UCHAR Save_CdbLen;
165 UCHAR Sccb_XferState;
166 ULONG Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 } SCCB;
168
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
170#pragma pack()
171
172
173
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174#define SCATTER_GATHER_COMMAND 0x02
175#define RESIDUAL_COMMAND 0x03
176#define RESIDUAL_SG_COMMAND 0x04
177#define RESET_COMMAND 0x81
178
179
180#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
181#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182#define SCCB_DATA_XFER_OUT 0x10 /* Write */
183#define SCCB_DATA_XFER_IN 0x08 /* Read */
184
185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
187
188
189#define BUS_FREE_ST 0
190#define SELECT_ST 1
191#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
192#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
193#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
194#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
195#define COMMAND_ST 6
196#define DATA_OUT_ST 7
197#define DATA_IN_ST 8
198#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
201
202#define F_HOST_XFER_DIR 0x01
203#define F_ALL_XFERRED 0x02
204#define F_SG_XFER 0x04
205#define F_AUTO_SENSE 0x08
206#define F_ODD_BALL_CNT 0x10
207#define F_NO_DATA_YET 0x80
208
209
210#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211#define F_DEV_SELECTED 0x04
212
213
214#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
215#define SCCB_DATA_UNDER_RUN 0x0C
216#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
217#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
219
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
221#define SCCB_BM_ERR 0x30 /* BusMaster error. */
222#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
223
224
225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227
228#define SCCB_IN_PROCESS 0x00
229#define SCCB_SUCCESS 0x01
230#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233
234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235#define ORION_FW_REV 3110
236
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237
238
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240
241#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
242
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243
James Bottomley 47b5d692005-04-24 02:38:05 -0500244#define MAX_SCSI_TAR 16
245#define MAX_LUN 32
246#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
250#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251
252
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -0800253#define RD_HARPOON(ioport) inb((u32bits)ioport)
254#define RDW_HARPOON(ioport) inw((u32bits)ioport)
255#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
256#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
257#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
258#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260
261#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262#define SYNC_TRYING BIT(6)
263#define SYNC_SUPPORTED (BIT(7)+BIT(6))
264
265#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266#define WIDE_ENABLED BIT(4)
267#define WIDE_NEGOCIATED BIT(5)
268
269#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270#define TAG_Q_TRYING BIT(2)
271#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
273#define TAR_ALLOW_DISC BIT(0)
274
275
276#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277#define EE_SYNC_5MB BIT(0)
278#define EE_SYNC_10MB BIT(1)
279#define EE_SYNC_20MB (BIT(0)+BIT(1))
280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281#define EE_WIDE_SCSI BIT(7)
282
283
James Bottomley 47b5d692005-04-24 02:38:05 -0500284typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285
286
287typedef struct SCCBMgr_tar_info {
288
289 PSCCB TarSelQ_Head;
290 PSCCB TarSelQ_Tail;
291 UCHAR TarLUN_CA; /*Contingent Allgiance */
292 UCHAR TarTagQ_Cnt;
293 UCHAR TarSelQ_Cnt;
294 UCHAR TarStatus;
295 UCHAR TarEEValue;
296 UCHAR TarSyncCtrl;
297 UCHAR TarReserved[2]; /* for alignment */
298 UCHAR LunDiscQ_Idx[MAX_LUN];
299 UCHAR TarLUNBusy[MAX_LUN];
300} SCCBMGR_TAR_INFO;
301
302typedef struct NVRAMInfo {
303 UCHAR niModel; /* Model No. of card */
304 UCHAR niCardNo; /* Card no. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 ULONG niBaseAddr; /* Port Address of card */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
307 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
308 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
309 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
310 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
311 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
312}NVRAMINFO;
313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315
316#define MODEL_LT 1
317#define MODEL_DL 2
318#define MODEL_LW 3
319#define MODEL_DW 4
320
321
322typedef struct SCCBcard {
323 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 ULONG ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327
328 USHORT cmdCounter;
329 UCHAR discQCount;
330 UCHAR tagQ_Lst;
331 UCHAR cardIndex;
332 UCHAR scanIndex;
333 UCHAR globalFlags;
334 UCHAR ourId;
335 PNVRamInfo pNvRamInfo;
336 PSCCB discQ_Tbl[QUEUE_DEPTH];
337
338}SCCBCARD;
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
342
343#define F_TAG_STARTED 0x01
344#define F_CONLUN_IO 0x02
345#define F_DO_RENEGO 0x04
346#define F_NO_FILTER 0x08
347#define F_GREEN_PC 0x10
348#define F_HOST_XFER_ACT 0x20
349#define F_NEW_SCCB_CMD 0x40
350#define F_UPDATE_EEPROM 0x80
351
352
353#define ID_STRING_LENGTH 32
354#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
357#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
358
359#define ASSIGN_ID 0x00
360#define SET_P_FLAG 0x01
361#define CFG_CMPLT 0x03
362#define DOM_MSTR 0x0F
363#define SYNC_PTRN 0x1F
364
365#define ID_0_7 0x18
366#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367#define MISC_CODE 0x14
368#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
371
372#define INIT_SELTD 0x01
373#define LEVEL2_TAR 0x02
374
375
376enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
377 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
378 CLR_PRIORITY,NO_ID_AVAIL };
379
380typedef struct SCCBscam_info {
381
382 UCHAR id_string[ID_STRING_LENGTH];
383 enum scam_id_st state;
384
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800385} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389#define SCSI_READ 0x08
390#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392#define SCSI_READ_EXTENDED 0x28
393#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
396
397
398#define SSGOOD 0x00
399#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400#define SSQ_FULL 0x28
401
402
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
404
405#define SMCMD_COMP 0x00
406#define SMEXT 0x01
407#define SMSAVE_DATA_PTR 0x02
408#define SMREST_DATA_PTR 0x03
409#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410#define SMABORT 0x06
411#define SMREJECT 0x07
412#define SMNO_OP 0x08
413#define SMPARITY 0x09
414#define SMDEV_RESET 0x0C
415#define SMABORT_TAG 0x0D
416#define SMINIT_RECOVERY 0x0F
417#define SMREL_RECOVERY 0x10
418
419#define SMIDENT 0x80
420#define DISC_PRIV 0x40
421
422
423#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424#define SMWDTR 0x03
425#define SM8BIT 0x00
426#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427#define SMIGNORWR 0x23 /* Ignore Wide Residue */
428
429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431
432
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
434
435
436#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437#define TWELVE_BYTE_CMD 0x0C
438
439#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
441
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442
443#define EEPROM_WD_CNT 256
444
445#define EEPROM_CHECK_SUM 0
446#define FW_SIGNATURE 2
447#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450#define SYSTEM_CONFIG 16
451#define SCSI_CONFIG 17
452#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453#define SCAM_CONFIG 20
454#define ADAPTER_SCSI_ID 24
455
456
457#define IGNORE_B_SCAN 32
458#define SEND_START_ENA 34
459#define DEVICE_ENABLE 36
460
461#define SYNC_RATE_TBL 38
462#define SYNC_RATE_TBL01 38
463#define SYNC_RATE_TBL23 40
464#define SYNC_RATE_TBL45 42
465#define SYNC_RATE_TBL67 44
466#define SYNC_RATE_TBL89 46
467#define SYNC_RATE_TBLab 48
468#define SYNC_RATE_TBLcd 50
469#define SYNC_RATE_TBLef 52
470
471
472
473#define EE_SCAMBASE 256
474
475
476
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 #define SCAM_ENABLED BIT(2)
478 #define SCAM_LEVEL2 BIT(3)
479
480
481 #define RENEGO_ENA BITW(10)
482 #define CONNIO_ENA BITW(11)
483 #define GREEN_PC_ENA BITW(12)
484
485
486 #define AUTO_RATE_00 00
487 #define AUTO_RATE_05 01
488 #define AUTO_RATE_10 02
489 #define AUTO_RATE_20 03
490
491 #define WIDE_NEGO_BIT BIT(7)
492 #define DISC_ENABLE_BIT BIT(6)
493
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495
496 #define hp_vendor_id_0 0x00 /* LSB */
497 #define ORION_VEND_0 0x4B
498
499 #define hp_vendor_id_1 0x01 /* MSB */
500 #define ORION_VEND_1 0x10
501
502 #define hp_device_id_0 0x02 /* LSB */
503 #define ORION_DEV_0 0x30
504
505 #define hp_device_id_1 0x03 /* MSB */
506 #define ORION_DEV_1 0x81
507
508 /* Sub Vendor ID and Sub Device ID only available in
509 Harpoon Version 2 and higher */
510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512
513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514
515 #define hp_semaphore 0x0C
516 #define SCCB_MGR_ACTIVE BIT(0)
517 #define TICKLE_ME BIT(1)
518 #define SCCB_MGR_PRESENT BIT(3)
519 #define BIOS_IN_USE BIT(4)
520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
523 #define hp_sys_ctrl 0x0F
524
525 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
526 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
527 #define HALT_MACH BIT(3) /*Halt State Machine */
528 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800534
535
536
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
538 #define hp_host_blk_cnt 0x13
539
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
541
542 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
543
544
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
546 #define hp_int_mask 0x17
547
548 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
549 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
551
552 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 #define hp_xfer_cnt_hi 0x1A
554 #define hp_xfer_cmd 0x1B
555
556 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
557 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
559
560 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563
564 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
565
566 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
567 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
569 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 #define hp_ee_ctrl 0x22
573
574 #define EXT_ARB_ACK BIT(7)
575 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
576 #define SEE_MS BIT(5)
577 #define SEE_CS BIT(3)
578 #define SEE_CLK BIT(2)
579 #define SEE_DO BIT(1)
580 #define SEE_DI BIT(0)
581
582 #define EE_READ 0x06
583 #define EE_WRITE 0x05
584 #define EWEN 0x04
585 #define EWEN_ADDR 0x03C0
586 #define EWDS 0x04
587 #define EWDS_ADDR 0x0000
588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592
593
594
595 #define hp_bm_ctrl 0x26
596
597 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
598 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
600 #define FAST_SINGLE BIT(6) /*?? */
601
602 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
605 #define hp_sg_addr 0x28
606 #define hp_page_ctrl 0x29
607
608 #define SCATTER_EN BIT(0)
609 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
611 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
612
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_pci_stat_cfg 0x2D
617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
627 #define hp_rev_num 0x33
628
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629
630 #define hp_stack_data 0x34
631 #define hp_stack_addr 0x35
632
633 #define hp_ext_status 0x36
634
635 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
636 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
637 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 #define CMD_ABORTED BIT(4) /*Command aborted */
639 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
640 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
641 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
642 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
643 BM_PARITY_ERR | PIO_OVERRUN)
644
645 #define hp_int_status 0x37
646
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
648 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
651
652 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654
655
656
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 #define hp_intena 0x40
658
659 #define RESET BITW(7)
660 #define PROG_HLT BITW(6)
661 #define PARITY BITW(5)
662 #define FIFO BITW(4)
663 #define SEL BITW(3)
664 #define SCAM_SEL BITW(2)
665 #define RSEL BITW(1)
666 #define TIMEOUT BITW(0)
667 #define BUS_FREE BITW(15)
668 #define XFER_CNT_0 BITW(14)
669 #define PHASE BITW(13)
670 #define IUNKWN BITW(12)
671 #define ICMD_COMP BITW(11)
672 #define ITICKLE BITW(10)
673 #define IDO_STRT BITW(9)
674 #define ITAR_DISC BITW(8)
675 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
676 #define CLR_ALL_INT 0xFFFF
677 #define CLR_ALL_INT_1 0xFF00
678
679 #define hp_intstat 0x42
680
681 #define hp_scsisig 0x44
682
683 #define SCSI_SEL BIT(7)
684 #define SCSI_BSY BIT(6)
685 #define SCSI_REQ BIT(5)
686 #define SCSI_ACK BIT(4)
687 #define SCSI_ATN BIT(3)
688 #define SCSI_CD BIT(2)
689 #define SCSI_MSG BIT(1)
690 #define SCSI_IOBIT BIT(0)
691
692 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
695 #define S_DATAI_PH ( BIT(0))
696 #define S_DATAO_PH 0x00
697 #define S_ILL_PH ( BIT(1) )
698
699 #define hp_scsictrl_0 0x45
700
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 #define SEL_TAR BIT(6)
702 #define ENA_ATN BIT(4)
703 #define ENA_RESEL BIT(2)
704 #define SCSI_RST BIT(1)
705 #define ENA_SCAM_SEL BIT(0)
706
707
708
709 #define hp_portctrl_0 0x46
710
711 #define SCSI_PORT BIT(7)
712 #define SCSI_INBIT BIT(6)
713 #define DMA_PORT BIT(5)
714 #define DMA_RD BIT(4)
715 #define HOST_PORT BIT(3)
716 #define HOST_WRT BIT(2)
717 #define SCSI_BUS_EN BIT(1)
718 #define START_TO BIT(0)
719
720 #define hp_scsireset 0x47
721
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 #define SCSI_INI BIT(6)
723 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 #define DMA_RESET BIT(3)
725 #define HPSCSI_RESET BIT(2)
726 #define PROG_RESET BIT(1)
727 #define FIFO_CLR BIT(0)
728
729 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731
732 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 #define hp_addstat 0x4E
734
735 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736 #define SCSI_MODE8 BIT(3)
737 #define SCSI_PAR_ERR BIT(0)
738
739 #define hp_prgmcnt_0 0x4F
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 #define hp_selfid_0 0x50
743 #define hp_selfid_1 0x51
744 #define hp_arb_id 0x52
745
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746
747 #define hp_select_id 0x53
748
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
750 #define hp_synctarg_base 0x54
751 #define hp_synctarg_12 0x54
752 #define hp_synctarg_13 0x55
753 #define hp_synctarg_14 0x56
754 #define hp_synctarg_15 0x57
755
756 #define hp_synctarg_8 0x58
757 #define hp_synctarg_9 0x59
758 #define hp_synctarg_10 0x5A
759 #define hp_synctarg_11 0x5B
760
761 #define hp_synctarg_4 0x5C
762 #define hp_synctarg_5 0x5D
763 #define hp_synctarg_6 0x5E
764 #define hp_synctarg_7 0x5F
765
766 #define hp_synctarg_0 0x60
767 #define hp_synctarg_1 0x61
768 #define hp_synctarg_2 0x62
769 #define hp_synctarg_3 0x63
770
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 #define DEFAULT_OFFSET 0x0F
773
774 #define hp_autostart_0 0x64
775 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 #define hp_autostart_3 0x67
777
778
779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 #define AUTO_IMMED BIT(5)
781 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
784 #define hp_gp_reg_0 0x68
785 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 #define hp_gp_reg_3 0x6B
787
788 #define hp_seltimeout 0x6C
789
790
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 #define TO_4ms 0x67 /* 3.9959ms */
792
793 #define TO_5ms 0x03 /* 4.9152ms */
794 #define TO_10ms 0x07 /* 11.xxxms */
795 #define TO_250ms 0x99 /* 250.68ms */
796 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
798 #define hp_clkctrl_0 0x6D
799
800 #define PWR_DWN BIT(6)
801 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
804 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
805
806 #define hp_fiforead 0x6E
807 #define hp_fifowrite 0x6F
808
809 #define hp_offsetctr 0x70
810 #define hp_xferstat 0x71
811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 #define hp_portctrl_1 0x72
815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 #define CHK_SCSI_P BIT(3)
817 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818
819 #define hp_xfer_pad 0x73
820
821 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 #define hp_scsidata_0 0x74
824 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 #define hp_aramBase 0x80
829 #define BIOS_DATA_OFFSET 0x60
830 #define BIOS_RELATIVE_CARD 0x64
831
832
833
834
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 #define AR3 (BITW(9) + BITW(8))
836 #define SDATA BITW(10)
837
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
839 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
840
841 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844
845 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
846
847 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
848
849
850 #define ADATA_OUT 0x00
851 #define ADATA_IN BITW(8)
852 #define ACOMMAND BITW(10)
853 #define ASTATUS (BITW(10)+BITW(8))
854 #define AMSG_OUT (BITW(10)+BITW(9))
855 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
857
858 #define BRH_OP BITW(13) /* Branch */
859
860
861 #define ALWAYS 0x00
862 #define EQUAL BITW(8)
863 #define NOT_EQ BITW(9)
864
865 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
866
867
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869
870
871 #define MPM_OP BITW(15) /* Match phase and move data */
872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
874 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
875
876
877 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
878
879
880 #define D_AR0 0x00
881 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
883
884
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890
891
892 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
893
894 #define SSI_OP (BITW(15)+BITW(11))
895
896
897 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
898 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899
900 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
901 #define SSI_ITICKLE (ITICKLE >> 8)
902
903 #define SSI_IUNKWN (IUNKWN >> 8)
904 #define SSI_INO_CC (IUNKWN >> 8)
905 #define SSI_IRFAIL (IUNKWN >> 8)
906
907
908 #define NP 0x10 /*Next Phase */
909 #define NTCMD 0x02 /*Non- Tagged Command start */
910 #define CMDPZ 0x04 /*Command phase */
911 #define DINT 0x12 /*Data Out/In interrupt */
912 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 #define DC 0x19 /*Disconnect Message */
914 #define ST 0x1D /*Status Phase */
915 #define UNKNWN 0x24 /*Unknown bus action */
916 #define CC 0x25 /*Command Completion failure */
917 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
919
920
921 #define ID_MSG_STRT hp_aramBase + 0x00
922 #define NON_TAG_ID_MSG hp_aramBase + 0x06
923 #define CMD_STRT hp_aramBase + 0x08
924 #define SYNC_MSGS hp_aramBase + 0x08
925
926
927
928
929
930 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 #define DISCONNECT_START 0x10/2
932 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 #define SELCHK_STRT SELCHK/2
935
936
937
938
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939
940
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800942
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
944#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
945/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
946 xfercnt <<= 16,\
947 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
948 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
950 addr >>= 16,\
951 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
952 WR_HARP32(port,hp_xfercnt_0,count),\
953 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
954 count >>= 16,\
955 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
957#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
958 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
959
960
961#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
962 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
963
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
966#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
967 WR_HARPOON(port+hp_scsireset, 0x00))
968
969#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
970 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
971
972#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
973 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
974
975#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
976 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
977
978#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
979 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
980
981
982
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
James Bottomley 47b5d692005-04-24 02:38:05 -0500984static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
985static void FPT_ssel(ULONG port, UCHAR p_card);
986static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
987static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
988static void FPT_stsyncn(ULONG port, UCHAR p_card);
989static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
990static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
991 PSCCBMgr_tar_info currTar_Info);
992static void FPT_sresb(ULONG port, UCHAR p_card);
993static void FPT_sxfrp(ULONG p_port, UCHAR p_card);
994static void FPT_schkdd(ULONG port, UCHAR p_card);
995static UCHAR FPT_RdStack(ULONG port, UCHAR index);
996static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
997static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
James Bottomley 47b5d692005-04-24 02:38:05 -0500999static void FPT_SendMsg(ULONG port, UCHAR message);
1000static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1001 UCHAR error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
James Bottomley 47b5d692005-04-24 02:38:05 -05001003static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1004static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
James Bottomley 47b5d692005-04-24 02:38:05 -05001006static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1007static void FPT_stwidn(ULONG port, UCHAR p_card);
1008static void FPT_siwidr(ULONG port, UCHAR width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
1010
James Bottomley 47b5d692005-04-24 02:38:05 -05001011static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1012static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1013static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1014 UCHAR p_card);
1015static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1016static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1017static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1018static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1019static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1020static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1021static UCHAR FPT_CalcLrc(UCHAR buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
1023
James Bottomley 47b5d692005-04-24 02:38:05 -05001024static void FPT_Wait1Second(ULONG p_port);
1025static void FPT_Wait(ULONG p_port, UCHAR p_delay);
1026static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1027static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1028static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1029static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1030static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
1032
1033
James Bottomley 47b5d692005-04-24 02:38:05 -05001034static void FPT_phaseDataOut(ULONG port, UCHAR p_card);
1035static void FPT_phaseDataIn(ULONG port, UCHAR p_card);
1036static void FPT_phaseCommand(ULONG port, UCHAR p_card);
1037static void FPT_phaseStatus(ULONG port, UCHAR p_card);
1038static void FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1039static void FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1040static void FPT_phaseIllegal(ULONG port, UCHAR p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
James Bottomley 47b5d692005-04-24 02:38:05 -05001042static void FPT_phaseDecode(ULONG port, UCHAR p_card);
1043static void FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1044static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046
1047
1048
James Bottomley 47b5d692005-04-24 02:38:05 -05001049static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1050static void FPT_BusMasterInit(ULONG p_port);
1051static void FPT_DiagEEPROM(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052
1053
1054
1055
James Bottomley 47b5d692005-04-24 02:38:05 -05001056static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1057static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1058static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1059static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1060static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
1062
James Bottomley 47b5d692005-04-24 02:38:05 -05001063static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1064 PSCCBcard pCurrCard, USHORT p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065
James Bottomley 47b5d692005-04-24 02:38:05 -05001066static void FPT_SccbMgrTableInitAll(void);
1067static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1068static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069
1070
1071
James Bottomley 47b5d692005-04-24 02:38:05 -05001072static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073
James Bottomley 47b5d692005-04-24 02:38:05 -05001074static int FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1075static void FPT_scbusf(ULONG p_port);
1076static void FPT_scsel(ULONG p_port);
1077static void FPT_scasid(UCHAR p_card, ULONG p_port);
1078static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1079static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1080static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1081static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1082static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1083static UCHAR FPT_scvalq(UCHAR p_quintet);
1084static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1085static void FPT_scwtsel(ULONG p_port);
1086static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1087static void FPT_scsavdi(UCHAR p_card, ULONG p_port);
1088static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
1090
James Bottomley 47b5d692005-04-24 02:38:05 -05001091static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1092static void FPT_autoLoadDefaultMap(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
1094
1095
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
James Bottomley 47b5d692005-04-24 02:38:05 -05001097static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1098static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1099static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1100static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
1102
James Bottomley 47b5d692005-04-24 02:38:05 -05001103static UCHAR FPT_mbCards = 0;
1104static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1105 ' ', 'B', 'T', '-', '9', '3', '0', \
1106 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1107 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108
James Bottomley 47b5d692005-04-24 02:38:05 -05001109static USHORT FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
1111
James Bottomley 47b5d692005-04-24 02:38:05 -05001112static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
1115/*---------------------------------------------------------------------
1116 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001117 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 *
1119 * Description: Setup and/or Search for cards and return info to caller.
1120 *
1121 *---------------------------------------------------------------------*/
1122
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001123static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 static UCHAR first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
1127 UCHAR i,j,id,ScamFlg;
1128 USHORT temp,temp2,temp3,temp4,temp5,temp6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 PNVRamInfo pCurrNvRam;
1131
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133
1134
1135 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1136 return((int)FAILURE);
1137
1138 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1139 return((int)FAILURE);
1140
1141 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1142 return((int)FAILURE);
1143
1144 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1145 return((int)FAILURE);
1146
1147
1148 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1149
1150/* For new Harpoon then check for sub_device ID LSB
1151 the bits(0-3) must be all ZERO for compatible with
1152 current version of SCCBMgr, else skip this Harpoon
1153 device. */
1154
1155 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1156 return((int)FAILURE);
1157 }
1158
1159 if (first_time)
1160 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001161 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001163 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 }
1165
James Bottomley 47b5d692005-04-24 02:38:05 -05001166 if(FPT_RdStack(ioport, 0) != 0x00) {
1167 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 {
1169 pCurrNvRam = NULL;
1170 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001171 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1172 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 }
1174 else
1175 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001176 if(FPT_mbCards < MAX_MB_CARDS) {
1177 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1178 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001180 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 }else
1182 return((int) FAILURE);
1183 }
1184 }else
1185 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186
1187 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1188 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1189
1190 if(pCurrNvRam)
1191 pCardInfo->si_id = pCurrNvRam->niAdapId;
1192 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001193 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 (UCHAR)0x0FF);
1195
1196 pCardInfo->si_lun = 0x00;
1197 pCardInfo->si_fw_revision = ORION_FW_REV;
1198 temp2 = 0x0000;
1199 temp3 = 0x0000;
1200 temp4 = 0x0000;
1201 temp5 = 0x0000;
1202 temp6 = 0x0000;
1203
1204 for (id = 0; id < (16/2); id++) {
1205
1206 if(pCurrNvRam){
1207 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1208 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1209 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1210 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001211 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
1213 for (i = 0; i < 2; temp >>=8,i++) {
1214
1215 temp2 >>= 1;
1216 temp3 >>= 1;
1217 temp4 >>= 1;
1218 temp5 >>= 1;
1219 temp6 >>= 1;
1220 switch (temp & 0x3)
1221 {
1222 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1223 temp6 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1225 temp5 |= 0x8000; /* Fall through */
1226 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1227 temp2 |= 0x8000; /* Fall through */
1228 case AUTO_RATE_00: /* Asynchronous */
1229 break;
1230 }
1231
1232 if (temp & DISC_ENABLE_BIT)
1233 temp3 |= 0x8000;
1234
1235 if (temp & WIDE_NEGO_BIT)
1236 temp4 |= 0x8000;
1237
1238 }
1239 }
1240
1241 pCardInfo->si_per_targ_init_sync = temp2;
1242 pCardInfo->si_per_targ_no_disc = temp3;
1243 pCardInfo->si_per_targ_wide_nego = temp4;
1244 pCardInfo->si_per_targ_fast_nego = temp5;
1245 pCardInfo->si_per_targ_ultra_nego = temp6;
1246
1247 if(pCurrNvRam)
1248 i = pCurrNvRam->niSysConf;
1249 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001250 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
1252 if(pCurrNvRam)
1253 ScamFlg = pCurrNvRam->niScamConf;
1254 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001255 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
1257 pCardInfo->si_flags = 0x0000;
1258
1259 if (i & 0x01)
1260 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1261
1262 if (!(i & 0x02))
1263 pCardInfo->si_flags |= SOFT_RESET;
1264
1265 if (i & 0x10)
1266 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1267
1268 if (ScamFlg & SCAM_ENABLED)
1269 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1270
1271 if (ScamFlg & SCAM_LEVEL2)
1272 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1273
1274 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1275 if (i & 0x04) {
1276 j |= SCSI_TERM_ENA_L;
1277 }
1278 WR_HARPOON(ioport+hp_bm_ctrl, j );
1279
1280 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1281 if (i & 0x08) {
1282 j |= SCSI_TERM_ENA_H;
1283 }
1284 WR_HARPOON(ioport+hp_ee_ctrl, j );
1285
1286 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1287
1288 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1289
1290 pCardInfo->si_card_family = HARPOON_FAMILY;
1291 pCardInfo->si_bustype = BUSTYPE_PCI;
1292
1293 if(pCurrNvRam){
1294 pCardInfo->si_card_model[0] = '9';
1295 switch(pCurrNvRam->niModel & 0x0f){
1296 case MODEL_LT:
1297 pCardInfo->si_card_model[1] = '3';
1298 pCardInfo->si_card_model[2] = '0';
1299 break;
1300 case MODEL_LW:
1301 pCardInfo->si_card_model[1] = '5';
1302 pCardInfo->si_card_model[2] = '0';
1303 break;
1304 case MODEL_DL:
1305 pCardInfo->si_card_model[1] = '3';
1306 pCardInfo->si_card_model[2] = '2';
1307 break;
1308 case MODEL_DW:
1309 pCardInfo->si_card_model[1] = '5';
1310 pCardInfo->si_card_model[2] = '2';
1311 break;
1312 }
1313 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001314 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001316 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317
1318 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
1319 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
1320 }
1321
1322 if (pCardInfo->si_card_model[1] == '3')
1323 {
1324 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1325 pCardInfo->si_flags |= LOW_BYTE_TERM;
1326 }
1327 else if (pCardInfo->si_card_model[2] == '0')
1328 {
1329 temp = RD_HARPOON(ioport+hp_xfer_pad);
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1331 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1332 pCardInfo->si_flags |= LOW_BYTE_TERM;
1333 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1334 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1335 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1336 WR_HARPOON(ioport+hp_xfer_pad, temp);
1337 }
1338 else
1339 {
1340 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1341 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1342 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1343 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1344 temp3 = 0;
1345 for (i = 0; i < 8; i++)
1346 {
1347 temp3 <<= 1;
1348 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1349 temp3 |= 1;
1350 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1351 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1352 }
1353 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1354 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1355 if (!(temp3 & BIT(7)))
1356 pCardInfo->si_flags |= LOW_BYTE_TERM;
1357 if (!(temp3 & BIT(6)))
1358 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1359 }
1360
1361
1362 ARAM_ACCESS(ioport);
1363
1364 for ( i = 0; i < 4; i++ ) {
1365
1366 pCardInfo->si_XlatInfo[i] =
1367 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1368 }
1369
1370 /* return with -1 if no sort, else return with
1371 logical card number sorted by BIOS (zero-based) */
1372
1373 pCardInfo->si_relative_cardnum =
1374 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1375
1376 SGRAM_ACCESS(ioport);
1377
James Bottomley 47b5d692005-04-24 02:38:05 -05001378 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1379 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1380 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1381 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1382 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1383 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1384 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1385 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386
1387 pCardInfo->si_present = 0x01;
1388
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 return(0);
1390}
1391
1392
1393/*---------------------------------------------------------------------
1394 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001395 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 *
1397 * Description: Setup adapter for normal operation (hard reset).
1398 *
1399 *---------------------------------------------------------------------*/
1400
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001401static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402{
1403 PSCCBcard CurrCard = NULL;
1404 PNVRamInfo pCurrNvRam;
1405 UCHAR i,j,thisCard, ScamFlg;
1406 USHORT temp,sync_bit_map,id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
1411 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1412
1413 if (thisCard == MAX_CARDS) {
1414
1415 return(FAILURE);
1416 }
1417
James Bottomley 47b5d692005-04-24 02:38:05 -05001418 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
James Bottomley 47b5d692005-04-24 02:38:05 -05001420 CurrCard = &FPT_BL_Card[thisCard];
1421 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 break;
1423 }
1424
James Bottomley 47b5d692005-04-24 02:38:05 -05001425 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
James Bottomley 47b5d692005-04-24 02:38:05 -05001427 FPT_BL_Card[thisCard].ioPort = ioport;
1428 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
James Bottomley 47b5d692005-04-24 02:38:05 -05001430 if(FPT_mbCards)
1431 for(i = 0; i < FPT_mbCards; i++){
1432 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1433 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001435 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 CurrCard->cardIndex = thisCard;
1437 CurrCard->cardInfo = pCardInfo;
1438
1439 break;
1440 }
1441 }
1442
1443 pCurrNvRam = CurrCard->pNvRamInfo;
1444
1445 if(pCurrNvRam){
1446 ScamFlg = pCurrNvRam->niScamConf;
1447 }
1448 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001449 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 }
1451
1452
James Bottomley 47b5d692005-04-24 02:38:05 -05001453 FPT_BusMasterInit(ioport);
1454 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
James Bottomley 47b5d692005-04-24 02:38:05 -05001456 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457
1458
1459 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1460
1461 WR_HARPOON(ioport+hp_selfid_0, id);
1462 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1463 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1464 CurrCard->ourId = pCardInfo->si_id;
1465
1466 i = (UCHAR) pCardInfo->si_flags;
1467 if (i & SCSI_PARITY_ENA)
1468 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1469
1470 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1471 if (i & LOW_BYTE_TERM)
1472 j |= SCSI_TERM_ENA_L;
1473 WR_HARPOON(ioport+hp_bm_ctrl, j);
1474
1475 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1476 if (i & HIGH_BYTE_TERM)
1477 j |= SCSI_TERM_ENA_H;
1478 WR_HARPOON(ioport+hp_ee_ctrl, j );
1479
1480
1481 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1482
James Bottomley 47b5d692005-04-24 02:38:05 -05001483 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484
James Bottomley 47b5d692005-04-24 02:38:05 -05001485 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 }
1487
1488
1489
1490 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1491 CurrCard->globalFlags |= F_NO_FILTER;
1492
1493 if(pCurrNvRam){
1494 if(pCurrNvRam->niSysConf & 0x10)
1495 CurrCard->globalFlags |= F_GREEN_PC;
1496 }
1497 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001498 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 CurrCard->globalFlags |= F_GREEN_PC;
1500 }
1501
1502 /* Set global flag to indicate Re-Negotiation to be done on all
1503 ckeck condition */
1504 if(pCurrNvRam){
1505 if(pCurrNvRam->niScsiConf & 0x04)
1506 CurrCard->globalFlags |= F_DO_RENEGO;
1507 }
1508 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001509 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 CurrCard->globalFlags |= F_DO_RENEGO;
1511 }
1512
1513 if(pCurrNvRam){
1514 if(pCurrNvRam->niScsiConf & 0x08)
1515 CurrCard->globalFlags |= F_CONLUN_IO;
1516 }
1517 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001518 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 CurrCard->globalFlags |= F_CONLUN_IO;
1520 }
1521
1522
1523 temp = pCardInfo->si_per_targ_no_disc;
1524
1525 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1526
1527 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001528 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 }
1530
1531 sync_bit_map = 0x0001;
1532
1533 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1534
1535 if(pCurrNvRam){
1536 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1537 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1538 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1539 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001540 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 for (i = 0; i < 2; temp >>=8,i++) {
1543
1544 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1545
James Bottomley 47b5d692005-04-24 02:38:05 -05001546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 }
1548
1549 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001550 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1551 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 (UCHAR)(temp & ~EE_SYNC_MASK);
1553 }
1554
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1556 (id*2+i >= 8)){
1557*/
1558 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1559
James Bottomley 47b5d692005-04-24 02:38:05 -05001560 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561
1562 }
1563
1564 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001565 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 }
1567
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568
1569 sync_bit_map <<= 1;
1570
1571
1572
1573 }
1574 }
1575
1576 WR_HARPOON((ioport+hp_semaphore),
1577 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1578
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 return((ULONG)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580}
1581
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001582static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
1584 UCHAR i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 ULONG portBase;
1586 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 PNVRamInfo pCurrNvRam;
1590
1591 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1592
1593 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001594 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1597 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1598 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599
1600 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05001601 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602
1603 portBase = pCurrNvRam->niBaseAddr;
1604
1605 for(i = 0; i < MAX_SCSI_TAR; i++){
1606 regOffset = hp_aramBase + 64 + i*4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 scamData = *pScamTbl;
1609 WR_HARP32(portBase, regOffset, scamData);
1610 }
1611
1612 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001613 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 }
1615}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
1617
James Bottomley 47b5d692005-04-24 02:38:05 -05001618static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619{
1620 UCHAR i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 ULONG portBase;
1622 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625
James Bottomley 47b5d692005-04-24 02:38:05 -05001626 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1627 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1628 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1629 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1630 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631
1632 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05001633 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634
1635 portBase = pNvRamInfo->niBaseAddr;
1636
1637 for(i = 0; i < MAX_SCSI_TAR; i++){
1638 regOffset = hp_aramBase + 64 + i*4;
1639 RD_HARP32(portBase, regOffset, scamData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 *pScamTbl = scamData;
1642 }
1643
1644}
1645
James Bottomley 47b5d692005-04-24 02:38:05 -05001646static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647{
1648 WR_HARPOON(portBase + hp_stack_addr, index);
1649 return(RD_HARPOON(portBase + hp_stack_data));
1650}
1651
James Bottomley 47b5d692005-04-24 02:38:05 -05001652static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653{
1654 WR_HARPOON(portBase + hp_stack_addr, index);
1655 WR_HARPOON(portBase + hp_stack_data, data);
1656}
1657
1658
James Bottomley 47b5d692005-04-24 02:38:05 -05001659static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660{
James Bottomley 47b5d692005-04-24 02:38:05 -05001661 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1662 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1664 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001665 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1667 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001668 return(1);
1669 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670
1671}
1672/*---------------------------------------------------------------------
1673 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001674 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 *
1676 * Description: Start a command pointed to by p_Sccb. When the
1677 * command is completed it will be returned via the
1678 * callback function.
1679 *
1680 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001681static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 UCHAR thisCard, lun;
1685 PSCCB pSaveSccb;
1686 CALL_BK_FN callback;
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1689 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1690
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1692 {
1693
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 p_Sccb->HostStatus = SCCB_COMPLETE;
1695 p_Sccb->SccbStatus = SCCB_ERROR;
1696 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1697 if (callback)
1698 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 return;
1701 }
1702
James Bottomley 47b5d692005-04-24 02:38:05 -05001703 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
1705
1706 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1707 {
1708 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1709 | SCCB_MGR_ACTIVE));
1710
1711 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1712 {
1713 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1714 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1715 }
1716 }
1717
1718 ((PSCCBcard)pCurrCard)->cmdCounter++;
1719
1720 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1721
1722 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1723 | TICKLE_ME));
1724 if(p_Sccb->OperationCode == RESET_COMMAND)
1725 {
1726 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1727 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001728 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1730 }
1731 else
1732 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001733 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 }
1735 }
1736
1737 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1738
1739 if(p_Sccb->OperationCode == RESET_COMMAND)
1740 {
1741 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1742 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001743 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1745 }
1746 else
1747 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001748 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 }
1750 }
1751
1752 else {
1753
1754 MDISABLE_INT(ioport);
1755
1756 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001757 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 lun = p_Sccb->Lun;
1759 else
1760 lun = 0;
1761 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001762 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1763 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1764 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
1766 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001767 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 }
1769
1770 else {
1771
1772 if(p_Sccb->OperationCode == RESET_COMMAND)
1773 {
1774 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1775 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001776 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1778 }
1779 else
1780 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001781 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 }
1783 }
1784
1785
1786 MENABLE_INT(ioport);
1787 }
1788
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789}
1790
1791
1792/*---------------------------------------------------------------------
1793 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001794 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 *
1796 * Description: Abort the command pointed to by p_Sccb. When the
1797 * command is completed it will be returned via the
1798 * callback function.
1799 *
1800 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001801static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
1805 UCHAR thisCard;
1806 CALL_BK_FN callback;
1807 UCHAR TID;
1808 PSCCB pSaveSCCB;
1809 PSCCBMgr_tar_info currTar_Info;
1810
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1813
1814 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1815
James Bottomley 47b5d692005-04-24 02:38:05 -05001816 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 {
1818
James Bottomley 47b5d692005-04-24 02:38:05 -05001819 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 {
1821
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 ((PSCCBcard)pCurrCard)->cmdCounter--;
1823
1824 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1825 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1826 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1827
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 p_Sccb->SccbStatus = SCCB_ABORT;
1829 callback = p_Sccb->SccbCallback;
1830 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
1832 return(0);
1833 }
1834
1835 else
1836 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1838 {
1839 p_Sccb->SccbStatus = SCCB_ABORT;
1840 return(0);
1841
1842 }
1843
1844 else
1845 {
1846
1847 TID = p_Sccb->TargID;
1848
1849
1850 if(p_Sccb->Sccb_tag)
1851 {
1852 MDISABLE_INT(ioport);
1853 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1854 {
1855 p_Sccb->SccbStatus = SCCB_ABORT;
1856 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1858
1859 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1860 {
1861 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001862 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 }
1864 else
1865 {
1866 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1867 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001868 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1870 }
1871 }
1872 MENABLE_INT(ioport);
1873 return(0);
1874 }
1875 else
1876 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001877 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878
James Bottomley 47b5d692005-04-24 02:38:05 -05001879 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 == p_Sccb)
1881 {
1882 p_Sccb->SccbStatus = SCCB_ABORT;
1883 return(0);
1884 }
1885 }
1886 }
1887 }
1888 }
1889 return(-1);
1890}
1891
1892
1893/*---------------------------------------------------------------------
1894 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001895 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 *
1897 * Description: Do a quick check to determine if there is a pending
1898 * interrupt for this card and disable the IRQ Pin if so.
1899 *
1900 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001901static UCHAR FlashPoint_InterruptPending(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904
1905 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1906
1907 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1908 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001909 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 }
1911
1912 else
1913
James Bottomley 47b5d692005-04-24 02:38:05 -05001914 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915}
1916
1917
1918
1919/*---------------------------------------------------------------------
1920 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001921 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 *
1923 * Description: This is our entry point when an interrupt is generated
1924 * by the card and the upper level driver passes it on to
1925 * us.
1926 *
1927 *---------------------------------------------------------------------*/
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001928static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929{
1930 PSCCB currSCCB;
1931 UCHAR thisCard,result,bm_status, bm_int_st;
1932 USHORT hp_int;
1933 UCHAR i, target;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1937 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1938
1939 MDISABLE_INT(ioport);
1940
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1942 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
1943 else
1944 bm_status = 0;
1945
1946 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1947
James Bottomley 47b5d692005-04-24 02:38:05 -05001948 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 bm_status)
1950 {
1951
1952 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1953
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001955 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1957 bm_status = 0;
1958
1959 if (result) {
1960
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 return(result);
1963 }
1964 }
1965
1966
1967 else if (hp_int & ICMD_COMP) {
1968
1969 if ( !(hp_int & BUS_FREE) ) {
1970 /* Wait for the BusFree before starting a new command. We
1971 must also check for being reselected since the BusFree
1972 may not show up if another device reselects us in 1.5us or
1973 less. SRR Wednesday, 3/8/1995.
1974 */
1975 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1976 }
1977
1978 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1979
James Bottomley 47b5d692005-04-24 02:38:05 -05001980 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
1982/* WRW_HARPOON((ioport+hp_intstat),
1983 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1984 */
1985
1986 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1987
James Bottomley 47b5d692005-04-24 02:38:05 -05001988 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989
1990 }
1991
1992
1993 else if (hp_int & ITAR_DISC)
1994 {
1995
1996 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1997
James Bottomley 47b5d692005-04-24 02:38:05 -05001998 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
2000 }
2001
2002 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2003
2004 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2005 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2006
2007 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2008 }
2009
2010 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002011 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012
2013 /* Wait for the BusFree before starting a new command. We
2014 must also check for being reselected since the BusFree
2015 may not show up if another device reselects us in 1.5us or
2016 less. SRR Wednesday, 3/8/1995.
2017 */
2018 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2019 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2020 RD_HARPOON((ioport+hp_scsisig)) ==
2021 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2022
2023 /*
2024 The additional loop exit condition above detects a timing problem
2025 with the revision D/E harpoon chips. The caller should reset the
2026 host adapter to recover when 0xFE is returned.
2027 */
2028 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2029 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 return 0xFE;
2032 }
2033
2034 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2035
2036
2037 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2038
2039 }
2040
2041
2042 else if (hp_int & RSEL) {
2043
2044 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2045
2046 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2047 {
2048 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2049 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002050 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 }
2052
2053 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2054 {
2055 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2056 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2057 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2058 }
2059
2060 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2061 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002062 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063 }
2064
James Bottomley 47b5d692005-04-24 02:38:05 -05002065 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2066 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067
2068 }
2069
2070
2071 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2072 {
2073
2074 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002075 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076
2077 }
2078
2079
2080 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2081 {
2082 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2083 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
2084 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002085 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 }
2087 else
2088 {
2089 /* Harpoon problem some SCSI target device respond to selection
2090 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2091 to latch the correct Target ID into reg. x53.
2092 The work around require to correct this reg. But when write to this
2093 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2094 need to read this reg first then restore it later. After update to 0x53 */
2095
2096 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
2097 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
2098 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
2099 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
2100 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
2101 WR_HARPOON(ioport+hp_fifowrite, i);
2102 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2103 }
2104 }
2105
2106 else if (hp_int & XFER_CNT_0) {
2107
2108 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2109
James Bottomley 47b5d692005-04-24 02:38:05 -05002110 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111
2112 }
2113
2114
2115 else if (hp_int & BUS_FREE) {
2116
2117 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2118
2119 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2120
James Bottomley 47b5d692005-04-24 02:38:05 -05002121 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 }
2123
James Bottomley 47b5d692005-04-24 02:38:05 -05002124 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 }
2126
2127
2128 else if (hp_int & ITICKLE) {
2129
2130 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2131 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2132 }
2133
2134
2135
2136 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2137
2138
2139 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2140
2141
2142 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2143
James Bottomley 47b5d692005-04-24 02:38:05 -05002144 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 }
2146
2147 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2148 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002149 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 }
2151
2152 break;
2153
2154 }
2155
2156 } /*end while */
2157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159
2160 return(0);
2161}
2162
2163/*---------------------------------------------------------------------
2164 *
2165 * Function: Sccb_bad_isr
2166 *
2167 * Description: Some type of interrupt has occurred which is slightly
2168 * out of the ordinary. We will now decode it fully, in
2169 * this routine. This is broken up in an attempt to save
2170 * processing time.
2171 *
2172 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002173static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2174 PSCCBcard pCurrCard, USHORT p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175{
James Bottomley 47b5d692005-04-24 02:38:05 -05002176 UCHAR temp, ScamFlg;
2177 PSCCBMgr_tar_info currTar_Info;
2178 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179
2180
2181 if (RD_HARPOON(p_port+hp_ext_status) &
2182 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2183 {
2184
2185 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2186 {
2187
James Bottomley 47b5d692005-04-24 02:38:05 -05002188 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 }
2190
2191 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2192
2193 {
2194 WR_HARPOON(p_port+hp_pci_stat_cfg,
2195 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2196
2197 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2198
2199 }
2200
2201 if (pCurrCard->currentSCCB != NULL)
2202 {
2203
2204 if (!pCurrCard->currentSCCB->HostStatus)
2205 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2206
James Bottomley 47b5d692005-04-24 02:38:05 -05002207 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208
2209 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
2210 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2211 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
2212 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2213
2214 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2215 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002216 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 }
2218 }
2219 }
2220
2221
2222 else if (p_int & RESET)
2223 {
2224
2225 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2226 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2227 if (pCurrCard->currentSCCB != NULL) {
2228
2229 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2230
James Bottomley 47b5d692005-04-24 02:38:05 -05002231 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232 }
2233
2234
2235 DISABLE_AUTO(p_port);
2236
James Bottomley 47b5d692005-04-24 02:38:05 -05002237 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
2239 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2240
2241 pCurrNvRam = pCurrCard->pNvRamInfo;
2242 if(pCurrNvRam){
2243 ScamFlg = pCurrNvRam->niScamConf;
2244 }
2245 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05002246 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 }
2248
James Bottomley 47b5d692005-04-24 02:38:05 -05002249 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250
James Bottomley 47b5d692005-04-24 02:38:05 -05002251 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252
2253 return(0xFF);
2254 }
2255
2256
2257 else if (p_int & FIFO) {
2258
2259 WRW_HARPOON((p_port+hp_intstat), FIFO);
2260
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002262 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 }
2264
2265 else if (p_int & TIMEOUT)
2266 {
2267
2268 DISABLE_AUTO(p_port);
2269
2270 WRW_HARPOON((p_port+hp_intstat),
2271 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2272
2273 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2274
2275
James Bottomley 47b5d692005-04-24 02:38:05 -05002276 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2278 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002279 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002281 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282
2283
2284 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2285 {
2286 currTar_Info->TarSyncCtrl = 0;
2287 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2288 }
2289
2290 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2291 {
2292 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2293 }
2294
James Bottomley 47b5d692005-04-24 02:38:05 -05002295 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
James Bottomley 47b5d692005-04-24 02:38:05 -05002297 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
2299 }
2300
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301 else if (p_int & SCAM_SEL)
2302 {
2303
James Bottomley 47b5d692005-04-24 02:38:05 -05002304 FPT_scarb(p_port,LEVEL2_TAR);
2305 FPT_scsel(p_port);
2306 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
James Bottomley 47b5d692005-04-24 02:38:05 -05002308 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309
2310 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2311 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
2313 return(0x00);
2314}
2315
2316
2317/*---------------------------------------------------------------------
2318 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 * Function: SccbMgrTableInit
2320 *
2321 * Description: Initialize all Sccb manager data structures.
2322 *
2323 *---------------------------------------------------------------------*/
2324
James Bottomley 47b5d692005-04-24 02:38:05 -05002325static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326{
2327 UCHAR thisCard;
2328
2329 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2330 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002331 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332
James Bottomley 47b5d692005-04-24 02:38:05 -05002333 FPT_BL_Card[thisCard].ioPort = 0x00;
2334 FPT_BL_Card[thisCard].cardInfo = NULL;
2335 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2336 FPT_BL_Card[thisCard].ourId = 0x00;
2337 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 }
2339}
2340
2341
2342/*---------------------------------------------------------------------
2343 *
2344 * Function: SccbMgrTableInit
2345 *
2346 * Description: Initialize all Sccb manager data structures.
2347 *
2348 *---------------------------------------------------------------------*/
2349
James Bottomley 47b5d692005-04-24 02:38:05 -05002350static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351{
2352 UCHAR scsiID, qtag;
2353
2354 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2355 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002356 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357 }
2358
2359 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2360 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002361 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2362 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2363 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 }
2365
2366 pCurrCard->scanIndex = 0x00;
2367 pCurrCard->currentSCCB = NULL;
2368 pCurrCard->globalFlags = 0x00;
2369 pCurrCard->cmdCounter = 0x00;
2370 pCurrCard->tagQ_Lst = 0x01;
2371 pCurrCard->discQCount = 0;
2372
2373
2374}
2375
2376
2377/*---------------------------------------------------------------------
2378 *
2379 * Function: SccbMgrTableInit
2380 *
2381 * Description: Initialize all Sccb manager data structures.
2382 *
2383 *---------------------------------------------------------------------*/
2384
James Bottomley 47b5d692005-04-24 02:38:05 -05002385static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386{
2387
2388 UCHAR lun, qtag;
2389 PSCCBMgr_tar_info currTar_Info;
2390
James Bottomley 47b5d692005-04-24 02:38:05 -05002391 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392
2393 currTar_Info->TarSelQ_Cnt = 0;
2394 currTar_Info->TarSyncCtrl = 0;
2395
2396 currTar_Info->TarSelQ_Head = NULL;
2397 currTar_Info->TarSelQ_Tail = NULL;
2398 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002399 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400
2401
2402 for (lun = 0; lun < MAX_LUN; lun++)
2403 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002404 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 currTar_Info->LunDiscQ_Idx[lun] = 0;
2406 }
2407
2408 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2409 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002410 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002412 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002414 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2415 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 }
2417 }
2418 }
2419}
2420
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421
2422/*---------------------------------------------------------------------
2423 *
2424 * Function: sfetm
2425 *
2426 * Description: Read in a message byte from the SCSI bus, and check
2427 * for a parity error.
2428 *
2429 *---------------------------------------------------------------------*/
2430
James Bottomley 47b5d692005-04-24 02:38:05 -05002431static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432{
2433 UCHAR message;
2434 USHORT TimeOutLoop;
2435
2436 TimeOutLoop = 0;
2437 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2438 (TimeOutLoop++ < 20000) ){}
2439
2440
2441 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2442
2443 message = RD_HARPOON(port+hp_scsidata_0);
2444
2445 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2446
2447
2448 if (TimeOutLoop > 20000)
2449 message = 0x00; /* force message byte = 0 if Time Out on Req */
2450
2451 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2452 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2453 {
2454 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2455 WR_HARPOON(port+hp_xferstat, 0);
2456 WR_HARPOON(port+hp_fiforead, 0);
2457 WR_HARPOON(port+hp_fifowrite, 0);
2458 if (pCurrSCCB != NULL)
2459 {
2460 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2461 }
2462 message = 0x00;
2463 do
2464 {
2465 ACCEPT_MSG_ATN(port);
2466 TimeOutLoop = 0;
2467 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2468 (TimeOutLoop++ < 20000) ){}
2469 if (TimeOutLoop > 20000)
2470 {
2471 WRW_HARPOON((port+hp_intstat), PARITY);
2472 return(message);
2473 }
2474 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2475 {
2476 WRW_HARPOON((port+hp_intstat), PARITY);
2477 return(message);
2478 }
2479 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2480
2481 RD_HARPOON(port+hp_scsidata_0);
2482
2483 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2484
2485 }while(1);
2486
2487 }
2488 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2489 WR_HARPOON(port+hp_xferstat, 0);
2490 WR_HARPOON(port+hp_fiforead, 0);
2491 WR_HARPOON(port+hp_fifowrite, 0);
2492 return(message);
2493}
2494
2495
2496/*---------------------------------------------------------------------
2497 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002498 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 *
2500 * Description: Load up automation and select target device.
2501 *
2502 *---------------------------------------------------------------------*/
2503
James Bottomley 47b5d692005-04-24 02:38:05 -05002504static void FPT_ssel(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505{
2506
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 UCHAR auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510 PSCCBcard CurrCard;
2511 PSCCB currSCCB;
2512 PSCCBMgr_tar_info currTar_Info;
2513 UCHAR lastTag, lun;
2514
James Bottomley 47b5d692005-04-24 02:38:05 -05002515 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 currSCCB = CurrCard->currentSCCB;
2517 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002518 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519 lastTag = CurrCard->tagQ_Lst;
2520
2521 ARAM_ACCESS(port);
2522
2523
2524 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2525 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2526
2527 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2528 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2529
2530 lun = currSCCB->Lun;
2531 else
2532 lun = 0;
2533
2534
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 if (CurrCard->globalFlags & F_TAG_STARTED)
2536 {
2537 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2538 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002539 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2541 == TAG_Q_TRYING))
2542 {
2543
2544 if (currTar_Info->TarTagQ_Cnt !=0)
2545 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002546 currTar_Info->TarLUNBusy[lun] = 1;
2547 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 SGRAM_ACCESS(port);
2549 return;
2550 }
2551
2552 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002553 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 }
2555
2556 } /*End non-tagged */
2557
2558 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002559 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560 }
2561
2562 } /*!Use cmd Q Tagged */
2563
2564 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002565 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002567 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568 SGRAM_ACCESS(port);
2569 return;
2570 }
2571
James Bottomley 47b5d692005-04-24 02:38:05 -05002572 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
2574 } /*else use cmd Q tagged */
2575
2576 } /*if glob tagged started */
2577
2578 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002579 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 }
2581
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
2583
2584 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2585 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2586 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2587 {
2588 if(CurrCard->discQCount >= QUEUE_DEPTH)
2589 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002590 currTar_Info->TarLUNBusy[lun] = 1;
2591 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 SGRAM_ACCESS(port);
2593 return;
2594 }
2595 for (i = 1; i < QUEUE_DEPTH; i++)
2596 {
2597 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2598 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2599 {
2600 CurrCard->tagQ_Lst = lastTag;
2601 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2602 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2603 CurrCard->discQCount++;
2604 break;
2605 }
2606 }
2607 if(i == QUEUE_DEPTH)
2608 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002609 currTar_Info->TarLUNBusy[lun] = 1;
2610 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611 SGRAM_ACCESS(port);
2612 return;
2613 }
2614 }
2615
2616
2617
James Bottomley 47b5d692005-04-24 02:38:05 -05002618 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619
2620 WR_HARPOON(port+hp_select_id, target);
2621 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2622
2623 if (currSCCB->OperationCode == RESET_COMMAND) {
2624 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2625 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2626
2627 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2628
2629 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2630
2631 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002632 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2634
2635 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2636 {
2637 currTar_Info->TarSyncCtrl = 0;
2638 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2639 }
2640
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2642 {
2643 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2644 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
James Bottomley 47b5d692005-04-24 02:38:05 -05002646 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2647 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648
2649 }
2650
2651 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2652 {
2653 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2654 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2655
2656 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2657
2658 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2659 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2660 >> 6) | (UCHAR)0x20)));
2661 WRW_HARPOON((port+SYNC_MSGS+2),
2662 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2663 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2664
2665 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002666 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
2668 }
2669
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002671 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2673 }
2674
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2676 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002677 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2679 }
2680
2681
2682 if (!auto_loaded)
2683 {
2684
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685 if (currSCCB->ControlByte & F_USE_CMD_Q)
2686 {
2687
2688 CurrCard->globalFlags |= F_TAG_STARTED;
2689
2690 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2691 == TAG_Q_REJECT)
2692 {
2693 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2694
2695 /* Fix up the start instruction with a jump to
2696 Non-Tag-CMD handling */
2697 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2698
2699 WRW_HARPOON((port+NON_TAG_ID_MSG),
2700 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2701
2702 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2703
2704 /* Setup our STATE so we know what happend when
2705 the wheels fall off. */
2706 currSCCB->Sccb_scsistat = SELECT_ST;
2707
James Bottomley 47b5d692005-04-24 02:38:05 -05002708 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 }
2710
2711 else
2712 {
2713 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2714
2715 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2716 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2717 >> 6) | (UCHAR)0x20)));
2718
2719 for (i = 1; i < QUEUE_DEPTH; i++)
2720 {
2721 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2722 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2723 {
2724 WRW_HARPOON((port+ID_MSG_STRT+6),
2725 (MPM_OP+AMSG_OUT+lastTag));
2726 CurrCard->tagQ_Lst = lastTag;
2727 currSCCB->Sccb_tag = lastTag;
2728 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2729 CurrCard->discQCount++;
2730 break;
2731 }
2732 }
2733
2734
2735 if ( i == QUEUE_DEPTH )
2736 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002737 currTar_Info->TarLUNBusy[lun] = 1;
2738 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739 SGRAM_ACCESS(port);
2740 return;
2741 }
2742
2743 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2744
2745 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2746 }
2747 }
2748
2749 else
2750 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
2752 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2753
2754 WRW_HARPOON((port+NON_TAG_ID_MSG),
2755 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2756
2757 currSCCB->Sccb_scsistat = SELECT_ST;
2758
2759 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761
2762
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 theCCB = (UCHAR *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764
2765 cdb_reg = port + CMD_STRT;
2766
2767 for (i=0; i < currSCCB->CdbLength; i++)
2768 {
2769 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2770 cdb_reg +=2;
2771 theCCB++;
2772 }
2773
2774 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2775 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2776
2777 } /* auto_loaded */
2778
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2780 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781
2782 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2783
2784 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2785
2786
2787 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2788 {
2789 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2790 }
2791 else
2792 {
2793
2794/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
2795 auto_loaded |= AUTO_IMMED; */
2796 auto_loaded = AUTO_IMMED;
2797
2798 DISABLE_AUTO(port);
2799
2800 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2801 }
2802
2803 SGRAM_ACCESS(port);
2804}
2805
2806
2807/*---------------------------------------------------------------------
2808 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002809 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810 *
2811 * Description: Hookup the correct CCB and handle the incoming messages.
2812 *
2813 *---------------------------------------------------------------------*/
2814
James Bottomley 47b5d692005-04-24 02:38:05 -05002815static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816{
2817
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819
2820
2821 PSCCBMgr_tar_info currTar_Info;
2822 PSCCB currSCCB;
2823
2824
2825
2826
2827 if(pCurrCard->currentSCCB != NULL)
2828 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002829 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 DISABLE_AUTO(port);
2831
2832
2833 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2834
2835
2836 currSCCB = pCurrCard->currentSCCB;
2837 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2838 {
2839 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2840 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2841 }
2842 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2843 {
2844 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2845 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2846 }
2847 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2848 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2849 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002850 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 if(currSCCB->Sccb_scsistat != ABORT_ST)
2852 {
2853 pCurrCard->discQCount--;
2854 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2855 = NULL;
2856 }
2857 }
2858 else
2859 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002860 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 if(currSCCB->Sccb_tag)
2862 {
2863 if(currSCCB->Sccb_scsistat != ABORT_ST)
2864 {
2865 pCurrCard->discQCount--;
2866 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2867 }
2868 }else
2869 {
2870 if(currSCCB->Sccb_scsistat != ABORT_ST)
2871 {
2872 pCurrCard->discQCount--;
2873 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2874 }
2875 }
2876 }
2877
James Bottomley 47b5d692005-04-24 02:38:05 -05002878 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 }
2880
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882
2883
2884 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002885 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886
2887
2888 msgRetryCount = 0;
2889 do
2890 {
2891
James Bottomley 47b5d692005-04-24 02:38:05 -05002892 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893 tag = 0;
2894
2895
2896 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2897 {
2898 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2899 {
2900
2901 WRW_HARPOON((port+hp_intstat), PHASE);
2902 return;
2903 }
2904 }
2905
2906 WRW_HARPOON((port+hp_intstat), PHASE);
2907 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2908 {
2909
James Bottomley 47b5d692005-04-24 02:38:05 -05002910 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 if (message)
2912 {
2913
2914 if (message <= (0x80 | LUN_MASK))
2915 {
2916 lun = message & (UCHAR)LUN_MASK;
2917
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2919 {
2920 if (currTar_Info->TarTagQ_Cnt != 0)
2921 {
2922
2923 if (!(currTar_Info->TarLUN_CA))
2924 {
2925 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2926
2927
James Bottomley 47b5d692005-04-24 02:38:05 -05002928 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 if (message)
2930 {
2931 ACCEPT_MSG(port);
2932 }
2933
2934 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002935 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936
James Bottomley 47b5d692005-04-24 02:38:05 -05002937 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002939 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940
2941 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002942 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943 }
2944
2945 } /*C.A. exists! */
2946
2947 } /*End Q cnt != 0 */
2948
2949 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950
2951 } /*End valid ID message. */
2952
2953 else
2954 {
2955
2956 ACCEPT_MSG_ATN(port);
2957 }
2958
2959 } /* End good id message. */
2960
2961 else
2962 {
2963
James Bottomley 47b5d692005-04-24 02:38:05 -05002964 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965 }
2966 }
2967 else
2968 {
2969 ACCEPT_MSG_ATN(port);
2970
2971 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2972 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2973 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2974
2975 return;
2976 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977
James Bottomley 47b5d692005-04-24 02:38:05 -05002978 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 {
2980 msgRetryCount++;
2981 if(msgRetryCount == 1)
2982 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002983 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 }
2985 else
2986 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002987 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988
James Bottomley 47b5d692005-04-24 02:38:05 -05002989 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990
James Bottomley 47b5d692005-04-24 02:38:05 -05002991 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 {
2993
James Bottomley 47b5d692005-04-24 02:38:05 -05002994 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995
2996 }
2997
James Bottomley 47b5d692005-04-24 02:38:05 -05002998 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999 {
3000
James Bottomley 47b5d692005-04-24 02:38:05 -05003001 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 }
3003
3004
James Bottomley 47b5d692005-04-24 02:38:05 -05003005 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3006 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007 return;
3008 }
3009 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003010 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011
3012
3013
3014 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3015 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3016 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003017 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3019 if(pCurrCard->currentSCCB != NULL)
3020 {
3021 ACCEPT_MSG(port);
3022 }
3023 else
3024 {
3025 ACCEPT_MSG_ATN(port);
3026 }
3027 }
3028 else
3029 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003030 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031
3032
3033 if (tag)
3034 {
3035 if (pCurrCard->discQ_Tbl[tag] != NULL)
3036 {
3037 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3038 currTar_Info->TarTagQ_Cnt--;
3039 ACCEPT_MSG(port);
3040 }
3041 else
3042 {
3043 ACCEPT_MSG_ATN(port);
3044 }
3045 }else
3046 {
3047 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3048 if(pCurrCard->currentSCCB != NULL)
3049 {
3050 ACCEPT_MSG(port);
3051 }
3052 else
3053 {
3054 ACCEPT_MSG_ATN(port);
3055 }
3056 }
3057 }
3058
3059 if(pCurrCard->currentSCCB != NULL)
3060 {
3061 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3062 {
3063 /* During Abort Tag command, the target could have got re-selected
3064 and completed the command. Check the select Q and remove the CCB
3065 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003066 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 }
3068 }
3069
3070
3071 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3072 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3073 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3074}
3075
James Bottomley 47b5d692005-04-24 02:38:05 -05003076static void FPT_SendMsg(ULONG port, UCHAR message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077{
3078 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3079 {
3080 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3081 {
3082
3083 WRW_HARPOON((port+hp_intstat), PHASE);
3084 return;
3085 }
3086 }
3087
3088 WRW_HARPOON((port+hp_intstat), PHASE);
3089 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3090 {
3091 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3092
3093
3094 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3095
3096 WR_HARPOON(port+hp_scsidata_0,message);
3097
3098 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3099
3100 ACCEPT_MSG(port);
3101
3102 WR_HARPOON(port+hp_portctrl_0, 0x00);
3103
3104 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3105 (message == SMABORT_TAG) )
3106 {
3107 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3108
3109 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3110 {
3111 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3112 }
3113 }
3114 }
3115}
3116
3117/*---------------------------------------------------------------------
3118 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003119 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 *
3121 * Description: Determine the proper responce to the message from the
3122 * target device.
3123 *
3124 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003125static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126{
3127 PSCCB currSCCB;
3128 PSCCBcard CurrCard;
3129 PSCCBMgr_tar_info currTar_Info;
3130
James Bottomley 47b5d692005-04-24 02:38:05 -05003131 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132 currSCCB = CurrCard->currentSCCB;
3133
James Bottomley 47b5d692005-04-24 02:38:05 -05003134 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135
3136 if (message == SMREST_DATA_PTR)
3137 {
3138 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3139 {
3140 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3141
James Bottomley 47b5d692005-04-24 02:38:05 -05003142 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 }
3144
3145 ACCEPT_MSG(port);
3146 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3147 }
3148
3149 else if (message == SMCMD_COMP)
3150 {
3151
3152
3153 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3154 {
3155 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
3156 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
3157 }
3158
3159 ACCEPT_MSG(port);
3160
3161 }
3162
3163 else if ((message == SMNO_OP) || (message >= SMIDENT)
3164 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3165 {
3166
3167 ACCEPT_MSG(port);
3168 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3169 }
3170
3171 else if (message == SMREJECT)
3172 {
3173
3174 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3175 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3176 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3177 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3178
3179 {
3180 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3181
3182 ACCEPT_MSG(port);
3183
3184
3185 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3186 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3187
3188 if(currSCCB->Lun == 0x00)
3189 {
3190 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3191 {
3192
3193 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3194
3195 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3196 }
3197
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3199 {
3200
3201
3202 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3203 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3204
3205 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3206
3207 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208
3209 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3210 {
3211 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3212 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3213
3214
3215 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3216 CurrCard->discQCount--;
3217 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3218 currSCCB->Sccb_tag = 0x00;
3219
3220 }
3221 }
3222
3223 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3224 {
3225
3226
3227 if(currSCCB->Lun == 0x00)
3228 {
3229 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3230 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3231 }
3232 }
3233
3234 else
3235 {
3236
3237 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3238 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003239 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003241 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242
3243
3244 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
3245
3246 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3247
3248 }
3249 }
3250
3251 else
3252 {
3253 ACCEPT_MSG(port);
3254
3255 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3256 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3257
3258 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3259 {
3260 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3261 }
3262 }
3263 }
3264
3265 else if (message == SMEXT)
3266 {
3267
3268 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003269 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003270 }
3271
3272 else if (message == SMIGNORWR)
3273 {
3274
3275 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3276
James Bottomley 47b5d692005-04-24 02:38:05 -05003277 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278
3279 if(currSCCB->Sccb_scsimsg != SMPARITY)
3280 ACCEPT_MSG(port);
3281 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3282 }
3283
3284
3285 else
3286 {
3287
3288 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3289 currSCCB->Sccb_scsimsg = SMREJECT;
3290
3291 ACCEPT_MSG_ATN(port);
3292 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3293 }
3294}
3295
3296
3297/*---------------------------------------------------------------------
3298 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003299 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300 *
3301 * Description: Decide what to do with the extended message.
3302 *
3303 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003304static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003305{
3306 UCHAR length,message;
3307
James Bottomley 47b5d692005-04-24 02:38:05 -05003308 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309 if (length)
3310 {
3311
3312 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003313 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003314 if (message)
3315 {
3316
3317 if (message == SMSYNC)
3318 {
3319
3320 if (length == 0x03)
3321 {
3322
3323 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003324 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 }
3326 else
3327 {
3328
3329 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3330 ACCEPT_MSG_ATN(port);
3331 }
3332 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 else if (message == SMWDTR)
3334 {
3335
3336 if (length == 0x02)
3337 {
3338
3339 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003340 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 }
3342 else
3343 {
3344
3345 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3346 ACCEPT_MSG_ATN(port);
3347
3348 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3349 }
3350 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003351 else
3352 {
3353
3354 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3355 ACCEPT_MSG_ATN(port);
3356
3357 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3358 }
3359 }
3360 else
3361 {
3362 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3363 ACCEPT_MSG(port);
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3365 }
3366 }else
3367 {
3368 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3369 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3370 }
3371}
3372
3373
3374/*---------------------------------------------------------------------
3375 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003376 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 *
3378 * Description: Read in a message byte from the SCSI bus, and check
3379 * for a parity error.
3380 *
3381 *---------------------------------------------------------------------*/
3382
James Bottomley 47b5d692005-04-24 02:38:05 -05003383static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003384{
3385 PSCCB currSCCB;
3386 PSCCBMgr_tar_info currTar_Info;
3387
James Bottomley 47b5d692005-04-24 02:38:05 -05003388 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3389 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390
3391 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3392
3393
3394 WRW_HARPOON((port+ID_MSG_STRT),
3395 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3396
3397 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3398
3399 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3400 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3401 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3402
3403
3404 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3405
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3407
3408 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3409
3410 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3411
3412 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3413
3414 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3415
3416 else
3417 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3418
3419
3420 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3421 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3422 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3423
3424
James Bottomley 47b5d692005-04-24 02:38:05 -05003425 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 {
3427 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3428 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3429 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
3430 }
3431 else
3432 {
3433 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3434 }
3435
3436
James Bottomley 47b5d692005-04-24 02:38:05 -05003437 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003438 }
3439
3440 else {
3441
3442 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3443 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003444 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445 }
3446}
3447
3448
3449
3450/*---------------------------------------------------------------------
3451 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003452 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453 *
3454 * Description: The has sent us a Sync Nego message so handle it as
3455 * necessary.
3456 *
3457 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003458static void FPT_stsyncn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003459{
3460 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3461 PSCCB currSCCB;
3462 PSCCBMgr_tar_info currTar_Info;
3463
James Bottomley 47b5d692005-04-24 02:38:05 -05003464 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3465 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466
James Bottomley 47b5d692005-04-24 02:38:05 -05003467 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003468
3469 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3470 {
3471 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3472 return;
3473 }
3474
3475 ACCEPT_MSG(port);
3476
3477
James Bottomley 47b5d692005-04-24 02:38:05 -05003478 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479
3480 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3481 {
3482 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3483 return;
3484 }
3485
3486 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3487
3488 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3489
3490 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3491
3492 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3493
3494 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3495
3496 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3497 else
3498
3499 our_sync_msg = 0; /* Message = Async */
3500
3501 if (sync_msg < our_sync_msg) {
3502 sync_msg = our_sync_msg; /*if faster, then set to max. */
3503 }
3504
3505 if (offset == ASYNC)
3506 sync_msg = ASYNC;
3507
3508 if (offset > MAX_OFFSET)
3509 offset = MAX_OFFSET;
3510
3511 sync_reg = 0x00;
3512
3513 if (sync_msg > 12)
3514
3515 sync_reg = 0x20; /* Use 10MB/s */
3516
3517 if (sync_msg > 25)
3518
3519 sync_reg = 0x40; /* Use 6.6MB/s */
3520
3521 if (sync_msg > 38)
3522
3523 sync_reg = 0x60; /* Use 5MB/s */
3524
3525 if (sync_msg > 50)
3526
3527 sync_reg = 0x80; /* Use 4MB/s */
3528
3529 if (sync_msg > 62)
3530
3531 sync_reg = 0xA0; /* Use 3.33MB/s */
3532
3533 if (sync_msg > 75)
3534
3535 sync_reg = 0xC0; /* Use 2.85MB/s */
3536
3537 if (sync_msg > 87)
3538
3539 sync_reg = 0xE0; /* Use 2.5MB/s */
3540
3541 if (sync_msg > 100) {
3542
3543 sync_reg = 0x00; /* Use ASYNC */
3544 offset = 0x00;
3545 }
3546
3547
Linus Torvalds1da177e2005-04-16 15:20:36 -07003548 if (currTar_Info->TarStatus & WIDE_ENABLED)
3549
3550 sync_reg |= offset;
3551
3552 else
3553
3554 sync_reg |= (offset | NARROW_SCSI);
3555
James Bottomley 47b5d692005-04-24 02:38:05 -05003556 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557
3558
3559 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3560
3561
3562 ACCEPT_MSG(port);
3563
3564 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3565 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3566
3567 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3568 }
3569
3570 else {
3571
3572
3573 ACCEPT_MSG_ATN(port);
3574
James Bottomley 47b5d692005-04-24 02:38:05 -05003575 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576
3577 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3578 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3579 }
3580}
3581
3582
3583/*---------------------------------------------------------------------
3584 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003585 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586 *
3587 * Description: Answer the targets sync message.
3588 *
3589 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003590static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003591{
3592 ARAM_ACCESS(port);
3593 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3594 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3595 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3596 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3597 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3598 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3599 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3600 SGRAM_ACCESS(port);
3601
3602 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3603 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3604
3605 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3606
3607 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3608}
3609
3610
3611
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612/*---------------------------------------------------------------------
3613 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003614 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615 *
3616 * Description: Read in a message byte from the SCSI bus, and check
3617 * for a parity error.
3618 *
3619 *---------------------------------------------------------------------*/
3620
James Bottomley 47b5d692005-04-24 02:38:05 -05003621static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003622{
3623 PSCCB currSCCB;
3624 PSCCBMgr_tar_info currTar_Info;
3625
James Bottomley 47b5d692005-04-24 02:38:05 -05003626 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3627 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628
3629 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3630
3631
3632 WRW_HARPOON((port+ID_MSG_STRT),
3633 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3634
3635 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3636
3637 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3638 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3639 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3640 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3641 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3642 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3643
3644 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3645
3646
3647 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3648 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
3649
James Bottomley 47b5d692005-04-24 02:38:05 -05003650 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003651 }
3652
3653 else {
3654
3655 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3656 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3657
3658 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003659 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660 }
3661}
3662
3663
3664
3665/*---------------------------------------------------------------------
3666 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003667 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 *
3669 * Description: The has sent us a Wide Nego message so handle it as
3670 * necessary.
3671 *
3672 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003673static void FPT_stwidn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003674{
3675 UCHAR width;
3676 PSCCB currSCCB;
3677 PSCCBMgr_tar_info currTar_Info;
3678
James Bottomley 47b5d692005-04-24 02:38:05 -05003679 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3680 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681
James Bottomley 47b5d692005-04-24 02:38:05 -05003682 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003683
3684 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3685 {
3686 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3687 return;
3688 }
3689
3690
3691 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3692 width = 0;
3693
3694 if (width) {
3695 currTar_Info->TarStatus |= WIDE_ENABLED;
3696 width = 0;
3697 }
3698 else {
3699 width = NARROW_SCSI;
3700 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3701 }
3702
3703
James Bottomley 47b5d692005-04-24 02:38:05 -05003704 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705
3706
3707 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3708 {
3709
3710
3711
3712 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3713
3714 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3715 {
3716 ACCEPT_MSG_ATN(port);
3717 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003718 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003719 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3720 SGRAM_ACCESS(port);
3721 }
3722 else
3723 {
3724 ACCEPT_MSG(port);
3725 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3726 }
3727 }
3728
3729 else {
3730
3731
3732 ACCEPT_MSG_ATN(port);
3733
3734 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3735 width = SM16BIT;
3736 else
3737 width = SM8BIT;
3738
James Bottomley 47b5d692005-04-24 02:38:05 -05003739 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740
3741 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3742 }
3743}
3744
3745
3746/*---------------------------------------------------------------------
3747 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003748 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 *
3750 * Description: Answer the targets Wide nego message.
3751 *
3752 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003753static void FPT_siwidr(ULONG port, UCHAR width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003754{
3755 ARAM_ACCESS(port);
3756 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3757 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3758 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3759 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3760 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3761 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3762 SGRAM_ACCESS(port);
3763
3764 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3765 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3766
3767 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3768
3769 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3770}
3771
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772
3773
3774/*---------------------------------------------------------------------
3775 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003776 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003777 *
3778 * Description: Write the desired value to the Sync Register for the
3779 * ID specified.
3780 *
3781 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003782static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
3783 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784{
3785 UCHAR index;
3786
3787 index = p_id;
3788
3789 switch (index) {
3790
3791 case 0:
3792 index = 12; /* hp_synctarg_0 */
3793 break;
3794 case 1:
3795 index = 13; /* hp_synctarg_1 */
3796 break;
3797 case 2:
3798 index = 14; /* hp_synctarg_2 */
3799 break;
3800 case 3:
3801 index = 15; /* hp_synctarg_3 */
3802 break;
3803 case 4:
3804 index = 8; /* hp_synctarg_4 */
3805 break;
3806 case 5:
3807 index = 9; /* hp_synctarg_5 */
3808 break;
3809 case 6:
3810 index = 10; /* hp_synctarg_6 */
3811 break;
3812 case 7:
3813 index = 11; /* hp_synctarg_7 */
3814 break;
3815 case 8:
3816 index = 4; /* hp_synctarg_8 */
3817 break;
3818 case 9:
3819 index = 5; /* hp_synctarg_9 */
3820 break;
3821 case 10:
3822 index = 6; /* hp_synctarg_10 */
3823 break;
3824 case 11:
3825 index = 7; /* hp_synctarg_11 */
3826 break;
3827 case 12:
3828 index = 0; /* hp_synctarg_12 */
3829 break;
3830 case 13:
3831 index = 1; /* hp_synctarg_13 */
3832 break;
3833 case 14:
3834 index = 2; /* hp_synctarg_14 */
3835 break;
3836 case 15:
3837 index = 3; /* hp_synctarg_15 */
3838
3839 }
3840
3841 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3842
3843 currTar_Info->TarSyncCtrl = p_sync_value;
3844}
3845
3846
3847/*---------------------------------------------------------------------
3848 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003849 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003850 *
3851 * Description: Reset the desired card's SCSI bus.
3852 *
3853 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003854static void FPT_sresb(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003855{
3856 UCHAR scsiID, i;
3857
3858 PSCCBMgr_tar_info currTar_Info;
3859
3860 WR_HARPOON(port+hp_page_ctrl,
3861 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3862 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3863
3864 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3865
3866 scsiID = RD_HARPOON(port+hp_seltimeout);
3867 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3868 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3869
3870 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3871
3872 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3873
3874 WR_HARPOON(port+hp_seltimeout,scsiID);
3875
3876 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3877
James Bottomley 47b5d692005-04-24 02:38:05 -05003878 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879
3880 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3881
3882 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3883
3884 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3885 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003886 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887
3888 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3889 {
3890 currTar_Info->TarSyncCtrl = 0;
3891 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3892 }
3893
3894 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3895 {
3896 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3897 }
3898
James Bottomley 47b5d692005-04-24 02:38:05 -05003899 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900
James Bottomley 47b5d692005-04-24 02:38:05 -05003901 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003902 }
3903
James Bottomley 47b5d692005-04-24 02:38:05 -05003904 FPT_BL_Card[p_card].scanIndex = 0x00;
3905 FPT_BL_Card[p_card].currentSCCB = NULL;
3906 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003908 FPT_BL_Card[p_card].cmdCounter = 0x00;
3909 FPT_BL_Card[p_card].discQCount = 0x00;
3910 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003911
3912 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003913 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914
3915 WR_HARPOON(port+hp_page_ctrl,
3916 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3917
3918}
3919
3920/*---------------------------------------------------------------------
3921 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003922 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 *
3924 * Description: Setup for the Auto Sense command.
3925 *
3926 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003927static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928{
3929 UCHAR i;
3930 PSCCB currSCCB;
3931
3932 currSCCB = pCurrCard->currentSCCB;
3933
3934
3935 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3936
3937 for (i = 0; i < 6; i++) {
3938
3939 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3940 }
3941
3942 currSCCB->CdbLength = SIX_BYTE_CMD;
3943 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3944 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
3945 currSCCB->Cdb[2] = 0x00;
3946 currSCCB->Cdb[3] = 0x00;
3947 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3948 currSCCB->Cdb[5] = 0x00;
3949
3950 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3951
3952 currSCCB->Sccb_ATC = 0x00;
3953
3954 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3955
3956 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3957
3958 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
3959
3960 currSCCB->ControlByte = 0x00;
3961
3962 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3963}
3964
3965
3966
3967/*---------------------------------------------------------------------
3968 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003969 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970 *
3971 * Description: Transfer data into the bit bucket until the device
3972 * decides to switch phase.
3973 *
3974 *---------------------------------------------------------------------*/
3975
James Bottomley 47b5d692005-04-24 02:38:05 -05003976static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003977{
3978 UCHAR curr_phz;
3979
3980
3981 DISABLE_AUTO(p_port);
3982
James Bottomley 47b5d692005-04-24 02:38:05 -05003983 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984
James Bottomley 47b5d692005-04-24 02:38:05 -05003985 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986
3987 }
3988
3989 /* If the Automation handled the end of the transfer then do not
3990 match the phase or we will get out of sync with the ISR. */
3991
3992 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3993 return;
3994
3995 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3996
3997 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
3998
3999 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4000
4001
4002 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4003
4004 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4005 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
4006 {
4007 if (curr_phz & (UCHAR)SCSI_IOBIT)
4008 {
4009 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4010
4011 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4012 {
4013 RD_HARPOON(p_port+hp_fifodata_0);
4014 }
4015 }
4016 else
4017 {
4018 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4019 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4020 {
4021 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4022 }
4023 }
4024 } /* End of While loop for padding data I/O phase */
4025
4026 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4027 {
4028 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4029 break;
4030 }
4031
4032 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4033 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4034 {
4035 RD_HARPOON(p_port+hp_fifodata_0);
4036 }
4037
4038 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4039 {
4040 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4041 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4042
4043 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4044 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4045 }
4046}
4047
4048
4049/*---------------------------------------------------------------------
4050 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004051 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052 *
4053 * Description: Make sure data has been flushed from both FIFOs and abort
4054 * the operations if necessary.
4055 *
4056 *---------------------------------------------------------------------*/
4057
James Bottomley 47b5d692005-04-24 02:38:05 -05004058static void FPT_schkdd(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004059{
4060 USHORT TimeOutLoop;
4061 UCHAR sPhase;
4062
4063 PSCCB currSCCB;
4064
James Bottomley 47b5d692005-04-24 02:38:05 -05004065 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004066
4067
4068 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4069 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4070 return;
4071 }
4072
4073
4074
4075 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4076 {
4077
4078 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4079
4080 currSCCB->Sccb_XferCnt = 1;
4081
4082 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4083 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4084 WR_HARPOON(port+hp_xferstat, 0x00);
4085 }
4086
4087 else
4088 {
4089
4090 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4091
4092 currSCCB->Sccb_XferCnt = 0;
4093 }
4094
4095 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4096 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4097
4098 currSCCB->HostStatus = SCCB_PARITY_ERR;
4099 WRW_HARPOON((port+hp_intstat), PARITY);
4100 }
4101
4102
James Bottomley 47b5d692005-04-24 02:38:05 -05004103 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004104
4105
4106 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4107
4108 TimeOutLoop = 0;
4109
4110 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4111 {
4112 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4113 return;
4114 }
4115 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
4116 break;
4117 }
4118 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4119 return;
4120 }
4121 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4122 break;
4123 }
4124
4125 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4126 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4127 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
4128 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4129 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4130 {
4131
4132 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4133
4134 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4135 {
4136 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004137 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138 }
4139
4140 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004141 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004142 }
4143 }
4144 else
4145 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004146 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004147 if (!(RDW_HARPOON((port+hp_intstat)) &
4148 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4149 {
4150 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004151 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 }
4153 }
4154
4155 }
4156
4157 else {
4158 WR_HARPOON(port+hp_portctrl_0, 0x00);
4159 }
4160}
4161
4162
4163/*---------------------------------------------------------------------
4164 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004165 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166 *
4167 * Description: Setup SCCB manager fields in this SCCB.
4168 *
4169 *---------------------------------------------------------------------*/
4170
James Bottomley 47b5d692005-04-24 02:38:05 -05004171static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004172{
4173 PSCCBMgr_tar_info currTar_Info;
4174
4175 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4176 {
4177 return;
4178 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004179 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004180
4181 p_sccb->Sccb_XferState = 0x00;
4182 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4183
4184 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4185 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4186
4187 p_sccb->Sccb_SGoffset = 0;
4188 p_sccb->Sccb_XferState = F_SG_XFER;
4189 p_sccb->Sccb_XferCnt = 0x00;
4190 }
4191
4192 if (p_sccb->DataLength == 0x00)
4193
4194 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4195
4196 if (p_sccb->ControlByte & F_USE_CMD_Q)
4197 {
4198 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4199 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4200
4201 else
4202 currTar_Info->TarStatus |= TAG_Q_TRYING;
4203 }
4204
4205/* For !single SCSI device in system & device allow Disconnect
4206 or command is tag_q type then send Cmd with Disconnect Enable
4207 else send Cmd with Disconnect Disable */
4208
4209/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004210 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004211 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4212 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4213*/
4214 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4215 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4216 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4217 }
4218
4219 else {
4220
4221 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
4222 }
4223
4224 p_sccb->HostStatus = 0x00;
4225 p_sccb->TargetStatus = 0x00;
4226 p_sccb->Sccb_tag = 0x00;
4227 p_sccb->Sccb_MGRFlags = 0x00;
4228 p_sccb->Sccb_sgseg = 0x00;
4229 p_sccb->Sccb_ATC = 0x00;
4230 p_sccb->Sccb_savedATC = 0x00;
4231/*
4232 p_sccb->SccbVirtDataPtr = 0x00;
4233 p_sccb->Sccb_forwardlink = NULL;
4234 p_sccb->Sccb_backlink = NULL;
4235 */
4236 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4237 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4238 p_sccb->Sccb_scsimsg = SMNO_OP;
4239
4240}
4241
4242
Linus Torvalds1da177e2005-04-16 15:20:36 -07004243/*---------------------------------------------------------------------
4244 *
4245 * Function: Phase Decode
4246 *
4247 * Description: Determine the phase and call the appropriate function.
4248 *
4249 *---------------------------------------------------------------------*/
4250
James Bottomley 47b5d692005-04-24 02:38:05 -05004251static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004252{
4253 unsigned char phase_ref;
James Bottomley 47b5d692005-04-24 02:38:05 -05004254 void (*phase) (ULONG, UCHAR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004255
4256
4257 DISABLE_AUTO(p_port);
4258
4259 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4260
James Bottomley 47b5d692005-04-24 02:38:05 -05004261 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262
4263 (*phase)(p_port, p_card); /* Call the correct phase func */
4264}
4265
4266
4267
4268/*---------------------------------------------------------------------
4269 *
4270 * Function: Data Out Phase
4271 *
4272 * Description: Start up both the BusMaster and Xbow.
4273 *
4274 *---------------------------------------------------------------------*/
4275
James Bottomley 47b5d692005-04-24 02:38:05 -05004276static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004277{
4278
4279 PSCCB currSCCB;
4280
James Bottomley 47b5d692005-04-24 02:38:05 -05004281 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282 if (currSCCB == NULL)
4283 {
4284 return; /* Exit if No SCCB record */
4285 }
4286
4287 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4288 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4289
4290 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4291
4292 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4293
4294 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4295
James Bottomley 47b5d692005-04-24 02:38:05 -05004296 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297
4298 if (currSCCB->Sccb_XferCnt == 0) {
4299
4300
4301 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4302 (currSCCB->HostStatus == SCCB_COMPLETE))
4303 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4304
James Bottomley 47b5d692005-04-24 02:38:05 -05004305 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004307 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308 }
4309}
4310
4311
4312/*---------------------------------------------------------------------
4313 *
4314 * Function: Data In Phase
4315 *
4316 * Description: Startup the BusMaster and the XBOW.
4317 *
4318 *---------------------------------------------------------------------*/
4319
James Bottomley 47b5d692005-04-24 02:38:05 -05004320static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321{
4322
4323 PSCCB currSCCB;
4324
James Bottomley 47b5d692005-04-24 02:38:05 -05004325 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326
4327 if (currSCCB == NULL)
4328 {
4329 return; /* Exit if No SCCB record */
4330 }
4331
4332
4333 currSCCB->Sccb_scsistat = DATA_IN_ST;
4334 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4335 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4336
4337 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4338
4339 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4340
4341 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4342
James Bottomley 47b5d692005-04-24 02:38:05 -05004343 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344
4345 if (currSCCB->Sccb_XferCnt == 0) {
4346
4347
4348 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4349 (currSCCB->HostStatus == SCCB_COMPLETE))
4350 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4351
James Bottomley 47b5d692005-04-24 02:38:05 -05004352 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004354 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355
4356 }
4357}
4358
4359/*---------------------------------------------------------------------
4360 *
4361 * Function: Command Phase
4362 *
4363 * Description: Load the CDB into the automation and start it up.
4364 *
4365 *---------------------------------------------------------------------*/
4366
James Bottomley 47b5d692005-04-24 02:38:05 -05004367static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368{
4369 PSCCB currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004370 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371 UCHAR i;
4372
James Bottomley 47b5d692005-04-24 02:38:05 -05004373 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004374
4375 if (currSCCB->OperationCode == RESET_COMMAND) {
4376
4377 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4378 currSCCB->CdbLength = SIX_BYTE_CMD;
4379 }
4380
4381 WR_HARPOON(p_port+hp_scsisig, 0x00);
4382
4383 ARAM_ACCESS(p_port);
4384
4385
4386 cdb_reg = p_port + CMD_STRT;
4387
4388 for (i=0; i < currSCCB->CdbLength; i++) {
4389
4390 if (currSCCB->OperationCode == RESET_COMMAND)
4391
4392 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4393
4394 else
4395 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4396 cdb_reg +=2;
4397 }
4398
4399 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4400 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4401
4402 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4403
4404 currSCCB->Sccb_scsistat = COMMAND_ST;
4405
4406 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4407 SGRAM_ACCESS(p_port);
4408}
4409
4410
4411/*---------------------------------------------------------------------
4412 *
4413 * Function: Status phase
4414 *
4415 * Description: Bring in the status and command complete message bytes
4416 *
4417 *---------------------------------------------------------------------*/
4418
James Bottomley 47b5d692005-04-24 02:38:05 -05004419static void FPT_phaseStatus(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004420{
4421 /* Start-up the automation to finish off this command and let the
4422 isr handle the interrupt for command complete when it comes in.
4423 We could wait here for the interrupt to be generated?
4424 */
4425
4426 WR_HARPOON(port+hp_scsisig, 0x00);
4427
4428 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4429}
4430
4431
4432/*---------------------------------------------------------------------
4433 *
4434 * Function: Phase Message Out
4435 *
4436 * Description: Send out our message (if we have one) and handle whatever
4437 * else is involed.
4438 *
4439 *---------------------------------------------------------------------*/
4440
James Bottomley 47b5d692005-04-24 02:38:05 -05004441static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442{
4443 UCHAR message,scsiID;
4444 PSCCB currSCCB;
4445 PSCCBMgr_tar_info currTar_Info;
4446
James Bottomley 47b5d692005-04-24 02:38:05 -05004447 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448
4449 if (currSCCB != NULL) {
4450
4451 message = currSCCB->Sccb_scsimsg;
4452 scsiID = currSCCB->TargID;
4453
4454 if (message == SMDEV_RESET)
4455 {
4456
4457
James Bottomley 47b5d692005-04-24 02:38:05 -05004458 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004460 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004461
James Bottomley 47b5d692005-04-24 02:38:05 -05004462 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463 {
4464
James Bottomley 47b5d692005-04-24 02:38:05 -05004465 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004466
4467 }
4468
James Bottomley 47b5d692005-04-24 02:38:05 -05004469 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 {
4471
James Bottomley 47b5d692005-04-24 02:38:05 -05004472 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 }
4474
4475
James Bottomley 47b5d692005-04-24 02:38:05 -05004476 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4477 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004478 }
4479 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4480 {
4481 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004482 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004484 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4485 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 }
4487
4488 }
4489
4490 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4491 {
4492
4493
4494 if(message == SMNO_OP)
4495 {
4496 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4497
James Bottomley 47b5d692005-04-24 02:38:05 -05004498 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004499 return;
4500 }
4501 }
4502 else
4503 {
4504
4505
4506 if (message == SMABORT)
4507
James Bottomley 47b5d692005-04-24 02:38:05 -05004508 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004509 }
4510
4511 }
4512 else
4513 {
4514 message = SMABORT;
4515 }
4516
4517 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4518
4519
4520 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4521
4522 WR_HARPOON(port+hp_scsidata_0,message);
4523
4524 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4525
4526 ACCEPT_MSG(port);
4527
4528 WR_HARPOON(port+hp_portctrl_0, 0x00);
4529
4530 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4531 (message == SMABORT_TAG) )
4532 {
4533
4534 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4535
4536 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4537 {
4538 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4539
4540 if (currSCCB != NULL)
4541 {
4542
James Bottomley 47b5d692005-04-24 02:38:05 -05004543 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4544 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4545 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004547 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548
James Bottomley 47b5d692005-04-24 02:38:05 -05004549 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004550 }
4551
4552 else
4553 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004554 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004555 }
4556 }
4557
4558 else
4559 {
4560
James Bottomley 47b5d692005-04-24 02:38:05 -05004561 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004562 }
4563 }
4564
4565 else
4566 {
4567
4568 if(message == SMPARITY)
4569 {
4570 currSCCB->Sccb_scsimsg = SMNO_OP;
4571 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4572 }
4573 else
4574 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004575 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004576 }
4577 }
4578}
4579
4580
4581/*---------------------------------------------------------------------
4582 *
4583 * Function: Message In phase
4584 *
4585 * Description: Bring in the message and determine what to do with it.
4586 *
4587 *---------------------------------------------------------------------*/
4588
James Bottomley 47b5d692005-04-24 02:38:05 -05004589static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004590{
4591 UCHAR message;
4592 PSCCB currSCCB;
4593
James Bottomley 47b5d692005-04-24 02:38:05 -05004594 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004595
James Bottomley 47b5d692005-04-24 02:38:05 -05004596 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004597 {
4598
James Bottomley 47b5d692005-04-24 02:38:05 -05004599 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004600 }
4601
4602 message = RD_HARPOON(port+hp_scsidata_0);
4603 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4604 {
4605
4606 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4607
4608 }
4609
4610 else
4611 {
4612
James Bottomley 47b5d692005-04-24 02:38:05 -05004613 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004614 if (message)
4615 {
4616
4617
James Bottomley 47b5d692005-04-24 02:38:05 -05004618 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004619
4620 }
4621 else
4622 {
4623 if(currSCCB->Sccb_scsimsg != SMPARITY)
4624 ACCEPT_MSG(port);
4625 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4626 }
4627 }
4628
4629}
4630
4631
4632/*---------------------------------------------------------------------
4633 *
4634 * Function: Illegal phase
4635 *
4636 * Description: Target switched to some illegal phase, so all we can do
4637 * is report an error back to the host (if that is possible)
4638 * and send an ABORT message to the misbehaving target.
4639 *
4640 *---------------------------------------------------------------------*/
4641
James Bottomley 47b5d692005-04-24 02:38:05 -05004642static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004643{
4644 PSCCB currSCCB;
4645
James Bottomley 47b5d692005-04-24 02:38:05 -05004646 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004647
4648 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4649 if (currSCCB != NULL) {
4650
4651 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4652 currSCCB->Sccb_scsistat = ABORT_ST;
4653 currSCCB->Sccb_scsimsg = SMABORT;
4654 }
4655
4656 ACCEPT_MSG_ATN(port);
4657}
4658
4659
4660
4661/*---------------------------------------------------------------------
4662 *
4663 * Function: Phase Check FIFO
4664 *
4665 * Description: Make sure data has been flushed from both FIFOs and abort
4666 * the operations if necessary.
4667 *
4668 *---------------------------------------------------------------------*/
4669
James Bottomley 47b5d692005-04-24 02:38:05 -05004670static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004671{
4672 ULONG xfercnt;
4673 PSCCB currSCCB;
4674
James Bottomley 47b5d692005-04-24 02:38:05 -05004675 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004676
4677 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4678 {
4679
4680 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4681 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4682
4683
4684 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4685 {
4686 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4687
4688 currSCCB->Sccb_XferCnt = 0;
4689
4690 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4691 (currSCCB->HostStatus == SCCB_COMPLETE))
4692 {
4693 currSCCB->HostStatus = SCCB_PARITY_ERR;
4694 WRW_HARPOON((port+hp_intstat), PARITY);
4695 }
4696
James Bottomley 47b5d692005-04-24 02:38:05 -05004697 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004698
James Bottomley 47b5d692005-04-24 02:38:05 -05004699 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004700
4701 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4702 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4703
4704 }
4705 } /*End Data In specific code. */
4706
4707
4708
Linus Torvalds1da177e2005-04-16 15:20:36 -07004709 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004710
4711
4712 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4713
4714
4715 WR_HARPOON(port+hp_portctrl_0, 0x00);
4716
4717 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4718
4719 currSCCB->Sccb_XferCnt = xfercnt;
4720
4721 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4722 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4723
4724 currSCCB->HostStatus = SCCB_PARITY_ERR;
4725 WRW_HARPOON((port+hp_intstat), PARITY);
4726 }
4727
4728
James Bottomley 47b5d692005-04-24 02:38:05 -05004729 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004730
4731
4732 WR_HARPOON(port+hp_fifowrite, 0x00);
4733 WR_HARPOON(port+hp_fiforead, 0x00);
4734 WR_HARPOON(port+hp_xferstat, 0x00);
4735
4736 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4737}
4738
4739
4740/*---------------------------------------------------------------------
4741 *
4742 * Function: Phase Bus Free
4743 *
4744 * Description: We just went bus free so figure out if it was
4745 * because of command complete or from a disconnect.
4746 *
4747 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004748static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004749{
4750 PSCCB currSCCB;
4751
James Bottomley 47b5d692005-04-24 02:38:05 -05004752 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004753
4754 if (currSCCB != NULL)
4755 {
4756
4757 DISABLE_AUTO(port);
4758
4759
4760 if (currSCCB->OperationCode == RESET_COMMAND)
4761 {
4762
James Bottomley 47b5d692005-04-24 02:38:05 -05004763 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4764 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004766 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004767 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004768
James Bottomley 47b5d692005-04-24 02:38:05 -05004769 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004770
James Bottomley 47b5d692005-04-24 02:38:05 -05004771 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004772
4773 }
4774
4775 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4776 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778 (UCHAR)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004779 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004780 }
4781
4782 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4783 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4785 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4787
James Bottomley 47b5d692005-04-24 02:38:05 -05004788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004789 }
4790
Linus Torvalds1da177e2005-04-16 15:20:36 -07004791 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4792 {
4793 /* Make sure this is not a phony BUS_FREE. If we were
4794 reselected or if BUSY is NOT on then this is a
4795 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4796
4797 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4798 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4799 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4801 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004802 }
4803
4804 else
4805 {
4806 return;
4807 }
4808 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004809
4810 else
4811 {
4812
4813 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4814
4815 if (!currSCCB->HostStatus)
4816 {
4817 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4818 }
4819
James Bottomley 47b5d692005-04-24 02:38:05 -05004820 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4821 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4822 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004824 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825
James Bottomley 47b5d692005-04-24 02:38:05 -05004826 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004827 return;
4828 }
4829
4830
James Bottomley 47b5d692005-04-24 02:38:05 -05004831 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004832
4833 } /*end if !=null */
4834}
4835
4836
4837
4838
Linus Torvalds1da177e2005-04-16 15:20:36 -07004839/*---------------------------------------------------------------------
4840 *
4841 * Function: Auto Load Default Map
4842 *
4843 * Description: Load the Automation RAM with the defualt map values.
4844 *
4845 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004846static void FPT_autoLoadDefaultMap(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004847{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004848 ULONG map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004849
4850 ARAM_ACCESS(p_port);
4851 map_addr = p_port + hp_aramBase;
4852
4853 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4888 map_addr +=2; /*This means AYNC DATA IN */
4889 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4910 map_addr +=2;
4911 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4912 map_addr +=2;
4913 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4920 map_addr +=2;
4921 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4922 map_addr +=2;
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4924 map_addr +=2;
4925
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4927 map_addr +=2;
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4929 map_addr +=2;
4930 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4931 map_addr +=2;
4932 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4933 map_addr +=2; /* DIDN'T GET ONE */
4934 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4935 map_addr +=2;
4936 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4937 map_addr +=2;
4938 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4939
4940
4941
4942 SGRAM_ACCESS(p_port);
4943}
4944
4945/*---------------------------------------------------------------------
4946 *
4947 * Function: Auto Command Complete
4948 *
4949 * Description: Post command back to host and find another command
4950 * to execute.
4951 *
4952 *---------------------------------------------------------------------*/
4953
James Bottomley 47b5d692005-04-24 02:38:05 -05004954static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004955{
4956 PSCCB currSCCB;
4957 UCHAR status_byte;
4958
James Bottomley 47b5d692005-04-24 02:38:05 -05004959 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004960
4961 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4962
James Bottomley 47b5d692005-04-24 02:38:05 -05004963 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004964
4965 if (status_byte != SSGOOD) {
4966
4967 if (status_byte == SSQ_FULL) {
4968
4969
James Bottomley 47b5d692005-04-24 02:38:05 -05004970 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4971 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004972 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004973 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4974 if(FPT_BL_Card[p_card].discQCount != 0)
4975 FPT_BL_Card[p_card].discQCount--;
4976 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 -07004977 }
4978 else
4979 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004980 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004981 if(currSCCB->Sccb_tag)
4982 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004983 if(FPT_BL_Card[p_card].discQCount != 0)
4984 FPT_BL_Card[p_card].discQCount--;
4985 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004986 }else
4987 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004988 if(FPT_BL_Card[p_card].discQCount != 0)
4989 FPT_BL_Card[p_card].discQCount--;
4990 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004991 }
4992 }
4993
4994 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4995
James Bottomley 47b5d692005-04-24 02:38:05 -05004996 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004997
4998 return;
4999 }
5000
5001 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5002 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005004 (UCHAR)SYNC_SUPPORTED;
5005
James Bottomley 47b5d692005-04-24 02:38:05 -05005006 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5007 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005008
James Bottomley 47b5d692005-04-24 02:38:05 -05005009 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5010 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005011 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005012 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5013 if(FPT_BL_Card[p_card].discQCount != 0)
5014 FPT_BL_Card[p_card].discQCount--;
5015 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 -07005016 }
5017 else
5018 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005019 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005020 if(currSCCB->Sccb_tag)
5021 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005022 if(FPT_BL_Card[p_card].discQCount != 0)
5023 FPT_BL_Card[p_card].discQCount--;
5024 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005025 }else
5026 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005027 if(FPT_BL_Card[p_card].discQCount != 0)
5028 FPT_BL_Card[p_card].discQCount--;
5029 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005030 }
5031 }
5032 return;
5033
5034 }
5035
5036 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5037 {
5038
James Bottomley 47b5d692005-04-24 02:38:05 -05005039 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5040 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005041 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5042
James Bottomley 47b5d692005-04-24 02:38:05 -05005043 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5044 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005045
James Bottomley 47b5d692005-04-24 02:38:05 -05005046 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5047 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005048 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005049 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5050 if(FPT_BL_Card[p_card].discQCount != 0)
5051 FPT_BL_Card[p_card].discQCount--;
5052 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 -07005053 }
5054 else
5055 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005056 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005057 if(currSCCB->Sccb_tag)
5058 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005059 if(FPT_BL_Card[p_card].discQCount != 0)
5060 FPT_BL_Card[p_card].discQCount--;
5061 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005062 }else
5063 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005064 if(FPT_BL_Card[p_card].discQCount != 0)
5065 FPT_BL_Card[p_card].discQCount--;
5066 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005067 }
5068 }
5069 return;
5070
5071 }
5072
5073 if (status_byte == SSCHECK)
5074 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005075 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005076 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005077 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005078 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005080 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005081 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005082 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005083 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005084 }
5085 }
5086 }
5087
5088 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5089
5090 currSCCB->SccbStatus = SCCB_ERROR;
5091 currSCCB->TargetStatus = status_byte;
5092
5093 if (status_byte == SSCHECK) {
5094
James Bottomley 47b5d692005-04-24 02:38:05 -05005095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5096 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005097
5098
Linus Torvalds1da177e2005-04-16 15:20:36 -07005099 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5100
5101 if (currSCCB->RequestSenseLength == 0)
5102 currSCCB->RequestSenseLength = 14;
5103
James Bottomley 47b5d692005-04-24 02:38:05 -05005104 FPT_ssenss(&FPT_BL_Card[p_card]);
5105 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005106
James Bottomley 47b5d692005-04-24 02:38:05 -05005107 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5108 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005109 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005110 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5111 if(FPT_BL_Card[p_card].discQCount != 0)
5112 FPT_BL_Card[p_card].discQCount--;
5113 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 -07005114 }
5115 else
5116 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005117 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005118 if(currSCCB->Sccb_tag)
5119 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005120 if(FPT_BL_Card[p_card].discQCount != 0)
5121 FPT_BL_Card[p_card].discQCount--;
5122 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005123 }else
5124 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005125 if(FPT_BL_Card[p_card].discQCount != 0)
5126 FPT_BL_Card[p_card].discQCount--;
5127 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005128 }
5129 }
5130 return;
5131 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005132 }
5133 }
5134 }
5135
5136
James Bottomley 47b5d692005-04-24 02:38:05 -05005137 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5138 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5139 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005140 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005141 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005142
5143
James Bottomley 47b5d692005-04-24 02:38:05 -05005144 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005145}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005146
5147#define SHORT_WAIT 0x0000000F
5148#define LONG_WAIT 0x0000FFFFL
5149
Linus Torvalds1da177e2005-04-16 15:20:36 -07005150
5151/*---------------------------------------------------------------------
5152 *
5153 * Function: Data Transfer Processor
5154 *
5155 * Description: This routine performs two tasks.
5156 * (1) Start data transfer by calling HOST_DATA_XFER_START
5157 * function. Once data transfer is started, (2) Depends
5158 * on the type of data transfer mode Scatter/Gather mode
5159 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5160 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5161 * data transfer done. In Scatter/Gather mode, this routine
5162 * checks bus master command complete and dual rank busy
5163 * bit to keep chaining SC transfer command. Similarly,
5164 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5165 * (F_HOST_XFER_ACT bit) for data transfer done.
5166 *
5167 *---------------------------------------------------------------------*/
5168
James Bottomley 47b5d692005-04-24 02:38:05 -05005169static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005170{
5171 PSCCB currSCCB;
5172
5173 currSCCB = pCurrCard->currentSCCB;
5174
5175 if (currSCCB->Sccb_XferState & F_SG_XFER)
5176 {
5177 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5178
5179 {
5180 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
5181 currSCCB->Sccb_SGoffset = 0x00;
5182 }
5183 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5184
James Bottomley 47b5d692005-04-24 02:38:05 -05005185 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005186 }
5187
5188 else
5189 {
5190 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5191 {
5192 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5193
James Bottomley 47b5d692005-04-24 02:38:05 -05005194 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005195 }
5196 }
5197}
5198
5199
5200/*---------------------------------------------------------------------
5201 *
5202 * Function: BusMaster Scatter Gather Data Transfer Start
5203 *
5204 * Description:
5205 *
5206 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005207static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005208{
5209 ULONG count,addr,tmpSGCnt;
5210 UINT sg_index;
5211 UCHAR sg_count, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005212 ULONG reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005213
5214
5215 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5216
5217 count = ((ULONG) HOST_RD_CMD)<<24;
5218 }
5219
5220 else {
5221 count = ((ULONG) HOST_WRT_CMD)<<24;
5222 }
5223
5224 sg_count = 0;
5225 tmpSGCnt = 0;
5226 sg_index = pcurrSCCB->Sccb_sgseg;
5227 reg_offset = hp_aramBase;
5228
5229
5230 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5231
5232
5233 WR_HARPOON(p_port+hp_page_ctrl, i);
5234
5235 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
5236 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5237
Linus Torvalds1da177e2005-04-16 15:20:36 -07005238 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5239 (sg_index * 2));
5240
5241 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5242 (sg_index * 2));
5243
5244 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5245 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005246
5247
5248 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5249
5250 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5251 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5252
5253 tmpSGCnt = count & 0x00FFFFFFL;
5254 }
5255
5256 WR_HARP32(p_port,reg_offset,addr);
5257 reg_offset +=4;
5258
5259 WR_HARP32(p_port,reg_offset,count);
5260 reg_offset +=4;
5261
5262 count &= 0xFF000000L;
5263 sg_index++;
5264 sg_count++;
5265
5266 } /*End While */
5267
5268 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5269
5270 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5271
5272 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5273
5274 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5275
5276
5277 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5278 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5279 }
5280
5281 else {
5282
5283
5284 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5285 (tmpSGCnt & 0x000000001))
5286 {
5287
5288 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5289 tmpSGCnt--;
5290 }
5291
5292
5293 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5294
5295 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5296 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5297 }
5298
5299
5300 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
5301
5302}
5303
5304
5305/*---------------------------------------------------------------------
5306 *
5307 * Function: BusMaster Data Transfer Start
5308 *
5309 * Description:
5310 *
5311 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005312static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005313{
5314 ULONG addr,count;
5315
5316 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5317
5318 count = pcurrSCCB->Sccb_XferCnt;
5319
5320 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5321 }
5322
5323 else {
5324 addr = pcurrSCCB->SensePointer;
5325 count = pcurrSCCB->RequestSenseLength;
5326
5327 }
5328
Linus Torvalds1da177e2005-04-16 15:20:36 -07005329 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005330
5331
5332 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5333
5334 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5335 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5336
5337 WR_HARPOON(p_port+hp_xfer_cmd,
5338 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5339 }
5340
5341 else {
5342
5343 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5344 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5345
5346 WR_HARPOON(p_port+hp_xfer_cmd,
5347 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5348
5349 }
5350}
5351
5352
5353/*---------------------------------------------------------------------
5354 *
5355 * Function: BusMaster Timeout Handler
5356 *
5357 * Description: This function is called after a bus master command busy time
5358 * out is detected. This routines issue halt state machine
5359 * with a software time out for command busy. If command busy
5360 * is still asserted at the end of the time out, it issues
5361 * hard abort with another software time out. It hard abort
5362 * command busy is also time out, it'll just give up.
5363 *
5364 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005365static UCHAR FPT_busMstrTimeOut(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005366{
5367 ULONG timeout;
5368
5369 timeout = LONG_WAIT;
5370
5371 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5372
5373 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5374
5375
5376
5377 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5378 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5379
5380 timeout = LONG_WAIT;
5381 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5382 }
5383
5384 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5385
5386 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005387 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388 }
5389
5390 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005391 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005392 }
5393}
5394
5395
5396/*---------------------------------------------------------------------
5397 *
5398 * Function: Host Data Transfer Abort
5399 *
5400 * Description: Abort any in progress transfer.
5401 *
5402 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005403static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404{
5405
5406 ULONG timeout;
5407 ULONG remain_cnt;
5408 UINT sg_ptr;
5409
James Bottomley 47b5d692005-04-24 02:38:05 -05005410 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005411
5412 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5413
5414
5415 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5416
5417 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5418 timeout = LONG_WAIT;
5419
5420 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5421
5422 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5423
5424 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5425
James Bottomley 47b5d692005-04-24 02:38:05 -05005426 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005427
5428 if (pCurrSCCB->HostStatus == 0x00)
5429
5430 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5431
5432 }
5433
5434 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5435
5436 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5437
5438 if (pCurrSCCB->HostStatus == 0x00)
5439
5440 {
5441 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005442 }
5443 }
5444 }
5445 }
5446
5447 else if (pCurrSCCB->Sccb_XferCnt) {
5448
5449 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5450
5451
5452 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5453 ~SCATTER_EN));
5454
5455 WR_HARPOON(port+hp_sg_addr,0x00);
5456
5457 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5458
5459 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5460
5461 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5462 }
5463
5464 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5465
5466 while (remain_cnt < 0x01000000L) {
5467
5468 sg_ptr--;
5469
Linus Torvalds1da177e2005-04-16 15:20:36 -07005470 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5471 DataPointer) + (sg_ptr * 2)))) {
5472
5473 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5474 DataPointer) + (sg_ptr * 2)));
5475 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005476
5477 else {
5478
5479 break;
5480 }
5481 }
5482
5483
5484
5485 if (remain_cnt < 0x01000000L) {
5486
5487
5488 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5489
5490 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5491
5492
5493 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5494 && (remain_cnt == 0))
5495
5496 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5497 }
5498
5499 else {
5500
5501
5502 if (pCurrSCCB->HostStatus == 0x00) {
5503
5504 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5505 }
5506 }
5507 }
5508
5509
5510 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5511
5512
5513 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5514
James Bottomley 47b5d692005-04-24 02:38:05 -05005515 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005516 }
5517
5518 else {
5519
5520 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5521
5522 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5523
5524 if (pCurrSCCB->HostStatus == 0x00) {
5525
5526 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005527 }
5528 }
5529 }
5530
5531 }
5532 }
5533
5534 else {
5535
5536
5537 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5538
5539 timeout = SHORT_WAIT;
5540
5541 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5542 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5543 timeout--) {}
5544 }
5545
5546 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5547
5548 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5549 FLUSH_XFER_CNTR));
5550
5551 timeout = LONG_WAIT;
5552
5553 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5554 timeout--) {}
5555
5556 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5557 ~FLUSH_XFER_CNTR));
5558
5559
5560 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5561
5562 if (pCurrSCCB->HostStatus == 0x00) {
5563
5564 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5565 }
5566
James Bottomley 47b5d692005-04-24 02:38:05 -05005567 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005568 }
5569 }
5570
5571 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5572
5573 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5574
5575 if (pCurrSCCB->HostStatus == 0x00) {
5576
5577 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005578 }
5579 }
5580 }
5581 }
5582
5583 }
5584
5585 else {
5586
5587
5588 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5589
5590 timeout = LONG_WAIT;
5591
5592 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5593
5594 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5595
5596 if (pCurrSCCB->HostStatus == 0x00) {
5597
5598 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5599 }
5600
James Bottomley 47b5d692005-04-24 02:38:05 -05005601 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005602 }
5603 }
5604
5605
5606 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5607
5608 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5609
5610 if (pCurrSCCB->HostStatus == 0x00) {
5611
5612 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005613 }
5614 }
5615
5616 }
5617
5618 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5619
5620 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5621 ~SCATTER_EN));
5622
5623 WR_HARPOON(port+hp_sg_addr,0x00);
5624
5625 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5626
5627 pCurrSCCB->Sccb_SGoffset = 0x00;
5628
5629
5630 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5631 pCurrSCCB->DataLength) {
5632
5633 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5634
5635 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5636
5637 }
5638 }
5639
5640 else {
5641
5642 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5643
5644 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5645 }
5646 }
5647
5648 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5649}
5650
5651
5652
5653/*---------------------------------------------------------------------
5654 *
5655 * Function: Host Data Transfer Restart
5656 *
5657 * Description: Reset the available count due to a restore data
5658 * pointers message.
5659 *
5660 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005661static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662{
5663 ULONG data_count;
5664 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005665 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005666
5667 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5668
5669 currSCCB->Sccb_XferCnt = 0;
5670
5671 sg_index = 0xffff; /*Index by long words into sg list. */
5672 data_count = 0; /*Running count of SG xfer counts. */
5673
Linus Torvalds1da177e2005-04-16 15:20:36 -07005674 sg_ptr = (ULONG *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005675
5676 while (data_count < currSCCB->Sccb_ATC) {
5677
5678 sg_index++;
5679 data_count += *(sg_ptr+(sg_index * 2));
5680 }
5681
5682 if (data_count == currSCCB->Sccb_ATC) {
5683
5684 currSCCB->Sccb_SGoffset = 0;
5685 sg_index++;
5686 }
5687
5688 else {
5689 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5690 }
5691
5692 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5693 }
5694
5695 else {
5696 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5697 }
5698}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699
5700
5701
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702/*---------------------------------------------------------------------
5703 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005704 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005705 *
5706 * Description: Setup all data structures necessary for SCAM selection.
5707 *
5708 *---------------------------------------------------------------------*/
5709
James Bottomley 47b5d692005-04-24 02:38:05 -05005710static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005711{
5712
Linus Torvalds1da177e2005-04-16 15:20:36 -07005713 UCHAR loser,assigned_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005714 ULONG p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005715
5716 UCHAR i,k,ScamFlg ;
5717 PSCCBcard currCard;
5718 PNVRamInfo pCurrNvRam;
5719
James Bottomley 47b5d692005-04-24 02:38:05 -05005720 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005721 p_port = currCard->ioPort;
5722 pCurrNvRam = currCard->pNvRamInfo;
5723
5724
5725 if(pCurrNvRam){
5726 ScamFlg = pCurrNvRam->niScamConf;
5727 i = pCurrNvRam->niSysConf;
5728 }
5729 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05005730 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5731 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732 }
5733 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5734 return;
5735
James Bottomley 47b5d692005-04-24 02:38:05 -05005736 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005737
5738 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5739 too slow to return to SCAM selection */
5740
5741 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005742 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005743 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005744 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005745
James Bottomley 47b5d692005-04-24 02:38:05 -05005746 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005747
5748 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5749 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005750 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005751
James Bottomley 47b5d692005-04-24 02:38:05 -05005752 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753
5754 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005755 FPT_scxferc(p_port,SYNC_PTRN);
5756 FPT_scxferc(p_port,DOM_MSTR);
5757 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005758 } while ( loser == 0xFF );
5759
James Bottomley 47b5d692005-04-24 02:38:05 -05005760 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761
5762 if ((p_power_up) && (!loser))
5763 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005764 FPT_sresb(p_port,p_card);
5765 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005766
James Bottomley 47b5d692005-04-24 02:38:05 -05005767 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005768
James Bottomley 47b5d692005-04-24 02:38:05 -05005769 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005770
5771 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005772 FPT_scxferc(p_port, SYNC_PTRN);
5773 FPT_scxferc(p_port, DOM_MSTR);
5774 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005775 id_string[0]);
5776 } while ( loser == 0xFF );
5777
James Bottomley 47b5d692005-04-24 02:38:05 -05005778 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005779 }
5780 }
5781
5782 else
5783 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005784 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005785 }
5786
5787
5788 if (!loser)
5789 {
5790
James Bottomley 47b5d692005-04-24 02:38:05 -05005791 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005792
5793
5794 if (ScamFlg & SCAM_ENABLED)
5795 {
5796
5797 for (i=0; i < MAX_SCSI_TAR; i++)
5798 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005799 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5800 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005801 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005802 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005803 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005804 FPT_scamInfo[i].state = LEGACY;
5805 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5806 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005807 {
5808
James Bottomley 47b5d692005-04-24 02:38:05 -05005809 FPT_scamInfo[i].id_string[0] = 0xFF;
5810 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005811 if(pCurrNvRam == NULL)
5812 currCard->globalFlags |= F_UPDATE_EEPROM;
5813 }
5814 }
5815 }
5816 }
5817
James Bottomley 47b5d692005-04-24 02:38:05 -05005818 FPT_sresb(p_port,p_card);
5819 FPT_Wait1Second(p_port);
5820 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5821 FPT_scsel(p_port);
5822 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005823 }
5824
Linus Torvalds1da177e2005-04-16 15:20:36 -07005825 }
5826
5827 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5828 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005829 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5830 assigned_id = 0;
5831 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005832
5833 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005834 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835
James Bottomley 47b5d692005-04-24 02:38:05 -05005836 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005837 if (i == ASSIGN_ID)
5838 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005839 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005841 i = FPT_scxferc(p_port,0x00);
5842 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005843 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005844 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005845
James Bottomley 47b5d692005-04-24 02:38:05 -05005846 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005847 {
5848 currCard->ourId =
5849 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005850 FPT_inisci(p_card, p_port, p_our_id);
5851 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5852 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005854 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005855 }
5856 }
5857 }
5858 }
5859
5860 else if (i == SET_P_FLAG)
5861 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005862 if (!(FPT_scsendi(p_port,
5863 &FPT_scamInfo[p_our_id].id_string[0])))
5864 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005865 }
5866 }while (!assigned_id);
5867
James Bottomley 47b5d692005-04-24 02:38:05 -05005868 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005869 }
5870
Linus Torvalds1da177e2005-04-16 15:20:36 -07005871 if (ScamFlg & SCAM_ENABLED)
5872 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005873 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005874 if (currCard->globalFlags & F_UPDATE_EEPROM)
5875 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005876 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005877 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5878 }
5879 }
5880
5881
Linus Torvalds1da177e2005-04-16 15:20:36 -07005882/*
5883 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5884 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005885 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5886 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887 k++;
5888 }
5889
5890 if (k==2)
5891 currCard->globalFlags |= F_SINGLE_DEVICE;
5892 else
5893 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5894*/
5895}
5896
5897
5898/*---------------------------------------------------------------------
5899 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005900 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005901 *
5902 * Description: Gain control of the bus and wait SCAM select time (250ms)
5903 *
5904 *---------------------------------------------------------------------*/
5905
James Bottomley 47b5d692005-04-24 02:38:05 -05005906static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005907{
5908 if (p_sel_type == INIT_SELTD)
5909 {
5910
5911 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5912
5913
5914 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005915 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005916
5917 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005918 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005919
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5921
5922 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5923
5924 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5925 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005926 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005927 }
5928
5929
5930 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5931
5932 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5933
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5935 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005936 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005937 }
5938 }
5939
5940
5941 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5942 & ~ACTdeassert));
5943 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5944 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005945 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005946 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5947
5948 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5949
5950 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5951 & ~SCSI_BSY));
5952
James Bottomley 47b5d692005-04-24 02:38:05 -05005953 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954
James Bottomley 47b5d692005-04-24 02:38:05 -05005955 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005956}
5957
5958
5959/*---------------------------------------------------------------------
5960 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005961 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005962 *
5963 * Description: Release the SCSI bus and disable SCAM selection.
5964 *
5965 *---------------------------------------------------------------------*/
5966
James Bottomley 47b5d692005-04-24 02:38:05 -05005967static void FPT_scbusf(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005968{
5969 WR_HARPOON(p_port+hp_page_ctrl,
5970 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5971
5972
5973 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5974
5975 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5976 & ~SCSI_BUS_EN));
5977
5978 WR_HARPOON(p_port+hp_scsisig, 0x00);
5979
5980
5981 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5982 & ~SCAM_EN));
5983
5984 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5985 | ACTdeassert));
5986
Linus Torvalds1da177e2005-04-16 15:20:36 -07005987 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005988
5989 WR_HARPOON(p_port+hp_page_ctrl,
5990 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5991}
5992
5993
5994
5995/*---------------------------------------------------------------------
5996 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005997 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005998 *
5999 * Description: Assign an ID to all the SCAM devices.
6000 *
6001 *---------------------------------------------------------------------*/
6002
James Bottomley 47b5d692005-04-24 02:38:05 -05006003static void FPT_scasid(UCHAR p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006004{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006005 UCHAR temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006006
6007 UCHAR i,k,scam_id;
6008 UCHAR crcBytes[3];
6009 PNVRamInfo pCurrNvRam;
6010 ushort_ptr pCrcBytes;
6011
James Bottomley 47b5d692005-04-24 02:38:05 -05006012 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006013
James Bottomley 47b5d692005-04-24 02:38:05 -05006014 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006015
6016 while (!i)
6017 {
6018
6019 for (k=0; k < ID_STRING_LENGTH; k++)
6020 {
6021 temp_id_string[k] = (UCHAR) 0x00;
6022 }
6023
James Bottomley 47b5d692005-04-24 02:38:05 -05006024 FPT_scxferc(p_port,SYNC_PTRN);
6025 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006026
James Bottomley 47b5d692005-04-24 02:38:05 -05006027 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006028 {
6029 if(pCurrNvRam){
6030 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006031 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6032 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006033 temp_id_string[1] = crcBytes[2];
6034 temp_id_string[2] = crcBytes[0];
6035 temp_id_string[3] = crcBytes[1];
6036 for(k = 4; k < ID_STRING_LENGTH; k++)
6037 temp_id_string[k] = (UCHAR) 0x00;
6038 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006039 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006040
6041 if (i == CLR_PRIORITY)
6042 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006043 FPT_scxferc(p_port,MISC_CODE);
6044 FPT_scxferc(p_port,CLR_P_FLAG);
6045 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006046 }
6047
6048 else if (i != NO_ID_AVAIL)
6049 {
6050 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006051 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006052 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006053 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006054
6055 scam_id = (i & (UCHAR) 0x07);
6056
6057
6058 for (k=1; k < 0x08; k <<= 1)
6059 if (!( k & i ))
6060 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6061
James Bottomley 47b5d692005-04-24 02:38:05 -05006062 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006063
James Bottomley 47b5d692005-04-24 02:38:05 -05006064 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006065 }
6066 }
6067
6068 else
6069 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006070 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006071 }
6072
6073 } /*End while */
6074
James Bottomley 47b5d692005-04-24 02:38:05 -05006075 FPT_scxferc(p_port,SYNC_PTRN);
6076 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006077}
6078
6079
6080
6081
6082
6083/*---------------------------------------------------------------------
6084 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006085 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006086 *
6087 * Description: Select all the SCAM devices.
6088 *
6089 *---------------------------------------------------------------------*/
6090
James Bottomley 47b5d692005-04-24 02:38:05 -05006091static void FPT_scsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006092{
6093
6094 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006095 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006096
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6098
6099
6100 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6101 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
6102 (UCHAR)(BIT(7)+BIT(6))));
6103
6104
6105 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006106 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006107
6108 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6109 ~(UCHAR)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006110 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006111
6112 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6113}
6114
6115
6116
6117/*---------------------------------------------------------------------
6118 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006119 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006120 *
6121 * Description: Handshake the p_data (DB4-0) across the bus.
6122 *
6123 *---------------------------------------------------------------------*/
6124
James Bottomley 47b5d692005-04-24 02:38:05 -05006125static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006126{
6127 UCHAR curr_data, ret_data;
6128
6129 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6130
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132
6133 curr_data &= ~BIT(7);
6134
6135 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6136
James Bottomley 47b5d692005-04-24 02:38:05 -05006137 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6139
6140 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
6141
6142 curr_data |= BIT(6);
6143
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145
6146 curr_data &= ~BIT(5);
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(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151
6152 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6153 curr_data |= BIT(7);
6154
6155 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6156
6157 curr_data &= ~BIT(6);
6158
6159 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6160
James Bottomley 47b5d692005-04-24 02:38:05 -05006161 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006162
6163 return(ret_data);
6164}
6165
6166
6167/*---------------------------------------------------------------------
6168 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006169 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006170 *
6171 * Description: Transfer our Identification string to determine if we
6172 * will be the dominant master.
6173 *
6174 *---------------------------------------------------------------------*/
6175
James Bottomley 47b5d692005-04-24 02:38:05 -05006176static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177{
6178 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6179
James Bottomley 47b5d692005-04-24 02:38:05 -05006180 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006181
6182 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6183
6184 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6185
6186 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006187 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006188
6189 else if (p_id_string[byte_cnt] & bit_cnt)
6190
James Bottomley 47b5d692005-04-24 02:38:05 -05006191 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006192
6193 else {
6194
James Bottomley 47b5d692005-04-24 02:38:05 -05006195 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006196 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006197 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006198 }
6199
6200 if ((ret_data & 0x1C) == 0x10)
6201 return(0x00); /*End of isolation stage, we won! */
6202
6203 if (ret_data & 0x1C)
6204 return(0xFF);
6205
6206 if ((defer) && (!(ret_data & 0x1F)))
6207 return(0x01); /*End of isolation stage, we lost. */
6208
6209 } /*bit loop */
6210
6211 } /*byte loop */
6212
6213 if (defer)
6214 return(0x01); /*We lost */
6215 else
6216 return(0); /*We WON! Yeeessss! */
6217}
6218
6219
6220
6221/*---------------------------------------------------------------------
6222 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006223 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006224 *
6225 * Description: Transfer the Identification string.
6226 *
6227 *---------------------------------------------------------------------*/
6228
James Bottomley 47b5d692005-04-24 02:38:05 -05006229static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006230{
6231 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
6232
6233 the_data = 0;
6234
6235 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6236
6237 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6238
James Bottomley 47b5d692005-04-24 02:38:05 -05006239 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006240
6241 if (ret_data & 0xFC)
6242 return(0xFF);
6243
6244 else {
6245
6246 the_data <<= 1;
6247 if (ret_data & BIT(1)) {
6248 the_data |= 1;
6249 }
6250 }
6251
6252 if ((ret_data & 0x1F) == 0)
6253 {
6254/*
6255 if(bit_cnt != 0 || bit_cnt != 8)
6256 {
6257 byte_cnt = 0;
6258 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006259 FPT_scxferc(p_port, SYNC_PTRN);
6260 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006261 continue;
6262 }
6263*/
6264 if (byte_cnt)
6265 return(0x00);
6266 else
6267 return(0xFF);
6268 }
6269
6270 } /*bit loop */
6271
6272 p_id_string[byte_cnt] = the_data;
6273
6274 } /*byte loop */
6275
6276 return(0);
6277}
6278
6279
6280
6281/*---------------------------------------------------------------------
6282 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006283 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006284 *
6285 * Description: Sample the SCSI data bus making sure the signal has been
6286 * deasserted for the correct number of consecutive samples.
6287 *
6288 *---------------------------------------------------------------------*/
6289
James Bottomley 47b5d692005-04-24 02:38:05 -05006290static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006291{
6292 UCHAR i;
6293
6294 i = 0;
6295 while ( i < MAX_SCSI_TAR ) {
6296
6297 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6298
6299 i = 0;
6300
6301 else
6302
6303 i++;
6304
6305 }
6306}
6307
6308
6309
6310/*---------------------------------------------------------------------
6311 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006312 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006313 *
6314 * Description: Sample the SCSI Signal lines making sure the signal has been
6315 * deasserted for the correct number of consecutive samples.
6316 *
6317 *---------------------------------------------------------------------*/
6318
James Bottomley 47b5d692005-04-24 02:38:05 -05006319static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006320{
6321 UCHAR i;
6322
6323 i = 0;
6324 while ( i < MAX_SCSI_TAR ) {
6325
6326 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6327
6328 i = 0;
6329
6330 else
6331
6332 i++;
6333
6334 }
6335}
6336
6337
6338/*---------------------------------------------------------------------
6339 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006340 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006341 *
6342 * Description: Make sure we received a valid data byte.
6343 *
6344 *---------------------------------------------------------------------*/
6345
James Bottomley 47b5d692005-04-24 02:38:05 -05006346static UCHAR FPT_scvalq(UCHAR p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347{
6348 UCHAR count;
6349
6350 for (count=1; count < 0x08; count<<=1) {
6351 if (!(p_quintet & count))
6352 p_quintet -= 0x80;
6353 }
6354
6355 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006356 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006357
6358 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006359 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360}
6361
6362
6363/*---------------------------------------------------------------------
6364 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006365 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006366 *
6367 * Description: Select the specified device ID using a selection timeout
6368 * less than 4ms. If somebody responds then it is a legacy
6369 * drive and this ID must be marked as such.
6370 *
6371 *---------------------------------------------------------------------*/
6372
James Bottomley 47b5d692005-04-24 02:38:05 -05006373static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006375 ULONG i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376
6377 WR_HARPOON(p_port+hp_page_ctrl,
6378 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6379
6380 ARAM_ACCESS(p_port);
6381
6382 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6383 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6384
6385
6386 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6387 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6388 }
6389 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6390
6391 WRW_HARPOON((p_port+hp_intstat),
6392 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6393
6394 WR_HARPOON(p_port+hp_select_id, targ_id);
6395
6396 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6397 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6398 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6399
6400
6401 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6402 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6403
6404 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006405 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006406
6407 DISABLE_AUTO(p_port);
6408
6409 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6410 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6411
6412 SGRAM_ACCESS(p_port);
6413
6414 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6415
6416 WRW_HARPOON((p_port+hp_intstat),
6417 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6418
6419 WR_HARPOON(p_port+hp_page_ctrl,
6420 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6421
James Bottomley 47b5d692005-04-24 02:38:05 -05006422 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006423 }
6424
6425 else {
6426
6427 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6428 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6429 {
6430 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6431 ACCEPT_MSG(p_port);
6432 }
6433 }
6434
6435 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6436
6437 WR_HARPOON(p_port+hp_page_ctrl,
6438 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6439
James Bottomley 47b5d692005-04-24 02:38:05 -05006440 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006441 }
6442}
6443
Linus Torvalds1da177e2005-04-16 15:20:36 -07006444/*---------------------------------------------------------------------
6445 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006446 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006447 *
6448 * Description: Wait to be selected by another SCAM initiator.
6449 *
6450 *---------------------------------------------------------------------*/
6451
James Bottomley 47b5d692005-04-24 02:38:05 -05006452static void FPT_scwtsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006453{
6454 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6455}
6456
6457
6458/*---------------------------------------------------------------------
6459 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006460 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006461 *
6462 * Description: Setup the data Structure with the info from the EEPROM.
6463 *
6464 *---------------------------------------------------------------------*/
6465
James Bottomley 47b5d692005-04-24 02:38:05 -05006466static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006467{
6468 UCHAR i,k,max_id;
6469 USHORT ee_data;
6470 PNVRamInfo pCurrNvRam;
6471
James Bottomley 47b5d692005-04-24 02:38:05 -05006472 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006473
6474 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6475 max_id = 0x08;
6476
6477 else
6478 max_id = 0x10;
6479
6480 if(pCurrNvRam){
6481 for(i = 0; i < max_id; i++){
6482
6483 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006484 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485 for(k = 4; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006486 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487
James Bottomley 47b5d692005-04-24 02:38:05 -05006488 if(FPT_scamInfo[i].id_string[0] == 0x00)
6489 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006491 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006492
6493 }
6494 }else {
6495 for (i=0; i < max_id; i++)
6496 {
6497 for (k=0; k < ID_STRING_LENGTH; k+=2)
6498 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006499 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006501 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502 ee_data >>= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006503 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504 }
6505
James Bottomley 47b5d692005-04-24 02:38:05 -05006506 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6507 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508
James Bottomley 47b5d692005-04-24 02:38:05 -05006509 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510
6511 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006512 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006513
6514 }
6515 }
6516 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006517 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518
6519}
6520
6521/*---------------------------------------------------------------------
6522 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006523 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524 *
6525 * Description: Match the Device ID string with our values stored in
6526 * the EEPROM.
6527 *
6528 *---------------------------------------------------------------------*/
6529
James Bottomley 47b5d692005-04-24 02:38:05 -05006530static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006531{
6532
6533 UCHAR i,k,match;
6534
6535
6536 for (i=0; i < MAX_SCSI_TAR; i++) {
6537
James Bottomley 47b5d692005-04-24 02:38:05 -05006538 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006539
6540 for (k=0; k < ID_STRING_LENGTH; k++)
6541 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006542 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6543 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006544 }
6545
6546 if (match)
6547 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006548 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006549 return(i);
6550 }
6551
Linus Torvalds1da177e2005-04-16 15:20:36 -07006552 }
6553
6554
6555
6556 if (p_id_string[0] & BIT(5))
6557 i = 8;
6558 else
6559 i = MAX_SCSI_TAR;
6560
6561 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6562 match = p_id_string[1] & (UCHAR) 0x1F;
6563 else
6564 match = 7;
6565
6566 while (i > 0)
6567 {
6568 i--;
6569
James Bottomley 47b5d692005-04-24 02:38:05 -05006570 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006571 {
6572 for (k=0; k < ID_STRING_LENGTH; k++)
6573 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006574 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006575 }
6576
James Bottomley 47b5d692005-04-24 02:38:05 -05006577 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006578
James Bottomley 47b5d692005-04-24 02:38:05 -05006579 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6580 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006581 return(match);
6582
6583 }
6584
6585
6586 match--;
6587
6588 if (match == 0xFF)
6589 {
6590 if (p_id_string[0] & BIT(5))
6591 match = 7;
6592 else
6593 match = MAX_SCSI_TAR-1;
6594 }
6595 }
6596
6597
6598
6599 if (p_id_string[0] & BIT(7))
6600 {
6601 return(CLR_PRIORITY);
6602 }
6603
6604
6605 if (p_id_string[0] & BIT(5))
6606 i = 8;
6607 else
6608 i = MAX_SCSI_TAR;
6609
6610 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6611 match = p_id_string[1] & (UCHAR) 0x1F;
6612 else
6613 match = 7;
6614
6615 while (i > 0)
6616 {
6617
6618 i--;
6619
James Bottomley 47b5d692005-04-24 02:38:05 -05006620 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006621 {
6622 for (k=0; k < ID_STRING_LENGTH; k++)
6623 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006624 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006625 }
6626
James Bottomley 47b5d692005-04-24 02:38:05 -05006627 FPT_scamInfo[match].id_string[0] |= BIT(7);
6628 FPT_scamInfo[match].state = ID_ASSIGNED;
6629 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6630 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006631 return(match);
6632
6633 }
6634
6635
6636 match--;
6637
6638 if (match == 0xFF)
6639 {
6640 if (p_id_string[0] & BIT(5))
6641 match = 7;
6642 else
6643 match = MAX_SCSI_TAR-1;
6644 }
6645 }
6646
6647 return(NO_ID_AVAIL);
6648}
6649
6650
6651/*---------------------------------------------------------------------
6652 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006653 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006654 *
6655 * Description: Save off the device SCAM ID strings.
6656 *
6657 *---------------------------------------------------------------------*/
6658
James Bottomley 47b5d692005-04-24 02:38:05 -05006659static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006660{
6661 UCHAR i,k,max_id;
6662 USHORT ee_data,sum_data;
6663
6664
6665 sum_data = 0x0000;
6666
6667 for (i = 1; i < EE_SCAMBASE/2; i++)
6668 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006669 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006670 }
6671
6672
James Bottomley 47b5d692005-04-24 02:38:05 -05006673 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006674
6675 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6676 max_id = 0x08;
6677
6678 else
6679 max_id = 0x10;
6680
6681 for (i=0; i < max_id; i++)
6682 {
6683
6684 for (k=0; k < ID_STRING_LENGTH; k+=2)
6685 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006686 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006688 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006689 sum_data += ee_data;
James Bottomley 47b5d692005-04-24 02:38:05 -05006690 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006691 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6692 }
6693 }
6694
6695
James Bottomley 47b5d692005-04-24 02:38:05 -05006696 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6697 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006699
6700/*---------------------------------------------------------------------
6701 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006702 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006703 *
6704 * Description: Setup the Xbow for normal operation.
6705 *
6706 *---------------------------------------------------------------------*/
6707
James Bottomley 47b5d692005-04-24 02:38:05 -05006708static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006709{
6710UCHAR i;
6711
6712 i = RD_HARPOON(port+hp_page_ctrl);
6713 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
6714
6715 WR_HARPOON(port+hp_scsireset,0x00);
6716 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6717
6718 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6719 FIFO_CLR));
6720
6721 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6722
6723 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6724
6725 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6726 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6727
6728 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6729
James Bottomley 47b5d692005-04-24 02:38:05 -05006730 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006731 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6732
6733 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006734 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735
James Bottomley 47b5d692005-04-24 02:38:05 -05006736 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006737
6738 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6739
6740 /* Turn on SCSI_MODE8 for narrow cards to fix the
6741 strapping issue with the DUAL CHANNEL card */
6742 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6743 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6744
Linus Torvalds1da177e2005-04-16 15:20:36 -07006745 WR_HARPOON(port+hp_page_ctrl, i);
6746
6747}
6748
6749
6750/*---------------------------------------------------------------------
6751 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006752 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006753 *
6754 * Description: Initialize the BusMaster for normal operations.
6755 *
6756 *---------------------------------------------------------------------*/
6757
James Bottomley 47b5d692005-04-24 02:38:05 -05006758static void FPT_BusMasterInit(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006759{
6760
6761
6762 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6763 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6764
6765 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6766
6767
6768 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6769
6770 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6771
6772
Linus Torvalds1da177e2005-04-16 15:20:36 -07006773 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6774 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6775 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6776 ~SCATTER_EN));
6777}
6778
6779
6780/*---------------------------------------------------------------------
6781 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006782 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006783 *
6784 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6785 * necessary.
6786 *
6787 *---------------------------------------------------------------------*/
6788
James Bottomley 47b5d692005-04-24 02:38:05 -05006789static void FPT_DiagEEPROM(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006790{
6791 USHORT index,temp,max_wd_cnt;
6792
6793 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6794 max_wd_cnt = EEPROM_WD_CNT;
6795 else
6796 max_wd_cnt = EEPROM_WD_CNT * 2;
6797
James Bottomley 47b5d692005-04-24 02:38:05 -05006798 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799
6800 if (temp == 0x4641) {
6801
6802 for (index = 2; index < max_wd_cnt; index++) {
6803
James Bottomley 47b5d692005-04-24 02:38:05 -05006804 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006805
6806 }
6807
James Bottomley 47b5d692005-04-24 02:38:05 -05006808 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006809
6810 return; /*EEPROM is Okay so return now! */
6811 }
6812 }
6813
6814
James Bottomley 47b5d692005-04-24 02:38:05 -05006815 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816
6817 for (index = 0; index < max_wd_cnt; index++) {
6818
James Bottomley 47b5d692005-04-24 02:38:05 -05006819 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 }
6821
6822 temp = 0;
6823
James Bottomley 47b5d692005-04-24 02:38:05 -05006824 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006826 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006828 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006830 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006832 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006834 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006835 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006836 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006838 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839 temp += 0x0007;
6840
James Bottomley 47b5d692005-04-24 02:38:05 -05006841 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006845 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846 temp += 0x0000;
6847
James Bottomley 47b5d692005-04-24 02:38:05 -05006848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006849 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006852 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006854 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006856 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006858 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006860 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006862 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006863 temp += 0x4242;
6864
6865
James Bottomley 47b5d692005-04-24 02:38:05 -05006866 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006870 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006872 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006874 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006878 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006880 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881 temp += 0x2020;
6882
6883 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006884 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 temp += (0x0700+TYPE_CODE0);
6886 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006887 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006888 temp += 0x5542; /* BUSLOGIC */
6889 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006890 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 temp += 0x4C53;
6892 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006893 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006894 temp += 0x474F;
6895 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006896 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006897 temp += 0x4349;
6898 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006899 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900 temp += 0x5442; /* BT- 930 */
6901 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006902 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006903 temp += 0x202D;
6904 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006905 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006906 temp += 0x3339;
6907 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006908 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909 temp += 0x2030;
6910 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006911 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912 temp += 0x5453;
6913 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006914 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006915 temp += 0x5645;
6916 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006917 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006918 temp += 0x2045;
6919 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006920 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006921 temp += 0x202F;
6922 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006923 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924 temp += 0x4F4A;
6925 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006926 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006927 temp += 0x204E;
6928 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006929 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006930 temp += 0x3539;
6931
6932
6933
James Bottomley 47b5d692005-04-24 02:38:05 -05006934 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935
James Bottomley 47b5d692005-04-24 02:38:05 -05006936 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006937
6938}
6939
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940
6941/*---------------------------------------------------------------------
6942 *
6943 * Function: Queue Search Select
6944 *
6945 * Description: Try to find a new command to execute.
6946 *
6947 *---------------------------------------------------------------------*/
6948
James Bottomley 47b5d692005-04-24 02:38:05 -05006949static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006950{
6951 UCHAR scan_ptr, lun;
6952 PSCCBMgr_tar_info currTar_Info;
6953 PSCCB pOldSccb;
6954
6955 scan_ptr = pCurrCard->scanIndex;
6956 do
6957 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006958 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006959 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6960 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6961 {
6962 if (currTar_Info->TarSelQ_Cnt != 0)
6963 {
6964
6965 scan_ptr++;
6966 if (scan_ptr == MAX_SCSI_TAR)
6967 scan_ptr = 0;
6968
6969 for(lun=0; lun < MAX_LUN; lun++)
6970 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006971 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006972 {
6973
6974 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6975 pOldSccb = NULL;
6976
6977 while((pCurrCard->currentSCCB != NULL) &&
6978 (lun != pCurrCard->currentSCCB->Lun))
6979 {
6980 pOldSccb = pCurrCard->currentSCCB;
6981 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6982 Sccb_forwardlink;
6983 }
6984 if(pCurrCard->currentSCCB == NULL)
6985 continue;
6986 if(pOldSccb != NULL)
6987 {
6988 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6989 Sccb_forwardlink;
6990 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6991 Sccb_backlink;
6992 currTar_Info->TarSelQ_Cnt--;
6993 }
6994 else
6995 {
6996 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6997
6998 if (currTar_Info->TarSelQ_Head == NULL)
6999 {
7000 currTar_Info->TarSelQ_Tail = NULL;
7001 currTar_Info->TarSelQ_Cnt = 0;
7002 }
7003 else
7004 {
7005 currTar_Info->TarSelQ_Cnt--;
7006 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7007 }
7008 }
7009 pCurrCard->scanIndex = scan_ptr;
7010
7011 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7012
7013 break;
7014 }
7015 }
7016 }
7017
7018 else
7019 {
7020 scan_ptr++;
7021 if (scan_ptr == MAX_SCSI_TAR) {
7022 scan_ptr = 0;
7023 }
7024 }
7025
7026 }
7027 else
7028 {
7029 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007030 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007031 {
7032
7033 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7034
7035 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7036
7037 if (currTar_Info->TarSelQ_Head == NULL)
7038 {
7039 currTar_Info->TarSelQ_Tail = NULL;
7040 currTar_Info->TarSelQ_Cnt = 0;
7041 }
7042 else
7043 {
7044 currTar_Info->TarSelQ_Cnt--;
7045 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7046 }
7047
7048 scan_ptr++;
7049 if (scan_ptr == MAX_SCSI_TAR)
7050 scan_ptr = 0;
7051
7052 pCurrCard->scanIndex = scan_ptr;
7053
7054 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7055
7056 break;
7057 }
7058
7059 else
7060 {
7061 scan_ptr++;
7062 if (scan_ptr == MAX_SCSI_TAR)
7063 {
7064 scan_ptr = 0;
7065 }
7066 }
7067 }
7068 } while (scan_ptr != pCurrCard->scanIndex);
7069}
7070
7071
7072/*---------------------------------------------------------------------
7073 *
7074 * Function: Queue Select Fail
7075 *
7076 * Description: Add the current SCCB to the head of the Queue.
7077 *
7078 *---------------------------------------------------------------------*/
7079
James Bottomley 47b5d692005-04-24 02:38:05 -05007080static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007081{
7082 UCHAR thisTarg;
7083 PSCCBMgr_tar_info currTar_Info;
7084
7085 if (pCurrCard->currentSCCB != NULL)
7086 {
7087 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007088 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007089
7090 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7091
7092 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7093
7094 if (currTar_Info->TarSelQ_Cnt == 0)
7095 {
7096 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7097 }
7098
7099 else
7100 {
7101 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7102 }
7103
7104
7105 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7106
7107 pCurrCard->currentSCCB = NULL;
7108 currTar_Info->TarSelQ_Cnt++;
7109 }
7110}
7111/*---------------------------------------------------------------------
7112 *
7113 * Function: Queue Command Complete
7114 *
7115 * Description: Call the callback function with the current SCCB.
7116 *
7117 *---------------------------------------------------------------------*/
7118
James Bottomley 47b5d692005-04-24 02:38:05 -05007119static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7120 UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007121{
7122
Linus Torvalds1da177e2005-04-16 15:20:36 -07007123 UCHAR i, SCSIcmd;
7124 CALL_BK_FN callback;
7125 PSCCBMgr_tar_info currTar_Info;
7126
7127 SCSIcmd = p_sccb->Cdb[0];
7128
7129
7130 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7131
7132 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7133 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7134 (p_sccb->TargetStatus != SSCHECK))
7135
7136 if ((SCSIcmd == SCSI_READ) ||
7137 (SCSIcmd == SCSI_WRITE) ||
7138 (SCSIcmd == SCSI_READ_EXTENDED) ||
7139 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7140 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7141 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7142 (pCurrCard->globalFlags & F_NO_FILTER)
7143 )
7144 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7145 }
7146
7147
7148 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7149 {
7150 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7151 p_sccb->SccbStatus = SCCB_ERROR;
7152 else
7153 p_sccb->SccbStatus = SCCB_SUCCESS;
7154 }
7155
7156 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7157
7158 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7159 for (i=0; i < 6; i++) {
7160 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7161 }
7162 }
7163
7164 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7165 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7166
James Bottomley 47b5d692005-04-24 02:38:05 -05007167 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007168 }
7169
7170 pCurrCard->cmdCounter--;
7171 if (!pCurrCard->cmdCounter) {
7172
7173 if (pCurrCard->globalFlags & F_GREEN_PC) {
7174 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7175 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7176 }
7177
7178 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7179 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7180
7181 }
7182
7183 if(pCurrCard->discQCount != 0)
7184 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007185 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007186 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7187 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7188 {
7189 pCurrCard->discQCount--;
7190 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7191 }
7192 else
7193 {
7194 if(p_sccb->Sccb_tag)
7195 {
7196 pCurrCard->discQCount--;
7197 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7198 }else
7199 {
7200 pCurrCard->discQCount--;
7201 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7202 }
7203 }
7204
7205 }
7206
7207 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7208 callback(p_sccb);
7209 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7210 pCurrCard->currentSCCB = NULL;
7211}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007212
7213
7214/*---------------------------------------------------------------------
7215 *
7216 * Function: Queue Disconnect
7217 *
7218 * Description: Add SCCB to our disconnect array.
7219 *
7220 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05007221static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007222{
7223 PSCCBMgr_tar_info currTar_Info;
7224
James Bottomley 47b5d692005-04-24 02:38:05 -05007225 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007226
James Bottomley 47b5d692005-04-24 02:38:05 -05007227 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007228 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7229 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007230 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007231 }
7232 else
7233 {
7234 if (p_sccb->Sccb_tag)
7235 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007236 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7237 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7238 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007239 }else
7240 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007241 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007242 }
7243 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007244 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007245}
7246
7247
7248/*---------------------------------------------------------------------
7249 *
7250 * Function: Queue Flush SCCB
7251 *
7252 * Description: Flush all SCCB's back to the host driver for this target.
7253 *
7254 *---------------------------------------------------------------------*/
7255
James Bottomley 47b5d692005-04-24 02:38:05 -05007256static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007257{
7258 UCHAR qtag,thisTarg;
7259 PSCCB currSCCB;
7260 PSCCBMgr_tar_info currTar_Info;
7261
James Bottomley 47b5d692005-04-24 02:38:05 -05007262 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007263 if(currSCCB != NULL)
7264 {
7265 thisTarg = (UCHAR)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007266 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007267
7268 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7269
James Bottomley 47b5d692005-04-24 02:38:05 -05007270 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7271 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007272 {
7273
James Bottomley 47b5d692005-04-24 02:38:05 -05007274 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007275
James Bottomley 47b5d692005-04-24 02:38:05 -05007276 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007277
James Bottomley 47b5d692005-04-24 02:38:05 -05007278 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007279 currTar_Info->TarTagQ_Cnt--;
7280
7281 }
7282 }
7283 }
7284
7285}
7286
7287/*---------------------------------------------------------------------
7288 *
7289 * Function: Queue Flush Target SCCB
7290 *
7291 * Description: Flush all SCCB's back to the host driver for this target.
7292 *
7293 *---------------------------------------------------------------------*/
7294
James Bottomley 47b5d692005-04-24 02:38:05 -05007295static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7296 UCHAR error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297{
7298 UCHAR qtag;
7299 PSCCBMgr_tar_info currTar_Info;
7300
James Bottomley 47b5d692005-04-24 02:38:05 -05007301 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007302
7303 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7304
James Bottomley 47b5d692005-04-24 02:38:05 -05007305 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7306 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007307 {
7308
James Bottomley 47b5d692005-04-24 02:38:05 -05007309 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007310
James Bottomley 47b5d692005-04-24 02:38:05 -05007311 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007312
James Bottomley 47b5d692005-04-24 02:38:05 -05007313 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007314 currTar_Info->TarTagQ_Cnt--;
7315
7316 }
7317 }
7318
7319}
7320
7321
7322
7323
7324
James Bottomley 47b5d692005-04-24 02:38:05 -05007325static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007326{
7327 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007328 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007329
7330 p_SCCB->Sccb_forwardlink = NULL;
7331
7332 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7333
7334 if (currTar_Info->TarSelQ_Cnt == 0) {
7335
7336 currTar_Info->TarSelQ_Head = p_SCCB;
7337 }
7338
7339 else {
7340
7341 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7342 }
7343
7344
7345 currTar_Info->TarSelQ_Tail = p_SCCB;
7346 currTar_Info->TarSelQ_Cnt++;
7347}
7348
7349
7350/*---------------------------------------------------------------------
7351 *
7352 * Function: Queue Find SCCB
7353 *
7354 * Description: Search the target select Queue for this SCCB, and
7355 * remove it if found.
7356 *
7357 *---------------------------------------------------------------------*/
7358
James Bottomley 47b5d692005-04-24 02:38:05 -05007359static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007360{
7361 PSCCB q_ptr;
7362 PSCCBMgr_tar_info currTar_Info;
7363
James Bottomley 47b5d692005-04-24 02:38:05 -05007364 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007365
7366 q_ptr = currTar_Info->TarSelQ_Head;
7367
7368 while(q_ptr != NULL) {
7369
7370 if (q_ptr == p_SCCB) {
7371
7372
7373 if (currTar_Info->TarSelQ_Head == q_ptr) {
7374
7375 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7376 }
7377
7378 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7379
7380 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7381 }
7382
7383 if (q_ptr->Sccb_forwardlink != NULL) {
7384 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7385 }
7386
7387 if (q_ptr->Sccb_backlink != NULL) {
7388 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7389 }
7390
7391 currTar_Info->TarSelQ_Cnt--;
7392
James Bottomley 47b5d692005-04-24 02:38:05 -05007393 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007394 }
7395
7396 else {
7397 q_ptr = q_ptr->Sccb_forwardlink;
7398 }
7399 }
7400
7401
James Bottomley 47b5d692005-04-24 02:38:05 -05007402 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007403
7404}
7405
7406
7407/*---------------------------------------------------------------------
7408 *
7409 * Function: Utility Update Residual Count
7410 *
7411 * Description: Update the XferCnt to the remaining byte count.
7412 * If we transferred all the data then just write zero.
7413 * If Non-SG transfer then report Total Cnt - Actual Transfer
7414 * Cnt. For SG transfers add the count fields of all
7415 * remaining SG elements, as well as any partial remaining
7416 * element.
7417 *
7418 *---------------------------------------------------------------------*/
7419
James Bottomley 47b5d692005-04-24 02:38:05 -05007420static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007421{
7422 ULONG partial_cnt;
7423 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007424 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007425
7426 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7427
7428 p_SCCB->DataLength = 0x0000;
7429 }
7430
7431 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7432
7433 partial_cnt = 0x0000;
7434
7435 sg_index = p_SCCB->Sccb_sgseg;
7436
Linus Torvalds1da177e2005-04-16 15:20:36 -07007437 sg_ptr = (ULONG *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007438
7439 if (p_SCCB->Sccb_SGoffset) {
7440
7441 partial_cnt = p_SCCB->Sccb_SGoffset;
7442 sg_index++;
7443 }
7444
7445 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7446 p_SCCB->DataLength ) {
7447
7448 partial_cnt += *(sg_ptr+(sg_index * 2));
7449 sg_index++;
7450 }
7451
7452 p_SCCB->DataLength = partial_cnt;
7453 }
7454
7455 else {
7456
7457 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7458 }
7459}
7460
7461
7462/*---------------------------------------------------------------------
7463 *
7464 * Function: Wait 1 Second
7465 *
7466 * Description: Wait for 1 second.
7467 *
7468 *---------------------------------------------------------------------*/
7469
James Bottomley 47b5d692005-04-24 02:38:05 -05007470static void FPT_Wait1Second(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007471{
7472 UCHAR i;
7473
7474 for(i=0; i < 4; i++) {
7475
James Bottomley 47b5d692005-04-24 02:38:05 -05007476 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007477
7478 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7479 break;
7480
7481 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7482 break;
7483 }
7484}
7485
7486
7487/*---------------------------------------------------------------------
7488 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007489 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007490 *
7491 * Description: Wait the desired delay.
7492 *
7493 *---------------------------------------------------------------------*/
7494
James Bottomley 47b5d692005-04-24 02:38:05 -05007495static void FPT_Wait(ULONG p_port, UCHAR p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007496{
7497 UCHAR old_timer;
7498 UCHAR green_flag;
7499
7500 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7501
7502 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7503 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7504
7505 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7506 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007507 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007508
7509
7510 WR_HARPOON(p_port+hp_portctrl_0,
7511 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7512
7513 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7514
7515 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7516 break;
7517
7518 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7519 break;
7520 }
7521
7522 WR_HARPOON(p_port+hp_portctrl_0,
7523 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7524
7525 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007526 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007527
7528 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7529
7530 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7531}
7532
7533
7534/*---------------------------------------------------------------------
7535 *
7536 * Function: Enable/Disable Write to EEPROM
7537 *
7538 * Description: The EEPROM must first be enabled for writes
7539 * A total of 9 clocks are needed.
7540 *
7541 *---------------------------------------------------------------------*/
7542
James Bottomley 47b5d692005-04-24 02:38:05 -05007543static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007544{
7545 UCHAR ee_value;
7546
7547 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7548
7549 if (p_mode)
7550
James Bottomley 47b5d692005-04-24 02:38:05 -05007551 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007552
7553 else
7554
7555
James Bottomley 47b5d692005-04-24 02:38:05 -05007556 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007557
7558 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7559 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7560}
7561
7562
7563/*---------------------------------------------------------------------
7564 *
7565 * Function: Write EEPROM
7566 *
7567 * Description: Write a word to the EEPROM at the specified
7568 * address.
7569 *
7570 *---------------------------------------------------------------------*/
7571
James Bottomley 47b5d692005-04-24 02:38:05 -05007572static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007573{
7574
7575 UCHAR ee_value;
7576 USHORT i;
7577
7578 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7579 (SEE_MS | SEE_CS));
7580
7581
7582
James Bottomley 47b5d692005-04-24 02:38:05 -05007583 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007584
7585
7586 ee_value |= (SEE_MS + SEE_CS);
7587
7588 for(i = 0x8000; i != 0; i>>=1) {
7589
7590 if (i & ee_data)
7591 ee_value |= SEE_DO;
7592 else
7593 ee_value &= ~SEE_DO;
7594
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 ee_value |= SEE_CLK; /* Clock data! */
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 ee_value &= ~SEE_CLK;
7601 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7602 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7603 }
7604 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7606
James Bottomley 47b5d692005-04-24 02:38:05 -05007607 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007608
7609 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7610 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7611 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7612}
7613
7614/*---------------------------------------------------------------------
7615 *
7616 * Function: Read EEPROM
7617 *
7618 * Description: Read a word from the EEPROM at the desired
7619 * address.
7620 *
7621 *---------------------------------------------------------------------*/
7622
James Bottomley 47b5d692005-04-24 02:38:05 -05007623static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007624{
7625 USHORT i, ee_data1, ee_data2;
7626
7627 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007628 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007629 do
7630 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007631 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007632
7633 if(ee_data1 == ee_data2)
7634 return(ee_data1);
7635
7636 ee_data1 = ee_data2;
7637 i++;
7638
7639 }while(i < 4);
7640
7641 return(ee_data1);
7642}
7643
7644/*---------------------------------------------------------------------
7645 *
7646 * Function: Read EEPROM Original
7647 *
7648 * Description: Read a word from the EEPROM at the desired
7649 * address.
7650 *
7651 *---------------------------------------------------------------------*/
7652
James Bottomley 47b5d692005-04-24 02:38:05 -05007653static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007654{
7655
7656 UCHAR ee_value;
7657 USHORT i, ee_data;
7658
7659 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7660 (SEE_MS | SEE_CS));
7661
7662
James Bottomley 47b5d692005-04-24 02:38:05 -05007663 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007664
7665
7666 ee_value |= (SEE_MS + SEE_CS);
7667 ee_data = 0;
7668
7669 for(i = 1; i <= 16; i++) {
7670
7671 ee_value |= SEE_CLK; /* Clock data! */
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674 ee_value &= ~SEE_CLK;
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7676 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7677
7678 ee_data <<= 1;
7679
7680 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7681 ee_data |= 1;
7682 }
7683
7684 ee_value &= ~(SEE_MS + SEE_CS);
7685 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7686 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7687
7688 return(ee_data);
7689}
7690
7691
7692/*---------------------------------------------------------------------
7693 *
7694 * Function: Send EE command and Address to the EEPROM
7695 *
7696 * Description: Transfers the correct command and sends the address
7697 * to the eeprom.
7698 *
7699 *---------------------------------------------------------------------*/
7700
James Bottomley 47b5d692005-04-24 02:38:05 -05007701static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007702{
7703 UCHAR ee_value;
7704 UCHAR narrow_flg;
7705
7706 USHORT i;
7707
7708
7709 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7710
7711
7712 ee_value = SEE_MS;
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714
7715 ee_value |= SEE_CS; /* Set CS to EEPROM */
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717
7718
7719 for(i = 0x04; i != 0; i>>=1) {
7720
7721 if (i & ee_cmd)
7722 ee_value |= SEE_DO;
7723 else
7724 ee_value &= ~SEE_DO;
7725
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 ee_value |= SEE_CLK; /* Clock data! */
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 ee_value &= ~SEE_CLK;
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7733 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7734 }
7735
7736
7737 if (narrow_flg)
7738 i = 0x0080;
7739
7740 else
7741 i = 0x0200;
7742
7743
7744 while (i != 0) {
7745
7746 if (i & ee_addr)
7747 ee_value |= SEE_DO;
7748 else
7749 ee_value &= ~SEE_DO;
7750
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 ee_value |= SEE_CLK; /* Clock data! */
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756 ee_value &= ~SEE_CLK;
7757 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7758 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7759
7760 i >>= 1;
7761 }
7762}
7763
James Bottomley 47b5d692005-04-24 02:38:05 -05007764static USHORT FPT_CalcCrc16(UCHAR buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007765{
7766 USHORT crc=0;
7767 int i,j;
7768 USHORT ch;
7769 for (i=0; i < ID_STRING_LENGTH; i++)
7770 {
7771 ch = (USHORT) buffer[i];
7772 for(j=0; j < 8; j++)
7773 {
7774 if ((crc ^ ch) & 1)
7775 crc = (crc >> 1) ^ CRCMASK;
7776 else
7777 crc >>= 1;
7778 ch >>= 1;
7779 }
7780 }
7781 return(crc);
7782}
7783
James Bottomley 47b5d692005-04-24 02:38:05 -05007784static UCHAR FPT_CalcLrc(UCHAR buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007785{
7786 int i;
7787 UCHAR lrc;
7788 lrc = 0;
7789 for(i = 0; i < ID_STRING_LENGTH; i++)
7790 lrc ^= buffer[i];
7791 return(lrc);
7792}
7793
7794
7795
7796/*
7797 The following inline definitions avoid type conflicts.
7798*/
7799
7800static inline unsigned char
7801FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7802{
7803 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7804}
7805
7806
7807static inline FlashPoint_CardHandle_T
7808FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7809{
7810 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7811}
7812
7813static inline void
7814FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7815{
7816 FlashPoint_ReleaseHostAdapter(CardHandle);
7817}
7818
7819
7820static inline void
7821FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7822{
7823 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7824}
7825
7826
7827static inline void
7828FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7829{
7830 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7831}
7832
7833
7834static inline boolean
7835FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7836{
7837 return FlashPoint_InterruptPending(CardHandle);
7838}
7839
7840
7841static inline int
7842FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7843{
7844 return FlashPoint_HandleInterrupt(CardHandle);
7845}
7846
7847
7848#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7849#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7850#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7851#define FlashPoint_StartCCB FlashPoint__StartCCB
7852#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7853#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7854#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7855
7856
Linus Torvalds1da177e2005-04-16 15:20:36 -07007857#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7858
7859
7860/*
7861 Define prototypes for the FlashPoint SCCB Manager Functions.
7862*/
7863
7864extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7865extern FlashPoint_CardHandle_T
7866 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7867extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7868extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7869extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7870extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7871extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007872
7873
7874#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */