blob: 895e4ff7be1dfb6942baf98f28db979e8e053f88 [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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 Dobriyanf31dc0cd2006-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 Dobriyandb038cf82006-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 Dobriyanf31dc0cd2006-03-08 00:14:31 -0800286};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287
288typedef struct NVRAMInfo {
Alexey Dobriyandb038cf82006-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 Dobriyandb038cf82006-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 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298}NVRAMINFO;
299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302#define MODEL_LT 1
303#define MODEL_DL 2
304#define MODEL_LW 3
305#define MODEL_DW 4
306
307
308typedef struct SCCBcard {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800309 struct sccb * currentSCCB;
Alexey Dobriyan7f101662006-03-08 00:14:30 -0800310 struct sccb_mgr_info * cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800312 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800314 unsigned short cmdCounter;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -0800315 unsigned char discQCount;
316 unsigned char tagQ_Lst;
317 unsigned char cardIndex;
318 unsigned char scanIndex;
319 unsigned char globalFlags;
320 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 PNVRamInfo pNvRamInfo;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800322 struct sccb * discQ_Tbl[QUEUE_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323
324}SCCBCARD;
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327
328
329#define F_TAG_STARTED 0x01
330#define F_CONLUN_IO 0x02
331#define F_DO_RENEGO 0x04
332#define F_NO_FILTER 0x08
333#define F_GREEN_PC 0x10
334#define F_HOST_XFER_ACT 0x20
335#define F_NEW_SCCB_CMD 0x40
336#define F_UPDATE_EEPROM 0x80
337
338
339#define ID_STRING_LENGTH 32
340#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
343#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
344
345#define ASSIGN_ID 0x00
346#define SET_P_FLAG 0x01
347#define CFG_CMPLT 0x03
348#define DOM_MSTR 0x0F
349#define SYNC_PTRN 0x1F
350
351#define ID_0_7 0x18
352#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353#define MISC_CODE 0x14
354#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
357
358#define INIT_SELTD 0x01
359#define LEVEL2_TAR 0x02
360
361
362enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
363 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
364 CLR_PRIORITY,NO_ID_AVAIL };
365
366typedef struct SCCBscam_info {
367
Alexey Dobriyandb038cf82006-03-08 00:14:24 -0800368 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 enum scam_id_st state;
370
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800371} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375#define SCSI_READ 0x08
376#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378#define SCSI_READ_EXTENDED 0x28
379#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
382
383
384#define SSGOOD 0x00
385#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386#define SSQ_FULL 0x28
387
388
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389
390
391#define SMCMD_COMP 0x00
392#define SMEXT 0x01
393#define SMSAVE_DATA_PTR 0x02
394#define SMREST_DATA_PTR 0x03
395#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396#define SMABORT 0x06
397#define SMREJECT 0x07
398#define SMNO_OP 0x08
399#define SMPARITY 0x09
400#define SMDEV_RESET 0x0C
401#define SMABORT_TAG 0x0D
402#define SMINIT_RECOVERY 0x0F
403#define SMREL_RECOVERY 0x10
404
405#define SMIDENT 0x80
406#define DISC_PRIV 0x40
407
408
409#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410#define SMWDTR 0x03
411#define SM8BIT 0x00
412#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413#define SMIGNORWR 0x23 /* Ignore Wide Residue */
414
415
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
417
418
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420
421
422#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423#define TWELVE_BYTE_CMD 0x0C
424
425#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
427
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429#define EEPROM_WD_CNT 256
430
431#define EEPROM_CHECK_SUM 0
432#define FW_SIGNATURE 2
433#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436#define SYSTEM_CONFIG 16
437#define SCSI_CONFIG 17
438#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439#define SCAM_CONFIG 20
440#define ADAPTER_SCSI_ID 24
441
442
443#define IGNORE_B_SCAN 32
444#define SEND_START_ENA 34
445#define DEVICE_ENABLE 36
446
447#define SYNC_RATE_TBL 38
448#define SYNC_RATE_TBL01 38
449#define SYNC_RATE_TBL23 40
450#define SYNC_RATE_TBL45 42
451#define SYNC_RATE_TBL67 44
452#define SYNC_RATE_TBL89 46
453#define SYNC_RATE_TBLab 48
454#define SYNC_RATE_TBLcd 50
455#define SYNC_RATE_TBLef 52
456
457
458
459#define EE_SCAMBASE 256
460
461
462
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 #define SCAM_ENABLED BIT(2)
464 #define SCAM_LEVEL2 BIT(3)
465
466
467 #define RENEGO_ENA BITW(10)
468 #define CONNIO_ENA BITW(11)
469 #define GREEN_PC_ENA BITW(12)
470
471
472 #define AUTO_RATE_00 00
473 #define AUTO_RATE_05 01
474 #define AUTO_RATE_10 02
475 #define AUTO_RATE_20 03
476
477 #define WIDE_NEGO_BIT BIT(7)
478 #define DISC_ENABLE_BIT BIT(6)
479
480
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 #define hp_vendor_id_0 0x00 /* LSB */
483 #define ORION_VEND_0 0x4B
484
485 #define hp_vendor_id_1 0x01 /* MSB */
486 #define ORION_VEND_1 0x10
487
488 #define hp_device_id_0 0x02 /* LSB */
489 #define ORION_DEV_0 0x30
490
491 #define hp_device_id_1 0x03 /* MSB */
492 #define ORION_DEV_1 0x81
493
494 /* Sub Vendor ID and Sub Device ID only available in
495 Harpoon Version 2 and higher */
496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
501 #define hp_semaphore 0x0C
502 #define SCCB_MGR_ACTIVE BIT(0)
503 #define TICKLE_ME BIT(1)
504 #define SCCB_MGR_PRESENT BIT(3)
505 #define BIOS_IN_USE BIT(4)
506
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
509 #define hp_sys_ctrl 0x0F
510
511 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
512 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
513 #define HALT_MACH BIT(3) /*Halt State Machine */
514 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515
516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800520
521
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 #define hp_host_blk_cnt 0x13
525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
527
528 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
529
530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
532 #define hp_int_mask 0x17
533
534 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
535 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
537
538 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 #define hp_xfer_cnt_hi 0x1A
540 #define hp_xfer_cmd 0x1B
541
542 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
543 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544
545
546 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
551
552 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
553 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554
555 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 #define hp_ee_ctrl 0x22
559
560 #define EXT_ARB_ACK BIT(7)
561 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
562 #define SEE_MS BIT(5)
563 #define SEE_CS BIT(3)
564 #define SEE_CLK BIT(2)
565 #define SEE_DO BIT(1)
566 #define SEE_DI BIT(0)
567
568 #define EE_READ 0x06
569 #define EE_WRITE 0x05
570 #define EWEN 0x04
571 #define EWEN_ADDR 0x03C0
572 #define EWDS 0x04
573 #define EWDS_ADDR 0x0000
574
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
578
579
580
581 #define hp_bm_ctrl 0x26
582
583 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
584 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
586 #define FAST_SINGLE BIT(6) /*?? */
587
588 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
591 #define hp_sg_addr 0x28
592 #define hp_page_ctrl 0x29
593
594 #define SCATTER_EN BIT(0)
595 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
597 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
602 #define hp_pci_stat_cfg 0x2D
603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613 #define hp_rev_num 0x33
614
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615
616 #define hp_stack_data 0x34
617 #define hp_stack_addr 0x35
618
619 #define hp_ext_status 0x36
620
621 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
622 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
623 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 #define CMD_ABORTED BIT(4) /*Command aborted */
625 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
626 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
627 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
628 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
629 BM_PARITY_ERR | PIO_OVERRUN)
630
631 #define hp_int_status 0x37
632
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
634 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
637
638 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
641
642
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 #define hp_intena 0x40
644
645 #define RESET BITW(7)
646 #define PROG_HLT BITW(6)
647 #define PARITY BITW(5)
648 #define FIFO BITW(4)
649 #define SEL BITW(3)
650 #define SCAM_SEL BITW(2)
651 #define RSEL BITW(1)
652 #define TIMEOUT BITW(0)
653 #define BUS_FREE BITW(15)
654 #define XFER_CNT_0 BITW(14)
655 #define PHASE BITW(13)
656 #define IUNKWN BITW(12)
657 #define ICMD_COMP BITW(11)
658 #define ITICKLE BITW(10)
659 #define IDO_STRT BITW(9)
660 #define ITAR_DISC BITW(8)
661 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
662 #define CLR_ALL_INT 0xFFFF
663 #define CLR_ALL_INT_1 0xFF00
664
665 #define hp_intstat 0x42
666
667 #define hp_scsisig 0x44
668
669 #define SCSI_SEL BIT(7)
670 #define SCSI_BSY BIT(6)
671 #define SCSI_REQ BIT(5)
672 #define SCSI_ACK BIT(4)
673 #define SCSI_ATN BIT(3)
674 #define SCSI_CD BIT(2)
675 #define SCSI_MSG BIT(1)
676 #define SCSI_IOBIT BIT(0)
677
678 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
681 #define S_DATAI_PH ( BIT(0))
682 #define S_DATAO_PH 0x00
683 #define S_ILL_PH ( BIT(1) )
684
685 #define hp_scsictrl_0 0x45
686
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 #define SEL_TAR BIT(6)
688 #define ENA_ATN BIT(4)
689 #define ENA_RESEL BIT(2)
690 #define SCSI_RST BIT(1)
691 #define ENA_SCAM_SEL BIT(0)
692
693
694
695 #define hp_portctrl_0 0x46
696
697 #define SCSI_PORT BIT(7)
698 #define SCSI_INBIT BIT(6)
699 #define DMA_PORT BIT(5)
700 #define DMA_RD BIT(4)
701 #define HOST_PORT BIT(3)
702 #define HOST_WRT BIT(2)
703 #define SCSI_BUS_EN BIT(1)
704 #define START_TO BIT(0)
705
706 #define hp_scsireset 0x47
707
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 #define SCSI_INI BIT(6)
709 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 #define DMA_RESET BIT(3)
711 #define HPSCSI_RESET BIT(2)
712 #define PROG_RESET BIT(1)
713 #define FIFO_CLR BIT(0)
714
715 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717
718 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 #define hp_addstat 0x4E
720
721 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 #define SCSI_MODE8 BIT(3)
723 #define SCSI_PAR_ERR BIT(0)
724
725 #define hp_prgmcnt_0 0x4F
726
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727
728 #define hp_selfid_0 0x50
729 #define hp_selfid_1 0x51
730 #define hp_arb_id 0x52
731
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
733 #define hp_select_id 0x53
734
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
736 #define hp_synctarg_base 0x54
737 #define hp_synctarg_12 0x54
738 #define hp_synctarg_13 0x55
739 #define hp_synctarg_14 0x56
740 #define hp_synctarg_15 0x57
741
742 #define hp_synctarg_8 0x58
743 #define hp_synctarg_9 0x59
744 #define hp_synctarg_10 0x5A
745 #define hp_synctarg_11 0x5B
746
747 #define hp_synctarg_4 0x5C
748 #define hp_synctarg_5 0x5D
749 #define hp_synctarg_6 0x5E
750 #define hp_synctarg_7 0x5F
751
752 #define hp_synctarg_0 0x60
753 #define hp_synctarg_1 0x61
754 #define hp_synctarg_2 0x62
755 #define hp_synctarg_3 0x63
756
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 #define DEFAULT_OFFSET 0x0F
759
760 #define hp_autostart_0 0x64
761 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 #define hp_autostart_3 0x67
763
764
765
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 #define AUTO_IMMED BIT(5)
767 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769
770 #define hp_gp_reg_0 0x68
771 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 #define hp_gp_reg_3 0x6B
773
774 #define hp_seltimeout 0x6C
775
776
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 #define TO_4ms 0x67 /* 3.9959ms */
778
779 #define TO_5ms 0x03 /* 4.9152ms */
780 #define TO_10ms 0x07 /* 11.xxxms */
781 #define TO_250ms 0x99 /* 250.68ms */
782 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
784 #define hp_clkctrl_0 0x6D
785
786 #define PWR_DWN BIT(6)
787 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789
790 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
791
792 #define hp_fiforead 0x6E
793 #define hp_fifowrite 0x6F
794
795 #define hp_offsetctr 0x70
796 #define hp_xferstat 0x71
797
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
800 #define hp_portctrl_1 0x72
801
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 #define CHK_SCSI_P BIT(3)
803 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
805 #define hp_xfer_pad 0x73
806
807 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
809 #define hp_scsidata_0 0x74
810 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 #define hp_aramBase 0x80
815 #define BIOS_DATA_OFFSET 0x60
816 #define BIOS_RELATIVE_CARD 0x64
817
818
819
820
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 #define AR3 (BITW(9) + BITW(8))
822 #define SDATA BITW(10)
823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
825 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
826
827 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
828
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
831 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
832
833 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
834
835
836 #define ADATA_OUT 0x00
837 #define ADATA_IN BITW(8)
838 #define ACOMMAND BITW(10)
839 #define ASTATUS (BITW(10)+BITW(8))
840 #define AMSG_OUT (BITW(10)+BITW(9))
841 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
843
844 #define BRH_OP BITW(13) /* Branch */
845
846
847 #define ALWAYS 0x00
848 #define EQUAL BITW(8)
849 #define NOT_EQ BITW(9)
850
851 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
852
853
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
856
857 #define MPM_OP BITW(15) /* Match phase and move data */
858
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859
860 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
861
862
863 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
864
865
866 #define D_AR0 0x00
867 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
869
870
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
877
878 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
879
880 #define SSI_OP (BITW(15)+BITW(11))
881
882
883 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
884 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
886 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
887 #define SSI_ITICKLE (ITICKLE >> 8)
888
889 #define SSI_IUNKWN (IUNKWN >> 8)
890 #define SSI_INO_CC (IUNKWN >> 8)
891 #define SSI_IRFAIL (IUNKWN >> 8)
892
893
894 #define NP 0x10 /*Next Phase */
895 #define NTCMD 0x02 /*Non- Tagged Command start */
896 #define CMDPZ 0x04 /*Command phase */
897 #define DINT 0x12 /*Data Out/In interrupt */
898 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 #define DC 0x19 /*Disconnect Message */
900 #define ST 0x1D /*Status Phase */
901 #define UNKNWN 0x24 /*Unknown bus action */
902 #define CC 0x25 /*Command Completion failure */
903 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
905
906
907 #define ID_MSG_STRT hp_aramBase + 0x00
908 #define NON_TAG_ID_MSG hp_aramBase + 0x06
909 #define CMD_STRT hp_aramBase + 0x08
910 #define SYNC_MSGS hp_aramBase + 0x08
911
912
913
914
915
916 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 #define DISCONNECT_START 0x10/2
918 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 #define SELCHK_STRT SELCHK/2
921
922
923
924
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925
926
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800928
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
930#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
931/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
932 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800933 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800935#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 -0700936 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800937 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800939 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 count >>= 16,\
941 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
943#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
944 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
945
946
947#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
948 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
949
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
952#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
953 WR_HARPOON(port+hp_scsireset, 0x00))
954
955#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
956 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
957
958#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
959 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
960
961#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
962 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
963
964#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
965 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
966
967
968
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800970static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
971static void FPT_ssel(unsigned long port, unsigned char p_card);
972static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800973static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800974static void FPT_stsyncn(unsigned long port, unsigned char p_card);
975static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
976static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -0800977 struct sccb_mgr_tar_info * currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800978static void FPT_sresb(unsigned long port, unsigned char p_card);
979static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
980static void FPT_schkdd(unsigned long port, unsigned char p_card);
981static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
982static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
983static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800985static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf82006-03-08 00:14:24 -0800986static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
987 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800989static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -0500990static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800992static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
993static void FPT_stwidn(unsigned long port, unsigned char p_card);
994static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995
996
Alexey Dobriyandb038cf82006-03-08 00:14:24 -0800997static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800998static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
999static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001000 unsigned char p_card);
1001static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1002static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001003static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1004static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1005static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001006static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001007static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
1009
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001010static void FPT_Wait1Second(unsigned long p_port);
1011static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1012static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1013static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1014static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1015static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1016static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
1018
1019
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001020static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1021static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1022static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1023static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1024static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1025static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1026static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001028static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1029static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1030static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
1032
1033
1034
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001035static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1036static void FPT_BusMasterInit(unsigned long p_port);
1037static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
1039
1040
1041
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001042static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001043static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1044static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1045static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1046static void FPT_hostDataXferRestart(struct sccb * currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
1048
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001049static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001050 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
James Bottomley 47b5d692005-04-24 02:38:05 -05001052static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001053static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1054static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
1056
1057
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001058static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001060static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1061static void FPT_scbusf(unsigned long p_port);
1062static void FPT_scsel(unsigned long p_port);
1063static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1064static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1065static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1066static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1067static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1068static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001069static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001070static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1071static void FPT_scwtsel(unsigned long p_port);
1072static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1073static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001074static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075
1076
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001077static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1078static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
1080
1081
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08001083static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
James Bottomley 47b5d692005-04-24 02:38:05 -05001084static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1085static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1086static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
1088
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001089static unsigned char FPT_mbCards = 0;
1090static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001091 ' ', 'B', 'T', '-', '9', '3', '0', \
1092 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1093 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001095static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
1097
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001098static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
1101/*---------------------------------------------------------------------
1102 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001103 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 *
1105 * Description: Setup and/or Search for cards and return info to caller.
1106 *
1107 *---------------------------------------------------------------------*/
1108
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001109static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001111 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001113 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001114 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001115 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 PNVRamInfo pCurrNvRam;
1117
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120
1121 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1122 return((int)FAILURE);
1123
1124 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1125 return((int)FAILURE);
1126
1127 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1128 return((int)FAILURE);
1129
1130 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1131 return((int)FAILURE);
1132
1133
1134 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1135
1136/* For new Harpoon then check for sub_device ID LSB
1137 the bits(0-3) must be all ZERO for compatible with
1138 current version of SCCBMgr, else skip this Harpoon
1139 device. */
1140
1141 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1142 return((int)FAILURE);
1143 }
1144
1145 if (first_time)
1146 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001147 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001149 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 }
1151
James Bottomley 47b5d692005-04-24 02:38:05 -05001152 if(FPT_RdStack(ioport, 0) != 0x00) {
1153 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 {
1155 pCurrNvRam = NULL;
1156 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001157 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1158 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159 }
1160 else
1161 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001162 if(FPT_mbCards < MAX_MB_CARDS) {
1163 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1164 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001166 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 }else
1168 return((int) FAILURE);
1169 }
1170 }else
1171 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
1173 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1174 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1175
1176 if(pCurrNvRam)
1177 pCardInfo->si_id = pCurrNvRam->niAdapId;
1178 else
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001179 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1180 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181
1182 pCardInfo->si_lun = 0x00;
1183 pCardInfo->si_fw_revision = ORION_FW_REV;
1184 temp2 = 0x0000;
1185 temp3 = 0x0000;
1186 temp4 = 0x0000;
1187 temp5 = 0x0000;
1188 temp6 = 0x0000;
1189
1190 for (id = 0; id < (16/2); id++) {
1191
1192 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001193 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1195 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1196 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001197 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
1199 for (i = 0; i < 2; temp >>=8,i++) {
1200
1201 temp2 >>= 1;
1202 temp3 >>= 1;
1203 temp4 >>= 1;
1204 temp5 >>= 1;
1205 temp6 >>= 1;
1206 switch (temp & 0x3)
1207 {
1208 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1209 temp6 |= 0x8000; /* Fall through */
1210 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1211 temp5 |= 0x8000; /* Fall through */
1212 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1213 temp2 |= 0x8000; /* Fall through */
1214 case AUTO_RATE_00: /* Asynchronous */
1215 break;
1216 }
1217
1218 if (temp & DISC_ENABLE_BIT)
1219 temp3 |= 0x8000;
1220
1221 if (temp & WIDE_NEGO_BIT)
1222 temp4 |= 0x8000;
1223
1224 }
1225 }
1226
1227 pCardInfo->si_per_targ_init_sync = temp2;
1228 pCardInfo->si_per_targ_no_disc = temp3;
1229 pCardInfo->si_per_targ_wide_nego = temp4;
1230 pCardInfo->si_per_targ_fast_nego = temp5;
1231 pCardInfo->si_per_targ_ultra_nego = temp6;
1232
1233 if(pCurrNvRam)
1234 i = pCurrNvRam->niSysConf;
1235 else
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001236 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
1238 if(pCurrNvRam)
1239 ScamFlg = pCurrNvRam->niScamConf;
1240 else
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001241 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
1243 pCardInfo->si_flags = 0x0000;
1244
1245 if (i & 0x01)
1246 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1247
1248 if (!(i & 0x02))
1249 pCardInfo->si_flags |= SOFT_RESET;
1250
1251 if (i & 0x10)
1252 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1253
1254 if (ScamFlg & SCAM_ENABLED)
1255 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1256
1257 if (ScamFlg & SCAM_LEVEL2)
1258 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1259
1260 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1261 if (i & 0x04) {
1262 j |= SCSI_TERM_ENA_L;
1263 }
1264 WR_HARPOON(ioport+hp_bm_ctrl, j );
1265
1266 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1267 if (i & 0x08) {
1268 j |= SCSI_TERM_ENA_H;
1269 }
1270 WR_HARPOON(ioport+hp_ee_ctrl, j );
1271
1272 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1273
1274 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1275
1276 pCardInfo->si_card_family = HARPOON_FAMILY;
1277 pCardInfo->si_bustype = BUSTYPE_PCI;
1278
1279 if(pCurrNvRam){
1280 pCardInfo->si_card_model[0] = '9';
1281 switch(pCurrNvRam->niModel & 0x0f){
1282 case MODEL_LT:
1283 pCardInfo->si_card_model[1] = '3';
1284 pCardInfo->si_card_model[2] = '0';
1285 break;
1286 case MODEL_LW:
1287 pCardInfo->si_card_model[1] = '5';
1288 pCardInfo->si_card_model[2] = '0';
1289 break;
1290 case MODEL_DL:
1291 pCardInfo->si_card_model[1] = '3';
1292 pCardInfo->si_card_model[2] = '2';
1293 break;
1294 case MODEL_DW:
1295 pCardInfo->si_card_model[1] = '5';
1296 pCardInfo->si_card_model[2] = '2';
1297 break;
1298 }
1299 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001300 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001301 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001302 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001304 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1305 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 }
1307
1308 if (pCardInfo->si_card_model[1] == '3')
1309 {
1310 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1311 pCardInfo->si_flags |= LOW_BYTE_TERM;
1312 }
1313 else if (pCardInfo->si_card_model[2] == '0')
1314 {
1315 temp = RD_HARPOON(ioport+hp_xfer_pad);
1316 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1317 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1318 pCardInfo->si_flags |= LOW_BYTE_TERM;
1319 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1320 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1321 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1322 WR_HARPOON(ioport+hp_xfer_pad, temp);
1323 }
1324 else
1325 {
1326 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1327 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1328 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1329 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1330 temp3 = 0;
1331 for (i = 0; i < 8; i++)
1332 {
1333 temp3 <<= 1;
1334 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1335 temp3 |= 1;
1336 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1337 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1338 }
1339 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1340 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1341 if (!(temp3 & BIT(7)))
1342 pCardInfo->si_flags |= LOW_BYTE_TERM;
1343 if (!(temp3 & BIT(6)))
1344 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1345 }
1346
1347
1348 ARAM_ACCESS(ioport);
1349
1350 for ( i = 0; i < 4; i++ ) {
1351
1352 pCardInfo->si_XlatInfo[i] =
1353 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1354 }
1355
1356 /* return with -1 if no sort, else return with
1357 logical card number sorted by BIOS (zero-based) */
1358
1359 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001360 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
1362 SGRAM_ACCESS(ioport);
1363
James Bottomley 47b5d692005-04-24 02:38:05 -05001364 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1365 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1366 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1367 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1368 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1369 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1370 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1371 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
1373 pCardInfo->si_present = 0x01;
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 return(0);
1376}
1377
1378
1379/*---------------------------------------------------------------------
1380 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001381 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 *
1383 * Description: Setup adapter for normal operation (hard reset).
1384 *
1385 *---------------------------------------------------------------------*/
1386
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001387static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388{
1389 PSCCBcard CurrCard = NULL;
1390 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001391 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001392 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001393 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
1397 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1398
1399 if (thisCard == MAX_CARDS) {
1400
1401 return(FAILURE);
1402 }
1403
James Bottomley 47b5d692005-04-24 02:38:05 -05001404 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
James Bottomley 47b5d692005-04-24 02:38:05 -05001406 CurrCard = &FPT_BL_Card[thisCard];
1407 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 break;
1409 }
1410
James Bottomley 47b5d692005-04-24 02:38:05 -05001411 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412
James Bottomley 47b5d692005-04-24 02:38:05 -05001413 FPT_BL_Card[thisCard].ioPort = ioport;
1414 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
James Bottomley 47b5d692005-04-24 02:38:05 -05001416 if(FPT_mbCards)
1417 for(i = 0; i < FPT_mbCards; i++){
1418 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1419 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001421 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422 CurrCard->cardIndex = thisCard;
1423 CurrCard->cardInfo = pCardInfo;
1424
1425 break;
1426 }
1427 }
1428
1429 pCurrNvRam = CurrCard->pNvRamInfo;
1430
1431 if(pCurrNvRam){
1432 ScamFlg = pCurrNvRam->niScamConf;
1433 }
1434 else{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001435 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 }
1437
1438
James Bottomley 47b5d692005-04-24 02:38:05 -05001439 FPT_BusMasterInit(ioport);
1440 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
James Bottomley 47b5d692005-04-24 02:38:05 -05001442 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
1444
1445 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1446
1447 WR_HARPOON(ioport+hp_selfid_0, id);
1448 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1449 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1450 CurrCard->ourId = pCardInfo->si_id;
1451
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001452 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 if (i & SCSI_PARITY_ENA)
1454 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1455
1456 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1457 if (i & LOW_BYTE_TERM)
1458 j |= SCSI_TERM_ENA_L;
1459 WR_HARPOON(ioport+hp_bm_ctrl, j);
1460
1461 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1462 if (i & HIGH_BYTE_TERM)
1463 j |= SCSI_TERM_ENA_H;
1464 WR_HARPOON(ioport+hp_ee_ctrl, j );
1465
1466
1467 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1468
James Bottomley 47b5d692005-04-24 02:38:05 -05001469 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
James Bottomley 47b5d692005-04-24 02:38:05 -05001471 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 }
1473
1474
1475
1476 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1477 CurrCard->globalFlags |= F_NO_FILTER;
1478
1479 if(pCurrNvRam){
1480 if(pCurrNvRam->niSysConf & 0x10)
1481 CurrCard->globalFlags |= F_GREEN_PC;
1482 }
1483 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001484 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 CurrCard->globalFlags |= F_GREEN_PC;
1486 }
1487
1488 /* Set global flag to indicate Re-Negotiation to be done on all
1489 ckeck condition */
1490 if(pCurrNvRam){
1491 if(pCurrNvRam->niScsiConf & 0x04)
1492 CurrCard->globalFlags |= F_DO_RENEGO;
1493 }
1494 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001495 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 CurrCard->globalFlags |= F_DO_RENEGO;
1497 }
1498
1499 if(pCurrNvRam){
1500 if(pCurrNvRam->niScsiConf & 0x08)
1501 CurrCard->globalFlags |= F_CONLUN_IO;
1502 }
1503 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001504 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 CurrCard->globalFlags |= F_CONLUN_IO;
1506 }
1507
1508
1509 temp = pCardInfo->si_per_targ_no_disc;
1510
1511 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1512
1513 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001514 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 }
1516
1517 sync_bit_map = 0x0001;
1518
1519 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1520
1521 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001522 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1524 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1525 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001526 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528 for (i = 0; i < 2; temp >>=8,i++) {
1529
1530 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1531
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001532 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 }
1534
1535 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001536 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1537 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001538 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 }
1540
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1542 (id*2+i >= 8)){
1543*/
1544 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1545
James Bottomley 47b5d692005-04-24 02:38:05 -05001546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547
1548 }
1549
1550 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001551 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 }
1553
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
1555 sync_bit_map <<= 1;
1556
1557
1558
1559 }
1560 }
1561
1562 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001563 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001565 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566}
1567
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001568static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001570 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001571 unsigned long portBase;
1572 unsigned long regOffset;
1573 unsigned long scamData;
1574 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 PNVRamInfo pCurrNvRam;
1576
1577 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1578
1579 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001580 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
1586 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001587 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588
1589 portBase = pCurrNvRam->niBaseAddr;
1590
1591 for(i = 0; i < MAX_SCSI_TAR; i++){
1592 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001593 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 scamData = *pScamTbl;
1595 WR_HARP32(portBase, regOffset, scamData);
1596 }
1597
1598 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001599 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 }
1601}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602
1603
James Bottomley 47b5d692005-04-24 02:38:05 -05001604static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001606 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001607 unsigned long portBase;
1608 unsigned long regOffset;
1609 unsigned long scamData;
1610 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
James Bottomley 47b5d692005-04-24 02:38:05 -05001612 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1613 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1614 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1615 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1616 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617
1618 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001619 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620
1621 portBase = pNvRamInfo->niBaseAddr;
1622
1623 for(i = 0; i < MAX_SCSI_TAR; i++){
1624 regOffset = hp_aramBase + 64 + i*4;
1625 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001626 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 *pScamTbl = scamData;
1628 }
1629
1630}
1631
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001632static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633{
1634 WR_HARPOON(portBase + hp_stack_addr, index);
1635 return(RD_HARPOON(portBase + hp_stack_data));
1636}
1637
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001638static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639{
1640 WR_HARPOON(portBase + hp_stack_addr, index);
1641 WR_HARPOON(portBase + hp_stack_data, data);
1642}
1643
1644
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001645static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646{
James Bottomley 47b5d692005-04-24 02:38:05 -05001647 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1648 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1650 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001651 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1653 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001654 return(1);
1655 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
1657}
1658/*---------------------------------------------------------------------
1659 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001660 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 *
1662 * Description: Start a command pointed to by p_Sccb. When the
1663 * command is completed it will be returned via the
1664 * callback function.
1665 *
1666 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001667static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001669 unsigned long ioport;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001670 unsigned char thisCard, lun;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001671 struct sccb * pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 CALL_BK_FN callback;
1673
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1675 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1676
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1678 {
1679
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 p_Sccb->HostStatus = SCCB_COMPLETE;
1681 p_Sccb->SccbStatus = SCCB_ERROR;
1682 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1683 if (callback)
1684 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 return;
1687 }
1688
James Bottomley 47b5d692005-04-24 02:38:05 -05001689 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
1691
1692 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1693 {
1694 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1695 | SCCB_MGR_ACTIVE));
1696
1697 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1698 {
1699 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1700 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1701 }
1702 }
1703
1704 ((PSCCBcard)pCurrCard)->cmdCounter++;
1705
1706 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1707
1708 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1709 | TICKLE_ME));
1710 if(p_Sccb->OperationCode == RESET_COMMAND)
1711 {
1712 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1713 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001714 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1716 }
1717 else
1718 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001719 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 }
1721 }
1722
1723 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1724
1725 if(p_Sccb->OperationCode == RESET_COMMAND)
1726 {
1727 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1728 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001729 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1731 }
1732 else
1733 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001734 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 }
1736 }
1737
1738 else {
1739
1740 MDISABLE_INT(ioport);
1741
1742 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001743 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 lun = p_Sccb->Lun;
1745 else
1746 lun = 0;
1747 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001748 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1749 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1750 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751
1752 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001753 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 }
1755
1756 else {
1757
1758 if(p_Sccb->OperationCode == RESET_COMMAND)
1759 {
1760 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1761 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001762 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1764 }
1765 else
1766 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001767 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 }
1769 }
1770
1771
1772 MENABLE_INT(ioport);
1773 }
1774
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775}
1776
1777
1778/*---------------------------------------------------------------------
1779 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001780 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 *
1782 * Description: Abort the command pointed to by p_Sccb. When the
1783 * command is completed it will be returned via the
1784 * callback function.
1785 *
1786 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001787static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001789 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001791 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 CALL_BK_FN callback;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001793 unsigned char TID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001794 struct sccb * pSaveSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08001795 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
1797
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1799
1800 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1801
James Bottomley 47b5d692005-04-24 02:38:05 -05001802 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 {
1804
James Bottomley 47b5d692005-04-24 02:38:05 -05001805 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 {
1807
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 ((PSCCBcard)pCurrCard)->cmdCounter--;
1809
1810 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1811 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001812 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 p_Sccb->SccbStatus = SCCB_ABORT;
1815 callback = p_Sccb->SccbCallback;
1816 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
1818 return(0);
1819 }
1820
1821 else
1822 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1824 {
1825 p_Sccb->SccbStatus = SCCB_ABORT;
1826 return(0);
1827
1828 }
1829
1830 else
1831 {
1832
1833 TID = p_Sccb->TargID;
1834
1835
1836 if(p_Sccb->Sccb_tag)
1837 {
1838 MDISABLE_INT(ioport);
1839 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1840 {
1841 p_Sccb->SccbStatus = SCCB_ABORT;
1842 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1844
1845 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1846 {
1847 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001848 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 }
1850 else
1851 {
1852 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1853 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001854 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1856 }
1857 }
1858 MENABLE_INT(ioport);
1859 return(0);
1860 }
1861 else
1862 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001863 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
James Bottomley 47b5d692005-04-24 02:38:05 -05001865 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 == p_Sccb)
1867 {
1868 p_Sccb->SccbStatus = SCCB_ABORT;
1869 return(0);
1870 }
1871 }
1872 }
1873 }
1874 }
1875 return(-1);
1876}
1877
1878
1879/*---------------------------------------------------------------------
1880 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001881 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 *
1883 * Description: Do a quick check to determine if there is a pending
1884 * interrupt for this card and disable the IRQ Pin if so.
1885 *
1886 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001887static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001889 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
1891 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1892
1893 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1894 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001895 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 }
1897
1898 else
1899
James Bottomley 47b5d692005-04-24 02:38:05 -05001900 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901}
1902
1903
1904
1905/*---------------------------------------------------------------------
1906 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001907 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 *
1909 * Description: This is our entry point when an interrupt is generated
1910 * by the card and the upper level driver passes it on to
1911 * us.
1912 *
1913 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001914static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001916 struct sccb * currSCCB;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001917 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001918 unsigned short hp_int;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001919 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001920 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921
1922 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1923 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1924
1925 MDISABLE_INT(ioport);
1926
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08001928 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 else
1930 bm_status = 0;
1931
1932 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1933
James Bottomley 47b5d692005-04-24 02:38:05 -05001934 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 bm_status)
1936 {
1937
1938 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1939
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001941 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1943 bm_status = 0;
1944
1945 if (result) {
1946
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 return(result);
1949 }
1950 }
1951
1952
1953 else if (hp_int & ICMD_COMP) {
1954
1955 if ( !(hp_int & BUS_FREE) ) {
1956 /* Wait for the BusFree before starting a new command. We
1957 must also check for being reselected since the BusFree
1958 may not show up if another device reselects us in 1.5us or
1959 less. SRR Wednesday, 3/8/1995.
1960 */
1961 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1962 }
1963
1964 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1965
James Bottomley 47b5d692005-04-24 02:38:05 -05001966 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967
1968/* WRW_HARPOON((ioport+hp_intstat),
1969 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1970 */
1971
1972 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1973
James Bottomley 47b5d692005-04-24 02:38:05 -05001974 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976 }
1977
1978
1979 else if (hp_int & ITAR_DISC)
1980 {
1981
1982 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1983
James Bottomley 47b5d692005-04-24 02:38:05 -05001984 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001985
1986 }
1987
1988 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1989
1990 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1991 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1992
1993 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1994 }
1995
1996 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05001997 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998
1999 /* Wait for the BusFree before starting a new command. We
2000 must also check for being reselected since the BusFree
2001 may not show up if another device reselects us in 1.5us or
2002 less. SRR Wednesday, 3/8/1995.
2003 */
2004 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2005 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2006 RD_HARPOON((ioport+hp_scsisig)) ==
2007 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2008
2009 /*
2010 The additional loop exit condition above detects a timing problem
2011 with the revision D/E harpoon chips. The caller should reset the
2012 host adapter to recover when 0xFE is returned.
2013 */
2014 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2015 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 return 0xFE;
2018 }
2019
2020 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2021
2022
2023 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2024
2025 }
2026
2027
2028 else if (hp_int & RSEL) {
2029
2030 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2031
2032 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2033 {
2034 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2035 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002036 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037 }
2038
2039 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2040 {
2041 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2042 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2043 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2044 }
2045
2046 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2047 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002048 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 }
2050
James Bottomley 47b5d692005-04-24 02:38:05 -05002051 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2052 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
2054 }
2055
2056
2057 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2058 {
2059
2060 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002061 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
2063 }
2064
2065
2066 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2067 {
2068 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002069 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002071 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072 }
2073 else
2074 {
2075 /* Harpoon problem some SCSI target device respond to selection
2076 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2077 to latch the correct Target ID into reg. x53.
2078 The work around require to correct this reg. But when write to this
2079 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2080 need to read this reg first then restore it later. After update to 0x53 */
2081
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002082 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2083 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2084 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2085 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2086 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 WR_HARPOON(ioport+hp_fifowrite, i);
2088 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2089 }
2090 }
2091
2092 else if (hp_int & XFER_CNT_0) {
2093
2094 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2095
James Bottomley 47b5d692005-04-24 02:38:05 -05002096 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097
2098 }
2099
2100
2101 else if (hp_int & BUS_FREE) {
2102
2103 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2104
2105 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2106
James Bottomley 47b5d692005-04-24 02:38:05 -05002107 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 }
2109
James Bottomley 47b5d692005-04-24 02:38:05 -05002110 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 }
2112
2113
2114 else if (hp_int & ITICKLE) {
2115
2116 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2117 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2118 }
2119
2120
2121
2122 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2123
2124
2125 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2126
2127
2128 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2129
James Bottomley 47b5d692005-04-24 02:38:05 -05002130 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131 }
2132
2133 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2134 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002135 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136 }
2137
2138 break;
2139
2140 }
2141
2142 } /*end while */
2143
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145
2146 return(0);
2147}
2148
2149/*---------------------------------------------------------------------
2150 *
2151 * Function: Sccb_bad_isr
2152 *
2153 * Description: Some type of interrupt has occurred which is slightly
2154 * out of the ordinary. We will now decode it fully, in
2155 * this routine. This is broken up in an attempt to save
2156 * processing time.
2157 *
2158 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002159static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002160 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002162 unsigned char temp, ScamFlg;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002163 struct sccb_mgr_tar_info * currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05002164 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165
2166
2167 if (RD_HARPOON(p_port+hp_ext_status) &
2168 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2169 {
2170
2171 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2172 {
2173
James Bottomley 47b5d692005-04-24 02:38:05 -05002174 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175 }
2176
2177 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2178
2179 {
2180 WR_HARPOON(p_port+hp_pci_stat_cfg,
2181 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2182
2183 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2184
2185 }
2186
2187 if (pCurrCard->currentSCCB != NULL)
2188 {
2189
2190 if (!pCurrCard->currentSCCB->HostStatus)
2191 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2192
James Bottomley 47b5d692005-04-24 02:38:05 -05002193 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002195 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002197 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2199
2200 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2201 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002202 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 }
2204 }
2205 }
2206
2207
2208 else if (p_int & RESET)
2209 {
2210
2211 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2212 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2213 if (pCurrCard->currentSCCB != NULL) {
2214
2215 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2216
James Bottomley 47b5d692005-04-24 02:38:05 -05002217 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218 }
2219
2220
2221 DISABLE_AUTO(p_port);
2222
James Bottomley 47b5d692005-04-24 02:38:05 -05002223 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224
2225 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2226
2227 pCurrNvRam = pCurrCard->pNvRamInfo;
2228 if(pCurrNvRam){
2229 ScamFlg = pCurrNvRam->niScamConf;
2230 }
2231 else{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002232 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 }
2234
James Bottomley 47b5d692005-04-24 02:38:05 -05002235 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236
James Bottomley 47b5d692005-04-24 02:38:05 -05002237 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
2239 return(0xFF);
2240 }
2241
2242
2243 else if (p_int & FIFO) {
2244
2245 WRW_HARPOON((p_port+hp_intstat), FIFO);
2246
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002248 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249 }
2250
2251 else if (p_int & TIMEOUT)
2252 {
2253
2254 DISABLE_AUTO(p_port);
2255
2256 WRW_HARPOON((p_port+hp_intstat),
2257 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2258
2259 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2260
2261
James Bottomley 47b5d692005-04-24 02:38:05 -05002262 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2264 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002265 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002267 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268
2269
2270 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2271 {
2272 currTar_Info->TarSyncCtrl = 0;
2273 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2274 }
2275
2276 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2277 {
2278 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2279 }
2280
James Bottomley 47b5d692005-04-24 02:38:05 -05002281 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282
James Bottomley 47b5d692005-04-24 02:38:05 -05002283 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284
2285 }
2286
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287 else if (p_int & SCAM_SEL)
2288 {
2289
James Bottomley 47b5d692005-04-24 02:38:05 -05002290 FPT_scarb(p_port,LEVEL2_TAR);
2291 FPT_scsel(p_port);
2292 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
James Bottomley 47b5d692005-04-24 02:38:05 -05002294 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295
2296 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2297 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
2299 return(0x00);
2300}
2301
2302
2303/*---------------------------------------------------------------------
2304 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 * Function: SccbMgrTableInit
2306 *
2307 * Description: Initialize all Sccb manager data structures.
2308 *
2309 *---------------------------------------------------------------------*/
2310
James Bottomley 47b5d692005-04-24 02:38:05 -05002311static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002313 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
2315 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2316 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002317 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318
James Bottomley 47b5d692005-04-24 02:38:05 -05002319 FPT_BL_Card[thisCard].ioPort = 0x00;
2320 FPT_BL_Card[thisCard].cardInfo = NULL;
2321 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2322 FPT_BL_Card[thisCard].ourId = 0x00;
2323 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 }
2325}
2326
2327
2328/*---------------------------------------------------------------------
2329 *
2330 * Function: SccbMgrTableInit
2331 *
2332 * Description: Initialize all Sccb manager data structures.
2333 *
2334 *---------------------------------------------------------------------*/
2335
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002336static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002338 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002339
2340 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2341 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002342 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343 }
2344
2345 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2346 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002347 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2348 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2349 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350 }
2351
2352 pCurrCard->scanIndex = 0x00;
2353 pCurrCard->currentSCCB = NULL;
2354 pCurrCard->globalFlags = 0x00;
2355 pCurrCard->cmdCounter = 0x00;
2356 pCurrCard->tagQ_Lst = 0x01;
2357 pCurrCard->discQCount = 0;
2358
2359
2360}
2361
2362
2363/*---------------------------------------------------------------------
2364 *
2365 * Function: SccbMgrTableInit
2366 *
2367 * Description: Initialize all Sccb manager data structures.
2368 *
2369 *---------------------------------------------------------------------*/
2370
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002371static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372{
2373
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002374 unsigned char lun, qtag;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002375 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376
James Bottomley 47b5d692005-04-24 02:38:05 -05002377 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378
2379 currTar_Info->TarSelQ_Cnt = 0;
2380 currTar_Info->TarSyncCtrl = 0;
2381
2382 currTar_Info->TarSelQ_Head = NULL;
2383 currTar_Info->TarSelQ_Tail = NULL;
2384 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002385 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386
2387
2388 for (lun = 0; lun < MAX_LUN; lun++)
2389 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002390 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391 currTar_Info->LunDiscQ_Idx[lun] = 0;
2392 }
2393
2394 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2395 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002396 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002398 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002400 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2401 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402 }
2403 }
2404 }
2405}
2406
Linus Torvalds1da177e2005-04-16 15:20:36 -07002407
2408/*---------------------------------------------------------------------
2409 *
2410 * Function: sfetm
2411 *
2412 * Description: Read in a message byte from the SCSI bus, and check
2413 * for a parity error.
2414 *
2415 *---------------------------------------------------------------------*/
2416
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002417static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002419 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002420 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421
2422 TimeOutLoop = 0;
2423 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2424 (TimeOutLoop++ < 20000) ){}
2425
2426
2427 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2428
2429 message = RD_HARPOON(port+hp_scsidata_0);
2430
2431 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2432
2433
2434 if (TimeOutLoop > 20000)
2435 message = 0x00; /* force message byte = 0 if Time Out on Req */
2436
2437 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2438 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2439 {
2440 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2441 WR_HARPOON(port+hp_xferstat, 0);
2442 WR_HARPOON(port+hp_fiforead, 0);
2443 WR_HARPOON(port+hp_fifowrite, 0);
2444 if (pCurrSCCB != NULL)
2445 {
2446 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2447 }
2448 message = 0x00;
2449 do
2450 {
2451 ACCEPT_MSG_ATN(port);
2452 TimeOutLoop = 0;
2453 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2454 (TimeOutLoop++ < 20000) ){}
2455 if (TimeOutLoop > 20000)
2456 {
2457 WRW_HARPOON((port+hp_intstat), PARITY);
2458 return(message);
2459 }
2460 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2461 {
2462 WRW_HARPOON((port+hp_intstat), PARITY);
2463 return(message);
2464 }
2465 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2466
2467 RD_HARPOON(port+hp_scsidata_0);
2468
2469 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2470
2471 }while(1);
2472
2473 }
2474 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2475 WR_HARPOON(port+hp_xferstat, 0);
2476 WR_HARPOON(port+hp_fiforead, 0);
2477 WR_HARPOON(port+hp_fifowrite, 0);
2478 return(message);
2479}
2480
2481
2482/*---------------------------------------------------------------------
2483 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002484 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 *
2486 * Description: Load up automation and select target device.
2487 *
2488 *---------------------------------------------------------------------*/
2489
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002490static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491{
2492
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002493 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002495 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 PSCCBcard CurrCard;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002497 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002498 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002499 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500
James Bottomley 47b5d692005-04-24 02:38:05 -05002501 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 currSCCB = CurrCard->currentSCCB;
2503 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002504 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 lastTag = CurrCard->tagQ_Lst;
2506
2507 ARAM_ACCESS(port);
2508
2509
2510 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2511 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2512
2513 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2514 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2515
2516 lun = currSCCB->Lun;
2517 else
2518 lun = 0;
2519
2520
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521 if (CurrCard->globalFlags & F_TAG_STARTED)
2522 {
2523 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2524 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002525 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2527 == TAG_Q_TRYING))
2528 {
2529
2530 if (currTar_Info->TarTagQ_Cnt !=0)
2531 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002532 currTar_Info->TarLUNBusy[lun] = 1;
2533 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534 SGRAM_ACCESS(port);
2535 return;
2536 }
2537
2538 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002539 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 }
2541
2542 } /*End non-tagged */
2543
2544 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002545 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 }
2547
2548 } /*!Use cmd Q Tagged */
2549
2550 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002551 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002553 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 SGRAM_ACCESS(port);
2555 return;
2556 }
2557
James Bottomley 47b5d692005-04-24 02:38:05 -05002558 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559
2560 } /*else use cmd Q tagged */
2561
2562 } /*if glob tagged started */
2563
2564 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002565 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 }
2567
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568
2569
2570 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2571 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2572 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2573 {
2574 if(CurrCard->discQCount >= QUEUE_DEPTH)
2575 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002576 currTar_Info->TarLUNBusy[lun] = 1;
2577 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578 SGRAM_ACCESS(port);
2579 return;
2580 }
2581 for (i = 1; i < QUEUE_DEPTH; i++)
2582 {
2583 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2584 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2585 {
2586 CurrCard->tagQ_Lst = lastTag;
2587 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2588 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2589 CurrCard->discQCount++;
2590 break;
2591 }
2592 }
2593 if(i == QUEUE_DEPTH)
2594 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002595 currTar_Info->TarLUNBusy[lun] = 1;
2596 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 SGRAM_ACCESS(port);
2598 return;
2599 }
2600 }
2601
2602
2603
James Bottomley 47b5d692005-04-24 02:38:05 -05002604 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605
2606 WR_HARPOON(port+hp_select_id, target);
2607 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2608
2609 if (currSCCB->OperationCode == RESET_COMMAND) {
2610 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2611 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2612
2613 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2614
2615 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2616
2617 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002618 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2620
2621 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2622 {
2623 currTar_Info->TarSyncCtrl = 0;
2624 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2625 }
2626
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2628 {
2629 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2630 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631
James Bottomley 47b5d692005-04-24 02:38:05 -05002632 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2633 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634
2635 }
2636
2637 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2638 {
2639 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2640 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2641
2642 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2643
2644 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002645 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2646 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647 WRW_HARPOON((port+SYNC_MSGS+2),
2648 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2649 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2650
2651 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002652 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653
2654 }
2655
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002657 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2659 }
2660
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2662 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002663 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2665 }
2666
2667
2668 if (!auto_loaded)
2669 {
2670
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 if (currSCCB->ControlByte & F_USE_CMD_Q)
2672 {
2673
2674 CurrCard->globalFlags |= F_TAG_STARTED;
2675
2676 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2677 == TAG_Q_REJECT)
2678 {
2679 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2680
2681 /* Fix up the start instruction with a jump to
2682 Non-Tag-CMD handling */
2683 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2684
2685 WRW_HARPOON((port+NON_TAG_ID_MSG),
2686 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2687
2688 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2689
2690 /* Setup our STATE so we know what happend when
2691 the wheels fall off. */
2692 currSCCB->Sccb_scsistat = SELECT_ST;
2693
James Bottomley 47b5d692005-04-24 02:38:05 -05002694 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002695 }
2696
2697 else
2698 {
2699 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2700
2701 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002702 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2703 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
2705 for (i = 1; i < QUEUE_DEPTH; i++)
2706 {
2707 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2708 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2709 {
2710 WRW_HARPOON((port+ID_MSG_STRT+6),
2711 (MPM_OP+AMSG_OUT+lastTag));
2712 CurrCard->tagQ_Lst = lastTag;
2713 currSCCB->Sccb_tag = lastTag;
2714 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2715 CurrCard->discQCount++;
2716 break;
2717 }
2718 }
2719
2720
2721 if ( i == QUEUE_DEPTH )
2722 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002723 currTar_Info->TarLUNBusy[lun] = 1;
2724 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 SGRAM_ACCESS(port);
2726 return;
2727 }
2728
2729 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2730
2731 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2732 }
2733 }
2734
2735 else
2736 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737
2738 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2739
2740 WRW_HARPOON((port+NON_TAG_ID_MSG),
2741 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2742
2743 currSCCB->Sccb_scsistat = SELECT_ST;
2744
2745 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747
2748
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002749 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
2751 cdb_reg = port + CMD_STRT;
2752
2753 for (i=0; i < currSCCB->CdbLength; i++)
2754 {
2755 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2756 cdb_reg +=2;
2757 theCCB++;
2758 }
2759
2760 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2761 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2762
2763 } /* auto_loaded */
2764
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002765 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767
2768 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2769
2770 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2771
2772
2773 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2774 {
2775 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2776 }
2777 else
2778 {
2779
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002780/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002781 auto_loaded |= AUTO_IMMED; */
2782 auto_loaded = AUTO_IMMED;
2783
2784 DISABLE_AUTO(port);
2785
2786 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2787 }
2788
2789 SGRAM_ACCESS(port);
2790}
2791
2792
2793/*---------------------------------------------------------------------
2794 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002795 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 *
2797 * Description: Hookup the correct CCB and handle the incoming messages.
2798 *
2799 *---------------------------------------------------------------------*/
2800
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002801static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802{
2803
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002804 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002805
2806
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002807 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002808 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809
2810
2811
2812
2813 if(pCurrCard->currentSCCB != NULL)
2814 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002815 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816 DISABLE_AUTO(port);
2817
2818
2819 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2820
2821
2822 currSCCB = pCurrCard->currentSCCB;
2823 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2824 {
2825 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2826 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2827 }
2828 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2829 {
2830 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2831 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2832 }
2833 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2834 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2835 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002836 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 if(currSCCB->Sccb_scsistat != ABORT_ST)
2838 {
2839 pCurrCard->discQCount--;
2840 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2841 = NULL;
2842 }
2843 }
2844 else
2845 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002846 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 if(currSCCB->Sccb_tag)
2848 {
2849 if(currSCCB->Sccb_scsistat != ABORT_ST)
2850 {
2851 pCurrCard->discQCount--;
2852 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2853 }
2854 }else
2855 {
2856 if(currSCCB->Sccb_scsistat != ABORT_ST)
2857 {
2858 pCurrCard->discQCount--;
2859 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2860 }
2861 }
2862 }
2863
James Bottomley 47b5d692005-04-24 02:38:05 -05002864 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 }
2866
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002867 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868
2869
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002870 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002871 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872
2873
2874 msgRetryCount = 0;
2875 do
2876 {
2877
James Bottomley 47b5d692005-04-24 02:38:05 -05002878 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 tag = 0;
2880
2881
2882 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2883 {
2884 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2885 {
2886
2887 WRW_HARPOON((port+hp_intstat), PHASE);
2888 return;
2889 }
2890 }
2891
2892 WRW_HARPOON((port+hp_intstat), PHASE);
2893 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2894 {
2895
James Bottomley 47b5d692005-04-24 02:38:05 -05002896 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897 if (message)
2898 {
2899
2900 if (message <= (0x80 | LUN_MASK))
2901 {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08002902 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2905 {
2906 if (currTar_Info->TarTagQ_Cnt != 0)
2907 {
2908
2909 if (!(currTar_Info->TarLUN_CA))
2910 {
2911 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2912
2913
James Bottomley 47b5d692005-04-24 02:38:05 -05002914 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915 if (message)
2916 {
2917 ACCEPT_MSG(port);
2918 }
2919
2920 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002921 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922
James Bottomley 47b5d692005-04-24 02:38:05 -05002923 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002925 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926
2927 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002928 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 }
2930
2931 } /*C.A. exists! */
2932
2933 } /*End Q cnt != 0 */
2934
2935 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936
2937 } /*End valid ID message. */
2938
2939 else
2940 {
2941
2942 ACCEPT_MSG_ATN(port);
2943 }
2944
2945 } /* End good id message. */
2946
2947 else
2948 {
2949
James Bottomley 47b5d692005-04-24 02:38:05 -05002950 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951 }
2952 }
2953 else
2954 {
2955 ACCEPT_MSG_ATN(port);
2956
2957 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2958 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2959 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2960
2961 return;
2962 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963
James Bottomley 47b5d692005-04-24 02:38:05 -05002964 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965 {
2966 msgRetryCount++;
2967 if(msgRetryCount == 1)
2968 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002969 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970 }
2971 else
2972 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002973 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
James Bottomley 47b5d692005-04-24 02:38:05 -05002975 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976
James Bottomley 47b5d692005-04-24 02:38:05 -05002977 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 {
2979
James Bottomley 47b5d692005-04-24 02:38:05 -05002980 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981
2982 }
2983
James Bottomley 47b5d692005-04-24 02:38:05 -05002984 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 {
2986
James Bottomley 47b5d692005-04-24 02:38:05 -05002987 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 }
2989
2990
James Bottomley 47b5d692005-04-24 02:38:05 -05002991 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2992 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 return;
2994 }
2995 }
James Bottomley 47b5d692005-04-24 02:38:05 -05002996 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997
2998
2999
3000 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3001 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3002 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003003 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3005 if(pCurrCard->currentSCCB != NULL)
3006 {
3007 ACCEPT_MSG(port);
3008 }
3009 else
3010 {
3011 ACCEPT_MSG_ATN(port);
3012 }
3013 }
3014 else
3015 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003016 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017
3018
3019 if (tag)
3020 {
3021 if (pCurrCard->discQ_Tbl[tag] != NULL)
3022 {
3023 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3024 currTar_Info->TarTagQ_Cnt--;
3025 ACCEPT_MSG(port);
3026 }
3027 else
3028 {
3029 ACCEPT_MSG_ATN(port);
3030 }
3031 }else
3032 {
3033 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3034 if(pCurrCard->currentSCCB != NULL)
3035 {
3036 ACCEPT_MSG(port);
3037 }
3038 else
3039 {
3040 ACCEPT_MSG_ATN(port);
3041 }
3042 }
3043 }
3044
3045 if(pCurrCard->currentSCCB != NULL)
3046 {
3047 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3048 {
3049 /* During Abort Tag command, the target could have got re-selected
3050 and completed the command. Check the select Q and remove the CCB
3051 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003052 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 }
3054 }
3055
3056
3057 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3058 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3059 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3060}
3061
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003062static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063{
3064 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3065 {
3066 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3067 {
3068
3069 WRW_HARPOON((port+hp_intstat), PHASE);
3070 return;
3071 }
3072 }
3073
3074 WRW_HARPOON((port+hp_intstat), PHASE);
3075 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3076 {
3077 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3078
3079
3080 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3081
3082 WR_HARPOON(port+hp_scsidata_0,message);
3083
3084 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3085
3086 ACCEPT_MSG(port);
3087
3088 WR_HARPOON(port+hp_portctrl_0, 0x00);
3089
3090 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3091 (message == SMABORT_TAG) )
3092 {
3093 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3094
3095 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3096 {
3097 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3098 }
3099 }
3100 }
3101}
3102
3103/*---------------------------------------------------------------------
3104 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003105 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003106 *
3107 * Description: Determine the proper responce to the message from the
3108 * target device.
3109 *
3110 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003111static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003112{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003113 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 PSCCBcard CurrCard;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003115 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116
James Bottomley 47b5d692005-04-24 02:38:05 -05003117 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 currSCCB = CurrCard->currentSCCB;
3119
James Bottomley 47b5d692005-04-24 02:38:05 -05003120 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121
3122 if (message == SMREST_DATA_PTR)
3123 {
3124 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3125 {
3126 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3127
James Bottomley 47b5d692005-04-24 02:38:05 -05003128 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129 }
3130
3131 ACCEPT_MSG(port);
3132 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3133 }
3134
3135 else if (message == SMCMD_COMP)
3136 {
3137
3138
3139 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3140 {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003141 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3142 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 }
3144
3145 ACCEPT_MSG(port);
3146
3147 }
3148
3149 else if ((message == SMNO_OP) || (message >= SMIDENT)
3150 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3151 {
3152
3153 ACCEPT_MSG(port);
3154 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3155 }
3156
3157 else if (message == SMREJECT)
3158 {
3159
3160 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3161 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3162 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3163 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3164
3165 {
3166 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3167
3168 ACCEPT_MSG(port);
3169
3170
3171 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3172 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3173
3174 if(currSCCB->Lun == 0x00)
3175 {
3176 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3177 {
3178
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003179 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180
3181 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3182 }
3183
Linus Torvalds1da177e2005-04-16 15:20:36 -07003184 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3185 {
3186
3187
3188 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3189 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3190
3191 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3192
3193 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194
3195 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3196 {
3197 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003198 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003199
3200
3201 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3202 CurrCard->discQCount--;
3203 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3204 currSCCB->Sccb_tag = 0x00;
3205
3206 }
3207 }
3208
3209 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3210 {
3211
3212
3213 if(currSCCB->Lun == 0x00)
3214 {
3215 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3216 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3217 }
3218 }
3219
3220 else
3221 {
3222
3223 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3224 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003225 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003227 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003228
3229
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003230 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231
3232 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3233
3234 }
3235 }
3236
3237 else
3238 {
3239 ACCEPT_MSG(port);
3240
3241 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3242 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3243
3244 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3245 {
3246 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3247 }
3248 }
3249 }
3250
3251 else if (message == SMEXT)
3252 {
3253
3254 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003255 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 }
3257
3258 else if (message == SMIGNORWR)
3259 {
3260
3261 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3262
James Bottomley 47b5d692005-04-24 02:38:05 -05003263 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264
3265 if(currSCCB->Sccb_scsimsg != SMPARITY)
3266 ACCEPT_MSG(port);
3267 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3268 }
3269
3270
3271 else
3272 {
3273
3274 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3275 currSCCB->Sccb_scsimsg = SMREJECT;
3276
3277 ACCEPT_MSG_ATN(port);
3278 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3279 }
3280}
3281
3282
3283/*---------------------------------------------------------------------
3284 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003285 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286 *
3287 * Description: Decide what to do with the extended message.
3288 *
3289 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003290static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003292 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003293
James Bottomley 47b5d692005-04-24 02:38:05 -05003294 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003295 if (length)
3296 {
3297
3298 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003299 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300 if (message)
3301 {
3302
3303 if (message == SMSYNC)
3304 {
3305
3306 if (length == 0x03)
3307 {
3308
3309 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003310 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311 }
3312 else
3313 {
3314
3315 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3316 ACCEPT_MSG_ATN(port);
3317 }
3318 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003319 else if (message == SMWDTR)
3320 {
3321
3322 if (length == 0x02)
3323 {
3324
3325 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003326 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003327 }
3328 else
3329 {
3330
3331 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3332 ACCEPT_MSG_ATN(port);
3333
3334 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3335 }
3336 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 else
3338 {
3339
3340 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3341 ACCEPT_MSG_ATN(port);
3342
3343 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3344 }
3345 }
3346 else
3347 {
3348 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3349 ACCEPT_MSG(port);
3350 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3351 }
3352 }else
3353 {
3354 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3355 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3356 }
3357}
3358
3359
3360/*---------------------------------------------------------------------
3361 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003362 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003363 *
3364 * Description: Read in a message byte from the SCSI bus, and check
3365 * for a parity error.
3366 *
3367 *---------------------------------------------------------------------*/
3368
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003369static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003370{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003371 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003372 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373
James Bottomley 47b5d692005-04-24 02:38:05 -05003374 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3375 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003376
3377 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3378
3379
3380 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003381 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382
3383 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3384
3385 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3386 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3387 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3388
3389
3390 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3391
3392 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3393
3394 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3395
3396 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3397
3398 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3399
3400 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3401
3402 else
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3404
3405
3406 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3407 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3408 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3409
3410
James Bottomley 47b5d692005-04-24 02:38:05 -05003411 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 {
3413 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3414 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003415 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416 }
3417 else
3418 {
3419 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3420 }
3421
3422
James Bottomley 47b5d692005-04-24 02:38:05 -05003423 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003424 }
3425
3426 else {
3427
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003428 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003430 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003431 }
3432}
3433
3434
3435
3436/*---------------------------------------------------------------------
3437 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003438 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439 *
3440 * Description: The has sent us a Sync Nego message so handle it as
3441 * necessary.
3442 *
3443 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003444static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003445{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003446 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003447 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003448 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449
James Bottomley 47b5d692005-04-24 02:38:05 -05003450 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3451 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452
James Bottomley 47b5d692005-04-24 02:38:05 -05003453 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454
3455 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3456 {
3457 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3458 return;
3459 }
3460
3461 ACCEPT_MSG(port);
3462
3463
James Bottomley 47b5d692005-04-24 02:38:05 -05003464 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003465
3466 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3467 {
3468 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3469 return;
3470 }
3471
3472 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3473
3474 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3475
3476 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3477
3478 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3479
3480 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3481
3482 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3483 else
3484
3485 our_sync_msg = 0; /* Message = Async */
3486
3487 if (sync_msg < our_sync_msg) {
3488 sync_msg = our_sync_msg; /*if faster, then set to max. */
3489 }
3490
3491 if (offset == ASYNC)
3492 sync_msg = ASYNC;
3493
3494 if (offset > MAX_OFFSET)
3495 offset = MAX_OFFSET;
3496
3497 sync_reg = 0x00;
3498
3499 if (sync_msg > 12)
3500
3501 sync_reg = 0x20; /* Use 10MB/s */
3502
3503 if (sync_msg > 25)
3504
3505 sync_reg = 0x40; /* Use 6.6MB/s */
3506
3507 if (sync_msg > 38)
3508
3509 sync_reg = 0x60; /* Use 5MB/s */
3510
3511 if (sync_msg > 50)
3512
3513 sync_reg = 0x80; /* Use 4MB/s */
3514
3515 if (sync_msg > 62)
3516
3517 sync_reg = 0xA0; /* Use 3.33MB/s */
3518
3519 if (sync_msg > 75)
3520
3521 sync_reg = 0xC0; /* Use 2.85MB/s */
3522
3523 if (sync_msg > 87)
3524
3525 sync_reg = 0xE0; /* Use 2.5MB/s */
3526
3527 if (sync_msg > 100) {
3528
3529 sync_reg = 0x00; /* Use ASYNC */
3530 offset = 0x00;
3531 }
3532
3533
Linus Torvalds1da177e2005-04-16 15:20:36 -07003534 if (currTar_Info->TarStatus & WIDE_ENABLED)
3535
3536 sync_reg |= offset;
3537
3538 else
3539
3540 sync_reg |= (offset | NARROW_SCSI);
3541
James Bottomley 47b5d692005-04-24 02:38:05 -05003542 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003543
3544
3545 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3546
3547
3548 ACCEPT_MSG(port);
3549
3550 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003551 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003552
3553 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3554 }
3555
3556 else {
3557
3558
3559 ACCEPT_MSG_ATN(port);
3560
James Bottomley 47b5d692005-04-24 02:38:05 -05003561 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003562
3563 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003564 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565 }
3566}
3567
3568
3569/*---------------------------------------------------------------------
3570 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003571 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572 *
3573 * Description: Answer the targets sync message.
3574 *
3575 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003576static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577{
3578 ARAM_ACCESS(port);
3579 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3580 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3581 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3582 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3583 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3584 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3585 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3586 SGRAM_ACCESS(port);
3587
3588 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3589 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3590
3591 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3592
3593 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3594}
3595
3596
3597
Linus Torvalds1da177e2005-04-16 15:20:36 -07003598/*---------------------------------------------------------------------
3599 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003600 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601 *
3602 * Description: Read in a message byte from the SCSI bus, and check
3603 * for a parity error.
3604 *
3605 *---------------------------------------------------------------------*/
3606
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003607static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003608{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003609 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003610 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611
James Bottomley 47b5d692005-04-24 02:38:05 -05003612 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3613 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003614
3615 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3616
3617
3618 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003619 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003620
3621 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3622
3623 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3624 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3625 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3626 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3627 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3628 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3629
3630 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3631
3632
3633 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003634 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635
James Bottomley 47b5d692005-04-24 02:38:05 -05003636 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003637 }
3638
3639 else {
3640
3641 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003642 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003643
3644 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003645 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003646 }
3647}
3648
3649
3650
3651/*---------------------------------------------------------------------
3652 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003653 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003654 *
3655 * Description: The has sent us a Wide Nego message so handle it as
3656 * necessary.
3657 *
3658 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003659static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003660{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003661 unsigned char width;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003662 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003663 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664
James Bottomley 47b5d692005-04-24 02:38:05 -05003665 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3666 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667
James Bottomley 47b5d692005-04-24 02:38:05 -05003668 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003669
3670 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3671 {
3672 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3673 return;
3674 }
3675
3676
3677 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3678 width = 0;
3679
3680 if (width) {
3681 currTar_Info->TarStatus |= WIDE_ENABLED;
3682 width = 0;
3683 }
3684 else {
3685 width = NARROW_SCSI;
3686 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3687 }
3688
3689
James Bottomley 47b5d692005-04-24 02:38:05 -05003690 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003691
3692
3693 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3694 {
3695
3696
3697
3698 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3699
3700 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3701 {
3702 ACCEPT_MSG_ATN(port);
3703 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003704 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003705 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3706 SGRAM_ACCESS(port);
3707 }
3708 else
3709 {
3710 ACCEPT_MSG(port);
3711 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3712 }
3713 }
3714
3715 else {
3716
3717
3718 ACCEPT_MSG_ATN(port);
3719
3720 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3721 width = SM16BIT;
3722 else
3723 width = SM8BIT;
3724
James Bottomley 47b5d692005-04-24 02:38:05 -05003725 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003726
3727 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3728 }
3729}
3730
3731
3732/*---------------------------------------------------------------------
3733 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003734 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735 *
3736 * Description: Answer the targets Wide nego message.
3737 *
3738 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003739static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740{
3741 ARAM_ACCESS(port);
3742 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3743 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3744 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3745 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3746 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3747 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3748 SGRAM_ACCESS(port);
3749
3750 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3751 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3752
3753 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3754
3755 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3756}
3757
Linus Torvalds1da177e2005-04-16 15:20:36 -07003758
3759
3760/*---------------------------------------------------------------------
3761 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003762 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003763 *
3764 * Description: Write the desired value to the Sync Register for the
3765 * ID specified.
3766 *
3767 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003768static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003769 struct sccb_mgr_tar_info * currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003771 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003772
3773 index = p_id;
3774
3775 switch (index) {
3776
3777 case 0:
3778 index = 12; /* hp_synctarg_0 */
3779 break;
3780 case 1:
3781 index = 13; /* hp_synctarg_1 */
3782 break;
3783 case 2:
3784 index = 14; /* hp_synctarg_2 */
3785 break;
3786 case 3:
3787 index = 15; /* hp_synctarg_3 */
3788 break;
3789 case 4:
3790 index = 8; /* hp_synctarg_4 */
3791 break;
3792 case 5:
3793 index = 9; /* hp_synctarg_5 */
3794 break;
3795 case 6:
3796 index = 10; /* hp_synctarg_6 */
3797 break;
3798 case 7:
3799 index = 11; /* hp_synctarg_7 */
3800 break;
3801 case 8:
3802 index = 4; /* hp_synctarg_8 */
3803 break;
3804 case 9:
3805 index = 5; /* hp_synctarg_9 */
3806 break;
3807 case 10:
3808 index = 6; /* hp_synctarg_10 */
3809 break;
3810 case 11:
3811 index = 7; /* hp_synctarg_11 */
3812 break;
3813 case 12:
3814 index = 0; /* hp_synctarg_12 */
3815 break;
3816 case 13:
3817 index = 1; /* hp_synctarg_13 */
3818 break;
3819 case 14:
3820 index = 2; /* hp_synctarg_14 */
3821 break;
3822 case 15:
3823 index = 3; /* hp_synctarg_15 */
3824
3825 }
3826
3827 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3828
3829 currTar_Info->TarSyncCtrl = p_sync_value;
3830}
3831
3832
3833/*---------------------------------------------------------------------
3834 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003835 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836 *
3837 * Description: Reset the desired card's SCSI bus.
3838 *
3839 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003840static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003842 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003844 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003845
3846 WR_HARPOON(port+hp_page_ctrl,
3847 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3848 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3849
3850 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3851
3852 scsiID = RD_HARPOON(port+hp_seltimeout);
3853 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3854 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3855
3856 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3857
3858 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3859
3860 WR_HARPOON(port+hp_seltimeout,scsiID);
3861
3862 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3863
James Bottomley 47b5d692005-04-24 02:38:05 -05003864 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865
3866 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3867
3868 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3869
3870 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3871 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003872 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003873
3874 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3875 {
3876 currTar_Info->TarSyncCtrl = 0;
3877 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3878 }
3879
3880 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3881 {
3882 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3883 }
3884
James Bottomley 47b5d692005-04-24 02:38:05 -05003885 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886
James Bottomley 47b5d692005-04-24 02:38:05 -05003887 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003888 }
3889
James Bottomley 47b5d692005-04-24 02:38:05 -05003890 FPT_BL_Card[p_card].scanIndex = 0x00;
3891 FPT_BL_Card[p_card].currentSCCB = NULL;
3892 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003893 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003894 FPT_BL_Card[p_card].cmdCounter = 0x00;
3895 FPT_BL_Card[p_card].discQCount = 0x00;
3896 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003897
3898 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003899 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003900
3901 WR_HARPOON(port+hp_page_ctrl,
3902 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3903
3904}
3905
3906/*---------------------------------------------------------------------
3907 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003908 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003909 *
3910 * Description: Setup for the Auto Sense command.
3911 *
3912 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003913static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003914{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003915 unsigned char i;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003916 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003917
3918 currSCCB = pCurrCard->currentSCCB;
3919
3920
3921 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3922
3923 for (i = 0; i < 6; i++) {
3924
3925 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3926 }
3927
3928 currSCCB->CdbLength = SIX_BYTE_CMD;
3929 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003930 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931 currSCCB->Cdb[2] = 0x00;
3932 currSCCB->Cdb[3] = 0x00;
3933 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3934 currSCCB->Cdb[5] = 0x00;
3935
3936 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3937
3938 currSCCB->Sccb_ATC = 0x00;
3939
3940 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3941
3942 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3943
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003944 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003945
3946 currSCCB->ControlByte = 0x00;
3947
3948 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3949}
3950
3951
3952
3953/*---------------------------------------------------------------------
3954 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003955 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003956 *
3957 * Description: Transfer data into the bit bucket until the device
3958 * decides to switch phase.
3959 *
3960 *---------------------------------------------------------------------*/
3961
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003962static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003964 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003965
3966
3967 DISABLE_AUTO(p_port);
3968
James Bottomley 47b5d692005-04-24 02:38:05 -05003969 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970
James Bottomley 47b5d692005-04-24 02:38:05 -05003971 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003972
3973 }
3974
3975 /* If the Automation handled the end of the transfer then do not
3976 match the phase or we will get out of sync with the ISR. */
3977
3978 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3979 return;
3980
3981 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3982
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003983 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003984
3985 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3986
3987
3988 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3989
3990 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003991 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003992 {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08003993 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003994 {
3995 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3996
3997 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3998 {
3999 RD_HARPOON(p_port+hp_fifodata_0);
4000 }
4001 }
4002 else
4003 {
4004 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4005 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4006 {
4007 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4008 }
4009 }
4010 } /* End of While loop for padding data I/O phase */
4011
4012 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4013 {
4014 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4015 break;
4016 }
4017
4018 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4019 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4020 {
4021 RD_HARPOON(p_port+hp_fifodata_0);
4022 }
4023
4024 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4025 {
4026 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4027 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4028
4029 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4030 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4031 }
4032}
4033
4034
4035/*---------------------------------------------------------------------
4036 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004037 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004038 *
4039 * Description: Make sure data has been flushed from both FIFOs and abort
4040 * the operations if necessary.
4041 *
4042 *---------------------------------------------------------------------*/
4043
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004044static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004045{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004046 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004047 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004049 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050
James Bottomley 47b5d692005-04-24 02:38:05 -05004051 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004052
4053
4054 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4055 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4056 return;
4057 }
4058
4059
4060
4061 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4062 {
4063
4064 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4065
4066 currSCCB->Sccb_XferCnt = 1;
4067
4068 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004069 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004070 WR_HARPOON(port+hp_xferstat, 0x00);
4071 }
4072
4073 else
4074 {
4075
4076 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4077
4078 currSCCB->Sccb_XferCnt = 0;
4079 }
4080
4081 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4082 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4083
4084 currSCCB->HostStatus = SCCB_PARITY_ERR;
4085 WRW_HARPOON((port+hp_intstat), PARITY);
4086 }
4087
4088
James Bottomley 47b5d692005-04-24 02:38:05 -05004089 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004090
4091
4092 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4093
4094 TimeOutLoop = 0;
4095
4096 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4097 {
4098 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4099 return;
4100 }
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004101 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004102 break;
4103 }
4104 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4105 return;
4106 }
4107 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4108 break;
4109 }
4110
4111 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4112 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004113 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004114 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4115 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4116 {
4117
4118 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4119
4120 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4121 {
4122 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004123 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004124 }
4125
4126 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004127 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004128 }
4129 }
4130 else
4131 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004132 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004133 if (!(RDW_HARPOON((port+hp_intstat)) &
4134 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4135 {
4136 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004137 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004138 }
4139 }
4140
4141 }
4142
4143 else {
4144 WR_HARPOON(port+hp_portctrl_0, 0x00);
4145 }
4146}
4147
4148
4149/*---------------------------------------------------------------------
4150 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004151 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004152 *
4153 * Description: Setup SCCB manager fields in this SCCB.
4154 *
4155 *---------------------------------------------------------------------*/
4156
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004157static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158{
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08004159 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004160
4161 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4162 {
4163 return;
4164 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004165 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004166
4167 p_sccb->Sccb_XferState = 0x00;
4168 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4169
4170 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4171 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4172
4173 p_sccb->Sccb_SGoffset = 0;
4174 p_sccb->Sccb_XferState = F_SG_XFER;
4175 p_sccb->Sccb_XferCnt = 0x00;
4176 }
4177
4178 if (p_sccb->DataLength == 0x00)
4179
4180 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4181
4182 if (p_sccb->ControlByte & F_USE_CMD_Q)
4183 {
4184 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4185 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4186
4187 else
4188 currTar_Info->TarStatus |= TAG_Q_TRYING;
4189 }
4190
4191/* For !single SCSI device in system & device allow Disconnect
4192 or command is tag_q type then send Cmd with Disconnect Enable
4193 else send Cmd with Disconnect Disable */
4194
4195/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004196 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004197 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4198 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4199*/
4200 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4201 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004202 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004203 }
4204
4205 else {
4206
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004207 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004208 }
4209
4210 p_sccb->HostStatus = 0x00;
4211 p_sccb->TargetStatus = 0x00;
4212 p_sccb->Sccb_tag = 0x00;
4213 p_sccb->Sccb_MGRFlags = 0x00;
4214 p_sccb->Sccb_sgseg = 0x00;
4215 p_sccb->Sccb_ATC = 0x00;
4216 p_sccb->Sccb_savedATC = 0x00;
4217/*
4218 p_sccb->SccbVirtDataPtr = 0x00;
4219 p_sccb->Sccb_forwardlink = NULL;
4220 p_sccb->Sccb_backlink = NULL;
4221 */
4222 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4223 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4224 p_sccb->Sccb_scsimsg = SMNO_OP;
4225
4226}
4227
4228
Linus Torvalds1da177e2005-04-16 15:20:36 -07004229/*---------------------------------------------------------------------
4230 *
4231 * Function: Phase Decode
4232 *
4233 * Description: Determine the phase and call the appropriate function.
4234 *
4235 *---------------------------------------------------------------------*/
4236
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004237static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004238{
4239 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004240 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004241
4242
4243 DISABLE_AUTO(p_port);
4244
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004245 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
James Bottomley 47b5d692005-04-24 02:38:05 -05004247 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004248
4249 (*phase)(p_port, p_card); /* Call the correct phase func */
4250}
4251
4252
4253
4254/*---------------------------------------------------------------------
4255 *
4256 * Function: Data Out Phase
4257 *
4258 * Description: Start up both the BusMaster and Xbow.
4259 *
4260 *---------------------------------------------------------------------*/
4261
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004262static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004263{
4264
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004265 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266
James Bottomley 47b5d692005-04-24 02:38:05 -05004267 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268 if (currSCCB == NULL)
4269 {
4270 return; /* Exit if No SCCB record */
4271 }
4272
4273 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4274 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4275
4276 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4277
4278 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4279
4280 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4281
James Bottomley 47b5d692005-04-24 02:38:05 -05004282 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283
4284 if (currSCCB->Sccb_XferCnt == 0) {
4285
4286
4287 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4288 (currSCCB->HostStatus == SCCB_COMPLETE))
4289 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4290
James Bottomley 47b5d692005-04-24 02:38:05 -05004291 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004293 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004294 }
4295}
4296
4297
4298/*---------------------------------------------------------------------
4299 *
4300 * Function: Data In Phase
4301 *
4302 * Description: Startup the BusMaster and the XBOW.
4303 *
4304 *---------------------------------------------------------------------*/
4305
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004306static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004307{
4308
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004309 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310
James Bottomley 47b5d692005-04-24 02:38:05 -05004311 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312
4313 if (currSCCB == NULL)
4314 {
4315 return; /* Exit if No SCCB record */
4316 }
4317
4318
4319 currSCCB->Sccb_scsistat = DATA_IN_ST;
4320 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4321 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4322
4323 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4324
4325 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4326
4327 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4328
James Bottomley 47b5d692005-04-24 02:38:05 -05004329 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004330
4331 if (currSCCB->Sccb_XferCnt == 0) {
4332
4333
4334 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4335 (currSCCB->HostStatus == SCCB_COMPLETE))
4336 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4337
James Bottomley 47b5d692005-04-24 02:38:05 -05004338 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004340 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004341
4342 }
4343}
4344
4345/*---------------------------------------------------------------------
4346 *
4347 * Function: Command Phase
4348 *
4349 * Description: Load the CDB into the automation and start it up.
4350 *
4351 *---------------------------------------------------------------------*/
4352
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004353static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004354{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004355 struct sccb * currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004356 unsigned long cdb_reg;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004357 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
James Bottomley 47b5d692005-04-24 02:38:05 -05004359 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360
4361 if (currSCCB->OperationCode == RESET_COMMAND) {
4362
4363 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4364 currSCCB->CdbLength = SIX_BYTE_CMD;
4365 }
4366
4367 WR_HARPOON(p_port+hp_scsisig, 0x00);
4368
4369 ARAM_ACCESS(p_port);
4370
4371
4372 cdb_reg = p_port + CMD_STRT;
4373
4374 for (i=0; i < currSCCB->CdbLength; i++) {
4375
4376 if (currSCCB->OperationCode == RESET_COMMAND)
4377
4378 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4379
4380 else
4381 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4382 cdb_reg +=2;
4383 }
4384
4385 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4386 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4387
4388 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4389
4390 currSCCB->Sccb_scsistat = COMMAND_ST;
4391
4392 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4393 SGRAM_ACCESS(p_port);
4394}
4395
4396
4397/*---------------------------------------------------------------------
4398 *
4399 * Function: Status phase
4400 *
4401 * Description: Bring in the status and command complete message bytes
4402 *
4403 *---------------------------------------------------------------------*/
4404
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004405static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004406{
4407 /* Start-up the automation to finish off this command and let the
4408 isr handle the interrupt for command complete when it comes in.
4409 We could wait here for the interrupt to be generated?
4410 */
4411
4412 WR_HARPOON(port+hp_scsisig, 0x00);
4413
4414 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4415}
4416
4417
4418/*---------------------------------------------------------------------
4419 *
4420 * Function: Phase Message Out
4421 *
4422 * Description: Send out our message (if we have one) and handle whatever
4423 * else is involed.
4424 *
4425 *---------------------------------------------------------------------*/
4426
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004427static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004428{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004429 unsigned char message,scsiID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004430 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08004431 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432
James Bottomley 47b5d692005-04-24 02:38:05 -05004433 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004434
4435 if (currSCCB != NULL) {
4436
4437 message = currSCCB->Sccb_scsimsg;
4438 scsiID = currSCCB->TargID;
4439
4440 if (message == SMDEV_RESET)
4441 {
4442
4443
James Bottomley 47b5d692005-04-24 02:38:05 -05004444 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004445 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004446 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447
James Bottomley 47b5d692005-04-24 02:38:05 -05004448 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004449 {
4450
James Bottomley 47b5d692005-04-24 02:38:05 -05004451 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452
4453 }
4454
James Bottomley 47b5d692005-04-24 02:38:05 -05004455 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004456 {
4457
James Bottomley 47b5d692005-04-24 02:38:05 -05004458 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004459 }
4460
4461
James Bottomley 47b5d692005-04-24 02:38:05 -05004462 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4463 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464 }
4465 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4466 {
4467 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004468 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004469 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004470 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4471 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004472 }
4473
4474 }
4475
4476 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4477 {
4478
4479
4480 if(message == SMNO_OP)
4481 {
4482 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4483
James Bottomley 47b5d692005-04-24 02:38:05 -05004484 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004485 return;
4486 }
4487 }
4488 else
4489 {
4490
4491
4492 if (message == SMABORT)
4493
James Bottomley 47b5d692005-04-24 02:38:05 -05004494 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004495 }
4496
4497 }
4498 else
4499 {
4500 message = SMABORT;
4501 }
4502
4503 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4504
4505
4506 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4507
4508 WR_HARPOON(port+hp_scsidata_0,message);
4509
4510 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4511
4512 ACCEPT_MSG(port);
4513
4514 WR_HARPOON(port+hp_portctrl_0, 0x00);
4515
4516 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4517 (message == SMABORT_TAG) )
4518 {
4519
4520 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4521
4522 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4523 {
4524 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4525
4526 if (currSCCB != NULL)
4527 {
4528
James Bottomley 47b5d692005-04-24 02:38:05 -05004529 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4530 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4531 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004532 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004533 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004534
James Bottomley 47b5d692005-04-24 02:38:05 -05004535 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004536 }
4537
4538 else
4539 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004540 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004541 }
4542 }
4543
4544 else
4545 {
4546
James Bottomley 47b5d692005-04-24 02:38:05 -05004547 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004548 }
4549 }
4550
4551 else
4552 {
4553
4554 if(message == SMPARITY)
4555 {
4556 currSCCB->Sccb_scsimsg = SMNO_OP;
4557 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4558 }
4559 else
4560 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004561 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004562 }
4563 }
4564}
4565
4566
4567/*---------------------------------------------------------------------
4568 *
4569 * Function: Message In phase
4570 *
4571 * Description: Bring in the message and determine what to do with it.
4572 *
4573 *---------------------------------------------------------------------*/
4574
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004575static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004576{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004577 unsigned char message;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004578 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579
James Bottomley 47b5d692005-04-24 02:38:05 -05004580 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581
James Bottomley 47b5d692005-04-24 02:38:05 -05004582 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004583 {
4584
James Bottomley 47b5d692005-04-24 02:38:05 -05004585 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004586 }
4587
4588 message = RD_HARPOON(port+hp_scsidata_0);
4589 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4590 {
4591
4592 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4593
4594 }
4595
4596 else
4597 {
4598
James Bottomley 47b5d692005-04-24 02:38:05 -05004599 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004600 if (message)
4601 {
4602
4603
James Bottomley 47b5d692005-04-24 02:38:05 -05004604 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004605
4606 }
4607 else
4608 {
4609 if(currSCCB->Sccb_scsimsg != SMPARITY)
4610 ACCEPT_MSG(port);
4611 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4612 }
4613 }
4614
4615}
4616
4617
4618/*---------------------------------------------------------------------
4619 *
4620 * Function: Illegal phase
4621 *
4622 * Description: Target switched to some illegal phase, so all we can do
4623 * is report an error back to the host (if that is possible)
4624 * and send an ABORT message to the misbehaving target.
4625 *
4626 *---------------------------------------------------------------------*/
4627
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004628static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004629{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004630 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004631
James Bottomley 47b5d692005-04-24 02:38:05 -05004632 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004633
4634 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4635 if (currSCCB != NULL) {
4636
4637 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4638 currSCCB->Sccb_scsistat = ABORT_ST;
4639 currSCCB->Sccb_scsimsg = SMABORT;
4640 }
4641
4642 ACCEPT_MSG_ATN(port);
4643}
4644
4645
4646
4647/*---------------------------------------------------------------------
4648 *
4649 * Function: Phase Check FIFO
4650 *
4651 * Description: Make sure data has been flushed from both FIFOs and abort
4652 * the operations if necessary.
4653 *
4654 *---------------------------------------------------------------------*/
4655
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004656static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004657{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004658 unsigned long xfercnt;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004659 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660
James Bottomley 47b5d692005-04-24 02:38:05 -05004661 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004662
4663 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4664 {
4665
4666 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4667 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4668
4669
4670 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4671 {
4672 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4673
4674 currSCCB->Sccb_XferCnt = 0;
4675
4676 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4677 (currSCCB->HostStatus == SCCB_COMPLETE))
4678 {
4679 currSCCB->HostStatus = SCCB_PARITY_ERR;
4680 WRW_HARPOON((port+hp_intstat), PARITY);
4681 }
4682
James Bottomley 47b5d692005-04-24 02:38:05 -05004683 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004684
James Bottomley 47b5d692005-04-24 02:38:05 -05004685 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004686
4687 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4688 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4689
4690 }
4691 } /*End Data In specific code. */
4692
4693
4694
Linus Torvalds1da177e2005-04-16 15:20:36 -07004695 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004696
4697
4698 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4699
4700
4701 WR_HARPOON(port+hp_portctrl_0, 0x00);
4702
4703 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4704
4705 currSCCB->Sccb_XferCnt = xfercnt;
4706
4707 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4708 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4709
4710 currSCCB->HostStatus = SCCB_PARITY_ERR;
4711 WRW_HARPOON((port+hp_intstat), PARITY);
4712 }
4713
4714
James Bottomley 47b5d692005-04-24 02:38:05 -05004715 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004716
4717
4718 WR_HARPOON(port+hp_fifowrite, 0x00);
4719 WR_HARPOON(port+hp_fiforead, 0x00);
4720 WR_HARPOON(port+hp_xferstat, 0x00);
4721
4722 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4723}
4724
4725
4726/*---------------------------------------------------------------------
4727 *
4728 * Function: Phase Bus Free
4729 *
4730 * Description: We just went bus free so figure out if it was
4731 * because of command complete or from a disconnect.
4732 *
4733 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004734static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004735{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004736 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004737
James Bottomley 47b5d692005-04-24 02:38:05 -05004738 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004739
4740 if (currSCCB != NULL)
4741 {
4742
4743 DISABLE_AUTO(port);
4744
4745
4746 if (currSCCB->OperationCode == RESET_COMMAND)
4747 {
4748
James Bottomley 47b5d692005-04-24 02:38:05 -05004749 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4750 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4751 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004752 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004753 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004754
James Bottomley 47b5d692005-04-24 02:38:05 -05004755 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756
James Bottomley 47b5d692005-04-24 02:38:05 -05004757 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004758
4759 }
4760
4761 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4762 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004764 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004766 }
4767
4768 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4769 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004770 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4771 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004772 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4773
James Bottomley 47b5d692005-04-24 02:38:05 -05004774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004775 }
4776
Linus Torvalds1da177e2005-04-16 15:20:36 -07004777 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4778 {
4779 /* Make sure this is not a phony BUS_FREE. If we were
4780 reselected or if BUSY is NOT on then this is a
4781 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4782
4783 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4784 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4785 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004786 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4787 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004788 }
4789
4790 else
4791 {
4792 return;
4793 }
4794 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004795
4796 else
4797 {
4798
4799 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4800
4801 if (!currSCCB->HostStatus)
4802 {
4803 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4804 }
4805
James Bottomley 47b5d692005-04-24 02:38:05 -05004806 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4807 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4808 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004809 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004810 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004811
James Bottomley 47b5d692005-04-24 02:38:05 -05004812 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004813 return;
4814 }
4815
4816
James Bottomley 47b5d692005-04-24 02:38:05 -05004817 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004818
4819 } /*end if !=null */
4820}
4821
4822
4823
4824
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825/*---------------------------------------------------------------------
4826 *
4827 * Function: Auto Load Default Map
4828 *
4829 * Description: Load the Automation RAM with the defualt map values.
4830 *
4831 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004832static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004833{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004834 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004835
4836 ARAM_ACCESS(p_port);
4837 map_addr = p_port + hp_aramBase;
4838
4839 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4840 map_addr +=2;
4841 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4842 map_addr +=2;
4843 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4844 map_addr +=2;
4845 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4846 map_addr +=2;
4847 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4848 map_addr +=2;
4849 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4850 map_addr +=2;
4851 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4852 map_addr +=2;
4853 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4874 map_addr +=2; /*This means AYNC DATA IN */
4875 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4888 map_addr +=2;
4889 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4910 map_addr +=2;
4911
4912 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4913 map_addr +=2;
4914 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4917 map_addr +=2;
4918 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4919 map_addr +=2; /* DIDN'T GET ONE */
4920 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4921 map_addr +=2;
4922 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4923 map_addr +=2;
4924 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4925
4926
4927
4928 SGRAM_ACCESS(p_port);
4929}
4930
4931/*---------------------------------------------------------------------
4932 *
4933 * Function: Auto Command Complete
4934 *
4935 * Description: Post command back to host and find another command
4936 * to execute.
4937 *
4938 *---------------------------------------------------------------------*/
4939
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004940static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004941{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004942 struct sccb * currSCCB;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004943 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004944
James Bottomley 47b5d692005-04-24 02:38:05 -05004945 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004946
4947 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4948
James Bottomley 47b5d692005-04-24 02:38:05 -05004949 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004950
4951 if (status_byte != SSGOOD) {
4952
4953 if (status_byte == SSQ_FULL) {
4954
4955
James Bottomley 47b5d692005-04-24 02:38:05 -05004956 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4957 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004958 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004959 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4960 if(FPT_BL_Card[p_card].discQCount != 0)
4961 FPT_BL_Card[p_card].discQCount--;
4962 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 -07004963 }
4964 else
4965 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004966 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004967 if(currSCCB->Sccb_tag)
4968 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004969 if(FPT_BL_Card[p_card].discQCount != 0)
4970 FPT_BL_Card[p_card].discQCount--;
4971 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004972 }else
4973 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004974 if(FPT_BL_Card[p_card].discQCount != 0)
4975 FPT_BL_Card[p_card].discQCount--;
4976 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004977 }
4978 }
4979
4980 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4981
James Bottomley 47b5d692005-04-24 02:38:05 -05004982 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004983
4984 return;
4985 }
4986
4987 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4988 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004989 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08004990 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004991
James Bottomley 47b5d692005-04-24 02:38:05 -05004992 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4993 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004994
James Bottomley 47b5d692005-04-24 02:38:05 -05004995 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4996 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004997 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004998 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4999 if(FPT_BL_Card[p_card].discQCount != 0)
5000 FPT_BL_Card[p_card].discQCount--;
5001 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 -07005002 }
5003 else
5004 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005005 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005006 if(currSCCB->Sccb_tag)
5007 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005008 if(FPT_BL_Card[p_card].discQCount != 0)
5009 FPT_BL_Card[p_card].discQCount--;
5010 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005011 }else
5012 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005013 if(FPT_BL_Card[p_card].discQCount != 0)
5014 FPT_BL_Card[p_card].discQCount--;
5015 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005016 }
5017 }
5018 return;
5019
5020 }
5021
5022 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5023 {
5024
James Bottomley 47b5d692005-04-24 02:38:05 -05005025 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5026 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005027 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5028
James Bottomley 47b5d692005-04-24 02:38:05 -05005029 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5030 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005031
James Bottomley 47b5d692005-04-24 02:38:05 -05005032 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5033 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005034 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5036 if(FPT_BL_Card[p_card].discQCount != 0)
5037 FPT_BL_Card[p_card].discQCount--;
5038 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 -07005039 }
5040 else
5041 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005042 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005043 if(currSCCB->Sccb_tag)
5044 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005045 if(FPT_BL_Card[p_card].discQCount != 0)
5046 FPT_BL_Card[p_card].discQCount--;
5047 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005048 }else
5049 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005050 if(FPT_BL_Card[p_card].discQCount != 0)
5051 FPT_BL_Card[p_card].discQCount--;
5052 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005053 }
5054 }
5055 return;
5056
5057 }
5058
5059 if (status_byte == SSCHECK)
5060 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005061 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005062 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005063 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005064 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005065 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005066 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005067 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005068 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005069 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005070 }
5071 }
5072 }
5073
5074 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5075
5076 currSCCB->SccbStatus = SCCB_ERROR;
5077 currSCCB->TargetStatus = status_byte;
5078
5079 if (status_byte == SSCHECK) {
5080
James Bottomley 47b5d692005-04-24 02:38:05 -05005081 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5082 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005083
5084
Linus Torvalds1da177e2005-04-16 15:20:36 -07005085 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5086
5087 if (currSCCB->RequestSenseLength == 0)
5088 currSCCB->RequestSenseLength = 14;
5089
James Bottomley 47b5d692005-04-24 02:38:05 -05005090 FPT_ssenss(&FPT_BL_Card[p_card]);
5091 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005092
James Bottomley 47b5d692005-04-24 02:38:05 -05005093 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5094 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005095 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005096 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5097 if(FPT_BL_Card[p_card].discQCount != 0)
5098 FPT_BL_Card[p_card].discQCount--;
5099 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 -07005100 }
5101 else
5102 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005103 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005104 if(currSCCB->Sccb_tag)
5105 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005106 if(FPT_BL_Card[p_card].discQCount != 0)
5107 FPT_BL_Card[p_card].discQCount--;
5108 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005109 }else
5110 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005111 if(FPT_BL_Card[p_card].discQCount != 0)
5112 FPT_BL_Card[p_card].discQCount--;
5113 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005114 }
5115 }
5116 return;
5117 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005118 }
5119 }
5120 }
5121
5122
James Bottomley 47b5d692005-04-24 02:38:05 -05005123 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5124 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5125 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005126 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005127 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005128
5129
James Bottomley 47b5d692005-04-24 02:38:05 -05005130 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005131}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005132
5133#define SHORT_WAIT 0x0000000F
5134#define LONG_WAIT 0x0000FFFFL
5135
Linus Torvalds1da177e2005-04-16 15:20:36 -07005136
5137/*---------------------------------------------------------------------
5138 *
5139 * Function: Data Transfer Processor
5140 *
5141 * Description: This routine performs two tasks.
5142 * (1) Start data transfer by calling HOST_DATA_XFER_START
5143 * function. Once data transfer is started, (2) Depends
5144 * on the type of data transfer mode Scatter/Gather mode
5145 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5146 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5147 * data transfer done. In Scatter/Gather mode, this routine
5148 * checks bus master command complete and dual rank busy
5149 * bit to keep chaining SC transfer command. Similarly,
5150 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5151 * (F_HOST_XFER_ACT bit) for data transfer done.
5152 *
5153 *---------------------------------------------------------------------*/
5154
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005155static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005156{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005157 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005158
5159 currSCCB = pCurrCard->currentSCCB;
5160
5161 if (currSCCB->Sccb_XferState & F_SG_XFER)
5162 {
5163 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5164
5165 {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005166 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005167 currSCCB->Sccb_SGoffset = 0x00;
5168 }
5169 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5170
James Bottomley 47b5d692005-04-24 02:38:05 -05005171 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005172 }
5173
5174 else
5175 {
5176 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5177 {
5178 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5179
James Bottomley 47b5d692005-04-24 02:38:05 -05005180 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005181 }
5182 }
5183}
5184
5185
5186/*---------------------------------------------------------------------
5187 *
5188 * Function: BusMaster Scatter Gather Data Transfer Start
5189 *
5190 * Description:
5191 *
5192 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005193static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005194{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005195 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005196 unsigned int sg_index;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005197 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005198 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005199
5200
5201 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5202
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005203 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005204 }
5205
5206 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005207 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005208 }
5209
5210 sg_count = 0;
5211 tmpSGCnt = 0;
5212 sg_index = pcurrSCCB->Sccb_sgseg;
5213 reg_offset = hp_aramBase;
5214
5215
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005216 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005217
5218
5219 WR_HARPOON(p_port+hp_page_ctrl, i);
5220
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005221 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005222 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005223
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005224 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005225 (sg_index * 2));
5226
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005227 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005228 (sg_index * 2));
5229
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005230 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005231 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005232
5233
5234 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5235
5236 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5237 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5238
5239 tmpSGCnt = count & 0x00FFFFFFL;
5240 }
5241
5242 WR_HARP32(p_port,reg_offset,addr);
5243 reg_offset +=4;
5244
5245 WR_HARP32(p_port,reg_offset,count);
5246 reg_offset +=4;
5247
5248 count &= 0xFF000000L;
5249 sg_index++;
5250 sg_count++;
5251
5252 } /*End While */
5253
5254 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5255
5256 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5257
5258 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5259
5260 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5261
5262
5263 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5264 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5265 }
5266
5267 else {
5268
5269
5270 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5271 (tmpSGCnt & 0x000000001))
5272 {
5273
5274 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5275 tmpSGCnt--;
5276 }
5277
5278
5279 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5280
5281 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5282 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5283 }
5284
5285
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005286 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005287
5288}
5289
5290
5291/*---------------------------------------------------------------------
5292 *
5293 * Function: BusMaster Data Transfer Start
5294 *
5295 * Description:
5296 *
5297 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005298static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005299{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005300 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005301
5302 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5303
5304 count = pcurrSCCB->Sccb_XferCnt;
5305
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005306 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005307 }
5308
5309 else {
5310 addr = pcurrSCCB->SensePointer;
5311 count = pcurrSCCB->RequestSenseLength;
5312
5313 }
5314
Linus Torvalds1da177e2005-04-16 15:20:36 -07005315 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005316
5317
5318 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5319
5320 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5321 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5322
5323 WR_HARPOON(p_port+hp_xfer_cmd,
5324 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5325 }
5326
5327 else {
5328
5329 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5330 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5331
5332 WR_HARPOON(p_port+hp_xfer_cmd,
5333 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5334
5335 }
5336}
5337
5338
5339/*---------------------------------------------------------------------
5340 *
5341 * Function: BusMaster Timeout Handler
5342 *
5343 * Description: This function is called after a bus master command busy time
5344 * out is detected. This routines issue halt state machine
5345 * with a software time out for command busy. If command busy
5346 * is still asserted at the end of the time out, it issues
5347 * hard abort with another software time out. It hard abort
5348 * command busy is also time out, it'll just give up.
5349 *
5350 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005351static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005352{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005353 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005354
5355 timeout = LONG_WAIT;
5356
5357 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5358
5359 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5360
5361
5362
5363 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5364 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5365
5366 timeout = LONG_WAIT;
5367 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5368 }
5369
5370 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5371
5372 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005373 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005374 }
5375
5376 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005377 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005378 }
5379}
5380
5381
5382/*---------------------------------------------------------------------
5383 *
5384 * Function: Host Data Transfer Abort
5385 *
5386 * Description: Abort any in progress transfer.
5387 *
5388 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005389static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005390{
5391
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005392 unsigned long timeout;
5393 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005394 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005395
James Bottomley 47b5d692005-04-24 02:38:05 -05005396 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005397
5398 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5399
5400
5401 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5402
5403 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5404 timeout = LONG_WAIT;
5405
5406 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5407
5408 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5409
5410 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5411
James Bottomley 47b5d692005-04-24 02:38:05 -05005412 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005413
5414 if (pCurrSCCB->HostStatus == 0x00)
5415
5416 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5417
5418 }
5419
5420 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5421
5422 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5423
5424 if (pCurrSCCB->HostStatus == 0x00)
5425
5426 {
5427 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005428 }
5429 }
5430 }
5431 }
5432
5433 else if (pCurrSCCB->Sccb_XferCnt) {
5434
5435 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5436
5437
5438 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5439 ~SCATTER_EN));
5440
5441 WR_HARPOON(port+hp_sg_addr,0x00);
5442
5443 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5444
Alexey Dobriyance793212006-03-08 00:14:26 -08005445 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005446
Alexey Dobriyance793212006-03-08 00:14:26 -08005447 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005448 }
5449
5450 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5451
5452 while (remain_cnt < 0x01000000L) {
5453
5454 sg_ptr--;
5455
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005456 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005457 DataPointer) + (sg_ptr * 2)))) {
5458
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005459 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005460 DataPointer) + (sg_ptr * 2)));
5461 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005462
5463 else {
5464
5465 break;
5466 }
5467 }
5468
5469
5470
5471 if (remain_cnt < 0x01000000L) {
5472
5473
5474 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5475
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005476 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005477
5478
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005479 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005480 && (remain_cnt == 0))
5481
5482 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5483 }
5484
5485 else {
5486
5487
5488 if (pCurrSCCB->HostStatus == 0x00) {
5489
5490 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5491 }
5492 }
5493 }
5494
5495
5496 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5497
5498
5499 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5500
James Bottomley 47b5d692005-04-24 02:38:05 -05005501 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005502 }
5503
5504 else {
5505
5506 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5507
5508 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5509
5510 if (pCurrSCCB->HostStatus == 0x00) {
5511
5512 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005513 }
5514 }
5515 }
5516
5517 }
5518 }
5519
5520 else {
5521
5522
5523 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5524
5525 timeout = SHORT_WAIT;
5526
5527 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5528 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5529 timeout--) {}
5530 }
5531
5532 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5533
5534 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5535 FLUSH_XFER_CNTR));
5536
5537 timeout = LONG_WAIT;
5538
5539 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5540 timeout--) {}
5541
5542 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5543 ~FLUSH_XFER_CNTR));
5544
5545
5546 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5547
5548 if (pCurrSCCB->HostStatus == 0x00) {
5549
5550 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5551 }
5552
James Bottomley 47b5d692005-04-24 02:38:05 -05005553 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005554 }
5555 }
5556
5557 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5558
5559 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5560
5561 if (pCurrSCCB->HostStatus == 0x00) {
5562
5563 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005564 }
5565 }
5566 }
5567 }
5568
5569 }
5570
5571 else {
5572
5573
5574 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5575
5576 timeout = LONG_WAIT;
5577
5578 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5579
5580 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5581
5582 if (pCurrSCCB->HostStatus == 0x00) {
5583
5584 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5585 }
5586
James Bottomley 47b5d692005-04-24 02:38:05 -05005587 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005588 }
5589 }
5590
5591
5592 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5593
5594 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5595
5596 if (pCurrSCCB->HostStatus == 0x00) {
5597
5598 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005599 }
5600 }
5601
5602 }
5603
5604 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5605
5606 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5607 ~SCATTER_EN));
5608
5609 WR_HARPOON(port+hp_sg_addr,0x00);
5610
5611 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5612
5613 pCurrSCCB->Sccb_SGoffset = 0x00;
5614
5615
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005616 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005617 pCurrSCCB->DataLength) {
5618
5619 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5620
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005621 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005622
5623 }
5624 }
5625
5626 else {
5627
5628 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5629
5630 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5631 }
5632 }
5633
5634 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5635}
5636
5637
5638
5639/*---------------------------------------------------------------------
5640 *
5641 * Function: Host Data Transfer Restart
5642 *
5643 * Description: Reset the available count due to a restore data
5644 * pointers message.
5645 *
5646 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005647static void FPT_hostDataXferRestart(struct sccb * currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005648{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005649 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005650 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005651 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005652
5653 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5654
5655 currSCCB->Sccb_XferCnt = 0;
5656
5657 sg_index = 0xffff; /*Index by long words into sg list. */
5658 data_count = 0; /*Running count of SG xfer counts. */
5659
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005660 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005661
5662 while (data_count < currSCCB->Sccb_ATC) {
5663
5664 sg_index++;
5665 data_count += *(sg_ptr+(sg_index * 2));
5666 }
5667
5668 if (data_count == currSCCB->Sccb_ATC) {
5669
5670 currSCCB->Sccb_SGoffset = 0;
5671 sg_index++;
5672 }
5673
5674 else {
5675 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5676 }
5677
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005678 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005679 }
5680
5681 else {
5682 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5683 }
5684}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005685
5686
5687
Linus Torvalds1da177e2005-04-16 15:20:36 -07005688/*---------------------------------------------------------------------
5689 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005690 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005691 *
5692 * Description: Setup all data structures necessary for SCAM selection.
5693 *
5694 *---------------------------------------------------------------------*/
5695
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005696static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005697{
5698
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005699 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005700 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005701
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005702 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005703 PSCCBcard currCard;
5704 PNVRamInfo pCurrNvRam;
5705
James Bottomley 47b5d692005-04-24 02:38:05 -05005706 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005707 p_port = currCard->ioPort;
5708 pCurrNvRam = currCard->pNvRamInfo;
5709
5710
5711 if(pCurrNvRam){
5712 ScamFlg = pCurrNvRam->niScamConf;
5713 i = pCurrNvRam->niSysConf;
5714 }
5715 else{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005716 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5717 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005718 }
5719 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5720 return;
5721
James Bottomley 47b5d692005-04-24 02:38:05 -05005722 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005723
5724 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5725 too slow to return to SCAM selection */
5726
5727 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005728 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005729 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005730 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731
James Bottomley 47b5d692005-04-24 02:38:05 -05005732 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005733
5734 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5735 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005736 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005737
James Bottomley 47b5d692005-04-24 02:38:05 -05005738 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005739
5740 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005741 FPT_scxferc(p_port,SYNC_PTRN);
5742 FPT_scxferc(p_port,DOM_MSTR);
5743 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005744 } while ( loser == 0xFF );
5745
James Bottomley 47b5d692005-04-24 02:38:05 -05005746 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005747
5748 if ((p_power_up) && (!loser))
5749 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005750 FPT_sresb(p_port,p_card);
5751 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005752
James Bottomley 47b5d692005-04-24 02:38:05 -05005753 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005754
James Bottomley 47b5d692005-04-24 02:38:05 -05005755 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005756
5757 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005758 FPT_scxferc(p_port, SYNC_PTRN);
5759 FPT_scxferc(p_port, DOM_MSTR);
5760 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761 id_string[0]);
5762 } while ( loser == 0xFF );
5763
James Bottomley 47b5d692005-04-24 02:38:05 -05005764 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005765 }
5766 }
5767
5768 else
5769 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005770 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005771 }
5772
5773
5774 if (!loser)
5775 {
5776
James Bottomley 47b5d692005-04-24 02:38:05 -05005777 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005778
5779
5780 if (ScamFlg & SCAM_ENABLED)
5781 {
5782
5783 for (i=0; i < MAX_SCSI_TAR; i++)
5784 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005785 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5786 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005787 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005788 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005789 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005790 FPT_scamInfo[i].state = LEGACY;
5791 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5792 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005793 {
5794
James Bottomley 47b5d692005-04-24 02:38:05 -05005795 FPT_scamInfo[i].id_string[0] = 0xFF;
5796 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005797 if(pCurrNvRam == NULL)
5798 currCard->globalFlags |= F_UPDATE_EEPROM;
5799 }
5800 }
5801 }
5802 }
5803
James Bottomley 47b5d692005-04-24 02:38:05 -05005804 FPT_sresb(p_port,p_card);
5805 FPT_Wait1Second(p_port);
5806 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5807 FPT_scsel(p_port);
5808 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005809 }
5810
Linus Torvalds1da177e2005-04-16 15:20:36 -07005811 }
5812
5813 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5814 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005815 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5816 assigned_id = 0;
5817 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005818
5819 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005820 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821
James Bottomley 47b5d692005-04-24 02:38:05 -05005822 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005823 if (i == ASSIGN_ID)
5824 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005825 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005826 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005827 i = FPT_scxferc(p_port,0x00);
5828 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005830 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831
James Bottomley 47b5d692005-04-24 02:38:05 -05005832 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005833 {
5834 currCard->ourId =
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005835 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005836 FPT_inisci(p_card, p_port, p_our_id);
5837 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5838 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005839 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005840 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841 }
5842 }
5843 }
5844 }
5845
5846 else if (i == SET_P_FLAG)
5847 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005848 if (!(FPT_scsendi(p_port,
5849 &FPT_scamInfo[p_our_id].id_string[0])))
5850 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851 }
5852 }while (!assigned_id);
5853
James Bottomley 47b5d692005-04-24 02:38:05 -05005854 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005855 }
5856
Linus Torvalds1da177e2005-04-16 15:20:36 -07005857 if (ScamFlg & SCAM_ENABLED)
5858 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005859 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005860 if (currCard->globalFlags & F_UPDATE_EEPROM)
5861 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005862 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5864 }
5865 }
5866
5867
Linus Torvalds1da177e2005-04-16 15:20:36 -07005868/*
5869 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5870 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005871 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5872 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005873 k++;
5874 }
5875
5876 if (k==2)
5877 currCard->globalFlags |= F_SINGLE_DEVICE;
5878 else
5879 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5880*/
5881}
5882
5883
5884/*---------------------------------------------------------------------
5885 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005886 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887 *
5888 * Description: Gain control of the bus and wait SCAM select time (250ms)
5889 *
5890 *---------------------------------------------------------------------*/
5891
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005892static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005893{
5894 if (p_sel_type == INIT_SELTD)
5895 {
5896
5897 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5898
5899
5900 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005901 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005902
5903 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005904 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005905
5906 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5907
5908 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5909
5910 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5911 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005912 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005913 }
5914
5915
5916 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5917
5918 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5919
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5921 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005922 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005923 }
5924 }
5925
5926
5927 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5928 & ~ACTdeassert));
5929 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5930 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005931 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5933
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5935
5936 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5937 & ~SCSI_BSY));
5938
James Bottomley 47b5d692005-04-24 02:38:05 -05005939 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005940
James Bottomley 47b5d692005-04-24 02:38:05 -05005941 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005942}
5943
5944
5945/*---------------------------------------------------------------------
5946 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005947 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005948 *
5949 * Description: Release the SCSI bus and disable SCAM selection.
5950 *
5951 *---------------------------------------------------------------------*/
5952
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005953static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005954{
5955 WR_HARPOON(p_port+hp_page_ctrl,
5956 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5957
5958
5959 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5960
5961 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5962 & ~SCSI_BUS_EN));
5963
5964 WR_HARPOON(p_port+hp_scsisig, 0x00);
5965
5966
5967 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5968 & ~SCAM_EN));
5969
5970 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5971 | ACTdeassert));
5972
Linus Torvalds1da177e2005-04-16 15:20:36 -07005973 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005974
5975 WR_HARPOON(p_port+hp_page_ctrl,
5976 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5977}
5978
5979
5980
5981/*---------------------------------------------------------------------
5982 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005983 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005984 *
5985 * Description: Assign an ID to all the SCAM devices.
5986 *
5987 *---------------------------------------------------------------------*/
5988
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005989static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005990{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005991 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005992
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08005993 unsigned char i,k,scam_id;
5994 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005995 PNVRamInfo pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08005996 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997
James Bottomley 47b5d692005-04-24 02:38:05 -05005998 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005999
James Bottomley 47b5d692005-04-24 02:38:05 -05006000 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006001
6002 while (!i)
6003 {
6004
6005 for (k=0; k < ID_STRING_LENGTH; k++)
6006 {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006007 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006008 }
6009
James Bottomley 47b5d692005-04-24 02:38:05 -05006010 FPT_scxferc(p_port,SYNC_PTRN);
6011 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006012
James Bottomley 47b5d692005-04-24 02:38:05 -05006013 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006014 {
6015 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006016 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006017 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6018 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006019 temp_id_string[1] = crcBytes[2];
6020 temp_id_string[2] = crcBytes[0];
6021 temp_id_string[3] = crcBytes[1];
6022 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006023 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006024 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006025 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006026
6027 if (i == CLR_PRIORITY)
6028 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006029 FPT_scxferc(p_port,MISC_CODE);
6030 FPT_scxferc(p_port,CLR_P_FLAG);
6031 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006032 }
6033
6034 else if (i != NO_ID_AVAIL)
6035 {
6036 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006037 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006038 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006039 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006040
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006041 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042
6043
6044 for (k=1; k < 0x08; k <<= 1)
6045 if (!( k & i ))
6046 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6047
James Bottomley 47b5d692005-04-24 02:38:05 -05006048 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049
James Bottomley 47b5d692005-04-24 02:38:05 -05006050 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006051 }
6052 }
6053
6054 else
6055 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006056 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006057 }
6058
6059 } /*End while */
6060
James Bottomley 47b5d692005-04-24 02:38:05 -05006061 FPT_scxferc(p_port,SYNC_PTRN);
6062 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006063}
6064
6065
6066
6067
6068
6069/*---------------------------------------------------------------------
6070 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006071 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006072 *
6073 * Description: Select all the SCAM devices.
6074 *
6075 *---------------------------------------------------------------------*/
6076
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006077static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006078{
6079
6080 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006081 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006082
6083 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6084
6085
6086 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006087 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6088 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006089
6090
6091 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006092 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006093
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006094 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6095 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006096 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006097
6098 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6099}
6100
6101
6102
6103/*---------------------------------------------------------------------
6104 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006105 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006106 *
6107 * Description: Handshake the p_data (DB4-0) across the bus.
6108 *
6109 *---------------------------------------------------------------------*/
6110
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006111static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006112{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006113 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006114
6115 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6116
6117 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6118
6119 curr_data &= ~BIT(7);
6120
6121 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6122
James Bottomley 47b5d692005-04-24 02:38:05 -05006123 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006124 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6125
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006126 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127
6128 curr_data |= BIT(6);
6129
6130 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6131
6132 curr_data &= ~BIT(5);
6133
6134 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6135
James Bottomley 47b5d692005-04-24 02:38:05 -05006136 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006137
6138 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6139 curr_data |= BIT(7);
6140
6141 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6142
6143 curr_data &= ~BIT(6);
6144
6145 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146
James Bottomley 47b5d692005-04-24 02:38:05 -05006147 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006148
6149 return(ret_data);
6150}
6151
6152
6153/*---------------------------------------------------------------------
6154 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006155 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006156 *
6157 * Description: Transfer our Identification string to determine if we
6158 * will be the dominant master.
6159 *
6160 *---------------------------------------------------------------------*/
6161
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006162static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006163{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006164 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006165
James Bottomley 47b5d692005-04-24 02:38:05 -05006166 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006167
6168 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6169
6170 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6171
6172 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006173 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006174
6175 else if (p_id_string[byte_cnt] & bit_cnt)
6176
James Bottomley 47b5d692005-04-24 02:38:05 -05006177 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006178
6179 else {
6180
James Bottomley 47b5d692005-04-24 02:38:05 -05006181 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006183 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006184 }
6185
6186 if ((ret_data & 0x1C) == 0x10)
6187 return(0x00); /*End of isolation stage, we won! */
6188
6189 if (ret_data & 0x1C)
6190 return(0xFF);
6191
6192 if ((defer) && (!(ret_data & 0x1F)))
6193 return(0x01); /*End of isolation stage, we lost. */
6194
6195 } /*bit loop */
6196
6197 } /*byte loop */
6198
6199 if (defer)
6200 return(0x01); /*We lost */
6201 else
6202 return(0); /*We WON! Yeeessss! */
6203}
6204
6205
6206
6207/*---------------------------------------------------------------------
6208 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006209 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006210 *
6211 * Description: Transfer the Identification string.
6212 *
6213 *---------------------------------------------------------------------*/
6214
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006215static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006216{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006217 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006218
6219 the_data = 0;
6220
6221 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6222
6223 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6224
James Bottomley 47b5d692005-04-24 02:38:05 -05006225 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006226
6227 if (ret_data & 0xFC)
6228 return(0xFF);
6229
6230 else {
6231
6232 the_data <<= 1;
6233 if (ret_data & BIT(1)) {
6234 the_data |= 1;
6235 }
6236 }
6237
6238 if ((ret_data & 0x1F) == 0)
6239 {
6240/*
6241 if(bit_cnt != 0 || bit_cnt != 8)
6242 {
6243 byte_cnt = 0;
6244 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006245 FPT_scxferc(p_port, SYNC_PTRN);
6246 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006247 continue;
6248 }
6249*/
6250 if (byte_cnt)
6251 return(0x00);
6252 else
6253 return(0xFF);
6254 }
6255
6256 } /*bit loop */
6257
6258 p_id_string[byte_cnt] = the_data;
6259
6260 } /*byte loop */
6261
6262 return(0);
6263}
6264
6265
6266
6267/*---------------------------------------------------------------------
6268 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006269 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006270 *
6271 * Description: Sample the SCSI data bus making sure the signal has been
6272 * deasserted for the correct number of consecutive samples.
6273 *
6274 *---------------------------------------------------------------------*/
6275
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006276static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006277{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006278 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006279
6280 i = 0;
6281 while ( i < MAX_SCSI_TAR ) {
6282
6283 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6284
6285 i = 0;
6286
6287 else
6288
6289 i++;
6290
6291 }
6292}
6293
6294
6295
6296/*---------------------------------------------------------------------
6297 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006298 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006299 *
6300 * Description: Sample the SCSI Signal lines making sure the signal has been
6301 * deasserted for the correct number of consecutive samples.
6302 *
6303 *---------------------------------------------------------------------*/
6304
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006305static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006306{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006307 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006308
6309 i = 0;
6310 while ( i < MAX_SCSI_TAR ) {
6311
6312 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6313
6314 i = 0;
6315
6316 else
6317
6318 i++;
6319
6320 }
6321}
6322
6323
6324/*---------------------------------------------------------------------
6325 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006326 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006327 *
6328 * Description: Make sure we received a valid data byte.
6329 *
6330 *---------------------------------------------------------------------*/
6331
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006332static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006333{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006334 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006335
6336 for (count=1; count < 0x08; count<<=1) {
6337 if (!(p_quintet & count))
6338 p_quintet -= 0x80;
6339 }
6340
6341 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006342 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006343
6344 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006345 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006346}
6347
6348
6349/*---------------------------------------------------------------------
6350 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006351 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006352 *
6353 * Description: Select the specified device ID using a selection timeout
6354 * less than 4ms. If somebody responds then it is a legacy
6355 * drive and this ID must be marked as such.
6356 *
6357 *---------------------------------------------------------------------*/
6358
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006359static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006361 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006362
6363 WR_HARPOON(p_port+hp_page_ctrl,
6364 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6365
6366 ARAM_ACCESS(p_port);
6367
6368 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6369 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6370
6371
6372 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6373 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6374 }
6375 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6376
6377 WRW_HARPOON((p_port+hp_intstat),
6378 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6379
6380 WR_HARPOON(p_port+hp_select_id, targ_id);
6381
6382 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6383 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6384 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6385
6386
6387 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6388 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6389
6390 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006391 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006392
6393 DISABLE_AUTO(p_port);
6394
6395 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6396 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6397
6398 SGRAM_ACCESS(p_port);
6399
6400 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6401
6402 WRW_HARPOON((p_port+hp_intstat),
6403 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6404
6405 WR_HARPOON(p_port+hp_page_ctrl,
6406 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6407
James Bottomley 47b5d692005-04-24 02:38:05 -05006408 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006409 }
6410
6411 else {
6412
6413 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6414 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6415 {
6416 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6417 ACCEPT_MSG(p_port);
6418 }
6419 }
6420
6421 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6422
6423 WR_HARPOON(p_port+hp_page_ctrl,
6424 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6425
James Bottomley 47b5d692005-04-24 02:38:05 -05006426 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006427 }
6428}
6429
Linus Torvalds1da177e2005-04-16 15:20:36 -07006430/*---------------------------------------------------------------------
6431 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006432 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006433 *
6434 * Description: Wait to be selected by another SCAM initiator.
6435 *
6436 *---------------------------------------------------------------------*/
6437
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006438static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006439{
6440 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6441}
6442
6443
6444/*---------------------------------------------------------------------
6445 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006446 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006447 *
6448 * Description: Setup the data Structure with the info from the EEPROM.
6449 *
6450 *---------------------------------------------------------------------*/
6451
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006452static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006453{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006454 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006455 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006456 PNVRamInfo pCurrNvRam;
6457
James Bottomley 47b5d692005-04-24 02:38:05 -05006458 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006459
6460 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6461 max_id = 0x08;
6462
6463 else
6464 max_id = 0x10;
6465
6466 if(pCurrNvRam){
6467 for(i = 0; i < max_id; i++){
6468
6469 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006470 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006472 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006473
James Bottomley 47b5d692005-04-24 02:38:05 -05006474 if(FPT_scamInfo[i].id_string[0] == 0x00)
6475 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006476 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006477 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006478
6479 }
6480 }else {
6481 for (i=0; i < max_id; i++)
6482 {
6483 for (k=0; k < ID_STRING_LENGTH; k+=2)
6484 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006485 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6486 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006487 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006488 ee_data >>= 8;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006489 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006490 }
6491
James Bottomley 47b5d692005-04-24 02:38:05 -05006492 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6493 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006494
James Bottomley 47b5d692005-04-24 02:38:05 -05006495 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006496
6497 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006498 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006499
6500 }
6501 }
6502 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006503 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006504
6505}
6506
6507/*---------------------------------------------------------------------
6508 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006509 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006510 *
6511 * Description: Match the Device ID string with our values stored in
6512 * the EEPROM.
6513 *
6514 *---------------------------------------------------------------------*/
6515
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006516static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006517{
6518
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006519 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520
6521
6522 for (i=0; i < MAX_SCSI_TAR; i++) {
6523
James Bottomley 47b5d692005-04-24 02:38:05 -05006524 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006525
6526 for (k=0; k < ID_STRING_LENGTH; k++)
6527 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006528 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6529 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006530 }
6531
6532 if (match)
6533 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006534 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006535 return(i);
6536 }
6537
Linus Torvalds1da177e2005-04-16 15:20:36 -07006538 }
6539
6540
6541
6542 if (p_id_string[0] & BIT(5))
6543 i = 8;
6544 else
6545 i = MAX_SCSI_TAR;
6546
6547 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006548 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006549 else
6550 match = 7;
6551
6552 while (i > 0)
6553 {
6554 i--;
6555
James Bottomley 47b5d692005-04-24 02:38:05 -05006556 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006557 {
6558 for (k=0; k < ID_STRING_LENGTH; k++)
6559 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006560 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006561 }
6562
James Bottomley 47b5d692005-04-24 02:38:05 -05006563 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006564
James Bottomley 47b5d692005-04-24 02:38:05 -05006565 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6566 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006567 return(match);
6568
6569 }
6570
6571
6572 match--;
6573
6574 if (match == 0xFF)
6575 {
6576 if (p_id_string[0] & BIT(5))
6577 match = 7;
6578 else
6579 match = MAX_SCSI_TAR-1;
6580 }
6581 }
6582
6583
6584
6585 if (p_id_string[0] & BIT(7))
6586 {
6587 return(CLR_PRIORITY);
6588 }
6589
6590
6591 if (p_id_string[0] & BIT(5))
6592 i = 8;
6593 else
6594 i = MAX_SCSI_TAR;
6595
6596 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006597 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006598 else
6599 match = 7;
6600
6601 while (i > 0)
6602 {
6603
6604 i--;
6605
James Bottomley 47b5d692005-04-24 02:38:05 -05006606 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006607 {
6608 for (k=0; k < ID_STRING_LENGTH; k++)
6609 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006610 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006611 }
6612
James Bottomley 47b5d692005-04-24 02:38:05 -05006613 FPT_scamInfo[match].id_string[0] |= BIT(7);
6614 FPT_scamInfo[match].state = ID_ASSIGNED;
6615 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6616 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006617 return(match);
6618
6619 }
6620
6621
6622 match--;
6623
6624 if (match == 0xFF)
6625 {
6626 if (p_id_string[0] & BIT(5))
6627 match = 7;
6628 else
6629 match = MAX_SCSI_TAR-1;
6630 }
6631 }
6632
6633 return(NO_ID_AVAIL);
6634}
6635
6636
6637/*---------------------------------------------------------------------
6638 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006639 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006640 *
6641 * Description: Save off the device SCAM ID strings.
6642 *
6643 *---------------------------------------------------------------------*/
6644
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006645static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006646{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006647 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006648 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006649
6650
6651 sum_data = 0x0000;
6652
6653 for (i = 1; i < EE_SCAMBASE/2; i++)
6654 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006655 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006656 }
6657
6658
James Bottomley 47b5d692005-04-24 02:38:05 -05006659 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006660
6661 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6662 max_id = 0x08;
6663
6664 else
6665 max_id = 0x10;
6666
6667 for (i=0; i < max_id; i++)
6668 {
6669
6670 for (k=0; k < ID_STRING_LENGTH; k+=2)
6671 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006672 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006673 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006674 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006675 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006676 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6677 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006678 }
6679 }
6680
6681
James Bottomley 47b5d692005-04-24 02:38:05 -05006682 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6683 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006684}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006685
6686/*---------------------------------------------------------------------
6687 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006688 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006689 *
6690 * Description: Setup the Xbow for normal operation.
6691 *
6692 *---------------------------------------------------------------------*/
6693
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006694static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006695{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006696unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006697
6698 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006699 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006700
6701 WR_HARPOON(port+hp_scsireset,0x00);
6702 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6703
6704 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6705 FIFO_CLR));
6706
6707 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6708
6709 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6710
6711 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6712 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6713
6714 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6715
James Bottomley 47b5d692005-04-24 02:38:05 -05006716 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006717 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6718
6719 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006720 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006721
James Bottomley 47b5d692005-04-24 02:38:05 -05006722 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006723
6724 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6725
6726 /* Turn on SCSI_MODE8 for narrow cards to fix the
6727 strapping issue with the DUAL CHANNEL card */
6728 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6729 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6730
Linus Torvalds1da177e2005-04-16 15:20:36 -07006731 WR_HARPOON(port+hp_page_ctrl, i);
6732
6733}
6734
6735
6736/*---------------------------------------------------------------------
6737 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006738 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006739 *
6740 * Description: Initialize the BusMaster for normal operations.
6741 *
6742 *---------------------------------------------------------------------*/
6743
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006744static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006745{
6746
6747
6748 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6749 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6750
6751 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6752
6753
6754 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6755
6756 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6757
6758
Linus Torvalds1da177e2005-04-16 15:20:36 -07006759 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6760 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6761 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6762 ~SCATTER_EN));
6763}
6764
6765
6766/*---------------------------------------------------------------------
6767 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006768 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006769 *
6770 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6771 * necessary.
6772 *
6773 *---------------------------------------------------------------------*/
6774
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006775static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006776{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006777 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006778
6779 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6780 max_wd_cnt = EEPROM_WD_CNT;
6781 else
6782 max_wd_cnt = EEPROM_WD_CNT * 2;
6783
James Bottomley 47b5d692005-04-24 02:38:05 -05006784 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006785
6786 if (temp == 0x4641) {
6787
6788 for (index = 2; index < max_wd_cnt; index++) {
6789
James Bottomley 47b5d692005-04-24 02:38:05 -05006790 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006791
6792 }
6793
James Bottomley 47b5d692005-04-24 02:38:05 -05006794 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006795
6796 return; /*EEPROM is Okay so return now! */
6797 }
6798 }
6799
6800
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006801 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006802
6803 for (index = 0; index < max_wd_cnt; index++) {
6804
James Bottomley 47b5d692005-04-24 02:38:05 -05006805 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806 }
6807
6808 temp = 0;
6809
James Bottomley 47b5d692005-04-24 02:38:05 -05006810 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006812 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006814 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006816 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006818 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006820 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006822 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006823 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006824 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825 temp += 0x0007;
6826
James Bottomley 47b5d692005-04-24 02:38:05 -05006827 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006828 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006829 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832 temp += 0x0000;
6833
James Bottomley 47b5d692005-04-24 02:38:05 -05006834 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006835 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006836 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006837 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006838 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006839 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006840 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006842 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006844 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006847 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006849 temp += 0x4242;
6850
6851
James Bottomley 47b5d692005-04-24 02:38:05 -05006852 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006854 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006856 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006858 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006860 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006862 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006863 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006864 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006866 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 temp += 0x2020;
6868
6869 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006870 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871 temp += (0x0700+TYPE_CODE0);
6872 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006873 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006874 temp += 0x5542; /* BUSLOGIC */
6875 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877 temp += 0x4C53;
6878 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006879 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006880 temp += 0x474F;
6881 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006882 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 temp += 0x4349;
6884 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006885 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006886 temp += 0x5442; /* BT- 930 */
6887 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006888 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889 temp += 0x202D;
6890 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006891 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006892 temp += 0x3339;
6893 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006894 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895 temp += 0x2030;
6896 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006897 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006898 temp += 0x5453;
6899 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006900 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006901 temp += 0x5645;
6902 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006903 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006904 temp += 0x2045;
6905 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006906 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006907 temp += 0x202F;
6908 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006909 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910 temp += 0x4F4A;
6911 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006912 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006913 temp += 0x204E;
6914 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006915 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006916 temp += 0x3539;
6917
6918
6919
James Bottomley 47b5d692005-04-24 02:38:05 -05006920 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006921
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006922 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006923
6924}
6925
Linus Torvalds1da177e2005-04-16 15:20:36 -07006926
6927/*---------------------------------------------------------------------
6928 *
6929 * Function: Queue Search Select
6930 *
6931 * Description: Try to find a new command to execute.
6932 *
6933 *---------------------------------------------------------------------*/
6934
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006935static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006936{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08006937 unsigned char scan_ptr, lun;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08006938 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006939 struct sccb * pOldSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940
6941 scan_ptr = pCurrCard->scanIndex;
6942 do
6943 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006944 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006945 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6946 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6947 {
6948 if (currTar_Info->TarSelQ_Cnt != 0)
6949 {
6950
6951 scan_ptr++;
6952 if (scan_ptr == MAX_SCSI_TAR)
6953 scan_ptr = 0;
6954
6955 for(lun=0; lun < MAX_LUN; lun++)
6956 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006957 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006958 {
6959
6960 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6961 pOldSccb = NULL;
6962
6963 while((pCurrCard->currentSCCB != NULL) &&
6964 (lun != pCurrCard->currentSCCB->Lun))
6965 {
6966 pOldSccb = pCurrCard->currentSCCB;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006967 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006968 Sccb_forwardlink;
6969 }
6970 if(pCurrCard->currentSCCB == NULL)
6971 continue;
6972 if(pOldSccb != NULL)
6973 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006974 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006975 Sccb_forwardlink;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006976 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006977 Sccb_backlink;
6978 currTar_Info->TarSelQ_Cnt--;
6979 }
6980 else
6981 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006982 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006983
6984 if (currTar_Info->TarSelQ_Head == NULL)
6985 {
6986 currTar_Info->TarSelQ_Tail = NULL;
6987 currTar_Info->TarSelQ_Cnt = 0;
6988 }
6989 else
6990 {
6991 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006992 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006993 }
6994 }
6995 pCurrCard->scanIndex = scan_ptr;
6996
6997 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6998
6999 break;
7000 }
7001 }
7002 }
7003
7004 else
7005 {
7006 scan_ptr++;
7007 if (scan_ptr == MAX_SCSI_TAR) {
7008 scan_ptr = 0;
7009 }
7010 }
7011
7012 }
7013 else
7014 {
7015 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007016 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007017 {
7018
7019 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7020
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007021 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007022
7023 if (currTar_Info->TarSelQ_Head == NULL)
7024 {
7025 currTar_Info->TarSelQ_Tail = NULL;
7026 currTar_Info->TarSelQ_Cnt = 0;
7027 }
7028 else
7029 {
7030 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007031 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007032 }
7033
7034 scan_ptr++;
7035 if (scan_ptr == MAX_SCSI_TAR)
7036 scan_ptr = 0;
7037
7038 pCurrCard->scanIndex = scan_ptr;
7039
7040 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7041
7042 break;
7043 }
7044
7045 else
7046 {
7047 scan_ptr++;
7048 if (scan_ptr == MAX_SCSI_TAR)
7049 {
7050 scan_ptr = 0;
7051 }
7052 }
7053 }
7054 } while (scan_ptr != pCurrCard->scanIndex);
7055}
7056
7057
7058/*---------------------------------------------------------------------
7059 *
7060 * Function: Queue Select Fail
7061 *
7062 * Description: Add the current SCCB to the head of the Queue.
7063 *
7064 *---------------------------------------------------------------------*/
7065
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007066static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007067{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007068 unsigned char thisTarg;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007069 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070
7071 if (pCurrCard->currentSCCB != NULL)
7072 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007073 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007074 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007075
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007076 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007077
7078 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7079
7080 if (currTar_Info->TarSelQ_Cnt == 0)
7081 {
7082 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7083 }
7084
7085 else
7086 {
7087 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7088 }
7089
7090
7091 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7092
7093 pCurrCard->currentSCCB = NULL;
7094 currTar_Info->TarSelQ_Cnt++;
7095 }
7096}
7097/*---------------------------------------------------------------------
7098 *
7099 * Function: Queue Command Complete
7100 *
7101 * Description: Call the callback function with the current SCCB.
7102 *
7103 *---------------------------------------------------------------------*/
7104
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007105static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007106 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007107{
7108
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007109 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007110 CALL_BK_FN callback;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007111 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007112
7113 SCSIcmd = p_sccb->Cdb[0];
7114
7115
7116 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7117
7118 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7119 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7120 (p_sccb->TargetStatus != SSCHECK))
7121
7122 if ((SCSIcmd == SCSI_READ) ||
7123 (SCSIcmd == SCSI_WRITE) ||
7124 (SCSIcmd == SCSI_READ_EXTENDED) ||
7125 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7126 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7127 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7128 (pCurrCard->globalFlags & F_NO_FILTER)
7129 )
7130 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7131 }
7132
7133
7134 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7135 {
7136 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7137 p_sccb->SccbStatus = SCCB_ERROR;
7138 else
7139 p_sccb->SccbStatus = SCCB_SUCCESS;
7140 }
7141
7142 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7143
7144 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7145 for (i=0; i < 6; i++) {
7146 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7147 }
7148 }
7149
7150 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7151 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7152
James Bottomley 47b5d692005-04-24 02:38:05 -05007153 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007154 }
7155
7156 pCurrCard->cmdCounter--;
7157 if (!pCurrCard->cmdCounter) {
7158
7159 if (pCurrCard->globalFlags & F_GREEN_PC) {
7160 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7161 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7162 }
7163
7164 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7165 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7166
7167 }
7168
7169 if(pCurrCard->discQCount != 0)
7170 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007171 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007172 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7173 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7174 {
7175 pCurrCard->discQCount--;
7176 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7177 }
7178 else
7179 {
7180 if(p_sccb->Sccb_tag)
7181 {
7182 pCurrCard->discQCount--;
7183 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7184 }else
7185 {
7186 pCurrCard->discQCount--;
7187 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7188 }
7189 }
7190
7191 }
7192
7193 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7194 callback(p_sccb);
7195 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7196 pCurrCard->currentSCCB = NULL;
7197}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007198
7199
7200/*---------------------------------------------------------------------
7201 *
7202 * Function: Queue Disconnect
7203 *
7204 * Description: Add SCCB to our disconnect array.
7205 *
7206 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007207static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007208{
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007209 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007210
James Bottomley 47b5d692005-04-24 02:38:05 -05007211 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007212
James Bottomley 47b5d692005-04-24 02:38:05 -05007213 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007214 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7215 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007216 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007217 }
7218 else
7219 {
7220 if (p_sccb->Sccb_tag)
7221 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007222 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7223 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7224 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007225 }else
7226 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007227 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007228 }
7229 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007230 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007231}
7232
7233
7234/*---------------------------------------------------------------------
7235 *
7236 * Function: Queue Flush SCCB
7237 *
7238 * Description: Flush all SCCB's back to the host driver for this target.
7239 *
7240 *---------------------------------------------------------------------*/
7241
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007242static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007243{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007244 unsigned char qtag,thisTarg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007245 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007246 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007247
James Bottomley 47b5d692005-04-24 02:38:05 -05007248 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007249 if(currSCCB != NULL)
7250 {
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007251 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007252 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007253
7254 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7255
James Bottomley 47b5d692005-04-24 02:38:05 -05007256 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7257 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007258 {
7259
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007260 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007261
James Bottomley 47b5d692005-04-24 02:38:05 -05007262 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007263
James Bottomley 47b5d692005-04-24 02:38:05 -05007264 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007265 currTar_Info->TarTagQ_Cnt--;
7266
7267 }
7268 }
7269 }
7270
7271}
7272
7273/*---------------------------------------------------------------------
7274 *
7275 * Function: Queue Flush Target SCCB
7276 *
7277 * Description: Flush all SCCB's back to the host driver for this target.
7278 *
7279 *---------------------------------------------------------------------*/
7280
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007281static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7282 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007283{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007284 unsigned char qtag;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007285 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007286
James Bottomley 47b5d692005-04-24 02:38:05 -05007287 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007288
7289 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7290
James Bottomley 47b5d692005-04-24 02:38:05 -05007291 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7292 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007293 {
7294
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007295 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296
James Bottomley 47b5d692005-04-24 02:38:05 -05007297 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007298
James Bottomley 47b5d692005-04-24 02:38:05 -05007299 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007300 currTar_Info->TarTagQ_Cnt--;
7301
7302 }
7303 }
7304
7305}
7306
7307
7308
7309
7310
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007311static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007312{
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007313 struct sccb_mgr_tar_info * currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007314 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007315
7316 p_SCCB->Sccb_forwardlink = NULL;
7317
7318 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7319
7320 if (currTar_Info->TarSelQ_Cnt == 0) {
7321
7322 currTar_Info->TarSelQ_Head = p_SCCB;
7323 }
7324
7325 else {
7326
7327 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7328 }
7329
7330
7331 currTar_Info->TarSelQ_Tail = p_SCCB;
7332 currTar_Info->TarSelQ_Cnt++;
7333}
7334
7335
7336/*---------------------------------------------------------------------
7337 *
7338 * Function: Queue Find SCCB
7339 *
7340 * Description: Search the target select Queue for this SCCB, and
7341 * remove it if found.
7342 *
7343 *---------------------------------------------------------------------*/
7344
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007345static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007346{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007347 struct sccb * q_ptr;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007348 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007349
James Bottomley 47b5d692005-04-24 02:38:05 -05007350 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007351
7352 q_ptr = currTar_Info->TarSelQ_Head;
7353
7354 while(q_ptr != NULL) {
7355
7356 if (q_ptr == p_SCCB) {
7357
7358
7359 if (currTar_Info->TarSelQ_Head == q_ptr) {
7360
7361 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7362 }
7363
7364 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7365
7366 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7367 }
7368
7369 if (q_ptr->Sccb_forwardlink != NULL) {
7370 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7371 }
7372
7373 if (q_ptr->Sccb_backlink != NULL) {
7374 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7375 }
7376
7377 currTar_Info->TarSelQ_Cnt--;
7378
James Bottomley 47b5d692005-04-24 02:38:05 -05007379 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007380 }
7381
7382 else {
7383 q_ptr = q_ptr->Sccb_forwardlink;
7384 }
7385 }
7386
7387
James Bottomley 47b5d692005-04-24 02:38:05 -05007388 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007389
7390}
7391
7392
7393/*---------------------------------------------------------------------
7394 *
7395 * Function: Utility Update Residual Count
7396 *
7397 * Description: Update the XferCnt to the remaining byte count.
7398 * If we transferred all the data then just write zero.
7399 * If Non-SG transfer then report Total Cnt - Actual Transfer
7400 * Cnt. For SG transfers add the count fields of all
7401 * remaining SG elements, as well as any partial remaining
7402 * element.
7403 *
7404 *---------------------------------------------------------------------*/
7405
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007406static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007407{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007408 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007409 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007410 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007411
7412 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7413
7414 p_SCCB->DataLength = 0x0000;
7415 }
7416
7417 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7418
7419 partial_cnt = 0x0000;
7420
7421 sg_index = p_SCCB->Sccb_sgseg;
7422
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007423 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007424
7425 if (p_SCCB->Sccb_SGoffset) {
7426
7427 partial_cnt = p_SCCB->Sccb_SGoffset;
7428 sg_index++;
7429 }
7430
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007431 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007432 p_SCCB->DataLength ) {
7433
7434 partial_cnt += *(sg_ptr+(sg_index * 2));
7435 sg_index++;
7436 }
7437
7438 p_SCCB->DataLength = partial_cnt;
7439 }
7440
7441 else {
7442
7443 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7444 }
7445}
7446
7447
7448/*---------------------------------------------------------------------
7449 *
7450 * Function: Wait 1 Second
7451 *
7452 * Description: Wait for 1 second.
7453 *
7454 *---------------------------------------------------------------------*/
7455
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007456static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007457{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007458 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007459
7460 for(i=0; i < 4; i++) {
7461
James Bottomley 47b5d692005-04-24 02:38:05 -05007462 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007463
7464 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7465 break;
7466
7467 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7468 break;
7469 }
7470}
7471
7472
7473/*---------------------------------------------------------------------
7474 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007475 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007476 *
7477 * Description: Wait the desired delay.
7478 *
7479 *---------------------------------------------------------------------*/
7480
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007481static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007482{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007483 unsigned char old_timer;
7484 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007485
7486 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7487
7488 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7489 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7490
7491 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7492 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007493 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007494
7495
7496 WR_HARPOON(p_port+hp_portctrl_0,
7497 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7498
7499 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7500
7501 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7502 break;
7503
7504 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7505 break;
7506 }
7507
7508 WR_HARPOON(p_port+hp_portctrl_0,
7509 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7510
7511 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007512 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007513
7514 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7515
7516 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7517}
7518
7519
7520/*---------------------------------------------------------------------
7521 *
7522 * Function: Enable/Disable Write to EEPROM
7523 *
7524 * Description: The EEPROM must first be enabled for writes
7525 * A total of 9 clocks are needed.
7526 *
7527 *---------------------------------------------------------------------*/
7528
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007529static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007530{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007531 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007532
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007533 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 -07007534
7535 if (p_mode)
7536
James Bottomley 47b5d692005-04-24 02:38:05 -05007537 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007538
7539 else
7540
7541
James Bottomley 47b5d692005-04-24 02:38:05 -05007542 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007543
7544 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7545 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7546}
7547
7548
7549/*---------------------------------------------------------------------
7550 *
7551 * Function: Write EEPROM
7552 *
7553 * Description: Write a word to the EEPROM at the specified
7554 * address.
7555 *
7556 *---------------------------------------------------------------------*/
7557
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007558static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007559{
7560
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007561 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007562 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007563
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007564 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 -07007565 (SEE_MS | SEE_CS));
7566
7567
7568
James Bottomley 47b5d692005-04-24 02:38:05 -05007569 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007570
7571
7572 ee_value |= (SEE_MS + SEE_CS);
7573
7574 for(i = 0x8000; i != 0; i>>=1) {
7575
7576 if (i & ee_data)
7577 ee_value |= SEE_DO;
7578 else
7579 ee_value &= ~SEE_DO;
7580
7581 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7582 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7583 ee_value |= SEE_CLK; /* Clock data! */
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 ee_value &= ~SEE_CLK;
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7589 }
7590 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7591 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7592
James Bottomley 47b5d692005-04-24 02:38:05 -05007593 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007594
7595 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7596 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7598}
7599
7600/*---------------------------------------------------------------------
7601 *
7602 * Function: Read EEPROM
7603 *
7604 * Description: Read a word from the EEPROM at the desired
7605 * address.
7606 *
7607 *---------------------------------------------------------------------*/
7608
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007609static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007610{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007611 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007612
7613 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007614 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007615 do
7616 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007617 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007618
7619 if(ee_data1 == ee_data2)
7620 return(ee_data1);
7621
7622 ee_data1 = ee_data2;
7623 i++;
7624
7625 }while(i < 4);
7626
7627 return(ee_data1);
7628}
7629
7630/*---------------------------------------------------------------------
7631 *
7632 * Function: Read EEPROM Original
7633 *
7634 * Description: Read a word from the EEPROM at the desired
7635 * address.
7636 *
7637 *---------------------------------------------------------------------*/
7638
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007639static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007640{
7641
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007642 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007643 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007644
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007645 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 -07007646 (SEE_MS | SEE_CS));
7647
7648
James Bottomley 47b5d692005-04-24 02:38:05 -05007649 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007650
7651
7652 ee_value |= (SEE_MS + SEE_CS);
7653 ee_data = 0;
7654
7655 for(i = 1; i <= 16; i++) {
7656
7657 ee_value |= SEE_CLK; /* Clock data! */
7658 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7659 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7660 ee_value &= ~SEE_CLK;
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7662 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7663
7664 ee_data <<= 1;
7665
7666 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7667 ee_data |= 1;
7668 }
7669
7670 ee_value &= ~(SEE_MS + SEE_CS);
7671 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7673
7674 return(ee_data);
7675}
7676
7677
7678/*---------------------------------------------------------------------
7679 *
7680 * Function: Send EE command and Address to the EEPROM
7681 *
7682 * Description: Transfers the correct command and sends the address
7683 * to the eeprom.
7684 *
7685 *---------------------------------------------------------------------*/
7686
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007687static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007688{
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007689 unsigned char ee_value;
7690 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007691
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007692 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007693
7694
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007695 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007696
7697
7698 ee_value = SEE_MS;
7699 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7700
7701 ee_value |= SEE_CS; /* Set CS to EEPROM */
7702 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7703
7704
7705 for(i = 0x04; i != 0; i>>=1) {
7706
7707 if (i & ee_cmd)
7708 ee_value |= SEE_DO;
7709 else
7710 ee_value &= ~SEE_DO;
7711
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 ee_value |= SEE_CLK; /* Clock data! */
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 ee_value &= ~SEE_CLK;
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7720 }
7721
7722
7723 if (narrow_flg)
7724 i = 0x0080;
7725
7726 else
7727 i = 0x0200;
7728
7729
7730 while (i != 0) {
7731
7732 if (i & ee_addr)
7733 ee_value |= SEE_DO;
7734 else
7735 ee_value &= ~SEE_DO;
7736
7737 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7738 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7739 ee_value |= SEE_CLK; /* Clock data! */
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 ee_value &= ~SEE_CLK;
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7745
7746 i >>= 1;
7747 }
7748}
7749
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007750static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007751{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007752 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007753 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007754 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007755 for (i=0; i < ID_STRING_LENGTH; i++)
7756 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007757 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007758 for(j=0; j < 8; j++)
7759 {
7760 if ((crc ^ ch) & 1)
7761 crc = (crc >> 1) ^ CRCMASK;
7762 else
7763 crc >>= 1;
7764 ch >>= 1;
7765 }
7766 }
7767 return(crc);
7768}
7769
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007770static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007771{
7772 int i;
Alexey Dobriyandb038cf82006-03-08 00:14:24 -08007773 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007774 lrc = 0;
7775 for(i = 0; i < ID_STRING_LENGTH; i++)
7776 lrc ^= buffer[i];
7777 return(lrc);
7778}
7779
7780
7781
7782/*
7783 The following inline definitions avoid type conflicts.
7784*/
7785
7786static inline unsigned char
7787FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7788{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007789 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007790}
7791
7792
7793static inline FlashPoint_CardHandle_T
7794FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7795{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007796 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007797}
7798
7799static inline void
7800FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7801{
7802 FlashPoint_ReleaseHostAdapter(CardHandle);
7803}
7804
7805
7806static inline void
7807FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7808{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007809 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007810}
7811
7812
7813static inline void
7814FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7815{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007816 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007817}
7818
7819
7820static inline boolean
7821FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7822{
7823 return FlashPoint_InterruptPending(CardHandle);
7824}
7825
7826
7827static inline int
7828FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7829{
7830 return FlashPoint_HandleInterrupt(CardHandle);
7831}
7832
7833
7834#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7835#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7836#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7837#define FlashPoint_StartCCB FlashPoint__StartCCB
7838#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7839#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7840#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7841
7842
Linus Torvalds1da177e2005-04-16 15:20:36 -07007843#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7844
7845
7846/*
7847 Define prototypes for the FlashPoint SCCB Manager Functions.
7848*/
7849
7850extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7851extern FlashPoint_CardHandle_T
7852 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7853extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7854extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7855extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7856extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7857extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007858
7859
7860#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */