blob: 696f31c5df76bd1a0b2ec3f71ecfb8a2b06156d7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#define CRCMASK 0xA001
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define FAILURE 0xFFFFFFFFL
41
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080051#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080052#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
54
55
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -080056struct sccb;
57typedef void (*CALL_BK_FN)(struct sccb *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59
Alexey Dobriyan7f101662006-03-08 00:14:30 -080060struct sccb_mgr_info {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080061 unsigned long si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080062 unsigned char si_present;
63 unsigned char si_intvect;
64 unsigned char si_id;
65 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080066 unsigned short si_fw_revision;
67 unsigned short si_per_targ_init_sync;
68 unsigned short si_per_targ_fast_nego;
69 unsigned short si_per_targ_ultra_nego;
70 unsigned short si_per_targ_no_disc;
71 unsigned short si_per_targ_wide_nego;
72 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080073 unsigned char si_card_family;
74 unsigned char si_bustype;
75 unsigned char si_card_model[3];
76 unsigned char si_relative_cardnum;
77 unsigned char si_reserved[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080078 unsigned long si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080079 unsigned char si_XlatInfo[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080080 unsigned long si_reserved2[5];
81 unsigned long si_secondary_range;
Alexey Dobriyan7f101662006-03-08 00:14:30 -080082};
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
85
James Bottomley 47b5d692005-04-24 02:38:05 -050086#define SCSI_PARITY_ENA 0x0001
87#define LOW_BYTE_TERM 0x0010
88#define HIGH_BYTE_TERM 0x0020
89#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
91#define SUPPORT_16TAR_32LUN 0x0002
92#define SOFT_RESET 0x0004
93#define EXTENDED_TRANSLATION 0x0008
94#define POST_ALL_UNDERRRUNS 0x0040
95#define FLAG_SCAM_ENABLED 0x0080
96#define FLAG_SCAM_LEVEL2 0x0100
97
98
99
100
101#define HARPOON_FAMILY 0x02
102
103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Alexey Dobriyan323579882006-01-15 02:12:54 +0100105/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 * The UCB Manager treats the SCCB as it's 'native hardware structure'
107 */
108
109
110#pragma pack(1)
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800111struct sccb {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800112 unsigned char OperationCode;
113 unsigned char ControlByte;
114 unsigned char CdbLength;
115 unsigned char RequestSenseLength;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800116 unsigned long DataLength;
117 unsigned long DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800118 unsigned char CcbRes[2];
119 unsigned char HostStatus;
120 unsigned char TargetStatus;
121 unsigned char TargID;
122 unsigned char Lun;
123 unsigned char Cdb[12];
124 unsigned char CcbRes1;
125 unsigned char Reserved1;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800126 unsigned long Reserved2;
127 unsigned long SensePointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
129
130 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800131 unsigned long SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800132 unsigned char SccbStatus;
133 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800134 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800137 unsigned long Sccb_XferCnt; /* actual transfer count */
138 unsigned long Sccb_ATC;
139 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
140 unsigned long Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800141 unsigned short Sccb_MGRFlags;
142 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800143 unsigned char Sccb_scsimsg; /* identify msg for selection */
144 unsigned char Sccb_tag;
145 unsigned char Sccb_scsistat;
146 unsigned char Sccb_idmsg; /* image of last msg in */
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800147 struct sccb * Sccb_forwardlink;
148 struct sccb * Sccb_backlink;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800149 unsigned long Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800150 unsigned char Save_Cdb[6];
151 unsigned char Save_CdbLen;
152 unsigned char Sccb_XferState;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800153 unsigned long Sccb_SGoffset;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800154 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
157#pragma pack()
158
159
160
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161#define SCATTER_GATHER_COMMAND 0x02
162#define RESIDUAL_COMMAND 0x03
163#define RESIDUAL_SG_COMMAND 0x04
164#define RESET_COMMAND 0x81
165
166
167#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
168#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169#define SCCB_DATA_XFER_OUT 0x10 /* Write */
170#define SCCB_DATA_XFER_IN 0x08 /* Read */
171
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
174
175
176#define BUS_FREE_ST 0
177#define SELECT_ST 1
178#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
179#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
180#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
181#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
182#define COMMAND_ST 6
183#define DATA_OUT_ST 7
184#define DATA_IN_ST 8
185#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
188
189#define F_HOST_XFER_DIR 0x01
190#define F_ALL_XFERRED 0x02
191#define F_SG_XFER 0x04
192#define F_AUTO_SENSE 0x08
193#define F_ODD_BALL_CNT 0x10
194#define F_NO_DATA_YET 0x80
195
196
197#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198#define F_DEV_SELECTED 0x04
199
200
201#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
202#define SCCB_DATA_UNDER_RUN 0x0C
203#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
204#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
208#define SCCB_BM_ERR 0x30 /* BusMaster error. */
209#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
210
211
212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
214
215#define SCCB_IN_PROCESS 0x00
216#define SCCB_SUCCESS 0x01
217#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222#define ORION_FW_REV 3110
223
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
James Bottomley 47b5d692005-04-24 02:38:05 -0500231#define MAX_SCSI_TAR 16
232#define MAX_LUN 32
233#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
237#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239
Alexey Dobriyanad0e1d92006-03-08 00:14:28 -0800240#define RD_HARPOON(ioport) inb((u32)ioport)
241#define RDW_HARPOON(ioport) inw((u32)ioport)
242#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
243#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
244#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
245#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247
248#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249#define SYNC_TRYING BIT(6)
250#define SYNC_SUPPORTED (BIT(7)+BIT(6))
251
252#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253#define WIDE_ENABLED BIT(4)
254#define WIDE_NEGOCIATED BIT(5)
255
256#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257#define TAG_Q_TRYING BIT(2)
258#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260#define TAR_ALLOW_DISC BIT(0)
261
262
263#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264#define EE_SYNC_5MB BIT(0)
265#define EE_SYNC_10MB BIT(1)
266#define EE_SYNC_20MB (BIT(0)+BIT(1))
267
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268#define EE_WIDE_SCSI BIT(7)
269
270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -0800273struct sccb_mgr_tar_info {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800275 struct sccb * TarSelQ_Head;
276 struct sccb * TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800277 unsigned char TarLUN_CA; /*Contingent Allgiance */
278 unsigned char TarTagQ_Cnt;
279 unsigned char TarSelQ_Cnt;
280 unsigned char TarStatus;
281 unsigned char TarEEValue;
282 unsigned char TarSyncCtrl;
283 unsigned char TarReserved[2]; /* for alignment */
284 unsigned char LunDiscQ_Idx[MAX_LUN];
285 unsigned char TarLUNBusy[MAX_LUN];
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -0800286};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800288struct nvram_info {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800289 unsigned char niModel; /* Model No. of card */
290 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800291 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800292 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
293 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
294 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
295 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
296 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
297 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800298};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
301#define MODEL_LT 1
302#define MODEL_DL 2
303#define MODEL_LW 3
304#define MODEL_DW 4
305
306
307typedef struct SCCBcard {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800308 struct sccb * currentSCCB;
Alexey Dobriyan7f101662006-03-08 00:14:30 -0800309 struct sccb_mgr_info * cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800311 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800313 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800314 unsigned char discQCount;
315 unsigned char tagQ_Lst;
316 unsigned char cardIndex;
317 unsigned char scanIndex;
318 unsigned char globalFlags;
319 unsigned char ourId;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800320 struct nvram_info * pNvRamInfo;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800321 struct sccb * discQ_Tbl[QUEUE_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
323}SCCBCARD;
324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
327
328#define F_TAG_STARTED 0x01
329#define F_CONLUN_IO 0x02
330#define F_DO_RENEGO 0x04
331#define F_NO_FILTER 0x08
332#define F_GREEN_PC 0x10
333#define F_HOST_XFER_ACT 0x20
334#define F_NEW_SCCB_CMD 0x40
335#define F_UPDATE_EEPROM 0x80
336
337
338#define ID_STRING_LENGTH 32
339#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
340
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
342#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
343
344#define ASSIGN_ID 0x00
345#define SET_P_FLAG 0x01
346#define CFG_CMPLT 0x03
347#define DOM_MSTR 0x0F
348#define SYNC_PTRN 0x1F
349
350#define ID_0_7 0x18
351#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352#define MISC_CODE 0x14
353#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
356
357#define INIT_SELTD 0x01
358#define LEVEL2_TAR 0x02
359
360
361enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
362 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
363 CLR_PRIORITY,NO_ID_AVAIL };
364
365typedef struct SCCBscam_info {
366
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800367 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 enum scam_id_st state;
369
Alexey Dobriyan85ae97d2006-03-08 00:14:22 -0800370} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374#define SCSI_READ 0x08
375#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377#define SCSI_READ_EXTENDED 0x28
378#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380
381
382
383#define SSGOOD 0x00
384#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385#define SSQ_FULL 0x28
386
387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389
390#define SMCMD_COMP 0x00
391#define SMEXT 0x01
392#define SMSAVE_DATA_PTR 0x02
393#define SMREST_DATA_PTR 0x03
394#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395#define SMABORT 0x06
396#define SMREJECT 0x07
397#define SMNO_OP 0x08
398#define SMPARITY 0x09
399#define SMDEV_RESET 0x0C
400#define SMABORT_TAG 0x0D
401#define SMINIT_RECOVERY 0x0F
402#define SMREL_RECOVERY 0x10
403
404#define SMIDENT 0x80
405#define DISC_PRIV 0x40
406
407
408#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409#define SMWDTR 0x03
410#define SM8BIT 0x00
411#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412#define SMIGNORWR 0x23 /* Ignore Wide Residue */
413
414
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
416
417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
419
420
421#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422#define TWELVE_BYTE_CMD 0x0C
423
424#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
426
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
428#define EEPROM_WD_CNT 256
429
430#define EEPROM_CHECK_SUM 0
431#define FW_SIGNATURE 2
432#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435#define SYSTEM_CONFIG 16
436#define SCSI_CONFIG 17
437#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438#define SCAM_CONFIG 20
439#define ADAPTER_SCSI_ID 24
440
441
442#define IGNORE_B_SCAN 32
443#define SEND_START_ENA 34
444#define DEVICE_ENABLE 36
445
446#define SYNC_RATE_TBL 38
447#define SYNC_RATE_TBL01 38
448#define SYNC_RATE_TBL23 40
449#define SYNC_RATE_TBL45 42
450#define SYNC_RATE_TBL67 44
451#define SYNC_RATE_TBL89 46
452#define SYNC_RATE_TBLab 48
453#define SYNC_RATE_TBLcd 50
454#define SYNC_RATE_TBLef 52
455
456
457
458#define EE_SCAMBASE 256
459
460
461
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 #define SCAM_ENABLED BIT(2)
463 #define SCAM_LEVEL2 BIT(3)
464
465
466 #define RENEGO_ENA BITW(10)
467 #define CONNIO_ENA BITW(11)
468 #define GREEN_PC_ENA BITW(12)
469
470
471 #define AUTO_RATE_00 00
472 #define AUTO_RATE_05 01
473 #define AUTO_RATE_10 02
474 #define AUTO_RATE_20 03
475
476 #define WIDE_NEGO_BIT BIT(7)
477 #define DISC_ENABLE_BIT BIT(6)
478
479
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481 #define hp_vendor_id_0 0x00 /* LSB */
482 #define ORION_VEND_0 0x4B
483
484 #define hp_vendor_id_1 0x01 /* MSB */
485 #define ORION_VEND_1 0x10
486
487 #define hp_device_id_0 0x02 /* LSB */
488 #define ORION_DEV_0 0x30
489
490 #define hp_device_id_1 0x03 /* MSB */
491 #define ORION_DEV_1 0x81
492
493 /* Sub Vendor ID and Sub Device ID only available in
494 Harpoon Version 2 and higher */
495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497
498
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500 #define hp_semaphore 0x0C
501 #define SCCB_MGR_ACTIVE BIT(0)
502 #define TICKLE_ME BIT(1)
503 #define SCCB_MGR_PRESENT BIT(3)
504 #define BIOS_IN_USE BIT(4)
505
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
508 #define hp_sys_ctrl 0x0F
509
510 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
511 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
512 #define HALT_MACH BIT(3) /*Halt State Machine */
513 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514
515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Alexey Dobriyan85ae97d2006-03-08 00:14:22 -0800519
520
521
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522
523 #define hp_host_blk_cnt 0x13
524
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
526
527 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
528
529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
531 #define hp_int_mask 0x17
532
533 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
534 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535
536
537 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 #define hp_xfer_cnt_hi 0x1A
539 #define hp_xfer_cmd 0x1B
540
541 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
542 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543
544
545 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
550
551 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
552 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553
554 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 #define hp_ee_ctrl 0x22
558
559 #define EXT_ARB_ACK BIT(7)
560 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
561 #define SEE_MS BIT(5)
562 #define SEE_CS BIT(3)
563 #define SEE_CLK BIT(2)
564 #define SEE_DO BIT(1)
565 #define SEE_DI BIT(0)
566
567 #define EE_READ 0x06
568 #define EE_WRITE 0x05
569 #define EWEN 0x04
570 #define EWEN_ADDR 0x03C0
571 #define EWDS 0x04
572 #define EWDS_ADDR 0x0000
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576
577
578
579
580 #define hp_bm_ctrl 0x26
581
582 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
583 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
585 #define FAST_SINGLE BIT(6) /*?? */
586
587 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
590 #define hp_sg_addr 0x28
591 #define hp_page_ctrl 0x29
592
593 #define SCATTER_EN BIT(0)
594 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
596 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601 #define hp_pci_stat_cfg 0x2D
602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
612 #define hp_rev_num 0x33
613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614
615 #define hp_stack_data 0x34
616 #define hp_stack_addr 0x35
617
618 #define hp_ext_status 0x36
619
620 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
621 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
622 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 #define CMD_ABORTED BIT(4) /*Command aborted */
624 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
625 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
626 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
627 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
628 BM_PARITY_ERR | PIO_OVERRUN)
629
630 #define hp_int_status 0x37
631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
633 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
636
637 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640
641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 #define hp_intena 0x40
643
644 #define RESET BITW(7)
645 #define PROG_HLT BITW(6)
646 #define PARITY BITW(5)
647 #define FIFO BITW(4)
648 #define SEL BITW(3)
649 #define SCAM_SEL BITW(2)
650 #define RSEL BITW(1)
651 #define TIMEOUT BITW(0)
652 #define BUS_FREE BITW(15)
653 #define XFER_CNT_0 BITW(14)
654 #define PHASE BITW(13)
655 #define IUNKWN BITW(12)
656 #define ICMD_COMP BITW(11)
657 #define ITICKLE BITW(10)
658 #define IDO_STRT BITW(9)
659 #define ITAR_DISC BITW(8)
660 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
661 #define CLR_ALL_INT 0xFFFF
662 #define CLR_ALL_INT_1 0xFF00
663
664 #define hp_intstat 0x42
665
666 #define hp_scsisig 0x44
667
668 #define SCSI_SEL BIT(7)
669 #define SCSI_BSY BIT(6)
670 #define SCSI_REQ BIT(5)
671 #define SCSI_ACK BIT(4)
672 #define SCSI_ATN BIT(3)
673 #define SCSI_CD BIT(2)
674 #define SCSI_MSG BIT(1)
675 #define SCSI_IOBIT BIT(0)
676
677 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
680 #define S_DATAI_PH ( BIT(0))
681 #define S_DATAO_PH 0x00
682 #define S_ILL_PH ( BIT(1) )
683
684 #define hp_scsictrl_0 0x45
685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 #define SEL_TAR BIT(6)
687 #define ENA_ATN BIT(4)
688 #define ENA_RESEL BIT(2)
689 #define SCSI_RST BIT(1)
690 #define ENA_SCAM_SEL BIT(0)
691
692
693
694 #define hp_portctrl_0 0x46
695
696 #define SCSI_PORT BIT(7)
697 #define SCSI_INBIT BIT(6)
698 #define DMA_PORT BIT(5)
699 #define DMA_RD BIT(4)
700 #define HOST_PORT BIT(3)
701 #define HOST_WRT BIT(2)
702 #define SCSI_BUS_EN BIT(1)
703 #define START_TO BIT(0)
704
705 #define hp_scsireset 0x47
706
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 #define SCSI_INI BIT(6)
708 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 #define DMA_RESET BIT(3)
710 #define HPSCSI_RESET BIT(2)
711 #define PROG_RESET BIT(1)
712 #define FIFO_CLR BIT(0)
713
714 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
717 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 #define hp_addstat 0x4E
719
720 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 #define SCSI_MODE8 BIT(3)
722 #define SCSI_PAR_ERR BIT(0)
723
724 #define hp_prgmcnt_0 0x4F
725
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
727 #define hp_selfid_0 0x50
728 #define hp_selfid_1 0x51
729 #define hp_arb_id 0x52
730
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731
732 #define hp_select_id 0x53
733
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734
735 #define hp_synctarg_base 0x54
736 #define hp_synctarg_12 0x54
737 #define hp_synctarg_13 0x55
738 #define hp_synctarg_14 0x56
739 #define hp_synctarg_15 0x57
740
741 #define hp_synctarg_8 0x58
742 #define hp_synctarg_9 0x59
743 #define hp_synctarg_10 0x5A
744 #define hp_synctarg_11 0x5B
745
746 #define hp_synctarg_4 0x5C
747 #define hp_synctarg_5 0x5D
748 #define hp_synctarg_6 0x5E
749 #define hp_synctarg_7 0x5F
750
751 #define hp_synctarg_0 0x60
752 #define hp_synctarg_1 0x61
753 #define hp_synctarg_2 0x62
754 #define hp_synctarg_3 0x63
755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 #define DEFAULT_OFFSET 0x0F
758
759 #define hp_autostart_0 0x64
760 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 #define hp_autostart_3 0x67
762
763
764
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 #define AUTO_IMMED BIT(5)
766 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768
769 #define hp_gp_reg_0 0x68
770 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 #define hp_gp_reg_3 0x6B
772
773 #define hp_seltimeout 0x6C
774
775
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 #define TO_4ms 0x67 /* 3.9959ms */
777
778 #define TO_5ms 0x03 /* 4.9152ms */
779 #define TO_10ms 0x07 /* 11.xxxms */
780 #define TO_250ms 0x99 /* 250.68ms */
781 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782
783 #define hp_clkctrl_0 0x6D
784
785 #define PWR_DWN BIT(6)
786 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788
789 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
790
791 #define hp_fiforead 0x6E
792 #define hp_fifowrite 0x6F
793
794 #define hp_offsetctr 0x70
795 #define hp_xferstat 0x71
796
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
799 #define hp_portctrl_1 0x72
800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 #define CHK_SCSI_P BIT(3)
802 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
804 #define hp_xfer_pad 0x73
805
806 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807
808 #define hp_scsidata_0 0x74
809 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
813 #define hp_aramBase 0x80
814 #define BIOS_DATA_OFFSET 0x60
815 #define BIOS_RELATIVE_CARD 0x64
816
817
818
819
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 #define AR3 (BITW(9) + BITW(8))
821 #define SDATA BITW(10)
822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
824 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
825
826 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
827
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
830 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
831
832 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
833
834
835 #define ADATA_OUT 0x00
836 #define ADATA_IN BITW(8)
837 #define ACOMMAND BITW(10)
838 #define ASTATUS (BITW(10)+BITW(8))
839 #define AMSG_OUT (BITW(10)+BITW(9))
840 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
842
843 #define BRH_OP BITW(13) /* Branch */
844
845
846 #define ALWAYS 0x00
847 #define EQUAL BITW(8)
848 #define NOT_EQ BITW(9)
849
850 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
851
852
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
855
856 #define MPM_OP BITW(15) /* Match phase and move data */
857
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
859 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
860
861
862 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
863
864
865 #define D_AR0 0x00
866 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
868
869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
876
877 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
878
879 #define SSI_OP (BITW(15)+BITW(11))
880
881
882 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
883 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
885 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
886 #define SSI_ITICKLE (ITICKLE >> 8)
887
888 #define SSI_IUNKWN (IUNKWN >> 8)
889 #define SSI_INO_CC (IUNKWN >> 8)
890 #define SSI_IRFAIL (IUNKWN >> 8)
891
892
893 #define NP 0x10 /*Next Phase */
894 #define NTCMD 0x02 /*Non- Tagged Command start */
895 #define CMDPZ 0x04 /*Command phase */
896 #define DINT 0x12 /*Data Out/In interrupt */
897 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 #define DC 0x19 /*Disconnect Message */
899 #define ST 0x1D /*Status Phase */
900 #define UNKNWN 0x24 /*Unknown bus action */
901 #define CC 0x25 /*Command Completion failure */
902 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
904
905
906 #define ID_MSG_STRT hp_aramBase + 0x00
907 #define NON_TAG_ID_MSG hp_aramBase + 0x06
908 #define CMD_STRT hp_aramBase + 0x08
909 #define SYNC_MSGS hp_aramBase + 0x08
910
911
912
913
914
915 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 #define DISCONNECT_START 0x10/2
917 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 #define SELCHK_STRT SELCHK/2
920
921
922
923
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
925
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Alexey Dobriyan85ae97d2006-03-08 00:14:22 -0800927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
929#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
930/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
931 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800932 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800934#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800936 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800938 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 count >>= 16,\
940 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941
942#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
943 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
944
945
946#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
947 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
948
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
951#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
952 WR_HARPOON(port+hp_scsireset, 0x00))
953
954#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
955 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
956
957#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
958 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
959
960#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
961 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
962
963#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
964 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
965
966
967
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800969static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
970static void FPT_ssel(unsigned long port, unsigned char p_card);
971static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800972static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800973static void FPT_stsyncn(unsigned long port, unsigned char p_card);
974static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
975static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -0800976 struct sccb_mgr_tar_info * currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800977static void FPT_sresb(unsigned long port, unsigned char p_card);
978static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
979static void FPT_schkdd(unsigned long port, unsigned char p_card);
980static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
981static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
982static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800984static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800985static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
986 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800988static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800989static void FPT_RNVRamData(struct nvram_info * pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800991static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
992static void FPT_stwidn(unsigned long port, unsigned char p_card);
993static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994
995
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800996static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800997static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
998static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800999 unsigned char p_card);
1000static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1001static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001002static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1003static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1004static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001005static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001006static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001009static void FPT_Wait1Second(unsigned long p_port);
1010static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1011static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1012static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1013static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1014static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1015static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016
1017
1018
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001019static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1020static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1021static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1022static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1023static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1024static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1025static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001027static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1028static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1029static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030
1031
1032
1033
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001034static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1035static void FPT_BusMasterInit(unsigned long p_port);
1036static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
1038
1039
1040
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001041static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001042static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1043static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1044static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1045static void FPT_hostDataXferRestart(struct sccb * currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
1047
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001048static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001049 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
James Bottomley 47b5d692005-04-24 02:38:05 -05001051static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001052static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1053static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055
1056
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001057static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001059static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1060static void FPT_scbusf(unsigned long p_port);
1061static void FPT_scsel(unsigned long p_port);
1062static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1063static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1064static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1065static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1066static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1067static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001068static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001069static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1070static void FPT_scwtsel(unsigned long p_port);
1071static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1072static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001073static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
1075
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001076static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1077static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
1079
1080
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08001082static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
James Bottomley 47b5d692005-04-24 02:38:05 -05001083static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1084static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001085static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086
1087
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001088static unsigned char FPT_mbCards = 0;
1089static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001090 ' ', 'B', 'T', '-', '9', '3', '0', \
1091 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1092 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001094static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
1096
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001097static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
1100/*---------------------------------------------------------------------
1101 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001102 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 *
1104 * Description: Setup and/or Search for cards and return info to caller.
1105 *
1106 *---------------------------------------------------------------------*/
1107
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001108static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001110 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001112 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001113 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001114 unsigned long ioport;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001115 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
1119
1120 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1121 return((int)FAILURE);
1122
1123 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1124 return((int)FAILURE);
1125
1126 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1127 return((int)FAILURE);
1128
1129 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1130 return((int)FAILURE);
1131
1132
1133 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1134
1135/* For new Harpoon then check for sub_device ID LSB
1136 the bits(0-3) must be all ZERO for compatible with
1137 current version of SCCBMgr, else skip this Harpoon
1138 device. */
1139
1140 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1141 return((int)FAILURE);
1142 }
1143
1144 if (first_time)
1145 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001146 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001148 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 }
1150
James Bottomley 47b5d692005-04-24 02:38:05 -05001151 if(FPT_RdStack(ioport, 0) != 0x00) {
1152 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 {
1154 pCurrNvRam = NULL;
1155 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001156 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1157 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 }
1159 else
1160 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001161 if(FPT_mbCards < MAX_MB_CARDS) {
1162 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1163 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001165 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 }else
1167 return((int) FAILURE);
1168 }
1169 }else
1170 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
1172 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1173 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1174
1175 if(pCurrNvRam)
1176 pCardInfo->si_id = pCurrNvRam->niAdapId;
1177 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001178 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1179 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
1181 pCardInfo->si_lun = 0x00;
1182 pCardInfo->si_fw_revision = ORION_FW_REV;
1183 temp2 = 0x0000;
1184 temp3 = 0x0000;
1185 temp4 = 0x0000;
1186 temp5 = 0x0000;
1187 temp6 = 0x0000;
1188
1189 for (id = 0; id < (16/2); id++) {
1190
1191 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001192 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1194 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1195 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001196 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197
1198 for (i = 0; i < 2; temp >>=8,i++) {
1199
1200 temp2 >>= 1;
1201 temp3 >>= 1;
1202 temp4 >>= 1;
1203 temp5 >>= 1;
1204 temp6 >>= 1;
1205 switch (temp & 0x3)
1206 {
1207 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1208 temp6 |= 0x8000; /* Fall through */
1209 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1210 temp5 |= 0x8000; /* Fall through */
1211 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1212 temp2 |= 0x8000; /* Fall through */
1213 case AUTO_RATE_00: /* Asynchronous */
1214 break;
1215 }
1216
1217 if (temp & DISC_ENABLE_BIT)
1218 temp3 |= 0x8000;
1219
1220 if (temp & WIDE_NEGO_BIT)
1221 temp4 |= 0x8000;
1222
1223 }
1224 }
1225
1226 pCardInfo->si_per_targ_init_sync = temp2;
1227 pCardInfo->si_per_targ_no_disc = temp3;
1228 pCardInfo->si_per_targ_wide_nego = temp4;
1229 pCardInfo->si_per_targ_fast_nego = temp5;
1230 pCardInfo->si_per_targ_ultra_nego = temp6;
1231
1232 if(pCurrNvRam)
1233 i = pCurrNvRam->niSysConf;
1234 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001235 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236
1237 if(pCurrNvRam)
1238 ScamFlg = pCurrNvRam->niScamConf;
1239 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001240 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
1242 pCardInfo->si_flags = 0x0000;
1243
1244 if (i & 0x01)
1245 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1246
1247 if (!(i & 0x02))
1248 pCardInfo->si_flags |= SOFT_RESET;
1249
1250 if (i & 0x10)
1251 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1252
1253 if (ScamFlg & SCAM_ENABLED)
1254 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1255
1256 if (ScamFlg & SCAM_LEVEL2)
1257 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1258
1259 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1260 if (i & 0x04) {
1261 j |= SCSI_TERM_ENA_L;
1262 }
1263 WR_HARPOON(ioport+hp_bm_ctrl, j );
1264
1265 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1266 if (i & 0x08) {
1267 j |= SCSI_TERM_ENA_H;
1268 }
1269 WR_HARPOON(ioport+hp_ee_ctrl, j );
1270
1271 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1272
1273 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1274
1275 pCardInfo->si_card_family = HARPOON_FAMILY;
1276 pCardInfo->si_bustype = BUSTYPE_PCI;
1277
1278 if(pCurrNvRam){
1279 pCardInfo->si_card_model[0] = '9';
1280 switch(pCurrNvRam->niModel & 0x0f){
1281 case MODEL_LT:
1282 pCardInfo->si_card_model[1] = '3';
1283 pCardInfo->si_card_model[2] = '0';
1284 break;
1285 case MODEL_LW:
1286 pCardInfo->si_card_model[1] = '5';
1287 pCardInfo->si_card_model[2] = '0';
1288 break;
1289 case MODEL_DL:
1290 pCardInfo->si_card_model[1] = '3';
1291 pCardInfo->si_card_model[2] = '2';
1292 break;
1293 case MODEL_DW:
1294 pCardInfo->si_card_model[1] = '5';
1295 pCardInfo->si_card_model[2] = '2';
1296 break;
1297 }
1298 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001299 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001300 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001301 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001303 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1304 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 }
1306
1307 if (pCardInfo->si_card_model[1] == '3')
1308 {
1309 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1310 pCardInfo->si_flags |= LOW_BYTE_TERM;
1311 }
1312 else if (pCardInfo->si_card_model[2] == '0')
1313 {
1314 temp = RD_HARPOON(ioport+hp_xfer_pad);
1315 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1316 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1317 pCardInfo->si_flags |= LOW_BYTE_TERM;
1318 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1319 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1320 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1321 WR_HARPOON(ioport+hp_xfer_pad, temp);
1322 }
1323 else
1324 {
1325 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1326 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1327 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1328 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1329 temp3 = 0;
1330 for (i = 0; i < 8; i++)
1331 {
1332 temp3 <<= 1;
1333 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1334 temp3 |= 1;
1335 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1336 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1337 }
1338 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1339 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1340 if (!(temp3 & BIT(7)))
1341 pCardInfo->si_flags |= LOW_BYTE_TERM;
1342 if (!(temp3 & BIT(6)))
1343 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1344 }
1345
1346
1347 ARAM_ACCESS(ioport);
1348
1349 for ( i = 0; i < 4; i++ ) {
1350
1351 pCardInfo->si_XlatInfo[i] =
1352 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1353 }
1354
1355 /* return with -1 if no sort, else return with
1356 logical card number sorted by BIOS (zero-based) */
1357
1358 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001359 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360
1361 SGRAM_ACCESS(ioport);
1362
James Bottomley 47b5d692005-04-24 02:38:05 -05001363 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1364 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1365 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1366 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1367 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1368 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1369 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1370 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
1372 pCardInfo->si_present = 0x01;
1373
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 return(0);
1375}
1376
1377
1378/*---------------------------------------------------------------------
1379 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001380 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 *
1382 * Description: Setup adapter for normal operation (hard reset).
1383 *
1384 *---------------------------------------------------------------------*/
1385
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001386static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387{
1388 PSCCBcard CurrCard = NULL;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001389 struct nvram_info * pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001390 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001391 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001392 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
1396 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1397
1398 if (thisCard == MAX_CARDS) {
1399
1400 return(FAILURE);
1401 }
1402
James Bottomley 47b5d692005-04-24 02:38:05 -05001403 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
James Bottomley 47b5d692005-04-24 02:38:05 -05001405 CurrCard = &FPT_BL_Card[thisCard];
1406 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 break;
1408 }
1409
James Bottomley 47b5d692005-04-24 02:38:05 -05001410 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
James Bottomley 47b5d692005-04-24 02:38:05 -05001412 FPT_BL_Card[thisCard].ioPort = ioport;
1413 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
James Bottomley 47b5d692005-04-24 02:38:05 -05001415 if(FPT_mbCards)
1416 for(i = 0; i < FPT_mbCards; i++){
1417 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1418 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001420 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 CurrCard->cardIndex = thisCard;
1422 CurrCard->cardInfo = pCardInfo;
1423
1424 break;
1425 }
1426 }
1427
1428 pCurrNvRam = CurrCard->pNvRamInfo;
1429
1430 if(pCurrNvRam){
1431 ScamFlg = pCurrNvRam->niScamConf;
1432 }
1433 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001434 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 }
1436
1437
James Bottomley 47b5d692005-04-24 02:38:05 -05001438 FPT_BusMasterInit(ioport);
1439 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
James Bottomley 47b5d692005-04-24 02:38:05 -05001441 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443
1444 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1445
1446 WR_HARPOON(ioport+hp_selfid_0, id);
1447 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1448 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1449 CurrCard->ourId = pCardInfo->si_id;
1450
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001451 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 if (i & SCSI_PARITY_ENA)
1453 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1454
1455 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1456 if (i & LOW_BYTE_TERM)
1457 j |= SCSI_TERM_ENA_L;
1458 WR_HARPOON(ioport+hp_bm_ctrl, j);
1459
1460 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1461 if (i & HIGH_BYTE_TERM)
1462 j |= SCSI_TERM_ENA_H;
1463 WR_HARPOON(ioport+hp_ee_ctrl, j );
1464
1465
1466 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1467
James Bottomley 47b5d692005-04-24 02:38:05 -05001468 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
James Bottomley 47b5d692005-04-24 02:38:05 -05001470 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 }
1472
1473
1474
1475 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1476 CurrCard->globalFlags |= F_NO_FILTER;
1477
1478 if(pCurrNvRam){
1479 if(pCurrNvRam->niSysConf & 0x10)
1480 CurrCard->globalFlags |= F_GREEN_PC;
1481 }
1482 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001483 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 CurrCard->globalFlags |= F_GREEN_PC;
1485 }
1486
1487 /* Set global flag to indicate Re-Negotiation to be done on all
1488 ckeck condition */
1489 if(pCurrNvRam){
1490 if(pCurrNvRam->niScsiConf & 0x04)
1491 CurrCard->globalFlags |= F_DO_RENEGO;
1492 }
1493 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001494 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 CurrCard->globalFlags |= F_DO_RENEGO;
1496 }
1497
1498 if(pCurrNvRam){
1499 if(pCurrNvRam->niScsiConf & 0x08)
1500 CurrCard->globalFlags |= F_CONLUN_IO;
1501 }
1502 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001503 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 CurrCard->globalFlags |= F_CONLUN_IO;
1505 }
1506
1507
1508 temp = pCardInfo->si_per_targ_no_disc;
1509
1510 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1511
1512 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001513 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 }
1515
1516 sync_bit_map = 0x0001;
1517
1518 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1519
1520 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001521 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1523 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1524 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001525 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
1527 for (i = 0; i < 2; temp >>=8,i++) {
1528
1529 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1530
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001531 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 }
1533
1534 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001535 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1536 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001537 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 }
1539
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1541 (id*2+i >= 8)){
1542*/
1543 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1544
James Bottomley 47b5d692005-04-24 02:38:05 -05001545 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 }
1548
1549 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001550 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 }
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
1554 sync_bit_map <<= 1;
1555
1556
1557
1558 }
1559 }
1560
1561 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001562 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001564 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565}
1566
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001567static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001569 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001570 unsigned long portBase;
1571 unsigned long regOffset;
1572 unsigned long scamData;
1573 unsigned long *pScamTbl;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001574 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
1576 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1577
1578 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001579 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1580 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
1585 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001586 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
1588 portBase = pCurrNvRam->niBaseAddr;
1589
1590 for(i = 0; i < MAX_SCSI_TAR; i++){
1591 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001592 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 scamData = *pScamTbl;
1594 WR_HARP32(portBase, regOffset, scamData);
1595 }
1596
1597 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001598 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 }
1600}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601
1602
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001603static void FPT_RNVRamData(struct nvram_info * pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001605 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001606 unsigned long portBase;
1607 unsigned long regOffset;
1608 unsigned long scamData;
1609 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610
James Bottomley 47b5d692005-04-24 02:38:05 -05001611 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1612 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1613 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1614 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1615 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
1617 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001618 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
1620 portBase = pNvRamInfo->niBaseAddr;
1621
1622 for(i = 0; i < MAX_SCSI_TAR; i++){
1623 regOffset = hp_aramBase + 64 + i*4;
1624 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001625 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 *pScamTbl = scamData;
1627 }
1628
1629}
1630
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001631static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632{
1633 WR_HARPOON(portBase + hp_stack_addr, index);
1634 return(RD_HARPOON(portBase + hp_stack_data));
1635}
1636
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001637static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638{
1639 WR_HARPOON(portBase + hp_stack_addr, index);
1640 WR_HARPOON(portBase + hp_stack_data, data);
1641}
1642
1643
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001644static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645{
James Bottomley 47b5d692005-04-24 02:38:05 -05001646 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1647 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1649 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001650 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1652 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001653 return(1);
1654 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655
1656}
1657/*---------------------------------------------------------------------
1658 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001659 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 *
1661 * Description: Start a command pointed to by p_Sccb. When the
1662 * command is completed it will be returned via the
1663 * callback function.
1664 *
1665 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001666static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001668 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001669 unsigned char thisCard, lun;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001670 struct sccb * pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 CALL_BK_FN callback;
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1674 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1677 {
1678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 p_Sccb->HostStatus = SCCB_COMPLETE;
1680 p_Sccb->SccbStatus = SCCB_ERROR;
1681 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1682 if (callback)
1683 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 return;
1686 }
1687
James Bottomley 47b5d692005-04-24 02:38:05 -05001688 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
1690
1691 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1692 {
1693 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1694 | SCCB_MGR_ACTIVE));
1695
1696 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1697 {
1698 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1699 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1700 }
1701 }
1702
1703 ((PSCCBcard)pCurrCard)->cmdCounter++;
1704
1705 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1706
1707 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1708 | TICKLE_ME));
1709 if(p_Sccb->OperationCode == RESET_COMMAND)
1710 {
1711 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1712 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001713 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1715 }
1716 else
1717 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001718 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 }
1720 }
1721
1722 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1723
1724 if(p_Sccb->OperationCode == RESET_COMMAND)
1725 {
1726 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1727 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001728 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1730 }
1731 else
1732 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001733 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 }
1735 }
1736
1737 else {
1738
1739 MDISABLE_INT(ioport);
1740
1741 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001742 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 lun = p_Sccb->Lun;
1744 else
1745 lun = 0;
1746 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001747 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1748 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1749 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
1751 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001752 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 }
1754
1755 else {
1756
1757 if(p_Sccb->OperationCode == RESET_COMMAND)
1758 {
1759 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1760 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001761 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1763 }
1764 else
1765 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001766 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 }
1768 }
1769
1770
1771 MENABLE_INT(ioport);
1772 }
1773
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774}
1775
1776
1777/*---------------------------------------------------------------------
1778 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001779 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 *
1781 * Description: Abort the command pointed to by p_Sccb. When the
1782 * command is completed it will be returned via the
1783 * callback function.
1784 *
1785 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001786static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001788 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001790 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001792 unsigned char TID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001793 struct sccb * pSaveSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08001794 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
1796
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1798
1799 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1800
James Bottomley 47b5d692005-04-24 02:38:05 -05001801 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 {
1803
James Bottomley 47b5d692005-04-24 02:38:05 -05001804 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 {
1806
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 ((PSCCBcard)pCurrCard)->cmdCounter--;
1808
1809 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1810 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001811 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 p_Sccb->SccbStatus = SCCB_ABORT;
1814 callback = p_Sccb->SccbCallback;
1815 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 return(0);
1818 }
1819
1820 else
1821 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1823 {
1824 p_Sccb->SccbStatus = SCCB_ABORT;
1825 return(0);
1826
1827 }
1828
1829 else
1830 {
1831
1832 TID = p_Sccb->TargID;
1833
1834
1835 if(p_Sccb->Sccb_tag)
1836 {
1837 MDISABLE_INT(ioport);
1838 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1839 {
1840 p_Sccb->SccbStatus = SCCB_ABORT;
1841 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1843
1844 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1845 {
1846 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001847 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 }
1849 else
1850 {
1851 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1852 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001853 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1855 }
1856 }
1857 MENABLE_INT(ioport);
1858 return(0);
1859 }
1860 else
1861 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001862 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
James Bottomley 47b5d692005-04-24 02:38:05 -05001864 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 == p_Sccb)
1866 {
1867 p_Sccb->SccbStatus = SCCB_ABORT;
1868 return(0);
1869 }
1870 }
1871 }
1872 }
1873 }
1874 return(-1);
1875}
1876
1877
1878/*---------------------------------------------------------------------
1879 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001880 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 *
1882 * Description: Do a quick check to determine if there is a pending
1883 * interrupt for this card and disable the IRQ Pin if so.
1884 *
1885 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001886static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001888 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889
1890 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1891
1892 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1893 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001894 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 }
1896
1897 else
1898
James Bottomley 47b5d692005-04-24 02:38:05 -05001899 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900}
1901
1902
1903
1904/*---------------------------------------------------------------------
1905 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001906 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 *
1908 * Description: This is our entry point when an interrupt is generated
1909 * by the card and the upper level driver passes it on to
1910 * us.
1911 *
1912 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001913static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001915 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001916 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001917 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001918 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001919 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
1921 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1922 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1923
1924 MDISABLE_INT(ioport);
1925
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001927 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 else
1929 bm_status = 0;
1930
1931 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1932
James Bottomley 47b5d692005-04-24 02:38:05 -05001933 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 bm_status)
1935 {
1936
1937 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1938
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001940 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1942 bm_status = 0;
1943
1944 if (result) {
1945
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 return(result);
1948 }
1949 }
1950
1951
1952 else if (hp_int & ICMD_COMP) {
1953
1954 if ( !(hp_int & BUS_FREE) ) {
1955 /* Wait for the BusFree before starting a new command. We
1956 must also check for being reselected since the BusFree
1957 may not show up if another device reselects us in 1.5us or
1958 less. SRR Wednesday, 3/8/1995.
1959 */
1960 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1961 }
1962
1963 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1964
James Bottomley 47b5d692005-04-24 02:38:05 -05001965 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966
1967/* WRW_HARPOON((ioport+hp_intstat),
1968 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1969 */
1970
1971 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1972
James Bottomley 47b5d692005-04-24 02:38:05 -05001973 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974
1975 }
1976
1977
1978 else if (hp_int & ITAR_DISC)
1979 {
1980
1981 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1982
James Bottomley 47b5d692005-04-24 02:38:05 -05001983 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
1985 }
1986
1987 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1988
1989 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1990 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1991
1992 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1993 }
1994
1995 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05001996 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
1998 /* Wait for the BusFree before starting a new command. We
1999 must also check for being reselected since the BusFree
2000 may not show up if another device reselects us in 1.5us or
2001 less. SRR Wednesday, 3/8/1995.
2002 */
2003 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2004 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2005 RD_HARPOON((ioport+hp_scsisig)) ==
2006 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2007
2008 /*
2009 The additional loop exit condition above detects a timing problem
2010 with the revision D/E harpoon chips. The caller should reset the
2011 host adapter to recover when 0xFE is returned.
2012 */
2013 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2014 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 return 0xFE;
2017 }
2018
2019 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2020
2021
2022 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2023
2024 }
2025
2026
2027 else if (hp_int & RSEL) {
2028
2029 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2030
2031 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2032 {
2033 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2034 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002035 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036 }
2037
2038 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2039 {
2040 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2041 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2042 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2043 }
2044
2045 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2046 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002047 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 }
2049
James Bottomley 47b5d692005-04-24 02:38:05 -05002050 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2051 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052
2053 }
2054
2055
2056 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2057 {
2058
2059 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002060 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061
2062 }
2063
2064
2065 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2066 {
2067 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002068 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002070 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 }
2072 else
2073 {
2074 /* Harpoon problem some SCSI target device respond to selection
2075 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2076 to latch the correct Target ID into reg. x53.
2077 The work around require to correct this reg. But when write to this
2078 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2079 need to read this reg first then restore it later. After update to 0x53 */
2080
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002081 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2082 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2083 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2084 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2085 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 WR_HARPOON(ioport+hp_fifowrite, i);
2087 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2088 }
2089 }
2090
2091 else if (hp_int & XFER_CNT_0) {
2092
2093 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2094
James Bottomley 47b5d692005-04-24 02:38:05 -05002095 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096
2097 }
2098
2099
2100 else if (hp_int & BUS_FREE) {
2101
2102 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2103
2104 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2105
James Bottomley 47b5d692005-04-24 02:38:05 -05002106 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107 }
2108
James Bottomley 47b5d692005-04-24 02:38:05 -05002109 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110 }
2111
2112
2113 else if (hp_int & ITICKLE) {
2114
2115 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2116 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2117 }
2118
2119
2120
2121 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2122
2123
2124 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2125
2126
2127 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2128
James Bottomley 47b5d692005-04-24 02:38:05 -05002129 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 }
2131
2132 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2133 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002134 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135 }
2136
2137 break;
2138
2139 }
2140
2141 } /*end while */
2142
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144
2145 return(0);
2146}
2147
2148/*---------------------------------------------------------------------
2149 *
2150 * Function: Sccb_bad_isr
2151 *
2152 * Description: Some type of interrupt has occurred which is slightly
2153 * out of the ordinary. We will now decode it fully, in
2154 * this routine. This is broken up in an attempt to save
2155 * processing time.
2156 *
2157 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002158static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002159 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002161 unsigned char temp, ScamFlg;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08002162 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08002163 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164
2165
2166 if (RD_HARPOON(p_port+hp_ext_status) &
2167 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2168 {
2169
2170 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2171 {
2172
James Bottomley 47b5d692005-04-24 02:38:05 -05002173 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 }
2175
2176 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2177
2178 {
2179 WR_HARPOON(p_port+hp_pci_stat_cfg,
2180 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2181
2182 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2183
2184 }
2185
2186 if (pCurrCard->currentSCCB != NULL)
2187 {
2188
2189 if (!pCurrCard->currentSCCB->HostStatus)
2190 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2191
James Bottomley 47b5d692005-04-24 02:38:05 -05002192 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002194 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002196 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2198
2199 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2200 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002201 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 }
2203 }
2204 }
2205
2206
2207 else if (p_int & RESET)
2208 {
2209
2210 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2211 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2212 if (pCurrCard->currentSCCB != NULL) {
2213
2214 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2215
James Bottomley 47b5d692005-04-24 02:38:05 -05002216 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 }
2218
2219
2220 DISABLE_AUTO(p_port);
2221
James Bottomley 47b5d692005-04-24 02:38:05 -05002222 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223
2224 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2225
2226 pCurrNvRam = pCurrCard->pNvRamInfo;
2227 if(pCurrNvRam){
2228 ScamFlg = pCurrNvRam->niScamConf;
2229 }
2230 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002231 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232 }
2233
James Bottomley 47b5d692005-04-24 02:38:05 -05002234 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
James Bottomley 47b5d692005-04-24 02:38:05 -05002236 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
2238 return(0xFF);
2239 }
2240
2241
2242 else if (p_int & FIFO) {
2243
2244 WRW_HARPOON((p_port+hp_intstat), FIFO);
2245
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002247 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 }
2249
2250 else if (p_int & TIMEOUT)
2251 {
2252
2253 DISABLE_AUTO(p_port);
2254
2255 WRW_HARPOON((p_port+hp_intstat),
2256 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2257
2258 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2259
2260
James Bottomley 47b5d692005-04-24 02:38:05 -05002261 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2263 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002264 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002265 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002266 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267
2268
2269 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2270 {
2271 currTar_Info->TarSyncCtrl = 0;
2272 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2273 }
2274
2275 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2276 {
2277 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2278 }
2279
James Bottomley 47b5d692005-04-24 02:38:05 -05002280 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
James Bottomley 47b5d692005-04-24 02:38:05 -05002282 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283
2284 }
2285
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 else if (p_int & SCAM_SEL)
2287 {
2288
James Bottomley 47b5d692005-04-24 02:38:05 -05002289 FPT_scarb(p_port,LEVEL2_TAR);
2290 FPT_scsel(p_port);
2291 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
James Bottomley 47b5d692005-04-24 02:38:05 -05002293 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
2295 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2296 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297
2298 return(0x00);
2299}
2300
2301
2302/*---------------------------------------------------------------------
2303 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304 * Function: SccbMgrTableInit
2305 *
2306 * Description: Initialize all Sccb manager data structures.
2307 *
2308 *---------------------------------------------------------------------*/
2309
James Bottomley 47b5d692005-04-24 02:38:05 -05002310static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002312 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313
2314 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2315 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002316 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317
James Bottomley 47b5d692005-04-24 02:38:05 -05002318 FPT_BL_Card[thisCard].ioPort = 0x00;
2319 FPT_BL_Card[thisCard].cardInfo = NULL;
2320 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2321 FPT_BL_Card[thisCard].ourId = 0x00;
2322 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 }
2324}
2325
2326
2327/*---------------------------------------------------------------------
2328 *
2329 * Function: SccbMgrTableInit
2330 *
2331 * Description: Initialize all Sccb manager data structures.
2332 *
2333 *---------------------------------------------------------------------*/
2334
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002335static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002337 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338
2339 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2340 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002341 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342 }
2343
2344 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2345 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002346 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2347 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2348 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 }
2350
2351 pCurrCard->scanIndex = 0x00;
2352 pCurrCard->currentSCCB = NULL;
2353 pCurrCard->globalFlags = 0x00;
2354 pCurrCard->cmdCounter = 0x00;
2355 pCurrCard->tagQ_Lst = 0x01;
2356 pCurrCard->discQCount = 0;
2357
2358
2359}
2360
2361
2362/*---------------------------------------------------------------------
2363 *
2364 * Function: SccbMgrTableInit
2365 *
2366 * Description: Initialize all Sccb manager data structures.
2367 *
2368 *---------------------------------------------------------------------*/
2369
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002370static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371{
2372
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002373 unsigned char lun, qtag;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08002374 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
James Bottomley 47b5d692005-04-24 02:38:05 -05002376 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377
2378 currTar_Info->TarSelQ_Cnt = 0;
2379 currTar_Info->TarSyncCtrl = 0;
2380
2381 currTar_Info->TarSelQ_Head = NULL;
2382 currTar_Info->TarSelQ_Tail = NULL;
2383 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002384 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385
2386
2387 for (lun = 0; lun < MAX_LUN; lun++)
2388 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002389 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390 currTar_Info->LunDiscQ_Idx[lun] = 0;
2391 }
2392
2393 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2394 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002395 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002397 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002399 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2400 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 }
2402 }
2403 }
2404}
2405
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406
2407/*---------------------------------------------------------------------
2408 *
2409 * Function: sfetm
2410 *
2411 * Description: Read in a message byte from the SCSI bus, and check
2412 * for a parity error.
2413 *
2414 *---------------------------------------------------------------------*/
2415
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002416static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002418 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002419 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420
2421 TimeOutLoop = 0;
2422 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2423 (TimeOutLoop++ < 20000) ){}
2424
2425
2426 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2427
2428 message = RD_HARPOON(port+hp_scsidata_0);
2429
2430 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2431
2432
2433 if (TimeOutLoop > 20000)
2434 message = 0x00; /* force message byte = 0 if Time Out on Req */
2435
2436 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2437 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2438 {
2439 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2440 WR_HARPOON(port+hp_xferstat, 0);
2441 WR_HARPOON(port+hp_fiforead, 0);
2442 WR_HARPOON(port+hp_fifowrite, 0);
2443 if (pCurrSCCB != NULL)
2444 {
2445 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2446 }
2447 message = 0x00;
2448 do
2449 {
2450 ACCEPT_MSG_ATN(port);
2451 TimeOutLoop = 0;
2452 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2453 (TimeOutLoop++ < 20000) ){}
2454 if (TimeOutLoop > 20000)
2455 {
2456 WRW_HARPOON((port+hp_intstat), PARITY);
2457 return(message);
2458 }
2459 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2460 {
2461 WRW_HARPOON((port+hp_intstat), PARITY);
2462 return(message);
2463 }
2464 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2465
2466 RD_HARPOON(port+hp_scsidata_0);
2467
2468 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2469
2470 }while(1);
2471
2472 }
2473 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2474 WR_HARPOON(port+hp_xferstat, 0);
2475 WR_HARPOON(port+hp_fiforead, 0);
2476 WR_HARPOON(port+hp_fifowrite, 0);
2477 return(message);
2478}
2479
2480
2481/*---------------------------------------------------------------------
2482 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002483 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484 *
2485 * Description: Load up automation and select target device.
2486 *
2487 *---------------------------------------------------------------------*/
2488
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002489static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490{
2491
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002492 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002494 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 PSCCBcard CurrCard;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002496 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08002497 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002498 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
James Bottomley 47b5d692005-04-24 02:38:05 -05002500 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 currSCCB = CurrCard->currentSCCB;
2502 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002503 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504 lastTag = CurrCard->tagQ_Lst;
2505
2506 ARAM_ACCESS(port);
2507
2508
2509 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2510 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2511
2512 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2513 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2514
2515 lun = currSCCB->Lun;
2516 else
2517 lun = 0;
2518
2519
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520 if (CurrCard->globalFlags & F_TAG_STARTED)
2521 {
2522 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2523 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002524 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2526 == TAG_Q_TRYING))
2527 {
2528
2529 if (currTar_Info->TarTagQ_Cnt !=0)
2530 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002531 currTar_Info->TarLUNBusy[lun] = 1;
2532 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 SGRAM_ACCESS(port);
2534 return;
2535 }
2536
2537 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002538 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 }
2540
2541 } /*End non-tagged */
2542
2543 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002544 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545 }
2546
2547 } /*!Use cmd Q Tagged */
2548
2549 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002550 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002552 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002553 SGRAM_ACCESS(port);
2554 return;
2555 }
2556
James Bottomley 47b5d692005-04-24 02:38:05 -05002557 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
2559 } /*else use cmd Q tagged */
2560
2561 } /*if glob tagged started */
2562
2563 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002564 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 }
2566
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567
2568
2569 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2570 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2571 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2572 {
2573 if(CurrCard->discQCount >= QUEUE_DEPTH)
2574 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002575 currTar_Info->TarLUNBusy[lun] = 1;
2576 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577 SGRAM_ACCESS(port);
2578 return;
2579 }
2580 for (i = 1; i < QUEUE_DEPTH; i++)
2581 {
2582 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2583 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2584 {
2585 CurrCard->tagQ_Lst = lastTag;
2586 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2587 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2588 CurrCard->discQCount++;
2589 break;
2590 }
2591 }
2592 if(i == QUEUE_DEPTH)
2593 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002594 currTar_Info->TarLUNBusy[lun] = 1;
2595 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596 SGRAM_ACCESS(port);
2597 return;
2598 }
2599 }
2600
2601
2602
James Bottomley 47b5d692005-04-24 02:38:05 -05002603 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
2605 WR_HARPOON(port+hp_select_id, target);
2606 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2607
2608 if (currSCCB->OperationCode == RESET_COMMAND) {
2609 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2610 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2611
2612 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2613
2614 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2615
2616 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002617 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2619
2620 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2621 {
2622 currTar_Info->TarSyncCtrl = 0;
2623 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2624 }
2625
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2627 {
2628 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2629 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630
James Bottomley 47b5d692005-04-24 02:38:05 -05002631 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2632 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633
2634 }
2635
2636 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2637 {
2638 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2639 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2640
2641 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2642
2643 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002644 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2645 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 WRW_HARPOON((port+SYNC_MSGS+2),
2647 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2648 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2649
2650 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002651 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652
2653 }
2654
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002656 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2658 }
2659
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2661 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002662 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2664 }
2665
2666
2667 if (!auto_loaded)
2668 {
2669
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670 if (currSCCB->ControlByte & F_USE_CMD_Q)
2671 {
2672
2673 CurrCard->globalFlags |= F_TAG_STARTED;
2674
2675 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2676 == TAG_Q_REJECT)
2677 {
2678 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2679
2680 /* Fix up the start instruction with a jump to
2681 Non-Tag-CMD handling */
2682 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2683
2684 WRW_HARPOON((port+NON_TAG_ID_MSG),
2685 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2686
2687 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2688
2689 /* Setup our STATE so we know what happend when
2690 the wheels fall off. */
2691 currSCCB->Sccb_scsistat = SELECT_ST;
2692
James Bottomley 47b5d692005-04-24 02:38:05 -05002693 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 }
2695
2696 else
2697 {
2698 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2699
2700 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002701 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2702 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703
2704 for (i = 1; i < QUEUE_DEPTH; i++)
2705 {
2706 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2707 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2708 {
2709 WRW_HARPOON((port+ID_MSG_STRT+6),
2710 (MPM_OP+AMSG_OUT+lastTag));
2711 CurrCard->tagQ_Lst = lastTag;
2712 currSCCB->Sccb_tag = lastTag;
2713 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2714 CurrCard->discQCount++;
2715 break;
2716 }
2717 }
2718
2719
2720 if ( i == QUEUE_DEPTH )
2721 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002722 currTar_Info->TarLUNBusy[lun] = 1;
2723 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724 SGRAM_ACCESS(port);
2725 return;
2726 }
2727
2728 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2729
2730 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2731 }
2732 }
2733
2734 else
2735 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736
2737 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2738
2739 WRW_HARPOON((port+NON_TAG_ID_MSG),
2740 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2741
2742 currSCCB->Sccb_scsistat = SELECT_ST;
2743
2744 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746
2747
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002748 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749
2750 cdb_reg = port + CMD_STRT;
2751
2752 for (i=0; i < currSCCB->CdbLength; i++)
2753 {
2754 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2755 cdb_reg +=2;
2756 theCCB++;
2757 }
2758
2759 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2760 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2761
2762 } /* auto_loaded */
2763
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002764 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766
2767 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2768
2769 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2770
2771
2772 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2773 {
2774 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2775 }
2776 else
2777 {
2778
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002779/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780 auto_loaded |= AUTO_IMMED; */
2781 auto_loaded = AUTO_IMMED;
2782
2783 DISABLE_AUTO(port);
2784
2785 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2786 }
2787
2788 SGRAM_ACCESS(port);
2789}
2790
2791
2792/*---------------------------------------------------------------------
2793 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002794 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 *
2796 * Description: Hookup the correct CCB and handle the incoming messages.
2797 *
2798 *---------------------------------------------------------------------*/
2799
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002800static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801{
2802
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002803 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804
2805
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08002806 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002807 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808
2809
2810
2811
2812 if(pCurrCard->currentSCCB != NULL)
2813 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002814 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 DISABLE_AUTO(port);
2816
2817
2818 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2819
2820
2821 currSCCB = pCurrCard->currentSCCB;
2822 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2823 {
2824 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2825 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2826 }
2827 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2828 {
2829 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2830 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2831 }
2832 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2833 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2834 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002835 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 if(currSCCB->Sccb_scsistat != ABORT_ST)
2837 {
2838 pCurrCard->discQCount--;
2839 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2840 = NULL;
2841 }
2842 }
2843 else
2844 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002845 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 if(currSCCB->Sccb_tag)
2847 {
2848 if(currSCCB->Sccb_scsistat != ABORT_ST)
2849 {
2850 pCurrCard->discQCount--;
2851 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2852 }
2853 }else
2854 {
2855 if(currSCCB->Sccb_scsistat != ABORT_ST)
2856 {
2857 pCurrCard->discQCount--;
2858 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2859 }
2860 }
2861 }
2862
James Bottomley 47b5d692005-04-24 02:38:05 -05002863 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 }
2865
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002866 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867
2868
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002869 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002870 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
2872
2873 msgRetryCount = 0;
2874 do
2875 {
2876
James Bottomley 47b5d692005-04-24 02:38:05 -05002877 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 tag = 0;
2879
2880
2881 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2882 {
2883 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2884 {
2885
2886 WRW_HARPOON((port+hp_intstat), PHASE);
2887 return;
2888 }
2889 }
2890
2891 WRW_HARPOON((port+hp_intstat), PHASE);
2892 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2893 {
2894
James Bottomley 47b5d692005-04-24 02:38:05 -05002895 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 if (message)
2897 {
2898
2899 if (message <= (0x80 | LUN_MASK))
2900 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002901 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2904 {
2905 if (currTar_Info->TarTagQ_Cnt != 0)
2906 {
2907
2908 if (!(currTar_Info->TarLUN_CA))
2909 {
2910 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2911
2912
James Bottomley 47b5d692005-04-24 02:38:05 -05002913 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 if (message)
2915 {
2916 ACCEPT_MSG(port);
2917 }
2918
2919 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002920 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
James Bottomley 47b5d692005-04-24 02:38:05 -05002922 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002924 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
2926 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002927 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 }
2929
2930 } /*C.A. exists! */
2931
2932 } /*End Q cnt != 0 */
2933
2934 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935
2936 } /*End valid ID message. */
2937
2938 else
2939 {
2940
2941 ACCEPT_MSG_ATN(port);
2942 }
2943
2944 } /* End good id message. */
2945
2946 else
2947 {
2948
James Bottomley 47b5d692005-04-24 02:38:05 -05002949 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950 }
2951 }
2952 else
2953 {
2954 ACCEPT_MSG_ATN(port);
2955
2956 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2957 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2958 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2959
2960 return;
2961 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962
James Bottomley 47b5d692005-04-24 02:38:05 -05002963 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 {
2965 msgRetryCount++;
2966 if(msgRetryCount == 1)
2967 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002968 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 }
2970 else
2971 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002972 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973
James Bottomley 47b5d692005-04-24 02:38:05 -05002974 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975
James Bottomley 47b5d692005-04-24 02:38:05 -05002976 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 {
2978
James Bottomley 47b5d692005-04-24 02:38:05 -05002979 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980
2981 }
2982
James Bottomley 47b5d692005-04-24 02:38:05 -05002983 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 {
2985
James Bottomley 47b5d692005-04-24 02:38:05 -05002986 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 }
2988
2989
James Bottomley 47b5d692005-04-24 02:38:05 -05002990 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2991 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 return;
2993 }
2994 }
James Bottomley 47b5d692005-04-24 02:38:05 -05002995 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002996
2997
2998
2999 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3000 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3001 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003002 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003003 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3004 if(pCurrCard->currentSCCB != NULL)
3005 {
3006 ACCEPT_MSG(port);
3007 }
3008 else
3009 {
3010 ACCEPT_MSG_ATN(port);
3011 }
3012 }
3013 else
3014 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003015 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016
3017
3018 if (tag)
3019 {
3020 if (pCurrCard->discQ_Tbl[tag] != NULL)
3021 {
3022 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3023 currTar_Info->TarTagQ_Cnt--;
3024 ACCEPT_MSG(port);
3025 }
3026 else
3027 {
3028 ACCEPT_MSG_ATN(port);
3029 }
3030 }else
3031 {
3032 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3033 if(pCurrCard->currentSCCB != NULL)
3034 {
3035 ACCEPT_MSG(port);
3036 }
3037 else
3038 {
3039 ACCEPT_MSG_ATN(port);
3040 }
3041 }
3042 }
3043
3044 if(pCurrCard->currentSCCB != NULL)
3045 {
3046 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3047 {
3048 /* During Abort Tag command, the target could have got re-selected
3049 and completed the command. Check the select Q and remove the CCB
3050 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003051 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 }
3053 }
3054
3055
3056 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3057 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3058 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3059}
3060
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003061static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062{
3063 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3064 {
3065 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3066 {
3067
3068 WRW_HARPOON((port+hp_intstat), PHASE);
3069 return;
3070 }
3071 }
3072
3073 WRW_HARPOON((port+hp_intstat), PHASE);
3074 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3075 {
3076 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3077
3078
3079 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3080
3081 WR_HARPOON(port+hp_scsidata_0,message);
3082
3083 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3084
3085 ACCEPT_MSG(port);
3086
3087 WR_HARPOON(port+hp_portctrl_0, 0x00);
3088
3089 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3090 (message == SMABORT_TAG) )
3091 {
3092 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3093
3094 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3095 {
3096 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3097 }
3098 }
3099 }
3100}
3101
3102/*---------------------------------------------------------------------
3103 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003104 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 *
3106 * Description: Determine the proper responce to the message from the
3107 * target device.
3108 *
3109 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003110static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003112 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113 PSCCBcard CurrCard;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003114 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115
James Bottomley 47b5d692005-04-24 02:38:05 -05003116 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117 currSCCB = CurrCard->currentSCCB;
3118
James Bottomley 47b5d692005-04-24 02:38:05 -05003119 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120
3121 if (message == SMREST_DATA_PTR)
3122 {
3123 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3124 {
3125 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3126
James Bottomley 47b5d692005-04-24 02:38:05 -05003127 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128 }
3129
3130 ACCEPT_MSG(port);
3131 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3132 }
3133
3134 else if (message == SMCMD_COMP)
3135 {
3136
3137
3138 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3139 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003140 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3141 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 }
3143
3144 ACCEPT_MSG(port);
3145
3146 }
3147
3148 else if ((message == SMNO_OP) || (message >= SMIDENT)
3149 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3150 {
3151
3152 ACCEPT_MSG(port);
3153 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3154 }
3155
3156 else if (message == SMREJECT)
3157 {
3158
3159 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3160 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3161 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3162 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3163
3164 {
3165 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3166
3167 ACCEPT_MSG(port);
3168
3169
3170 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3171 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3172
3173 if(currSCCB->Lun == 0x00)
3174 {
3175 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3176 {
3177
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003178 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179
3180 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3181 }
3182
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3184 {
3185
3186
3187 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3188 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3189
3190 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3191
3192 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
3194 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3195 {
3196 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003197 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198
3199
3200 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3201 CurrCard->discQCount--;
3202 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3203 currSCCB->Sccb_tag = 0x00;
3204
3205 }
3206 }
3207
3208 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3209 {
3210
3211
3212 if(currSCCB->Lun == 0x00)
3213 {
3214 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3215 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3216 }
3217 }
3218
3219 else
3220 {
3221
3222 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3223 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003224 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003225 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003226 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227
3228
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003229 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003230
3231 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3232
3233 }
3234 }
3235
3236 else
3237 {
3238 ACCEPT_MSG(port);
3239
3240 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3241 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3242
3243 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3244 {
3245 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3246 }
3247 }
3248 }
3249
3250 else if (message == SMEXT)
3251 {
3252
3253 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003254 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 }
3256
3257 else if (message == SMIGNORWR)
3258 {
3259
3260 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3261
James Bottomley 47b5d692005-04-24 02:38:05 -05003262 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003263
3264 if(currSCCB->Sccb_scsimsg != SMPARITY)
3265 ACCEPT_MSG(port);
3266 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3267 }
3268
3269
3270 else
3271 {
3272
3273 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3274 currSCCB->Sccb_scsimsg = SMREJECT;
3275
3276 ACCEPT_MSG_ATN(port);
3277 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3278 }
3279}
3280
3281
3282/*---------------------------------------------------------------------
3283 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003284 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003285 *
3286 * Description: Decide what to do with the extended message.
3287 *
3288 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003289static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003290{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003291 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292
James Bottomley 47b5d692005-04-24 02:38:05 -05003293 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294 if (length)
3295 {
3296
3297 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003298 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003299 if (message)
3300 {
3301
3302 if (message == SMSYNC)
3303 {
3304
3305 if (length == 0x03)
3306 {
3307
3308 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003309 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310 }
3311 else
3312 {
3313
3314 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3315 ACCEPT_MSG_ATN(port);
3316 }
3317 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003318 else if (message == SMWDTR)
3319 {
3320
3321 if (length == 0x02)
3322 {
3323
3324 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003325 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003326 }
3327 else
3328 {
3329
3330 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3331 ACCEPT_MSG_ATN(port);
3332
3333 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3334 }
3335 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 else
3337 {
3338
3339 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3340 ACCEPT_MSG_ATN(port);
3341
3342 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3343 }
3344 }
3345 else
3346 {
3347 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3348 ACCEPT_MSG(port);
3349 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3350 }
3351 }else
3352 {
3353 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3354 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3355 }
3356}
3357
3358
3359/*---------------------------------------------------------------------
3360 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003361 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003362 *
3363 * Description: Read in a message byte from the SCSI bus, and check
3364 * for a parity error.
3365 *
3366 *---------------------------------------------------------------------*/
3367
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003368static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003369{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003370 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003371 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003372
James Bottomley 47b5d692005-04-24 02:38:05 -05003373 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3374 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003375
3376 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3377
3378
3379 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003380 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003381
3382 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3383
3384 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3385 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3386 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3387
3388
3389 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3390
3391 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3392
3393 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3394
3395 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3396
3397 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3398
3399 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3400
3401 else
3402 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3403
3404
3405 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3406 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3407 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3408
3409
James Bottomley 47b5d692005-04-24 02:38:05 -05003410 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003411 {
3412 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3413 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003414 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003415 }
3416 else
3417 {
3418 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3419 }
3420
3421
James Bottomley 47b5d692005-04-24 02:38:05 -05003422 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423 }
3424
3425 else {
3426
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003427 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003428 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003429 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430 }
3431}
3432
3433
3434
3435/*---------------------------------------------------------------------
3436 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003437 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003438 *
3439 * Description: The has sent us a Sync Nego message so handle it as
3440 * necessary.
3441 *
3442 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003443static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003445 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003446 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003447 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448
James Bottomley 47b5d692005-04-24 02:38:05 -05003449 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3450 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451
James Bottomley 47b5d692005-04-24 02:38:05 -05003452 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453
3454 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3455 {
3456 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3457 return;
3458 }
3459
3460 ACCEPT_MSG(port);
3461
3462
James Bottomley 47b5d692005-04-24 02:38:05 -05003463 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464
3465 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3466 {
3467 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3468 return;
3469 }
3470
3471 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3472
3473 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3474
3475 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3476
3477 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3478
3479 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3480
3481 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3482 else
3483
3484 our_sync_msg = 0; /* Message = Async */
3485
3486 if (sync_msg < our_sync_msg) {
3487 sync_msg = our_sync_msg; /*if faster, then set to max. */
3488 }
3489
3490 if (offset == ASYNC)
3491 sync_msg = ASYNC;
3492
3493 if (offset > MAX_OFFSET)
3494 offset = MAX_OFFSET;
3495
3496 sync_reg = 0x00;
3497
3498 if (sync_msg > 12)
3499
3500 sync_reg = 0x20; /* Use 10MB/s */
3501
3502 if (sync_msg > 25)
3503
3504 sync_reg = 0x40; /* Use 6.6MB/s */
3505
3506 if (sync_msg > 38)
3507
3508 sync_reg = 0x60; /* Use 5MB/s */
3509
3510 if (sync_msg > 50)
3511
3512 sync_reg = 0x80; /* Use 4MB/s */
3513
3514 if (sync_msg > 62)
3515
3516 sync_reg = 0xA0; /* Use 3.33MB/s */
3517
3518 if (sync_msg > 75)
3519
3520 sync_reg = 0xC0; /* Use 2.85MB/s */
3521
3522 if (sync_msg > 87)
3523
3524 sync_reg = 0xE0; /* Use 2.5MB/s */
3525
3526 if (sync_msg > 100) {
3527
3528 sync_reg = 0x00; /* Use ASYNC */
3529 offset = 0x00;
3530 }
3531
3532
Linus Torvalds1da177e2005-04-16 15:20:36 -07003533 if (currTar_Info->TarStatus & WIDE_ENABLED)
3534
3535 sync_reg |= offset;
3536
3537 else
3538
3539 sync_reg |= (offset | NARROW_SCSI);
3540
James Bottomley 47b5d692005-04-24 02:38:05 -05003541 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003542
3543
3544 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3545
3546
3547 ACCEPT_MSG(port);
3548
3549 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003550 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003551
3552 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3553 }
3554
3555 else {
3556
3557
3558 ACCEPT_MSG_ATN(port);
3559
James Bottomley 47b5d692005-04-24 02:38:05 -05003560 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561
3562 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003563 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564 }
3565}
3566
3567
3568/*---------------------------------------------------------------------
3569 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003570 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003571 *
3572 * Description: Answer the targets sync message.
3573 *
3574 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003575static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003576{
3577 ARAM_ACCESS(port);
3578 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3579 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3580 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3581 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3582 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3583 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3584 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3585 SGRAM_ACCESS(port);
3586
3587 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3588 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3589
3590 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3591
3592 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3593}
3594
3595
3596
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597/*---------------------------------------------------------------------
3598 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003599 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003600 *
3601 * Description: Read in a message byte from the SCSI bus, and check
3602 * for a parity error.
3603 *
3604 *---------------------------------------------------------------------*/
3605
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003606static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003608 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003609 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003610
James Bottomley 47b5d692005-04-24 02:38:05 -05003611 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3612 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613
3614 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3615
3616
3617 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003618 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619
3620 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3621
3622 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3623 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3624 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3625 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3626 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3627 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3628
3629 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3630
3631
3632 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003633 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003634
James Bottomley 47b5d692005-04-24 02:38:05 -05003635 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636 }
3637
3638 else {
3639
3640 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003641 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003642
3643 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003644 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645 }
3646}
3647
3648
3649
3650/*---------------------------------------------------------------------
3651 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003652 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003653 *
3654 * Description: The has sent us a Wide Nego message so handle it as
3655 * necessary.
3656 *
3657 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003658static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003659{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003660 unsigned char width;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003661 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003662 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663
James Bottomley 47b5d692005-04-24 02:38:05 -05003664 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3665 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666
James Bottomley 47b5d692005-04-24 02:38:05 -05003667 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668
3669 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3670 {
3671 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3672 return;
3673 }
3674
3675
3676 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3677 width = 0;
3678
3679 if (width) {
3680 currTar_Info->TarStatus |= WIDE_ENABLED;
3681 width = 0;
3682 }
3683 else {
3684 width = NARROW_SCSI;
3685 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3686 }
3687
3688
James Bottomley 47b5d692005-04-24 02:38:05 -05003689 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690
3691
3692 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3693 {
3694
3695
3696
3697 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3698
3699 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3700 {
3701 ACCEPT_MSG_ATN(port);
3702 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003703 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3705 SGRAM_ACCESS(port);
3706 }
3707 else
3708 {
3709 ACCEPT_MSG(port);
3710 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3711 }
3712 }
3713
3714 else {
3715
3716
3717 ACCEPT_MSG_ATN(port);
3718
3719 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3720 width = SM16BIT;
3721 else
3722 width = SM8BIT;
3723
James Bottomley 47b5d692005-04-24 02:38:05 -05003724 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725
3726 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3727 }
3728}
3729
3730
3731/*---------------------------------------------------------------------
3732 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003733 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003734 *
3735 * Description: Answer the targets Wide nego message.
3736 *
3737 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003738static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739{
3740 ARAM_ACCESS(port);
3741 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3742 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3743 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3744 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3745 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3746 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3747 SGRAM_ACCESS(port);
3748
3749 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3750 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3751
3752 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3753
3754 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3755}
3756
Linus Torvalds1da177e2005-04-16 15:20:36 -07003757
3758
3759/*---------------------------------------------------------------------
3760 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003761 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 *
3763 * Description: Write the desired value to the Sync Register for the
3764 * ID specified.
3765 *
3766 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003767static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003768 struct sccb_mgr_tar_info * currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003769{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003770 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771
3772 index = p_id;
3773
3774 switch (index) {
3775
3776 case 0:
3777 index = 12; /* hp_synctarg_0 */
3778 break;
3779 case 1:
3780 index = 13; /* hp_synctarg_1 */
3781 break;
3782 case 2:
3783 index = 14; /* hp_synctarg_2 */
3784 break;
3785 case 3:
3786 index = 15; /* hp_synctarg_3 */
3787 break;
3788 case 4:
3789 index = 8; /* hp_synctarg_4 */
3790 break;
3791 case 5:
3792 index = 9; /* hp_synctarg_5 */
3793 break;
3794 case 6:
3795 index = 10; /* hp_synctarg_6 */
3796 break;
3797 case 7:
3798 index = 11; /* hp_synctarg_7 */
3799 break;
3800 case 8:
3801 index = 4; /* hp_synctarg_8 */
3802 break;
3803 case 9:
3804 index = 5; /* hp_synctarg_9 */
3805 break;
3806 case 10:
3807 index = 6; /* hp_synctarg_10 */
3808 break;
3809 case 11:
3810 index = 7; /* hp_synctarg_11 */
3811 break;
3812 case 12:
3813 index = 0; /* hp_synctarg_12 */
3814 break;
3815 case 13:
3816 index = 1; /* hp_synctarg_13 */
3817 break;
3818 case 14:
3819 index = 2; /* hp_synctarg_14 */
3820 break;
3821 case 15:
3822 index = 3; /* hp_synctarg_15 */
3823
3824 }
3825
3826 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3827
3828 currTar_Info->TarSyncCtrl = p_sync_value;
3829}
3830
3831
3832/*---------------------------------------------------------------------
3833 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003834 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003835 *
3836 * Description: Reset the desired card's SCSI bus.
3837 *
3838 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003839static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003840{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003841 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08003843 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844
3845 WR_HARPOON(port+hp_page_ctrl,
3846 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3847 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3848
3849 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3850
3851 scsiID = RD_HARPOON(port+hp_seltimeout);
3852 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3853 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3854
3855 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3856
3857 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3858
3859 WR_HARPOON(port+hp_seltimeout,scsiID);
3860
3861 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3862
James Bottomley 47b5d692005-04-24 02:38:05 -05003863 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003864
3865 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3866
3867 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3868
3869 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3870 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003871 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872
3873 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3874 {
3875 currTar_Info->TarSyncCtrl = 0;
3876 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3877 }
3878
3879 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3880 {
3881 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3882 }
3883
James Bottomley 47b5d692005-04-24 02:38:05 -05003884 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003885
James Bottomley 47b5d692005-04-24 02:38:05 -05003886 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887 }
3888
James Bottomley 47b5d692005-04-24 02:38:05 -05003889 FPT_BL_Card[p_card].scanIndex = 0x00;
3890 FPT_BL_Card[p_card].currentSCCB = NULL;
3891 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003893 FPT_BL_Card[p_card].cmdCounter = 0x00;
3894 FPT_BL_Card[p_card].discQCount = 0x00;
3895 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003896
3897 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003898 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003899
3900 WR_HARPOON(port+hp_page_ctrl,
3901 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3902
3903}
3904
3905/*---------------------------------------------------------------------
3906 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003907 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003908 *
3909 * Description: Setup for the Auto Sense command.
3910 *
3911 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003912static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003914 unsigned char i;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003915 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916
3917 currSCCB = pCurrCard->currentSCCB;
3918
3919
3920 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3921
3922 for (i = 0; i < 6; i++) {
3923
3924 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3925 }
3926
3927 currSCCB->CdbLength = SIX_BYTE_CMD;
3928 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003929 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930 currSCCB->Cdb[2] = 0x00;
3931 currSCCB->Cdb[3] = 0x00;
3932 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3933 currSCCB->Cdb[5] = 0x00;
3934
3935 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3936
3937 currSCCB->Sccb_ATC = 0x00;
3938
3939 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3940
3941 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3942
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003943 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944
3945 currSCCB->ControlByte = 0x00;
3946
3947 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3948}
3949
3950
3951
3952/*---------------------------------------------------------------------
3953 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003954 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955 *
3956 * Description: Transfer data into the bit bucket until the device
3957 * decides to switch phase.
3958 *
3959 *---------------------------------------------------------------------*/
3960
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003961static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003962{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003963 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964
3965
3966 DISABLE_AUTO(p_port);
3967
James Bottomley 47b5d692005-04-24 02:38:05 -05003968 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003969
James Bottomley 47b5d692005-04-24 02:38:05 -05003970 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971
3972 }
3973
3974 /* If the Automation handled the end of the transfer then do not
3975 match the phase or we will get out of sync with the ISR. */
3976
3977 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3978 return;
3979
3980 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3981
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003982 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983
3984 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3985
3986
3987 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3988
3989 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003990 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003991 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003992 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993 {
3994 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3995
3996 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3997 {
3998 RD_HARPOON(p_port+hp_fifodata_0);
3999 }
4000 }
4001 else
4002 {
4003 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4004 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4005 {
4006 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4007 }
4008 }
4009 } /* End of While loop for padding data I/O phase */
4010
4011 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4012 {
4013 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4014 break;
4015 }
4016
4017 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4018 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4019 {
4020 RD_HARPOON(p_port+hp_fifodata_0);
4021 }
4022
4023 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4024 {
4025 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4026 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4027
4028 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4029 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4030 }
4031}
4032
4033
4034/*---------------------------------------------------------------------
4035 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004036 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004037 *
4038 * Description: Make sure data has been flushed from both FIFOs and abort
4039 * the operations if necessary.
4040 *
4041 *---------------------------------------------------------------------*/
4042
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004043static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004044{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004045 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004046 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004047
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004048 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049
James Bottomley 47b5d692005-04-24 02:38:05 -05004050 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
4052
4053 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4054 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4055 return;
4056 }
4057
4058
4059
4060 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4061 {
4062
4063 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4064
4065 currSCCB->Sccb_XferCnt = 1;
4066
4067 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004068 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004069 WR_HARPOON(port+hp_xferstat, 0x00);
4070 }
4071
4072 else
4073 {
4074
4075 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4076
4077 currSCCB->Sccb_XferCnt = 0;
4078 }
4079
4080 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4081 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4082
4083 currSCCB->HostStatus = SCCB_PARITY_ERR;
4084 WRW_HARPOON((port+hp_intstat), PARITY);
4085 }
4086
4087
James Bottomley 47b5d692005-04-24 02:38:05 -05004088 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004089
4090
4091 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4092
4093 TimeOutLoop = 0;
4094
4095 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4096 {
4097 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4098 return;
4099 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004100 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004101 break;
4102 }
4103 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4104 return;
4105 }
4106 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4107 break;
4108 }
4109
4110 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4111 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004112 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004113 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4114 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4115 {
4116
4117 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4118
4119 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4120 {
4121 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004122 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004123 }
4124
4125 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004126 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004127 }
4128 }
4129 else
4130 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004131 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004132 if (!(RDW_HARPOON((port+hp_intstat)) &
4133 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4134 {
4135 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004136 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004137 }
4138 }
4139
4140 }
4141
4142 else {
4143 WR_HARPOON(port+hp_portctrl_0, 0x00);
4144 }
4145}
4146
4147
4148/*---------------------------------------------------------------------
4149 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004150 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004151 *
4152 * Description: Setup SCCB manager fields in this SCCB.
4153 *
4154 *---------------------------------------------------------------------*/
4155
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004156static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004157{
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08004158 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159
4160 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4161 {
4162 return;
4163 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004164 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004165
4166 p_sccb->Sccb_XferState = 0x00;
4167 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4168
4169 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4170 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4171
4172 p_sccb->Sccb_SGoffset = 0;
4173 p_sccb->Sccb_XferState = F_SG_XFER;
4174 p_sccb->Sccb_XferCnt = 0x00;
4175 }
4176
4177 if (p_sccb->DataLength == 0x00)
4178
4179 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4180
4181 if (p_sccb->ControlByte & F_USE_CMD_Q)
4182 {
4183 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4184 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4185
4186 else
4187 currTar_Info->TarStatus |= TAG_Q_TRYING;
4188 }
4189
4190/* For !single SCSI device in system & device allow Disconnect
4191 or command is tag_q type then send Cmd with Disconnect Enable
4192 else send Cmd with Disconnect Disable */
4193
4194/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004195 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4197 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4198*/
4199 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4200 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004201 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004202 }
4203
4204 else {
4205
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004206 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004207 }
4208
4209 p_sccb->HostStatus = 0x00;
4210 p_sccb->TargetStatus = 0x00;
4211 p_sccb->Sccb_tag = 0x00;
4212 p_sccb->Sccb_MGRFlags = 0x00;
4213 p_sccb->Sccb_sgseg = 0x00;
4214 p_sccb->Sccb_ATC = 0x00;
4215 p_sccb->Sccb_savedATC = 0x00;
4216/*
4217 p_sccb->SccbVirtDataPtr = 0x00;
4218 p_sccb->Sccb_forwardlink = NULL;
4219 p_sccb->Sccb_backlink = NULL;
4220 */
4221 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4222 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4223 p_sccb->Sccb_scsimsg = SMNO_OP;
4224
4225}
4226
4227
Linus Torvalds1da177e2005-04-16 15:20:36 -07004228/*---------------------------------------------------------------------
4229 *
4230 * Function: Phase Decode
4231 *
4232 * Description: Determine the phase and call the appropriate function.
4233 *
4234 *---------------------------------------------------------------------*/
4235
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004236static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004237{
4238 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004239 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004240
4241
4242 DISABLE_AUTO(p_port);
4243
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004244 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004245
James Bottomley 47b5d692005-04-24 02:38:05 -05004246 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247
4248 (*phase)(p_port, p_card); /* Call the correct phase func */
4249}
4250
4251
4252
4253/*---------------------------------------------------------------------
4254 *
4255 * Function: Data Out Phase
4256 *
4257 * Description: Start up both the BusMaster and Xbow.
4258 *
4259 *---------------------------------------------------------------------*/
4260
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004261static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004262{
4263
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004264 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004265
James Bottomley 47b5d692005-04-24 02:38:05 -05004266 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267 if (currSCCB == NULL)
4268 {
4269 return; /* Exit if No SCCB record */
4270 }
4271
4272 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4273 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4274
4275 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4276
4277 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4278
4279 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4280
James Bottomley 47b5d692005-04-24 02:38:05 -05004281 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004282
4283 if (currSCCB->Sccb_XferCnt == 0) {
4284
4285
4286 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4287 (currSCCB->HostStatus == SCCB_COMPLETE))
4288 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4289
James Bottomley 47b5d692005-04-24 02:38:05 -05004290 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004292 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 }
4294}
4295
4296
4297/*---------------------------------------------------------------------
4298 *
4299 * Function: Data In Phase
4300 *
4301 * Description: Startup the BusMaster and the XBOW.
4302 *
4303 *---------------------------------------------------------------------*/
4304
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004305static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004306{
4307
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004308 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004309
James Bottomley 47b5d692005-04-24 02:38:05 -05004310 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311
4312 if (currSCCB == NULL)
4313 {
4314 return; /* Exit if No SCCB record */
4315 }
4316
4317
4318 currSCCB->Sccb_scsistat = DATA_IN_ST;
4319 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4320 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4321
4322 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4323
4324 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4325
4326 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4327
James Bottomley 47b5d692005-04-24 02:38:05 -05004328 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004329
4330 if (currSCCB->Sccb_XferCnt == 0) {
4331
4332
4333 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4334 (currSCCB->HostStatus == SCCB_COMPLETE))
4335 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4336
James Bottomley 47b5d692005-04-24 02:38:05 -05004337 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004338 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004339 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340
4341 }
4342}
4343
4344/*---------------------------------------------------------------------
4345 *
4346 * Function: Command Phase
4347 *
4348 * Description: Load the CDB into the automation and start it up.
4349 *
4350 *---------------------------------------------------------------------*/
4351
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004352static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004354 struct sccb * currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004355 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004356 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357
James Bottomley 47b5d692005-04-24 02:38:05 -05004358 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004359
4360 if (currSCCB->OperationCode == RESET_COMMAND) {
4361
4362 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4363 currSCCB->CdbLength = SIX_BYTE_CMD;
4364 }
4365
4366 WR_HARPOON(p_port+hp_scsisig, 0x00);
4367
4368 ARAM_ACCESS(p_port);
4369
4370
4371 cdb_reg = p_port + CMD_STRT;
4372
4373 for (i=0; i < currSCCB->CdbLength; i++) {
4374
4375 if (currSCCB->OperationCode == RESET_COMMAND)
4376
4377 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4378
4379 else
4380 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4381 cdb_reg +=2;
4382 }
4383
4384 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4385 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4386
4387 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4388
4389 currSCCB->Sccb_scsistat = COMMAND_ST;
4390
4391 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4392 SGRAM_ACCESS(p_port);
4393}
4394
4395
4396/*---------------------------------------------------------------------
4397 *
4398 * Function: Status phase
4399 *
4400 * Description: Bring in the status and command complete message bytes
4401 *
4402 *---------------------------------------------------------------------*/
4403
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004404static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405{
4406 /* Start-up the automation to finish off this command and let the
4407 isr handle the interrupt for command complete when it comes in.
4408 We could wait here for the interrupt to be generated?
4409 */
4410
4411 WR_HARPOON(port+hp_scsisig, 0x00);
4412
4413 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4414}
4415
4416
4417/*---------------------------------------------------------------------
4418 *
4419 * Function: Phase Message Out
4420 *
4421 * Description: Send out our message (if we have one) and handle whatever
4422 * else is involed.
4423 *
4424 *---------------------------------------------------------------------*/
4425
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004426static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004427{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004428 unsigned char message,scsiID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004429 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08004430 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004431
James Bottomley 47b5d692005-04-24 02:38:05 -05004432 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004433
4434 if (currSCCB != NULL) {
4435
4436 message = currSCCB->Sccb_scsimsg;
4437 scsiID = currSCCB->TargID;
4438
4439 if (message == SMDEV_RESET)
4440 {
4441
4442
James Bottomley 47b5d692005-04-24 02:38:05 -05004443 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004444 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004445 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446
James Bottomley 47b5d692005-04-24 02:38:05 -05004447 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448 {
4449
James Bottomley 47b5d692005-04-24 02:38:05 -05004450 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451
4452 }
4453
James Bottomley 47b5d692005-04-24 02:38:05 -05004454 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004455 {
4456
James Bottomley 47b5d692005-04-24 02:38:05 -05004457 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458 }
4459
4460
James Bottomley 47b5d692005-04-24 02:38:05 -05004461 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4462 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004463 }
4464 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4465 {
4466 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004467 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004468 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004469 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4470 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004471 }
4472
4473 }
4474
4475 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4476 {
4477
4478
4479 if(message == SMNO_OP)
4480 {
4481 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4482
James Bottomley 47b5d692005-04-24 02:38:05 -05004483 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004484 return;
4485 }
4486 }
4487 else
4488 {
4489
4490
4491 if (message == SMABORT)
4492
James Bottomley 47b5d692005-04-24 02:38:05 -05004493 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 }
4495
4496 }
4497 else
4498 {
4499 message = SMABORT;
4500 }
4501
4502 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4503
4504
4505 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4506
4507 WR_HARPOON(port+hp_scsidata_0,message);
4508
4509 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4510
4511 ACCEPT_MSG(port);
4512
4513 WR_HARPOON(port+hp_portctrl_0, 0x00);
4514
4515 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4516 (message == SMABORT_TAG) )
4517 {
4518
4519 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4520
4521 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4522 {
4523 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4524
4525 if (currSCCB != NULL)
4526 {
4527
James Bottomley 47b5d692005-04-24 02:38:05 -05004528 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4529 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4530 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004531 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004532 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004533
James Bottomley 47b5d692005-04-24 02:38:05 -05004534 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535 }
4536
4537 else
4538 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004539 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004540 }
4541 }
4542
4543 else
4544 {
4545
James Bottomley 47b5d692005-04-24 02:38:05 -05004546 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547 }
4548 }
4549
4550 else
4551 {
4552
4553 if(message == SMPARITY)
4554 {
4555 currSCCB->Sccb_scsimsg = SMNO_OP;
4556 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4557 }
4558 else
4559 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004560 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004561 }
4562 }
4563}
4564
4565
4566/*---------------------------------------------------------------------
4567 *
4568 * Function: Message In phase
4569 *
4570 * Description: Bring in the message and determine what to do with it.
4571 *
4572 *---------------------------------------------------------------------*/
4573
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004574static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004575{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004576 unsigned char message;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004577 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004578
James Bottomley 47b5d692005-04-24 02:38:05 -05004579 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580
James Bottomley 47b5d692005-04-24 02:38:05 -05004581 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582 {
4583
James Bottomley 47b5d692005-04-24 02:38:05 -05004584 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004585 }
4586
4587 message = RD_HARPOON(port+hp_scsidata_0);
4588 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4589 {
4590
4591 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4592
4593 }
4594
4595 else
4596 {
4597
James Bottomley 47b5d692005-04-24 02:38:05 -05004598 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004599 if (message)
4600 {
4601
4602
James Bottomley 47b5d692005-04-24 02:38:05 -05004603 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004604
4605 }
4606 else
4607 {
4608 if(currSCCB->Sccb_scsimsg != SMPARITY)
4609 ACCEPT_MSG(port);
4610 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4611 }
4612 }
4613
4614}
4615
4616
4617/*---------------------------------------------------------------------
4618 *
4619 * Function: Illegal phase
4620 *
4621 * Description: Target switched to some illegal phase, so all we can do
4622 * is report an error back to the host (if that is possible)
4623 * and send an ABORT message to the misbehaving target.
4624 *
4625 *---------------------------------------------------------------------*/
4626
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004627static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004628{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004629 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630
James Bottomley 47b5d692005-04-24 02:38:05 -05004631 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632
4633 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4634 if (currSCCB != NULL) {
4635
4636 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4637 currSCCB->Sccb_scsistat = ABORT_ST;
4638 currSCCB->Sccb_scsimsg = SMABORT;
4639 }
4640
4641 ACCEPT_MSG_ATN(port);
4642}
4643
4644
4645
4646/*---------------------------------------------------------------------
4647 *
4648 * Function: Phase Check FIFO
4649 *
4650 * Description: Make sure data has been flushed from both FIFOs and abort
4651 * the operations if necessary.
4652 *
4653 *---------------------------------------------------------------------*/
4654
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004655static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004656{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004657 unsigned long xfercnt;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004658 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004659
James Bottomley 47b5d692005-04-24 02:38:05 -05004660 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004661
4662 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4663 {
4664
4665 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4666 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4667
4668
4669 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4670 {
4671 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4672
4673 currSCCB->Sccb_XferCnt = 0;
4674
4675 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4676 (currSCCB->HostStatus == SCCB_COMPLETE))
4677 {
4678 currSCCB->HostStatus = SCCB_PARITY_ERR;
4679 WRW_HARPOON((port+hp_intstat), PARITY);
4680 }
4681
James Bottomley 47b5d692005-04-24 02:38:05 -05004682 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004683
James Bottomley 47b5d692005-04-24 02:38:05 -05004684 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004685
4686 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4687 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4688
4689 }
4690 } /*End Data In specific code. */
4691
4692
4693
Linus Torvalds1da177e2005-04-16 15:20:36 -07004694 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695
4696
4697 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4698
4699
4700 WR_HARPOON(port+hp_portctrl_0, 0x00);
4701
4702 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4703
4704 currSCCB->Sccb_XferCnt = xfercnt;
4705
4706 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4707 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4708
4709 currSCCB->HostStatus = SCCB_PARITY_ERR;
4710 WRW_HARPOON((port+hp_intstat), PARITY);
4711 }
4712
4713
James Bottomley 47b5d692005-04-24 02:38:05 -05004714 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004715
4716
4717 WR_HARPOON(port+hp_fifowrite, 0x00);
4718 WR_HARPOON(port+hp_fiforead, 0x00);
4719 WR_HARPOON(port+hp_xferstat, 0x00);
4720
4721 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4722}
4723
4724
4725/*---------------------------------------------------------------------
4726 *
4727 * Function: Phase Bus Free
4728 *
4729 * Description: We just went bus free so figure out if it was
4730 * because of command complete or from a disconnect.
4731 *
4732 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004733static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004734{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004735 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004736
James Bottomley 47b5d692005-04-24 02:38:05 -05004737 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004738
4739 if (currSCCB != NULL)
4740 {
4741
4742 DISABLE_AUTO(port);
4743
4744
4745 if (currSCCB->OperationCode == RESET_COMMAND)
4746 {
4747
James Bottomley 47b5d692005-04-24 02:38:05 -05004748 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4749 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4750 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004751 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004752 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004753
James Bottomley 47b5d692005-04-24 02:38:05 -05004754 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004755
James Bottomley 47b5d692005-04-24 02:38:05 -05004756 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004757
4758 }
4759
4760 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4761 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004763 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004765 }
4766
4767 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4768 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004769 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4770 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004771 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4772
James Bottomley 47b5d692005-04-24 02:38:05 -05004773 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004774 }
4775
Linus Torvalds1da177e2005-04-16 15:20:36 -07004776 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4777 {
4778 /* Make sure this is not a phony BUS_FREE. If we were
4779 reselected or if BUSY is NOT on then this is a
4780 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4781
4782 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4783 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4784 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4786 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004787 }
4788
4789 else
4790 {
4791 return;
4792 }
4793 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004794
4795 else
4796 {
4797
4798 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4799
4800 if (!currSCCB->HostStatus)
4801 {
4802 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4803 }
4804
James Bottomley 47b5d692005-04-24 02:38:05 -05004805 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4806 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4807 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004808 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004809 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004810
James Bottomley 47b5d692005-04-24 02:38:05 -05004811 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004812 return;
4813 }
4814
4815
James Bottomley 47b5d692005-04-24 02:38:05 -05004816 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004817
4818 } /*end if !=null */
4819}
4820
4821
4822
4823
Linus Torvalds1da177e2005-04-16 15:20:36 -07004824/*---------------------------------------------------------------------
4825 *
4826 * Function: Auto Load Default Map
4827 *
4828 * Description: Load the Automation RAM with the defualt map values.
4829 *
4830 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004831static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004832{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004833 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004834
4835 ARAM_ACCESS(p_port);
4836 map_addr = p_port + hp_aramBase;
4837
4838 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4839 map_addr +=2;
4840 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4841 map_addr +=2;
4842 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4843 map_addr +=2;
4844 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4845 map_addr +=2;
4846 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4847 map_addr +=2;
4848 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4849 map_addr +=2;
4850 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4851 map_addr +=2;
4852 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4873 map_addr +=2; /*This means AYNC DATA IN */
4874 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4875 map_addr +=2;
4876 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4877 map_addr +=2;
4878 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4883 map_addr +=2;
4884 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4885 map_addr +=2;
4886 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4887 map_addr +=2;
4888 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4909 map_addr +=2;
4910
4911 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4912 map_addr +=2;
4913 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4918 map_addr +=2; /* DIDN'T GET ONE */
4919 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4920 map_addr +=2;
4921 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4922 map_addr +=2;
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4924
4925
4926
4927 SGRAM_ACCESS(p_port);
4928}
4929
4930/*---------------------------------------------------------------------
4931 *
4932 * Function: Auto Command Complete
4933 *
4934 * Description: Post command back to host and find another command
4935 * to execute.
4936 *
4937 *---------------------------------------------------------------------*/
4938
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004939static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004940{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004941 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004942 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004943
James Bottomley 47b5d692005-04-24 02:38:05 -05004944 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004945
4946 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4947
James Bottomley 47b5d692005-04-24 02:38:05 -05004948 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004949
4950 if (status_byte != SSGOOD) {
4951
4952 if (status_byte == SSQ_FULL) {
4953
4954
James Bottomley 47b5d692005-04-24 02:38:05 -05004955 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4956 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004957 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004958 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4959 if(FPT_BL_Card[p_card].discQCount != 0)
4960 FPT_BL_Card[p_card].discQCount--;
4961 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 -07004962 }
4963 else
4964 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004965 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004966 if(currSCCB->Sccb_tag)
4967 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004968 if(FPT_BL_Card[p_card].discQCount != 0)
4969 FPT_BL_Card[p_card].discQCount--;
4970 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004971 }else
4972 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004973 if(FPT_BL_Card[p_card].discQCount != 0)
4974 FPT_BL_Card[p_card].discQCount--;
4975 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004976 }
4977 }
4978
4979 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4980
James Bottomley 47b5d692005-04-24 02:38:05 -05004981 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004982
4983 return;
4984 }
4985
4986 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4987 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004988 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004989 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004990
James Bottomley 47b5d692005-04-24 02:38:05 -05004991 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4992 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004993
James Bottomley 47b5d692005-04-24 02:38:05 -05004994 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4995 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004996 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004997 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4998 if(FPT_BL_Card[p_card].discQCount != 0)
4999 FPT_BL_Card[p_card].discQCount--;
5000 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 -07005001 }
5002 else
5003 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005004 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005005 if(currSCCB->Sccb_tag)
5006 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005007 if(FPT_BL_Card[p_card].discQCount != 0)
5008 FPT_BL_Card[p_card].discQCount--;
5009 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005010 }else
5011 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005012 if(FPT_BL_Card[p_card].discQCount != 0)
5013 FPT_BL_Card[p_card].discQCount--;
5014 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005015 }
5016 }
5017 return;
5018
5019 }
5020
5021 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5022 {
5023
James Bottomley 47b5d692005-04-24 02:38:05 -05005024 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5025 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005026 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5027
James Bottomley 47b5d692005-04-24 02:38:05 -05005028 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5029 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005030
James Bottomley 47b5d692005-04-24 02:38:05 -05005031 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5032 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005033 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005034 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5035 if(FPT_BL_Card[p_card].discQCount != 0)
5036 FPT_BL_Card[p_card].discQCount--;
5037 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 -07005038 }
5039 else
5040 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005041 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005042 if(currSCCB->Sccb_tag)
5043 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005044 if(FPT_BL_Card[p_card].discQCount != 0)
5045 FPT_BL_Card[p_card].discQCount--;
5046 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005047 }else
5048 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005049 if(FPT_BL_Card[p_card].discQCount != 0)
5050 FPT_BL_Card[p_card].discQCount--;
5051 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005052 }
5053 }
5054 return;
5055
5056 }
5057
5058 if (status_byte == SSCHECK)
5059 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005060 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005061 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005062 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005063 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005064 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005065 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005066 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005067 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005068 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005069 }
5070 }
5071 }
5072
5073 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5074
5075 currSCCB->SccbStatus = SCCB_ERROR;
5076 currSCCB->TargetStatus = status_byte;
5077
5078 if (status_byte == SSCHECK) {
5079
James Bottomley 47b5d692005-04-24 02:38:05 -05005080 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5081 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005082
5083
Linus Torvalds1da177e2005-04-16 15:20:36 -07005084 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5085
5086 if (currSCCB->RequestSenseLength == 0)
5087 currSCCB->RequestSenseLength = 14;
5088
James Bottomley 47b5d692005-04-24 02:38:05 -05005089 FPT_ssenss(&FPT_BL_Card[p_card]);
5090 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005091
James Bottomley 47b5d692005-04-24 02:38:05 -05005092 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5093 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005094 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5096 if(FPT_BL_Card[p_card].discQCount != 0)
5097 FPT_BL_Card[p_card].discQCount--;
5098 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 -07005099 }
5100 else
5101 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005102 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005103 if(currSCCB->Sccb_tag)
5104 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005105 if(FPT_BL_Card[p_card].discQCount != 0)
5106 FPT_BL_Card[p_card].discQCount--;
5107 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005108 }else
5109 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005110 if(FPT_BL_Card[p_card].discQCount != 0)
5111 FPT_BL_Card[p_card].discQCount--;
5112 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005113 }
5114 }
5115 return;
5116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005117 }
5118 }
5119 }
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
5128
James Bottomley 47b5d692005-04-24 02:38:05 -05005129 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005130}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005131
5132#define SHORT_WAIT 0x0000000F
5133#define LONG_WAIT 0x0000FFFFL
5134
Linus Torvalds1da177e2005-04-16 15:20:36 -07005135
5136/*---------------------------------------------------------------------
5137 *
5138 * Function: Data Transfer Processor
5139 *
5140 * Description: This routine performs two tasks.
5141 * (1) Start data transfer by calling HOST_DATA_XFER_START
5142 * function. Once data transfer is started, (2) Depends
5143 * on the type of data transfer mode Scatter/Gather mode
5144 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5145 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5146 * data transfer done. In Scatter/Gather mode, this routine
5147 * checks bus master command complete and dual rank busy
5148 * bit to keep chaining SC transfer command. Similarly,
5149 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5150 * (F_HOST_XFER_ACT bit) for data transfer done.
5151 *
5152 *---------------------------------------------------------------------*/
5153
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005154static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005155{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005156 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005157
5158 currSCCB = pCurrCard->currentSCCB;
5159
5160 if (currSCCB->Sccb_XferState & F_SG_XFER)
5161 {
5162 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5163
5164 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005165 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005166 currSCCB->Sccb_SGoffset = 0x00;
5167 }
5168 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5169
James Bottomley 47b5d692005-04-24 02:38:05 -05005170 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005171 }
5172
5173 else
5174 {
5175 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5176 {
5177 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5178
James Bottomley 47b5d692005-04-24 02:38:05 -05005179 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005180 }
5181 }
5182}
5183
5184
5185/*---------------------------------------------------------------------
5186 *
5187 * Function: BusMaster Scatter Gather Data Transfer Start
5188 *
5189 * Description:
5190 *
5191 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005192static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005193{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005194 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005195 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005196 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005197 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005198
5199
5200 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5201
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005202 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005203 }
5204
5205 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005206 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005207 }
5208
5209 sg_count = 0;
5210 tmpSGCnt = 0;
5211 sg_index = pcurrSCCB->Sccb_sgseg;
5212 reg_offset = hp_aramBase;
5213
5214
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005215 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005216
5217
5218 WR_HARPOON(p_port+hp_page_ctrl, i);
5219
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005220 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005221 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005222
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005223 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224 (sg_index * 2));
5225
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005226 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005227 (sg_index * 2));
5228
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005229 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005231
5232
5233 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5234
5235 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5236 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5237
5238 tmpSGCnt = count & 0x00FFFFFFL;
5239 }
5240
5241 WR_HARP32(p_port,reg_offset,addr);
5242 reg_offset +=4;
5243
5244 WR_HARP32(p_port,reg_offset,count);
5245 reg_offset +=4;
5246
5247 count &= 0xFF000000L;
5248 sg_index++;
5249 sg_count++;
5250
5251 } /*End While */
5252
5253 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5254
5255 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5256
5257 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5258
5259 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5260
5261
5262 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5263 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5264 }
5265
5266 else {
5267
5268
5269 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5270 (tmpSGCnt & 0x000000001))
5271 {
5272
5273 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5274 tmpSGCnt--;
5275 }
5276
5277
5278 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5279
5280 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5281 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5282 }
5283
5284
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005285 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005286
5287}
5288
5289
5290/*---------------------------------------------------------------------
5291 *
5292 * Function: BusMaster Data Transfer Start
5293 *
5294 * Description:
5295 *
5296 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005297static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005298{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005299 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005300
5301 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5302
5303 count = pcurrSCCB->Sccb_XferCnt;
5304
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005305 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005306 }
5307
5308 else {
5309 addr = pcurrSCCB->SensePointer;
5310 count = pcurrSCCB->RequestSenseLength;
5311
5312 }
5313
Linus Torvalds1da177e2005-04-16 15:20:36 -07005314 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005315
5316
5317 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5318
5319 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5320 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5321
5322 WR_HARPOON(p_port+hp_xfer_cmd,
5323 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5324 }
5325
5326 else {
5327
5328 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5329 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5330
5331 WR_HARPOON(p_port+hp_xfer_cmd,
5332 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5333
5334 }
5335}
5336
5337
5338/*---------------------------------------------------------------------
5339 *
5340 * Function: BusMaster Timeout Handler
5341 *
5342 * Description: This function is called after a bus master command busy time
5343 * out is detected. This routines issue halt state machine
5344 * with a software time out for command busy. If command busy
5345 * is still asserted at the end of the time out, it issues
5346 * hard abort with another software time out. It hard abort
5347 * command busy is also time out, it'll just give up.
5348 *
5349 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005350static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005351{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005352 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353
5354 timeout = LONG_WAIT;
5355
5356 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5357
5358 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5359
5360
5361
5362 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5363 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5364
5365 timeout = LONG_WAIT;
5366 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5367 }
5368
5369 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5370
5371 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005372 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005373 }
5374
5375 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005376 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005377 }
5378}
5379
5380
5381/*---------------------------------------------------------------------
5382 *
5383 * Function: Host Data Transfer Abort
5384 *
5385 * Description: Abort any in progress transfer.
5386 *
5387 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005388static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005389{
5390
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005391 unsigned long timeout;
5392 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005393 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005394
James Bottomley 47b5d692005-04-24 02:38:05 -05005395 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005396
5397 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5398
5399
5400 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5401
5402 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5403 timeout = LONG_WAIT;
5404
5405 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5406
5407 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5408
5409 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5410
James Bottomley 47b5d692005-04-24 02:38:05 -05005411 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005412
5413 if (pCurrSCCB->HostStatus == 0x00)
5414
5415 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5416
5417 }
5418
5419 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5420
5421 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5422
5423 if (pCurrSCCB->HostStatus == 0x00)
5424
5425 {
5426 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005427 }
5428 }
5429 }
5430 }
5431
5432 else if (pCurrSCCB->Sccb_XferCnt) {
5433
5434 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5435
5436
5437 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5438 ~SCATTER_EN));
5439
5440 WR_HARPOON(port+hp_sg_addr,0x00);
5441
5442 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5443
Alexey Dobriyance793212006-03-08 00:14:26 -08005444 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005445
Alexey Dobriyance793212006-03-08 00:14:26 -08005446 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005447 }
5448
5449 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5450
5451 while (remain_cnt < 0x01000000L) {
5452
5453 sg_ptr--;
5454
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005455 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005456 DataPointer) + (sg_ptr * 2)))) {
5457
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005458 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005459 DataPointer) + (sg_ptr * 2)));
5460 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005461
5462 else {
5463
5464 break;
5465 }
5466 }
5467
5468
5469
5470 if (remain_cnt < 0x01000000L) {
5471
5472
5473 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5474
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005475 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005476
5477
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005478 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005479 && (remain_cnt == 0))
5480
5481 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5482 }
5483
5484 else {
5485
5486
5487 if (pCurrSCCB->HostStatus == 0x00) {
5488
5489 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5490 }
5491 }
5492 }
5493
5494
5495 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5496
5497
5498 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5499
James Bottomley 47b5d692005-04-24 02:38:05 -05005500 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005501 }
5502
5503 else {
5504
5505 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5506
5507 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5508
5509 if (pCurrSCCB->HostStatus == 0x00) {
5510
5511 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005512 }
5513 }
5514 }
5515
5516 }
5517 }
5518
5519 else {
5520
5521
5522 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5523
5524 timeout = SHORT_WAIT;
5525
5526 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5527 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5528 timeout--) {}
5529 }
5530
5531 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5532
5533 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5534 FLUSH_XFER_CNTR));
5535
5536 timeout = LONG_WAIT;
5537
5538 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5539 timeout--) {}
5540
5541 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5542 ~FLUSH_XFER_CNTR));
5543
5544
5545 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5546
5547 if (pCurrSCCB->HostStatus == 0x00) {
5548
5549 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5550 }
5551
James Bottomley 47b5d692005-04-24 02:38:05 -05005552 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005553 }
5554 }
5555
5556 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5557
5558 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5559
5560 if (pCurrSCCB->HostStatus == 0x00) {
5561
5562 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005563 }
5564 }
5565 }
5566 }
5567
5568 }
5569
5570 else {
5571
5572
5573 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5574
5575 timeout = LONG_WAIT;
5576
5577 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5578
5579 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5580
5581 if (pCurrSCCB->HostStatus == 0x00) {
5582
5583 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5584 }
5585
James Bottomley 47b5d692005-04-24 02:38:05 -05005586 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005587 }
5588 }
5589
5590
5591 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5592
5593 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5594
5595 if (pCurrSCCB->HostStatus == 0x00) {
5596
5597 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005598 }
5599 }
5600
5601 }
5602
5603 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5604
5605 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5606 ~SCATTER_EN));
5607
5608 WR_HARPOON(port+hp_sg_addr,0x00);
5609
5610 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5611
5612 pCurrSCCB->Sccb_SGoffset = 0x00;
5613
5614
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005615 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005616 pCurrSCCB->DataLength) {
5617
5618 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5619
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005620 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005621
5622 }
5623 }
5624
5625 else {
5626
5627 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5628
5629 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5630 }
5631 }
5632
5633 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5634}
5635
5636
5637
5638/*---------------------------------------------------------------------
5639 *
5640 * Function: Host Data Transfer Restart
5641 *
5642 * Description: Reset the available count due to a restore data
5643 * pointers message.
5644 *
5645 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005646static void FPT_hostDataXferRestart(struct sccb * currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005647{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005648 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005649 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005650 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005651
5652 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5653
5654 currSCCB->Sccb_XferCnt = 0;
5655
5656 sg_index = 0xffff; /*Index by long words into sg list. */
5657 data_count = 0; /*Running count of SG xfer counts. */
5658
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005659 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005660
5661 while (data_count < currSCCB->Sccb_ATC) {
5662
5663 sg_index++;
5664 data_count += *(sg_ptr+(sg_index * 2));
5665 }
5666
5667 if (data_count == currSCCB->Sccb_ATC) {
5668
5669 currSCCB->Sccb_SGoffset = 0;
5670 sg_index++;
5671 }
5672
5673 else {
5674 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5675 }
5676
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005677 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005678 }
5679
5680 else {
5681 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5682 }
5683}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005684
5685
5686
Linus Torvalds1da177e2005-04-16 15:20:36 -07005687/*---------------------------------------------------------------------
5688 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005689 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005690 *
5691 * Description: Setup all data structures necessary for SCAM selection.
5692 *
5693 *---------------------------------------------------------------------*/
5694
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005695static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005696{
5697
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005698 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005699 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005700
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005701 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702 PSCCBcard currCard;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08005703 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005704
James Bottomley 47b5d692005-04-24 02:38:05 -05005705 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005706 p_port = currCard->ioPort;
5707 pCurrNvRam = currCard->pNvRamInfo;
5708
5709
5710 if(pCurrNvRam){
5711 ScamFlg = pCurrNvRam->niScamConf;
5712 i = pCurrNvRam->niSysConf;
5713 }
5714 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005715 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5716 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005717 }
5718 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5719 return;
5720
James Bottomley 47b5d692005-04-24 02:38:05 -05005721 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005722
5723 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5724 too slow to return to SCAM selection */
5725
5726 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005727 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005728 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005729 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005730
James Bottomley 47b5d692005-04-24 02:38:05 -05005731 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732
5733 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5734 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005735 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005736
James Bottomley 47b5d692005-04-24 02:38:05 -05005737 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005738
5739 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005740 FPT_scxferc(p_port,SYNC_PTRN);
5741 FPT_scxferc(p_port,DOM_MSTR);
5742 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005743 } while ( loser == 0xFF );
5744
James Bottomley 47b5d692005-04-24 02:38:05 -05005745 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005746
5747 if ((p_power_up) && (!loser))
5748 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005749 FPT_sresb(p_port,p_card);
5750 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005751
James Bottomley 47b5d692005-04-24 02:38:05 -05005752 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753
James Bottomley 47b5d692005-04-24 02:38:05 -05005754 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005755
5756 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005757 FPT_scxferc(p_port, SYNC_PTRN);
5758 FPT_scxferc(p_port, DOM_MSTR);
5759 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005760 id_string[0]);
5761 } while ( loser == 0xFF );
5762
James Bottomley 47b5d692005-04-24 02:38:05 -05005763 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005764 }
5765 }
5766
5767 else
5768 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005769 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005770 }
5771
5772
5773 if (!loser)
5774 {
5775
James Bottomley 47b5d692005-04-24 02:38:05 -05005776 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005777
5778
5779 if (ScamFlg & SCAM_ENABLED)
5780 {
5781
5782 for (i=0; i < MAX_SCSI_TAR; i++)
5783 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005784 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5785 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005786 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005787 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005788 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005789 FPT_scamInfo[i].state = LEGACY;
5790 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5791 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005792 {
5793
James Bottomley 47b5d692005-04-24 02:38:05 -05005794 FPT_scamInfo[i].id_string[0] = 0xFF;
5795 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005796 if(pCurrNvRam == NULL)
5797 currCard->globalFlags |= F_UPDATE_EEPROM;
5798 }
5799 }
5800 }
5801 }
5802
James Bottomley 47b5d692005-04-24 02:38:05 -05005803 FPT_sresb(p_port,p_card);
5804 FPT_Wait1Second(p_port);
5805 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5806 FPT_scsel(p_port);
5807 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005808 }
5809
Linus Torvalds1da177e2005-04-16 15:20:36 -07005810 }
5811
5812 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5813 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005814 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5815 assigned_id = 0;
5816 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005817
5818 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005819 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005820
James Bottomley 47b5d692005-04-24 02:38:05 -05005821 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005822 if (i == ASSIGN_ID)
5823 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005824 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005825 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005826 i = FPT_scxferc(p_port,0x00);
5827 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005828 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005829 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005830
James Bottomley 47b5d692005-04-24 02:38:05 -05005831 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005832 {
5833 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005834 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005835 FPT_inisci(p_card, p_port, p_our_id);
5836 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5837 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005838 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005839 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840 }
5841 }
5842 }
5843 }
5844
5845 else if (i == SET_P_FLAG)
5846 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005847 if (!(FPT_scsendi(p_port,
5848 &FPT_scamInfo[p_our_id].id_string[0])))
5849 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005850 }
5851 }while (!assigned_id);
5852
James Bottomley 47b5d692005-04-24 02:38:05 -05005853 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005854 }
5855
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 if (ScamFlg & SCAM_ENABLED)
5857 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005858 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005859 if (currCard->globalFlags & F_UPDATE_EEPROM)
5860 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005861 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005862 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5863 }
5864 }
5865
5866
Linus Torvalds1da177e2005-04-16 15:20:36 -07005867/*
5868 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5869 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005870 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5871 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005872 k++;
5873 }
5874
5875 if (k==2)
5876 currCard->globalFlags |= F_SINGLE_DEVICE;
5877 else
5878 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5879*/
5880}
5881
5882
5883/*---------------------------------------------------------------------
5884 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005885 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005886 *
5887 * Description: Gain control of the bus and wait SCAM select time (250ms)
5888 *
5889 *---------------------------------------------------------------------*/
5890
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005891static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005892{
5893 if (p_sel_type == INIT_SELTD)
5894 {
5895
5896 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5897
5898
5899 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005900 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005901
5902 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005903 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005904
5905 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5906
5907 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5908
5909 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5910 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005911 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005912 }
5913
5914
5915 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5916
5917 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5918
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5920 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005921 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005922 }
5923 }
5924
5925
5926 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5927 & ~ACTdeassert));
5928 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5929 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005930 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005931 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5932
5933 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5934
5935 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5936 & ~SCSI_BSY));
5937
James Bottomley 47b5d692005-04-24 02:38:05 -05005938 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005939
James Bottomley 47b5d692005-04-24 02:38:05 -05005940 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005941}
5942
5943
5944/*---------------------------------------------------------------------
5945 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005946 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005947 *
5948 * Description: Release the SCSI bus and disable SCAM selection.
5949 *
5950 *---------------------------------------------------------------------*/
5951
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005952static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005953{
5954 WR_HARPOON(p_port+hp_page_ctrl,
5955 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5956
5957
5958 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5959
5960 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5961 & ~SCSI_BUS_EN));
5962
5963 WR_HARPOON(p_port+hp_scsisig, 0x00);
5964
5965
5966 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5967 & ~SCAM_EN));
5968
5969 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5970 | ACTdeassert));
5971
Linus Torvalds1da177e2005-04-16 15:20:36 -07005972 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005973
5974 WR_HARPOON(p_port+hp_page_ctrl,
5975 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5976}
5977
5978
5979
5980/*---------------------------------------------------------------------
5981 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005982 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005983 *
5984 * Description: Assign an ID to all the SCAM devices.
5985 *
5986 *---------------------------------------------------------------------*/
5987
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005988static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005989{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005990 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005991
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005992 unsigned char i,k,scam_id;
5993 unsigned char crcBytes[3];
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08005994 struct nvram_info * pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08005995 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005996
James Bottomley 47b5d692005-04-24 02:38:05 -05005997 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005998
James Bottomley 47b5d692005-04-24 02:38:05 -05005999 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006000
6001 while (!i)
6002 {
6003
6004 for (k=0; k < ID_STRING_LENGTH; k++)
6005 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006006 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006007 }
6008
James Bottomley 47b5d692005-04-24 02:38:05 -05006009 FPT_scxferc(p_port,SYNC_PTRN);
6010 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006011
James Bottomley 47b5d692005-04-24 02:38:05 -05006012 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006013 {
6014 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006015 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006016 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6017 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006018 temp_id_string[1] = crcBytes[2];
6019 temp_id_string[2] = crcBytes[0];
6020 temp_id_string[3] = crcBytes[1];
6021 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006022 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006023 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006024 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025
6026 if (i == CLR_PRIORITY)
6027 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006028 FPT_scxferc(p_port,MISC_CODE);
6029 FPT_scxferc(p_port,CLR_P_FLAG);
6030 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006031 }
6032
6033 else if (i != NO_ID_AVAIL)
6034 {
6035 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006036 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006037 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006038 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006039
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006040 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006041
6042
6043 for (k=1; k < 0x08; k <<= 1)
6044 if (!( k & i ))
6045 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6046
James Bottomley 47b5d692005-04-24 02:38:05 -05006047 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006048
James Bottomley 47b5d692005-04-24 02:38:05 -05006049 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006050 }
6051 }
6052
6053 else
6054 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006055 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006056 }
6057
6058 } /*End while */
6059
James Bottomley 47b5d692005-04-24 02:38:05 -05006060 FPT_scxferc(p_port,SYNC_PTRN);
6061 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006062}
6063
6064
6065
6066
6067
6068/*---------------------------------------------------------------------
6069 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006070 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006071 *
6072 * Description: Select all the SCAM devices.
6073 *
6074 *---------------------------------------------------------------------*/
6075
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006076static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006077{
6078
6079 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006080 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006081
6082 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6083
6084
6085 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006086 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6087 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006088
6089
6090 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006091 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006092
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006093 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6094 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006095 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006096
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6098}
6099
6100
6101
6102/*---------------------------------------------------------------------
6103 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006104 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006105 *
6106 * Description: Handshake the p_data (DB4-0) across the bus.
6107 *
6108 *---------------------------------------------------------------------*/
6109
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006110static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006111{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006112 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006113
6114 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6115
6116 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6117
6118 curr_data &= ~BIT(7);
6119
6120 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6121
James Bottomley 47b5d692005-04-24 02:38:05 -05006122 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006123 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6124
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006125 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006126
6127 curr_data |= BIT(6);
6128
6129 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6130
6131 curr_data &= ~BIT(5);
6132
6133 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6134
James Bottomley 47b5d692005-04-24 02:38:05 -05006135 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006136
6137 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6138 curr_data |= BIT(7);
6139
6140 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6141
6142 curr_data &= ~BIT(6);
6143
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145
James Bottomley 47b5d692005-04-24 02:38:05 -05006146 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006147
6148 return(ret_data);
6149}
6150
6151
6152/*---------------------------------------------------------------------
6153 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006154 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006155 *
6156 * Description: Transfer our Identification string to determine if we
6157 * will be the dominant master.
6158 *
6159 *---------------------------------------------------------------------*/
6160
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006161static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006162{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006163 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006164
James Bottomley 47b5d692005-04-24 02:38:05 -05006165 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006166
6167 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6168
6169 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6170
6171 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006172 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006173
6174 else if (p_id_string[byte_cnt] & bit_cnt)
6175
James Bottomley 47b5d692005-04-24 02:38:05 -05006176 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006177
6178 else {
6179
James Bottomley 47b5d692005-04-24 02:38:05 -05006180 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006181 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006182 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006183 }
6184
6185 if ((ret_data & 0x1C) == 0x10)
6186 return(0x00); /*End of isolation stage, we won! */
6187
6188 if (ret_data & 0x1C)
6189 return(0xFF);
6190
6191 if ((defer) && (!(ret_data & 0x1F)))
6192 return(0x01); /*End of isolation stage, we lost. */
6193
6194 } /*bit loop */
6195
6196 } /*byte loop */
6197
6198 if (defer)
6199 return(0x01); /*We lost */
6200 else
6201 return(0); /*We WON! Yeeessss! */
6202}
6203
6204
6205
6206/*---------------------------------------------------------------------
6207 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006208 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006209 *
6210 * Description: Transfer the Identification string.
6211 *
6212 *---------------------------------------------------------------------*/
6213
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006214static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006215{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006216 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006217
6218 the_data = 0;
6219
6220 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6221
6222 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6223
James Bottomley 47b5d692005-04-24 02:38:05 -05006224 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006225
6226 if (ret_data & 0xFC)
6227 return(0xFF);
6228
6229 else {
6230
6231 the_data <<= 1;
6232 if (ret_data & BIT(1)) {
6233 the_data |= 1;
6234 }
6235 }
6236
6237 if ((ret_data & 0x1F) == 0)
6238 {
6239/*
6240 if(bit_cnt != 0 || bit_cnt != 8)
6241 {
6242 byte_cnt = 0;
6243 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006244 FPT_scxferc(p_port, SYNC_PTRN);
6245 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006246 continue;
6247 }
6248*/
6249 if (byte_cnt)
6250 return(0x00);
6251 else
6252 return(0xFF);
6253 }
6254
6255 } /*bit loop */
6256
6257 p_id_string[byte_cnt] = the_data;
6258
6259 } /*byte loop */
6260
6261 return(0);
6262}
6263
6264
6265
6266/*---------------------------------------------------------------------
6267 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006268 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006269 *
6270 * Description: Sample the SCSI data bus making sure the signal has been
6271 * deasserted for the correct number of consecutive samples.
6272 *
6273 *---------------------------------------------------------------------*/
6274
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006275static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006276{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006277 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006278
6279 i = 0;
6280 while ( i < MAX_SCSI_TAR ) {
6281
6282 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6283
6284 i = 0;
6285
6286 else
6287
6288 i++;
6289
6290 }
6291}
6292
6293
6294
6295/*---------------------------------------------------------------------
6296 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006297 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006298 *
6299 * Description: Sample the SCSI Signal lines making sure the signal has been
6300 * deasserted for the correct number of consecutive samples.
6301 *
6302 *---------------------------------------------------------------------*/
6303
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006304static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006305{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006306 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006307
6308 i = 0;
6309 while ( i < MAX_SCSI_TAR ) {
6310
6311 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6312
6313 i = 0;
6314
6315 else
6316
6317 i++;
6318
6319 }
6320}
6321
6322
6323/*---------------------------------------------------------------------
6324 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006325 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006326 *
6327 * Description: Make sure we received a valid data byte.
6328 *
6329 *---------------------------------------------------------------------*/
6330
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006331static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006332{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006333 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006334
6335 for (count=1; count < 0x08; count<<=1) {
6336 if (!(p_quintet & count))
6337 p_quintet -= 0x80;
6338 }
6339
6340 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006341 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006342
6343 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006344 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006345}
6346
6347
6348/*---------------------------------------------------------------------
6349 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006350 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006351 *
6352 * Description: Select the specified device ID using a selection timeout
6353 * less than 4ms. If somebody responds then it is a legacy
6354 * drive and this ID must be marked as such.
6355 *
6356 *---------------------------------------------------------------------*/
6357
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006358static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006359{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006360 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006361
6362 WR_HARPOON(p_port+hp_page_ctrl,
6363 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6364
6365 ARAM_ACCESS(p_port);
6366
6367 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6368 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6369
6370
6371 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6372 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6373 }
6374 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6375
6376 WRW_HARPOON((p_port+hp_intstat),
6377 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6378
6379 WR_HARPOON(p_port+hp_select_id, targ_id);
6380
6381 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6382 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6383 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6384
6385
6386 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6387 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6388
6389 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006390 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006391
6392 DISABLE_AUTO(p_port);
6393
6394 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6395 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6396
6397 SGRAM_ACCESS(p_port);
6398
6399 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6400
6401 WRW_HARPOON((p_port+hp_intstat),
6402 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6403
6404 WR_HARPOON(p_port+hp_page_ctrl,
6405 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6406
James Bottomley 47b5d692005-04-24 02:38:05 -05006407 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006408 }
6409
6410 else {
6411
6412 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6413 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6414 {
6415 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6416 ACCEPT_MSG(p_port);
6417 }
6418 }
6419
6420 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6421
6422 WR_HARPOON(p_port+hp_page_ctrl,
6423 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6424
James Bottomley 47b5d692005-04-24 02:38:05 -05006425 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006426 }
6427}
6428
Linus Torvalds1da177e2005-04-16 15:20:36 -07006429/*---------------------------------------------------------------------
6430 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006431 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006432 *
6433 * Description: Wait to be selected by another SCAM initiator.
6434 *
6435 *---------------------------------------------------------------------*/
6436
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006437static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006438{
6439 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6440}
6441
6442
6443/*---------------------------------------------------------------------
6444 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006445 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006446 *
6447 * Description: Setup the data Structure with the info from the EEPROM.
6448 *
6449 *---------------------------------------------------------------------*/
6450
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006451static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006452{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006453 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006454 unsigned short ee_data;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08006455 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456
James Bottomley 47b5d692005-04-24 02:38:05 -05006457 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006458
6459 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6460 max_id = 0x08;
6461
6462 else
6463 max_id = 0x10;
6464
6465 if(pCurrNvRam){
6466 for(i = 0; i < max_id; i++){
6467
6468 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006469 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006470 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006471 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472
James Bottomley 47b5d692005-04-24 02:38:05 -05006473 if(FPT_scamInfo[i].id_string[0] == 0x00)
6474 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006475 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006476 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006477
6478 }
6479 }else {
6480 for (i=0; i < max_id; i++)
6481 {
6482 for (k=0; k < ID_STRING_LENGTH; k+=2)
6483 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006484 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6485 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006486 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006487 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006488 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489 }
6490
James Bottomley 47b5d692005-04-24 02:38:05 -05006491 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6492 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006493
James Bottomley 47b5d692005-04-24 02:38:05 -05006494 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006495
6496 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006497 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006498
6499 }
6500 }
6501 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006502 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503
6504}
6505
6506/*---------------------------------------------------------------------
6507 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006508 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006509 *
6510 * Description: Match the Device ID string with our values stored in
6511 * the EEPROM.
6512 *
6513 *---------------------------------------------------------------------*/
6514
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006515static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006516{
6517
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006518 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006519
6520
6521 for (i=0; i < MAX_SCSI_TAR; i++) {
6522
James Bottomley 47b5d692005-04-24 02:38:05 -05006523 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524
6525 for (k=0; k < ID_STRING_LENGTH; k++)
6526 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006527 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6528 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529 }
6530
6531 if (match)
6532 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006533 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534 return(i);
6535 }
6536
Linus Torvalds1da177e2005-04-16 15:20:36 -07006537 }
6538
6539
6540
6541 if (p_id_string[0] & BIT(5))
6542 i = 8;
6543 else
6544 i = MAX_SCSI_TAR;
6545
6546 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006547 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006548 else
6549 match = 7;
6550
6551 while (i > 0)
6552 {
6553 i--;
6554
James Bottomley 47b5d692005-04-24 02:38:05 -05006555 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006556 {
6557 for (k=0; k < ID_STRING_LENGTH; k++)
6558 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006559 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 }
6561
James Bottomley 47b5d692005-04-24 02:38:05 -05006562 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006563
James Bottomley 47b5d692005-04-24 02:38:05 -05006564 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6565 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006566 return(match);
6567
6568 }
6569
6570
6571 match--;
6572
6573 if (match == 0xFF)
6574 {
6575 if (p_id_string[0] & BIT(5))
6576 match = 7;
6577 else
6578 match = MAX_SCSI_TAR-1;
6579 }
6580 }
6581
6582
6583
6584 if (p_id_string[0] & BIT(7))
6585 {
6586 return(CLR_PRIORITY);
6587 }
6588
6589
6590 if (p_id_string[0] & BIT(5))
6591 i = 8;
6592 else
6593 i = MAX_SCSI_TAR;
6594
6595 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006596 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006597 else
6598 match = 7;
6599
6600 while (i > 0)
6601 {
6602
6603 i--;
6604
James Bottomley 47b5d692005-04-24 02:38:05 -05006605 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006606 {
6607 for (k=0; k < ID_STRING_LENGTH; k++)
6608 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006609 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006610 }
6611
James Bottomley 47b5d692005-04-24 02:38:05 -05006612 FPT_scamInfo[match].id_string[0] |= BIT(7);
6613 FPT_scamInfo[match].state = ID_ASSIGNED;
6614 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6615 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006616 return(match);
6617
6618 }
6619
6620
6621 match--;
6622
6623 if (match == 0xFF)
6624 {
6625 if (p_id_string[0] & BIT(5))
6626 match = 7;
6627 else
6628 match = MAX_SCSI_TAR-1;
6629 }
6630 }
6631
6632 return(NO_ID_AVAIL);
6633}
6634
6635
6636/*---------------------------------------------------------------------
6637 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006638 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006639 *
6640 * Description: Save off the device SCAM ID strings.
6641 *
6642 *---------------------------------------------------------------------*/
6643
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006644static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006645{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006646 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006647 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006648
6649
6650 sum_data = 0x0000;
6651
6652 for (i = 1; i < EE_SCAMBASE/2; i++)
6653 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006654 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006655 }
6656
6657
James Bottomley 47b5d692005-04-24 02:38:05 -05006658 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006659
6660 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6661 max_id = 0x08;
6662
6663 else
6664 max_id = 0x10;
6665
6666 for (i=0; i < max_id; i++)
6667 {
6668
6669 for (k=0; k < ID_STRING_LENGTH; k+=2)
6670 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006671 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006672 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006673 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006674 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006675 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6676 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006677 }
6678 }
6679
6680
James Bottomley 47b5d692005-04-24 02:38:05 -05006681 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6682 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684
6685/*---------------------------------------------------------------------
6686 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006687 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006688 *
6689 * Description: Setup the Xbow for normal operation.
6690 *
6691 *---------------------------------------------------------------------*/
6692
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006693static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006694{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006695unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006696
6697 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006698 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006699
6700 WR_HARPOON(port+hp_scsireset,0x00);
6701 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6702
6703 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6704 FIFO_CLR));
6705
6706 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6707
6708 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6709
6710 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6711 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6712
6713 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6714
James Bottomley 47b5d692005-04-24 02:38:05 -05006715 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006716 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6717
6718 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006719 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006720
James Bottomley 47b5d692005-04-24 02:38:05 -05006721 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006722
6723 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6724
6725 /* Turn on SCSI_MODE8 for narrow cards to fix the
6726 strapping issue with the DUAL CHANNEL card */
6727 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6728 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6729
Linus Torvalds1da177e2005-04-16 15:20:36 -07006730 WR_HARPOON(port+hp_page_ctrl, i);
6731
6732}
6733
6734
6735/*---------------------------------------------------------------------
6736 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006737 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006738 *
6739 * Description: Initialize the BusMaster for normal operations.
6740 *
6741 *---------------------------------------------------------------------*/
6742
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006743static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006744{
6745
6746
6747 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6748 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6749
6750 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6751
6752
6753 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6754
6755 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6756
6757
Linus Torvalds1da177e2005-04-16 15:20:36 -07006758 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6759 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6760 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6761 ~SCATTER_EN));
6762}
6763
6764
6765/*---------------------------------------------------------------------
6766 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006767 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006768 *
6769 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6770 * necessary.
6771 *
6772 *---------------------------------------------------------------------*/
6773
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006774static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006775{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006776 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006777
6778 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6779 max_wd_cnt = EEPROM_WD_CNT;
6780 else
6781 max_wd_cnt = EEPROM_WD_CNT * 2;
6782
James Bottomley 47b5d692005-04-24 02:38:05 -05006783 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006784
6785 if (temp == 0x4641) {
6786
6787 for (index = 2; index < max_wd_cnt; index++) {
6788
James Bottomley 47b5d692005-04-24 02:38:05 -05006789 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006790
6791 }
6792
James Bottomley 47b5d692005-04-24 02:38:05 -05006793 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006794
6795 return; /*EEPROM is Okay so return now! */
6796 }
6797 }
6798
6799
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006800 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006801
6802 for (index = 0; index < max_wd_cnt; index++) {
6803
James Bottomley 47b5d692005-04-24 02:38:05 -05006804 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006805 }
6806
6807 temp = 0;
6808
James Bottomley 47b5d692005-04-24 02:38:05 -05006809 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006810 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006811 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006813 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006815 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006817 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006818 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006819 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006821 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006823 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 temp += 0x0007;
6825
James Bottomley 47b5d692005-04-24 02:38:05 -05006826 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006827 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006828 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006830 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 temp += 0x0000;
6832
James Bottomley 47b5d692005-04-24 02:38:05 -05006833 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006834 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006835 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006837 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006839 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006841 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848 temp += 0x4242;
6849
6850
James Bottomley 47b5d692005-04-24 02:38:05 -05006851 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006852 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006853 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006855 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006857 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006859 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006861 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006863 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006864 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006866 temp += 0x2020;
6867
6868 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006869 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006870 temp += (0x0700+TYPE_CODE0);
6871 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006872 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 temp += 0x5542; /* BUSLOGIC */
6874 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006875 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006876 temp += 0x4C53;
6877 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006878 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879 temp += 0x474F;
6880 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006881 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006882 temp += 0x4349;
6883 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006884 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 temp += 0x5442; /* BT- 930 */
6886 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006887 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006888 temp += 0x202D;
6889 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006890 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 temp += 0x3339;
6892 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006893 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006894 temp += 0x2030;
6895 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006896 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006897 temp += 0x5453;
6898 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006899 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006900 temp += 0x5645;
6901 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006902 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006903 temp += 0x2045;
6904 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006905 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006906 temp += 0x202F;
6907 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006908 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006909 temp += 0x4F4A;
6910 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006911 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006912 temp += 0x204E;
6913 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006914 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006915 temp += 0x3539;
6916
6917
6918
James Bottomley 47b5d692005-04-24 02:38:05 -05006919 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006920
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006921 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006922
6923}
6924
Linus Torvalds1da177e2005-04-16 15:20:36 -07006925
6926/*---------------------------------------------------------------------
6927 *
6928 * Function: Queue Search Select
6929 *
6930 * Description: Try to find a new command to execute.
6931 *
6932 *---------------------------------------------------------------------*/
6933
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006934static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006935{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006936 unsigned char scan_ptr, lun;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08006937 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006938 struct sccb * pOldSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006939
6940 scan_ptr = pCurrCard->scanIndex;
6941 do
6942 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006943 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006944 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6945 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6946 {
6947 if (currTar_Info->TarSelQ_Cnt != 0)
6948 {
6949
6950 scan_ptr++;
6951 if (scan_ptr == MAX_SCSI_TAR)
6952 scan_ptr = 0;
6953
6954 for(lun=0; lun < MAX_LUN; lun++)
6955 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006956 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006957 {
6958
6959 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6960 pOldSccb = NULL;
6961
6962 while((pCurrCard->currentSCCB != NULL) &&
6963 (lun != pCurrCard->currentSCCB->Lun))
6964 {
6965 pOldSccb = pCurrCard->currentSCCB;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006966 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006967 Sccb_forwardlink;
6968 }
6969 if(pCurrCard->currentSCCB == NULL)
6970 continue;
6971 if(pOldSccb != NULL)
6972 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006973 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006974 Sccb_forwardlink;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006975 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006976 Sccb_backlink;
6977 currTar_Info->TarSelQ_Cnt--;
6978 }
6979 else
6980 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006981 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006982
6983 if (currTar_Info->TarSelQ_Head == NULL)
6984 {
6985 currTar_Info->TarSelQ_Tail = NULL;
6986 currTar_Info->TarSelQ_Cnt = 0;
6987 }
6988 else
6989 {
6990 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006991 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006992 }
6993 }
6994 pCurrCard->scanIndex = scan_ptr;
6995
6996 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6997
6998 break;
6999 }
7000 }
7001 }
7002
7003 else
7004 {
7005 scan_ptr++;
7006 if (scan_ptr == MAX_SCSI_TAR) {
7007 scan_ptr = 0;
7008 }
7009 }
7010
7011 }
7012 else
7013 {
7014 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007015 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007016 {
7017
7018 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7019
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007020 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007021
7022 if (currTar_Info->TarSelQ_Head == NULL)
7023 {
7024 currTar_Info->TarSelQ_Tail = NULL;
7025 currTar_Info->TarSelQ_Cnt = 0;
7026 }
7027 else
7028 {
7029 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007030 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007031 }
7032
7033 scan_ptr++;
7034 if (scan_ptr == MAX_SCSI_TAR)
7035 scan_ptr = 0;
7036
7037 pCurrCard->scanIndex = scan_ptr;
7038
7039 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7040
7041 break;
7042 }
7043
7044 else
7045 {
7046 scan_ptr++;
7047 if (scan_ptr == MAX_SCSI_TAR)
7048 {
7049 scan_ptr = 0;
7050 }
7051 }
7052 }
7053 } while (scan_ptr != pCurrCard->scanIndex);
7054}
7055
7056
7057/*---------------------------------------------------------------------
7058 *
7059 * Function: Queue Select Fail
7060 *
7061 * Description: Add the current SCCB to the head of the Queue.
7062 *
7063 *---------------------------------------------------------------------*/
7064
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007065static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007066{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007067 unsigned char thisTarg;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007068 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007069
7070 if (pCurrCard->currentSCCB != NULL)
7071 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007072 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007073 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007074
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007075 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076
7077 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7078
7079 if (currTar_Info->TarSelQ_Cnt == 0)
7080 {
7081 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7082 }
7083
7084 else
7085 {
7086 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7087 }
7088
7089
7090 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7091
7092 pCurrCard->currentSCCB = NULL;
7093 currTar_Info->TarSelQ_Cnt++;
7094 }
7095}
7096/*---------------------------------------------------------------------
7097 *
7098 * Function: Queue Command Complete
7099 *
7100 * Description: Call the callback function with the current SCCB.
7101 *
7102 *---------------------------------------------------------------------*/
7103
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007104static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007105 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007106{
7107
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007108 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007109 CALL_BK_FN callback;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007110 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007111
7112 SCSIcmd = p_sccb->Cdb[0];
7113
7114
7115 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7116
7117 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7118 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7119 (p_sccb->TargetStatus != SSCHECK))
7120
7121 if ((SCSIcmd == SCSI_READ) ||
7122 (SCSIcmd == SCSI_WRITE) ||
7123 (SCSIcmd == SCSI_READ_EXTENDED) ||
7124 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7125 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7126 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7127 (pCurrCard->globalFlags & F_NO_FILTER)
7128 )
7129 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7130 }
7131
7132
7133 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7134 {
7135 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7136 p_sccb->SccbStatus = SCCB_ERROR;
7137 else
7138 p_sccb->SccbStatus = SCCB_SUCCESS;
7139 }
7140
7141 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7142
7143 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7144 for (i=0; i < 6; i++) {
7145 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7146 }
7147 }
7148
7149 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7150 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7151
James Bottomley 47b5d692005-04-24 02:38:05 -05007152 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007153 }
7154
7155 pCurrCard->cmdCounter--;
7156 if (!pCurrCard->cmdCounter) {
7157
7158 if (pCurrCard->globalFlags & F_GREEN_PC) {
7159 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7160 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7161 }
7162
7163 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7164 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7165
7166 }
7167
7168 if(pCurrCard->discQCount != 0)
7169 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007170 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007171 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7172 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7173 {
7174 pCurrCard->discQCount--;
7175 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7176 }
7177 else
7178 {
7179 if(p_sccb->Sccb_tag)
7180 {
7181 pCurrCard->discQCount--;
7182 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7183 }else
7184 {
7185 pCurrCard->discQCount--;
7186 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7187 }
7188 }
7189
7190 }
7191
7192 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7193 callback(p_sccb);
7194 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7195 pCurrCard->currentSCCB = NULL;
7196}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007197
7198
7199/*---------------------------------------------------------------------
7200 *
7201 * Function: Queue Disconnect
7202 *
7203 * Description: Add SCCB to our disconnect array.
7204 *
7205 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007206static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007207{
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007208 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007209
James Bottomley 47b5d692005-04-24 02:38:05 -05007210 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007211
James Bottomley 47b5d692005-04-24 02:38:05 -05007212 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007213 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7214 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007215 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007216 }
7217 else
7218 {
7219 if (p_sccb->Sccb_tag)
7220 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007221 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7222 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7223 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007224 }else
7225 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007226 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007227 }
7228 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007229 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007230}
7231
7232
7233/*---------------------------------------------------------------------
7234 *
7235 * Function: Queue Flush SCCB
7236 *
7237 * Description: Flush all SCCB's back to the host driver for this target.
7238 *
7239 *---------------------------------------------------------------------*/
7240
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007241static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007242{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007243 unsigned char qtag,thisTarg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007244 struct sccb * currSCCB;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007245 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007246
James Bottomley 47b5d692005-04-24 02:38:05 -05007247 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007248 if(currSCCB != NULL)
7249 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007250 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007251 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007252
7253 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7254
James Bottomley 47b5d692005-04-24 02:38:05 -05007255 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7256 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007257 {
7258
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007259 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007260
James Bottomley 47b5d692005-04-24 02:38:05 -05007261 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007262
James Bottomley 47b5d692005-04-24 02:38:05 -05007263 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007264 currTar_Info->TarTagQ_Cnt--;
7265
7266 }
7267 }
7268 }
7269
7270}
7271
7272/*---------------------------------------------------------------------
7273 *
7274 * Function: Queue Flush Target SCCB
7275 *
7276 * Description: Flush all SCCB's back to the host driver for this target.
7277 *
7278 *---------------------------------------------------------------------*/
7279
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007280static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7281 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007282{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007283 unsigned char qtag;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007284 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007285
James Bottomley 47b5d692005-04-24 02:38:05 -05007286 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007287
7288 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7289
James Bottomley 47b5d692005-04-24 02:38:05 -05007290 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7291 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292 {
7293
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007294 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007295
James Bottomley 47b5d692005-04-24 02:38:05 -05007296 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297
James Bottomley 47b5d692005-04-24 02:38:05 -05007298 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299 currTar_Info->TarTagQ_Cnt--;
7300
7301 }
7302 }
7303
7304}
7305
7306
7307
7308
7309
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007310static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007311{
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007312 struct sccb_mgr_tar_info * currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007313 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007314
7315 p_SCCB->Sccb_forwardlink = NULL;
7316
7317 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7318
7319 if (currTar_Info->TarSelQ_Cnt == 0) {
7320
7321 currTar_Info->TarSelQ_Head = p_SCCB;
7322 }
7323
7324 else {
7325
7326 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7327 }
7328
7329
7330 currTar_Info->TarSelQ_Tail = p_SCCB;
7331 currTar_Info->TarSelQ_Cnt++;
7332}
7333
7334
7335/*---------------------------------------------------------------------
7336 *
7337 * Function: Queue Find SCCB
7338 *
7339 * Description: Search the target select Queue for this SCCB, and
7340 * remove it if found.
7341 *
7342 *---------------------------------------------------------------------*/
7343
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007344static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007345{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007346 struct sccb * q_ptr;
Alexey Dobriyanf31dc0c2006-03-08 00:14:31 -08007347 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007348
James Bottomley 47b5d692005-04-24 02:38:05 -05007349 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007350
7351 q_ptr = currTar_Info->TarSelQ_Head;
7352
7353 while(q_ptr != NULL) {
7354
7355 if (q_ptr == p_SCCB) {
7356
7357
7358 if (currTar_Info->TarSelQ_Head == q_ptr) {
7359
7360 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7361 }
7362
7363 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7364
7365 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7366 }
7367
7368 if (q_ptr->Sccb_forwardlink != NULL) {
7369 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7370 }
7371
7372 if (q_ptr->Sccb_backlink != NULL) {
7373 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7374 }
7375
7376 currTar_Info->TarSelQ_Cnt--;
7377
James Bottomley 47b5d692005-04-24 02:38:05 -05007378 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007379 }
7380
7381 else {
7382 q_ptr = q_ptr->Sccb_forwardlink;
7383 }
7384 }
7385
7386
James Bottomley 47b5d692005-04-24 02:38:05 -05007387 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007388
7389}
7390
7391
7392/*---------------------------------------------------------------------
7393 *
7394 * Function: Utility Update Residual Count
7395 *
7396 * Description: Update the XferCnt to the remaining byte count.
7397 * If we transferred all the data then just write zero.
7398 * If Non-SG transfer then report Total Cnt - Actual Transfer
7399 * Cnt. For SG transfers add the count fields of all
7400 * remaining SG elements, as well as any partial remaining
7401 * element.
7402 *
7403 *---------------------------------------------------------------------*/
7404
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007405static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007406{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007407 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007408 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007409 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007410
7411 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7412
7413 p_SCCB->DataLength = 0x0000;
7414 }
7415
7416 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7417
7418 partial_cnt = 0x0000;
7419
7420 sg_index = p_SCCB->Sccb_sgseg;
7421
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007422 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007423
7424 if (p_SCCB->Sccb_SGoffset) {
7425
7426 partial_cnt = p_SCCB->Sccb_SGoffset;
7427 sg_index++;
7428 }
7429
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007430 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007431 p_SCCB->DataLength ) {
7432
7433 partial_cnt += *(sg_ptr+(sg_index * 2));
7434 sg_index++;
7435 }
7436
7437 p_SCCB->DataLength = partial_cnt;
7438 }
7439
7440 else {
7441
7442 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7443 }
7444}
7445
7446
7447/*---------------------------------------------------------------------
7448 *
7449 * Function: Wait 1 Second
7450 *
7451 * Description: Wait for 1 second.
7452 *
7453 *---------------------------------------------------------------------*/
7454
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007455static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007456{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007457 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007458
7459 for(i=0; i < 4; i++) {
7460
James Bottomley 47b5d692005-04-24 02:38:05 -05007461 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007462
7463 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7464 break;
7465
7466 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7467 break;
7468 }
7469}
7470
7471
7472/*---------------------------------------------------------------------
7473 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007474 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007475 *
7476 * Description: Wait the desired delay.
7477 *
7478 *---------------------------------------------------------------------*/
7479
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007480static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007481{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007482 unsigned char old_timer;
7483 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007484
7485 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7486
7487 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7488 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7489
7490 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7491 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007492 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007493
7494
7495 WR_HARPOON(p_port+hp_portctrl_0,
7496 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7497
7498 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7499
7500 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7501 break;
7502
7503 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7504 break;
7505 }
7506
7507 WR_HARPOON(p_port+hp_portctrl_0,
7508 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7509
7510 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007511 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007512
7513 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7514
7515 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7516}
7517
7518
7519/*---------------------------------------------------------------------
7520 *
7521 * Function: Enable/Disable Write to EEPROM
7522 *
7523 * Description: The EEPROM must first be enabled for writes
7524 * A total of 9 clocks are needed.
7525 *
7526 *---------------------------------------------------------------------*/
7527
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007528static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007529{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007530 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007531
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007532 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007533
7534 if (p_mode)
7535
James Bottomley 47b5d692005-04-24 02:38:05 -05007536 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007537
7538 else
7539
7540
James Bottomley 47b5d692005-04-24 02:38:05 -05007541 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007542
7543 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7544 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7545}
7546
7547
7548/*---------------------------------------------------------------------
7549 *
7550 * Function: Write EEPROM
7551 *
7552 * Description: Write a word to the EEPROM at the specified
7553 * address.
7554 *
7555 *---------------------------------------------------------------------*/
7556
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007557static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007558{
7559
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007560 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007561 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007562
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007563 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
Linus Torvalds1da177e2005-04-16 15:20:36 -07007564 (SEE_MS | SEE_CS));
7565
7566
7567
James Bottomley 47b5d692005-04-24 02:38:05 -05007568 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007569
7570
7571 ee_value |= (SEE_MS + SEE_CS);
7572
7573 for(i = 0x8000; i != 0; i>>=1) {
7574
7575 if (i & ee_data)
7576 ee_value |= SEE_DO;
7577 else
7578 ee_value &= ~SEE_DO;
7579
7580 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7581 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7582 ee_value |= SEE_CLK; /* Clock data! */
7583 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 ee_value &= ~SEE_CLK;
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 }
7589 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7590 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7591
James Bottomley 47b5d692005-04-24 02:38:05 -05007592 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007593
7594 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7595 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7597}
7598
7599/*---------------------------------------------------------------------
7600 *
7601 * Function: Read EEPROM
7602 *
7603 * Description: Read a word from the EEPROM at the desired
7604 * address.
7605 *
7606 *---------------------------------------------------------------------*/
7607
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007608static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007609{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007610 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007611
7612 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007613 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007614 do
7615 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007616 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007617
7618 if(ee_data1 == ee_data2)
7619 return(ee_data1);
7620
7621 ee_data1 = ee_data2;
7622 i++;
7623
7624 }while(i < 4);
7625
7626 return(ee_data1);
7627}
7628
7629/*---------------------------------------------------------------------
7630 *
7631 * Function: Read EEPROM Original
7632 *
7633 * Description: Read a word from the EEPROM at the desired
7634 * address.
7635 *
7636 *---------------------------------------------------------------------*/
7637
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007638static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007639{
7640
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007641 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007642 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007643
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007644 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
Linus Torvalds1da177e2005-04-16 15:20:36 -07007645 (SEE_MS | SEE_CS));
7646
7647
James Bottomley 47b5d692005-04-24 02:38:05 -05007648 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007649
7650
7651 ee_value |= (SEE_MS + SEE_CS);
7652 ee_data = 0;
7653
7654 for(i = 1; i <= 16; i++) {
7655
7656 ee_value |= SEE_CLK; /* Clock data! */
7657 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7658 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7659 ee_value &= ~SEE_CLK;
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7662
7663 ee_data <<= 1;
7664
7665 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7666 ee_data |= 1;
7667 }
7668
7669 ee_value &= ~(SEE_MS + SEE_CS);
7670 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7672
7673 return(ee_data);
7674}
7675
7676
7677/*---------------------------------------------------------------------
7678 *
7679 * Function: Send EE command and Address to the EEPROM
7680 *
7681 * Description: Transfers the correct command and sends the address
7682 * to the eeprom.
7683 *
7684 *---------------------------------------------------------------------*/
7685
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007686static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007687{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007688 unsigned char ee_value;
7689 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007690
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007691 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007692
7693
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007694 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007695
7696
7697 ee_value = SEE_MS;
7698 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7699
7700 ee_value |= SEE_CS; /* Set CS to EEPROM */
7701 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7702
7703
7704 for(i = 0x04; i != 0; i>>=1) {
7705
7706 if (i & ee_cmd)
7707 ee_value |= SEE_DO;
7708 else
7709 ee_value &= ~SEE_DO;
7710
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713 ee_value |= SEE_CLK; /* Clock data! */
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 ee_value &= ~SEE_CLK;
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 }
7720
7721
7722 if (narrow_flg)
7723 i = 0x0080;
7724
7725 else
7726 i = 0x0200;
7727
7728
7729 while (i != 0) {
7730
7731 if (i & ee_addr)
7732 ee_value |= SEE_DO;
7733 else
7734 ee_value &= ~SEE_DO;
7735
7736 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7737 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7738 ee_value |= SEE_CLK; /* Clock data! */
7739 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 ee_value &= ~SEE_CLK;
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744
7745 i >>= 1;
7746 }
7747}
7748
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007749static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007750{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007751 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007752 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007753 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007754 for (i=0; i < ID_STRING_LENGTH; i++)
7755 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007756 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007757 for(j=0; j < 8; j++)
7758 {
7759 if ((crc ^ ch) & 1)
7760 crc = (crc >> 1) ^ CRCMASK;
7761 else
7762 crc >>= 1;
7763 ch >>= 1;
7764 }
7765 }
7766 return(crc);
7767}
7768
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007769static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007770{
7771 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007772 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007773 lrc = 0;
7774 for(i = 0; i < ID_STRING_LENGTH; i++)
7775 lrc ^= buffer[i];
7776 return(lrc);
7777}
7778
7779
7780
7781/*
7782 The following inline definitions avoid type conflicts.
7783*/
7784
7785static inline unsigned char
7786FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7787{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007788 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007789}
7790
7791
7792static inline FlashPoint_CardHandle_T
7793FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7794{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007795 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007796}
7797
7798static inline void
7799FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7800{
7801 FlashPoint_ReleaseHostAdapter(CardHandle);
7802}
7803
7804
7805static inline void
7806FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7807{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007808 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007809}
7810
7811
7812static inline void
7813FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7814{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007815 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007816}
7817
7818
7819static inline boolean
7820FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7821{
7822 return FlashPoint_InterruptPending(CardHandle);
7823}
7824
7825
7826static inline int
7827FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7828{
7829 return FlashPoint_HandleInterrupt(CardHandle);
7830}
7831
7832
7833#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7834#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7835#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7836#define FlashPoint_StartCCB FlashPoint__StartCCB
7837#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7838#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7839#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7840
7841
Linus Torvalds1da177e2005-04-16 15:20:36 -07007842#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7843
7844
7845/*
7846 Define prototypes for the FlashPoint SCCB Manager Functions.
7847*/
7848
7849extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7850extern FlashPoint_CardHandle_T
7851 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7852extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7853extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7854extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7855extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7856extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007857
7858
7859#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */