blob: 5beed4f6d985a7b2bd2c9f007b2e49158989ec31 [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
29#define OS_InPortByte(port) inb(port)
30#define OS_InPortWord(port) inw(port)
31#define OS_InPortLong(port) inl(port)
32#define OS_OutPortByte(port, value) outb(value, port)
33#define OS_OutPortWord(port, value) outw(value, port)
34#define OS_OutPortLong(port, value) outl(value, port)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36
37/*
38 Define name replacements for compatibility with the Linux BusLogic Driver.
39*/
40
41#define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter
42#define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter
43#define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter
44#define SccbMgr_start_sccb FlashPoint_StartCCB
45#define SccbMgr_abort_sccb FlashPoint_AbortCCB
46#define SccbMgr_my_int FlashPoint_InterruptPending
47#define SccbMgr_isr FlashPoint_HandleInterrupt
48
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#define MAX_CDBLEN 12
51
52#define SCAM_LEV_2 1
53
54#define CRCMASK 0xA001
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#define BL_VENDOR_ID 0x104B
57#define FP_DEVICE_ID 0x8130
58#define MM_DEVICE_ID 0x1040
59
60
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#define FAILURE 0xFFFFFFFFL
62
63
64typedef unsigned char UCHAR;
65typedef unsigned short USHORT;
66typedef unsigned int UINT;
67typedef unsigned long ULONG;
68typedef unsigned char * PUCHAR;
69typedef unsigned short* PUSHORT;
70typedef unsigned long * PULONG;
71typedef void * PVOID;
72
73
Linus Torvalds1da177e2005-04-16 15:20:36 -070074typedef unsigned char * uchar_ptr;
75typedef unsigned short * ushort_ptr;
76typedef unsigned long * ulong_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079#define s08bits char
80#define s16bits short
81#define s32bits long
82
83#define u08bits unsigned s08bits
84#define u16bits unsigned s16bits
85#define u32bits unsigned s32bits
86
Linus Torvalds1da177e2005-04-16 15:20:36 -070087typedef u08bits * pu08bits;
88typedef u16bits * pu16bits;
89typedef u32bits * pu32bits;
90
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
92#define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
93#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
94
95
96
Linus Torvalds1da177e2005-04-16 15:20:36 -070097
James Bottomley 47b5d692005-04-24 02:38:05 -050098typedef struct _SCCB *PSCCB;
99typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
101
102typedef struct SCCBMgr_info {
103 ULONG si_baseaddr;
104 UCHAR si_present;
105 UCHAR si_intvect;
106 UCHAR si_id;
107 UCHAR si_lun;
108 USHORT si_fw_revision;
109 USHORT si_per_targ_init_sync;
110 USHORT si_per_targ_fast_nego;
111 USHORT si_per_targ_ultra_nego;
112 USHORT si_per_targ_no_disc;
113 USHORT si_per_targ_wide_nego;
114 USHORT si_flags;
115 UCHAR si_card_family;
116 UCHAR si_bustype;
117 UCHAR si_card_model[3];
118 UCHAR si_relative_cardnum;
119 UCHAR si_reserved[4];
120 ULONG si_OS_reserved;
121 UCHAR si_XlatInfo[4];
122 ULONG si_reserved2[5];
123 ULONG si_secondary_range;
124} SCCBMGR_INFO;
125
James Bottomley 47b5d692005-04-24 02:38:05 -0500126typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
128
James Bottomley 47b5d692005-04-24 02:38:05 -0500129#define SCSI_PARITY_ENA 0x0001
130#define LOW_BYTE_TERM 0x0010
131#define HIGH_BYTE_TERM 0x0020
132#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134#define SUPPORT_16TAR_32LUN 0x0002
135#define SOFT_RESET 0x0004
136#define EXTENDED_TRANSLATION 0x0008
137#define POST_ALL_UNDERRRUNS 0x0040
138#define FLAG_SCAM_ENABLED 0x0080
139#define FLAG_SCAM_LEVEL2 0x0100
140
141
142
143
144#define HARPOON_FAMILY 0x02
145
146
147#define ISA_BUS_CARD 0x01
148#define EISA_BUS_CARD 0x02
149#define PCI_BUS_CARD 0x03
150#define VESA_BUS_CARD 0x04
151
152/* SCCB struc used for both SCCB and UCB manager compiles!
153 * The UCB Manager treats the SCCB as it's 'native hardware structure'
154 */
155
156
157#pragma pack(1)
158typedef struct _SCCB {
159 UCHAR OperationCode;
160 UCHAR ControlByte;
161 UCHAR CdbLength;
162 UCHAR RequestSenseLength;
163 ULONG DataLength;
164 ULONG DataPointer;
165 UCHAR CcbRes[2];
166 UCHAR HostStatus;
167 UCHAR TargetStatus;
168 UCHAR TargID;
169 UCHAR Lun;
170 UCHAR Cdb[12];
171 UCHAR CcbRes1;
172 UCHAR Reserved1;
173 ULONG Reserved2;
174 ULONG SensePointer;
175
176
177 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
178 ULONG SccbIOPort; /* Identifies board base port */
179 UCHAR SccbStatus;
180 UCHAR SCCBRes2;
181 USHORT SccbOSFlags;
182
183
184 ULONG Sccb_XferCnt; /* actual transfer count */
185 ULONG Sccb_ATC;
186 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
187 ULONG Sccb_res1;
188 USHORT Sccb_MGRFlags;
189 USHORT Sccb_sgseg;
190 UCHAR Sccb_scsimsg; /* identify msg for selection */
191 UCHAR Sccb_tag;
192 UCHAR Sccb_scsistat;
193 UCHAR Sccb_idmsg; /* image of last msg in */
194 PSCCB Sccb_forwardlink;
195 PSCCB Sccb_backlink;
196 ULONG Sccb_savedATC;
197 UCHAR Save_Cdb[6];
198 UCHAR Save_CdbLen;
199 UCHAR Sccb_XferState;
200 ULONG Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 } SCCB;
202
203#define SCCB_SIZE sizeof(SCCB)
204
205#pragma pack()
206
207
208
209#define SCSI_INITIATOR_COMMAND 0x00
210#define TARGET_MODE_COMMAND 0x01
211#define SCATTER_GATHER_COMMAND 0x02
212#define RESIDUAL_COMMAND 0x03
213#define RESIDUAL_SG_COMMAND 0x04
214#define RESET_COMMAND 0x81
215
216
217#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
218#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
219#define TAG_Q_MASK 0xE0
220#define SCCB_DATA_XFER_OUT 0x10 /* Write */
221#define SCCB_DATA_XFER_IN 0x08 /* Read */
222
223
224#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */
225#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
226
227
228#define BUS_FREE_ST 0
229#define SELECT_ST 1
230#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
231#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
232#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
233#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
234#define COMMAND_ST 6
235#define DATA_OUT_ST 7
236#define DATA_IN_ST 8
237#define DISCONNECT_ST 9
238#define STATUS_ST 10
239#define ABORT_ST 11
240#define MESSAGE_ST 12
241
242
243#define F_HOST_XFER_DIR 0x01
244#define F_ALL_XFERRED 0x02
245#define F_SG_XFER 0x04
246#define F_AUTO_SENSE 0x08
247#define F_ODD_BALL_CNT 0x10
248#define F_NO_DATA_YET 0x80
249
250
251#define F_STATUSLOADED 0x01
252#define F_MSGLOADED 0x02
253#define F_DEV_SELECTED 0x04
254
255
256#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
257#define SCCB_DATA_UNDER_RUN 0x0C
258#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
259#define SCCB_DATA_OVER_RUN 0x12
260#define SCCB_UNEXPECTED_BUS_FREE 0x13 /* Target dropped SCSI BSY */
261#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
262
263#define SCCB_INVALID_OP_CODE 0x16 /* SCCB invalid operation code */
264#define SCCB_INVALID_SCCB 0x1A /* Invalid SCCB - bad parameter */
265#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
266#define SCCB_BM_ERR 0x30 /* BusMaster error. */
267#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
268
269
270
James Bottomley 47b5d692005-04-24 02:38:05 -0500271#define SCCB_INVALID_DIRECTION 0x18 /* Invalid target direction */
272#define SCCB_DUPLICATE_SCCB 0x19 /* Duplicate SCCB */
273#define SCCB_SCSI_RST 0x35 /* SCSI RESET detected. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
275
276#define SCCB_IN_PROCESS 0x00
277#define SCCB_SUCCESS 0x01
278#define SCCB_ABORT 0x02
279#define SCCB_NOT_FOUND 0x03
280#define SCCB_ERROR 0x04
281#define SCCB_INVALID 0x05
282
283#define SCCB_SIZE sizeof(SCCB)
284
285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286#define ORION_FW_REV 3110
287
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288#define HARP_REVD 1
289
290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
293#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
294
295#define WIDE_SCSI 1
296
James Bottomley 47b5d692005-04-24 02:38:05 -0500297#define MAX_SCSI_TAR 16
298#define MAX_LUN 32
299#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
301#if defined(HARP_REVA)
302#define SG_BUF_CNT 15 /*Number of prefetched elements. */
303#else
304#define SG_BUF_CNT 16 /*Number of prefetched elements. */
305#endif
306
307#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
308#define SG_LOCAL_MASK 0x00000000L
309#define SG_ELEMENT_MASK 0xFFFFFFFFL
310
311
James Bottomley 47b5d692005-04-24 02:38:05 -0500312#define RD_HARPOON(ioport) OS_InPortByte((u32bits)ioport)
313#define RDW_HARPOON(ioport) OS_InPortWord((u32bits)ioport)
314#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
315#define WR_HARPOON(ioport,val) OS_OutPortByte((u32bits)ioport,(u08bits) val)
316#define WRW_HARPOON(ioport,val) OS_OutPortWord((u32bits)ioport,(u16bits)val)
317#define WR_HARP32(ioport,offset,data) OS_OutPortLong((u32bits)(ioport + offset), data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
319
320#define TAR_SYNC_MASK (BIT(7)+BIT(6))
321#define SYNC_UNKNOWN 0x00
322#define SYNC_TRYING BIT(6)
323#define SYNC_SUPPORTED (BIT(7)+BIT(6))
324
325#define TAR_WIDE_MASK (BIT(5)+BIT(4))
326#define WIDE_DISABLED 0x00
327#define WIDE_ENABLED BIT(4)
328#define WIDE_NEGOCIATED BIT(5)
329
330#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
331#define TAG_Q_UNKNOWN 0x00
332#define TAG_Q_TRYING BIT(2)
333#define TAG_Q_REJECT BIT(3)
334#define TAG_Q_SUPPORTED (BIT(3)+BIT(2))
335
336#define TAR_ALLOW_DISC BIT(0)
337
338
339#define EE_SYNC_MASK (BIT(0)+BIT(1))
340#define EE_SYNC_ASYNC 0x00
341#define EE_SYNC_5MB BIT(0)
342#define EE_SYNC_10MB BIT(1)
343#define EE_SYNC_20MB (BIT(0)+BIT(1))
344
345#define EE_ALLOW_DISC BIT(6)
346#define EE_WIDE_SCSI BIT(7)
347
348
James Bottomley 47b5d692005-04-24 02:38:05 -0500349typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350
351
352typedef struct SCCBMgr_tar_info {
353
354 PSCCB TarSelQ_Head;
355 PSCCB TarSelQ_Tail;
356 UCHAR TarLUN_CA; /*Contingent Allgiance */
357 UCHAR TarTagQ_Cnt;
358 UCHAR TarSelQ_Cnt;
359 UCHAR TarStatus;
360 UCHAR TarEEValue;
361 UCHAR TarSyncCtrl;
362 UCHAR TarReserved[2]; /* for alignment */
363 UCHAR LunDiscQ_Idx[MAX_LUN];
364 UCHAR TarLUNBusy[MAX_LUN];
365} SCCBMGR_TAR_INFO;
366
367typedef struct NVRAMInfo {
368 UCHAR niModel; /* Model No. of card */
369 UCHAR niCardNo; /* Card no. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 ULONG niBaseAddr; /* Port Address of card */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
372 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
373 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
374 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
375 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
376 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
377}NVRAMINFO;
378
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
381#define MODEL_LT 1
382#define MODEL_DL 2
383#define MODEL_LW 3
384#define MODEL_DW 4
385
386
387typedef struct SCCBcard {
388 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 ULONG ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
393 USHORT cmdCounter;
394 UCHAR discQCount;
395 UCHAR tagQ_Lst;
396 UCHAR cardIndex;
397 UCHAR scanIndex;
398 UCHAR globalFlags;
399 UCHAR ourId;
400 PNVRamInfo pNvRamInfo;
401 PSCCB discQ_Tbl[QUEUE_DEPTH];
402
403}SCCBCARD;
404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
407
408#define F_TAG_STARTED 0x01
409#define F_CONLUN_IO 0x02
410#define F_DO_RENEGO 0x04
411#define F_NO_FILTER 0x08
412#define F_GREEN_PC 0x10
413#define F_HOST_XFER_ACT 0x20
414#define F_NEW_SCCB_CMD 0x40
415#define F_UPDATE_EEPROM 0x80
416
417
418#define ID_STRING_LENGTH 32
419#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
420
421#define TYPE_CODE1 00 /*No ID yet */
422
423#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
424
425#define ASSIGN_ID 0x00
426#define SET_P_FLAG 0x01
427#define CFG_CMPLT 0x03
428#define DOM_MSTR 0x0F
429#define SYNC_PTRN 0x1F
430
431#define ID_0_7 0x18
432#define ID_8_F 0x11
433#define ID_10_17 0x12
434#define ID_18_1F 0x0B
435#define MISC_CODE 0x14
436#define CLR_P_FLAG 0x18
437#define LOCATE_ON 0x12
438#define LOCATE_OFF 0x0B
439
440#define LVL_1_MST 0x00
441#define LVL_2_MST 0x40
442#define DOM_LVL_2 0xC0
443
444
445#define INIT_SELTD 0x01
446#define LEVEL2_TAR 0x02
447
448
449enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
450 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
451 CLR_PRIORITY,NO_ID_AVAIL };
452
453typedef struct SCCBscam_info {
454
455 UCHAR id_string[ID_STRING_LENGTH];
456 enum scam_id_st state;
457
458} SCCBSCAM_INFO, *PSCCBSCAM_INFO;
459
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460
461#define SCSI_TEST_UNIT_READY 0x00
462#define SCSI_REZERO_UNIT 0x01
463#define SCSI_REQUEST_SENSE 0x03
464#define SCSI_FORMAT_UNIT 0x04
465#define SCSI_REASSIGN 0x07
466#define SCSI_READ 0x08
467#define SCSI_WRITE 0x0A
468#define SCSI_SEEK 0x0B
469#define SCSI_INQUIRY 0x12
470#define SCSI_MODE_SELECT 0x15
471#define SCSI_RESERVE_UNIT 0x16
472#define SCSI_RELEASE_UNIT 0x17
473#define SCSI_MODE_SENSE 0x1A
474#define SCSI_START_STOP_UNIT 0x1B
475#define SCSI_SEND_DIAGNOSTIC 0x1D
476#define SCSI_READ_CAPACITY 0x25
477#define SCSI_READ_EXTENDED 0x28
478#define SCSI_WRITE_EXTENDED 0x2A
479#define SCSI_SEEK_EXTENDED 0x2B
480#define SCSI_WRITE_AND_VERIFY 0x2E
481#define SCSI_VERIFY 0x2F
482#define SCSI_READ_DEFECT_DATA 0x37
483#define SCSI_WRITE_BUFFER 0x3B
484#define SCSI_READ_BUFFER 0x3C
485#define SCSI_RECV_DIAGNOSTIC 0x1C
486#define SCSI_READ_LONG 0x3E
487#define SCSI_WRITE_LONG 0x3F
488#define SCSI_LAST_SCSI_CMND SCSI_WRITE_LONG
489#define SCSI_INVALID_CMND 0xFF
490
491
492
493#define SSGOOD 0x00
494#define SSCHECK 0x02
495#define SSCOND_MET 0x04
496#define SSBUSY 0x08
497#define SSRESERVATION_CONFLICT 0x18
498#define SSCMD_TERM 0x22
499#define SSQ_FULL 0x28
500
501
502#define SKNO_SEN 0x00
503#define SKRECOV_ERR 0x01
504#define SKNOT_RDY 0x02
505#define SKMED_ERR 0x03
506#define SKHW_ERR 0x04
507#define SKILL_REQ 0x05
508#define SKUNIT_ATTN 0x06
509#define SKDATA_PROTECT 0x07
510#define SKBLNK_CHK 0x08
511#define SKCPY_ABORT 0x0A
512#define SKABORT_CMD 0x0B
513#define SKEQUAL 0x0C
514#define SKVOL_OVF 0x0D
515#define SKMIS_CMP 0x0E
516
517
518#define SMCMD_COMP 0x00
519#define SMEXT 0x01
520#define SMSAVE_DATA_PTR 0x02
521#define SMREST_DATA_PTR 0x03
522#define SMDISC 0x04
523#define SMINIT_DETEC_ERR 0x05
524#define SMABORT 0x06
525#define SMREJECT 0x07
526#define SMNO_OP 0x08
527#define SMPARITY 0x09
528#define SMDEV_RESET 0x0C
529#define SMABORT_TAG 0x0D
530#define SMINIT_RECOVERY 0x0F
531#define SMREL_RECOVERY 0x10
532
533#define SMIDENT 0x80
534#define DISC_PRIV 0x40
535
536
537#define SMSYNC 0x01
538#define SM10MBS 0x19 /* 100ns */
539#define SM5MBS 0x32 /* 200ns */
540#define SMOFFSET 0x0F /* Maxoffset value */
541#define SMWDTR 0x03
542#define SM8BIT 0x00
543#define SM16BIT 0x01
544#define SM32BIT 0x02
545#define SMIGNORWR 0x23 /* Ignore Wide Residue */
546
547
548#define ARBITRATION_DELAY 0x01 /* 2.4us using a 40Mhz clock */
549#define BUS_SETTLE_DELAY 0x01 /* 400ns */
550#define BUS_CLEAR_DELAY 0x01 /* 800ns */
551
552
553
554#define SPHASE_TO 0x0A /* 10 second timeout waiting for */
555#define SCMD_TO 0x0F /* Overall command timeout */
556
557
558
559#define SIX_BYTE_CMD 0x06
560#define TEN_BYTE_CMD 0x0A
561#define TWELVE_BYTE_CMD 0x0C
562
563#define ASYNC 0x00
564#define PERI25NS 0x06 /* 25/4ns to next clock for xbow. */
565#define SYNC10MBS 0x19
566#define SYNC5MBS 0x32
567#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
570#define EEPROM_WD_CNT 256
571
572#define EEPROM_CHECK_SUM 0
573#define FW_SIGNATURE 2
574#define MODEL_NUMB_0 4
575#define MODEL_NUMB_1 5
576#define MODEL_NUMB_2 6
577#define MODEL_NUMB_3 7
578#define MODEL_NUMB_4 8
579#define MODEL_NUMB_5 9
580#define IO_BASE_ADDR 10
581#define IRQ_NUMBER 12
582#define PCI_INT_PIN 13
583#define BUS_DELAY 14 /*On time in byte 14 off delay in 15 */
584#define SYSTEM_CONFIG 16
585#define SCSI_CONFIG 17
586#define BIOS_CONFIG 18
587#define SPIN_UP_DELAY 19
588#define SCAM_CONFIG 20
589#define ADAPTER_SCSI_ID 24
590
591
592#define IGNORE_B_SCAN 32
593#define SEND_START_ENA 34
594#define DEVICE_ENABLE 36
595
596#define SYNC_RATE_TBL 38
597#define SYNC_RATE_TBL01 38
598#define SYNC_RATE_TBL23 40
599#define SYNC_RATE_TBL45 42
600#define SYNC_RATE_TBL67 44
601#define SYNC_RATE_TBL89 46
602#define SYNC_RATE_TBLab 48
603#define SYNC_RATE_TBLcd 50
604#define SYNC_RATE_TBLef 52
605
606
607
608#define EE_SCAMBASE 256
609
610
611
612 #define DOM_MASTER (BIT(0) + BIT(1))
613 #define SCAM_ENABLED BIT(2)
614 #define SCAM_LEVEL2 BIT(3)
615
616
617 #define RENEGO_ENA BITW(10)
618 #define CONNIO_ENA BITW(11)
619 #define GREEN_PC_ENA BITW(12)
620
621
622 #define AUTO_RATE_00 00
623 #define AUTO_RATE_05 01
624 #define AUTO_RATE_10 02
625 #define AUTO_RATE_20 03
626
627 #define WIDE_NEGO_BIT BIT(7)
628 #define DISC_ENABLE_BIT BIT(6)
629
630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
632 #define hp_vendor_id_0 0x00 /* LSB */
633 #define ORION_VEND_0 0x4B
634
635 #define hp_vendor_id_1 0x01 /* MSB */
636 #define ORION_VEND_1 0x10
637
638 #define hp_device_id_0 0x02 /* LSB */
639 #define ORION_DEV_0 0x30
640
641 #define hp_device_id_1 0x03 /* MSB */
642 #define ORION_DEV_1 0x81
643
644 /* Sub Vendor ID and Sub Device ID only available in
645 Harpoon Version 2 and higher */
646
647 #define hp_sub_vendor_id_0 0x04 /* LSB */
648 #define hp_sub_vendor_id_1 0x05 /* MSB */
649 #define hp_sub_device_id_0 0x06 /* LSB */
650 #define hp_sub_device_id_1 0x07 /* MSB */
651
652
653 #define hp_dual_addr_lo 0x08
654 #define hp_dual_addr_lmi 0x09
655 #define hp_dual_addr_hmi 0x0A
656 #define hp_dual_addr_hi 0x0B
657
658 #define hp_semaphore 0x0C
659 #define SCCB_MGR_ACTIVE BIT(0)
660 #define TICKLE_ME BIT(1)
661 #define SCCB_MGR_PRESENT BIT(3)
662 #define BIOS_IN_USE BIT(4)
663
664 #define hp_user_defined_D 0x0D
665
666 #define hp_reserved_E 0x0E
667
668 #define hp_sys_ctrl 0x0F
669
670 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
671 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
672 #define HALT_MACH BIT(3) /*Halt State Machine */
673 #define HARD_ABORT BIT(4) /*Hard Abort */
674 #define DIAG_MODE BIT(5) /*Diagnostic Mode */
675
676 #define BM_ABORT_TMOUT 0x50 /*Halt State machine time out */
677
678 #define hp_sys_cfg 0x10
679
680 #define DONT_RST_FIFO BIT(7) /*Don't reset FIFO */
681
682
683 #define hp_host_ctrl0 0x11
684
685 #define DUAL_ADDR_MODE BIT(0) /*Enable 64-bit addresses */
686 #define IO_MEM_SPACE BIT(1) /*I/O Memory Space */
687 #define RESOURCE_LOCK BIT(2) /*Enable Resource Lock */
688 #define IGNOR_ACCESS_ERR BIT(3) /*Ignore Access Error */
689 #define HOST_INT_EDGE BIT(4) /*Host interrupt level/edge mode sel */
690 #define SIX_CLOCKS BIT(5) /*6 Clocks between Strobe */
691 #define DMA_EVEN_PARITY BIT(6) /*Enable DMA Enen Parity */
692
693/*
694 #define BURST_MODE BIT(0)
695*/
696
697 #define hp_reserved_12 0x12
698
699 #define hp_host_blk_cnt 0x13
700
701 #define XFER_BLK1 0x00 /* 0 0 0 1 byte per block*/
702 #define XFER_BLK2 0x01 /* 0 0 1 2 byte per block*/
703 #define XFER_BLK4 0x02 /* 0 1 0 4 byte per block*/
704 #define XFER_BLK8 0x03 /* 0 1 1 8 byte per block*/
705 #define XFER_BLK16 0x04 /* 1 0 0 16 byte per block*/
706 #define XFER_BLK32 0x05 /* 1 0 1 32 byte per block*/
707 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
708
709 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
710
711
712 #define hp_reserved_14 0x14
713 #define hp_reserved_15 0x15
714 #define hp_reserved_16 0x16
715
716 #define hp_int_mask 0x17
717
718 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
719 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
720 #define INT_SCSI BIT(2) /* Scsi block interrupt */
721 #define INT_FIFO_RDY BIT(4) /* FIFO data ready */
722
723
724 #define hp_xfer_cnt_lo 0x18
725 #define hp_xfer_cnt_mi 0x19
726 #define hp_xfer_cnt_hi 0x1A
727 #define hp_xfer_cmd 0x1B
728
729 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
730 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
731 #define XFER_HOST_MPU 0x02 /* 0 1 0 Transfer Host -> MPU */
732 #define XFER_MPU_HOST 0x03 /* 0 1 1 Transfer MPU -> Host */
733 #define XFER_DMA_MPU 0x04 /* 1 0 0 Transfer DMA -> MPU */
734 #define XFER_MPU_DMA 0x05 /* 1 0 1 Transfer MPU -> DMA */
735 #define SET_SEMAPHORE 0x06 /* 1 1 0 Set Semaphore */
736 #define XFER_NOP 0x07 /* 1 1 1 Transfer NOP */
737 #define XFER_MB_MPU 0x06 /* 1 1 0 Transfer MB -> MPU */
738 #define XFER_MB_DMA 0x07 /* 1 1 1 Transfer MB -> DMA */
739
740
741 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
742 #define XFER_HOST_8BIT 0x08 /* 0 1 8 BIT Transfer Size */
743 #define XFER_HOST_16BIT 0x10 /* 1 0 16 BIT Transfer Size */
744 #define XFER_HOST_32BIT 0x18 /* 1 1 32 BIT Transfer Size */
745
746 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
747 #define XFER_DMA_16BIT 0x40 /* 1 0 16 BIT Transfer Size */
748
749 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
750
751 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
752 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
753 #define WIDE_HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_16BIT))
754 #define WIDE_HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_16BIT))
755
756 #define hp_host_addr_lo 0x1C
757 #define hp_host_addr_lmi 0x1D
758 #define hp_host_addr_hmi 0x1E
759 #define hp_host_addr_hi 0x1F
760
761 #define hp_pio_data 0x20
762 #define hp_reserved_21 0x21
763 #define hp_ee_ctrl 0x22
764
765 #define EXT_ARB_ACK BIT(7)
766 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
767 #define SEE_MS BIT(5)
768 #define SEE_CS BIT(3)
769 #define SEE_CLK BIT(2)
770 #define SEE_DO BIT(1)
771 #define SEE_DI BIT(0)
772
773 #define EE_READ 0x06
774 #define EE_WRITE 0x05
775 #define EWEN 0x04
776 #define EWEN_ADDR 0x03C0
777 #define EWDS 0x04
778 #define EWDS_ADDR 0x0000
779
780 #define hp_brdctl 0x23
781
782 #define DAT_7 BIT(7)
783 #define DAT_6 BIT(6)
784 #define DAT_5 BIT(5)
785 #define BRD_STB BIT(4)
786 #define BRD_CS BIT(3)
787 #define BRD_WR BIT(2)
788
789 #define hp_reserved_24 0x24
790 #define hp_reserved_25 0x25
791
792
793
794
795 #define hp_bm_ctrl 0x26
796
797 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
798 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
799 #define BM_XFER_MIN_8 BIT(2) /*Enable bus master transfer of 9 */
800 #define BIOS_ENA BIT(3) /*Enable BIOS/FLASH Enable */
801 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
802 #define FAST_SINGLE BIT(6) /*?? */
803
804 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
805
806 #define hp_reserved_27 0x27
807
808 #define hp_sg_addr 0x28
809 #define hp_page_ctrl 0x29
810
811 #define SCATTER_EN BIT(0)
812 #define SGRAM_ARAM BIT(1)
813 #define BIOS_SHADOW BIT(2)
814 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
815 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
816
817 #define hp_reserved_2A 0x2A
818 #define hp_pci_cmd_cfg 0x2B
819
820 #define IO_SPACE_ENA BIT(0) /*enable I/O space */
821 #define MEM_SPACE_ENA BIT(1) /*enable memory space */
822 #define BUS_MSTR_ENA BIT(2) /*enable bus master operation */
823 #define MEM_WI_ENA BIT(4) /*enable Write and Invalidate */
824 #define PAR_ERR_RESP BIT(6) /*enable parity error responce. */
825
826 #define hp_reserved_2C 0x2C
827
828 #define hp_pci_stat_cfg 0x2D
829
830 #define DATA_PARITY_ERR BIT(0)
831 #define REC_TARGET_ABORT BIT(4) /*received Target abort */
832 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
833 #define SIG_SYSTEM_ERR BIT(6)
834 #define DETECTED_PAR_ERR BIT(7)
835
836 #define hp_reserved_2E 0x2E
837
838 #define hp_sys_status 0x2F
839
840 #define SLV_DATA_RDY BIT(0) /*Slave data ready */
841 #define XFER_CNT_ZERO BIT(1) /*Transfer counter = 0 */
842 #define BM_FIFO_EMPTY BIT(2) /*FIFO empty */
843 #define BM_FIFO_FULL BIT(3) /*FIFO full */
844 #define HOST_OP_DONE BIT(4) /*host operation done */
845 #define DMA_OP_DONE BIT(5) /*DMA operation done */
846 #define SLV_OP_DONE BIT(6) /*Slave operation done */
847 #define PWR_ON_FLAG BIT(7) /*Power on flag */
848
849 #define hp_reserved_30 0x30
850
851 #define hp_host_status0 0x31
852
853 #define HOST_TERM BIT(5) /*Host Terminal Count */
854 #define HOST_TRSHLD BIT(6) /*Host Threshold */
855 #define CONNECTED_2_HOST BIT(7) /*Connected to Host */
856
857 #define hp_reserved_32 0x32
858
859 #define hp_rev_num 0x33
860
861 #define REV_A_CONST 0x0E
862 #define REV_B_CONST 0x0E
863
864 #define hp_stack_data 0x34
865 #define hp_stack_addr 0x35
866
867 #define hp_ext_status 0x36
868
869 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
870 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
871 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
872 #define FIFO_TC_NOT_ZERO BIT(2) /*FIFO or transfer counter not zero */
873 #define CHIP_RST_OCCUR BIT(3) /*Chip reset occurs */
874 #define CMD_ABORTED BIT(4) /*Command aborted */
875 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
876 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
877 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
878 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
879 BM_PARITY_ERR | PIO_OVERRUN)
880
881 #define hp_int_status 0x37
882
883 #define BM_CMD_CMPL BIT(0) /*Bus Master command complete */
884 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
885 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
886 #define BM_FIFO_RDY BIT(4)
887 #define INT_ASSERTED BIT(5) /* */
888 #define SRAM_BUSY BIT(6) /*Scatter/Gather RAM busy */
889 #define CMD_REG_BUSY BIT(7)
890
891
892 #define hp_fifo_cnt 0x38
893 #define hp_curr_host_cnt 0x39
894 #define hp_reserved_3A 0x3A
895 #define hp_fifo_in_addr 0x3B
896
897 #define hp_fifo_out_addr 0x3C
898 #define hp_reserved_3D 0x3D
899 #define hp_reserved_3E 0x3E
900 #define hp_reserved_3F 0x3F
901
902
903
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 #define hp_intena 0x40
905
906 #define RESET BITW(7)
907 #define PROG_HLT BITW(6)
908 #define PARITY BITW(5)
909 #define FIFO BITW(4)
910 #define SEL BITW(3)
911 #define SCAM_SEL BITW(2)
912 #define RSEL BITW(1)
913 #define TIMEOUT BITW(0)
914 #define BUS_FREE BITW(15)
915 #define XFER_CNT_0 BITW(14)
916 #define PHASE BITW(13)
917 #define IUNKWN BITW(12)
918 #define ICMD_COMP BITW(11)
919 #define ITICKLE BITW(10)
920 #define IDO_STRT BITW(9)
921 #define ITAR_DISC BITW(8)
922 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
923 #define CLR_ALL_INT 0xFFFF
924 #define CLR_ALL_INT_1 0xFF00
925
926 #define hp_intstat 0x42
927
928 #define hp_scsisig 0x44
929
930 #define SCSI_SEL BIT(7)
931 #define SCSI_BSY BIT(6)
932 #define SCSI_REQ BIT(5)
933 #define SCSI_ACK BIT(4)
934 #define SCSI_ATN BIT(3)
935 #define SCSI_CD BIT(2)
936 #define SCSI_MSG BIT(1)
937 #define SCSI_IOBIT BIT(0)
938
939 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
940 #define S_CMD_PH (BIT(2) )
941 #define S_MSGO_PH (BIT(2)+BIT(1) )
942 #define S_STAT_PH (BIT(2) +BIT(0))
943 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
944 #define S_DATAI_PH ( BIT(0))
945 #define S_DATAO_PH 0x00
946 #define S_ILL_PH ( BIT(1) )
947
948 #define hp_scsictrl_0 0x45
949
950 #define NO_ARB BIT(7)
951 #define SEL_TAR BIT(6)
952 #define ENA_ATN BIT(4)
953 #define ENA_RESEL BIT(2)
954 #define SCSI_RST BIT(1)
955 #define ENA_SCAM_SEL BIT(0)
956
957
958
959 #define hp_portctrl_0 0x46
960
961 #define SCSI_PORT BIT(7)
962 #define SCSI_INBIT BIT(6)
963 #define DMA_PORT BIT(5)
964 #define DMA_RD BIT(4)
965 #define HOST_PORT BIT(3)
966 #define HOST_WRT BIT(2)
967 #define SCSI_BUS_EN BIT(1)
968 #define START_TO BIT(0)
969
970 #define hp_scsireset 0x47
971
972 #define SCSI_TAR BIT(7)
973 #define SCSI_INI BIT(6)
974 #define SCAM_EN BIT(5)
975 #define ACK_HOLD BIT(4)
976 #define DMA_RESET BIT(3)
977 #define HPSCSI_RESET BIT(2)
978 #define PROG_RESET BIT(1)
979 #define FIFO_CLR BIT(0)
980
981 #define hp_xfercnt_0 0x48
982 #define hp_xfercnt_1 0x49
983 #define hp_xfercnt_2 0x4A
984 #define hp_xfercnt_3 0x4B
985
986 #define hp_fifodata_0 0x4C
987 #define hp_fifodata_1 0x4D
988 #define hp_addstat 0x4E
989
990 #define SCAM_TIMER BIT(7)
991 #define AUTO_RUNNING BIT(6)
992 #define FAST_SYNC BIT(5)
993 #define SCSI_MODE8 BIT(3)
994 #define SCSI_PAR_ERR BIT(0)
995
996 #define hp_prgmcnt_0 0x4F
997
998 #define AUTO_PC_MASK 0x3F
999
1000 #define hp_selfid_0 0x50
1001 #define hp_selfid_1 0x51
1002 #define hp_arb_id 0x52
1003
1004 #define ARB_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0))
1005
1006 #define hp_select_id 0x53
1007
1008 #define RESEL_ID (BIT(7) + BIT(6) + BIT(5) + BIT(4))
1009 #define SELECT_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0))
1010
1011 #define hp_synctarg_base 0x54
1012 #define hp_synctarg_12 0x54
1013 #define hp_synctarg_13 0x55
1014 #define hp_synctarg_14 0x56
1015 #define hp_synctarg_15 0x57
1016
1017 #define hp_synctarg_8 0x58
1018 #define hp_synctarg_9 0x59
1019 #define hp_synctarg_10 0x5A
1020 #define hp_synctarg_11 0x5B
1021
1022 #define hp_synctarg_4 0x5C
1023 #define hp_synctarg_5 0x5D
1024 #define hp_synctarg_6 0x5E
1025 #define hp_synctarg_7 0x5F
1026
1027 #define hp_synctarg_0 0x60
1028 #define hp_synctarg_1 0x61
1029 #define hp_synctarg_2 0x62
1030 #define hp_synctarg_3 0x63
1031
1032 #define RATE_20MB 0x00
1033 #define RATE_10MB ( BIT(5))
1034 #define RATE_6_6MB ( BIT(6) )
1035 #define RATE_5MB ( BIT(6)+BIT(5))
1036 #define RATE_4MB (BIT(7) )
1037 #define RATE_3_33MB (BIT(7) +BIT(5))
1038 #define RATE_2_85MB (BIT(7)+BIT(6) )
1039 #define RATE_2_5MB (BIT(7)+BIT(5)+BIT(6))
1040 #define NEXT_CLK BIT(5)
1041 #define SLOWEST_SYNC (BIT(7)+BIT(6)+BIT(5))
1042 #define NARROW_SCSI BIT(4)
1043 #define SYNC_OFFSET (BIT(3) + BIT(2) + BIT(1) + BIT(0))
1044 #define DEFAULT_ASYNC 0x00
1045 #define DEFAULT_OFFSET 0x0F
1046
1047 #define hp_autostart_0 0x64
1048 #define hp_autostart_1 0x65
1049 #define hp_autostart_2 0x66
1050 #define hp_autostart_3 0x67
1051
1052
1053
1054 #define DISABLE 0x00
1055 #define AUTO_IMMED BIT(5)
1056 #define SELECT BIT(6)
1057 #define RESELECT (BIT(6)+BIT(5))
1058 #define BUSFREE BIT(7)
1059 #define XFER_0 (BIT(7)+BIT(5))
1060 #define END_DATA (BIT(7)+BIT(6))
1061 #define MSG_PHZ (BIT(7)+BIT(6)+BIT(5))
1062
1063 #define hp_gp_reg_0 0x68
1064 #define hp_gp_reg_1 0x69
1065 #define hp_gp_reg_2 0x6A
1066 #define hp_gp_reg_3 0x6B
1067
1068 #define hp_seltimeout 0x6C
1069
1070
1071 #define TO_2ms 0x54 /* 2.0503ms */
1072 #define TO_4ms 0x67 /* 3.9959ms */
1073
1074 #define TO_5ms 0x03 /* 4.9152ms */
1075 #define TO_10ms 0x07 /* 11.xxxms */
1076 #define TO_250ms 0x99 /* 250.68ms */
1077 #define TO_290ms 0xB1 /* 289.99ms */
1078 #define TO_350ms 0xD6 /* 350.62ms */
1079 #define TO_417ms 0xFF /* 417.79ms */
1080
1081 #define hp_clkctrl_0 0x6D
1082
1083 #define PWR_DWN BIT(6)
1084 #define ACTdeassert BIT(4)
1085 #define ATNonErr BIT(3)
1086 #define CLK_30MHZ BIT(1)
1087 #define CLK_40MHZ (BIT(1) + BIT(0))
1088 #define CLK_50MHZ BIT(2)
1089
1090 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
1091
1092 #define hp_fiforead 0x6E
1093 #define hp_fifowrite 0x6F
1094
1095 #define hp_offsetctr 0x70
1096 #define hp_xferstat 0x71
1097
1098 #define FIFO_FULL BIT(7)
1099 #define FIFO_EMPTY BIT(6)
1100 #define FIFO_MASK 0x3F /* Mask for the FIFO count value. */
1101 #define FIFO_LEN 0x20
1102
1103 #define hp_portctrl_1 0x72
1104
1105 #define EVEN_HOST_P BIT(5)
1106 #define INVT_SCSI BIT(4)
1107 #define CHK_SCSI_P BIT(3)
1108 #define HOST_MODE8 BIT(0)
1109 #define HOST_MODE16 0x00
1110
1111 #define hp_xfer_pad 0x73
1112
1113 #define ID_UNLOCK BIT(3)
1114 #define XFER_PAD BIT(2)
1115
1116 #define hp_scsidata_0 0x74
1117 #define hp_scsidata_1 0x75
1118 #define hp_timer_0 0x76
1119 #define hp_timer_1 0x77
1120
1121 #define hp_reserved_78 0x78
1122 #define hp_reserved_79 0x79
1123 #define hp_reserved_7A 0x7A
1124 #define hp_reserved_7B 0x7B
1125
1126 #define hp_reserved_7C 0x7C
1127 #define hp_reserved_7D 0x7D
1128 #define hp_reserved_7E 0x7E
1129 #define hp_reserved_7F 0x7F
1130
1131 #define hp_aramBase 0x80
1132 #define BIOS_DATA_OFFSET 0x60
1133 #define BIOS_RELATIVE_CARD 0x64
1134
1135
1136
1137
1138 #define AUTO_LEN 0x80
1139 #define AR0 0x00
1140 #define AR1 BITW(8)
1141 #define AR2 BITW(9)
1142 #define AR3 (BITW(9) + BITW(8))
1143 #define SDATA BITW(10)
1144
1145 #define NOP_OP 0x00 /* Nop command */
1146
1147 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
1148
1149 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
1150
1151 #define CBE_OP (BITW(14)+BITW(12)+BITW(11)) /* Cmp SCSI cmd class & Branch EQ */
1152
1153 #define CBN_OP (BITW(14)+BITW(13)) /* Cmp SCSI cmd class & Branch NOT EQ */
1154
1155 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
1156
1157 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
1158
1159
1160 #define ADATA_OUT 0x00
1161 #define ADATA_IN BITW(8)
1162 #define ACOMMAND BITW(10)
1163 #define ASTATUS (BITW(10)+BITW(8))
1164 #define AMSG_OUT (BITW(10)+BITW(9))
1165 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
1166 #define AILLEGAL (BITW(9)+BITW(8))
1167
1168
1169 #define BRH_OP BITW(13) /* Branch */
1170
1171
1172 #define ALWAYS 0x00
1173 #define EQUAL BITW(8)
1174 #define NOT_EQ BITW(9)
1175
1176 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
1177
1178
1179 #define ATN_SET BITW(8)
1180 #define ATN_RESET BITW(9)
1181 #define XFER_CNT (BITW(9)+BITW(8))
1182 #define FIFO_0 BITW(10)
1183 #define FIFO_NOT0 (BITW(10)+BITW(8))
1184 #define T_USE_SYNC0 (BITW(10)+BITW(9))
1185
1186
1187 #define MPM_OP BITW(15) /* Match phase and move data */
1188
1189 #define MDR_OP (BITW(12)+BITW(11)) /* Move data to Reg. */
1190
1191 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
1192
1193
1194 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
1195
1196
1197 #define D_AR0 0x00
1198 #define D_AR1 BIT(0)
1199 #define D_AR2 BIT(1)
1200 #define D_AR3 (BIT(1) + BIT(0))
1201 #define D_SDATA BIT(2)
1202 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
1203
1204
1205 #define ADR_OP (BITW(13)+BITW(12)) /* Logical AND Reg. w. Data */
1206
1207 #define ADS_OP (BITW(14)+BITW(13)+BITW(12))
1208
1209 #define ODR_OP (BITW(13)+BITW(12)+BITW(11))
1210
1211 #define ODS_OP (BITW(14)+BITW(13)+BITW(12)+BITW(11))
1212
1213 #define STR_OP (BITW(15)+BITW(14)) /* Store to A_Reg. */
1214
1215 #define AINT_ENA1 0x00
1216 #define AINT_STAT1 BITW(8)
1217 #define ASCSI_SIG BITW(9)
1218 #define ASCSI_CNTL (BITW(9)+BITW(8))
1219 #define APORT_CNTL BITW(10)
1220 #define ARST_CNTL (BITW(10)+BITW(8))
1221 #define AXFERCNT0 (BITW(10)+BITW(9))
1222 #define AXFERCNT1 (BITW(10)+BITW(9)+BITW(8))
1223 #define AXFERCNT2 BITW(11)
1224 #define AFIFO_DATA (BITW(11)+BITW(8))
1225 #define ASCSISELID (BITW(11)+BITW(9))
1226 #define ASCSISYNC0 (BITW(11)+BITW(9)+BITW(8))
1227
1228
1229 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
1230
1231 #define SSI_OP (BITW(15)+BITW(11))
1232
1233
1234 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
1235 #define SSI_IDO_STRT (IDO_STRT >> 8)
1236 #define SSI_IDI_STRT (IDO_STRT >> 8)
1237
1238 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
1239 #define SSI_ITICKLE (ITICKLE >> 8)
1240
1241 #define SSI_IUNKWN (IUNKWN >> 8)
1242 #define SSI_INO_CC (IUNKWN >> 8)
1243 #define SSI_IRFAIL (IUNKWN >> 8)
1244
1245
1246 #define NP 0x10 /*Next Phase */
1247 #define NTCMD 0x02 /*Non- Tagged Command start */
1248 #define CMDPZ 0x04 /*Command phase */
1249 #define DINT 0x12 /*Data Out/In interrupt */
1250 #define DI 0x13 /*Data Out */
1251 #define MI 0x14 /*Message In */
1252 #define DC 0x19 /*Disconnect Message */
1253 #define ST 0x1D /*Status Phase */
1254 #define UNKNWN 0x24 /*Unknown bus action */
1255 #define CC 0x25 /*Command Completion failure */
1256 #define TICK 0x26 /*New target reselected us. */
1257 #define RFAIL 0x27 /*Reselection failed */
1258 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
1259
1260
1261 #define ID_MSG_STRT hp_aramBase + 0x00
1262 #define NON_TAG_ID_MSG hp_aramBase + 0x06
1263 #define CMD_STRT hp_aramBase + 0x08
1264 #define SYNC_MSGS hp_aramBase + 0x08
1265
1266
1267
1268
1269
1270 #define TAG_STRT 0x00
1271 #define SELECTION_START 0x00
1272 #define DISCONNECT_START 0x10/2
1273 #define END_DATA_START 0x14/2
1274 #define NONTAG_STRT 0x02/2
1275 #define CMD_ONLY_STRT CMDPZ/2
1276 #define TICKLE_STRT TICK/2
1277 #define SELCHK_STRT SELCHK/2
1278
1279
1280
1281
1282#define mEEPROM_CLK_DELAY(port) (RD_HARPOON(port+hp_intstat_1))
1283
1284#define mWAIT_10MS(port) (RD_HARPOON(port+hp_intstat_1))
1285
1286
1287#define CLR_XFER_CNT(port) (WR_HARPOON(port+hp_xfercnt_0, 0x00))
1288
1289#define SET_XFER_CNT(port, data) (WR_HARP32(port,hp_xfercnt_0,data))
1290
1291#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
1292/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
1293 xfercnt <<= 16,\
1294 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
1295 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
1297 addr >>= 16,\
1298 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
1299 WR_HARP32(port,hp_xfercnt_0,count),\
1300 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
1301 count >>= 16,\
1302 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303
1304#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
1305 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
1306
1307
1308#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
1309 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
1310
1311#define ACCEPT_STAT(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
1312 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
1313
1314#define ACCEPT_STAT_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
1315 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
1316
1317#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
1318 WR_HARPOON(port+hp_scsireset, 0x00))
1319
1320#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
1321 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
1322
1323#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
1324 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
1325
1326#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
1327 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
1328
1329#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
1330 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
1331
1332
1333
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335void scsiStartAuto(ULONG port);
James Bottomley 47b5d692005-04-24 02:38:05 -05001336static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
1337static void FPT_ssel(ULONG port, UCHAR p_card);
1338static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
1339static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
1340static void FPT_stsyncn(ULONG port, UCHAR p_card);
1341static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
1342static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
1343 PSCCBMgr_tar_info currTar_Info);
1344static void FPT_sresb(ULONG port, UCHAR p_card);
1345static void FPT_sxfrp(ULONG p_port, UCHAR p_card);
1346static void FPT_schkdd(ULONG port, UCHAR p_card);
1347static UCHAR FPT_RdStack(ULONG port, UCHAR index);
1348static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
1349static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350
James Bottomley 47b5d692005-04-24 02:38:05 -05001351static void FPT_SendMsg(ULONG port, UCHAR message);
1352static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1353 UCHAR error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
James Bottomley 47b5d692005-04-24 02:38:05 -05001355static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1356static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
James Bottomley 47b5d692005-04-24 02:38:05 -05001358static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1359static void FPT_stwidn(ULONG port, UCHAR p_card);
1360static void FPT_siwidr(ULONG port, UCHAR width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
1362
James Bottomley 47b5d692005-04-24 02:38:05 -05001363static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1364static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1365static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1366 UCHAR p_card);
1367static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1368static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1369static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1370static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1371static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1372static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1373static UCHAR FPT_CalcLrc(UCHAR buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
1375
James Bottomley 47b5d692005-04-24 02:38:05 -05001376static void FPT_Wait1Second(ULONG p_port);
1377static void FPT_Wait(ULONG p_port, UCHAR p_delay);
1378static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1379static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1380static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1381static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1382static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
1384
1385
James Bottomley 47b5d692005-04-24 02:38:05 -05001386static void FPT_phaseDataOut(ULONG port, UCHAR p_card);
1387static void FPT_phaseDataIn(ULONG port, UCHAR p_card);
1388static void FPT_phaseCommand(ULONG port, UCHAR p_card);
1389static void FPT_phaseStatus(ULONG port, UCHAR p_card);
1390static void FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1391static void FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1392static void FPT_phaseIllegal(ULONG port, UCHAR p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393
James Bottomley 47b5d692005-04-24 02:38:05 -05001394static void FPT_phaseDecode(ULONG port, UCHAR p_card);
1395static void FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1396static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
1398
1399
1400
James Bottomley 47b5d692005-04-24 02:38:05 -05001401static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1402static void FPT_BusMasterInit(ULONG p_port);
1403static void FPT_DiagEEPROM(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405
1406
1407
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408void busMstrAbort(ULONG port);
James Bottomley 47b5d692005-04-24 02:38:05 -05001409static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1410static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1411static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1412static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1413static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
1415
James Bottomley 47b5d692005-04-24 02:38:05 -05001416static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1417 PSCCBcard pCurrCard, USHORT p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
James Bottomley 47b5d692005-04-24 02:38:05 -05001419static void FPT_SccbMgrTableInitAll(void);
1420static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1421static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
1423
1424
James Bottomley 47b5d692005-04-24 02:38:05 -05001425static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
James Bottomley 47b5d692005-04-24 02:38:05 -05001427static int FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1428static void FPT_scbusf(ULONG p_port);
1429static void FPT_scsel(ULONG p_port);
1430static void FPT_scasid(UCHAR p_card, ULONG p_port);
1431static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1432static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1433static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1434static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1435static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1436static UCHAR FPT_scvalq(UCHAR p_quintet);
1437static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1438static void FPT_scwtsel(ULONG p_port);
1439static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1440static void FPT_scsavdi(UCHAR p_card, ULONG p_port);
1441static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443
James Bottomley 47b5d692005-04-24 02:38:05 -05001444static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1445static void FPT_autoLoadDefaultMap(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
1447
1448
James Bottomley 47b5d692005-04-24 02:38:05 -05001449void OS_start_timer(unsigned long ioport, unsigned long timeout);
1450void OS_stop_timer(unsigned long ioport, unsigned long timeout);
1451void OS_disable_int(unsigned char intvec);
1452void OS_enable_int(unsigned char intvec);
1453void OS_delay(unsigned long count);
1454int OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
James Bottomley 47b5d692005-04-24 02:38:05 -05001456static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1457static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1458static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1459static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
1461
James Bottomley 47b5d692005-04-24 02:38:05 -05001462static UCHAR FPT_mbCards = 0;
1463static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1464 ' ', 'B', 'T', '-', '9', '3', '0', \
1465 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1466 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467
James Bottomley 47b5d692005-04-24 02:38:05 -05001468static USHORT FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
1470
James Bottomley 47b5d692005-04-24 02:38:05 -05001471static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474/*---------------------------------------------------------------------
1475 *
1476 * Function: SccbMgr_sense_adapter
1477 *
1478 * Description: Setup and/or Search for cards and return info to caller.
1479 *
1480 *---------------------------------------------------------------------*/
1481
James Bottomley 47b5d692005-04-24 02:38:05 -05001482static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 static UCHAR first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485
1486 UCHAR i,j,id,ScamFlg;
1487 USHORT temp,temp2,temp3,temp4,temp5,temp6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 PNVRamInfo pCurrNvRam;
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
1493
1494 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1495 return((int)FAILURE);
1496
1497 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1498 return((int)FAILURE);
1499
1500 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1501 return((int)FAILURE);
1502
1503 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1504 return((int)FAILURE);
1505
1506
1507 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1508
1509/* For new Harpoon then check for sub_device ID LSB
1510 the bits(0-3) must be all ZERO for compatible with
1511 current version of SCCBMgr, else skip this Harpoon
1512 device. */
1513
1514 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1515 return((int)FAILURE);
1516 }
1517
1518 if (first_time)
1519 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001520 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001522 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 }
1524
James Bottomley 47b5d692005-04-24 02:38:05 -05001525 if(FPT_RdStack(ioport, 0) != 0x00) {
1526 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 {
1528 pCurrNvRam = NULL;
1529 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001530 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1531 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 }
1533 else
1534 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001535 if(FPT_mbCards < MAX_MB_CARDS) {
1536 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1537 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001539 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 }else
1541 return((int) FAILURE);
1542 }
1543 }else
1544 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545
1546 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1547 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1548
1549 if(pCurrNvRam)
1550 pCardInfo->si_id = pCurrNvRam->niAdapId;
1551 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001552 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 (UCHAR)0x0FF);
1554
1555 pCardInfo->si_lun = 0x00;
1556 pCardInfo->si_fw_revision = ORION_FW_REV;
1557 temp2 = 0x0000;
1558 temp3 = 0x0000;
1559 temp4 = 0x0000;
1560 temp5 = 0x0000;
1561 temp6 = 0x0000;
1562
1563 for (id = 0; id < (16/2); id++) {
1564
1565 if(pCurrNvRam){
1566 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1567 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1568 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1569 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001570 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571
1572 for (i = 0; i < 2; temp >>=8,i++) {
1573
1574 temp2 >>= 1;
1575 temp3 >>= 1;
1576 temp4 >>= 1;
1577 temp5 >>= 1;
1578 temp6 >>= 1;
1579 switch (temp & 0x3)
1580 {
1581 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1582 temp6 |= 0x8000; /* Fall through */
1583 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1584 temp5 |= 0x8000; /* Fall through */
1585 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1586 temp2 |= 0x8000; /* Fall through */
1587 case AUTO_RATE_00: /* Asynchronous */
1588 break;
1589 }
1590
1591 if (temp & DISC_ENABLE_BIT)
1592 temp3 |= 0x8000;
1593
1594 if (temp & WIDE_NEGO_BIT)
1595 temp4 |= 0x8000;
1596
1597 }
1598 }
1599
1600 pCardInfo->si_per_targ_init_sync = temp2;
1601 pCardInfo->si_per_targ_no_disc = temp3;
1602 pCardInfo->si_per_targ_wide_nego = temp4;
1603 pCardInfo->si_per_targ_fast_nego = temp5;
1604 pCardInfo->si_per_targ_ultra_nego = temp6;
1605
1606 if(pCurrNvRam)
1607 i = pCurrNvRam->niSysConf;
1608 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001609 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610
1611 if(pCurrNvRam)
1612 ScamFlg = pCurrNvRam->niScamConf;
1613 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001614 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
1616 pCardInfo->si_flags = 0x0000;
1617
1618 if (i & 0x01)
1619 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1620
1621 if (!(i & 0x02))
1622 pCardInfo->si_flags |= SOFT_RESET;
1623
1624 if (i & 0x10)
1625 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1626
1627 if (ScamFlg & SCAM_ENABLED)
1628 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1629
1630 if (ScamFlg & SCAM_LEVEL2)
1631 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1632
1633 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1634 if (i & 0x04) {
1635 j |= SCSI_TERM_ENA_L;
1636 }
1637 WR_HARPOON(ioport+hp_bm_ctrl, j );
1638
1639 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1640 if (i & 0x08) {
1641 j |= SCSI_TERM_ENA_H;
1642 }
1643 WR_HARPOON(ioport+hp_ee_ctrl, j );
1644
1645 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1646
1647 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1648
1649 pCardInfo->si_card_family = HARPOON_FAMILY;
1650 pCardInfo->si_bustype = BUSTYPE_PCI;
1651
1652 if(pCurrNvRam){
1653 pCardInfo->si_card_model[0] = '9';
1654 switch(pCurrNvRam->niModel & 0x0f){
1655 case MODEL_LT:
1656 pCardInfo->si_card_model[1] = '3';
1657 pCardInfo->si_card_model[2] = '0';
1658 break;
1659 case MODEL_LW:
1660 pCardInfo->si_card_model[1] = '5';
1661 pCardInfo->si_card_model[2] = '0';
1662 break;
1663 case MODEL_DL:
1664 pCardInfo->si_card_model[1] = '3';
1665 pCardInfo->si_card_model[2] = '2';
1666 break;
1667 case MODEL_DW:
1668 pCardInfo->si_card_model[1] = '5';
1669 pCardInfo->si_card_model[2] = '2';
1670 break;
1671 }
1672 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001673 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001675 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
1678 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
1679 }
1680
1681 if (pCardInfo->si_card_model[1] == '3')
1682 {
1683 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1684 pCardInfo->si_flags |= LOW_BYTE_TERM;
1685 }
1686 else if (pCardInfo->si_card_model[2] == '0')
1687 {
1688 temp = RD_HARPOON(ioport+hp_xfer_pad);
1689 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1690 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1691 pCardInfo->si_flags |= LOW_BYTE_TERM;
1692 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1693 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1694 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1695 WR_HARPOON(ioport+hp_xfer_pad, temp);
1696 }
1697 else
1698 {
1699 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1700 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1701 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1702 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1703 temp3 = 0;
1704 for (i = 0; i < 8; i++)
1705 {
1706 temp3 <<= 1;
1707 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1708 temp3 |= 1;
1709 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1710 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1711 }
1712 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1713 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1714 if (!(temp3 & BIT(7)))
1715 pCardInfo->si_flags |= LOW_BYTE_TERM;
1716 if (!(temp3 & BIT(6)))
1717 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1718 }
1719
1720
1721 ARAM_ACCESS(ioport);
1722
1723 for ( i = 0; i < 4; i++ ) {
1724
1725 pCardInfo->si_XlatInfo[i] =
1726 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1727 }
1728
1729 /* return with -1 if no sort, else return with
1730 logical card number sorted by BIOS (zero-based) */
1731
1732 pCardInfo->si_relative_cardnum =
1733 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1734
1735 SGRAM_ACCESS(ioport);
1736
James Bottomley 47b5d692005-04-24 02:38:05 -05001737 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1738 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1739 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1740 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1741 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1742 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1743 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1744 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745
1746 pCardInfo->si_present = 0x01;
1747
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 return(0);
1749}
1750
1751
1752/*---------------------------------------------------------------------
1753 *
1754 * Function: SccbMgr_config_adapter
1755 *
1756 * Description: Setup adapter for normal operation (hard reset).
1757 *
1758 *---------------------------------------------------------------------*/
1759
James Bottomley 47b5d692005-04-24 02:38:05 -05001760static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761{
1762 PSCCBcard CurrCard = NULL;
1763 PNVRamInfo pCurrNvRam;
1764 UCHAR i,j,thisCard, ScamFlg;
1765 USHORT temp,sync_bit_map,id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
1770 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1771
1772 if (thisCard == MAX_CARDS) {
1773
1774 return(FAILURE);
1775 }
1776
James Bottomley 47b5d692005-04-24 02:38:05 -05001777 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778
James Bottomley 47b5d692005-04-24 02:38:05 -05001779 CurrCard = &FPT_BL_Card[thisCard];
1780 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 break;
1782 }
1783
James Bottomley 47b5d692005-04-24 02:38:05 -05001784 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
James Bottomley 47b5d692005-04-24 02:38:05 -05001786 FPT_BL_Card[thisCard].ioPort = ioport;
1787 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
James Bottomley 47b5d692005-04-24 02:38:05 -05001789 if(FPT_mbCards)
1790 for(i = 0; i < FPT_mbCards; i++){
1791 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1792 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001794 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 CurrCard->cardIndex = thisCard;
1796 CurrCard->cardInfo = pCardInfo;
1797
1798 break;
1799 }
1800 }
1801
1802 pCurrNvRam = CurrCard->pNvRamInfo;
1803
1804 if(pCurrNvRam){
1805 ScamFlg = pCurrNvRam->niScamConf;
1806 }
1807 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001808 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 }
1810
1811
James Bottomley 47b5d692005-04-24 02:38:05 -05001812 FPT_BusMasterInit(ioport);
1813 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814
James Bottomley 47b5d692005-04-24 02:38:05 -05001815 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817
1818 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1819
1820 WR_HARPOON(ioport+hp_selfid_0, id);
1821 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1822 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1823 CurrCard->ourId = pCardInfo->si_id;
1824
1825 i = (UCHAR) pCardInfo->si_flags;
1826 if (i & SCSI_PARITY_ENA)
1827 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1828
1829 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1830 if (i & LOW_BYTE_TERM)
1831 j |= SCSI_TERM_ENA_L;
1832 WR_HARPOON(ioport+hp_bm_ctrl, j);
1833
1834 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1835 if (i & HIGH_BYTE_TERM)
1836 j |= SCSI_TERM_ENA_H;
1837 WR_HARPOON(ioport+hp_ee_ctrl, j );
1838
1839
1840 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1841
James Bottomley 47b5d692005-04-24 02:38:05 -05001842 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
James Bottomley 47b5d692005-04-24 02:38:05 -05001844 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 }
1846
1847
1848
1849 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1850 CurrCard->globalFlags |= F_NO_FILTER;
1851
1852 if(pCurrNvRam){
1853 if(pCurrNvRam->niSysConf & 0x10)
1854 CurrCard->globalFlags |= F_GREEN_PC;
1855 }
1856 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001857 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 CurrCard->globalFlags |= F_GREEN_PC;
1859 }
1860
1861 /* Set global flag to indicate Re-Negotiation to be done on all
1862 ckeck condition */
1863 if(pCurrNvRam){
1864 if(pCurrNvRam->niScsiConf & 0x04)
1865 CurrCard->globalFlags |= F_DO_RENEGO;
1866 }
1867 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001868 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 CurrCard->globalFlags |= F_DO_RENEGO;
1870 }
1871
1872 if(pCurrNvRam){
1873 if(pCurrNvRam->niScsiConf & 0x08)
1874 CurrCard->globalFlags |= F_CONLUN_IO;
1875 }
1876 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001877 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 CurrCard->globalFlags |= F_CONLUN_IO;
1879 }
1880
1881
1882 temp = pCardInfo->si_per_targ_no_disc;
1883
1884 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1885
1886 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001887 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 }
1889
1890 sync_bit_map = 0x0001;
1891
1892 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1893
1894 if(pCurrNvRam){
1895 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1896 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1897 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1898 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001899 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
1901 for (i = 0; i < 2; temp >>=8,i++) {
1902
1903 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1904
James Bottomley 47b5d692005-04-24 02:38:05 -05001905 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 }
1907
1908 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001909 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1910 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 (UCHAR)(temp & ~EE_SYNC_MASK);
1912 }
1913
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1915 (id*2+i >= 8)){
1916*/
1917 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1918
James Bottomley 47b5d692005-04-24 02:38:05 -05001919 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
1921 }
1922
1923 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001924 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 }
1926
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927
1928 sync_bit_map <<= 1;
1929
1930
1931
1932 }
1933 }
1934
1935 WR_HARPOON((ioport+hp_semaphore),
1936 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 return((ULONG)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939}
1940
James Bottomley 47b5d692005-04-24 02:38:05 -05001941static void SccbMgr_unload_card(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942{
1943 UCHAR i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 ULONG portBase;
1945 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 PNVRamInfo pCurrNvRam;
1949
1950 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1951
1952 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001953 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1954 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1955 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1956 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1957 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958
1959 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05001960 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
1962 portBase = pCurrNvRam->niBaseAddr;
1963
1964 for(i = 0; i < MAX_SCSI_TAR; i++){
1965 regOffset = hp_aramBase + 64 + i*4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 scamData = *pScamTbl;
1968 WR_HARP32(portBase, regOffset, scamData);
1969 }
1970
1971 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001972 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 }
1974}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976
James Bottomley 47b5d692005-04-24 02:38:05 -05001977static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978{
1979 UCHAR i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 ULONG portBase;
1981 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
James Bottomley 47b5d692005-04-24 02:38:05 -05001985 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1986 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1987 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1988 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1989 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990
1991 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05001992 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993
1994 portBase = pNvRamInfo->niBaseAddr;
1995
1996 for(i = 0; i < MAX_SCSI_TAR; i++){
1997 regOffset = hp_aramBase + 64 + i*4;
1998 RD_HARP32(portBase, regOffset, scamData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 *pScamTbl = scamData;
2001 }
2002
2003}
2004
James Bottomley 47b5d692005-04-24 02:38:05 -05002005static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006{
2007 WR_HARPOON(portBase + hp_stack_addr, index);
2008 return(RD_HARPOON(portBase + hp_stack_data));
2009}
2010
James Bottomley 47b5d692005-04-24 02:38:05 -05002011static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012{
2013 WR_HARPOON(portBase + hp_stack_addr, index);
2014 WR_HARPOON(portBase + hp_stack_data, data);
2015}
2016
2017
James Bottomley 47b5d692005-04-24 02:38:05 -05002018static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019{
James Bottomley 47b5d692005-04-24 02:38:05 -05002020 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
2021 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
2023 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05002024 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
2026 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05002027 return(1);
2028 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029
2030}
2031/*---------------------------------------------------------------------
2032 *
2033 * Function: SccbMgr_start_sccb
2034 *
2035 * Description: Start a command pointed to by p_Sccb. When the
2036 * command is completed it will be returned via the
2037 * callback function.
2038 *
2039 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002040static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 UCHAR thisCard, lun;
2044 PSCCB pSaveSccb;
2045 CALL_BK_FN callback;
2046
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
2048 ioport = ((PSCCBcard) pCurrCard)->ioPort;
2049
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
2051 {
2052
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053 p_Sccb->HostStatus = SCCB_COMPLETE;
2054 p_Sccb->SccbStatus = SCCB_ERROR;
2055 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
2056 if (callback)
2057 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058
Linus Torvalds1da177e2005-04-16 15:20:36 -07002059 return;
2060 }
2061
James Bottomley 47b5d692005-04-24 02:38:05 -05002062 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
2064
2065 if (!((PSCCBcard) pCurrCard)->cmdCounter)
2066 {
2067 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
2068 | SCCB_MGR_ACTIVE));
2069
2070 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
2071 {
2072 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
2073 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
2074 }
2075 }
2076
2077 ((PSCCBcard)pCurrCard)->cmdCounter++;
2078
2079 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
2080
2081 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
2082 | TICKLE_ME));
2083 if(p_Sccb->OperationCode == RESET_COMMAND)
2084 {
2085 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
2086 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05002087 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
2089 }
2090 else
2091 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002092 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 }
2094 }
2095
2096 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
2097
2098 if(p_Sccb->OperationCode == RESET_COMMAND)
2099 {
2100 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
2101 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05002102 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
2104 }
2105 else
2106 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002107 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 }
2109 }
2110
2111 else {
2112
2113 MDISABLE_INT(ioport);
2114
2115 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05002116 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117 lun = p_Sccb->Lun;
2118 else
2119 lun = 0;
2120 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05002121 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
2122 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
2123 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124
2125 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05002126 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 }
2128
2129 else {
2130
2131 if(p_Sccb->OperationCode == RESET_COMMAND)
2132 {
2133 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
2134 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05002135 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
2137 }
2138 else
2139 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002140 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 }
2142 }
2143
2144
2145 MENABLE_INT(ioport);
2146 }
2147
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148}
2149
2150
2151/*---------------------------------------------------------------------
2152 *
2153 * Function: SccbMgr_abort_sccb
2154 *
2155 * Description: Abort the command pointed to by p_Sccb. When the
2156 * command is completed it will be returned via the
2157 * callback function.
2158 *
2159 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002160static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163
2164 UCHAR thisCard;
2165 CALL_BK_FN callback;
2166 UCHAR TID;
2167 PSCCB pSaveSCCB;
2168 PSCCBMgr_tar_info currTar_Info;
2169
2170
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171 ioport = ((PSCCBcard) pCurrCard)->ioPort;
2172
2173 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
2174
James Bottomley 47b5d692005-04-24 02:38:05 -05002175 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 {
2177
James Bottomley 47b5d692005-04-24 02:38:05 -05002178 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 {
2180
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181 ((PSCCBcard)pCurrCard)->cmdCounter--;
2182
2183 if (!((PSCCBcard)pCurrCard)->cmdCounter)
2184 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
2185 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
2186
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 p_Sccb->SccbStatus = SCCB_ABORT;
2188 callback = p_Sccb->SccbCallback;
2189 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190
2191 return(0);
2192 }
2193
2194 else
2195 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
2197 {
2198 p_Sccb->SccbStatus = SCCB_ABORT;
2199 return(0);
2200
2201 }
2202
2203 else
2204 {
2205
2206 TID = p_Sccb->TargID;
2207
2208
2209 if(p_Sccb->Sccb_tag)
2210 {
2211 MDISABLE_INT(ioport);
2212 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
2213 {
2214 p_Sccb->SccbStatus = SCCB_ABORT;
2215 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
2217
2218 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
2219 {
2220 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05002221 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222 }
2223 else
2224 {
2225 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
2226 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05002227 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
2229 }
2230 }
2231 MENABLE_INT(ioport);
2232 return(0);
2233 }
2234 else
2235 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002236 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
James Bottomley 47b5d692005-04-24 02:38:05 -05002238 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 == p_Sccb)
2240 {
2241 p_Sccb->SccbStatus = SCCB_ABORT;
2242 return(0);
2243 }
2244 }
2245 }
2246 }
2247 }
2248 return(-1);
2249}
2250
2251
2252/*---------------------------------------------------------------------
2253 *
2254 * Function: SccbMgr_my_int
2255 *
2256 * Description: Do a quick check to determine if there is a pending
2257 * interrupt for this card and disable the IRQ Pin if so.
2258 *
2259 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002260static UCHAR SccbMgr_my_int(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263
2264 ioport = ((PSCCBcard)pCurrCard)->ioPort;
2265
2266 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
2267 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002268 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 }
2270
2271 else
2272
James Bottomley 47b5d692005-04-24 02:38:05 -05002273 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274}
2275
2276
2277
2278/*---------------------------------------------------------------------
2279 *
2280 * Function: SccbMgr_isr
2281 *
2282 * Description: This is our entry point when an interrupt is generated
2283 * by the card and the upper level driver passes it on to
2284 * us.
2285 *
2286 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002287static int SccbMgr_isr(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288{
2289 PSCCB currSCCB;
2290 UCHAR thisCard,result,bm_status, bm_int_st;
2291 USHORT hp_int;
2292 UCHAR i, target;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
2295 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
2296 ioport = ((PSCCBcard)pCurrCard)->ioPort;
2297
2298 MDISABLE_INT(ioport);
2299
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
2301 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
2302 else
2303 bm_status = 0;
2304
2305 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
2306
James Bottomley 47b5d692005-04-24 02:38:05 -05002307 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 bm_status)
2309 {
2310
2311 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
2312
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002314 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
2316 bm_status = 0;
2317
2318 if (result) {
2319
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 return(result);
2322 }
2323 }
2324
2325
2326 else if (hp_int & ICMD_COMP) {
2327
2328 if ( !(hp_int & BUS_FREE) ) {
2329 /* Wait for the BusFree before starting a new command. We
2330 must also check for being reselected since the BusFree
2331 may not show up if another device reselects us in 1.5us or
2332 less. SRR Wednesday, 3/8/1995.
2333 */
2334 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
2335 }
2336
2337 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2338
James Bottomley 47b5d692005-04-24 02:38:05 -05002339 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340
2341/* WRW_HARPOON((ioport+hp_intstat),
2342 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
2343 */
2344
2345 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
2346
James Bottomley 47b5d692005-04-24 02:38:05 -05002347 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348
2349 }
2350
2351
2352 else if (hp_int & ITAR_DISC)
2353 {
2354
2355 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2356
James Bottomley 47b5d692005-04-24 02:38:05 -05002357 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358
2359 }
2360
2361 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2362
2363 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2364 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2365
2366 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2367 }
2368
2369 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002370 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371
2372 /* Wait for the BusFree before starting a new command. We
2373 must also check for being reselected since the BusFree
2374 may not show up if another device reselects us in 1.5us or
2375 less. SRR Wednesday, 3/8/1995.
2376 */
2377 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2378 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2379 RD_HARPOON((ioport+hp_scsisig)) ==
2380 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2381
2382 /*
2383 The additional loop exit condition above detects a timing problem
2384 with the revision D/E harpoon chips. The caller should reset the
2385 host adapter to recover when 0xFE is returned.
2386 */
2387 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2388 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390 return 0xFE;
2391 }
2392
2393 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2394
2395
2396 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2397
2398 }
2399
2400
2401 else if (hp_int & RSEL) {
2402
2403 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2404
2405 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2406 {
2407 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2408 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002409 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 }
2411
2412 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2413 {
2414 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2415 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2416 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2417 }
2418
2419 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2420 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002421 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422 }
2423
James Bottomley 47b5d692005-04-24 02:38:05 -05002424 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2425 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426
2427 }
2428
2429
2430 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2431 {
2432
2433 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002434 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435
2436 }
2437
2438
2439 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2440 {
2441 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2442 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
2443 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002444 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445 }
2446 else
2447 {
2448 /* Harpoon problem some SCSI target device respond to selection
2449 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2450 to latch the correct Target ID into reg. x53.
2451 The work around require to correct this reg. But when write to this
2452 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2453 need to read this reg first then restore it later. After update to 0x53 */
2454
2455 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
2456 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
2457 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
2458 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
2459 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
2460 WR_HARPOON(ioport+hp_fifowrite, i);
2461 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2462 }
2463 }
2464
2465 else if (hp_int & XFER_CNT_0) {
2466
2467 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2468
James Bottomley 47b5d692005-04-24 02:38:05 -05002469 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470
2471 }
2472
2473
2474 else if (hp_int & BUS_FREE) {
2475
2476 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2477
2478 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2479
James Bottomley 47b5d692005-04-24 02:38:05 -05002480 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481 }
2482
James Bottomley 47b5d692005-04-24 02:38:05 -05002483 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484 }
2485
2486
2487 else if (hp_int & ITICKLE) {
2488
2489 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2490 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2491 }
2492
2493
2494
2495 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2496
2497
2498 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2499
2500
2501 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2502
James Bottomley 47b5d692005-04-24 02:38:05 -05002503 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 }
2505
2506 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2507 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002508 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509 }
2510
2511 break;
2512
2513 }
2514
2515 } /*end while */
2516
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518
2519 return(0);
2520}
2521
2522/*---------------------------------------------------------------------
2523 *
2524 * Function: Sccb_bad_isr
2525 *
2526 * Description: Some type of interrupt has occurred which is slightly
2527 * out of the ordinary. We will now decode it fully, in
2528 * this routine. This is broken up in an attempt to save
2529 * processing time.
2530 *
2531 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002532static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2533 PSCCBcard pCurrCard, USHORT p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534{
James Bottomley 47b5d692005-04-24 02:38:05 -05002535 UCHAR temp, ScamFlg;
2536 PSCCBMgr_tar_info currTar_Info;
2537 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002538
2539
2540 if (RD_HARPOON(p_port+hp_ext_status) &
2541 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2542 {
2543
2544 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2545 {
2546
James Bottomley 47b5d692005-04-24 02:38:05 -05002547 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 }
2549
2550 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2551
2552 {
2553 WR_HARPOON(p_port+hp_pci_stat_cfg,
2554 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2555
2556 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2557
2558 }
2559
2560 if (pCurrCard->currentSCCB != NULL)
2561 {
2562
2563 if (!pCurrCard->currentSCCB->HostStatus)
2564 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2565
James Bottomley 47b5d692005-04-24 02:38:05 -05002566 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
2568 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
2569 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2570 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
2571 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2572
2573 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2574 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002575 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 }
2577 }
2578 }
2579
2580
2581 else if (p_int & RESET)
2582 {
2583
2584 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2585 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2586 if (pCurrCard->currentSCCB != NULL) {
2587
2588 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2589
James Bottomley 47b5d692005-04-24 02:38:05 -05002590 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591 }
2592
2593
2594 DISABLE_AUTO(p_port);
2595
James Bottomley 47b5d692005-04-24 02:38:05 -05002596 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597
2598 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2599
2600 pCurrNvRam = pCurrCard->pNvRamInfo;
2601 if(pCurrNvRam){
2602 ScamFlg = pCurrNvRam->niScamConf;
2603 }
2604 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05002605 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 }
2607
James Bottomley 47b5d692005-04-24 02:38:05 -05002608 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
James Bottomley 47b5d692005-04-24 02:38:05 -05002610 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611
2612 return(0xFF);
2613 }
2614
2615
2616 else if (p_int & FIFO) {
2617
2618 WRW_HARPOON((p_port+hp_intstat), FIFO);
2619
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002621 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 }
2623
2624 else if (p_int & TIMEOUT)
2625 {
2626
2627 DISABLE_AUTO(p_port);
2628
2629 WRW_HARPOON((p_port+hp_intstat),
2630 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2631
2632 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2633
2634
James Bottomley 47b5d692005-04-24 02:38:05 -05002635 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2637 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002638 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002640 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641
2642
2643 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2644 {
2645 currTar_Info->TarSyncCtrl = 0;
2646 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2647 }
2648
2649 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2650 {
2651 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2652 }
2653
James Bottomley 47b5d692005-04-24 02:38:05 -05002654 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655
James Bottomley 47b5d692005-04-24 02:38:05 -05002656 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657
2658 }
2659
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 else if (p_int & SCAM_SEL)
2661 {
2662
James Bottomley 47b5d692005-04-24 02:38:05 -05002663 FPT_scarb(p_port,LEVEL2_TAR);
2664 FPT_scsel(p_port);
2665 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
James Bottomley 47b5d692005-04-24 02:38:05 -05002667 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668
2669 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2670 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671
2672 return(0x00);
2673}
2674
2675
2676/*---------------------------------------------------------------------
2677 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 * Function: SccbMgrTableInit
2679 *
2680 * Description: Initialize all Sccb manager data structures.
2681 *
2682 *---------------------------------------------------------------------*/
2683
James Bottomley 47b5d692005-04-24 02:38:05 -05002684static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685{
2686 UCHAR thisCard;
2687
2688 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2689 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002690 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691
James Bottomley 47b5d692005-04-24 02:38:05 -05002692 FPT_BL_Card[thisCard].ioPort = 0x00;
2693 FPT_BL_Card[thisCard].cardInfo = NULL;
2694 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2695 FPT_BL_Card[thisCard].ourId = 0x00;
2696 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 }
2698}
2699
2700
2701/*---------------------------------------------------------------------
2702 *
2703 * Function: SccbMgrTableInit
2704 *
2705 * Description: Initialize all Sccb manager data structures.
2706 *
2707 *---------------------------------------------------------------------*/
2708
James Bottomley 47b5d692005-04-24 02:38:05 -05002709static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710{
2711 UCHAR scsiID, qtag;
2712
2713 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2714 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002715 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 }
2717
2718 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2719 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002720 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2721 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2722 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 }
2724
2725 pCurrCard->scanIndex = 0x00;
2726 pCurrCard->currentSCCB = NULL;
2727 pCurrCard->globalFlags = 0x00;
2728 pCurrCard->cmdCounter = 0x00;
2729 pCurrCard->tagQ_Lst = 0x01;
2730 pCurrCard->discQCount = 0;
2731
2732
2733}
2734
2735
2736/*---------------------------------------------------------------------
2737 *
2738 * Function: SccbMgrTableInit
2739 *
2740 * Description: Initialize all Sccb manager data structures.
2741 *
2742 *---------------------------------------------------------------------*/
2743
James Bottomley 47b5d692005-04-24 02:38:05 -05002744static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745{
2746
2747 UCHAR lun, qtag;
2748 PSCCBMgr_tar_info currTar_Info;
2749
James Bottomley 47b5d692005-04-24 02:38:05 -05002750 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
2752 currTar_Info->TarSelQ_Cnt = 0;
2753 currTar_Info->TarSyncCtrl = 0;
2754
2755 currTar_Info->TarSelQ_Head = NULL;
2756 currTar_Info->TarSelQ_Tail = NULL;
2757 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002758 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759
2760
2761 for (lun = 0; lun < MAX_LUN; lun++)
2762 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002763 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 currTar_Info->LunDiscQ_Idx[lun] = 0;
2765 }
2766
2767 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2768 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002769 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002771 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002772 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002773 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2774 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775 }
2776 }
2777 }
2778}
2779
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
2781/*---------------------------------------------------------------------
2782 *
2783 * Function: sfetm
2784 *
2785 * Description: Read in a message byte from the SCSI bus, and check
2786 * for a parity error.
2787 *
2788 *---------------------------------------------------------------------*/
2789
James Bottomley 47b5d692005-04-24 02:38:05 -05002790static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791{
2792 UCHAR message;
2793 USHORT TimeOutLoop;
2794
2795 TimeOutLoop = 0;
2796 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2797 (TimeOutLoop++ < 20000) ){}
2798
2799
2800 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2801
2802 message = RD_HARPOON(port+hp_scsidata_0);
2803
2804 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2805
2806
2807 if (TimeOutLoop > 20000)
2808 message = 0x00; /* force message byte = 0 if Time Out on Req */
2809
2810 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2811 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2812 {
2813 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2814 WR_HARPOON(port+hp_xferstat, 0);
2815 WR_HARPOON(port+hp_fiforead, 0);
2816 WR_HARPOON(port+hp_fifowrite, 0);
2817 if (pCurrSCCB != NULL)
2818 {
2819 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2820 }
2821 message = 0x00;
2822 do
2823 {
2824 ACCEPT_MSG_ATN(port);
2825 TimeOutLoop = 0;
2826 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2827 (TimeOutLoop++ < 20000) ){}
2828 if (TimeOutLoop > 20000)
2829 {
2830 WRW_HARPOON((port+hp_intstat), PARITY);
2831 return(message);
2832 }
2833 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2834 {
2835 WRW_HARPOON((port+hp_intstat), PARITY);
2836 return(message);
2837 }
2838 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2839
2840 RD_HARPOON(port+hp_scsidata_0);
2841
2842 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2843
2844 }while(1);
2845
2846 }
2847 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2848 WR_HARPOON(port+hp_xferstat, 0);
2849 WR_HARPOON(port+hp_fiforead, 0);
2850 WR_HARPOON(port+hp_fifowrite, 0);
2851 return(message);
2852}
2853
2854
2855/*---------------------------------------------------------------------
2856 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002857 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 *
2859 * Description: Load up automation and select target device.
2860 *
2861 *---------------------------------------------------------------------*/
2862
James Bottomley 47b5d692005-04-24 02:38:05 -05002863static void FPT_ssel(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864{
2865
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 UCHAR auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 PSCCBcard CurrCard;
2870 PSCCB currSCCB;
2871 PSCCBMgr_tar_info currTar_Info;
2872 UCHAR lastTag, lun;
2873
James Bottomley 47b5d692005-04-24 02:38:05 -05002874 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 currSCCB = CurrCard->currentSCCB;
2876 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002877 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 lastTag = CurrCard->tagQ_Lst;
2879
2880 ARAM_ACCESS(port);
2881
2882
2883 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2884 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2885
2886 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2887 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2888
2889 lun = currSCCB->Lun;
2890 else
2891 lun = 0;
2892
2893
Linus Torvalds1da177e2005-04-16 15:20:36 -07002894 if (CurrCard->globalFlags & F_TAG_STARTED)
2895 {
2896 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2897 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002898 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2900 == TAG_Q_TRYING))
2901 {
2902
2903 if (currTar_Info->TarTagQ_Cnt !=0)
2904 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002905 currTar_Info->TarLUNBusy[lun] = 1;
2906 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 SGRAM_ACCESS(port);
2908 return;
2909 }
2910
2911 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002912 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 }
2914
2915 } /*End non-tagged */
2916
2917 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002918 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919 }
2920
2921 } /*!Use cmd Q Tagged */
2922
2923 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002924 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002926 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 SGRAM_ACCESS(port);
2928 return;
2929 }
2930
James Bottomley 47b5d692005-04-24 02:38:05 -05002931 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932
2933 } /*else use cmd Q tagged */
2934
2935 } /*if glob tagged started */
2936
2937 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002938 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 }
2940
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941
2942
2943 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2944 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2945 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2946 {
2947 if(CurrCard->discQCount >= QUEUE_DEPTH)
2948 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002949 currTar_Info->TarLUNBusy[lun] = 1;
2950 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951 SGRAM_ACCESS(port);
2952 return;
2953 }
2954 for (i = 1; i < QUEUE_DEPTH; i++)
2955 {
2956 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2957 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2958 {
2959 CurrCard->tagQ_Lst = lastTag;
2960 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2961 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2962 CurrCard->discQCount++;
2963 break;
2964 }
2965 }
2966 if(i == QUEUE_DEPTH)
2967 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002968 currTar_Info->TarLUNBusy[lun] = 1;
2969 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970 SGRAM_ACCESS(port);
2971 return;
2972 }
2973 }
2974
2975
2976
James Bottomley 47b5d692005-04-24 02:38:05 -05002977 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978
2979 WR_HARPOON(port+hp_select_id, target);
2980 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2981
2982 if (currSCCB->OperationCode == RESET_COMMAND) {
2983 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2984 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2985
2986 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2987
2988 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2989
2990 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002991 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2993
2994 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2995 {
2996 currTar_Info->TarSyncCtrl = 0;
2997 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2998 }
2999
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3001 {
3002 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3003 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004
James Bottomley 47b5d692005-04-24 02:38:05 -05003005 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
3006 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003007
3008 }
3009
3010 else if(currSCCB->Sccb_scsistat == ABORT_ST)
3011 {
3012 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
3013 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
3014
3015 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3016
3017 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
3018 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
3019 >> 6) | (UCHAR)0x20)));
3020 WRW_HARPOON((port+SYNC_MSGS+2),
3021 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
3022 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
3023
3024 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05003025 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026
3027 }
3028
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05003030 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031 currSCCB->Sccb_scsistat = SELECT_WN_ST;
3032 }
3033
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
3035 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05003036 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3038 }
3039
3040
3041 if (!auto_loaded)
3042 {
3043
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044 if (currSCCB->ControlByte & F_USE_CMD_Q)
3045 {
3046
3047 CurrCard->globalFlags |= F_TAG_STARTED;
3048
3049 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
3050 == TAG_Q_REJECT)
3051 {
3052 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3053
3054 /* Fix up the start instruction with a jump to
3055 Non-Tag-CMD handling */
3056 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
3057
3058 WRW_HARPOON((port+NON_TAG_ID_MSG),
3059 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
3060
3061 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3062
3063 /* Setup our STATE so we know what happend when
3064 the wheels fall off. */
3065 currSCCB->Sccb_scsistat = SELECT_ST;
3066
James Bottomley 47b5d692005-04-24 02:38:05 -05003067 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 }
3069
3070 else
3071 {
3072 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
3073
3074 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
3075 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
3076 >> 6) | (UCHAR)0x20)));
3077
3078 for (i = 1; i < QUEUE_DEPTH; i++)
3079 {
3080 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
3081 if (CurrCard->discQ_Tbl[lastTag] == NULL)
3082 {
3083 WRW_HARPOON((port+ID_MSG_STRT+6),
3084 (MPM_OP+AMSG_OUT+lastTag));
3085 CurrCard->tagQ_Lst = lastTag;
3086 currSCCB->Sccb_tag = lastTag;
3087 CurrCard->discQ_Tbl[lastTag] = currSCCB;
3088 CurrCard->discQCount++;
3089 break;
3090 }
3091 }
3092
3093
3094 if ( i == QUEUE_DEPTH )
3095 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003096 currTar_Info->TarLUNBusy[lun] = 1;
3097 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 SGRAM_ACCESS(port);
3099 return;
3100 }
3101
3102 currSCCB->Sccb_scsistat = SELECT_Q_ST;
3103
3104 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3105 }
3106 }
3107
3108 else
3109 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110
3111 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
3112
3113 WRW_HARPOON((port+NON_TAG_ID_MSG),
3114 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
3115
3116 currSCCB->Sccb_scsistat = SELECT_ST;
3117
3118 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120
3121
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 theCCB = (UCHAR *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123
3124 cdb_reg = port + CMD_STRT;
3125
3126 for (i=0; i < currSCCB->CdbLength; i++)
3127 {
3128 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
3129 cdb_reg +=2;
3130 theCCB++;
3131 }
3132
3133 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
3134 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
3135
3136 } /* auto_loaded */
3137
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
3139 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140
3141 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
3142
3143 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
3144
3145
3146 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
3147 {
3148 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
3149 }
3150 else
3151 {
3152
3153/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
3154 auto_loaded |= AUTO_IMMED; */
3155 auto_loaded = AUTO_IMMED;
3156
3157 DISABLE_AUTO(port);
3158
3159 WR_HARPOON(port+hp_autostart_3, auto_loaded);
3160 }
3161
3162 SGRAM_ACCESS(port);
3163}
3164
3165
3166/*---------------------------------------------------------------------
3167 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003168 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169 *
3170 * Description: Hookup the correct CCB and handle the incoming messages.
3171 *
3172 *---------------------------------------------------------------------*/
3173
James Bottomley 47b5d692005-04-24 02:38:05 -05003174static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175{
3176
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178
3179
3180 PSCCBMgr_tar_info currTar_Info;
3181 PSCCB currSCCB;
3182
3183
3184
3185
3186 if(pCurrCard->currentSCCB != NULL)
3187 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003188 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189 DISABLE_AUTO(port);
3190
3191
3192 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
3193
3194
3195 currSCCB = pCurrCard->currentSCCB;
3196 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
3197 {
3198 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3199 currSCCB->Sccb_scsistat = BUS_FREE_ST;
3200 }
3201 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
3202 {
3203 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3204 currSCCB->Sccb_scsistat = BUS_FREE_ST;
3205 }
3206 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3207 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3208 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003209 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 if(currSCCB->Sccb_scsistat != ABORT_ST)
3211 {
3212 pCurrCard->discQCount--;
3213 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
3214 = NULL;
3215 }
3216 }
3217 else
3218 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003219 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003220 if(currSCCB->Sccb_tag)
3221 {
3222 if(currSCCB->Sccb_scsistat != ABORT_ST)
3223 {
3224 pCurrCard->discQCount--;
3225 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3226 }
3227 }else
3228 {
3229 if(currSCCB->Sccb_scsistat != ABORT_ST)
3230 {
3231 pCurrCard->discQCount--;
3232 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
3233 }
3234 }
3235 }
3236
James Bottomley 47b5d692005-04-24 02:38:05 -05003237 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003238 }
3239
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241
3242
3243 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05003244 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003245
3246
3247 msgRetryCount = 0;
3248 do
3249 {
3250
James Bottomley 47b5d692005-04-24 02:38:05 -05003251 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252 tag = 0;
3253
3254
3255 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3256 {
3257 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3258 {
3259
3260 WRW_HARPOON((port+hp_intstat), PHASE);
3261 return;
3262 }
3263 }
3264
3265 WRW_HARPOON((port+hp_intstat), PHASE);
3266 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
3267 {
3268
James Bottomley 47b5d692005-04-24 02:38:05 -05003269 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003270 if (message)
3271 {
3272
3273 if (message <= (0x80 | LUN_MASK))
3274 {
3275 lun = message & (UCHAR)LUN_MASK;
3276
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
3278 {
3279 if (currTar_Info->TarTagQ_Cnt != 0)
3280 {
3281
3282 if (!(currTar_Info->TarLUN_CA))
3283 {
3284 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
3285
3286
James Bottomley 47b5d692005-04-24 02:38:05 -05003287 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288 if (message)
3289 {
3290 ACCEPT_MSG(port);
3291 }
3292
3293 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003294 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295
James Bottomley 47b5d692005-04-24 02:38:05 -05003296 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003297 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003298 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299
3300 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05003301 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302 }
3303
3304 } /*C.A. exists! */
3305
3306 } /*End Q cnt != 0 */
3307
3308 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309
3310 } /*End valid ID message. */
3311
3312 else
3313 {
3314
3315 ACCEPT_MSG_ATN(port);
3316 }
3317
3318 } /* End good id message. */
3319
3320 else
3321 {
3322
James Bottomley 47b5d692005-04-24 02:38:05 -05003323 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003324 }
3325 }
3326 else
3327 {
3328 ACCEPT_MSG_ATN(port);
3329
3330 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3331 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3332 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3333
3334 return;
3335 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336
James Bottomley 47b5d692005-04-24 02:38:05 -05003337 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338 {
3339 msgRetryCount++;
3340 if(msgRetryCount == 1)
3341 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003342 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003343 }
3344 else
3345 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003346 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347
James Bottomley 47b5d692005-04-24 02:38:05 -05003348 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349
James Bottomley 47b5d692005-04-24 02:38:05 -05003350 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003351 {
3352
James Bottomley 47b5d692005-04-24 02:38:05 -05003353 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354
3355 }
3356
James Bottomley 47b5d692005-04-24 02:38:05 -05003357 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 {
3359
James Bottomley 47b5d692005-04-24 02:38:05 -05003360 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003361 }
3362
3363
James Bottomley 47b5d692005-04-24 02:38:05 -05003364 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3365 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003366 return;
3367 }
3368 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003369 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003370
3371
3372
3373 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3374 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3375 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003376 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3378 if(pCurrCard->currentSCCB != NULL)
3379 {
3380 ACCEPT_MSG(port);
3381 }
3382 else
3383 {
3384 ACCEPT_MSG_ATN(port);
3385 }
3386 }
3387 else
3388 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003389 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390
3391
3392 if (tag)
3393 {
3394 if (pCurrCard->discQ_Tbl[tag] != NULL)
3395 {
3396 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3397 currTar_Info->TarTagQ_Cnt--;
3398 ACCEPT_MSG(port);
3399 }
3400 else
3401 {
3402 ACCEPT_MSG_ATN(port);
3403 }
3404 }else
3405 {
3406 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3407 if(pCurrCard->currentSCCB != NULL)
3408 {
3409 ACCEPT_MSG(port);
3410 }
3411 else
3412 {
3413 ACCEPT_MSG_ATN(port);
3414 }
3415 }
3416 }
3417
3418 if(pCurrCard->currentSCCB != NULL)
3419 {
3420 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3421 {
3422 /* During Abort Tag command, the target could have got re-selected
3423 and completed the command. Check the select Q and remove the CCB
3424 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003425 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 }
3427 }
3428
3429
3430 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3431 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3432 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3433}
3434
James Bottomley 47b5d692005-04-24 02:38:05 -05003435static void FPT_SendMsg(ULONG port, UCHAR message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003436{
3437 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3438 {
3439 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3440 {
3441
3442 WRW_HARPOON((port+hp_intstat), PHASE);
3443 return;
3444 }
3445 }
3446
3447 WRW_HARPOON((port+hp_intstat), PHASE);
3448 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3449 {
3450 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3451
3452
3453 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3454
3455 WR_HARPOON(port+hp_scsidata_0,message);
3456
3457 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3458
3459 ACCEPT_MSG(port);
3460
3461 WR_HARPOON(port+hp_portctrl_0, 0x00);
3462
3463 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3464 (message == SMABORT_TAG) )
3465 {
3466 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3467
3468 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3469 {
3470 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3471 }
3472 }
3473 }
3474}
3475
3476/*---------------------------------------------------------------------
3477 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003478 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479 *
3480 * Description: Determine the proper responce to the message from the
3481 * target device.
3482 *
3483 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003484static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485{
3486 PSCCB currSCCB;
3487 PSCCBcard CurrCard;
3488 PSCCBMgr_tar_info currTar_Info;
3489
James Bottomley 47b5d692005-04-24 02:38:05 -05003490 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003491 currSCCB = CurrCard->currentSCCB;
3492
James Bottomley 47b5d692005-04-24 02:38:05 -05003493 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003494
3495 if (message == SMREST_DATA_PTR)
3496 {
3497 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3498 {
3499 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3500
James Bottomley 47b5d692005-04-24 02:38:05 -05003501 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003502 }
3503
3504 ACCEPT_MSG(port);
3505 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3506 }
3507
3508 else if (message == SMCMD_COMP)
3509 {
3510
3511
3512 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3513 {
3514 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
3515 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
3516 }
3517
3518 ACCEPT_MSG(port);
3519
3520 }
3521
3522 else if ((message == SMNO_OP) || (message >= SMIDENT)
3523 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3524 {
3525
3526 ACCEPT_MSG(port);
3527 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3528 }
3529
3530 else if (message == SMREJECT)
3531 {
3532
3533 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3534 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3535 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3536 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3537
3538 {
3539 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3540
3541 ACCEPT_MSG(port);
3542
3543
3544 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3545 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3546
3547 if(currSCCB->Lun == 0x00)
3548 {
3549 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3550 {
3551
3552 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3553
3554 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3555 }
3556
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3558 {
3559
3560
3561 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3562 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3563
3564 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3565
3566 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003567
3568 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3569 {
3570 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3571 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3572
3573
3574 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3575 CurrCard->discQCount--;
3576 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3577 currSCCB->Sccb_tag = 0x00;
3578
3579 }
3580 }
3581
3582 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3583 {
3584
3585
3586 if(currSCCB->Lun == 0x00)
3587 {
3588 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3589 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3590 }
3591 }
3592
3593 else
3594 {
3595
3596 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3597 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003598 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003600 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601
3602
3603 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
3604
3605 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3606
3607 }
3608 }
3609
3610 else
3611 {
3612 ACCEPT_MSG(port);
3613
3614 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3615 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3616
3617 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3618 {
3619 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3620 }
3621 }
3622 }
3623
3624 else if (message == SMEXT)
3625 {
3626
3627 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003628 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003629 }
3630
3631 else if (message == SMIGNORWR)
3632 {
3633
3634 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3635
James Bottomley 47b5d692005-04-24 02:38:05 -05003636 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637
3638 if(currSCCB->Sccb_scsimsg != SMPARITY)
3639 ACCEPT_MSG(port);
3640 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3641 }
3642
3643
3644 else
3645 {
3646
3647 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3648 currSCCB->Sccb_scsimsg = SMREJECT;
3649
3650 ACCEPT_MSG_ATN(port);
3651 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3652 }
3653}
3654
3655
3656/*---------------------------------------------------------------------
3657 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003658 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003659 *
3660 * Description: Decide what to do with the extended message.
3661 *
3662 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003663static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664{
3665 UCHAR length,message;
3666
James Bottomley 47b5d692005-04-24 02:38:05 -05003667 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668 if (length)
3669 {
3670
3671 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003672 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003673 if (message)
3674 {
3675
3676 if (message == SMSYNC)
3677 {
3678
3679 if (length == 0x03)
3680 {
3681
3682 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003683 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 }
3685 else
3686 {
3687
3688 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3689 ACCEPT_MSG_ATN(port);
3690 }
3691 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692 else if (message == SMWDTR)
3693 {
3694
3695 if (length == 0x02)
3696 {
3697
3698 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003699 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003700 }
3701 else
3702 {
3703
3704 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3705 ACCEPT_MSG_ATN(port);
3706
3707 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3708 }
3709 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710 else
3711 {
3712
3713 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3714 ACCEPT_MSG_ATN(port);
3715
3716 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3717 }
3718 }
3719 else
3720 {
3721 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3722 ACCEPT_MSG(port);
3723 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3724 }
3725 }else
3726 {
3727 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3728 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3729 }
3730}
3731
3732
3733/*---------------------------------------------------------------------
3734 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003735 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736 *
3737 * Description: Read in a message byte from the SCSI bus, and check
3738 * for a parity error.
3739 *
3740 *---------------------------------------------------------------------*/
3741
James Bottomley 47b5d692005-04-24 02:38:05 -05003742static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003743{
3744 PSCCB currSCCB;
3745 PSCCBMgr_tar_info currTar_Info;
3746
James Bottomley 47b5d692005-04-24 02:38:05 -05003747 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3748 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749
3750 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3751
3752
3753 WRW_HARPOON((port+ID_MSG_STRT),
3754 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3755
3756 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3757
3758 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3759 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3760 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3761
3762
3763 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3764
3765 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3766
3767 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3768
3769 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3770
3771 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3772
3773 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3774
3775 else
3776 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3777
3778
3779 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3780 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3781 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3782
3783
James Bottomley 47b5d692005-04-24 02:38:05 -05003784 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003785 {
3786 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3787 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3788 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
3789 }
3790 else
3791 {
3792 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3793 }
3794
3795
James Bottomley 47b5d692005-04-24 02:38:05 -05003796 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003797 }
3798
3799 else {
3800
3801 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3802 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003803 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003804 }
3805}
3806
3807
3808
3809/*---------------------------------------------------------------------
3810 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003811 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003812 *
3813 * Description: The has sent us a Sync Nego message so handle it as
3814 * necessary.
3815 *
3816 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003817static void FPT_stsyncn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003818{
3819 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3820 PSCCB currSCCB;
3821 PSCCBMgr_tar_info currTar_Info;
3822
James Bottomley 47b5d692005-04-24 02:38:05 -05003823 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3824 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825
James Bottomley 47b5d692005-04-24 02:38:05 -05003826 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827
3828 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3829 {
3830 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3831 return;
3832 }
3833
3834 ACCEPT_MSG(port);
3835
3836
James Bottomley 47b5d692005-04-24 02:38:05 -05003837 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003838
3839 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3840 {
3841 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3842 return;
3843 }
3844
3845 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3846
3847 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3848
3849 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3850
3851 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3852
3853 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3854
3855 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3856 else
3857
3858 our_sync_msg = 0; /* Message = Async */
3859
3860 if (sync_msg < our_sync_msg) {
3861 sync_msg = our_sync_msg; /*if faster, then set to max. */
3862 }
3863
3864 if (offset == ASYNC)
3865 sync_msg = ASYNC;
3866
3867 if (offset > MAX_OFFSET)
3868 offset = MAX_OFFSET;
3869
3870 sync_reg = 0x00;
3871
3872 if (sync_msg > 12)
3873
3874 sync_reg = 0x20; /* Use 10MB/s */
3875
3876 if (sync_msg > 25)
3877
3878 sync_reg = 0x40; /* Use 6.6MB/s */
3879
3880 if (sync_msg > 38)
3881
3882 sync_reg = 0x60; /* Use 5MB/s */
3883
3884 if (sync_msg > 50)
3885
3886 sync_reg = 0x80; /* Use 4MB/s */
3887
3888 if (sync_msg > 62)
3889
3890 sync_reg = 0xA0; /* Use 3.33MB/s */
3891
3892 if (sync_msg > 75)
3893
3894 sync_reg = 0xC0; /* Use 2.85MB/s */
3895
3896 if (sync_msg > 87)
3897
3898 sync_reg = 0xE0; /* Use 2.5MB/s */
3899
3900 if (sync_msg > 100) {
3901
3902 sync_reg = 0x00; /* Use ASYNC */
3903 offset = 0x00;
3904 }
3905
3906
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 if (currTar_Info->TarStatus & WIDE_ENABLED)
3908
3909 sync_reg |= offset;
3910
3911 else
3912
3913 sync_reg |= (offset | NARROW_SCSI);
3914
James Bottomley 47b5d692005-04-24 02:38:05 -05003915 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916
3917
3918 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3919
3920
3921 ACCEPT_MSG(port);
3922
3923 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3924 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3925
3926 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3927 }
3928
3929 else {
3930
3931
3932 ACCEPT_MSG_ATN(port);
3933
James Bottomley 47b5d692005-04-24 02:38:05 -05003934 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003935
3936 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3937 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3938 }
3939}
3940
3941
3942/*---------------------------------------------------------------------
3943 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003944 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945 *
3946 * Description: Answer the targets sync message.
3947 *
3948 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003949static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950{
3951 ARAM_ACCESS(port);
3952 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3953 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3954 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3955 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3956 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3957 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3958 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3959 SGRAM_ACCESS(port);
3960
3961 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3962 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3963
3964 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3965
3966 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3967}
3968
3969
3970
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971/*---------------------------------------------------------------------
3972 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003973 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974 *
3975 * Description: Read in a message byte from the SCSI bus, and check
3976 * for a parity error.
3977 *
3978 *---------------------------------------------------------------------*/
3979
James Bottomley 47b5d692005-04-24 02:38:05 -05003980static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003981{
3982 PSCCB currSCCB;
3983 PSCCBMgr_tar_info currTar_Info;
3984
James Bottomley 47b5d692005-04-24 02:38:05 -05003985 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3986 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003987
3988 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3989
3990
3991 WRW_HARPOON((port+ID_MSG_STRT),
3992 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3993
3994 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3995
3996 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3997 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3998 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3999 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
4000 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
4001 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
4002
4003 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
4004
4005
4006 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
4007 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
4008
James Bottomley 47b5d692005-04-24 02:38:05 -05004009 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010 }
4011
4012 else {
4013
4014 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
4015 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
4016
4017 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05004018 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004019 }
4020}
4021
4022
4023
4024/*---------------------------------------------------------------------
4025 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004026 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07004027 *
4028 * Description: The has sent us a Wide Nego message so handle it as
4029 * necessary.
4030 *
4031 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004032static void FPT_stwidn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004033{
4034 UCHAR width;
4035 PSCCB currSCCB;
4036 PSCCBMgr_tar_info currTar_Info;
4037
James Bottomley 47b5d692005-04-24 02:38:05 -05004038 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4039 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004040
James Bottomley 47b5d692005-04-24 02:38:05 -05004041 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004042
4043 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
4044 {
4045 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4046 return;
4047 }
4048
4049
4050 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
4051 width = 0;
4052
4053 if (width) {
4054 currTar_Info->TarStatus |= WIDE_ENABLED;
4055 width = 0;
4056 }
4057 else {
4058 width = NARROW_SCSI;
4059 currTar_Info->TarStatus &= ~WIDE_ENABLED;
4060 }
4061
4062
James Bottomley 47b5d692005-04-24 02:38:05 -05004063 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004064
4065
4066 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
4067 {
4068
4069
4070
4071 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
4072
4073 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
4074 {
4075 ACCEPT_MSG_ATN(port);
4076 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05004077 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004078 currSCCB->Sccb_scsistat = SELECT_SN_ST;
4079 SGRAM_ACCESS(port);
4080 }
4081 else
4082 {
4083 ACCEPT_MSG(port);
4084 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4085 }
4086 }
4087
4088 else {
4089
4090
4091 ACCEPT_MSG_ATN(port);
4092
4093 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
4094 width = SM16BIT;
4095 else
4096 width = SM8BIT;
4097
James Bottomley 47b5d692005-04-24 02:38:05 -05004098 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004099
4100 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
4101 }
4102}
4103
4104
4105/*---------------------------------------------------------------------
4106 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004107 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07004108 *
4109 * Description: Answer the targets Wide nego message.
4110 *
4111 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004112static void FPT_siwidr(ULONG port, UCHAR width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113{
4114 ARAM_ACCESS(port);
4115 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
4116 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
4117 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
4118 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
4119 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
4120 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
4121 SGRAM_ACCESS(port);
4122
4123 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4124 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
4125
4126 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
4127
4128 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
4129}
4130
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131
4132
4133/*---------------------------------------------------------------------
4134 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004135 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 *
4137 * Description: Write the desired value to the Sync Register for the
4138 * ID specified.
4139 *
4140 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004141static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
4142 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004143{
4144 UCHAR index;
4145
4146 index = p_id;
4147
4148 switch (index) {
4149
4150 case 0:
4151 index = 12; /* hp_synctarg_0 */
4152 break;
4153 case 1:
4154 index = 13; /* hp_synctarg_1 */
4155 break;
4156 case 2:
4157 index = 14; /* hp_synctarg_2 */
4158 break;
4159 case 3:
4160 index = 15; /* hp_synctarg_3 */
4161 break;
4162 case 4:
4163 index = 8; /* hp_synctarg_4 */
4164 break;
4165 case 5:
4166 index = 9; /* hp_synctarg_5 */
4167 break;
4168 case 6:
4169 index = 10; /* hp_synctarg_6 */
4170 break;
4171 case 7:
4172 index = 11; /* hp_synctarg_7 */
4173 break;
4174 case 8:
4175 index = 4; /* hp_synctarg_8 */
4176 break;
4177 case 9:
4178 index = 5; /* hp_synctarg_9 */
4179 break;
4180 case 10:
4181 index = 6; /* hp_synctarg_10 */
4182 break;
4183 case 11:
4184 index = 7; /* hp_synctarg_11 */
4185 break;
4186 case 12:
4187 index = 0; /* hp_synctarg_12 */
4188 break;
4189 case 13:
4190 index = 1; /* hp_synctarg_13 */
4191 break;
4192 case 14:
4193 index = 2; /* hp_synctarg_14 */
4194 break;
4195 case 15:
4196 index = 3; /* hp_synctarg_15 */
4197
4198 }
4199
4200 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
4201
4202 currTar_Info->TarSyncCtrl = p_sync_value;
4203}
4204
4205
4206/*---------------------------------------------------------------------
4207 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004208 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209 *
4210 * Description: Reset the desired card's SCSI bus.
4211 *
4212 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004213static void FPT_sresb(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004214{
4215 UCHAR scsiID, i;
4216
4217 PSCCBMgr_tar_info currTar_Info;
4218
4219 WR_HARPOON(port+hp_page_ctrl,
4220 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
4221 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
4222
4223 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
4224
4225 scsiID = RD_HARPOON(port+hp_seltimeout);
4226 WR_HARPOON(port+hp_seltimeout,TO_5ms);
4227 WRW_HARPOON((port+hp_intstat), TIMEOUT);
4228
4229 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
4230
4231 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
4232
4233 WR_HARPOON(port+hp_seltimeout,scsiID);
4234
4235 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
4236
James Bottomley 47b5d692005-04-24 02:38:05 -05004237 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238
4239 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
4240
4241 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
4242
4243 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
4244 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004245 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
4247 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
4248 {
4249 currTar_Info->TarSyncCtrl = 0;
4250 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
4251 }
4252
4253 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
4254 {
4255 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
4256 }
4257
James Bottomley 47b5d692005-04-24 02:38:05 -05004258 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259
James Bottomley 47b5d692005-04-24 02:38:05 -05004260 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261 }
4262
James Bottomley 47b5d692005-04-24 02:38:05 -05004263 FPT_BL_Card[p_card].scanIndex = 0x00;
4264 FPT_BL_Card[p_card].currentSCCB = NULL;
4265 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05004267 FPT_BL_Card[p_card].cmdCounter = 0x00;
4268 FPT_BL_Card[p_card].discQCount = 0x00;
4269 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004270
4271 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05004272 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004273
4274 WR_HARPOON(port+hp_page_ctrl,
4275 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
4276
4277}
4278
4279/*---------------------------------------------------------------------
4280 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004281 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282 *
4283 * Description: Setup for the Auto Sense command.
4284 *
4285 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004286static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004287{
4288 UCHAR i;
4289 PSCCB currSCCB;
4290
4291 currSCCB = pCurrCard->currentSCCB;
4292
4293
4294 currSCCB->Save_CdbLen = currSCCB->CdbLength;
4295
4296 for (i = 0; i < 6; i++) {
4297
4298 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
4299 }
4300
4301 currSCCB->CdbLength = SIX_BYTE_CMD;
4302 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
4303 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
4304 currSCCB->Cdb[2] = 0x00;
4305 currSCCB->Cdb[3] = 0x00;
4306 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
4307 currSCCB->Cdb[5] = 0x00;
4308
4309 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
4310
4311 currSCCB->Sccb_ATC = 0x00;
4312
4313 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
4314
4315 currSCCB->Sccb_XferState &= ~F_SG_XFER;
4316
4317 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
4318
4319 currSCCB->ControlByte = 0x00;
4320
4321 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
4322}
4323
4324
4325
4326/*---------------------------------------------------------------------
4327 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004328 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329 *
4330 * Description: Transfer data into the bit bucket until the device
4331 * decides to switch phase.
4332 *
4333 *---------------------------------------------------------------------*/
4334
James Bottomley 47b5d692005-04-24 02:38:05 -05004335static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004336{
4337 UCHAR curr_phz;
4338
4339
4340 DISABLE_AUTO(p_port);
4341
James Bottomley 47b5d692005-04-24 02:38:05 -05004342 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004343
James Bottomley 47b5d692005-04-24 02:38:05 -05004344 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004345
4346 }
4347
4348 /* If the Automation handled the end of the transfer then do not
4349 match the phase or we will get out of sync with the ISR. */
4350
4351 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
4352 return;
4353
4354 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
4355
4356 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
4357
4358 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4359
4360
4361 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4362
4363 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4364 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
4365 {
4366 if (curr_phz & (UCHAR)SCSI_IOBIT)
4367 {
4368 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4369
4370 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4371 {
4372 RD_HARPOON(p_port+hp_fifodata_0);
4373 }
4374 }
4375 else
4376 {
4377 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4378 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4379 {
4380 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4381 }
4382 }
4383 } /* End of While loop for padding data I/O phase */
4384
4385 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4386 {
4387 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4388 break;
4389 }
4390
4391 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4392 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4393 {
4394 RD_HARPOON(p_port+hp_fifodata_0);
4395 }
4396
4397 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4398 {
4399 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4400 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4401
4402 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4403 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4404 }
4405}
4406
4407
4408/*---------------------------------------------------------------------
4409 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004410 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004411 *
4412 * Description: Make sure data has been flushed from both FIFOs and abort
4413 * the operations if necessary.
4414 *
4415 *---------------------------------------------------------------------*/
4416
James Bottomley 47b5d692005-04-24 02:38:05 -05004417static void FPT_schkdd(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004418{
4419 USHORT TimeOutLoop;
4420 UCHAR sPhase;
4421
4422 PSCCB currSCCB;
4423
James Bottomley 47b5d692005-04-24 02:38:05 -05004424 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004425
4426
4427 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4428 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4429 return;
4430 }
4431
4432
4433
4434 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4435 {
4436
4437 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4438
4439 currSCCB->Sccb_XferCnt = 1;
4440
4441 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4442 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4443 WR_HARPOON(port+hp_xferstat, 0x00);
4444 }
4445
4446 else
4447 {
4448
4449 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4450
4451 currSCCB->Sccb_XferCnt = 0;
4452 }
4453
4454 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4455 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4456
4457 currSCCB->HostStatus = SCCB_PARITY_ERR;
4458 WRW_HARPOON((port+hp_intstat), PARITY);
4459 }
4460
4461
James Bottomley 47b5d692005-04-24 02:38:05 -05004462 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463
4464
4465 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4466
4467 TimeOutLoop = 0;
4468
4469 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4470 {
4471 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4472 return;
4473 }
4474 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
4475 break;
4476 }
4477 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4478 return;
4479 }
4480 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4481 break;
4482 }
4483
4484 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4485 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4486 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
4487 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4488 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4489 {
4490
4491 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4492
4493 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4494 {
4495 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004496 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004497 }
4498
4499 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004500 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004501 }
4502 }
4503 else
4504 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004505 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004506 if (!(RDW_HARPOON((port+hp_intstat)) &
4507 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4508 {
4509 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004510 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004511 }
4512 }
4513
4514 }
4515
4516 else {
4517 WR_HARPOON(port+hp_portctrl_0, 0x00);
4518 }
4519}
4520
4521
4522/*---------------------------------------------------------------------
4523 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004524 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525 *
4526 * Description: Setup SCCB manager fields in this SCCB.
4527 *
4528 *---------------------------------------------------------------------*/
4529
James Bottomley 47b5d692005-04-24 02:38:05 -05004530static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004531{
4532 PSCCBMgr_tar_info currTar_Info;
4533
4534 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4535 {
4536 return;
4537 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004538 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539
4540 p_sccb->Sccb_XferState = 0x00;
4541 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4542
4543 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4544 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4545
4546 p_sccb->Sccb_SGoffset = 0;
4547 p_sccb->Sccb_XferState = F_SG_XFER;
4548 p_sccb->Sccb_XferCnt = 0x00;
4549 }
4550
4551 if (p_sccb->DataLength == 0x00)
4552
4553 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4554
4555 if (p_sccb->ControlByte & F_USE_CMD_Q)
4556 {
4557 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4558 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4559
4560 else
4561 currTar_Info->TarStatus |= TAG_Q_TRYING;
4562 }
4563
4564/* For !single SCSI device in system & device allow Disconnect
4565 or command is tag_q type then send Cmd with Disconnect Enable
4566 else send Cmd with Disconnect Disable */
4567
4568/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004569 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004570 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4571 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4572*/
4573 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4574 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4575 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4576 }
4577
4578 else {
4579
4580 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
4581 }
4582
4583 p_sccb->HostStatus = 0x00;
4584 p_sccb->TargetStatus = 0x00;
4585 p_sccb->Sccb_tag = 0x00;
4586 p_sccb->Sccb_MGRFlags = 0x00;
4587 p_sccb->Sccb_sgseg = 0x00;
4588 p_sccb->Sccb_ATC = 0x00;
4589 p_sccb->Sccb_savedATC = 0x00;
4590/*
4591 p_sccb->SccbVirtDataPtr = 0x00;
4592 p_sccb->Sccb_forwardlink = NULL;
4593 p_sccb->Sccb_backlink = NULL;
4594 */
4595 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4596 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4597 p_sccb->Sccb_scsimsg = SMNO_OP;
4598
4599}
4600
4601
Linus Torvalds1da177e2005-04-16 15:20:36 -07004602/*---------------------------------------------------------------------
4603 *
4604 * Function: Phase Decode
4605 *
4606 * Description: Determine the phase and call the appropriate function.
4607 *
4608 *---------------------------------------------------------------------*/
4609
James Bottomley 47b5d692005-04-24 02:38:05 -05004610static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611{
4612 unsigned char phase_ref;
James Bottomley 47b5d692005-04-24 02:38:05 -05004613 void (*phase) (ULONG, UCHAR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004614
4615
4616 DISABLE_AUTO(p_port);
4617
4618 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4619
James Bottomley 47b5d692005-04-24 02:38:05 -05004620 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004621
4622 (*phase)(p_port, p_card); /* Call the correct phase func */
4623}
4624
4625
4626
4627/*---------------------------------------------------------------------
4628 *
4629 * Function: Data Out Phase
4630 *
4631 * Description: Start up both the BusMaster and Xbow.
4632 *
4633 *---------------------------------------------------------------------*/
4634
James Bottomley 47b5d692005-04-24 02:38:05 -05004635static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004636{
4637
4638 PSCCB currSCCB;
4639
James Bottomley 47b5d692005-04-24 02:38:05 -05004640 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004641 if (currSCCB == NULL)
4642 {
4643 return; /* Exit if No SCCB record */
4644 }
4645
4646 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4647 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4648
4649 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4650
4651 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4652
4653 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4654
James Bottomley 47b5d692005-04-24 02:38:05 -05004655 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004656
4657 if (currSCCB->Sccb_XferCnt == 0) {
4658
4659
4660 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4661 (currSCCB->HostStatus == SCCB_COMPLETE))
4662 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4663
James Bottomley 47b5d692005-04-24 02:38:05 -05004664 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004665 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004666 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004667 }
4668}
4669
4670
4671/*---------------------------------------------------------------------
4672 *
4673 * Function: Data In Phase
4674 *
4675 * Description: Startup the BusMaster and the XBOW.
4676 *
4677 *---------------------------------------------------------------------*/
4678
James Bottomley 47b5d692005-04-24 02:38:05 -05004679static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004680{
4681
4682 PSCCB currSCCB;
4683
James Bottomley 47b5d692005-04-24 02:38:05 -05004684 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004685
4686 if (currSCCB == NULL)
4687 {
4688 return; /* Exit if No SCCB record */
4689 }
4690
4691
4692 currSCCB->Sccb_scsistat = DATA_IN_ST;
4693 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4694 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4695
4696 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4697
4698 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4699
4700 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4701
James Bottomley 47b5d692005-04-24 02:38:05 -05004702 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004703
4704 if (currSCCB->Sccb_XferCnt == 0) {
4705
4706
4707 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4708 (currSCCB->HostStatus == SCCB_COMPLETE))
4709 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4710
James Bottomley 47b5d692005-04-24 02:38:05 -05004711 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004712 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004713 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004714
4715 }
4716}
4717
4718/*---------------------------------------------------------------------
4719 *
4720 * Function: Command Phase
4721 *
4722 * Description: Load the CDB into the automation and start it up.
4723 *
4724 *---------------------------------------------------------------------*/
4725
James Bottomley 47b5d692005-04-24 02:38:05 -05004726static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004727{
4728 PSCCB currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004729 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004730 UCHAR i;
4731
James Bottomley 47b5d692005-04-24 02:38:05 -05004732 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004733
4734 if (currSCCB->OperationCode == RESET_COMMAND) {
4735
4736 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4737 currSCCB->CdbLength = SIX_BYTE_CMD;
4738 }
4739
4740 WR_HARPOON(p_port+hp_scsisig, 0x00);
4741
4742 ARAM_ACCESS(p_port);
4743
4744
4745 cdb_reg = p_port + CMD_STRT;
4746
4747 for (i=0; i < currSCCB->CdbLength; i++) {
4748
4749 if (currSCCB->OperationCode == RESET_COMMAND)
4750
4751 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4752
4753 else
4754 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4755 cdb_reg +=2;
4756 }
4757
4758 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4759 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4760
4761 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4762
4763 currSCCB->Sccb_scsistat = COMMAND_ST;
4764
4765 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4766 SGRAM_ACCESS(p_port);
4767}
4768
4769
4770/*---------------------------------------------------------------------
4771 *
4772 * Function: Status phase
4773 *
4774 * Description: Bring in the status and command complete message bytes
4775 *
4776 *---------------------------------------------------------------------*/
4777
James Bottomley 47b5d692005-04-24 02:38:05 -05004778static void FPT_phaseStatus(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004779{
4780 /* Start-up the automation to finish off this command and let the
4781 isr handle the interrupt for command complete when it comes in.
4782 We could wait here for the interrupt to be generated?
4783 */
4784
4785 WR_HARPOON(port+hp_scsisig, 0x00);
4786
4787 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4788}
4789
4790
4791/*---------------------------------------------------------------------
4792 *
4793 * Function: Phase Message Out
4794 *
4795 * Description: Send out our message (if we have one) and handle whatever
4796 * else is involed.
4797 *
4798 *---------------------------------------------------------------------*/
4799
James Bottomley 47b5d692005-04-24 02:38:05 -05004800static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004801{
4802 UCHAR message,scsiID;
4803 PSCCB currSCCB;
4804 PSCCBMgr_tar_info currTar_Info;
4805
James Bottomley 47b5d692005-04-24 02:38:05 -05004806 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004807
4808 if (currSCCB != NULL) {
4809
4810 message = currSCCB->Sccb_scsimsg;
4811 scsiID = currSCCB->TargID;
4812
4813 if (message == SMDEV_RESET)
4814 {
4815
4816
James Bottomley 47b5d692005-04-24 02:38:05 -05004817 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004818 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004819 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004820
James Bottomley 47b5d692005-04-24 02:38:05 -05004821 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004822 {
4823
James Bottomley 47b5d692005-04-24 02:38:05 -05004824 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825
4826 }
4827
James Bottomley 47b5d692005-04-24 02:38:05 -05004828 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004829 {
4830
James Bottomley 47b5d692005-04-24 02:38:05 -05004831 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004832 }
4833
4834
James Bottomley 47b5d692005-04-24 02:38:05 -05004835 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4836 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004837 }
4838 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4839 {
4840 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004841 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004842 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004843 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4844 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004845 }
4846
4847 }
4848
4849 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4850 {
4851
4852
4853 if(message == SMNO_OP)
4854 {
4855 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4856
James Bottomley 47b5d692005-04-24 02:38:05 -05004857 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004858 return;
4859 }
4860 }
4861 else
4862 {
4863
4864
4865 if (message == SMABORT)
4866
James Bottomley 47b5d692005-04-24 02:38:05 -05004867 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004868 }
4869
4870 }
4871 else
4872 {
4873 message = SMABORT;
4874 }
4875
4876 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4877
4878
4879 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4880
4881 WR_HARPOON(port+hp_scsidata_0,message);
4882
4883 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4884
4885 ACCEPT_MSG(port);
4886
4887 WR_HARPOON(port+hp_portctrl_0, 0x00);
4888
4889 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4890 (message == SMABORT_TAG) )
4891 {
4892
4893 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4894
4895 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4896 {
4897 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4898
4899 if (currSCCB != NULL)
4900 {
4901
James Bottomley 47b5d692005-04-24 02:38:05 -05004902 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4903 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4904 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004905 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004906 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004907
James Bottomley 47b5d692005-04-24 02:38:05 -05004908 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004909 }
4910
4911 else
4912 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004913 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004914 }
4915 }
4916
4917 else
4918 {
4919
James Bottomley 47b5d692005-04-24 02:38:05 -05004920 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004921 }
4922 }
4923
4924 else
4925 {
4926
4927 if(message == SMPARITY)
4928 {
4929 currSCCB->Sccb_scsimsg = SMNO_OP;
4930 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4931 }
4932 else
4933 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004934 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004935 }
4936 }
4937}
4938
4939
4940/*---------------------------------------------------------------------
4941 *
4942 * Function: Message In phase
4943 *
4944 * Description: Bring in the message and determine what to do with it.
4945 *
4946 *---------------------------------------------------------------------*/
4947
James Bottomley 47b5d692005-04-24 02:38:05 -05004948static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004949{
4950 UCHAR message;
4951 PSCCB currSCCB;
4952
James Bottomley 47b5d692005-04-24 02:38:05 -05004953 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004954
James Bottomley 47b5d692005-04-24 02:38:05 -05004955 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004956 {
4957
James Bottomley 47b5d692005-04-24 02:38:05 -05004958 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004959 }
4960
4961 message = RD_HARPOON(port+hp_scsidata_0);
4962 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4963 {
4964
4965 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4966
4967 }
4968
4969 else
4970 {
4971
James Bottomley 47b5d692005-04-24 02:38:05 -05004972 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004973 if (message)
4974 {
4975
4976
James Bottomley 47b5d692005-04-24 02:38:05 -05004977 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004978
4979 }
4980 else
4981 {
4982 if(currSCCB->Sccb_scsimsg != SMPARITY)
4983 ACCEPT_MSG(port);
4984 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4985 }
4986 }
4987
4988}
4989
4990
4991/*---------------------------------------------------------------------
4992 *
4993 * Function: Illegal phase
4994 *
4995 * Description: Target switched to some illegal phase, so all we can do
4996 * is report an error back to the host (if that is possible)
4997 * and send an ABORT message to the misbehaving target.
4998 *
4999 *---------------------------------------------------------------------*/
5000
James Bottomley 47b5d692005-04-24 02:38:05 -05005001static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005002{
5003 PSCCB currSCCB;
5004
James Bottomley 47b5d692005-04-24 02:38:05 -05005005 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005006
5007 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
5008 if (currSCCB != NULL) {
5009
5010 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
5011 currSCCB->Sccb_scsistat = ABORT_ST;
5012 currSCCB->Sccb_scsimsg = SMABORT;
5013 }
5014
5015 ACCEPT_MSG_ATN(port);
5016}
5017
5018
5019
5020/*---------------------------------------------------------------------
5021 *
5022 * Function: Phase Check FIFO
5023 *
5024 * Description: Make sure data has been flushed from both FIFOs and abort
5025 * the operations if necessary.
5026 *
5027 *---------------------------------------------------------------------*/
5028
James Bottomley 47b5d692005-04-24 02:38:05 -05005029static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005030{
5031 ULONG xfercnt;
5032 PSCCB currSCCB;
5033
James Bottomley 47b5d692005-04-24 02:38:05 -05005034 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005035
5036 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
5037 {
5038
5039 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
5040 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
5041
5042
5043 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
5044 {
5045 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
5046
5047 currSCCB->Sccb_XferCnt = 0;
5048
5049 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
5050 (currSCCB->HostStatus == SCCB_COMPLETE))
5051 {
5052 currSCCB->HostStatus = SCCB_PARITY_ERR;
5053 WRW_HARPOON((port+hp_intstat), PARITY);
5054 }
5055
James Bottomley 47b5d692005-04-24 02:38:05 -05005056 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005057
James Bottomley 47b5d692005-04-24 02:38:05 -05005058 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005059
5060 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
5061 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
5062
5063 }
5064 } /*End Data In specific code. */
5065
5066
5067
Linus Torvalds1da177e2005-04-16 15:20:36 -07005068 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005069
5070
5071 WR_HARPOON(port+hp_xfercnt_0, 0x00);
5072
5073
5074 WR_HARPOON(port+hp_portctrl_0, 0x00);
5075
5076 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
5077
5078 currSCCB->Sccb_XferCnt = xfercnt;
5079
5080 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
5081 (currSCCB->HostStatus == SCCB_COMPLETE)) {
5082
5083 currSCCB->HostStatus = SCCB_PARITY_ERR;
5084 WRW_HARPOON((port+hp_intstat), PARITY);
5085 }
5086
5087
James Bottomley 47b5d692005-04-24 02:38:05 -05005088 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005089
5090
5091 WR_HARPOON(port+hp_fifowrite, 0x00);
5092 WR_HARPOON(port+hp_fiforead, 0x00);
5093 WR_HARPOON(port+hp_xferstat, 0x00);
5094
5095 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
5096}
5097
5098
5099/*---------------------------------------------------------------------
5100 *
5101 * Function: Phase Bus Free
5102 *
5103 * Description: We just went bus free so figure out if it was
5104 * because of command complete or from a disconnect.
5105 *
5106 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005107static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005108{
5109 PSCCB currSCCB;
5110
James Bottomley 47b5d692005-04-24 02:38:05 -05005111 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005112
5113 if (currSCCB != NULL)
5114 {
5115
5116 DISABLE_AUTO(port);
5117
5118
5119 if (currSCCB->OperationCode == RESET_COMMAND)
5120 {
5121
James Bottomley 47b5d692005-04-24 02:38:05 -05005122 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5123 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5124 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005125 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005126 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005127
James Bottomley 47b5d692005-04-24 02:38:05 -05005128 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005129
James Bottomley 47b5d692005-04-24 02:38:05 -05005130 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005131
5132 }
5133
5134 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5135 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005136 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005137 (UCHAR)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05005138 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005139 }
5140
5141 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5142 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005143 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5144 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005145 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5146
James Bottomley 47b5d692005-04-24 02:38:05 -05005147 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005148 }
5149
Linus Torvalds1da177e2005-04-16 15:20:36 -07005150 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
5151 {
5152 /* Make sure this is not a phony BUS_FREE. If we were
5153 reselected or if BUSY is NOT on then this is a
5154 valid BUS FREE. SRR Wednesday, 5/10/1995. */
5155
5156 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
5157 (RDW_HARPOON((port+hp_intstat)) & RSEL))
5158 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005159 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
5160 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005161 }
5162
5163 else
5164 {
5165 return;
5166 }
5167 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005168
5169 else
5170 {
5171
5172 currSCCB->Sccb_scsistat = BUS_FREE_ST;
5173
5174 if (!currSCCB->HostStatus)
5175 {
5176 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
5177 }
5178
James Bottomley 47b5d692005-04-24 02:38:05 -05005179 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5180 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5181 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005182 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005183 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005184
James Bottomley 47b5d692005-04-24 02:38:05 -05005185 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005186 return;
5187 }
5188
5189
James Bottomley 47b5d692005-04-24 02:38:05 -05005190 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005191
5192 } /*end if !=null */
5193}
5194
5195
5196
5197
Linus Torvalds1da177e2005-04-16 15:20:36 -07005198/*---------------------------------------------------------------------
5199 *
5200 * Function: Auto Load Default Map
5201 *
5202 * Description: Load the Automation RAM with the defualt map values.
5203 *
5204 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005205static void FPT_autoLoadDefaultMap(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005206{
Linus Torvalds1da177e2005-04-16 15:20:36 -07005207 ULONG map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005208
5209 ARAM_ACCESS(p_port);
5210 map_addr = p_port + hp_aramBase;
5211
5212 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
5213 map_addr +=2;
5214 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
5215 map_addr +=2;
5216 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
5217 map_addr +=2;
5218 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
5219 map_addr +=2;
5220 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
5221 map_addr +=2;
5222 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
5223 map_addr +=2;
5224 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
5225 map_addr +=2;
5226 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
5227 map_addr +=2;
5228 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
5229 map_addr +=2;
5230 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
5231 map_addr +=2;
5232 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
5233 map_addr +=2;
5234 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
5235 map_addr +=2;
5236 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
5237 map_addr +=2;
5238 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
5239 map_addr +=2;
5240 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
5241 map_addr +=2;
5242 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
5243 map_addr +=2;
5244 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
5245 map_addr +=2;
5246 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
5247 map_addr +=2; /*This means AYNC DATA IN */
5248 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
5249 map_addr +=2;
5250 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
5251 map_addr +=2;
5252 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
5253 map_addr +=2;
5254 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
5255 map_addr +=2;
5256 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
5257 map_addr +=2;
5258 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
5259 map_addr +=2;
5260 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
5261 map_addr +=2;
5262 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
5263 map_addr +=2;
5264 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
5265 map_addr +=2;
5266 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
5267 map_addr +=2;
5268 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
5269 map_addr +=2;
5270 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
5271 map_addr +=2;
5272 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
5273 map_addr +=2;
5274 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
5275 map_addr +=2;
5276 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
5277 map_addr +=2;
5278 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
5279 map_addr +=2;
5280 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
5281 map_addr +=2;
5282 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
5283 map_addr +=2;
5284
5285 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
5286 map_addr +=2;
5287 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
5288 map_addr +=2;
5289 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
5290 map_addr +=2;
5291 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
5292 map_addr +=2; /* DIDN'T GET ONE */
5293 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
5294 map_addr +=2;
5295 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
5296 map_addr +=2;
5297 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
5298
5299
5300
5301 SGRAM_ACCESS(p_port);
5302}
5303
5304/*---------------------------------------------------------------------
5305 *
5306 * Function: Auto Command Complete
5307 *
5308 * Description: Post command back to host and find another command
5309 * to execute.
5310 *
5311 *---------------------------------------------------------------------*/
5312
James Bottomley 47b5d692005-04-24 02:38:05 -05005313static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005314{
5315 PSCCB currSCCB;
5316 UCHAR status_byte;
5317
James Bottomley 47b5d692005-04-24 02:38:05 -05005318 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005319
5320 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
5321
James Bottomley 47b5d692005-04-24 02:38:05 -05005322 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005323
5324 if (status_byte != SSGOOD) {
5325
5326 if (status_byte == SSQ_FULL) {
5327
5328
James Bottomley 47b5d692005-04-24 02:38:05 -05005329 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5330 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005331 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005332 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5333 if(FPT_BL_Card[p_card].discQCount != 0)
5334 FPT_BL_Card[p_card].discQCount--;
5335 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 -07005336 }
5337 else
5338 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005339 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005340 if(currSCCB->Sccb_tag)
5341 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005342 if(FPT_BL_Card[p_card].discQCount != 0)
5343 FPT_BL_Card[p_card].discQCount--;
5344 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005345 }else
5346 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005347 if(FPT_BL_Card[p_card].discQCount != 0)
5348 FPT_BL_Card[p_card].discQCount--;
5349 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005350 }
5351 }
5352
5353 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
5354
James Bottomley 47b5d692005-04-24 02:38:05 -05005355 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005356
5357 return;
5358 }
5359
5360 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5361 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005362 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005363 (UCHAR)SYNC_SUPPORTED;
5364
James Bottomley 47b5d692005-04-24 02:38:05 -05005365 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5366 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005367
James Bottomley 47b5d692005-04-24 02:38:05 -05005368 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5369 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005371 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5372 if(FPT_BL_Card[p_card].discQCount != 0)
5373 FPT_BL_Card[p_card].discQCount--;
5374 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 -07005375 }
5376 else
5377 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005378 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005379 if(currSCCB->Sccb_tag)
5380 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005381 if(FPT_BL_Card[p_card].discQCount != 0)
5382 FPT_BL_Card[p_card].discQCount--;
5383 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005384 }else
5385 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005386 if(FPT_BL_Card[p_card].discQCount != 0)
5387 FPT_BL_Card[p_card].discQCount--;
5388 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389 }
5390 }
5391 return;
5392
5393 }
5394
5395 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5396 {
5397
James Bottomley 47b5d692005-04-24 02:38:05 -05005398 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5399 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005400 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5401
James Bottomley 47b5d692005-04-24 02:38:05 -05005402 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5403 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404
James Bottomley 47b5d692005-04-24 02:38:05 -05005405 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5406 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005407 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005408 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5409 if(FPT_BL_Card[p_card].discQCount != 0)
5410 FPT_BL_Card[p_card].discQCount--;
5411 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 -07005412 }
5413 else
5414 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005415 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416 if(currSCCB->Sccb_tag)
5417 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005418 if(FPT_BL_Card[p_card].discQCount != 0)
5419 FPT_BL_Card[p_card].discQCount--;
5420 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005421 }else
5422 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005423 if(FPT_BL_Card[p_card].discQCount != 0)
5424 FPT_BL_Card[p_card].discQCount--;
5425 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005426 }
5427 }
5428 return;
5429
5430 }
5431
5432 if (status_byte == SSCHECK)
5433 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005434 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005435 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005436 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005437 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005438 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005439 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005440 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005441 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005442 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005443 }
5444 }
5445 }
5446
5447 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5448
5449 currSCCB->SccbStatus = SCCB_ERROR;
5450 currSCCB->TargetStatus = status_byte;
5451
5452 if (status_byte == SSCHECK) {
5453
James Bottomley 47b5d692005-04-24 02:38:05 -05005454 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5455 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005456
5457
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5459
5460 if (currSCCB->RequestSenseLength == 0)
5461 currSCCB->RequestSenseLength = 14;
5462
James Bottomley 47b5d692005-04-24 02:38:05 -05005463 FPT_ssenss(&FPT_BL_Card[p_card]);
5464 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005465
James Bottomley 47b5d692005-04-24 02:38:05 -05005466 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5467 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005468 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005469 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5470 if(FPT_BL_Card[p_card].discQCount != 0)
5471 FPT_BL_Card[p_card].discQCount--;
5472 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 -07005473 }
5474 else
5475 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005476 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005477 if(currSCCB->Sccb_tag)
5478 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005479 if(FPT_BL_Card[p_card].discQCount != 0)
5480 FPT_BL_Card[p_card].discQCount--;
5481 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005482 }else
5483 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005484 if(FPT_BL_Card[p_card].discQCount != 0)
5485 FPT_BL_Card[p_card].discQCount--;
5486 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005487 }
5488 }
5489 return;
5490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005491 }
5492 }
5493 }
5494
5495
James Bottomley 47b5d692005-04-24 02:38:05 -05005496 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5497 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5498 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005499 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005500 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005501
5502
James Bottomley 47b5d692005-04-24 02:38:05 -05005503 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005504}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005505
5506#define SHORT_WAIT 0x0000000F
5507#define LONG_WAIT 0x0000FFFFL
5508
Linus Torvalds1da177e2005-04-16 15:20:36 -07005509
5510/*---------------------------------------------------------------------
5511 *
5512 * Function: Data Transfer Processor
5513 *
5514 * Description: This routine performs two tasks.
5515 * (1) Start data transfer by calling HOST_DATA_XFER_START
5516 * function. Once data transfer is started, (2) Depends
5517 * on the type of data transfer mode Scatter/Gather mode
5518 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5519 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5520 * data transfer done. In Scatter/Gather mode, this routine
5521 * checks bus master command complete and dual rank busy
5522 * bit to keep chaining SC transfer command. Similarly,
5523 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5524 * (F_HOST_XFER_ACT bit) for data transfer done.
5525 *
5526 *---------------------------------------------------------------------*/
5527
James Bottomley 47b5d692005-04-24 02:38:05 -05005528static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005529{
5530 PSCCB currSCCB;
5531
5532 currSCCB = pCurrCard->currentSCCB;
5533
5534 if (currSCCB->Sccb_XferState & F_SG_XFER)
5535 {
5536 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5537
5538 {
5539 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
5540 currSCCB->Sccb_SGoffset = 0x00;
5541 }
5542 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5543
James Bottomley 47b5d692005-04-24 02:38:05 -05005544 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005545 }
5546
5547 else
5548 {
5549 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5550 {
5551 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5552
James Bottomley 47b5d692005-04-24 02:38:05 -05005553 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005554 }
5555 }
5556}
5557
5558
5559/*---------------------------------------------------------------------
5560 *
5561 * Function: BusMaster Scatter Gather Data Transfer Start
5562 *
5563 * Description:
5564 *
5565 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005566static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005567{
5568 ULONG count,addr,tmpSGCnt;
5569 UINT sg_index;
5570 UCHAR sg_count, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005571 ULONG reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005572
5573
5574 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5575
5576 count = ((ULONG) HOST_RD_CMD)<<24;
5577 }
5578
5579 else {
5580 count = ((ULONG) HOST_WRT_CMD)<<24;
5581 }
5582
5583 sg_count = 0;
5584 tmpSGCnt = 0;
5585 sg_index = pcurrSCCB->Sccb_sgseg;
5586 reg_offset = hp_aramBase;
5587
5588
5589 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5590
5591
5592 WR_HARPOON(p_port+hp_page_ctrl, i);
5593
5594 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
5595 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5596
Linus Torvalds1da177e2005-04-16 15:20:36 -07005597 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5598 (sg_index * 2));
5599
5600 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5601 (sg_index * 2));
5602
5603 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5604 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005605
5606
5607 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5608
5609 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5610 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5611
5612 tmpSGCnt = count & 0x00FFFFFFL;
5613 }
5614
5615 WR_HARP32(p_port,reg_offset,addr);
5616 reg_offset +=4;
5617
5618 WR_HARP32(p_port,reg_offset,count);
5619 reg_offset +=4;
5620
5621 count &= 0xFF000000L;
5622 sg_index++;
5623 sg_count++;
5624
5625 } /*End While */
5626
5627 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5628
5629 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5630
5631 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5632
5633 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5634
5635
5636 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5637 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5638 }
5639
5640 else {
5641
5642
5643 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5644 (tmpSGCnt & 0x000000001))
5645 {
5646
5647 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5648 tmpSGCnt--;
5649 }
5650
5651
5652 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5653
5654 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5655 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5656 }
5657
5658
5659 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
5660
5661}
5662
5663
5664/*---------------------------------------------------------------------
5665 *
5666 * Function: BusMaster Data Transfer Start
5667 *
5668 * Description:
5669 *
5670 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005671static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005672{
5673 ULONG addr,count;
5674
5675 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5676
5677 count = pcurrSCCB->Sccb_XferCnt;
5678
5679 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5680 }
5681
5682 else {
5683 addr = pcurrSCCB->SensePointer;
5684 count = pcurrSCCB->RequestSenseLength;
5685
5686 }
5687
Linus Torvalds1da177e2005-04-16 15:20:36 -07005688 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689
5690
5691 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5692
5693 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5694 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5695
5696 WR_HARPOON(p_port+hp_xfer_cmd,
5697 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5698 }
5699
5700 else {
5701
5702 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5703 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5704
5705 WR_HARPOON(p_port+hp_xfer_cmd,
5706 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5707
5708 }
5709}
5710
5711
5712/*---------------------------------------------------------------------
5713 *
5714 * Function: BusMaster Timeout Handler
5715 *
5716 * Description: This function is called after a bus master command busy time
5717 * out is detected. This routines issue halt state machine
5718 * with a software time out for command busy. If command busy
5719 * is still asserted at the end of the time out, it issues
5720 * hard abort with another software time out. It hard abort
5721 * command busy is also time out, it'll just give up.
5722 *
5723 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005724static UCHAR FPT_busMstrTimeOut(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005725{
5726 ULONG timeout;
5727
5728 timeout = LONG_WAIT;
5729
5730 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5731
5732 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5733
5734
5735
5736 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5737 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5738
5739 timeout = LONG_WAIT;
5740 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5741 }
5742
5743 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5744
5745 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005746 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005747 }
5748
5749 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005750 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005751 }
5752}
5753
5754
5755/*---------------------------------------------------------------------
5756 *
5757 * Function: Host Data Transfer Abort
5758 *
5759 * Description: Abort any in progress transfer.
5760 *
5761 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005762static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763{
5764
5765 ULONG timeout;
5766 ULONG remain_cnt;
5767 UINT sg_ptr;
5768
James Bottomley 47b5d692005-04-24 02:38:05 -05005769 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005770
5771 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5772
5773
5774 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5775
5776 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5777 timeout = LONG_WAIT;
5778
5779 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5780
5781 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5782
5783 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5784
James Bottomley 47b5d692005-04-24 02:38:05 -05005785 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005786
5787 if (pCurrSCCB->HostStatus == 0x00)
5788
5789 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5790
5791 }
5792
5793 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5794
5795 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5796
5797 if (pCurrSCCB->HostStatus == 0x00)
5798
5799 {
5800 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005801 }
5802 }
5803 }
5804 }
5805
5806 else if (pCurrSCCB->Sccb_XferCnt) {
5807
5808 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5809
5810
5811 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5812 ~SCATTER_EN));
5813
5814 WR_HARPOON(port+hp_sg_addr,0x00);
5815
5816 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5817
5818 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5819
5820 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5821 }
5822
5823 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5824
5825 while (remain_cnt < 0x01000000L) {
5826
5827 sg_ptr--;
5828
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5830 DataPointer) + (sg_ptr * 2)))) {
5831
5832 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5833 DataPointer) + (sg_ptr * 2)));
5834 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005835
5836 else {
5837
5838 break;
5839 }
5840 }
5841
5842
5843
5844 if (remain_cnt < 0x01000000L) {
5845
5846
5847 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5848
5849 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5850
5851
5852 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5853 && (remain_cnt == 0))
5854
5855 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5856 }
5857
5858 else {
5859
5860
5861 if (pCurrSCCB->HostStatus == 0x00) {
5862
5863 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5864 }
5865 }
5866 }
5867
5868
5869 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5870
5871
5872 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5873
James Bottomley 47b5d692005-04-24 02:38:05 -05005874 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005875 }
5876
5877 else {
5878
5879 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5880
5881 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5882
5883 if (pCurrSCCB->HostStatus == 0x00) {
5884
5885 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005886 }
5887 }
5888 }
5889
5890 }
5891 }
5892
5893 else {
5894
5895
5896 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5897
5898 timeout = SHORT_WAIT;
5899
5900 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5901 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5902 timeout--) {}
5903 }
5904
5905 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5906
5907 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5908 FLUSH_XFER_CNTR));
5909
5910 timeout = LONG_WAIT;
5911
5912 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5913 timeout--) {}
5914
5915 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5916 ~FLUSH_XFER_CNTR));
5917
5918
5919 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5920
5921 if (pCurrSCCB->HostStatus == 0x00) {
5922
5923 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5924 }
5925
James Bottomley 47b5d692005-04-24 02:38:05 -05005926 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005927 }
5928 }
5929
5930 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5931
5932 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5933
5934 if (pCurrSCCB->HostStatus == 0x00) {
5935
5936 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005937 }
5938 }
5939 }
5940 }
5941
5942 }
5943
5944 else {
5945
5946
5947 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5948
5949 timeout = LONG_WAIT;
5950
5951 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5952
5953 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5954
5955 if (pCurrSCCB->HostStatus == 0x00) {
5956
5957 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5958 }
5959
James Bottomley 47b5d692005-04-24 02:38:05 -05005960 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005961 }
5962 }
5963
5964
5965 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5966
5967 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5968
5969 if (pCurrSCCB->HostStatus == 0x00) {
5970
5971 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005972 }
5973 }
5974
5975 }
5976
5977 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5978
5979 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5980 ~SCATTER_EN));
5981
5982 WR_HARPOON(port+hp_sg_addr,0x00);
5983
5984 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5985
5986 pCurrSCCB->Sccb_SGoffset = 0x00;
5987
5988
5989 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5990 pCurrSCCB->DataLength) {
5991
5992 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5993
5994 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5995
5996 }
5997 }
5998
5999 else {
6000
6001 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
6002
6003 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
6004 }
6005 }
6006
6007 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
6008}
6009
6010
6011
6012/*---------------------------------------------------------------------
6013 *
6014 * Function: Host Data Transfer Restart
6015 *
6016 * Description: Reset the available count due to a restore data
6017 * pointers message.
6018 *
6019 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05006020static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021{
6022 ULONG data_count;
6023 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006024 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025
6026 if (currSCCB->Sccb_XferState & F_SG_XFER) {
6027
6028 currSCCB->Sccb_XferCnt = 0;
6029
6030 sg_index = 0xffff; /*Index by long words into sg list. */
6031 data_count = 0; /*Running count of SG xfer counts. */
6032
Linus Torvalds1da177e2005-04-16 15:20:36 -07006033 sg_ptr = (ULONG *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006034
6035 while (data_count < currSCCB->Sccb_ATC) {
6036
6037 sg_index++;
6038 data_count += *(sg_ptr+(sg_index * 2));
6039 }
6040
6041 if (data_count == currSCCB->Sccb_ATC) {
6042
6043 currSCCB->Sccb_SGoffset = 0;
6044 sg_index++;
6045 }
6046
6047 else {
6048 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
6049 }
6050
6051 currSCCB->Sccb_sgseg = (USHORT)sg_index;
6052 }
6053
6054 else {
6055 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
6056 }
6057}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006058
6059
6060
Linus Torvalds1da177e2005-04-16 15:20:36 -07006061/*---------------------------------------------------------------------
6062 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006063 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07006064 *
6065 * Description: Setup all data structures necessary for SCAM selection.
6066 *
6067 *---------------------------------------------------------------------*/
6068
James Bottomley 47b5d692005-04-24 02:38:05 -05006069static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006070{
6071
Linus Torvalds1da177e2005-04-16 15:20:36 -07006072 UCHAR loser,assigned_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006073 ULONG p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006074
6075 UCHAR i,k,ScamFlg ;
6076 PSCCBcard currCard;
6077 PNVRamInfo pCurrNvRam;
6078
James Bottomley 47b5d692005-04-24 02:38:05 -05006079 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006080 p_port = currCard->ioPort;
6081 pCurrNvRam = currCard->pNvRamInfo;
6082
6083
6084 if(pCurrNvRam){
6085 ScamFlg = pCurrNvRam->niScamConf;
6086 i = pCurrNvRam->niSysConf;
6087 }
6088 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05006089 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
6090 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006091 }
6092 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
6093 return;
6094
James Bottomley 47b5d692005-04-24 02:38:05 -05006095 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006096
6097 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
6098 too slow to return to SCAM selection */
6099
6100 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05006101 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006102 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006103 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006104
James Bottomley 47b5d692005-04-24 02:38:05 -05006105 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006106
6107 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6108 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006109 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006110
James Bottomley 47b5d692005-04-24 02:38:05 -05006111 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006112
6113 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05006114 FPT_scxferc(p_port,SYNC_PTRN);
6115 FPT_scxferc(p_port,DOM_MSTR);
6116 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006117 } while ( loser == 0xFF );
6118
James Bottomley 47b5d692005-04-24 02:38:05 -05006119 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006120
6121 if ((p_power_up) && (!loser))
6122 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006123 FPT_sresb(p_port,p_card);
6124 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006125
James Bottomley 47b5d692005-04-24 02:38:05 -05006126 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127
James Bottomley 47b5d692005-04-24 02:38:05 -05006128 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006129
6130 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05006131 FPT_scxferc(p_port, SYNC_PTRN);
6132 FPT_scxferc(p_port, DOM_MSTR);
6133 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07006134 id_string[0]);
6135 } while ( loser == 0xFF );
6136
James Bottomley 47b5d692005-04-24 02:38:05 -05006137 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138 }
6139 }
6140
6141 else
6142 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006143 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006144 }
6145
6146
6147 if (!loser)
6148 {
6149
James Bottomley 47b5d692005-04-24 02:38:05 -05006150 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006151
6152
6153 if (ScamFlg & SCAM_ENABLED)
6154 {
6155
6156 for (i=0; i < MAX_SCSI_TAR; i++)
6157 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006158 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
6159 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006160 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006161 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006162 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006163 FPT_scamInfo[i].state = LEGACY;
6164 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
6165 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006166 {
6167
James Bottomley 47b5d692005-04-24 02:38:05 -05006168 FPT_scamInfo[i].id_string[0] = 0xFF;
6169 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006170 if(pCurrNvRam == NULL)
6171 currCard->globalFlags |= F_UPDATE_EEPROM;
6172 }
6173 }
6174 }
6175 }
6176
James Bottomley 47b5d692005-04-24 02:38:05 -05006177 FPT_sresb(p_port,p_card);
6178 FPT_Wait1Second(p_port);
6179 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
6180 FPT_scsel(p_port);
6181 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182 }
6183
Linus Torvalds1da177e2005-04-16 15:20:36 -07006184 }
6185
6186 else if ((loser) && (ScamFlg & SCAM_ENABLED))
6187 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006188 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
6189 assigned_id = 0;
6190 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006191
6192 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05006193 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006194
James Bottomley 47b5d692005-04-24 02:38:05 -05006195 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006196 if (i == ASSIGN_ID)
6197 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006198 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006199 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006200 i = FPT_scxferc(p_port,0x00);
6201 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006202 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006203 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006204
James Bottomley 47b5d692005-04-24 02:38:05 -05006205 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006206 {
6207 currCard->ourId =
6208 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006209 FPT_inisci(p_card, p_port, p_our_id);
6210 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
6211 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07006212 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006213 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006214 }
6215 }
6216 }
6217 }
6218
6219 else if (i == SET_P_FLAG)
6220 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006221 if (!(FPT_scsendi(p_port,
6222 &FPT_scamInfo[p_our_id].id_string[0])))
6223 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006224 }
6225 }while (!assigned_id);
6226
James Bottomley 47b5d692005-04-24 02:38:05 -05006227 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006228 }
6229
Linus Torvalds1da177e2005-04-16 15:20:36 -07006230 if (ScamFlg & SCAM_ENABLED)
6231 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006232 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006233 if (currCard->globalFlags & F_UPDATE_EEPROM)
6234 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006235 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006236 currCard->globalFlags &= ~F_UPDATE_EEPROM;
6237 }
6238 }
6239
6240
Linus Torvalds1da177e2005-04-16 15:20:36 -07006241/*
6242 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
6243 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006244 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
6245 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006246 k++;
6247 }
6248
6249 if (k==2)
6250 currCard->globalFlags |= F_SINGLE_DEVICE;
6251 else
6252 currCard->globalFlags &= ~F_SINGLE_DEVICE;
6253*/
6254}
6255
6256
6257/*---------------------------------------------------------------------
6258 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006259 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07006260 *
6261 * Description: Gain control of the bus and wait SCAM select time (250ms)
6262 *
6263 *---------------------------------------------------------------------*/
6264
James Bottomley 47b5d692005-04-24 02:38:05 -05006265static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006266{
6267 if (p_sel_type == INIT_SELTD)
6268 {
6269
6270 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
6271
6272
6273 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05006274 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006275
6276 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05006277 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006278
6279 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
6280
6281 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
6282
6283 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
6284 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05006285 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006286 }
6287
6288
6289 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
6290
6291 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
6292
6293 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
6294 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006295 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006296 }
6297 }
6298
6299
6300 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
6301 & ~ACTdeassert));
6302 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
6303 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006304 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006305 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
6306
6307 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
6308
6309 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
6310 & ~SCSI_BSY));
6311
James Bottomley 47b5d692005-04-24 02:38:05 -05006312 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006313
James Bottomley 47b5d692005-04-24 02:38:05 -05006314 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006315}
6316
6317
6318/*---------------------------------------------------------------------
6319 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006320 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07006321 *
6322 * Description: Release the SCSI bus and disable SCAM selection.
6323 *
6324 *---------------------------------------------------------------------*/
6325
James Bottomley 47b5d692005-04-24 02:38:05 -05006326static void FPT_scbusf(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006327{
6328 WR_HARPOON(p_port+hp_page_ctrl,
6329 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6330
6331
6332 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
6333
6334 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
6335 & ~SCSI_BUS_EN));
6336
6337 WR_HARPOON(p_port+hp_scsisig, 0x00);
6338
6339
6340 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
6341 & ~SCAM_EN));
6342
6343 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
6344 | ACTdeassert));
6345
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347
6348 WR_HARPOON(p_port+hp_page_ctrl,
6349 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6350}
6351
6352
6353
6354/*---------------------------------------------------------------------
6355 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006356 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006357 *
6358 * Description: Assign an ID to all the SCAM devices.
6359 *
6360 *---------------------------------------------------------------------*/
6361
James Bottomley 47b5d692005-04-24 02:38:05 -05006362static void FPT_scasid(UCHAR p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006364 UCHAR temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006365
6366 UCHAR i,k,scam_id;
6367 UCHAR crcBytes[3];
6368 PNVRamInfo pCurrNvRam;
6369 ushort_ptr pCrcBytes;
6370
James Bottomley 47b5d692005-04-24 02:38:05 -05006371 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006372
James Bottomley 47b5d692005-04-24 02:38:05 -05006373 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006374
6375 while (!i)
6376 {
6377
6378 for (k=0; k < ID_STRING_LENGTH; k++)
6379 {
6380 temp_id_string[k] = (UCHAR) 0x00;
6381 }
6382
James Bottomley 47b5d692005-04-24 02:38:05 -05006383 FPT_scxferc(p_port,SYNC_PTRN);
6384 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006385
James Bottomley 47b5d692005-04-24 02:38:05 -05006386 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006387 {
6388 if(pCurrNvRam){
6389 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006390 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6391 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006392 temp_id_string[1] = crcBytes[2];
6393 temp_id_string[2] = crcBytes[0];
6394 temp_id_string[3] = crcBytes[1];
6395 for(k = 4; k < ID_STRING_LENGTH; k++)
6396 temp_id_string[k] = (UCHAR) 0x00;
6397 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006398 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006399
6400 if (i == CLR_PRIORITY)
6401 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006402 FPT_scxferc(p_port,MISC_CODE);
6403 FPT_scxferc(p_port,CLR_P_FLAG);
6404 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006405 }
6406
6407 else if (i != NO_ID_AVAIL)
6408 {
6409 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006410 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006411 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006412 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006413
6414 scam_id = (i & (UCHAR) 0x07);
6415
6416
6417 for (k=1; k < 0x08; k <<= 1)
6418 if (!( k & i ))
6419 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6420
James Bottomley 47b5d692005-04-24 02:38:05 -05006421 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006422
James Bottomley 47b5d692005-04-24 02:38:05 -05006423 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006424 }
6425 }
6426
6427 else
6428 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006429 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006430 }
6431
6432 } /*End while */
6433
James Bottomley 47b5d692005-04-24 02:38:05 -05006434 FPT_scxferc(p_port,SYNC_PTRN);
6435 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006436}
6437
6438
6439
6440
6441
6442/*---------------------------------------------------------------------
6443 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006444 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445 *
6446 * Description: Select all the SCAM devices.
6447 *
6448 *---------------------------------------------------------------------*/
6449
James Bottomley 47b5d692005-04-24 02:38:05 -05006450static void FPT_scsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451{
6452
6453 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006454 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455
6456 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6457
6458
6459 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6460 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
6461 (UCHAR)(BIT(7)+BIT(6))));
6462
6463
6464 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006465 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006466
6467 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6468 ~(UCHAR)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006469 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470
6471 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6472}
6473
6474
6475
6476/*---------------------------------------------------------------------
6477 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006478 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006479 *
6480 * Description: Handshake the p_data (DB4-0) across the bus.
6481 *
6482 *---------------------------------------------------------------------*/
6483
James Bottomley 47b5d692005-04-24 02:38:05 -05006484static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006485{
6486 UCHAR curr_data, ret_data;
6487
6488 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6489
6490 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6491
6492 curr_data &= ~BIT(7);
6493
6494 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6495
James Bottomley 47b5d692005-04-24 02:38:05 -05006496 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6498
6499 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
6500
6501 curr_data |= BIT(6);
6502
6503 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6504
6505 curr_data &= ~BIT(5);
6506
6507 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6508
James Bottomley 47b5d692005-04-24 02:38:05 -05006509 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510
6511 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6512 curr_data |= BIT(7);
6513
6514 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6515
6516 curr_data &= ~BIT(6);
6517
6518 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6519
James Bottomley 47b5d692005-04-24 02:38:05 -05006520 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006521
6522 return(ret_data);
6523}
6524
6525
6526/*---------------------------------------------------------------------
6527 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006528 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529 *
6530 * Description: Transfer our Identification string to determine if we
6531 * will be the dominant master.
6532 *
6533 *---------------------------------------------------------------------*/
6534
James Bottomley 47b5d692005-04-24 02:38:05 -05006535static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536{
6537 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6538
James Bottomley 47b5d692005-04-24 02:38:05 -05006539 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540
6541 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6542
6543 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6544
6545 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006546 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547
6548 else if (p_id_string[byte_cnt] & bit_cnt)
6549
James Bottomley 47b5d692005-04-24 02:38:05 -05006550 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006551
6552 else {
6553
James Bottomley 47b5d692005-04-24 02:38:05 -05006554 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006556 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006557 }
6558
6559 if ((ret_data & 0x1C) == 0x10)
6560 return(0x00); /*End of isolation stage, we won! */
6561
6562 if (ret_data & 0x1C)
6563 return(0xFF);
6564
6565 if ((defer) && (!(ret_data & 0x1F)))
6566 return(0x01); /*End of isolation stage, we lost. */
6567
6568 } /*bit loop */
6569
6570 } /*byte loop */
6571
6572 if (defer)
6573 return(0x01); /*We lost */
6574 else
6575 return(0); /*We WON! Yeeessss! */
6576}
6577
6578
6579
6580/*---------------------------------------------------------------------
6581 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006582 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006583 *
6584 * Description: Transfer the Identification string.
6585 *
6586 *---------------------------------------------------------------------*/
6587
James Bottomley 47b5d692005-04-24 02:38:05 -05006588static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006589{
6590 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
6591
6592 the_data = 0;
6593
6594 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6595
6596 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6597
James Bottomley 47b5d692005-04-24 02:38:05 -05006598 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006599
6600 if (ret_data & 0xFC)
6601 return(0xFF);
6602
6603 else {
6604
6605 the_data <<= 1;
6606 if (ret_data & BIT(1)) {
6607 the_data |= 1;
6608 }
6609 }
6610
6611 if ((ret_data & 0x1F) == 0)
6612 {
6613/*
6614 if(bit_cnt != 0 || bit_cnt != 8)
6615 {
6616 byte_cnt = 0;
6617 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006618 FPT_scxferc(p_port, SYNC_PTRN);
6619 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006620 continue;
6621 }
6622*/
6623 if (byte_cnt)
6624 return(0x00);
6625 else
6626 return(0xFF);
6627 }
6628
6629 } /*bit loop */
6630
6631 p_id_string[byte_cnt] = the_data;
6632
6633 } /*byte loop */
6634
6635 return(0);
6636}
6637
6638
6639
6640/*---------------------------------------------------------------------
6641 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006642 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006643 *
6644 * Description: Sample the SCSI data bus making sure the signal has been
6645 * deasserted for the correct number of consecutive samples.
6646 *
6647 *---------------------------------------------------------------------*/
6648
James Bottomley 47b5d692005-04-24 02:38:05 -05006649static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006650{
6651 UCHAR i;
6652
6653 i = 0;
6654 while ( i < MAX_SCSI_TAR ) {
6655
6656 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6657
6658 i = 0;
6659
6660 else
6661
6662 i++;
6663
6664 }
6665}
6666
6667
6668
6669/*---------------------------------------------------------------------
6670 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006671 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672 *
6673 * Description: Sample the SCSI Signal lines making sure the signal has been
6674 * deasserted for the correct number of consecutive samples.
6675 *
6676 *---------------------------------------------------------------------*/
6677
James Bottomley 47b5d692005-04-24 02:38:05 -05006678static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006679{
6680 UCHAR i;
6681
6682 i = 0;
6683 while ( i < MAX_SCSI_TAR ) {
6684
6685 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6686
6687 i = 0;
6688
6689 else
6690
6691 i++;
6692
6693 }
6694}
6695
6696
6697/*---------------------------------------------------------------------
6698 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006699 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006700 *
6701 * Description: Make sure we received a valid data byte.
6702 *
6703 *---------------------------------------------------------------------*/
6704
James Bottomley 47b5d692005-04-24 02:38:05 -05006705static UCHAR FPT_scvalq(UCHAR p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006706{
6707 UCHAR count;
6708
6709 for (count=1; count < 0x08; count<<=1) {
6710 if (!(p_quintet & count))
6711 p_quintet -= 0x80;
6712 }
6713
6714 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006715 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006716
6717 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006718 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719}
6720
6721
6722/*---------------------------------------------------------------------
6723 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006724 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725 *
6726 * Description: Select the specified device ID using a selection timeout
6727 * less than 4ms. If somebody responds then it is a legacy
6728 * drive and this ID must be marked as such.
6729 *
6730 *---------------------------------------------------------------------*/
6731
James Bottomley 47b5d692005-04-24 02:38:05 -05006732static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006733{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006734 ULONG i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006735
6736 WR_HARPOON(p_port+hp_page_ctrl,
6737 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6738
6739 ARAM_ACCESS(p_port);
6740
6741 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6742 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6743
6744
6745 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6746 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6747 }
6748 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6749
6750 WRW_HARPOON((p_port+hp_intstat),
6751 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6752
6753 WR_HARPOON(p_port+hp_select_id, targ_id);
6754
6755 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6756 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6757 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6758
6759
6760 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6761 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6762
6763 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006764 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006765
6766 DISABLE_AUTO(p_port);
6767
6768 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6769 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6770
6771 SGRAM_ACCESS(p_port);
6772
6773 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6774
6775 WRW_HARPOON((p_port+hp_intstat),
6776 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6777
6778 WR_HARPOON(p_port+hp_page_ctrl,
6779 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6780
James Bottomley 47b5d692005-04-24 02:38:05 -05006781 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006782 }
6783
6784 else {
6785
6786 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6787 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6788 {
6789 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6790 ACCEPT_MSG(p_port);
6791 }
6792 }
6793
6794 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6795
6796 WR_HARPOON(p_port+hp_page_ctrl,
6797 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6798
James Bottomley 47b5d692005-04-24 02:38:05 -05006799 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006800 }
6801}
6802
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803/*---------------------------------------------------------------------
6804 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006805 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806 *
6807 * Description: Wait to be selected by another SCAM initiator.
6808 *
6809 *---------------------------------------------------------------------*/
6810
James Bottomley 47b5d692005-04-24 02:38:05 -05006811static void FPT_scwtsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812{
6813 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6814}
6815
6816
6817/*---------------------------------------------------------------------
6818 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006819 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 *
6821 * Description: Setup the data Structure with the info from the EEPROM.
6822 *
6823 *---------------------------------------------------------------------*/
6824
James Bottomley 47b5d692005-04-24 02:38:05 -05006825static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826{
6827 UCHAR i,k,max_id;
6828 USHORT ee_data;
6829 PNVRamInfo pCurrNvRam;
6830
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832
6833 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6834 max_id = 0x08;
6835
6836 else
6837 max_id = 0x10;
6838
6839 if(pCurrNvRam){
6840 for(i = 0; i < max_id; i++){
6841
6842 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844 for(k = 4; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006845 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846
James Bottomley 47b5d692005-04-24 02:38:05 -05006847 if(FPT_scamInfo[i].id_string[0] == 0x00)
6848 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006849 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006850 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851
6852 }
6853 }else {
6854 for (i=0; i < max_id; i++)
6855 {
6856 for (k=0; k < ID_STRING_LENGTH; k+=2)
6857 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006858 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006860 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 ee_data >>= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006862 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006863 }
6864
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6866 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869
6870 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006871 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872
6873 }
6874 }
6875 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877
6878}
6879
6880/*---------------------------------------------------------------------
6881 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006882 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 *
6884 * Description: Match the Device ID string with our values stored in
6885 * the EEPROM.
6886 *
6887 *---------------------------------------------------------------------*/
6888
James Bottomley 47b5d692005-04-24 02:38:05 -05006889static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890{
6891
6892 UCHAR i,k,match;
6893
6894
6895 for (i=0; i < MAX_SCSI_TAR; i++) {
6896
James Bottomley 47b5d692005-04-24 02:38:05 -05006897 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898
6899 for (k=0; k < ID_STRING_LENGTH; k++)
6900 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006901 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6902 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006903 }
6904
6905 if (match)
6906 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006907 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006908 return(i);
6909 }
6910
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911 }
6912
6913
6914
6915 if (p_id_string[0] & BIT(5))
6916 i = 8;
6917 else
6918 i = MAX_SCSI_TAR;
6919
6920 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6921 match = p_id_string[1] & (UCHAR) 0x1F;
6922 else
6923 match = 7;
6924
6925 while (i > 0)
6926 {
6927 i--;
6928
James Bottomley 47b5d692005-04-24 02:38:05 -05006929 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006930 {
6931 for (k=0; k < ID_STRING_LENGTH; k++)
6932 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006933 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934 }
6935
James Bottomley 47b5d692005-04-24 02:38:05 -05006936 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006937
James Bottomley 47b5d692005-04-24 02:38:05 -05006938 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6939 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940 return(match);
6941
6942 }
6943
6944
6945 match--;
6946
6947 if (match == 0xFF)
6948 {
6949 if (p_id_string[0] & BIT(5))
6950 match = 7;
6951 else
6952 match = MAX_SCSI_TAR-1;
6953 }
6954 }
6955
6956
6957
6958 if (p_id_string[0] & BIT(7))
6959 {
6960 return(CLR_PRIORITY);
6961 }
6962
6963
6964 if (p_id_string[0] & BIT(5))
6965 i = 8;
6966 else
6967 i = MAX_SCSI_TAR;
6968
6969 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6970 match = p_id_string[1] & (UCHAR) 0x1F;
6971 else
6972 match = 7;
6973
6974 while (i > 0)
6975 {
6976
6977 i--;
6978
James Bottomley 47b5d692005-04-24 02:38:05 -05006979 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006980 {
6981 for (k=0; k < ID_STRING_LENGTH; k++)
6982 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006983 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006984 }
6985
James Bottomley 47b5d692005-04-24 02:38:05 -05006986 FPT_scamInfo[match].id_string[0] |= BIT(7);
6987 FPT_scamInfo[match].state = ID_ASSIGNED;
6988 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6989 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006990 return(match);
6991
6992 }
6993
6994
6995 match--;
6996
6997 if (match == 0xFF)
6998 {
6999 if (p_id_string[0] & BIT(5))
7000 match = 7;
7001 else
7002 match = MAX_SCSI_TAR-1;
7003 }
7004 }
7005
7006 return(NO_ID_AVAIL);
7007}
7008
7009
7010/*---------------------------------------------------------------------
7011 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007012 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07007013 *
7014 * Description: Save off the device SCAM ID strings.
7015 *
7016 *---------------------------------------------------------------------*/
7017
James Bottomley 47b5d692005-04-24 02:38:05 -05007018static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007019{
7020 UCHAR i,k,max_id;
7021 USHORT ee_data,sum_data;
7022
7023
7024 sum_data = 0x0000;
7025
7026 for (i = 1; i < EE_SCAMBASE/2; i++)
7027 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007028 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007029 }
7030
7031
James Bottomley 47b5d692005-04-24 02:38:05 -05007032 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007033
7034 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
7035 max_id = 0x08;
7036
7037 else
7038 max_id = 0x10;
7039
7040 for (i=0; i < max_id; i++)
7041 {
7042
7043 for (k=0; k < ID_STRING_LENGTH; k+=2)
7044 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007045 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007046 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05007047 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007048 sum_data += ee_data;
James Bottomley 47b5d692005-04-24 02:38:05 -05007049 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07007050 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
7051 }
7052 }
7053
7054
James Bottomley 47b5d692005-04-24 02:38:05 -05007055 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
7056 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007057}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007058
7059/*---------------------------------------------------------------------
7060 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007061 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07007062 *
7063 * Description: Setup the Xbow for normal operation.
7064 *
7065 *---------------------------------------------------------------------*/
7066
James Bottomley 47b5d692005-04-24 02:38:05 -05007067static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007068{
7069UCHAR i;
7070
7071 i = RD_HARPOON(port+hp_page_ctrl);
7072 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
7073
7074 WR_HARPOON(port+hp_scsireset,0x00);
7075 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
7076
7077 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
7078 FIFO_CLR));
7079
7080 WR_HARPOON(port+hp_scsireset,SCSI_INI);
7081
7082 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
7083
7084 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
7085 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
7086
7087 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
7088
James Bottomley 47b5d692005-04-24 02:38:05 -05007089 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07007090 BUS_FREE | XFER_CNT_0 | AUTO_INT;
7091
7092 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05007093 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007094
James Bottomley 47b5d692005-04-24 02:38:05 -05007095 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007096
7097 WR_HARPOON(port+hp_seltimeout,TO_290ms);
7098
7099 /* Turn on SCSI_MODE8 for narrow cards to fix the
7100 strapping issue with the DUAL CHANNEL card */
7101 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
7102 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
7103
Linus Torvalds1da177e2005-04-16 15:20:36 -07007104 WR_HARPOON(port+hp_page_ctrl, i);
7105
7106}
7107
7108
7109/*---------------------------------------------------------------------
7110 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007111 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07007112 *
7113 * Description: Initialize the BusMaster for normal operations.
7114 *
7115 *---------------------------------------------------------------------*/
7116
James Bottomley 47b5d692005-04-24 02:38:05 -05007117static void FPT_BusMasterInit(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007118{
7119
7120
7121 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
7122 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
7123
7124 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
7125
7126
7127 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
7128
7129 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
7130
7131
Linus Torvalds1da177e2005-04-16 15:20:36 -07007132 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
7133 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
7134 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
7135 ~SCATTER_EN));
7136}
7137
7138
7139/*---------------------------------------------------------------------
7140 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007141 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07007142 *
7143 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
7144 * necessary.
7145 *
7146 *---------------------------------------------------------------------*/
7147
James Bottomley 47b5d692005-04-24 02:38:05 -05007148static void FPT_DiagEEPROM(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007149{
7150 USHORT index,temp,max_wd_cnt;
7151
7152 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
7153 max_wd_cnt = EEPROM_WD_CNT;
7154 else
7155 max_wd_cnt = EEPROM_WD_CNT * 2;
7156
James Bottomley 47b5d692005-04-24 02:38:05 -05007157 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007158
7159 if (temp == 0x4641) {
7160
7161 for (index = 2; index < max_wd_cnt; index++) {
7162
James Bottomley 47b5d692005-04-24 02:38:05 -05007163 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007164
7165 }
7166
James Bottomley 47b5d692005-04-24 02:38:05 -05007167 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007168
7169 return; /*EEPROM is Okay so return now! */
7170 }
7171 }
7172
7173
James Bottomley 47b5d692005-04-24 02:38:05 -05007174 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007175
7176 for (index = 0; index < max_wd_cnt; index++) {
7177
James Bottomley 47b5d692005-04-24 02:38:05 -05007178 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007179 }
7180
7181 temp = 0;
7182
James Bottomley 47b5d692005-04-24 02:38:05 -05007183 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007184 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05007185 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007186 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05007187 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007188 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05007189 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007190 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05007191 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007192 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05007193 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007194 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05007195 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007196 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05007197 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007198 temp += 0x0007;
7199
James Bottomley 47b5d692005-04-24 02:38:05 -05007200 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007201 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05007202 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007203 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05007204 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007205 temp += 0x0000;
7206
James Bottomley 47b5d692005-04-24 02:38:05 -05007207 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007208 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007209 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007210 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007211 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007212 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007213 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007214 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007215 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007216 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007217 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007218 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007219 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007220 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05007221 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007222 temp += 0x4242;
7223
7224
James Bottomley 47b5d692005-04-24 02:38:05 -05007225 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007226 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05007227 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007228 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05007229 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007230 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05007231 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007232 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05007233 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007234 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05007235 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007236 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05007237 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007238 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05007239 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007240 temp += 0x2020;
7241
7242 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05007243 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007244 temp += (0x0700+TYPE_CODE0);
7245 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007246 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007247 temp += 0x5542; /* BUSLOGIC */
7248 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007249 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007250 temp += 0x4C53;
7251 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007252 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007253 temp += 0x474F;
7254 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007255 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007256 temp += 0x4349;
7257 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007258 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007259 temp += 0x5442; /* BT- 930 */
7260 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007261 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007262 temp += 0x202D;
7263 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007264 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007265 temp += 0x3339;
7266 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05007267 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07007268 temp += 0x2030;
7269 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007270 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007271 temp += 0x5453;
7272 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007273 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007274 temp += 0x5645;
7275 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007276 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007277 temp += 0x2045;
7278 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007279 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007280 temp += 0x202F;
7281 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007282 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007283 temp += 0x4F4A;
7284 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007285 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007286 temp += 0x204E;
7287 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05007288 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007289 temp += 0x3539;
7290
7291
7292
James Bottomley 47b5d692005-04-24 02:38:05 -05007293 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007294
James Bottomley 47b5d692005-04-24 02:38:05 -05007295 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296
7297}
7298
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299
7300/*---------------------------------------------------------------------
7301 *
7302 * Function: Queue Search Select
7303 *
7304 * Description: Try to find a new command to execute.
7305 *
7306 *---------------------------------------------------------------------*/
7307
James Bottomley 47b5d692005-04-24 02:38:05 -05007308static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007309{
7310 UCHAR scan_ptr, lun;
7311 PSCCBMgr_tar_info currTar_Info;
7312 PSCCB pOldSccb;
7313
7314 scan_ptr = pCurrCard->scanIndex;
7315 do
7316 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007317 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007318 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
7319 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
7320 {
7321 if (currTar_Info->TarSelQ_Cnt != 0)
7322 {
7323
7324 scan_ptr++;
7325 if (scan_ptr == MAX_SCSI_TAR)
7326 scan_ptr = 0;
7327
7328 for(lun=0; lun < MAX_LUN; lun++)
7329 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007330 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007331 {
7332
7333 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7334 pOldSccb = NULL;
7335
7336 while((pCurrCard->currentSCCB != NULL) &&
7337 (lun != pCurrCard->currentSCCB->Lun))
7338 {
7339 pOldSccb = pCurrCard->currentSCCB;
7340 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
7341 Sccb_forwardlink;
7342 }
7343 if(pCurrCard->currentSCCB == NULL)
7344 continue;
7345 if(pOldSccb != NULL)
7346 {
7347 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
7348 Sccb_forwardlink;
7349 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
7350 Sccb_backlink;
7351 currTar_Info->TarSelQ_Cnt--;
7352 }
7353 else
7354 {
7355 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7356
7357 if (currTar_Info->TarSelQ_Head == NULL)
7358 {
7359 currTar_Info->TarSelQ_Tail = NULL;
7360 currTar_Info->TarSelQ_Cnt = 0;
7361 }
7362 else
7363 {
7364 currTar_Info->TarSelQ_Cnt--;
7365 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7366 }
7367 }
7368 pCurrCard->scanIndex = scan_ptr;
7369
7370 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7371
7372 break;
7373 }
7374 }
7375 }
7376
7377 else
7378 {
7379 scan_ptr++;
7380 if (scan_ptr == MAX_SCSI_TAR) {
7381 scan_ptr = 0;
7382 }
7383 }
7384
7385 }
7386 else
7387 {
7388 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007389 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007390 {
7391
7392 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7393
7394 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7395
7396 if (currTar_Info->TarSelQ_Head == NULL)
7397 {
7398 currTar_Info->TarSelQ_Tail = NULL;
7399 currTar_Info->TarSelQ_Cnt = 0;
7400 }
7401 else
7402 {
7403 currTar_Info->TarSelQ_Cnt--;
7404 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7405 }
7406
7407 scan_ptr++;
7408 if (scan_ptr == MAX_SCSI_TAR)
7409 scan_ptr = 0;
7410
7411 pCurrCard->scanIndex = scan_ptr;
7412
7413 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7414
7415 break;
7416 }
7417
7418 else
7419 {
7420 scan_ptr++;
7421 if (scan_ptr == MAX_SCSI_TAR)
7422 {
7423 scan_ptr = 0;
7424 }
7425 }
7426 }
7427 } while (scan_ptr != pCurrCard->scanIndex);
7428}
7429
7430
7431/*---------------------------------------------------------------------
7432 *
7433 * Function: Queue Select Fail
7434 *
7435 * Description: Add the current SCCB to the head of the Queue.
7436 *
7437 *---------------------------------------------------------------------*/
7438
James Bottomley 47b5d692005-04-24 02:38:05 -05007439static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007440{
7441 UCHAR thisTarg;
7442 PSCCBMgr_tar_info currTar_Info;
7443
7444 if (pCurrCard->currentSCCB != NULL)
7445 {
7446 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007447 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007448
7449 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7450
7451 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7452
7453 if (currTar_Info->TarSelQ_Cnt == 0)
7454 {
7455 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7456 }
7457
7458 else
7459 {
7460 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7461 }
7462
7463
7464 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7465
7466 pCurrCard->currentSCCB = NULL;
7467 currTar_Info->TarSelQ_Cnt++;
7468 }
7469}
7470/*---------------------------------------------------------------------
7471 *
7472 * Function: Queue Command Complete
7473 *
7474 * Description: Call the callback function with the current SCCB.
7475 *
7476 *---------------------------------------------------------------------*/
7477
James Bottomley 47b5d692005-04-24 02:38:05 -05007478static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7479 UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007480{
7481
Linus Torvalds1da177e2005-04-16 15:20:36 -07007482 UCHAR i, SCSIcmd;
7483 CALL_BK_FN callback;
7484 PSCCBMgr_tar_info currTar_Info;
7485
7486 SCSIcmd = p_sccb->Cdb[0];
7487
7488
7489 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7490
7491 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7492 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7493 (p_sccb->TargetStatus != SSCHECK))
7494
7495 if ((SCSIcmd == SCSI_READ) ||
7496 (SCSIcmd == SCSI_WRITE) ||
7497 (SCSIcmd == SCSI_READ_EXTENDED) ||
7498 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7499 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7500 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7501 (pCurrCard->globalFlags & F_NO_FILTER)
7502 )
7503 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7504 }
7505
7506
7507 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7508 {
7509 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7510 p_sccb->SccbStatus = SCCB_ERROR;
7511 else
7512 p_sccb->SccbStatus = SCCB_SUCCESS;
7513 }
7514
7515 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7516
7517 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7518 for (i=0; i < 6; i++) {
7519 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7520 }
7521 }
7522
7523 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7524 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7525
James Bottomley 47b5d692005-04-24 02:38:05 -05007526 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007527 }
7528
7529 pCurrCard->cmdCounter--;
7530 if (!pCurrCard->cmdCounter) {
7531
7532 if (pCurrCard->globalFlags & F_GREEN_PC) {
7533 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7534 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7535 }
7536
7537 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7538 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7539
7540 }
7541
7542 if(pCurrCard->discQCount != 0)
7543 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007544 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007545 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7546 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7547 {
7548 pCurrCard->discQCount--;
7549 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7550 }
7551 else
7552 {
7553 if(p_sccb->Sccb_tag)
7554 {
7555 pCurrCard->discQCount--;
7556 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7557 }else
7558 {
7559 pCurrCard->discQCount--;
7560 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7561 }
7562 }
7563
7564 }
7565
7566 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7567 callback(p_sccb);
7568 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7569 pCurrCard->currentSCCB = NULL;
7570}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007571
7572
7573/*---------------------------------------------------------------------
7574 *
7575 * Function: Queue Disconnect
7576 *
7577 * Description: Add SCCB to our disconnect array.
7578 *
7579 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05007580static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007581{
7582 PSCCBMgr_tar_info currTar_Info;
7583
James Bottomley 47b5d692005-04-24 02:38:05 -05007584 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007585
James Bottomley 47b5d692005-04-24 02:38:05 -05007586 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007587 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7588 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007589 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007590 }
7591 else
7592 {
7593 if (p_sccb->Sccb_tag)
7594 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007595 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7596 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7597 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007598 }else
7599 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007600 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007601 }
7602 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007603 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007604}
7605
7606
7607/*---------------------------------------------------------------------
7608 *
7609 * Function: Queue Flush SCCB
7610 *
7611 * Description: Flush all SCCB's back to the host driver for this target.
7612 *
7613 *---------------------------------------------------------------------*/
7614
James Bottomley 47b5d692005-04-24 02:38:05 -05007615static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007616{
7617 UCHAR qtag,thisTarg;
7618 PSCCB currSCCB;
7619 PSCCBMgr_tar_info currTar_Info;
7620
James Bottomley 47b5d692005-04-24 02:38:05 -05007621 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007622 if(currSCCB != NULL)
7623 {
7624 thisTarg = (UCHAR)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007625 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007626
7627 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7628
James Bottomley 47b5d692005-04-24 02:38:05 -05007629 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7630 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007631 {
7632
James Bottomley 47b5d692005-04-24 02:38:05 -05007633 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007634
James Bottomley 47b5d692005-04-24 02:38:05 -05007635 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007636
James Bottomley 47b5d692005-04-24 02:38:05 -05007637 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007638 currTar_Info->TarTagQ_Cnt--;
7639
7640 }
7641 }
7642 }
7643
7644}
7645
7646/*---------------------------------------------------------------------
7647 *
7648 * Function: Queue Flush Target SCCB
7649 *
7650 * Description: Flush all SCCB's back to the host driver for this target.
7651 *
7652 *---------------------------------------------------------------------*/
7653
James Bottomley 47b5d692005-04-24 02:38:05 -05007654static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7655 UCHAR error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007656{
7657 UCHAR qtag;
7658 PSCCBMgr_tar_info currTar_Info;
7659
James Bottomley 47b5d692005-04-24 02:38:05 -05007660 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007661
7662 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7663
James Bottomley 47b5d692005-04-24 02:38:05 -05007664 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7665 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007666 {
7667
James Bottomley 47b5d692005-04-24 02:38:05 -05007668 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007669
James Bottomley 47b5d692005-04-24 02:38:05 -05007670 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007671
James Bottomley 47b5d692005-04-24 02:38:05 -05007672 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007673 currTar_Info->TarTagQ_Cnt--;
7674
7675 }
7676 }
7677
7678}
7679
7680
7681
7682
7683
James Bottomley 47b5d692005-04-24 02:38:05 -05007684static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007685{
7686 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007687 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007688
7689 p_SCCB->Sccb_forwardlink = NULL;
7690
7691 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7692
7693 if (currTar_Info->TarSelQ_Cnt == 0) {
7694
7695 currTar_Info->TarSelQ_Head = p_SCCB;
7696 }
7697
7698 else {
7699
7700 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7701 }
7702
7703
7704 currTar_Info->TarSelQ_Tail = p_SCCB;
7705 currTar_Info->TarSelQ_Cnt++;
7706}
7707
7708
7709/*---------------------------------------------------------------------
7710 *
7711 * Function: Queue Find SCCB
7712 *
7713 * Description: Search the target select Queue for this SCCB, and
7714 * remove it if found.
7715 *
7716 *---------------------------------------------------------------------*/
7717
James Bottomley 47b5d692005-04-24 02:38:05 -05007718static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007719{
7720 PSCCB q_ptr;
7721 PSCCBMgr_tar_info currTar_Info;
7722
James Bottomley 47b5d692005-04-24 02:38:05 -05007723 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007724
7725 q_ptr = currTar_Info->TarSelQ_Head;
7726
7727 while(q_ptr != NULL) {
7728
7729 if (q_ptr == p_SCCB) {
7730
7731
7732 if (currTar_Info->TarSelQ_Head == q_ptr) {
7733
7734 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7735 }
7736
7737 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7738
7739 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7740 }
7741
7742 if (q_ptr->Sccb_forwardlink != NULL) {
7743 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7744 }
7745
7746 if (q_ptr->Sccb_backlink != NULL) {
7747 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7748 }
7749
7750 currTar_Info->TarSelQ_Cnt--;
7751
James Bottomley 47b5d692005-04-24 02:38:05 -05007752 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007753 }
7754
7755 else {
7756 q_ptr = q_ptr->Sccb_forwardlink;
7757 }
7758 }
7759
7760
James Bottomley 47b5d692005-04-24 02:38:05 -05007761 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007762
7763}
7764
7765
7766/*---------------------------------------------------------------------
7767 *
7768 * Function: Utility Update Residual Count
7769 *
7770 * Description: Update the XferCnt to the remaining byte count.
7771 * If we transferred all the data then just write zero.
7772 * If Non-SG transfer then report Total Cnt - Actual Transfer
7773 * Cnt. For SG transfers add the count fields of all
7774 * remaining SG elements, as well as any partial remaining
7775 * element.
7776 *
7777 *---------------------------------------------------------------------*/
7778
James Bottomley 47b5d692005-04-24 02:38:05 -05007779static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007780{
7781 ULONG partial_cnt;
7782 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007783 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007784
7785 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7786
7787 p_SCCB->DataLength = 0x0000;
7788 }
7789
7790 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7791
7792 partial_cnt = 0x0000;
7793
7794 sg_index = p_SCCB->Sccb_sgseg;
7795
Linus Torvalds1da177e2005-04-16 15:20:36 -07007796 sg_ptr = (ULONG *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007797
7798 if (p_SCCB->Sccb_SGoffset) {
7799
7800 partial_cnt = p_SCCB->Sccb_SGoffset;
7801 sg_index++;
7802 }
7803
7804 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7805 p_SCCB->DataLength ) {
7806
7807 partial_cnt += *(sg_ptr+(sg_index * 2));
7808 sg_index++;
7809 }
7810
7811 p_SCCB->DataLength = partial_cnt;
7812 }
7813
7814 else {
7815
7816 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7817 }
7818}
7819
7820
7821/*---------------------------------------------------------------------
7822 *
7823 * Function: Wait 1 Second
7824 *
7825 * Description: Wait for 1 second.
7826 *
7827 *---------------------------------------------------------------------*/
7828
James Bottomley 47b5d692005-04-24 02:38:05 -05007829static void FPT_Wait1Second(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007830{
7831 UCHAR i;
7832
7833 for(i=0; i < 4; i++) {
7834
James Bottomley 47b5d692005-04-24 02:38:05 -05007835 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007836
7837 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7838 break;
7839
7840 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7841 break;
7842 }
7843}
7844
7845
7846/*---------------------------------------------------------------------
7847 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007848 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007849 *
7850 * Description: Wait the desired delay.
7851 *
7852 *---------------------------------------------------------------------*/
7853
James Bottomley 47b5d692005-04-24 02:38:05 -05007854static void FPT_Wait(ULONG p_port, UCHAR p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007855{
7856 UCHAR old_timer;
7857 UCHAR green_flag;
7858
7859 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7860
7861 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7862 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7863
7864 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7865 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007866 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007867
7868
7869 WR_HARPOON(p_port+hp_portctrl_0,
7870 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7871
7872 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7873
7874 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7875 break;
7876
7877 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7878 break;
7879 }
7880
7881 WR_HARPOON(p_port+hp_portctrl_0,
7882 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7883
7884 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007885 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007886
7887 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7888
7889 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7890}
7891
7892
7893/*---------------------------------------------------------------------
7894 *
7895 * Function: Enable/Disable Write to EEPROM
7896 *
7897 * Description: The EEPROM must first be enabled for writes
7898 * A total of 9 clocks are needed.
7899 *
7900 *---------------------------------------------------------------------*/
7901
James Bottomley 47b5d692005-04-24 02:38:05 -05007902static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007903{
7904 UCHAR ee_value;
7905
7906 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7907
7908 if (p_mode)
7909
James Bottomley 47b5d692005-04-24 02:38:05 -05007910 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007911
7912 else
7913
7914
James Bottomley 47b5d692005-04-24 02:38:05 -05007915 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007916
7917 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7918 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7919}
7920
7921
7922/*---------------------------------------------------------------------
7923 *
7924 * Function: Write EEPROM
7925 *
7926 * Description: Write a word to the EEPROM at the specified
7927 * address.
7928 *
7929 *---------------------------------------------------------------------*/
7930
James Bottomley 47b5d692005-04-24 02:38:05 -05007931static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007932{
7933
7934 UCHAR ee_value;
7935 USHORT i;
7936
7937 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7938 (SEE_MS | SEE_CS));
7939
7940
7941
James Bottomley 47b5d692005-04-24 02:38:05 -05007942 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007943
7944
7945 ee_value |= (SEE_MS + SEE_CS);
7946
7947 for(i = 0x8000; i != 0; i>>=1) {
7948
7949 if (i & ee_data)
7950 ee_value |= SEE_DO;
7951 else
7952 ee_value &= ~SEE_DO;
7953
7954 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7955 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7956 ee_value |= SEE_CLK; /* Clock data! */
7957 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7958 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7959 ee_value &= ~SEE_CLK;
7960 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7961 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7962 }
7963 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7964 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7965
James Bottomley 47b5d692005-04-24 02:38:05 -05007966 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007967
7968 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7969 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7970 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7971}
7972
7973/*---------------------------------------------------------------------
7974 *
7975 * Function: Read EEPROM
7976 *
7977 * Description: Read a word from the EEPROM at the desired
7978 * address.
7979 *
7980 *---------------------------------------------------------------------*/
7981
James Bottomley 47b5d692005-04-24 02:38:05 -05007982static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007983{
7984 USHORT i, ee_data1, ee_data2;
7985
7986 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007987 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007988 do
7989 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007990 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007991
7992 if(ee_data1 == ee_data2)
7993 return(ee_data1);
7994
7995 ee_data1 = ee_data2;
7996 i++;
7997
7998 }while(i < 4);
7999
8000 return(ee_data1);
8001}
8002
8003/*---------------------------------------------------------------------
8004 *
8005 * Function: Read EEPROM Original
8006 *
8007 * Description: Read a word from the EEPROM at the desired
8008 * address.
8009 *
8010 *---------------------------------------------------------------------*/
8011
James Bottomley 47b5d692005-04-24 02:38:05 -05008012static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07008013{
8014
8015 UCHAR ee_value;
8016 USHORT i, ee_data;
8017
8018 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
8019 (SEE_MS | SEE_CS));
8020
8021
James Bottomley 47b5d692005-04-24 02:38:05 -05008022 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07008023
8024
8025 ee_value |= (SEE_MS + SEE_CS);
8026 ee_data = 0;
8027
8028 for(i = 1; i <= 16; i++) {
8029
8030 ee_value |= SEE_CLK; /* Clock data! */
8031 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8032 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8033 ee_value &= ~SEE_CLK;
8034 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8035 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8036
8037 ee_data <<= 1;
8038
8039 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
8040 ee_data |= 1;
8041 }
8042
8043 ee_value &= ~(SEE_MS + SEE_CS);
8044 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
8045 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
8046
8047 return(ee_data);
8048}
8049
8050
8051/*---------------------------------------------------------------------
8052 *
8053 * Function: Send EE command and Address to the EEPROM
8054 *
8055 * Description: Transfers the correct command and sends the address
8056 * to the eeprom.
8057 *
8058 *---------------------------------------------------------------------*/
8059
James Bottomley 47b5d692005-04-24 02:38:05 -05008060static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07008061{
8062 UCHAR ee_value;
8063 UCHAR narrow_flg;
8064
8065 USHORT i;
8066
8067
8068 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
8069
8070
8071 ee_value = SEE_MS;
8072 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8073
8074 ee_value |= SEE_CS; /* Set CS to EEPROM */
8075 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8076
8077
8078 for(i = 0x04; i != 0; i>>=1) {
8079
8080 if (i & ee_cmd)
8081 ee_value |= SEE_DO;
8082 else
8083 ee_value &= ~SEE_DO;
8084
8085 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8086 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8087 ee_value |= SEE_CLK; /* Clock data! */
8088 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8089 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8090 ee_value &= ~SEE_CLK;
8091 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8092 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8093 }
8094
8095
8096 if (narrow_flg)
8097 i = 0x0080;
8098
8099 else
8100 i = 0x0200;
8101
8102
8103 while (i != 0) {
8104
8105 if (i & ee_addr)
8106 ee_value |= SEE_DO;
8107 else
8108 ee_value &= ~SEE_DO;
8109
8110 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8111 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8112 ee_value |= SEE_CLK; /* Clock data! */
8113 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8114 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8115 ee_value &= ~SEE_CLK;
8116 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8117 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
8118
8119 i >>= 1;
8120 }
8121}
8122
James Bottomley 47b5d692005-04-24 02:38:05 -05008123static USHORT FPT_CalcCrc16(UCHAR buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07008124{
8125 USHORT crc=0;
8126 int i,j;
8127 USHORT ch;
8128 for (i=0; i < ID_STRING_LENGTH; i++)
8129 {
8130 ch = (USHORT) buffer[i];
8131 for(j=0; j < 8; j++)
8132 {
8133 if ((crc ^ ch) & 1)
8134 crc = (crc >> 1) ^ CRCMASK;
8135 else
8136 crc >>= 1;
8137 ch >>= 1;
8138 }
8139 }
8140 return(crc);
8141}
8142
James Bottomley 47b5d692005-04-24 02:38:05 -05008143static UCHAR FPT_CalcLrc(UCHAR buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07008144{
8145 int i;
8146 UCHAR lrc;
8147 lrc = 0;
8148 for(i = 0; i < ID_STRING_LENGTH; i++)
8149 lrc ^= buffer[i];
8150 return(lrc);
8151}
8152
8153
8154
8155/*
8156 The following inline definitions avoid type conflicts.
8157*/
8158
8159static inline unsigned char
8160FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
8161{
8162 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
8163}
8164
8165
8166static inline FlashPoint_CardHandle_T
8167FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
8168{
8169 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
8170}
8171
8172static inline void
8173FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
8174{
8175 FlashPoint_ReleaseHostAdapter(CardHandle);
8176}
8177
8178
8179static inline void
8180FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
8181{
8182 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
8183}
8184
8185
8186static inline void
8187FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
8188{
8189 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
8190}
8191
8192
8193static inline boolean
8194FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
8195{
8196 return FlashPoint_InterruptPending(CardHandle);
8197}
8198
8199
8200static inline int
8201FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
8202{
8203 return FlashPoint_HandleInterrupt(CardHandle);
8204}
8205
8206
8207#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
8208#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
8209#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
8210#define FlashPoint_StartCCB FlashPoint__StartCCB
8211#define FlashPoint_AbortCCB FlashPoint__AbortCCB
8212#define FlashPoint_InterruptPending FlashPoint__InterruptPending
8213#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
8214
8215
Linus Torvalds1da177e2005-04-16 15:20:36 -07008216#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
8217
8218
8219/*
8220 Define prototypes for the FlashPoint SCCB Manager Functions.
8221*/
8222
8223extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
8224extern FlashPoint_CardHandle_T
8225 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
8226extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
8227extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
8228extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
8229extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
8230extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07008231
8232
8233#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */