blob: 37ee2cb60d20c0e05b4a2d3b4a2bfa0ece99dd38 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36#define CRCMASK 0xA001
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#define FAILURE 0xFFFFFFFFL
41
42
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080051#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080052#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
54
55
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -080056struct sccb;
57typedef void (*CALL_BK_FN)(struct sccb *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59
Alexey Dobriyan7f101662006-03-08 00:14:30 -080060struct sccb_mgr_info {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080061 unsigned long si_baseaddr;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080062 unsigned char si_present;
63 unsigned char si_intvect;
64 unsigned char si_id;
65 unsigned char si_lun;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -080066 unsigned short si_fw_revision;
67 unsigned short si_per_targ_init_sync;
68 unsigned short si_per_targ_fast_nego;
69 unsigned short si_per_targ_ultra_nego;
70 unsigned short si_per_targ_no_disc;
71 unsigned short si_per_targ_wide_nego;
72 unsigned short si_flags;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080073 unsigned char si_card_family;
74 unsigned char si_bustype;
75 unsigned char si_card_model[3];
76 unsigned char si_relative_cardnum;
77 unsigned char si_reserved[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080078 unsigned long si_OS_reserved;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -080079 unsigned char si_XlatInfo[4];
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -080080 unsigned long si_reserved2[5];
81 unsigned long si_secondary_range;
Alexey Dobriyan7f101662006-03-08 00:14:30 -080082};
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
85
James Bottomley 47b5d692005-04-24 02:38:05 -050086#define SCSI_PARITY_ENA 0x0001
87#define LOW_BYTE_TERM 0x0010
88#define HIGH_BYTE_TERM 0x0020
89#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
91#define SUPPORT_16TAR_32LUN 0x0002
92#define SOFT_RESET 0x0004
93#define EXTENDED_TRANSLATION 0x0008
94#define POST_ALL_UNDERRRUNS 0x0040
95#define FLAG_SCAM_ENABLED 0x0080
96#define FLAG_SCAM_LEVEL2 0x0100
97
98
99
100
101#define HARPOON_FAMILY 0x02
102
103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
Alexey Dobriyan323579882006-01-15 02:12:54 +0100105/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 * The UCB Manager treats the SCCB as it's 'native hardware structure'
107 */
108
109
110#pragma pack(1)
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800111struct sccb {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800112 unsigned char OperationCode;
113 unsigned char ControlByte;
114 unsigned char CdbLength;
115 unsigned char RequestSenseLength;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800116 unsigned long DataLength;
117 unsigned long DataPointer;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800118 unsigned char CcbRes[2];
119 unsigned char HostStatus;
120 unsigned char TargetStatus;
121 unsigned char TargID;
122 unsigned char Lun;
123 unsigned char Cdb[12];
124 unsigned char CcbRes1;
125 unsigned char Reserved1;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800126 unsigned long Reserved2;
127 unsigned long SensePointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
129
130 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800131 unsigned long SccbIOPort; /* Identifies board base port */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800132 unsigned char SccbStatus;
133 unsigned char SCCBRes2;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800134 unsigned short SccbOSFlags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800137 unsigned long Sccb_XferCnt; /* actual transfer count */
138 unsigned long Sccb_ATC;
139 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
140 unsigned long Sccb_res1;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800141 unsigned short Sccb_MGRFlags;
142 unsigned short Sccb_sgseg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800143 unsigned char Sccb_scsimsg; /* identify msg for selection */
144 unsigned char Sccb_tag;
145 unsigned char Sccb_scsistat;
146 unsigned char Sccb_idmsg; /* image of last msg in */
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800147 struct sccb * Sccb_forwardlink;
148 struct sccb * Sccb_backlink;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800149 unsigned long Sccb_savedATC;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800150 unsigned char Save_Cdb[6];
151 unsigned char Save_CdbLen;
152 unsigned char Sccb_XferState;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800153 unsigned long Sccb_SGoffset;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800154 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
157#pragma pack()
158
159
160
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161#define SCATTER_GATHER_COMMAND 0x02
162#define RESIDUAL_COMMAND 0x03
163#define RESIDUAL_SG_COMMAND 0x04
164#define RESET_COMMAND 0x81
165
166
167#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
168#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169#define SCCB_DATA_XFER_OUT 0x10 /* Write */
170#define SCCB_DATA_XFER_IN 0x08 /* Read */
171
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
174
175
176#define BUS_FREE_ST 0
177#define SELECT_ST 1
178#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
179#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
180#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
181#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
182#define COMMAND_ST 6
183#define DATA_OUT_ST 7
184#define DATA_IN_ST 8
185#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
188
189#define F_HOST_XFER_DIR 0x01
190#define F_ALL_XFERRED 0x02
191#define F_SG_XFER 0x04
192#define F_AUTO_SENSE 0x08
193#define F_ODD_BALL_CNT 0x10
194#define F_NO_DATA_YET 0x80
195
196
197#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198#define F_DEV_SELECTED 0x04
199
200
201#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
202#define SCCB_DATA_UNDER_RUN 0x0C
203#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
204#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
208#define SCCB_BM_ERR 0x30 /* BusMaster error. */
209#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
210
211
212
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213
214
215#define SCCB_IN_PROCESS 0x00
216#define SCCB_SUCCESS 0x01
217#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222#define ORION_FW_REV 3110
223
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224
225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230
James Bottomley 47b5d692005-04-24 02:38:05 -0500231#define MAX_SCSI_TAR 16
232#define MAX_LUN 32
233#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
237#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239
Alexey Dobriyanad0e1d92006-03-08 00:14:28 -0800240#define RD_HARPOON(ioport) inb((u32)ioport)
241#define RDW_HARPOON(ioport) inw((u32)ioport)
242#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
243#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
244#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
245#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247
248#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249#define SYNC_TRYING BIT(6)
250#define SYNC_SUPPORTED (BIT(7)+BIT(6))
251
252#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253#define WIDE_ENABLED BIT(4)
254#define WIDE_NEGOCIATED BIT(5)
255
256#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257#define TAG_Q_TRYING BIT(2)
258#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
260#define TAR_ALLOW_DISC BIT(0)
261
262
263#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264#define EE_SYNC_5MB BIT(0)
265#define EE_SYNC_10MB BIT(1)
266#define EE_SYNC_20MB (BIT(0)+BIT(1))
267
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268#define EE_WIDE_SCSI BIT(7)
269
270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272
Alexey 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 Dobriyandb038cf2006-03-08 00:14:24 -0800277 unsigned char TarLUN_CA; /*Contingent Allgiance */
278 unsigned char TarTagQ_Cnt;
279 unsigned char TarSelQ_Cnt;
280 unsigned char TarStatus;
281 unsigned char TarEEValue;
282 unsigned char TarSyncCtrl;
283 unsigned char TarReserved[2]; /* for alignment */
284 unsigned char LunDiscQ_Idx[MAX_LUN];
285 unsigned char TarLUNBusy[MAX_LUN];
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -0800286};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800288struct nvram_info {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800289 unsigned char niModel; /* Model No. of card */
290 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800291 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800292 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
293 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
294 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
295 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
296 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
297 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800298};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
301#define MODEL_LT 1
302#define MODEL_DL 2
303#define MODEL_LW 3
304#define MODEL_DW 4
305
306
Alexey Dobriyan13e68512006-03-08 00:14:34 -0800307struct sccb_card {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800308 struct sccb * currentSCCB;
Alexey Dobriyan7f101662006-03-08 00:14:30 -0800309 struct sccb_mgr_info * cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800311 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800313 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800314 unsigned char discQCount;
315 unsigned char tagQ_Lst;
316 unsigned char cardIndex;
317 unsigned char scanIndex;
318 unsigned char globalFlags;
319 unsigned char ourId;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800320 struct nvram_info * pNvRamInfo;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800321 struct sccb * discQ_Tbl[QUEUE_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
Alexey Dobriyan13e68512006-03-08 00:14:34 -0800323};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
326
327#define F_TAG_STARTED 0x01
328#define F_CONLUN_IO 0x02
329#define F_DO_RENEGO 0x04
330#define F_NO_FILTER 0x08
331#define F_GREEN_PC 0x10
332#define F_HOST_XFER_ACT 0x20
333#define F_NEW_SCCB_CMD 0x40
334#define F_UPDATE_EEPROM 0x80
335
336
337#define ID_STRING_LENGTH 32
338#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340
341#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
342
343#define ASSIGN_ID 0x00
344#define SET_P_FLAG 0x01
345#define CFG_CMPLT 0x03
346#define DOM_MSTR 0x0F
347#define SYNC_PTRN 0x1F
348
349#define ID_0_7 0x18
350#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351#define MISC_CODE 0x14
352#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355
356#define INIT_SELTD 0x01
357#define LEVEL2_TAR 0x02
358
359
360enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
361 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
362 CLR_PRIORITY,NO_ID_AVAIL };
363
364typedef struct SCCBscam_info {
365
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800366 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 enum scam_id_st state;
368
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800369} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373#define SCSI_READ 0x08
374#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376#define SCSI_READ_EXTENDED 0x28
377#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
380
381
382#define SSGOOD 0x00
383#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384#define SSQ_FULL 0x28
385
386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
388
389#define SMCMD_COMP 0x00
390#define SMEXT 0x01
391#define SMSAVE_DATA_PTR 0x02
392#define SMREST_DATA_PTR 0x03
393#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394#define SMABORT 0x06
395#define SMREJECT 0x07
396#define SMNO_OP 0x08
397#define SMPARITY 0x09
398#define SMDEV_RESET 0x0C
399#define SMABORT_TAG 0x0D
400#define SMINIT_RECOVERY 0x0F
401#define SMREL_RECOVERY 0x10
402
403#define SMIDENT 0x80
404#define DISC_PRIV 0x40
405
406
407#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408#define SMWDTR 0x03
409#define SM8BIT 0x00
410#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411#define SMIGNORWR 0x23 /* Ignore Wide Residue */
412
413
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
415
416
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418
419
420#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421#define TWELVE_BYTE_CMD 0x0C
422
423#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
425
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427#define EEPROM_WD_CNT 256
428
429#define EEPROM_CHECK_SUM 0
430#define FW_SIGNATURE 2
431#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434#define SYSTEM_CONFIG 16
435#define SCSI_CONFIG 17
436#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437#define SCAM_CONFIG 20
438#define ADAPTER_SCSI_ID 24
439
440
441#define IGNORE_B_SCAN 32
442#define SEND_START_ENA 34
443#define DEVICE_ENABLE 36
444
445#define SYNC_RATE_TBL 38
446#define SYNC_RATE_TBL01 38
447#define SYNC_RATE_TBL23 40
448#define SYNC_RATE_TBL45 42
449#define SYNC_RATE_TBL67 44
450#define SYNC_RATE_TBL89 46
451#define SYNC_RATE_TBLab 48
452#define SYNC_RATE_TBLcd 50
453#define SYNC_RATE_TBLef 52
454
455
456
457#define EE_SCAMBASE 256
458
459
460
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 #define SCAM_ENABLED BIT(2)
462 #define SCAM_LEVEL2 BIT(3)
463
464
465 #define RENEGO_ENA BITW(10)
466 #define CONNIO_ENA BITW(11)
467 #define GREEN_PC_ENA BITW(12)
468
469
470 #define AUTO_RATE_00 00
471 #define AUTO_RATE_05 01
472 #define AUTO_RATE_10 02
473 #define AUTO_RATE_20 03
474
475 #define WIDE_NEGO_BIT BIT(7)
476 #define DISC_ENABLE_BIT BIT(6)
477
478
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
480 #define hp_vendor_id_0 0x00 /* LSB */
481 #define ORION_VEND_0 0x4B
482
483 #define hp_vendor_id_1 0x01 /* MSB */
484 #define ORION_VEND_1 0x10
485
486 #define hp_device_id_0 0x02 /* LSB */
487 #define ORION_DEV_0 0x30
488
489 #define hp_device_id_1 0x03 /* MSB */
490 #define ORION_DEV_1 0x81
491
492 /* Sub Vendor ID and Sub Device ID only available in
493 Harpoon Version 2 and higher */
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499 #define hp_semaphore 0x0C
500 #define SCCB_MGR_ACTIVE BIT(0)
501 #define TICKLE_ME BIT(1)
502 #define SCCB_MGR_PRESENT BIT(3)
503 #define BIOS_IN_USE BIT(4)
504
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
507 #define hp_sys_ctrl 0x0F
508
509 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
510 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
511 #define HALT_MACH BIT(3) /*Halt State Machine */
512 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513
514
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800518
519
520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
522 #define hp_host_blk_cnt 0x13
523
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
525
526 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
527
528
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529
530 #define hp_int_mask 0x17
531
532 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
533 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534
535
536 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 #define hp_xfer_cnt_hi 0x1A
538 #define hp_xfer_cmd 0x1B
539
540 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
541 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
543
544 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
546 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
549
550 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
551 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552
553 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 #define hp_ee_ctrl 0x22
557
558 #define EXT_ARB_ACK BIT(7)
559 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
560 #define SEE_MS BIT(5)
561 #define SEE_CS BIT(3)
562 #define SEE_CLK BIT(2)
563 #define SEE_DO BIT(1)
564 #define SEE_DI BIT(0)
565
566 #define EE_READ 0x06
567 #define EE_WRITE 0x05
568 #define EWEN 0x04
569 #define EWEN_ADDR 0x03C0
570 #define EWDS 0x04
571 #define EWDS_ADDR 0x0000
572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
576
577
578
579 #define hp_bm_ctrl 0x26
580
581 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
582 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
584 #define FAST_SINGLE BIT(6) /*?? */
585
586 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
589 #define hp_sg_addr 0x28
590 #define hp_page_ctrl 0x29
591
592 #define SCATTER_EN BIT(0)
593 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
595 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
600 #define hp_pci_stat_cfg 0x2D
601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
611 #define hp_rev_num 0x33
612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 #define hp_stack_data 0x34
615 #define hp_stack_addr 0x35
616
617 #define hp_ext_status 0x36
618
619 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
620 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
621 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 #define CMD_ABORTED BIT(4) /*Command aborted */
623 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
624 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
625 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
626 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
627 BM_PARITY_ERR | PIO_OVERRUN)
628
629 #define hp_int_status 0x37
630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
632 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635
636 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
639
640
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 #define hp_intena 0x40
642
643 #define RESET BITW(7)
644 #define PROG_HLT BITW(6)
645 #define PARITY BITW(5)
646 #define FIFO BITW(4)
647 #define SEL BITW(3)
648 #define SCAM_SEL BITW(2)
649 #define RSEL BITW(1)
650 #define TIMEOUT BITW(0)
651 #define BUS_FREE BITW(15)
652 #define XFER_CNT_0 BITW(14)
653 #define PHASE BITW(13)
654 #define IUNKWN BITW(12)
655 #define ICMD_COMP BITW(11)
656 #define ITICKLE BITW(10)
657 #define IDO_STRT BITW(9)
658 #define ITAR_DISC BITW(8)
659 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
660 #define CLR_ALL_INT 0xFFFF
661 #define CLR_ALL_INT_1 0xFF00
662
663 #define hp_intstat 0x42
664
665 #define hp_scsisig 0x44
666
667 #define SCSI_SEL BIT(7)
668 #define SCSI_BSY BIT(6)
669 #define SCSI_REQ BIT(5)
670 #define SCSI_ACK BIT(4)
671 #define SCSI_ATN BIT(3)
672 #define SCSI_CD BIT(2)
673 #define SCSI_MSG BIT(1)
674 #define SCSI_IOBIT BIT(0)
675
676 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
679 #define S_DATAI_PH ( BIT(0))
680 #define S_DATAO_PH 0x00
681 #define S_ILL_PH ( BIT(1) )
682
683 #define hp_scsictrl_0 0x45
684
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 #define SEL_TAR BIT(6)
686 #define ENA_ATN BIT(4)
687 #define ENA_RESEL BIT(2)
688 #define SCSI_RST BIT(1)
689 #define ENA_SCAM_SEL BIT(0)
690
691
692
693 #define hp_portctrl_0 0x46
694
695 #define SCSI_PORT BIT(7)
696 #define SCSI_INBIT BIT(6)
697 #define DMA_PORT BIT(5)
698 #define DMA_RD BIT(4)
699 #define HOST_PORT BIT(3)
700 #define HOST_WRT BIT(2)
701 #define SCSI_BUS_EN BIT(1)
702 #define START_TO BIT(0)
703
704 #define hp_scsireset 0x47
705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 #define SCSI_INI BIT(6)
707 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 #define DMA_RESET BIT(3)
709 #define HPSCSI_RESET BIT(2)
710 #define PROG_RESET BIT(1)
711 #define FIFO_CLR BIT(0)
712
713 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715
716 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 #define hp_addstat 0x4E
718
719 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 #define SCSI_MODE8 BIT(3)
721 #define SCSI_PAR_ERR BIT(0)
722
723 #define hp_prgmcnt_0 0x4F
724
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725
726 #define hp_selfid_0 0x50
727 #define hp_selfid_1 0x51
728 #define hp_arb_id 0x52
729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 #define hp_select_id 0x53
732
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
734 #define hp_synctarg_base 0x54
735 #define hp_synctarg_12 0x54
736 #define hp_synctarg_13 0x55
737 #define hp_synctarg_14 0x56
738 #define hp_synctarg_15 0x57
739
740 #define hp_synctarg_8 0x58
741 #define hp_synctarg_9 0x59
742 #define hp_synctarg_10 0x5A
743 #define hp_synctarg_11 0x5B
744
745 #define hp_synctarg_4 0x5C
746 #define hp_synctarg_5 0x5D
747 #define hp_synctarg_6 0x5E
748 #define hp_synctarg_7 0x5F
749
750 #define hp_synctarg_0 0x60
751 #define hp_synctarg_1 0x61
752 #define hp_synctarg_2 0x62
753 #define hp_synctarg_3 0x63
754
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 #define DEFAULT_OFFSET 0x0F
757
758 #define hp_autostart_0 0x64
759 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 #define hp_autostart_3 0x67
761
762
763
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 #define AUTO_IMMED BIT(5)
765 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767
768 #define hp_gp_reg_0 0x68
769 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770 #define hp_gp_reg_3 0x6B
771
772 #define hp_seltimeout 0x6C
773
774
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 #define TO_4ms 0x67 /* 3.9959ms */
776
777 #define TO_5ms 0x03 /* 4.9152ms */
778 #define TO_10ms 0x07 /* 11.xxxms */
779 #define TO_250ms 0x99 /* 250.68ms */
780 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
782 #define hp_clkctrl_0 0x6D
783
784 #define PWR_DWN BIT(6)
785 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
788 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
789
790 #define hp_fiforead 0x6E
791 #define hp_fifowrite 0x6F
792
793 #define hp_offsetctr 0x70
794 #define hp_xferstat 0x71
795
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
798 #define hp_portctrl_1 0x72
799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 #define CHK_SCSI_P BIT(3)
801 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 #define hp_xfer_pad 0x73
804
805 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806
807 #define hp_scsidata_0 0x74
808 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 #define hp_aramBase 0x80
813 #define BIOS_DATA_OFFSET 0x60
814 #define BIOS_RELATIVE_CARD 0x64
815
816
817
818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 #define AR3 (BITW(9) + BITW(8))
820 #define SDATA BITW(10)
821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
824
825 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828
829 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
830
831 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
832
833
834 #define ADATA_OUT 0x00
835 #define ADATA_IN BITW(8)
836 #define ACOMMAND BITW(10)
837 #define ASTATUS (BITW(10)+BITW(8))
838 #define AMSG_OUT (BITW(10)+BITW(9))
839 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840
841
842 #define BRH_OP BITW(13) /* Branch */
843
844
845 #define ALWAYS 0x00
846 #define EQUAL BITW(8)
847 #define NOT_EQ BITW(9)
848
849 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
850
851
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853
854
855 #define MPM_OP BITW(15) /* Match phase and move data */
856
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857
858 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
859
860
861 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
862
863
864 #define D_AR0 0x00
865 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
867
868
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
875
876 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
877
878 #define SSI_OP (BITW(15)+BITW(11))
879
880
881 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
882 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883
884 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
885 #define SSI_ITICKLE (ITICKLE >> 8)
886
887 #define SSI_IUNKWN (IUNKWN >> 8)
888 #define SSI_INO_CC (IUNKWN >> 8)
889 #define SSI_IRFAIL (IUNKWN >> 8)
890
891
892 #define NP 0x10 /*Next Phase */
893 #define NTCMD 0x02 /*Non- Tagged Command start */
894 #define CMDPZ 0x04 /*Command phase */
895 #define DINT 0x12 /*Data Out/In interrupt */
896 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 #define DC 0x19 /*Disconnect Message */
898 #define ST 0x1D /*Status Phase */
899 #define UNKNWN 0x24 /*Unknown bus action */
900 #define CC 0x25 /*Command Completion failure */
901 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
903
904
905 #define ID_MSG_STRT hp_aramBase + 0x00
906 #define NON_TAG_ID_MSG hp_aramBase + 0x06
907 #define CMD_STRT hp_aramBase + 0x08
908 #define SYNC_MSGS hp_aramBase + 0x08
909
910
911
912
913
914 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 #define DISCONNECT_START 0x10/2
916 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 #define SELCHK_STRT SELCHK/2
919
920
921
922
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923
924
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800926
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
928#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
929/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
930 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800931 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800933#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 -0700934 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800935 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800937 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 count >>= 16,\
939 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
941#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
942 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
943
944
945#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
946 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
947
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
950#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
951 WR_HARPOON(port+hp_scsireset, 0x00))
952
953#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
954 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
955
956#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
957 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
958
959#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
960 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
961
962#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
963 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
964
965
966
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800968static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
969static void FPT_ssel(unsigned long port, unsigned char p_card);
Alexey Dobriyan13e68512006-03-08 00:14:34 -0800970static void FPT_sres(unsigned long port, unsigned char p_card, struct sccb_card * pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800971static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800972static void FPT_stsyncn(unsigned long port, unsigned char p_card);
973static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
974static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -0800975 struct sccb_mgr_tar_info * currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800976static void FPT_sresb(unsigned long port, unsigned char p_card);
977static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
978static void FPT_schkdd(unsigned long port, unsigned char p_card);
979static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
980static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
981static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800983static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800984static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
985 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800987static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -0800988static void FPT_RNVRamData(struct nvram_info * pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800990static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
991static void FPT_stwidn(unsigned long port, unsigned char p_card);
992static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
994
Alexey Dobriyan13e68512006-03-08 00:14:34 -0800995static void FPT_queueSelectFail(struct sccb_card * pCurrCard, unsigned char p_card);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800996static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
Alexey Dobriyan13e68512006-03-08 00:14:34 -0800997static void FPT_queueCmdComplete(struct sccb_card * pCurrCard, struct sccb * p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800998 unsigned char p_card);
Alexey Dobriyan13e68512006-03-08 00:14:34 -0800999static void FPT_queueSearchSelect(struct sccb_card * pCurrCard, unsigned char p_card);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001000static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001001static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1002static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1003static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001004static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001005static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006
1007
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001008static void FPT_Wait1Second(unsigned long p_port);
1009static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1010static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1011static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1012static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1013static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1014static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016
1017
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001018static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1019static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1020static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1021static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1022static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1023static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1024static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001026static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1027static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1028static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
1030
1031
1032
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001033static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1034static void FPT_BusMasterInit(unsigned long p_port);
1035static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
1037
1038
1039
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001040static void FPT_dataXferProcessor(unsigned long port, struct sccb_card * pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001041static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1042static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1043static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1044static void FPT_hostDataXferRestart(struct sccb * currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001047static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001048 struct sccb_card * pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
James Bottomley 47b5d692005-04-24 02:38:05 -05001050static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001051static void FPT_SccbMgrTableInitCard(struct sccb_card * pCurrCard, unsigned char p_card);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001052static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
1054
1055
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001056static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001058static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1059static void FPT_scbusf(unsigned long p_port);
1060static void FPT_scsel(unsigned long p_port);
1061static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1062static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1063static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1064static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1065static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1066static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001067static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001068static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1069static void FPT_scwtsel(unsigned long p_port);
1070static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1071static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001072static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073
1074
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001075static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1076static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078
1079
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08001081static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001082static struct sccb_card FPT_BL_Card[MAX_CARDS] = { { 0 } };
James Bottomley 47b5d692005-04-24 02:38:05 -05001083static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001084static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
1086
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001087static unsigned char FPT_mbCards = 0;
1088static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001089 ' ', 'B', 'T', '-', '9', '3', '0', \
1090 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1091 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001093static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
1095
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001096static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
1099/*---------------------------------------------------------------------
1100 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001101 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 *
1103 * Description: Setup and/or Search for cards and return info to caller.
1104 *
1105 *---------------------------------------------------------------------*/
1106
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001107static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001109 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001111 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001112 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001113 unsigned long ioport;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001114 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118
1119 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1120 return((int)FAILURE);
1121
1122 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1123 return((int)FAILURE);
1124
1125 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1126 return((int)FAILURE);
1127
1128 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1129 return((int)FAILURE);
1130
1131
1132 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1133
1134/* For new Harpoon then check for sub_device ID LSB
1135 the bits(0-3) must be all ZERO for compatible with
1136 current version of SCCBMgr, else skip this Harpoon
1137 device. */
1138
1139 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1140 return((int)FAILURE);
1141 }
1142
1143 if (first_time)
1144 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001145 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001147 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 }
1149
James Bottomley 47b5d692005-04-24 02:38:05 -05001150 if(FPT_RdStack(ioport, 0) != 0x00) {
1151 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 {
1153 pCurrNvRam = NULL;
1154 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001155 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1156 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 }
1158 else
1159 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001160 if(FPT_mbCards < MAX_MB_CARDS) {
1161 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1162 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001164 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 }else
1166 return((int) FAILURE);
1167 }
1168 }else
1169 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
1171 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1172 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1173
1174 if(pCurrNvRam)
1175 pCardInfo->si_id = pCurrNvRam->niAdapId;
1176 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001177 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1178 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179
1180 pCardInfo->si_lun = 0x00;
1181 pCardInfo->si_fw_revision = ORION_FW_REV;
1182 temp2 = 0x0000;
1183 temp3 = 0x0000;
1184 temp4 = 0x0000;
1185 temp5 = 0x0000;
1186 temp6 = 0x0000;
1187
1188 for (id = 0; id < (16/2); id++) {
1189
1190 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001191 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1193 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1194 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001195 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
1197 for (i = 0; i < 2; temp >>=8,i++) {
1198
1199 temp2 >>= 1;
1200 temp3 >>= 1;
1201 temp4 >>= 1;
1202 temp5 >>= 1;
1203 temp6 >>= 1;
1204 switch (temp & 0x3)
1205 {
1206 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1207 temp6 |= 0x8000; /* Fall through */
1208 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1209 temp5 |= 0x8000; /* Fall through */
1210 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1211 temp2 |= 0x8000; /* Fall through */
1212 case AUTO_RATE_00: /* Asynchronous */
1213 break;
1214 }
1215
1216 if (temp & DISC_ENABLE_BIT)
1217 temp3 |= 0x8000;
1218
1219 if (temp & WIDE_NEGO_BIT)
1220 temp4 |= 0x8000;
1221
1222 }
1223 }
1224
1225 pCardInfo->si_per_targ_init_sync = temp2;
1226 pCardInfo->si_per_targ_no_disc = temp3;
1227 pCardInfo->si_per_targ_wide_nego = temp4;
1228 pCardInfo->si_per_targ_fast_nego = temp5;
1229 pCardInfo->si_per_targ_ultra_nego = temp6;
1230
1231 if(pCurrNvRam)
1232 i = pCurrNvRam->niSysConf;
1233 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001234 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
1236 if(pCurrNvRam)
1237 ScamFlg = pCurrNvRam->niScamConf;
1238 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001239 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
1241 pCardInfo->si_flags = 0x0000;
1242
1243 if (i & 0x01)
1244 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1245
1246 if (!(i & 0x02))
1247 pCardInfo->si_flags |= SOFT_RESET;
1248
1249 if (i & 0x10)
1250 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1251
1252 if (ScamFlg & SCAM_ENABLED)
1253 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1254
1255 if (ScamFlg & SCAM_LEVEL2)
1256 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1257
1258 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1259 if (i & 0x04) {
1260 j |= SCSI_TERM_ENA_L;
1261 }
1262 WR_HARPOON(ioport+hp_bm_ctrl, j );
1263
1264 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1265 if (i & 0x08) {
1266 j |= SCSI_TERM_ENA_H;
1267 }
1268 WR_HARPOON(ioport+hp_ee_ctrl, j );
1269
1270 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1271
1272 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1273
1274 pCardInfo->si_card_family = HARPOON_FAMILY;
1275 pCardInfo->si_bustype = BUSTYPE_PCI;
1276
1277 if(pCurrNvRam){
1278 pCardInfo->si_card_model[0] = '9';
1279 switch(pCurrNvRam->niModel & 0x0f){
1280 case MODEL_LT:
1281 pCardInfo->si_card_model[1] = '3';
1282 pCardInfo->si_card_model[2] = '0';
1283 break;
1284 case MODEL_LW:
1285 pCardInfo->si_card_model[1] = '5';
1286 pCardInfo->si_card_model[2] = '0';
1287 break;
1288 case MODEL_DL:
1289 pCardInfo->si_card_model[1] = '3';
1290 pCardInfo->si_card_model[2] = '2';
1291 break;
1292 case MODEL_DW:
1293 pCardInfo->si_card_model[1] = '5';
1294 pCardInfo->si_card_model[2] = '2';
1295 break;
1296 }
1297 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001298 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001299 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001300 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001302 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1303 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 }
1305
1306 if (pCardInfo->si_card_model[1] == '3')
1307 {
1308 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1309 pCardInfo->si_flags |= LOW_BYTE_TERM;
1310 }
1311 else if (pCardInfo->si_card_model[2] == '0')
1312 {
1313 temp = RD_HARPOON(ioport+hp_xfer_pad);
1314 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1315 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1316 pCardInfo->si_flags |= LOW_BYTE_TERM;
1317 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1318 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1319 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1320 WR_HARPOON(ioport+hp_xfer_pad, temp);
1321 }
1322 else
1323 {
1324 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1325 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1326 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1327 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1328 temp3 = 0;
1329 for (i = 0; i < 8; i++)
1330 {
1331 temp3 <<= 1;
1332 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1333 temp3 |= 1;
1334 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1335 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1336 }
1337 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1338 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1339 if (!(temp3 & BIT(7)))
1340 pCardInfo->si_flags |= LOW_BYTE_TERM;
1341 if (!(temp3 & BIT(6)))
1342 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1343 }
1344
1345
1346 ARAM_ACCESS(ioport);
1347
1348 for ( i = 0; i < 4; i++ ) {
1349
1350 pCardInfo->si_XlatInfo[i] =
1351 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1352 }
1353
1354 /* return with -1 if no sort, else return with
1355 logical card number sorted by BIOS (zero-based) */
1356
1357 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001358 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
1360 SGRAM_ACCESS(ioport);
1361
James Bottomley 47b5d692005-04-24 02:38:05 -05001362 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1363 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1364 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1365 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1366 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1367 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1368 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1369 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370
1371 pCardInfo->si_present = 0x01;
1372
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 return(0);
1374}
1375
1376
1377/*---------------------------------------------------------------------
1378 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001379 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 *
1381 * Description: Setup adapter for normal operation (hard reset).
1382 *
1383 *---------------------------------------------------------------------*/
1384
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001385static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386{
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001387 struct sccb_card * CurrCard = NULL;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001388 struct nvram_info * pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001389 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001390 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001391 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
1395 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1396
1397 if (thisCard == MAX_CARDS) {
1398
1399 return(FAILURE);
1400 }
1401
James Bottomley 47b5d692005-04-24 02:38:05 -05001402 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
James Bottomley 47b5d692005-04-24 02:38:05 -05001404 CurrCard = &FPT_BL_Card[thisCard];
1405 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 break;
1407 }
1408
James Bottomley 47b5d692005-04-24 02:38:05 -05001409 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
James Bottomley 47b5d692005-04-24 02:38:05 -05001411 FPT_BL_Card[thisCard].ioPort = ioport;
1412 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413
James Bottomley 47b5d692005-04-24 02:38:05 -05001414 if(FPT_mbCards)
1415 for(i = 0; i < FPT_mbCards; i++){
1416 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1417 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001419 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 CurrCard->cardIndex = thisCard;
1421 CurrCard->cardInfo = pCardInfo;
1422
1423 break;
1424 }
1425 }
1426
1427 pCurrNvRam = CurrCard->pNvRamInfo;
1428
1429 if(pCurrNvRam){
1430 ScamFlg = pCurrNvRam->niScamConf;
1431 }
1432 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001433 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 }
1435
1436
James Bottomley 47b5d692005-04-24 02:38:05 -05001437 FPT_BusMasterInit(ioport);
1438 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439
James Bottomley 47b5d692005-04-24 02:38:05 -05001440 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442
1443 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1444
1445 WR_HARPOON(ioport+hp_selfid_0, id);
1446 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1447 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1448 CurrCard->ourId = pCardInfo->si_id;
1449
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001450 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 if (i & SCSI_PARITY_ENA)
1452 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1453
1454 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1455 if (i & LOW_BYTE_TERM)
1456 j |= SCSI_TERM_ENA_L;
1457 WR_HARPOON(ioport+hp_bm_ctrl, j);
1458
1459 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1460 if (i & HIGH_BYTE_TERM)
1461 j |= SCSI_TERM_ENA_H;
1462 WR_HARPOON(ioport+hp_ee_ctrl, j );
1463
1464
1465 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1466
James Bottomley 47b5d692005-04-24 02:38:05 -05001467 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
James Bottomley 47b5d692005-04-24 02:38:05 -05001469 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 }
1471
1472
1473
1474 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1475 CurrCard->globalFlags |= F_NO_FILTER;
1476
1477 if(pCurrNvRam){
1478 if(pCurrNvRam->niSysConf & 0x10)
1479 CurrCard->globalFlags |= F_GREEN_PC;
1480 }
1481 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001482 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 CurrCard->globalFlags |= F_GREEN_PC;
1484 }
1485
1486 /* Set global flag to indicate Re-Negotiation to be done on all
1487 ckeck condition */
1488 if(pCurrNvRam){
1489 if(pCurrNvRam->niScsiConf & 0x04)
1490 CurrCard->globalFlags |= F_DO_RENEGO;
1491 }
1492 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001493 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 CurrCard->globalFlags |= F_DO_RENEGO;
1495 }
1496
1497 if(pCurrNvRam){
1498 if(pCurrNvRam->niScsiConf & 0x08)
1499 CurrCard->globalFlags |= F_CONLUN_IO;
1500 }
1501 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001502 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 CurrCard->globalFlags |= F_CONLUN_IO;
1504 }
1505
1506
1507 temp = pCardInfo->si_per_targ_no_disc;
1508
1509 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1510
1511 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001512 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 }
1514
1515 sync_bit_map = 0x0001;
1516
1517 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1518
1519 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001520 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1522 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1523 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001524 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525
1526 for (i = 0; i < 2; temp >>=8,i++) {
1527
1528 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1529
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001530 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 }
1532
1533 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001534 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1535 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001536 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 }
1538
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1540 (id*2+i >= 8)){
1541*/
1542 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1543
James Bottomley 47b5d692005-04-24 02:38:05 -05001544 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545
1546 }
1547
1548 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001549 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 }
1551
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552
1553 sync_bit_map <<= 1;
1554
1555
1556
1557 }
1558 }
1559
1560 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001561 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001563 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564}
1565
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001566static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001568 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001569 unsigned long portBase;
1570 unsigned long regOffset;
1571 unsigned long scamData;
1572 unsigned long *pScamTbl;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001573 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001575 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
1577 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001578 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1579 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1580 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001585 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
1587 portBase = pCurrNvRam->niBaseAddr;
1588
1589 for(i = 0; i < MAX_SCSI_TAR; i++){
1590 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001591 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 scamData = *pScamTbl;
1593 WR_HARP32(portBase, regOffset, scamData);
1594 }
1595
1596 }else{
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001597 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 }
1599}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
1601
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08001602static void FPT_RNVRamData(struct nvram_info * pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001604 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001605 unsigned long portBase;
1606 unsigned long regOffset;
1607 unsigned long scamData;
1608 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609
James Bottomley 47b5d692005-04-24 02:38:05 -05001610 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1611 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1612 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1613 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1614 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
1616 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001617 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618
1619 portBase = pNvRamInfo->niBaseAddr;
1620
1621 for(i = 0; i < MAX_SCSI_TAR; i++){
1622 regOffset = hp_aramBase + 64 + i*4;
1623 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001624 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 *pScamTbl = scamData;
1626 }
1627
1628}
1629
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001630static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631{
1632 WR_HARPOON(portBase + hp_stack_addr, index);
1633 return(RD_HARPOON(portBase + hp_stack_data));
1634}
1635
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001636static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637{
1638 WR_HARPOON(portBase + hp_stack_addr, index);
1639 WR_HARPOON(portBase + hp_stack_data, data);
1640}
1641
1642
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001643static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644{
James Bottomley 47b5d692005-04-24 02:38:05 -05001645 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1646 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1648 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001649 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1651 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001652 return(1);
1653 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
1655}
1656/*---------------------------------------------------------------------
1657 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001658 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 *
1660 * Description: Start a command pointed to by p_Sccb. When the
1661 * command is completed it will be returned via the
1662 * callback function.
1663 *
1664 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001665static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001667 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001668 unsigned char thisCard, lun;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001669 struct sccb * pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 CALL_BK_FN callback;
1671
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001672 thisCard = ((struct sccb_card *) pCurrCard)->cardIndex;
1673 ioport = ((struct sccb_card *) pCurrCard)->ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1676 {
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 p_Sccb->HostStatus = SCCB_COMPLETE;
1679 p_Sccb->SccbStatus = SCCB_ERROR;
1680 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1681 if (callback)
1682 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 return;
1685 }
1686
James Bottomley 47b5d692005-04-24 02:38:05 -05001687 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001690 if (!((struct sccb_card *) pCurrCard)->cmdCounter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 {
1692 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1693 | SCCB_MGR_ACTIVE));
1694
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001695 if (((struct sccb_card *) pCurrCard)->globalFlags & F_GREEN_PC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 {
1697 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1698 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1699 }
1700 }
1701
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001702 ((struct sccb_card *)pCurrCard)->cmdCounter++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
1704 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1705
1706 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1707 | TICKLE_ME));
1708 if(p_Sccb->OperationCode == RESET_COMMAND)
1709 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001710 pSaveSccb = ((struct sccb_card *) pCurrCard)->currentSCCB;
1711 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001712 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001713 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 }
1715 else
1716 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001717 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 }
1719 }
1720
1721 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1722
1723 if(p_Sccb->OperationCode == RESET_COMMAND)
1724 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001725 pSaveSccb = ((struct sccb_card *) pCurrCard)->currentSCCB;
1726 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001727 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001728 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 }
1730 else
1731 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001732 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 }
1734 }
1735
1736 else {
1737
1738 MDISABLE_INT(ioport);
1739
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001740 if((((struct sccb_card *) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001741 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 lun = p_Sccb->Lun;
1743 else
1744 lun = 0;
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001745 if ((((struct sccb_card *) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001746 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1747 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1748 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001750 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001751 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 }
1753
1754 else {
1755
1756 if(p_Sccb->OperationCode == RESET_COMMAND)
1757 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001758 pSaveSccb = ((struct sccb_card *) pCurrCard)->currentSCCB;
1759 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001760 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001761 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 }
1763 else
1764 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001765 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 }
1767 }
1768
1769
1770 MENABLE_INT(ioport);
1771 }
1772
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773}
1774
1775
1776/*---------------------------------------------------------------------
1777 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001778 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 *
1780 * Description: Abort the command pointed to by p_Sccb. When the
1781 * command is completed it will be returned via the
1782 * callback function.
1783 *
1784 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001785static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001787 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001789 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001791 unsigned char TID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001792 struct sccb * pSaveSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08001793 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
1795
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001796 ioport = ((struct sccb_card *) pCurrCard)->ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001798 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
James Bottomley 47b5d692005-04-24 02:38:05 -05001800 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 {
1802
James Bottomley 47b5d692005-04-24 02:38:05 -05001803 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 {
1805
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001806 ((struct sccb_card *)pCurrCard)->cmdCounter--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001808 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001810 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 p_Sccb->SccbStatus = SCCB_ABORT;
1813 callback = p_Sccb->SccbCallback;
1814 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
1816 return(0);
1817 }
1818
1819 else
1820 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001821 if (((struct sccb_card *)pCurrCard)->currentSCCB == p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 {
1823 p_Sccb->SccbStatus = SCCB_ABORT;
1824 return(0);
1825
1826 }
1827
1828 else
1829 {
1830
1831 TID = p_Sccb->TargID;
1832
1833
1834 if(p_Sccb->Sccb_tag)
1835 {
1836 MDISABLE_INT(ioport);
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001837 if (((struct sccb_card *) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 {
1839 p_Sccb->SccbStatus = SCCB_ABORT;
1840 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1842
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001843 if(((struct sccb_card *) pCurrCard)->currentSCCB == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001845 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001846 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 }
1848 else
1849 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001850 pSaveSCCB = ((struct sccb_card *) pCurrCard)->currentSCCB;
1851 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1852 FPT_queueSelectFail((struct sccb_card *) pCurrCard, thisCard);
1853 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 }
1855 }
1856 MENABLE_INT(ioport);
1857 return(0);
1858 }
1859 else
1860 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001861 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
James Bottomley 47b5d692005-04-24 02:38:05 -05001863 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 == p_Sccb)
1865 {
1866 p_Sccb->SccbStatus = SCCB_ABORT;
1867 return(0);
1868 }
1869 }
1870 }
1871 }
1872 }
1873 return(-1);
1874}
1875
1876
1877/*---------------------------------------------------------------------
1878 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001879 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 *
1881 * Description: Do a quick check to determine if there is a pending
1882 * interrupt for this card and disable the IRQ Pin if so.
1883 *
1884 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001885static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001887 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001889 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890
1891 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1892 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001893 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 }
1895
1896 else
1897
James Bottomley 47b5d692005-04-24 02:38:05 -05001898 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899}
1900
1901
1902
1903/*---------------------------------------------------------------------
1904 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001905 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 *
1907 * Description: This is our entry point when an interrupt is generated
1908 * by the card and the upper level driver passes it on to
1909 * us.
1910 *
1911 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001912static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001914 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001915 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001916 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001917 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001918 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001920 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1921 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922
1923 MDISABLE_INT(ioport);
1924
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001926 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 else
1928 bm_status = 0;
1929
1930 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1931
James Bottomley 47b5d692005-04-24 02:38:05 -05001932 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 bm_status)
1934 {
1935
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001936 currSCCB = ((struct sccb_card *)pCurrCard)->currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001939 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((struct sccb_card *)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1941 bm_status = 0;
1942
1943 if (result) {
1944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 return(result);
1947 }
1948 }
1949
1950
1951 else if (hp_int & ICMD_COMP) {
1952
1953 if ( !(hp_int & BUS_FREE) ) {
1954 /* Wait for the BusFree before starting a new command. We
1955 must also check for being reselected since the BusFree
1956 may not show up if another device reselects us in 1.5us or
1957 less. SRR Wednesday, 3/8/1995.
1958 */
1959 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1960 }
1961
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001962 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
James Bottomley 47b5d692005-04-24 02:38:05 -05001964 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965
1966/* WRW_HARPOON((ioport+hp_intstat),
1967 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1968 */
1969
1970 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1971
James Bottomley 47b5d692005-04-24 02:38:05 -05001972 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973
1974 }
1975
1976
1977 else if (hp_int & ITAR_DISC)
1978 {
1979
Alexey Dobriyan13e68512006-03-08 00:14:34 -08001980 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
James Bottomley 47b5d692005-04-24 02:38:05 -05001982 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983
1984 }
1985
1986 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1987
1988 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1989 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1990
1991 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1992 }
1993
1994 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05001995 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996
1997 /* Wait for the BusFree before starting a new command. We
1998 must also check for being reselected since the BusFree
1999 may not show up if another device reselects us in 1.5us or
2000 less. SRR Wednesday, 3/8/1995.
2001 */
2002 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2003 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2004 RD_HARPOON((ioport+hp_scsisig)) ==
2005 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2006
2007 /*
2008 The additional loop exit condition above detects a timing problem
2009 with the revision D/E harpoon chips. The caller should reset the
2010 host adapter to recover when 0xFE is returned.
2011 */
2012 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2013 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 return 0xFE;
2016 }
2017
2018 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2019
2020
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002021 ((struct sccb_card *)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022
2023 }
2024
2025
2026 else if (hp_int & RSEL) {
2027
2028 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2029
2030 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2031 {
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002032 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002034 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 }
2036
2037 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2038 {
2039 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2040 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2041 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2042 }
2043
2044 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2045 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002046 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 }
2048
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002049 FPT_sres(ioport,thisCard,((struct sccb_card *)pCurrCard));
James Bottomley 47b5d692005-04-24 02:38:05 -05002050 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051
2052 }
2053
2054
2055 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2056 {
2057
2058 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002059 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060
2061 }
2062
2063
2064 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2065 {
2066 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002067 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002069 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 }
2071 else
2072 {
2073 /* Harpoon problem some SCSI target device respond to selection
2074 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2075 to latch the correct Target ID into reg. x53.
2076 The work around require to correct this reg. But when write to this
2077 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2078 need to read this reg first then restore it later. After update to 0x53 */
2079
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002080 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2081 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2082 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2083 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2084 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 WR_HARPOON(ioport+hp_fifowrite, i);
2086 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2087 }
2088 }
2089
2090 else if (hp_int & XFER_CNT_0) {
2091
2092 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2093
James Bottomley 47b5d692005-04-24 02:38:05 -05002094 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095
2096 }
2097
2098
2099 else if (hp_int & BUS_FREE) {
2100
2101 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2102
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002103 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
James Bottomley 47b5d692005-04-24 02:38:05 -05002105 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106 }
2107
James Bottomley 47b5d692005-04-24 02:38:05 -05002108 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 }
2110
2111
2112 else if (hp_int & ITICKLE) {
2113
2114 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002115 ((struct sccb_card *)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116 }
2117
2118
2119
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002120 if (((struct sccb_card *)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002121
2122
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002123 ((struct sccb_card *)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124
2125
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002126 if (((struct sccb_card *)pCurrCard)->currentSCCB == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002128 FPT_queueSearchSelect(((struct sccb_card *)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 }
2130
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002131 if (((struct sccb_card *)pCurrCard)->currentSCCB != NULL) {
2132 ((struct sccb_card *)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002133 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134 }
2135
2136 break;
2137
2138 }
2139
2140 } /*end while */
2141
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
2144 return(0);
2145}
2146
2147/*---------------------------------------------------------------------
2148 *
2149 * Function: Sccb_bad_isr
2150 *
2151 * Description: Some type of interrupt has occurred which is slightly
2152 * out of the ordinary. We will now decode it fully, in
2153 * this routine. This is broken up in an attempt to save
2154 * processing time.
2155 *
2156 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002157static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002158 struct sccb_card * pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002160 unsigned char temp, ScamFlg;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002161 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08002162 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163
2164
2165 if (RD_HARPOON(p_port+hp_ext_status) &
2166 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2167 {
2168
2169 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2170 {
2171
James Bottomley 47b5d692005-04-24 02:38:05 -05002172 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173 }
2174
2175 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2176
2177 {
2178 WR_HARPOON(p_port+hp_pci_stat_cfg,
2179 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2180
2181 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2182
2183 }
2184
2185 if (pCurrCard->currentSCCB != NULL)
2186 {
2187
2188 if (!pCurrCard->currentSCCB->HostStatus)
2189 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2190
James Bottomley 47b5d692005-04-24 02:38:05 -05002191 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002193 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002195 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2197
2198 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2199 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002200 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201 }
2202 }
2203 }
2204
2205
2206 else if (p_int & RESET)
2207 {
2208
2209 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2210 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2211 if (pCurrCard->currentSCCB != NULL) {
2212
2213 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2214
James Bottomley 47b5d692005-04-24 02:38:05 -05002215 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216 }
2217
2218
2219 DISABLE_AUTO(p_port);
2220
James Bottomley 47b5d692005-04-24 02:38:05 -05002221 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222
2223 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2224
2225 pCurrNvRam = pCurrCard->pNvRamInfo;
2226 if(pCurrNvRam){
2227 ScamFlg = pCurrNvRam->niScamConf;
2228 }
2229 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002230 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 }
2232
James Bottomley 47b5d692005-04-24 02:38:05 -05002233 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234
James Bottomley 47b5d692005-04-24 02:38:05 -05002235 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236
2237 return(0xFF);
2238 }
2239
2240
2241 else if (p_int & FIFO) {
2242
2243 WRW_HARPOON((p_port+hp_intstat), FIFO);
2244
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002246 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 }
2248
2249 else if (p_int & TIMEOUT)
2250 {
2251
2252 DISABLE_AUTO(p_port);
2253
2254 WRW_HARPOON((p_port+hp_intstat),
2255 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2256
2257 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2258
2259
James Bottomley 47b5d692005-04-24 02:38:05 -05002260 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2262 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002263 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002265 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266
2267
2268 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2269 {
2270 currTar_Info->TarSyncCtrl = 0;
2271 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2272 }
2273
2274 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2275 {
2276 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2277 }
2278
James Bottomley 47b5d692005-04-24 02:38:05 -05002279 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
James Bottomley 47b5d692005-04-24 02:38:05 -05002281 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282
2283 }
2284
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 else if (p_int & SCAM_SEL)
2286 {
2287
James Bottomley 47b5d692005-04-24 02:38:05 -05002288 FPT_scarb(p_port,LEVEL2_TAR);
2289 FPT_scsel(p_port);
2290 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291
James Bottomley 47b5d692005-04-24 02:38:05 -05002292 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
2294 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2295 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
2297 return(0x00);
2298}
2299
2300
2301/*---------------------------------------------------------------------
2302 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 * Function: SccbMgrTableInit
2304 *
2305 * Description: Initialize all Sccb manager data structures.
2306 *
2307 *---------------------------------------------------------------------*/
2308
James Bottomley 47b5d692005-04-24 02:38:05 -05002309static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002311 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
2313 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2314 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002315 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
James Bottomley 47b5d692005-04-24 02:38:05 -05002317 FPT_BL_Card[thisCard].ioPort = 0x00;
2318 FPT_BL_Card[thisCard].cardInfo = NULL;
2319 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2320 FPT_BL_Card[thisCard].ourId = 0x00;
2321 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 }
2323}
2324
2325
2326/*---------------------------------------------------------------------
2327 *
2328 * Function: SccbMgrTableInit
2329 *
2330 * Description: Initialize all Sccb manager data structures.
2331 *
2332 *---------------------------------------------------------------------*/
2333
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002334static void FPT_SccbMgrTableInitCard(struct sccb_card * pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002336 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
2338 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2339 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002340 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341 }
2342
2343 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2344 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002345 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2346 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2347 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348 }
2349
2350 pCurrCard->scanIndex = 0x00;
2351 pCurrCard->currentSCCB = NULL;
2352 pCurrCard->globalFlags = 0x00;
2353 pCurrCard->cmdCounter = 0x00;
2354 pCurrCard->tagQ_Lst = 0x01;
2355 pCurrCard->discQCount = 0;
2356
2357
2358}
2359
2360
2361/*---------------------------------------------------------------------
2362 *
2363 * Function: SccbMgrTableInit
2364 *
2365 * Description: Initialize all Sccb manager data structures.
2366 *
2367 *---------------------------------------------------------------------*/
2368
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002369static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370{
2371
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002372 unsigned char lun, qtag;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002373 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
James Bottomley 47b5d692005-04-24 02:38:05 -05002375 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376
2377 currTar_Info->TarSelQ_Cnt = 0;
2378 currTar_Info->TarSyncCtrl = 0;
2379
2380 currTar_Info->TarSelQ_Head = NULL;
2381 currTar_Info->TarSelQ_Tail = NULL;
2382 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002383 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384
2385
2386 for (lun = 0; lun < MAX_LUN; lun++)
2387 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002388 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 currTar_Info->LunDiscQ_Idx[lun] = 0;
2390 }
2391
2392 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2393 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002394 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002396 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002398 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2399 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400 }
2401 }
2402 }
2403}
2404
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405
2406/*---------------------------------------------------------------------
2407 *
2408 * Function: sfetm
2409 *
2410 * Description: Read in a message byte from the SCSI bus, and check
2411 * for a parity error.
2412 *
2413 *---------------------------------------------------------------------*/
2414
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002415static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002417 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002418 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419
2420 TimeOutLoop = 0;
2421 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2422 (TimeOutLoop++ < 20000) ){}
2423
2424
2425 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2426
2427 message = RD_HARPOON(port+hp_scsidata_0);
2428
2429 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2430
2431
2432 if (TimeOutLoop > 20000)
2433 message = 0x00; /* force message byte = 0 if Time Out on Req */
2434
2435 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2436 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2437 {
2438 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2439 WR_HARPOON(port+hp_xferstat, 0);
2440 WR_HARPOON(port+hp_fiforead, 0);
2441 WR_HARPOON(port+hp_fifowrite, 0);
2442 if (pCurrSCCB != NULL)
2443 {
2444 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2445 }
2446 message = 0x00;
2447 do
2448 {
2449 ACCEPT_MSG_ATN(port);
2450 TimeOutLoop = 0;
2451 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2452 (TimeOutLoop++ < 20000) ){}
2453 if (TimeOutLoop > 20000)
2454 {
2455 WRW_HARPOON((port+hp_intstat), PARITY);
2456 return(message);
2457 }
2458 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2459 {
2460 WRW_HARPOON((port+hp_intstat), PARITY);
2461 return(message);
2462 }
2463 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2464
2465 RD_HARPOON(port+hp_scsidata_0);
2466
2467 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2468
2469 }while(1);
2470
2471 }
2472 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2473 WR_HARPOON(port+hp_xferstat, 0);
2474 WR_HARPOON(port+hp_fiforead, 0);
2475 WR_HARPOON(port+hp_fifowrite, 0);
2476 return(message);
2477}
2478
2479
2480/*---------------------------------------------------------------------
2481 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002482 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483 *
2484 * Description: Load up automation and select target device.
2485 *
2486 *---------------------------------------------------------------------*/
2487
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002488static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489{
2490
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002491 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002493 unsigned long cdb_reg;
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002494 struct sccb_card * CurrCard;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002495 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002496 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002497 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498
James Bottomley 47b5d692005-04-24 02:38:05 -05002499 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002500 currSCCB = CurrCard->currentSCCB;
2501 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002502 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 lastTag = CurrCard->tagQ_Lst;
2504
2505 ARAM_ACCESS(port);
2506
2507
2508 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2509 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2510
2511 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2512 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2513
2514 lun = currSCCB->Lun;
2515 else
2516 lun = 0;
2517
2518
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519 if (CurrCard->globalFlags & F_TAG_STARTED)
2520 {
2521 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2522 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002523 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2525 == TAG_Q_TRYING))
2526 {
2527
2528 if (currTar_Info->TarTagQ_Cnt !=0)
2529 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002530 currTar_Info->TarLUNBusy[lun] = 1;
2531 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 SGRAM_ACCESS(port);
2533 return;
2534 }
2535
2536 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002537 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002538 }
2539
2540 } /*End non-tagged */
2541
2542 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002543 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 }
2545
2546 } /*!Use cmd Q Tagged */
2547
2548 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002549 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002551 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552 SGRAM_ACCESS(port);
2553 return;
2554 }
2555
James Bottomley 47b5d692005-04-24 02:38:05 -05002556 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557
2558 } /*else use cmd Q tagged */
2559
2560 } /*if glob tagged started */
2561
2562 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002563 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 }
2565
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566
2567
2568 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2569 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2570 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2571 {
2572 if(CurrCard->discQCount >= QUEUE_DEPTH)
2573 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002574 currTar_Info->TarLUNBusy[lun] = 1;
2575 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 SGRAM_ACCESS(port);
2577 return;
2578 }
2579 for (i = 1; i < QUEUE_DEPTH; i++)
2580 {
2581 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2582 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2583 {
2584 CurrCard->tagQ_Lst = lastTag;
2585 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2586 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2587 CurrCard->discQCount++;
2588 break;
2589 }
2590 }
2591 if(i == QUEUE_DEPTH)
2592 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002593 currTar_Info->TarLUNBusy[lun] = 1;
2594 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 SGRAM_ACCESS(port);
2596 return;
2597 }
2598 }
2599
2600
2601
James Bottomley 47b5d692005-04-24 02:38:05 -05002602 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
2604 WR_HARPOON(port+hp_select_id, target);
2605 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2606
2607 if (currSCCB->OperationCode == RESET_COMMAND) {
2608 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2609 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2610
2611 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2612
2613 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2614
2615 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002616 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2618
2619 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2620 {
2621 currTar_Info->TarSyncCtrl = 0;
2622 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2623 }
2624
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2626 {
2627 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2628 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629
James Bottomley 47b5d692005-04-24 02:38:05 -05002630 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2631 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632
2633 }
2634
2635 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2636 {
2637 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2638 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2639
2640 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2641
2642 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002643 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2644 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 WRW_HARPOON((port+SYNC_MSGS+2),
2646 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2647 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2648
2649 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002650 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651
2652 }
2653
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002655 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2657 }
2658
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2660 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002661 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2663 }
2664
2665
2666 if (!auto_loaded)
2667 {
2668
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 if (currSCCB->ControlByte & F_USE_CMD_Q)
2670 {
2671
2672 CurrCard->globalFlags |= F_TAG_STARTED;
2673
2674 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2675 == TAG_Q_REJECT)
2676 {
2677 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2678
2679 /* Fix up the start instruction with a jump to
2680 Non-Tag-CMD handling */
2681 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2682
2683 WRW_HARPOON((port+NON_TAG_ID_MSG),
2684 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2685
2686 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2687
2688 /* Setup our STATE so we know what happend when
2689 the wheels fall off. */
2690 currSCCB->Sccb_scsistat = SELECT_ST;
2691
James Bottomley 47b5d692005-04-24 02:38:05 -05002692 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693 }
2694
2695 else
2696 {
2697 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2698
2699 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002700 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2701 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702
2703 for (i = 1; i < QUEUE_DEPTH; i++)
2704 {
2705 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2706 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2707 {
2708 WRW_HARPOON((port+ID_MSG_STRT+6),
2709 (MPM_OP+AMSG_OUT+lastTag));
2710 CurrCard->tagQ_Lst = lastTag;
2711 currSCCB->Sccb_tag = lastTag;
2712 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2713 CurrCard->discQCount++;
2714 break;
2715 }
2716 }
2717
2718
2719 if ( i == QUEUE_DEPTH )
2720 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002721 currTar_Info->TarLUNBusy[lun] = 1;
2722 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723 SGRAM_ACCESS(port);
2724 return;
2725 }
2726
2727 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2728
2729 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2730 }
2731 }
2732
2733 else
2734 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002735
2736 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2737
2738 WRW_HARPOON((port+NON_TAG_ID_MSG),
2739 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2740
2741 currSCCB->Sccb_scsistat = SELECT_ST;
2742
2743 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745
2746
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002747 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748
2749 cdb_reg = port + CMD_STRT;
2750
2751 for (i=0; i < currSCCB->CdbLength; i++)
2752 {
2753 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2754 cdb_reg +=2;
2755 theCCB++;
2756 }
2757
2758 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2759 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2760
2761 } /* auto_loaded */
2762
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002763 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765
2766 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2767
2768 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2769
2770
2771 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2772 {
2773 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2774 }
2775 else
2776 {
2777
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002778/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779 auto_loaded |= AUTO_IMMED; */
2780 auto_loaded = AUTO_IMMED;
2781
2782 DISABLE_AUTO(port);
2783
2784 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2785 }
2786
2787 SGRAM_ACCESS(port);
2788}
2789
2790
2791/*---------------------------------------------------------------------
2792 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002793 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 *
2795 * Description: Hookup the correct CCB and handle the incoming messages.
2796 *
2797 *---------------------------------------------------------------------*/
2798
Alexey Dobriyan13e68512006-03-08 00:14:34 -08002799static void FPT_sres(unsigned long port, unsigned char p_card, struct sccb_card * pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800{
2801
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002802 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803
2804
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08002805 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002806 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002807
2808
2809
2810
2811 if(pCurrCard->currentSCCB != NULL)
2812 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002813 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814 DISABLE_AUTO(port);
2815
2816
2817 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2818
2819
2820 currSCCB = pCurrCard->currentSCCB;
2821 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2822 {
2823 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2824 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2825 }
2826 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2827 {
2828 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2829 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2830 }
2831 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2832 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2833 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002834 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835 if(currSCCB->Sccb_scsistat != ABORT_ST)
2836 {
2837 pCurrCard->discQCount--;
2838 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2839 = NULL;
2840 }
2841 }
2842 else
2843 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002844 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845 if(currSCCB->Sccb_tag)
2846 {
2847 if(currSCCB->Sccb_scsistat != ABORT_ST)
2848 {
2849 pCurrCard->discQCount--;
2850 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2851 }
2852 }else
2853 {
2854 if(currSCCB->Sccb_scsistat != ABORT_ST)
2855 {
2856 pCurrCard->discQCount--;
2857 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2858 }
2859 }
2860 }
2861
James Bottomley 47b5d692005-04-24 02:38:05 -05002862 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 }
2864
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002865 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
2867
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002868 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002869 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870
2871
2872 msgRetryCount = 0;
2873 do
2874 {
2875
James Bottomley 47b5d692005-04-24 02:38:05 -05002876 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 tag = 0;
2878
2879
2880 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2881 {
2882 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2883 {
2884
2885 WRW_HARPOON((port+hp_intstat), PHASE);
2886 return;
2887 }
2888 }
2889
2890 WRW_HARPOON((port+hp_intstat), PHASE);
2891 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2892 {
2893
James Bottomley 47b5d692005-04-24 02:38:05 -05002894 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 if (message)
2896 {
2897
2898 if (message <= (0x80 | LUN_MASK))
2899 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002900 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2903 {
2904 if (currTar_Info->TarTagQ_Cnt != 0)
2905 {
2906
2907 if (!(currTar_Info->TarLUN_CA))
2908 {
2909 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2910
2911
James Bottomley 47b5d692005-04-24 02:38:05 -05002912 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913 if (message)
2914 {
2915 ACCEPT_MSG(port);
2916 }
2917
2918 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002919 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920
James Bottomley 47b5d692005-04-24 02:38:05 -05002921 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002923 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924
2925 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002926 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 }
2928
2929 } /*C.A. exists! */
2930
2931 } /*End Q cnt != 0 */
2932
2933 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934
2935 } /*End valid ID message. */
2936
2937 else
2938 {
2939
2940 ACCEPT_MSG_ATN(port);
2941 }
2942
2943 } /* End good id message. */
2944
2945 else
2946 {
2947
James Bottomley 47b5d692005-04-24 02:38:05 -05002948 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949 }
2950 }
2951 else
2952 {
2953 ACCEPT_MSG_ATN(port);
2954
2955 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2956 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2957 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2958
2959 return;
2960 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961
James Bottomley 47b5d692005-04-24 02:38:05 -05002962 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 {
2964 msgRetryCount++;
2965 if(msgRetryCount == 1)
2966 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002967 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 }
2969 else
2970 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002971 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972
James Bottomley 47b5d692005-04-24 02:38:05 -05002973 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
James Bottomley 47b5d692005-04-24 02:38:05 -05002975 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 {
2977
James Bottomley 47b5d692005-04-24 02:38:05 -05002978 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979
2980 }
2981
James Bottomley 47b5d692005-04-24 02:38:05 -05002982 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 {
2984
James Bottomley 47b5d692005-04-24 02:38:05 -05002985 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 }
2987
2988
James Bottomley 47b5d692005-04-24 02:38:05 -05002989 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2990 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991 return;
2992 }
2993 }
James Bottomley 47b5d692005-04-24 02:38:05 -05002994 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995
2996
2997
2998 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2999 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3000 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003001 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3003 if(pCurrCard->currentSCCB != NULL)
3004 {
3005 ACCEPT_MSG(port);
3006 }
3007 else
3008 {
3009 ACCEPT_MSG_ATN(port);
3010 }
3011 }
3012 else
3013 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003014 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015
3016
3017 if (tag)
3018 {
3019 if (pCurrCard->discQ_Tbl[tag] != NULL)
3020 {
3021 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3022 currTar_Info->TarTagQ_Cnt--;
3023 ACCEPT_MSG(port);
3024 }
3025 else
3026 {
3027 ACCEPT_MSG_ATN(port);
3028 }
3029 }else
3030 {
3031 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3032 if(pCurrCard->currentSCCB != NULL)
3033 {
3034 ACCEPT_MSG(port);
3035 }
3036 else
3037 {
3038 ACCEPT_MSG_ATN(port);
3039 }
3040 }
3041 }
3042
3043 if(pCurrCard->currentSCCB != NULL)
3044 {
3045 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3046 {
3047 /* During Abort Tag command, the target could have got re-selected
3048 and completed the command. Check the select Q and remove the CCB
3049 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003050 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 }
3052 }
3053
3054
3055 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3056 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3057 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3058}
3059
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003060static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061{
3062 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3063 {
3064 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3065 {
3066
3067 WRW_HARPOON((port+hp_intstat), PHASE);
3068 return;
3069 }
3070 }
3071
3072 WRW_HARPOON((port+hp_intstat), PHASE);
3073 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3074 {
3075 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3076
3077
3078 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3079
3080 WR_HARPOON(port+hp_scsidata_0,message);
3081
3082 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3083
3084 ACCEPT_MSG(port);
3085
3086 WR_HARPOON(port+hp_portctrl_0, 0x00);
3087
3088 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3089 (message == SMABORT_TAG) )
3090 {
3091 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3092
3093 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3094 {
3095 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3096 }
3097 }
3098 }
3099}
3100
3101/*---------------------------------------------------------------------
3102 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003103 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 *
3105 * Description: Determine the proper responce to the message from the
3106 * target device.
3107 *
3108 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003109static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003111 struct sccb * currSCCB;
Alexey Dobriyan13e68512006-03-08 00:14:34 -08003112 struct sccb_card * CurrCard;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003113 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114
James Bottomley 47b5d692005-04-24 02:38:05 -05003115 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116 currSCCB = CurrCard->currentSCCB;
3117
James Bottomley 47b5d692005-04-24 02:38:05 -05003118 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119
3120 if (message == SMREST_DATA_PTR)
3121 {
3122 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3123 {
3124 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3125
James Bottomley 47b5d692005-04-24 02:38:05 -05003126 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 }
3128
3129 ACCEPT_MSG(port);
3130 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3131 }
3132
3133 else if (message == SMCMD_COMP)
3134 {
3135
3136
3137 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3138 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003139 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3140 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 }
3142
3143 ACCEPT_MSG(port);
3144
3145 }
3146
3147 else if ((message == SMNO_OP) || (message >= SMIDENT)
3148 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3149 {
3150
3151 ACCEPT_MSG(port);
3152 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3153 }
3154
3155 else if (message == SMREJECT)
3156 {
3157
3158 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3159 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3160 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3161 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3162
3163 {
3164 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3165
3166 ACCEPT_MSG(port);
3167
3168
3169 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3170 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3171
3172 if(currSCCB->Lun == 0x00)
3173 {
3174 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3175 {
3176
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003177 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178
3179 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3180 }
3181
Linus Torvalds1da177e2005-04-16 15:20:36 -07003182 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3183 {
3184
3185
3186 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3187 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3188
3189 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3190
3191 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192
3193 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3194 {
3195 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003196 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197
3198
3199 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3200 CurrCard->discQCount--;
3201 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3202 currSCCB->Sccb_tag = 0x00;
3203
3204 }
3205 }
3206
3207 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3208 {
3209
3210
3211 if(currSCCB->Lun == 0x00)
3212 {
3213 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3214 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3215 }
3216 }
3217
3218 else
3219 {
3220
3221 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3222 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003223 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003225 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226
3227
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003228 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229
3230 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3231
3232 }
3233 }
3234
3235 else
3236 {
3237 ACCEPT_MSG(port);
3238
3239 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3240 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3241
3242 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3243 {
3244 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3245 }
3246 }
3247 }
3248
3249 else if (message == SMEXT)
3250 {
3251
3252 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003253 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003254 }
3255
3256 else if (message == SMIGNORWR)
3257 {
3258
3259 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3260
James Bottomley 47b5d692005-04-24 02:38:05 -05003261 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262
3263 if(currSCCB->Sccb_scsimsg != SMPARITY)
3264 ACCEPT_MSG(port);
3265 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3266 }
3267
3268
3269 else
3270 {
3271
3272 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3273 currSCCB->Sccb_scsimsg = SMREJECT;
3274
3275 ACCEPT_MSG_ATN(port);
3276 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3277 }
3278}
3279
3280
3281/*---------------------------------------------------------------------
3282 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003283 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003284 *
3285 * Description: Decide what to do with the extended message.
3286 *
3287 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003288static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003289{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003290 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003291
James Bottomley 47b5d692005-04-24 02:38:05 -05003292 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003293 if (length)
3294 {
3295
3296 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003297 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003298 if (message)
3299 {
3300
3301 if (message == SMSYNC)
3302 {
3303
3304 if (length == 0x03)
3305 {
3306
3307 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003308 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309 }
3310 else
3311 {
3312
3313 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3314 ACCEPT_MSG_ATN(port);
3315 }
3316 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317 else if (message == SMWDTR)
3318 {
3319
3320 if (length == 0x02)
3321 {
3322
3323 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003324 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 }
3326 else
3327 {
3328
3329 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3330 ACCEPT_MSG_ATN(port);
3331
3332 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3333 }
3334 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003335 else
3336 {
3337
3338 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3339 ACCEPT_MSG_ATN(port);
3340
3341 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3342 }
3343 }
3344 else
3345 {
3346 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3347 ACCEPT_MSG(port);
3348 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3349 }
3350 }else
3351 {
3352 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3353 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3354 }
3355}
3356
3357
3358/*---------------------------------------------------------------------
3359 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003360 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003361 *
3362 * Description: Read in a message byte from the SCSI bus, and check
3363 * for a parity error.
3364 *
3365 *---------------------------------------------------------------------*/
3366
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003367static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003368{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003369 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003370 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003371
James Bottomley 47b5d692005-04-24 02:38:05 -05003372 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3373 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003374
3375 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3376
3377
3378 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003379 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003380
3381 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3382
3383 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3384 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3385 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3386
3387
3388 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3389
3390 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3391
3392 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3393
3394 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3395
3396 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3397
3398 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3399
3400 else
3401 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3402
3403
3404 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3405 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3406 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3407
3408
James Bottomley 47b5d692005-04-24 02:38:05 -05003409 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003410 {
3411 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3412 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003413 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414 }
3415 else
3416 {
3417 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3418 }
3419
3420
James Bottomley 47b5d692005-04-24 02:38:05 -05003421 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 }
3423
3424 else {
3425
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003426 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003428 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003429 }
3430}
3431
3432
3433
3434/*---------------------------------------------------------------------
3435 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003436 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 *
3438 * Description: The has sent us a Sync Nego message so handle it as
3439 * necessary.
3440 *
3441 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003442static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003443{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003444 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003445 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003446 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447
James Bottomley 47b5d692005-04-24 02:38:05 -05003448 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3449 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003450
James Bottomley 47b5d692005-04-24 02:38:05 -05003451 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452
3453 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3454 {
3455 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3456 return;
3457 }
3458
3459 ACCEPT_MSG(port);
3460
3461
James Bottomley 47b5d692005-04-24 02:38:05 -05003462 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003463
3464 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3465 {
3466 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3467 return;
3468 }
3469
3470 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3471
3472 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3473
3474 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3475
3476 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3477
3478 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3479
3480 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3481 else
3482
3483 our_sync_msg = 0; /* Message = Async */
3484
3485 if (sync_msg < our_sync_msg) {
3486 sync_msg = our_sync_msg; /*if faster, then set to max. */
3487 }
3488
3489 if (offset == ASYNC)
3490 sync_msg = ASYNC;
3491
3492 if (offset > MAX_OFFSET)
3493 offset = MAX_OFFSET;
3494
3495 sync_reg = 0x00;
3496
3497 if (sync_msg > 12)
3498
3499 sync_reg = 0x20; /* Use 10MB/s */
3500
3501 if (sync_msg > 25)
3502
3503 sync_reg = 0x40; /* Use 6.6MB/s */
3504
3505 if (sync_msg > 38)
3506
3507 sync_reg = 0x60; /* Use 5MB/s */
3508
3509 if (sync_msg > 50)
3510
3511 sync_reg = 0x80; /* Use 4MB/s */
3512
3513 if (sync_msg > 62)
3514
3515 sync_reg = 0xA0; /* Use 3.33MB/s */
3516
3517 if (sync_msg > 75)
3518
3519 sync_reg = 0xC0; /* Use 2.85MB/s */
3520
3521 if (sync_msg > 87)
3522
3523 sync_reg = 0xE0; /* Use 2.5MB/s */
3524
3525 if (sync_msg > 100) {
3526
3527 sync_reg = 0x00; /* Use ASYNC */
3528 offset = 0x00;
3529 }
3530
3531
Linus Torvalds1da177e2005-04-16 15:20:36 -07003532 if (currTar_Info->TarStatus & WIDE_ENABLED)
3533
3534 sync_reg |= offset;
3535
3536 else
3537
3538 sync_reg |= (offset | NARROW_SCSI);
3539
James Bottomley 47b5d692005-04-24 02:38:05 -05003540 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541
3542
3543 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3544
3545
3546 ACCEPT_MSG(port);
3547
3548 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003549 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003550
3551 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3552 }
3553
3554 else {
3555
3556
3557 ACCEPT_MSG_ATN(port);
3558
James Bottomley 47b5d692005-04-24 02:38:05 -05003559 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003560
3561 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003562 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003563 }
3564}
3565
3566
3567/*---------------------------------------------------------------------
3568 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003569 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003570 *
3571 * Description: Answer the targets sync message.
3572 *
3573 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003574static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003575{
3576 ARAM_ACCESS(port);
3577 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3578 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3579 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3580 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3581 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3582 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3583 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3584 SGRAM_ACCESS(port);
3585
3586 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3587 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3588
3589 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3590
3591 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3592}
3593
3594
3595
Linus Torvalds1da177e2005-04-16 15:20:36 -07003596/*---------------------------------------------------------------------
3597 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003598 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599 *
3600 * Description: Read in a message byte from the SCSI bus, and check
3601 * for a parity error.
3602 *
3603 *---------------------------------------------------------------------*/
3604
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003605static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003606{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003607 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003608 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609
James Bottomley 47b5d692005-04-24 02:38:05 -05003610 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3611 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003612
3613 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3614
3615
3616 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003617 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003618
3619 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3620
3621 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3622 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3623 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3624 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3625 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3626 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3627
3628 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3629
3630
3631 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003632 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633
James Bottomley 47b5d692005-04-24 02:38:05 -05003634 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635 }
3636
3637 else {
3638
3639 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003640 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003641
3642 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003643 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644 }
3645}
3646
3647
3648
3649/*---------------------------------------------------------------------
3650 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003651 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003652 *
3653 * Description: The has sent us a Wide Nego message so handle it as
3654 * necessary.
3655 *
3656 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003657static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003659 unsigned char width;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003660 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003661 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003662
James Bottomley 47b5d692005-04-24 02:38:05 -05003663 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3664 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003665
James Bottomley 47b5d692005-04-24 02:38:05 -05003666 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667
3668 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3669 {
3670 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3671 return;
3672 }
3673
3674
3675 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3676 width = 0;
3677
3678 if (width) {
3679 currTar_Info->TarStatus |= WIDE_ENABLED;
3680 width = 0;
3681 }
3682 else {
3683 width = NARROW_SCSI;
3684 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3685 }
3686
3687
James Bottomley 47b5d692005-04-24 02:38:05 -05003688 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003689
3690
3691 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3692 {
3693
3694
3695
3696 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3697
3698 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3699 {
3700 ACCEPT_MSG_ATN(port);
3701 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003702 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3704 SGRAM_ACCESS(port);
3705 }
3706 else
3707 {
3708 ACCEPT_MSG(port);
3709 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3710 }
3711 }
3712
3713 else {
3714
3715
3716 ACCEPT_MSG_ATN(port);
3717
3718 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3719 width = SM16BIT;
3720 else
3721 width = SM8BIT;
3722
James Bottomley 47b5d692005-04-24 02:38:05 -05003723 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724
3725 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3726 }
3727}
3728
3729
3730/*---------------------------------------------------------------------
3731 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003732 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003733 *
3734 * Description: Answer the targets Wide nego message.
3735 *
3736 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003737static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003738{
3739 ARAM_ACCESS(port);
3740 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3741 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3742 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3743 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3744 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3745 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3746 SGRAM_ACCESS(port);
3747
3748 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3749 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3750
3751 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3752
3753 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3754}
3755
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
3757
3758/*---------------------------------------------------------------------
3759 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003760 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003761 *
3762 * Description: Write the desired value to the Sync Register for the
3763 * ID specified.
3764 *
3765 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003766static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003767 struct sccb_mgr_tar_info * currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003768{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003769 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770
3771 index = p_id;
3772
3773 switch (index) {
3774
3775 case 0:
3776 index = 12; /* hp_synctarg_0 */
3777 break;
3778 case 1:
3779 index = 13; /* hp_synctarg_1 */
3780 break;
3781 case 2:
3782 index = 14; /* hp_synctarg_2 */
3783 break;
3784 case 3:
3785 index = 15; /* hp_synctarg_3 */
3786 break;
3787 case 4:
3788 index = 8; /* hp_synctarg_4 */
3789 break;
3790 case 5:
3791 index = 9; /* hp_synctarg_5 */
3792 break;
3793 case 6:
3794 index = 10; /* hp_synctarg_6 */
3795 break;
3796 case 7:
3797 index = 11; /* hp_synctarg_7 */
3798 break;
3799 case 8:
3800 index = 4; /* hp_synctarg_8 */
3801 break;
3802 case 9:
3803 index = 5; /* hp_synctarg_9 */
3804 break;
3805 case 10:
3806 index = 6; /* hp_synctarg_10 */
3807 break;
3808 case 11:
3809 index = 7; /* hp_synctarg_11 */
3810 break;
3811 case 12:
3812 index = 0; /* hp_synctarg_12 */
3813 break;
3814 case 13:
3815 index = 1; /* hp_synctarg_13 */
3816 break;
3817 case 14:
3818 index = 2; /* hp_synctarg_14 */
3819 break;
3820 case 15:
3821 index = 3; /* hp_synctarg_15 */
3822
3823 }
3824
3825 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3826
3827 currTar_Info->TarSyncCtrl = p_sync_value;
3828}
3829
3830
3831/*---------------------------------------------------------------------
3832 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003833 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003834 *
3835 * Description: Reset the desired card's SCSI bus.
3836 *
3837 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003838static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003839{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003840 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003841
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08003842 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843
3844 WR_HARPOON(port+hp_page_ctrl,
3845 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3846 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3847
3848 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3849
3850 scsiID = RD_HARPOON(port+hp_seltimeout);
3851 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3852 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3853
3854 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3855
3856 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3857
3858 WR_HARPOON(port+hp_seltimeout,scsiID);
3859
3860 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3861
James Bottomley 47b5d692005-04-24 02:38:05 -05003862 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003863
3864 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3865
3866 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3867
3868 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3869 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003870 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871
3872 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3873 {
3874 currTar_Info->TarSyncCtrl = 0;
3875 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3876 }
3877
3878 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3879 {
3880 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3881 }
3882
James Bottomley 47b5d692005-04-24 02:38:05 -05003883 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884
James Bottomley 47b5d692005-04-24 02:38:05 -05003885 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886 }
3887
James Bottomley 47b5d692005-04-24 02:38:05 -05003888 FPT_BL_Card[p_card].scanIndex = 0x00;
3889 FPT_BL_Card[p_card].currentSCCB = NULL;
3890 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003891 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003892 FPT_BL_Card[p_card].cmdCounter = 0x00;
3893 FPT_BL_Card[p_card].discQCount = 0x00;
3894 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895
3896 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003897 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898
3899 WR_HARPOON(port+hp_page_ctrl,
3900 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3901
3902}
3903
3904/*---------------------------------------------------------------------
3905 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003906 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003907 *
3908 * Description: Setup for the Auto Sense command.
3909 *
3910 *---------------------------------------------------------------------*/
Alexey Dobriyan13e68512006-03-08 00:14:34 -08003911static void FPT_ssenss(struct sccb_card * pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003912{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003913 unsigned char i;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003914 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915
3916 currSCCB = pCurrCard->currentSCCB;
3917
3918
3919 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3920
3921 for (i = 0; i < 6; i++) {
3922
3923 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3924 }
3925
3926 currSCCB->CdbLength = SIX_BYTE_CMD;
3927 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003928 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003929 currSCCB->Cdb[2] = 0x00;
3930 currSCCB->Cdb[3] = 0x00;
3931 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3932 currSCCB->Cdb[5] = 0x00;
3933
3934 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3935
3936 currSCCB->Sccb_ATC = 0x00;
3937
3938 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3939
3940 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3941
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003942 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943
3944 currSCCB->ControlByte = 0x00;
3945
3946 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3947}
3948
3949
3950
3951/*---------------------------------------------------------------------
3952 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003953 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003954 *
3955 * Description: Transfer data into the bit bucket until the device
3956 * decides to switch phase.
3957 *
3958 *---------------------------------------------------------------------*/
3959
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003960static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003962 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003963
3964
3965 DISABLE_AUTO(p_port);
3966
James Bottomley 47b5d692005-04-24 02:38:05 -05003967 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968
James Bottomley 47b5d692005-04-24 02:38:05 -05003969 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003970
3971 }
3972
3973 /* If the Automation handled the end of the transfer then do not
3974 match the phase or we will get out of sync with the ISR. */
3975
3976 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3977 return;
3978
3979 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3980
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003981 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003982
3983 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3984
3985
3986 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3987
3988 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003989 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003990 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003991 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003992 {
3993 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3994
3995 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3996 {
3997 RD_HARPOON(p_port+hp_fifodata_0);
3998 }
3999 }
4000 else
4001 {
4002 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4003 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4004 {
4005 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4006 }
4007 }
4008 } /* End of While loop for padding data I/O phase */
4009
4010 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4011 {
4012 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4013 break;
4014 }
4015
4016 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4017 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4018 {
4019 RD_HARPOON(p_port+hp_fifodata_0);
4020 }
4021
4022 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4023 {
4024 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4025 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4026
4027 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4028 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4029 }
4030}
4031
4032
4033/*---------------------------------------------------------------------
4034 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004035 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004036 *
4037 * Description: Make sure data has been flushed from both FIFOs and abort
4038 * the operations if necessary.
4039 *
4040 *---------------------------------------------------------------------*/
4041
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004042static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004043{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004044 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004045 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004047 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004048
James Bottomley 47b5d692005-04-24 02:38:05 -05004049 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004050
4051
4052 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4053 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4054 return;
4055 }
4056
4057
4058
4059 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4060 {
4061
4062 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4063
4064 currSCCB->Sccb_XferCnt = 1;
4065
4066 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004067 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004068 WR_HARPOON(port+hp_xferstat, 0x00);
4069 }
4070
4071 else
4072 {
4073
4074 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4075
4076 currSCCB->Sccb_XferCnt = 0;
4077 }
4078
4079 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4080 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4081
4082 currSCCB->HostStatus = SCCB_PARITY_ERR;
4083 WRW_HARPOON((port+hp_intstat), PARITY);
4084 }
4085
4086
James Bottomley 47b5d692005-04-24 02:38:05 -05004087 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004088
4089
4090 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4091
4092 TimeOutLoop = 0;
4093
4094 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4095 {
4096 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4097 return;
4098 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004099 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004100 break;
4101 }
4102 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4103 return;
4104 }
4105 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4106 break;
4107 }
4108
4109 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4110 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004111 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004112 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4113 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4114 {
4115
4116 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4117
4118 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4119 {
4120 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004121 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004122 }
4123
4124 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004125 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004126 }
4127 }
4128 else
4129 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004130 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004131 if (!(RDW_HARPOON((port+hp_intstat)) &
4132 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4133 {
4134 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004135 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004136 }
4137 }
4138
4139 }
4140
4141 else {
4142 WR_HARPOON(port+hp_portctrl_0, 0x00);
4143 }
4144}
4145
4146
4147/*---------------------------------------------------------------------
4148 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004149 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004150 *
4151 * Description: Setup SCCB manager fields in this SCCB.
4152 *
4153 *---------------------------------------------------------------------*/
4154
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004155static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004156{
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08004157 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158
4159 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4160 {
4161 return;
4162 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004163 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004164
4165 p_sccb->Sccb_XferState = 0x00;
4166 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4167
4168 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4169 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4170
4171 p_sccb->Sccb_SGoffset = 0;
4172 p_sccb->Sccb_XferState = F_SG_XFER;
4173 p_sccb->Sccb_XferCnt = 0x00;
4174 }
4175
4176 if (p_sccb->DataLength == 0x00)
4177
4178 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4179
4180 if (p_sccb->ControlByte & F_USE_CMD_Q)
4181 {
4182 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4183 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4184
4185 else
4186 currTar_Info->TarStatus |= TAG_Q_TRYING;
4187 }
4188
4189/* For !single SCSI device in system & device allow Disconnect
4190 or command is tag_q type then send Cmd with Disconnect Enable
4191 else send Cmd with Disconnect Disable */
4192
4193/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004194 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004195 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4196 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4197*/
4198 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4199 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004200 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004201 }
4202
4203 else {
4204
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004205 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004206 }
4207
4208 p_sccb->HostStatus = 0x00;
4209 p_sccb->TargetStatus = 0x00;
4210 p_sccb->Sccb_tag = 0x00;
4211 p_sccb->Sccb_MGRFlags = 0x00;
4212 p_sccb->Sccb_sgseg = 0x00;
4213 p_sccb->Sccb_ATC = 0x00;
4214 p_sccb->Sccb_savedATC = 0x00;
4215/*
4216 p_sccb->SccbVirtDataPtr = 0x00;
4217 p_sccb->Sccb_forwardlink = NULL;
4218 p_sccb->Sccb_backlink = NULL;
4219 */
4220 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4221 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4222 p_sccb->Sccb_scsimsg = SMNO_OP;
4223
4224}
4225
4226
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227/*---------------------------------------------------------------------
4228 *
4229 * Function: Phase Decode
4230 *
4231 * Description: Determine the phase and call the appropriate function.
4232 *
4233 *---------------------------------------------------------------------*/
4234
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004235static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004236{
4237 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004238 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239
4240
4241 DISABLE_AUTO(p_port);
4242
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004243 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004244
James Bottomley 47b5d692005-04-24 02:38:05 -05004245 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004246
4247 (*phase)(p_port, p_card); /* Call the correct phase func */
4248}
4249
4250
4251
4252/*---------------------------------------------------------------------
4253 *
4254 * Function: Data Out Phase
4255 *
4256 * Description: Start up both the BusMaster and Xbow.
4257 *
4258 *---------------------------------------------------------------------*/
4259
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004260static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004261{
4262
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004263 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264
James Bottomley 47b5d692005-04-24 02:38:05 -05004265 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 if (currSCCB == NULL)
4267 {
4268 return; /* Exit if No SCCB record */
4269 }
4270
4271 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4272 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4273
4274 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4275
4276 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4277
4278 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4279
James Bottomley 47b5d692005-04-24 02:38:05 -05004280 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004281
4282 if (currSCCB->Sccb_XferCnt == 0) {
4283
4284
4285 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4286 (currSCCB->HostStatus == SCCB_COMPLETE))
4287 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4288
James Bottomley 47b5d692005-04-24 02:38:05 -05004289 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004290 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004291 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004292 }
4293}
4294
4295
4296/*---------------------------------------------------------------------
4297 *
4298 * Function: Data In Phase
4299 *
4300 * Description: Startup the BusMaster and the XBOW.
4301 *
4302 *---------------------------------------------------------------------*/
4303
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004304static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004305{
4306
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004307 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308
James Bottomley 47b5d692005-04-24 02:38:05 -05004309 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004310
4311 if (currSCCB == NULL)
4312 {
4313 return; /* Exit if No SCCB record */
4314 }
4315
4316
4317 currSCCB->Sccb_scsistat = DATA_IN_ST;
4318 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4319 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4320
4321 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4322
4323 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4324
4325 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4326
James Bottomley 47b5d692005-04-24 02:38:05 -05004327 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004328
4329 if (currSCCB->Sccb_XferCnt == 0) {
4330
4331
4332 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4333 (currSCCB->HostStatus == SCCB_COMPLETE))
4334 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4335
James Bottomley 47b5d692005-04-24 02:38:05 -05004336 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004338 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004339
4340 }
4341}
4342
4343/*---------------------------------------------------------------------
4344 *
4345 * Function: Command Phase
4346 *
4347 * Description: Load the CDB into the automation and start it up.
4348 *
4349 *---------------------------------------------------------------------*/
4350
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004351static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004352{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004353 struct sccb * currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004354 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004355 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004356
James Bottomley 47b5d692005-04-24 02:38:05 -05004357 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004358
4359 if (currSCCB->OperationCode == RESET_COMMAND) {
4360
4361 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4362 currSCCB->CdbLength = SIX_BYTE_CMD;
4363 }
4364
4365 WR_HARPOON(p_port+hp_scsisig, 0x00);
4366
4367 ARAM_ACCESS(p_port);
4368
4369
4370 cdb_reg = p_port + CMD_STRT;
4371
4372 for (i=0; i < currSCCB->CdbLength; i++) {
4373
4374 if (currSCCB->OperationCode == RESET_COMMAND)
4375
4376 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4377
4378 else
4379 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4380 cdb_reg +=2;
4381 }
4382
4383 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4384 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4385
4386 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4387
4388 currSCCB->Sccb_scsistat = COMMAND_ST;
4389
4390 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4391 SGRAM_ACCESS(p_port);
4392}
4393
4394
4395/*---------------------------------------------------------------------
4396 *
4397 * Function: Status phase
4398 *
4399 * Description: Bring in the status and command complete message bytes
4400 *
4401 *---------------------------------------------------------------------*/
4402
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004403static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004404{
4405 /* Start-up the automation to finish off this command and let the
4406 isr handle the interrupt for command complete when it comes in.
4407 We could wait here for the interrupt to be generated?
4408 */
4409
4410 WR_HARPOON(port+hp_scsisig, 0x00);
4411
4412 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4413}
4414
4415
4416/*---------------------------------------------------------------------
4417 *
4418 * Function: Phase Message Out
4419 *
4420 * Description: Send out our message (if we have one) and handle whatever
4421 * else is involed.
4422 *
4423 *---------------------------------------------------------------------*/
4424
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004425static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004426{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004427 unsigned char message,scsiID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004428 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08004429 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004430
James Bottomley 47b5d692005-04-24 02:38:05 -05004431 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432
4433 if (currSCCB != NULL) {
4434
4435 message = currSCCB->Sccb_scsimsg;
4436 scsiID = currSCCB->TargID;
4437
4438 if (message == SMDEV_RESET)
4439 {
4440
4441
James Bottomley 47b5d692005-04-24 02:38:05 -05004442 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004443 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004444 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004445
James Bottomley 47b5d692005-04-24 02:38:05 -05004446 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004447 {
4448
James Bottomley 47b5d692005-04-24 02:38:05 -05004449 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450
4451 }
4452
James Bottomley 47b5d692005-04-24 02:38:05 -05004453 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004454 {
4455
James Bottomley 47b5d692005-04-24 02:38:05 -05004456 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457 }
4458
4459
James Bottomley 47b5d692005-04-24 02:38:05 -05004460 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4461 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004462 }
4463 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4464 {
4465 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004466 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004467 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004468 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4469 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 }
4471
4472 }
4473
4474 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4475 {
4476
4477
4478 if(message == SMNO_OP)
4479 {
4480 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4481
James Bottomley 47b5d692005-04-24 02:38:05 -05004482 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004483 return;
4484 }
4485 }
4486 else
4487 {
4488
4489
4490 if (message == SMABORT)
4491
James Bottomley 47b5d692005-04-24 02:38:05 -05004492 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004493 }
4494
4495 }
4496 else
4497 {
4498 message = SMABORT;
4499 }
4500
4501 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4502
4503
4504 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4505
4506 WR_HARPOON(port+hp_scsidata_0,message);
4507
4508 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4509
4510 ACCEPT_MSG(port);
4511
4512 WR_HARPOON(port+hp_portctrl_0, 0x00);
4513
4514 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4515 (message == SMABORT_TAG) )
4516 {
4517
4518 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4519
4520 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4521 {
4522 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4523
4524 if (currSCCB != NULL)
4525 {
4526
James Bottomley 47b5d692005-04-24 02:38:05 -05004527 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4528 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4529 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004530 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004531 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004532
James Bottomley 47b5d692005-04-24 02:38:05 -05004533 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004534 }
4535
4536 else
4537 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004538 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004539 }
4540 }
4541
4542 else
4543 {
4544
James Bottomley 47b5d692005-04-24 02:38:05 -05004545 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004546 }
4547 }
4548
4549 else
4550 {
4551
4552 if(message == SMPARITY)
4553 {
4554 currSCCB->Sccb_scsimsg = SMNO_OP;
4555 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4556 }
4557 else
4558 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004559 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004560 }
4561 }
4562}
4563
4564
4565/*---------------------------------------------------------------------
4566 *
4567 * Function: Message In phase
4568 *
4569 * Description: Bring in the message and determine what to do with it.
4570 *
4571 *---------------------------------------------------------------------*/
4572
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004573static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004574{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004575 unsigned char message;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004576 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004577
James Bottomley 47b5d692005-04-24 02:38:05 -05004578 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004579
James Bottomley 47b5d692005-04-24 02:38:05 -05004580 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004581 {
4582
James Bottomley 47b5d692005-04-24 02:38:05 -05004583 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584 }
4585
4586 message = RD_HARPOON(port+hp_scsidata_0);
4587 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4588 {
4589
4590 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4591
4592 }
4593
4594 else
4595 {
4596
James Bottomley 47b5d692005-04-24 02:38:05 -05004597 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004598 if (message)
4599 {
4600
4601
James Bottomley 47b5d692005-04-24 02:38:05 -05004602 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004603
4604 }
4605 else
4606 {
4607 if(currSCCB->Sccb_scsimsg != SMPARITY)
4608 ACCEPT_MSG(port);
4609 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4610 }
4611 }
4612
4613}
4614
4615
4616/*---------------------------------------------------------------------
4617 *
4618 * Function: Illegal phase
4619 *
4620 * Description: Target switched to some illegal phase, so all we can do
4621 * is report an error back to the host (if that is possible)
4622 * and send an ABORT message to the misbehaving target.
4623 *
4624 *---------------------------------------------------------------------*/
4625
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004626static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004627{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004628 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004629
James Bottomley 47b5d692005-04-24 02:38:05 -05004630 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004631
4632 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4633 if (currSCCB != NULL) {
4634
4635 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4636 currSCCB->Sccb_scsistat = ABORT_ST;
4637 currSCCB->Sccb_scsimsg = SMABORT;
4638 }
4639
4640 ACCEPT_MSG_ATN(port);
4641}
4642
4643
4644
4645/*---------------------------------------------------------------------
4646 *
4647 * Function: Phase Check FIFO
4648 *
4649 * Description: Make sure data has been flushed from both FIFOs and abort
4650 * the operations if necessary.
4651 *
4652 *---------------------------------------------------------------------*/
4653
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004654static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004655{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004656 unsigned long xfercnt;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004657 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004658
James Bottomley 47b5d692005-04-24 02:38:05 -05004659 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004660
4661 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4662 {
4663
4664 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4665 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4666
4667
4668 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4669 {
4670 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4671
4672 currSCCB->Sccb_XferCnt = 0;
4673
4674 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4675 (currSCCB->HostStatus == SCCB_COMPLETE))
4676 {
4677 currSCCB->HostStatus = SCCB_PARITY_ERR;
4678 WRW_HARPOON((port+hp_intstat), PARITY);
4679 }
4680
James Bottomley 47b5d692005-04-24 02:38:05 -05004681 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004682
James Bottomley 47b5d692005-04-24 02:38:05 -05004683 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004684
4685 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4686 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4687
4688 }
4689 } /*End Data In specific code. */
4690
4691
4692
Linus Torvalds1da177e2005-04-16 15:20:36 -07004693 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004694
4695
4696 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4697
4698
4699 WR_HARPOON(port+hp_portctrl_0, 0x00);
4700
4701 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4702
4703 currSCCB->Sccb_XferCnt = xfercnt;
4704
4705 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4706 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4707
4708 currSCCB->HostStatus = SCCB_PARITY_ERR;
4709 WRW_HARPOON((port+hp_intstat), PARITY);
4710 }
4711
4712
James Bottomley 47b5d692005-04-24 02:38:05 -05004713 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004714
4715
4716 WR_HARPOON(port+hp_fifowrite, 0x00);
4717 WR_HARPOON(port+hp_fiforead, 0x00);
4718 WR_HARPOON(port+hp_xferstat, 0x00);
4719
4720 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4721}
4722
4723
4724/*---------------------------------------------------------------------
4725 *
4726 * Function: Phase Bus Free
4727 *
4728 * Description: We just went bus free so figure out if it was
4729 * because of command complete or from a disconnect.
4730 *
4731 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004732static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004733{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004734 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004735
James Bottomley 47b5d692005-04-24 02:38:05 -05004736 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004737
4738 if (currSCCB != NULL)
4739 {
4740
4741 DISABLE_AUTO(port);
4742
4743
4744 if (currSCCB->OperationCode == RESET_COMMAND)
4745 {
4746
James Bottomley 47b5d692005-04-24 02:38:05 -05004747 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4748 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4749 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004750 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004751 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004752
James Bottomley 47b5d692005-04-24 02:38:05 -05004753 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004754
James Bottomley 47b5d692005-04-24 02:38:05 -05004755 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004756
4757 }
4758
4759 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4760 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004761 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004762 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004764 }
4765
4766 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4767 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004768 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4769 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004770 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4771
James Bottomley 47b5d692005-04-24 02:38:05 -05004772 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004773 }
4774
Linus Torvalds1da177e2005-04-16 15:20:36 -07004775 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4776 {
4777 /* Make sure this is not a phony BUS_FREE. If we were
4778 reselected or if BUSY is NOT on then this is a
4779 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4780
4781 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4782 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4783 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786 }
4787
4788 else
4789 {
4790 return;
4791 }
4792 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004793
4794 else
4795 {
4796
4797 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4798
4799 if (!currSCCB->HostStatus)
4800 {
4801 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4802 }
4803
James Bottomley 47b5d692005-04-24 02:38:05 -05004804 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4805 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4806 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004807 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004808 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004809
James Bottomley 47b5d692005-04-24 02:38:05 -05004810 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004811 return;
4812 }
4813
4814
James Bottomley 47b5d692005-04-24 02:38:05 -05004815 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004816
4817 } /*end if !=null */
4818}
4819
4820
4821
4822
Linus Torvalds1da177e2005-04-16 15:20:36 -07004823/*---------------------------------------------------------------------
4824 *
4825 * Function: Auto Load Default Map
4826 *
4827 * Description: Load the Automation RAM with the defualt map values.
4828 *
4829 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004830static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004831{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004832 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004833
4834 ARAM_ACCESS(p_port);
4835 map_addr = p_port + hp_aramBase;
4836
4837 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4838 map_addr +=2;
4839 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4840 map_addr +=2;
4841 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4842 map_addr +=2;
4843 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4844 map_addr +=2;
4845 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4846 map_addr +=2;
4847 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4848 map_addr +=2;
4849 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4850 map_addr +=2;
4851 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4852 map_addr +=2;
4853 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4872 map_addr +=2; /*This means AYNC DATA IN */
4873 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4888 map_addr +=2;
4889 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4908 map_addr +=2;
4909
4910 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4911 map_addr +=2;
4912 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4913 map_addr +=2;
4914 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4915 map_addr +=2;
4916 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4917 map_addr +=2; /* DIDN'T GET ONE */
4918 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4919 map_addr +=2;
4920 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4921 map_addr +=2;
4922 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4923
4924
4925
4926 SGRAM_ACCESS(p_port);
4927}
4928
4929/*---------------------------------------------------------------------
4930 *
4931 * Function: Auto Command Complete
4932 *
4933 * Description: Post command back to host and find another command
4934 * to execute.
4935 *
4936 *---------------------------------------------------------------------*/
4937
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004938static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004939{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004940 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004941 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004942
James Bottomley 47b5d692005-04-24 02:38:05 -05004943 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004944
4945 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4946
James Bottomley 47b5d692005-04-24 02:38:05 -05004947 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004948
4949 if (status_byte != SSGOOD) {
4950
4951 if (status_byte == SSQ_FULL) {
4952
4953
James Bottomley 47b5d692005-04-24 02:38:05 -05004954 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4955 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004956 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004957 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4958 if(FPT_BL_Card[p_card].discQCount != 0)
4959 FPT_BL_Card[p_card].discQCount--;
4960 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 -07004961 }
4962 else
4963 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004964 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004965 if(currSCCB->Sccb_tag)
4966 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004967 if(FPT_BL_Card[p_card].discQCount != 0)
4968 FPT_BL_Card[p_card].discQCount--;
4969 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004970 }else
4971 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004972 if(FPT_BL_Card[p_card].discQCount != 0)
4973 FPT_BL_Card[p_card].discQCount--;
4974 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004975 }
4976 }
4977
4978 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4979
James Bottomley 47b5d692005-04-24 02:38:05 -05004980 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004981
4982 return;
4983 }
4984
4985 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4986 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004987 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004988 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004989
James Bottomley 47b5d692005-04-24 02:38:05 -05004990 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4991 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004992
James Bottomley 47b5d692005-04-24 02:38:05 -05004993 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4994 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004995 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004996 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4997 if(FPT_BL_Card[p_card].discQCount != 0)
4998 FPT_BL_Card[p_card].discQCount--;
4999 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 -07005000 }
5001 else
5002 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005004 if(currSCCB->Sccb_tag)
5005 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005006 if(FPT_BL_Card[p_card].discQCount != 0)
5007 FPT_BL_Card[p_card].discQCount--;
5008 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005009 }else
5010 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005011 if(FPT_BL_Card[p_card].discQCount != 0)
5012 FPT_BL_Card[p_card].discQCount--;
5013 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005014 }
5015 }
5016 return;
5017
5018 }
5019
5020 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5021 {
5022
James Bottomley 47b5d692005-04-24 02:38:05 -05005023 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5024 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005025 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5026
James Bottomley 47b5d692005-04-24 02:38:05 -05005027 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5028 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005029
James Bottomley 47b5d692005-04-24 02:38:05 -05005030 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5031 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005032 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005033 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5034 if(FPT_BL_Card[p_card].discQCount != 0)
5035 FPT_BL_Card[p_card].discQCount--;
5036 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 -07005037 }
5038 else
5039 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005040 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005041 if(currSCCB->Sccb_tag)
5042 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005043 if(FPT_BL_Card[p_card].discQCount != 0)
5044 FPT_BL_Card[p_card].discQCount--;
5045 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005046 }else
5047 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005048 if(FPT_BL_Card[p_card].discQCount != 0)
5049 FPT_BL_Card[p_card].discQCount--;
5050 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005051 }
5052 }
5053 return;
5054
5055 }
5056
5057 if (status_byte == SSCHECK)
5058 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005059 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005060 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005061 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005062 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005063 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005064 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005065 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005066 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005067 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005068 }
5069 }
5070 }
5071
5072 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5073
5074 currSCCB->SccbStatus = SCCB_ERROR;
5075 currSCCB->TargetStatus = status_byte;
5076
5077 if (status_byte == SSCHECK) {
5078
James Bottomley 47b5d692005-04-24 02:38:05 -05005079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5080 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005081
5082
Linus Torvalds1da177e2005-04-16 15:20:36 -07005083 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5084
5085 if (currSCCB->RequestSenseLength == 0)
5086 currSCCB->RequestSenseLength = 14;
5087
James Bottomley 47b5d692005-04-24 02:38:05 -05005088 FPT_ssenss(&FPT_BL_Card[p_card]);
5089 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005090
James Bottomley 47b5d692005-04-24 02:38:05 -05005091 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5092 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005093 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005094 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5095 if(FPT_BL_Card[p_card].discQCount != 0)
5096 FPT_BL_Card[p_card].discQCount--;
5097 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 -07005098 }
5099 else
5100 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005101 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005102 if(currSCCB->Sccb_tag)
5103 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005104 if(FPT_BL_Card[p_card].discQCount != 0)
5105 FPT_BL_Card[p_card].discQCount--;
5106 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005107 }else
5108 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005109 if(FPT_BL_Card[p_card].discQCount != 0)
5110 FPT_BL_Card[p_card].discQCount--;
5111 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005112 }
5113 }
5114 return;
5115 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005116 }
5117 }
5118 }
5119
5120
James Bottomley 47b5d692005-04-24 02:38:05 -05005121 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5122 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5123 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005124 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005125 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005126
5127
James Bottomley 47b5d692005-04-24 02:38:05 -05005128 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005129}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005130
5131#define SHORT_WAIT 0x0000000F
5132#define LONG_WAIT 0x0000FFFFL
5133
Linus Torvalds1da177e2005-04-16 15:20:36 -07005134
5135/*---------------------------------------------------------------------
5136 *
5137 * Function: Data Transfer Processor
5138 *
5139 * Description: This routine performs two tasks.
5140 * (1) Start data transfer by calling HOST_DATA_XFER_START
5141 * function. Once data transfer is started, (2) Depends
5142 * on the type of data transfer mode Scatter/Gather mode
5143 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5144 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5145 * data transfer done. In Scatter/Gather mode, this routine
5146 * checks bus master command complete and dual rank busy
5147 * bit to keep chaining SC transfer command. Similarly,
5148 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5149 * (F_HOST_XFER_ACT bit) for data transfer done.
5150 *
5151 *---------------------------------------------------------------------*/
5152
Alexey Dobriyan13e68512006-03-08 00:14:34 -08005153static void FPT_dataXferProcessor(unsigned long port, struct sccb_card * pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005154{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005155 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005156
5157 currSCCB = pCurrCard->currentSCCB;
5158
5159 if (currSCCB->Sccb_XferState & F_SG_XFER)
5160 {
5161 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5162
5163 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005164 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005165 currSCCB->Sccb_SGoffset = 0x00;
5166 }
5167 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5168
James Bottomley 47b5d692005-04-24 02:38:05 -05005169 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005170 }
5171
5172 else
5173 {
5174 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5175 {
5176 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5177
James Bottomley 47b5d692005-04-24 02:38:05 -05005178 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005179 }
5180 }
5181}
5182
5183
5184/*---------------------------------------------------------------------
5185 *
5186 * Function: BusMaster Scatter Gather Data Transfer Start
5187 *
5188 * Description:
5189 *
5190 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005191static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005192{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005193 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005194 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005195 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005196 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005197
5198
5199 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5200
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005201 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005202 }
5203
5204 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005205 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005206 }
5207
5208 sg_count = 0;
5209 tmpSGCnt = 0;
5210 sg_index = pcurrSCCB->Sccb_sgseg;
5211 reg_offset = hp_aramBase;
5212
5213
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005214 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005215
5216
5217 WR_HARPOON(p_port+hp_page_ctrl, i);
5218
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005219 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005220 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005221
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005222 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005223 (sg_index * 2));
5224
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005225 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226 (sg_index * 2));
5227
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005228 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005230
5231
5232 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5233
5234 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5235 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5236
5237 tmpSGCnt = count & 0x00FFFFFFL;
5238 }
5239
5240 WR_HARP32(p_port,reg_offset,addr);
5241 reg_offset +=4;
5242
5243 WR_HARP32(p_port,reg_offset,count);
5244 reg_offset +=4;
5245
5246 count &= 0xFF000000L;
5247 sg_index++;
5248 sg_count++;
5249
5250 } /*End While */
5251
5252 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5253
5254 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5255
5256 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5257
5258 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5259
5260
5261 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5262 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5263 }
5264
5265 else {
5266
5267
5268 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5269 (tmpSGCnt & 0x000000001))
5270 {
5271
5272 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5273 tmpSGCnt--;
5274 }
5275
5276
5277 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5278
5279 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5280 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5281 }
5282
5283
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005284 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005285
5286}
5287
5288
5289/*---------------------------------------------------------------------
5290 *
5291 * Function: BusMaster Data Transfer Start
5292 *
5293 * Description:
5294 *
5295 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005296static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005297{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005298 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005299
5300 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5301
5302 count = pcurrSCCB->Sccb_XferCnt;
5303
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005304 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005305 }
5306
5307 else {
5308 addr = pcurrSCCB->SensePointer;
5309 count = pcurrSCCB->RequestSenseLength;
5310
5311 }
5312
Linus Torvalds1da177e2005-04-16 15:20:36 -07005313 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005314
5315
5316 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5317
5318 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5319 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5320
5321 WR_HARPOON(p_port+hp_xfer_cmd,
5322 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5323 }
5324
5325 else {
5326
5327 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5328 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5329
5330 WR_HARPOON(p_port+hp_xfer_cmd,
5331 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5332
5333 }
5334}
5335
5336
5337/*---------------------------------------------------------------------
5338 *
5339 * Function: BusMaster Timeout Handler
5340 *
5341 * Description: This function is called after a bus master command busy time
5342 * out is detected. This routines issue halt state machine
5343 * with a software time out for command busy. If command busy
5344 * is still asserted at the end of the time out, it issues
5345 * hard abort with another software time out. It hard abort
5346 * command busy is also time out, it'll just give up.
5347 *
5348 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005349static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005350{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005351 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005352
5353 timeout = LONG_WAIT;
5354
5355 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5356
5357 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5358
5359
5360
5361 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5362 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5363
5364 timeout = LONG_WAIT;
5365 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5366 }
5367
5368 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5369
5370 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005371 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005372 }
5373
5374 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005375 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005376 }
5377}
5378
5379
5380/*---------------------------------------------------------------------
5381 *
5382 * Function: Host Data Transfer Abort
5383 *
5384 * Description: Abort any in progress transfer.
5385 *
5386 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005387static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005388{
5389
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005390 unsigned long timeout;
5391 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005392 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005393
James Bottomley 47b5d692005-04-24 02:38:05 -05005394 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005395
5396 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5397
5398
5399 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5400
5401 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5402 timeout = LONG_WAIT;
5403
5404 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5405
5406 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5407
5408 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5409
James Bottomley 47b5d692005-04-24 02:38:05 -05005410 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005411
5412 if (pCurrSCCB->HostStatus == 0x00)
5413
5414 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5415
5416 }
5417
5418 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5419
5420 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5421
5422 if (pCurrSCCB->HostStatus == 0x00)
5423
5424 {
5425 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005426 }
5427 }
5428 }
5429 }
5430
5431 else if (pCurrSCCB->Sccb_XferCnt) {
5432
5433 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5434
5435
5436 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5437 ~SCATTER_EN));
5438
5439 WR_HARPOON(port+hp_sg_addr,0x00);
5440
5441 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5442
Alexey Dobriyance793212006-03-08 00:14:26 -08005443 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005444
Alexey Dobriyance793212006-03-08 00:14:26 -08005445 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005446 }
5447
5448 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5449
5450 while (remain_cnt < 0x01000000L) {
5451
5452 sg_ptr--;
5453
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005454 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005455 DataPointer) + (sg_ptr * 2)))) {
5456
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005457 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458 DataPointer) + (sg_ptr * 2)));
5459 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005460
5461 else {
5462
5463 break;
5464 }
5465 }
5466
5467
5468
5469 if (remain_cnt < 0x01000000L) {
5470
5471
5472 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5473
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005474 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005475
5476
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005477 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005478 && (remain_cnt == 0))
5479
5480 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5481 }
5482
5483 else {
5484
5485
5486 if (pCurrSCCB->HostStatus == 0x00) {
5487
5488 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5489 }
5490 }
5491 }
5492
5493
5494 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5495
5496
5497 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5498
James Bottomley 47b5d692005-04-24 02:38:05 -05005499 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005500 }
5501
5502 else {
5503
5504 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5505
5506 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5507
5508 if (pCurrSCCB->HostStatus == 0x00) {
5509
5510 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005511 }
5512 }
5513 }
5514
5515 }
5516 }
5517
5518 else {
5519
5520
5521 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5522
5523 timeout = SHORT_WAIT;
5524
5525 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5526 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5527 timeout--) {}
5528 }
5529
5530 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5531
5532 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5533 FLUSH_XFER_CNTR));
5534
5535 timeout = LONG_WAIT;
5536
5537 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5538 timeout--) {}
5539
5540 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5541 ~FLUSH_XFER_CNTR));
5542
5543
5544 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5545
5546 if (pCurrSCCB->HostStatus == 0x00) {
5547
5548 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5549 }
5550
James Bottomley 47b5d692005-04-24 02:38:05 -05005551 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005552 }
5553 }
5554
5555 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5556
5557 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5558
5559 if (pCurrSCCB->HostStatus == 0x00) {
5560
5561 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005562 }
5563 }
5564 }
5565 }
5566
5567 }
5568
5569 else {
5570
5571
5572 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5573
5574 timeout = LONG_WAIT;
5575
5576 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5577
5578 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5579
5580 if (pCurrSCCB->HostStatus == 0x00) {
5581
5582 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5583 }
5584
James Bottomley 47b5d692005-04-24 02:38:05 -05005585 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005586 }
5587 }
5588
5589
5590 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5591
5592 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5593
5594 if (pCurrSCCB->HostStatus == 0x00) {
5595
5596 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005597 }
5598 }
5599
5600 }
5601
5602 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5603
5604 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5605 ~SCATTER_EN));
5606
5607 WR_HARPOON(port+hp_sg_addr,0x00);
5608
5609 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5610
5611 pCurrSCCB->Sccb_SGoffset = 0x00;
5612
5613
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005614 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005615 pCurrSCCB->DataLength) {
5616
5617 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5618
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005619 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005620
5621 }
5622 }
5623
5624 else {
5625
5626 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5627
5628 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5629 }
5630 }
5631
5632 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5633}
5634
5635
5636
5637/*---------------------------------------------------------------------
5638 *
5639 * Function: Host Data Transfer Restart
5640 *
5641 * Description: Reset the available count due to a restore data
5642 * pointers message.
5643 *
5644 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005645static void FPT_hostDataXferRestart(struct sccb * currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005646{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005647 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005648 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005649 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005650
5651 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5652
5653 currSCCB->Sccb_XferCnt = 0;
5654
5655 sg_index = 0xffff; /*Index by long words into sg list. */
5656 data_count = 0; /*Running count of SG xfer counts. */
5657
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005658 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005659
5660 while (data_count < currSCCB->Sccb_ATC) {
5661
5662 sg_index++;
5663 data_count += *(sg_ptr+(sg_index * 2));
5664 }
5665
5666 if (data_count == currSCCB->Sccb_ATC) {
5667
5668 currSCCB->Sccb_SGoffset = 0;
5669 sg_index++;
5670 }
5671
5672 else {
5673 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5674 }
5675
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005676 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005677 }
5678
5679 else {
5680 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5681 }
5682}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005683
5684
5685
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686/*---------------------------------------------------------------------
5687 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005688 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689 *
5690 * Description: Setup all data structures necessary for SCAM selection.
5691 *
5692 *---------------------------------------------------------------------*/
5693
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005694static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005695{
5696
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005697 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005698 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005699
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005700 unsigned char i,k,ScamFlg ;
Alexey Dobriyan13e68512006-03-08 00:14:34 -08005701 struct sccb_card * currCard;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08005702 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005703
James Bottomley 47b5d692005-04-24 02:38:05 -05005704 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005705 p_port = currCard->ioPort;
5706 pCurrNvRam = currCard->pNvRamInfo;
5707
5708
5709 if(pCurrNvRam){
5710 ScamFlg = pCurrNvRam->niScamConf;
5711 i = pCurrNvRam->niSysConf;
5712 }
5713 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005714 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5715 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005716 }
5717 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5718 return;
5719
James Bottomley 47b5d692005-04-24 02:38:05 -05005720 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005721
5722 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5723 too slow to return to SCAM selection */
5724
5725 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005726 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005728 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005729
James Bottomley 47b5d692005-04-24 02:38:05 -05005730 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731
5732 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5733 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005734 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005735
James Bottomley 47b5d692005-04-24 02:38:05 -05005736 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005737
5738 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005739 FPT_scxferc(p_port,SYNC_PTRN);
5740 FPT_scxferc(p_port,DOM_MSTR);
5741 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005742 } while ( loser == 0xFF );
5743
James Bottomley 47b5d692005-04-24 02:38:05 -05005744 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005745
5746 if ((p_power_up) && (!loser))
5747 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005748 FPT_sresb(p_port,p_card);
5749 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005750
James Bottomley 47b5d692005-04-24 02:38:05 -05005751 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005752
James Bottomley 47b5d692005-04-24 02:38:05 -05005753 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005754
5755 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005756 FPT_scxferc(p_port, SYNC_PTRN);
5757 FPT_scxferc(p_port, DOM_MSTR);
5758 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759 id_string[0]);
5760 } while ( loser == 0xFF );
5761
James Bottomley 47b5d692005-04-24 02:38:05 -05005762 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763 }
5764 }
5765
5766 else
5767 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005768 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769 }
5770
5771
5772 if (!loser)
5773 {
5774
James Bottomley 47b5d692005-04-24 02:38:05 -05005775 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005776
5777
5778 if (ScamFlg & SCAM_ENABLED)
5779 {
5780
5781 for (i=0; i < MAX_SCSI_TAR; i++)
5782 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005783 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5784 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005785 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005786 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005787 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005788 FPT_scamInfo[i].state = LEGACY;
5789 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5790 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005791 {
5792
James Bottomley 47b5d692005-04-24 02:38:05 -05005793 FPT_scamInfo[i].id_string[0] = 0xFF;
5794 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005795 if(pCurrNvRam == NULL)
5796 currCard->globalFlags |= F_UPDATE_EEPROM;
5797 }
5798 }
5799 }
5800 }
5801
James Bottomley 47b5d692005-04-24 02:38:05 -05005802 FPT_sresb(p_port,p_card);
5803 FPT_Wait1Second(p_port);
5804 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5805 FPT_scsel(p_port);
5806 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005807 }
5808
Linus Torvalds1da177e2005-04-16 15:20:36 -07005809 }
5810
5811 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5812 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005813 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5814 assigned_id = 0;
5815 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005816
5817 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005818 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005819
James Bottomley 47b5d692005-04-24 02:38:05 -05005820 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005821 if (i == ASSIGN_ID)
5822 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005823 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005824 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005825 i = FPT_scxferc(p_port,0x00);
5826 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005827 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005828 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005829
James Bottomley 47b5d692005-04-24 02:38:05 -05005830 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005831 {
5832 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005833 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005834 FPT_inisci(p_card, p_port, p_our_id);
5835 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5836 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005837 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005838 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005839 }
5840 }
5841 }
5842 }
5843
5844 else if (i == SET_P_FLAG)
5845 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005846 if (!(FPT_scsendi(p_port,
5847 &FPT_scamInfo[p_our_id].id_string[0])))
5848 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005849 }
5850 }while (!assigned_id);
5851
James Bottomley 47b5d692005-04-24 02:38:05 -05005852 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 }
5854
Linus Torvalds1da177e2005-04-16 15:20:36 -07005855 if (ScamFlg & SCAM_ENABLED)
5856 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005857 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005858 if (currCard->globalFlags & F_UPDATE_EEPROM)
5859 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005860 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005861 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5862 }
5863 }
5864
5865
Linus Torvalds1da177e2005-04-16 15:20:36 -07005866/*
5867 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5868 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005869 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5870 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005871 k++;
5872 }
5873
5874 if (k==2)
5875 currCard->globalFlags |= F_SINGLE_DEVICE;
5876 else
5877 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5878*/
5879}
5880
5881
5882/*---------------------------------------------------------------------
5883 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005884 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005885 *
5886 * Description: Gain control of the bus and wait SCAM select time (250ms)
5887 *
5888 *---------------------------------------------------------------------*/
5889
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005890static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005891{
5892 if (p_sel_type == INIT_SELTD)
5893 {
5894
5895 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5896
5897
5898 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005899 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005900
5901 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005902 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005903
5904 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5905
5906 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5907
5908 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5909 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005910 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005911 }
5912
5913
5914 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5915
5916 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5917
5918 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5919 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005920 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005921 }
5922 }
5923
5924
5925 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5926 & ~ACTdeassert));
5927 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5928 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005929 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005930 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5931
5932 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5933
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5935 & ~SCSI_BSY));
5936
James Bottomley 47b5d692005-04-24 02:38:05 -05005937 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005938
James Bottomley 47b5d692005-04-24 02:38:05 -05005939 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005940}
5941
5942
5943/*---------------------------------------------------------------------
5944 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005945 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005946 *
5947 * Description: Release the SCSI bus and disable SCAM selection.
5948 *
5949 *---------------------------------------------------------------------*/
5950
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005951static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005952{
5953 WR_HARPOON(p_port+hp_page_ctrl,
5954 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5955
5956
5957 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5958
5959 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5960 & ~SCSI_BUS_EN));
5961
5962 WR_HARPOON(p_port+hp_scsisig, 0x00);
5963
5964
5965 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5966 & ~SCAM_EN));
5967
5968 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5969 | ACTdeassert));
5970
Linus Torvalds1da177e2005-04-16 15:20:36 -07005971 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005972
5973 WR_HARPOON(p_port+hp_page_ctrl,
5974 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5975}
5976
5977
5978
5979/*---------------------------------------------------------------------
5980 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005981 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005982 *
5983 * Description: Assign an ID to all the SCAM devices.
5984 *
5985 *---------------------------------------------------------------------*/
5986
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005987static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005988{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005989 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005990
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005991 unsigned char i,k,scam_id;
5992 unsigned char crcBytes[3];
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08005993 struct nvram_info * pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08005994 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005995
James Bottomley 47b5d692005-04-24 02:38:05 -05005996 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005997
James Bottomley 47b5d692005-04-24 02:38:05 -05005998 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005999
6000 while (!i)
6001 {
6002
6003 for (k=0; k < ID_STRING_LENGTH; k++)
6004 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006005 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006006 }
6007
James Bottomley 47b5d692005-04-24 02:38:05 -05006008 FPT_scxferc(p_port,SYNC_PTRN);
6009 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006010
James Bottomley 47b5d692005-04-24 02:38:05 -05006011 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006012 {
6013 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006014 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006015 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6016 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006017 temp_id_string[1] = crcBytes[2];
6018 temp_id_string[2] = crcBytes[0];
6019 temp_id_string[3] = crcBytes[1];
6020 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006021 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006022 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006023 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006024
6025 if (i == CLR_PRIORITY)
6026 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006027 FPT_scxferc(p_port,MISC_CODE);
6028 FPT_scxferc(p_port,CLR_P_FLAG);
6029 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006030 }
6031
6032 else if (i != NO_ID_AVAIL)
6033 {
6034 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006035 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006036 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006037 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006038
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006039 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006040
6041
6042 for (k=1; k < 0x08; k <<= 1)
6043 if (!( k & i ))
6044 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6045
James Bottomley 47b5d692005-04-24 02:38:05 -05006046 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006047
James Bottomley 47b5d692005-04-24 02:38:05 -05006048 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049 }
6050 }
6051
6052 else
6053 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006054 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006055 }
6056
6057 } /*End while */
6058
James Bottomley 47b5d692005-04-24 02:38:05 -05006059 FPT_scxferc(p_port,SYNC_PTRN);
6060 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006061}
6062
6063
6064
6065
6066
6067/*---------------------------------------------------------------------
6068 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006069 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006070 *
6071 * Description: Select all the SCAM devices.
6072 *
6073 *---------------------------------------------------------------------*/
6074
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006075static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006076{
6077
6078 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006079 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006080
6081 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6082
6083
6084 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006085 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6086 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006087
6088
6089 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006090 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006091
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006092 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6093 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006094 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006095
6096 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6097}
6098
6099
6100
6101/*---------------------------------------------------------------------
6102 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006103 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006104 *
6105 * Description: Handshake the p_data (DB4-0) across the bus.
6106 *
6107 *---------------------------------------------------------------------*/
6108
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006109static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006110{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006111 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006112
6113 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6114
6115 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6116
6117 curr_data &= ~BIT(7);
6118
6119 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6120
James Bottomley 47b5d692005-04-24 02:38:05 -05006121 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006122 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6123
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006124 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006125
6126 curr_data |= BIT(6);
6127
6128 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6129
6130 curr_data &= ~BIT(5);
6131
6132 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133
James Bottomley 47b5d692005-04-24 02:38:05 -05006134 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006135
6136 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6137 curr_data |= BIT(7);
6138
6139 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6140
6141 curr_data &= ~BIT(6);
6142
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6144
James Bottomley 47b5d692005-04-24 02:38:05 -05006145 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006146
6147 return(ret_data);
6148}
6149
6150
6151/*---------------------------------------------------------------------
6152 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006153 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006154 *
6155 * Description: Transfer our Identification string to determine if we
6156 * will be the dominant master.
6157 *
6158 *---------------------------------------------------------------------*/
6159
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006160static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006161{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006162 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006163
James Bottomley 47b5d692005-04-24 02:38:05 -05006164 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006165
6166 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6167
6168 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6169
6170 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006171 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006172
6173 else if (p_id_string[byte_cnt] & bit_cnt)
6174
James Bottomley 47b5d692005-04-24 02:38:05 -05006175 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006176
6177 else {
6178
James Bottomley 47b5d692005-04-24 02:38:05 -05006179 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006180 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006181 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006182 }
6183
6184 if ((ret_data & 0x1C) == 0x10)
6185 return(0x00); /*End of isolation stage, we won! */
6186
6187 if (ret_data & 0x1C)
6188 return(0xFF);
6189
6190 if ((defer) && (!(ret_data & 0x1F)))
6191 return(0x01); /*End of isolation stage, we lost. */
6192
6193 } /*bit loop */
6194
6195 } /*byte loop */
6196
6197 if (defer)
6198 return(0x01); /*We lost */
6199 else
6200 return(0); /*We WON! Yeeessss! */
6201}
6202
6203
6204
6205/*---------------------------------------------------------------------
6206 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006207 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006208 *
6209 * Description: Transfer the Identification string.
6210 *
6211 *---------------------------------------------------------------------*/
6212
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006213static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006214{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006215 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006216
6217 the_data = 0;
6218
6219 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6220
6221 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6222
James Bottomley 47b5d692005-04-24 02:38:05 -05006223 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006224
6225 if (ret_data & 0xFC)
6226 return(0xFF);
6227
6228 else {
6229
6230 the_data <<= 1;
6231 if (ret_data & BIT(1)) {
6232 the_data |= 1;
6233 }
6234 }
6235
6236 if ((ret_data & 0x1F) == 0)
6237 {
6238/*
6239 if(bit_cnt != 0 || bit_cnt != 8)
6240 {
6241 byte_cnt = 0;
6242 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006243 FPT_scxferc(p_port, SYNC_PTRN);
6244 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006245 continue;
6246 }
6247*/
6248 if (byte_cnt)
6249 return(0x00);
6250 else
6251 return(0xFF);
6252 }
6253
6254 } /*bit loop */
6255
6256 p_id_string[byte_cnt] = the_data;
6257
6258 } /*byte loop */
6259
6260 return(0);
6261}
6262
6263
6264
6265/*---------------------------------------------------------------------
6266 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006267 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006268 *
6269 * Description: Sample the SCSI data bus making sure the signal has been
6270 * deasserted for the correct number of consecutive samples.
6271 *
6272 *---------------------------------------------------------------------*/
6273
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006274static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006275{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006276 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006277
6278 i = 0;
6279 while ( i < MAX_SCSI_TAR ) {
6280
6281 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6282
6283 i = 0;
6284
6285 else
6286
6287 i++;
6288
6289 }
6290}
6291
6292
6293
6294/*---------------------------------------------------------------------
6295 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006296 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006297 *
6298 * Description: Sample the SCSI Signal lines making sure the signal has been
6299 * deasserted for the correct number of consecutive samples.
6300 *
6301 *---------------------------------------------------------------------*/
6302
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006303static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006304{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006305 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006306
6307 i = 0;
6308 while ( i < MAX_SCSI_TAR ) {
6309
6310 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6311
6312 i = 0;
6313
6314 else
6315
6316 i++;
6317
6318 }
6319}
6320
6321
6322/*---------------------------------------------------------------------
6323 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006324 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006325 *
6326 * Description: Make sure we received a valid data byte.
6327 *
6328 *---------------------------------------------------------------------*/
6329
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006330static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006331{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006332 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006333
6334 for (count=1; count < 0x08; count<<=1) {
6335 if (!(p_quintet & count))
6336 p_quintet -= 0x80;
6337 }
6338
6339 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006340 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006341
6342 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006343 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006344}
6345
6346
6347/*---------------------------------------------------------------------
6348 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006349 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006350 *
6351 * Description: Select the specified device ID using a selection timeout
6352 * less than 4ms. If somebody responds then it is a legacy
6353 * drive and this ID must be marked as such.
6354 *
6355 *---------------------------------------------------------------------*/
6356
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006357static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006358{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006359 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006360
6361 WR_HARPOON(p_port+hp_page_ctrl,
6362 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6363
6364 ARAM_ACCESS(p_port);
6365
6366 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6367 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6368
6369
6370 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6371 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6372 }
6373 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6374
6375 WRW_HARPOON((p_port+hp_intstat),
6376 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6377
6378 WR_HARPOON(p_port+hp_select_id, targ_id);
6379
6380 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6381 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6382 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6383
6384
6385 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6386 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6387
6388 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006389 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390
6391 DISABLE_AUTO(p_port);
6392
6393 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6394 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6395
6396 SGRAM_ACCESS(p_port);
6397
6398 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6399
6400 WRW_HARPOON((p_port+hp_intstat),
6401 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6402
6403 WR_HARPOON(p_port+hp_page_ctrl,
6404 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6405
James Bottomley 47b5d692005-04-24 02:38:05 -05006406 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006407 }
6408
6409 else {
6410
6411 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6412 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6413 {
6414 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6415 ACCEPT_MSG(p_port);
6416 }
6417 }
6418
6419 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6420
6421 WR_HARPOON(p_port+hp_page_ctrl,
6422 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6423
James Bottomley 47b5d692005-04-24 02:38:05 -05006424 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006425 }
6426}
6427
Linus Torvalds1da177e2005-04-16 15:20:36 -07006428/*---------------------------------------------------------------------
6429 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006430 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006431 *
6432 * Description: Wait to be selected by another SCAM initiator.
6433 *
6434 *---------------------------------------------------------------------*/
6435
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006436static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006437{
6438 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6439}
6440
6441
6442/*---------------------------------------------------------------------
6443 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006444 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006445 *
6446 * Description: Setup the data Structure with the info from the EEPROM.
6447 *
6448 *---------------------------------------------------------------------*/
6449
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006450static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006451{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006452 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006453 unsigned short ee_data;
Alexey Dobriyan68d0c1a2006-03-08 00:14:33 -08006454 struct nvram_info * pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006455
James Bottomley 47b5d692005-04-24 02:38:05 -05006456 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457
6458 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6459 max_id = 0x08;
6460
6461 else
6462 max_id = 0x10;
6463
6464 if(pCurrNvRam){
6465 for(i = 0; i < max_id; i++){
6466
6467 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006468 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006469 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006470 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006471
James Bottomley 47b5d692005-04-24 02:38:05 -05006472 if(FPT_scamInfo[i].id_string[0] == 0x00)
6473 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006474 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006475 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006476
6477 }
6478 }else {
6479 for (i=0; i < max_id; i++)
6480 {
6481 for (k=0; k < ID_STRING_LENGTH; k+=2)
6482 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006483 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6484 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006485 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006486 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006487 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006488 }
6489
James Bottomley 47b5d692005-04-24 02:38:05 -05006490 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6491 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006492
James Bottomley 47b5d692005-04-24 02:38:05 -05006493 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006494
6495 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006496 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497
6498 }
6499 }
6500 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006501 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006502
6503}
6504
6505/*---------------------------------------------------------------------
6506 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006507 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508 *
6509 * Description: Match the Device ID string with our values stored in
6510 * the EEPROM.
6511 *
6512 *---------------------------------------------------------------------*/
6513
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006514static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006515{
6516
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006517 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518
6519
6520 for (i=0; i < MAX_SCSI_TAR; i++) {
6521
James Bottomley 47b5d692005-04-24 02:38:05 -05006522 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006523
6524 for (k=0; k < ID_STRING_LENGTH; k++)
6525 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006526 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6527 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006528 }
6529
6530 if (match)
6531 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006532 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006533 return(i);
6534 }
6535
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536 }
6537
6538
6539
6540 if (p_id_string[0] & BIT(5))
6541 i = 8;
6542 else
6543 i = MAX_SCSI_TAR;
6544
6545 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006546 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547 else
6548 match = 7;
6549
6550 while (i > 0)
6551 {
6552 i--;
6553
James Bottomley 47b5d692005-04-24 02:38:05 -05006554 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555 {
6556 for (k=0; k < ID_STRING_LENGTH; k++)
6557 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006558 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006559 }
6560
James Bottomley 47b5d692005-04-24 02:38:05 -05006561 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562
James Bottomley 47b5d692005-04-24 02:38:05 -05006563 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6564 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565 return(match);
6566
6567 }
6568
6569
6570 match--;
6571
6572 if (match == 0xFF)
6573 {
6574 if (p_id_string[0] & BIT(5))
6575 match = 7;
6576 else
6577 match = MAX_SCSI_TAR-1;
6578 }
6579 }
6580
6581
6582
6583 if (p_id_string[0] & BIT(7))
6584 {
6585 return(CLR_PRIORITY);
6586 }
6587
6588
6589 if (p_id_string[0] & BIT(5))
6590 i = 8;
6591 else
6592 i = MAX_SCSI_TAR;
6593
6594 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006595 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006596 else
6597 match = 7;
6598
6599 while (i > 0)
6600 {
6601
6602 i--;
6603
James Bottomley 47b5d692005-04-24 02:38:05 -05006604 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006605 {
6606 for (k=0; k < ID_STRING_LENGTH; k++)
6607 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006608 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006609 }
6610
James Bottomley 47b5d692005-04-24 02:38:05 -05006611 FPT_scamInfo[match].id_string[0] |= BIT(7);
6612 FPT_scamInfo[match].state = ID_ASSIGNED;
6613 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6614 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006615 return(match);
6616
6617 }
6618
6619
6620 match--;
6621
6622 if (match == 0xFF)
6623 {
6624 if (p_id_string[0] & BIT(5))
6625 match = 7;
6626 else
6627 match = MAX_SCSI_TAR-1;
6628 }
6629 }
6630
6631 return(NO_ID_AVAIL);
6632}
6633
6634
6635/*---------------------------------------------------------------------
6636 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006637 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006638 *
6639 * Description: Save off the device SCAM ID strings.
6640 *
6641 *---------------------------------------------------------------------*/
6642
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006643static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006644{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006645 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006646 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006647
6648
6649 sum_data = 0x0000;
6650
6651 for (i = 1; i < EE_SCAMBASE/2; i++)
6652 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006653 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006654 }
6655
6656
James Bottomley 47b5d692005-04-24 02:38:05 -05006657 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006658
6659 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6660 max_id = 0x08;
6661
6662 else
6663 max_id = 0x10;
6664
6665 for (i=0; i < max_id; i++)
6666 {
6667
6668 for (k=0; k < ID_STRING_LENGTH; k+=2)
6669 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006670 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006671 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006672 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006673 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006674 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6675 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676 }
6677 }
6678
6679
James Bottomley 47b5d692005-04-24 02:38:05 -05006680 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6681 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006682}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006683
6684/*---------------------------------------------------------------------
6685 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006686 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006687 *
6688 * Description: Setup the Xbow for normal operation.
6689 *
6690 *---------------------------------------------------------------------*/
6691
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006692static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006693{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006694unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006695
6696 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006697 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698
6699 WR_HARPOON(port+hp_scsireset,0x00);
6700 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6701
6702 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6703 FIFO_CLR));
6704
6705 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6706
6707 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6708
6709 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6710 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6711
6712 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6713
James Bottomley 47b5d692005-04-24 02:38:05 -05006714 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006715 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6716
6717 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006718 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719
James Bottomley 47b5d692005-04-24 02:38:05 -05006720 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006721
6722 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6723
6724 /* Turn on SCSI_MODE8 for narrow cards to fix the
6725 strapping issue with the DUAL CHANNEL card */
6726 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6727 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6728
Linus Torvalds1da177e2005-04-16 15:20:36 -07006729 WR_HARPOON(port+hp_page_ctrl, i);
6730
6731}
6732
6733
6734/*---------------------------------------------------------------------
6735 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006736 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006737 *
6738 * Description: Initialize the BusMaster for normal operations.
6739 *
6740 *---------------------------------------------------------------------*/
6741
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006742static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006743{
6744
6745
6746 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6747 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6748
6749 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6750
6751
6752 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6753
6754 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6755
6756
Linus Torvalds1da177e2005-04-16 15:20:36 -07006757 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6758 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6759 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6760 ~SCATTER_EN));
6761}
6762
6763
6764/*---------------------------------------------------------------------
6765 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006766 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006767 *
6768 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6769 * necessary.
6770 *
6771 *---------------------------------------------------------------------*/
6772
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006773static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006774{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006775 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006776
6777 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6778 max_wd_cnt = EEPROM_WD_CNT;
6779 else
6780 max_wd_cnt = EEPROM_WD_CNT * 2;
6781
James Bottomley 47b5d692005-04-24 02:38:05 -05006782 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006783
6784 if (temp == 0x4641) {
6785
6786 for (index = 2; index < max_wd_cnt; index++) {
6787
James Bottomley 47b5d692005-04-24 02:38:05 -05006788 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789
6790 }
6791
James Bottomley 47b5d692005-04-24 02:38:05 -05006792 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006793
6794 return; /*EEPROM is Okay so return now! */
6795 }
6796 }
6797
6798
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006799 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006800
6801 for (index = 0; index < max_wd_cnt; index++) {
6802
James Bottomley 47b5d692005-04-24 02:38:05 -05006803 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006804 }
6805
6806 temp = 0;
6807
James Bottomley 47b5d692005-04-24 02:38:05 -05006808 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006809 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006810 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006811 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006812 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006813 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006814 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006816 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006817 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006818 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006819 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006820 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006822 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006823 temp += 0x0007;
6824
James Bottomley 47b5d692005-04-24 02:38:05 -05006825 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006827 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/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, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006830 temp += 0x0000;
6831
James Bottomley 47b5d692005-04-24 02:38:05 -05006832 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006834 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/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_TBL45/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_TBL67/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_TBL89/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_TBLab/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_TBLcd/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_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006847 temp += 0x4242;
6848
6849
James Bottomley 47b5d692005-04-24 02:38:05 -05006850 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006852 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006854 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006856 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006857 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006858 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006859 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006860 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006861 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006862 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006863 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006864 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865 temp += 0x2020;
6866
6867 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869 temp += (0x0700+TYPE_CODE0);
6870 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006871 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872 temp += 0x5542; /* BUSLOGIC */
6873 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006874 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 temp += 0x4C53;
6876 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006877 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006878 temp += 0x474F;
6879 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006880 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881 temp += 0x4349;
6882 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006883 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006884 temp += 0x5442; /* BT- 930 */
6885 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006886 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887 temp += 0x202D;
6888 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006889 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890 temp += 0x3339;
6891 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006892 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006893 temp += 0x2030;
6894 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006895 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006896 temp += 0x5453;
6897 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006898 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006899 temp += 0x5645;
6900 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006901 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006902 temp += 0x2045;
6903 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006904 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006905 temp += 0x202F;
6906 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006907 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006908 temp += 0x4F4A;
6909 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006910 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911 temp += 0x204E;
6912 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006913 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006914 temp += 0x3539;
6915
6916
6917
James Bottomley 47b5d692005-04-24 02:38:05 -05006918 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006919
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006920 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006921
6922}
6923
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924
6925/*---------------------------------------------------------------------
6926 *
6927 * Function: Queue Search Select
6928 *
6929 * Description: Try to find a new command to execute.
6930 *
6931 *---------------------------------------------------------------------*/
6932
Alexey Dobriyan13e68512006-03-08 00:14:34 -08006933static void FPT_queueSearchSelect(struct sccb_card * pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006935 unsigned char scan_ptr, lun;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08006936 struct sccb_mgr_tar_info * currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006937 struct sccb * pOldSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006938
6939 scan_ptr = pCurrCard->scanIndex;
6940 do
6941 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006942 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006943 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6944 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6945 {
6946 if (currTar_Info->TarSelQ_Cnt != 0)
6947 {
6948
6949 scan_ptr++;
6950 if (scan_ptr == MAX_SCSI_TAR)
6951 scan_ptr = 0;
6952
6953 for(lun=0; lun < MAX_LUN; lun++)
6954 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006955 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006956 {
6957
6958 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6959 pOldSccb = NULL;
6960
6961 while((pCurrCard->currentSCCB != NULL) &&
6962 (lun != pCurrCard->currentSCCB->Lun))
6963 {
6964 pOldSccb = pCurrCard->currentSCCB;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006965 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006966 Sccb_forwardlink;
6967 }
6968 if(pCurrCard->currentSCCB == NULL)
6969 continue;
6970 if(pOldSccb != NULL)
6971 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006972 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006973 Sccb_forwardlink;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006974 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006975 Sccb_backlink;
6976 currTar_Info->TarSelQ_Cnt--;
6977 }
6978 else
6979 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006980 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006981
6982 if (currTar_Info->TarSelQ_Head == NULL)
6983 {
6984 currTar_Info->TarSelQ_Tail = NULL;
6985 currTar_Info->TarSelQ_Cnt = 0;
6986 }
6987 else
6988 {
6989 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006990 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006991 }
6992 }
6993 pCurrCard->scanIndex = scan_ptr;
6994
6995 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6996
6997 break;
6998 }
6999 }
7000 }
7001
7002 else
7003 {
7004 scan_ptr++;
7005 if (scan_ptr == MAX_SCSI_TAR) {
7006 scan_ptr = 0;
7007 }
7008 }
7009
7010 }
7011 else
7012 {
7013 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007014 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007015 {
7016
7017 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7018
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007019 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007020
7021 if (currTar_Info->TarSelQ_Head == NULL)
7022 {
7023 currTar_Info->TarSelQ_Tail = NULL;
7024 currTar_Info->TarSelQ_Cnt = 0;
7025 }
7026 else
7027 {
7028 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007029 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007030 }
7031
7032 scan_ptr++;
7033 if (scan_ptr == MAX_SCSI_TAR)
7034 scan_ptr = 0;
7035
7036 pCurrCard->scanIndex = scan_ptr;
7037
7038 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7039
7040 break;
7041 }
7042
7043 else
7044 {
7045 scan_ptr++;
7046 if (scan_ptr == MAX_SCSI_TAR)
7047 {
7048 scan_ptr = 0;
7049 }
7050 }
7051 }
7052 } while (scan_ptr != pCurrCard->scanIndex);
7053}
7054
7055
7056/*---------------------------------------------------------------------
7057 *
7058 * Function: Queue Select Fail
7059 *
7060 * Description: Add the current SCCB to the head of the Queue.
7061 *
7062 *---------------------------------------------------------------------*/
7063
Alexey Dobriyan13e68512006-03-08 00:14:34 -08007064static void FPT_queueSelectFail(struct sccb_card * pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007065{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007066 unsigned char thisTarg;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007067 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007068
7069 if (pCurrCard->currentSCCB != NULL)
7070 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007071 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007072 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007073
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007074 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007075
7076 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7077
7078 if (currTar_Info->TarSelQ_Cnt == 0)
7079 {
7080 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7081 }
7082
7083 else
7084 {
7085 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7086 }
7087
7088
7089 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7090
7091 pCurrCard->currentSCCB = NULL;
7092 currTar_Info->TarSelQ_Cnt++;
7093 }
7094}
7095/*---------------------------------------------------------------------
7096 *
7097 * Function: Queue Command Complete
7098 *
7099 * Description: Call the callback function with the current SCCB.
7100 *
7101 *---------------------------------------------------------------------*/
7102
Alexey Dobriyan13e68512006-03-08 00:14:34 -08007103static void FPT_queueCmdComplete(struct sccb_card * pCurrCard, struct sccb * p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007104 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007105{
7106
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007107 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007108 CALL_BK_FN callback;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007109 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007110
7111 SCSIcmd = p_sccb->Cdb[0];
7112
7113
7114 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7115
7116 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7117 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7118 (p_sccb->TargetStatus != SSCHECK))
7119
7120 if ((SCSIcmd == SCSI_READ) ||
7121 (SCSIcmd == SCSI_WRITE) ||
7122 (SCSIcmd == SCSI_READ_EXTENDED) ||
7123 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7124 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7125 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7126 (pCurrCard->globalFlags & F_NO_FILTER)
7127 )
7128 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7129 }
7130
7131
7132 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7133 {
7134 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7135 p_sccb->SccbStatus = SCCB_ERROR;
7136 else
7137 p_sccb->SccbStatus = SCCB_SUCCESS;
7138 }
7139
7140 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7141
7142 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7143 for (i=0; i < 6; i++) {
7144 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7145 }
7146 }
7147
7148 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7149 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7150
James Bottomley 47b5d692005-04-24 02:38:05 -05007151 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007152 }
7153
7154 pCurrCard->cmdCounter--;
7155 if (!pCurrCard->cmdCounter) {
7156
7157 if (pCurrCard->globalFlags & F_GREEN_PC) {
7158 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7159 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7160 }
7161
7162 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7163 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7164
7165 }
7166
7167 if(pCurrCard->discQCount != 0)
7168 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007169 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007170 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7171 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7172 {
7173 pCurrCard->discQCount--;
7174 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7175 }
7176 else
7177 {
7178 if(p_sccb->Sccb_tag)
7179 {
7180 pCurrCard->discQCount--;
7181 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7182 }else
7183 {
7184 pCurrCard->discQCount--;
7185 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7186 }
7187 }
7188
7189 }
7190
7191 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7192 callback(p_sccb);
7193 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7194 pCurrCard->currentSCCB = NULL;
7195}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007196
7197
7198/*---------------------------------------------------------------------
7199 *
7200 * Function: Queue Disconnect
7201 *
7202 * Description: Add SCCB to our disconnect array.
7203 *
7204 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007205static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007206{
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007207 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007208
James Bottomley 47b5d692005-04-24 02:38:05 -05007209 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007210
James Bottomley 47b5d692005-04-24 02:38:05 -05007211 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007212 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7213 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007214 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007215 }
7216 else
7217 {
7218 if (p_sccb->Sccb_tag)
7219 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007220 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7221 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7222 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007223 }else
7224 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007225 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007226 }
7227 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007228 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007229}
7230
7231
7232/*---------------------------------------------------------------------
7233 *
7234 * Function: Queue Flush SCCB
7235 *
7236 * Description: Flush all SCCB's back to the host driver for this target.
7237 *
7238 *---------------------------------------------------------------------*/
7239
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007240static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007241{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007242 unsigned char qtag,thisTarg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007243 struct sccb * currSCCB;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007244 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007245
James Bottomley 47b5d692005-04-24 02:38:05 -05007246 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007247 if(currSCCB != NULL)
7248 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007249 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007250 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007251
7252 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7253
James Bottomley 47b5d692005-04-24 02:38:05 -05007254 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7255 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007256 {
7257
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007258 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007259
James Bottomley 47b5d692005-04-24 02:38:05 -05007260 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007261
James Bottomley 47b5d692005-04-24 02:38:05 -05007262 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007263 currTar_Info->TarTagQ_Cnt--;
7264
7265 }
7266 }
7267 }
7268
7269}
7270
7271/*---------------------------------------------------------------------
7272 *
7273 * Function: Queue Flush Target SCCB
7274 *
7275 * Description: Flush all SCCB's back to the host driver for this target.
7276 *
7277 *---------------------------------------------------------------------*/
7278
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007279static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7280 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007281{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007282 unsigned char qtag;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007283 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007284
James Bottomley 47b5d692005-04-24 02:38:05 -05007285 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007286
7287 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7288
James Bottomley 47b5d692005-04-24 02:38:05 -05007289 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7290 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007291 {
7292
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007293 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007294
James Bottomley 47b5d692005-04-24 02:38:05 -05007295 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007296
James Bottomley 47b5d692005-04-24 02:38:05 -05007297 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007298 currTar_Info->TarTagQ_Cnt--;
7299
7300 }
7301 }
7302
7303}
7304
7305
7306
7307
7308
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007309static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007310{
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007311 struct sccb_mgr_tar_info * currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007312 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007313
7314 p_SCCB->Sccb_forwardlink = NULL;
7315
7316 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7317
7318 if (currTar_Info->TarSelQ_Cnt == 0) {
7319
7320 currTar_Info->TarSelQ_Head = p_SCCB;
7321 }
7322
7323 else {
7324
7325 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7326 }
7327
7328
7329 currTar_Info->TarSelQ_Tail = p_SCCB;
7330 currTar_Info->TarSelQ_Cnt++;
7331}
7332
7333
7334/*---------------------------------------------------------------------
7335 *
7336 * Function: Queue Find SCCB
7337 *
7338 * Description: Search the target select Queue for this SCCB, and
7339 * remove it if found.
7340 *
7341 *---------------------------------------------------------------------*/
7342
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007343static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007344{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007345 struct sccb * q_ptr;
Alexey Dobriyanf31dc0cd2006-03-08 00:14:31 -08007346 struct sccb_mgr_tar_info * currTar_Info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007347
James Bottomley 47b5d692005-04-24 02:38:05 -05007348 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007349
7350 q_ptr = currTar_Info->TarSelQ_Head;
7351
7352 while(q_ptr != NULL) {
7353
7354 if (q_ptr == p_SCCB) {
7355
7356
7357 if (currTar_Info->TarSelQ_Head == q_ptr) {
7358
7359 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7360 }
7361
7362 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7363
7364 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7365 }
7366
7367 if (q_ptr->Sccb_forwardlink != NULL) {
7368 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7369 }
7370
7371 if (q_ptr->Sccb_backlink != NULL) {
7372 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7373 }
7374
7375 currTar_Info->TarSelQ_Cnt--;
7376
James Bottomley 47b5d692005-04-24 02:38:05 -05007377 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007378 }
7379
7380 else {
7381 q_ptr = q_ptr->Sccb_forwardlink;
7382 }
7383 }
7384
7385
James Bottomley 47b5d692005-04-24 02:38:05 -05007386 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007387
7388}
7389
7390
7391/*---------------------------------------------------------------------
7392 *
7393 * Function: Utility Update Residual Count
7394 *
7395 * Description: Update the XferCnt to the remaining byte count.
7396 * If we transferred all the data then just write zero.
7397 * If Non-SG transfer then report Total Cnt - Actual Transfer
7398 * Cnt. For SG transfers add the count fields of all
7399 * remaining SG elements, as well as any partial remaining
7400 * element.
7401 *
7402 *---------------------------------------------------------------------*/
7403
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007404static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007405{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007406 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007407 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007408 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007409
7410 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7411
7412 p_SCCB->DataLength = 0x0000;
7413 }
7414
7415 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7416
7417 partial_cnt = 0x0000;
7418
7419 sg_index = p_SCCB->Sccb_sgseg;
7420
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007421 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007422
7423 if (p_SCCB->Sccb_SGoffset) {
7424
7425 partial_cnt = p_SCCB->Sccb_SGoffset;
7426 sg_index++;
7427 }
7428
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007429 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007430 p_SCCB->DataLength ) {
7431
7432 partial_cnt += *(sg_ptr+(sg_index * 2));
7433 sg_index++;
7434 }
7435
7436 p_SCCB->DataLength = partial_cnt;
7437 }
7438
7439 else {
7440
7441 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7442 }
7443}
7444
7445
7446/*---------------------------------------------------------------------
7447 *
7448 * Function: Wait 1 Second
7449 *
7450 * Description: Wait for 1 second.
7451 *
7452 *---------------------------------------------------------------------*/
7453
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007454static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007455{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007456 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007457
7458 for(i=0; i < 4; i++) {
7459
James Bottomley 47b5d692005-04-24 02:38:05 -05007460 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007461
7462 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7463 break;
7464
7465 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7466 break;
7467 }
7468}
7469
7470
7471/*---------------------------------------------------------------------
7472 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007473 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007474 *
7475 * Description: Wait the desired delay.
7476 *
7477 *---------------------------------------------------------------------*/
7478
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007479static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007480{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007481 unsigned char old_timer;
7482 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007483
7484 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7485
7486 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7487 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7488
7489 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7490 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007491 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007492
7493
7494 WR_HARPOON(p_port+hp_portctrl_0,
7495 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7496
7497 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7498
7499 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7500 break;
7501
7502 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7503 break;
7504 }
7505
7506 WR_HARPOON(p_port+hp_portctrl_0,
7507 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7508
7509 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007510 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007511
7512 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7513
7514 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7515}
7516
7517
7518/*---------------------------------------------------------------------
7519 *
7520 * Function: Enable/Disable Write to EEPROM
7521 *
7522 * Description: The EEPROM must first be enabled for writes
7523 * A total of 9 clocks are needed.
7524 *
7525 *---------------------------------------------------------------------*/
7526
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007527static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007528{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007529 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007530
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007531 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 -07007532
7533 if (p_mode)
7534
James Bottomley 47b5d692005-04-24 02:38:05 -05007535 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007536
7537 else
7538
7539
James Bottomley 47b5d692005-04-24 02:38:05 -05007540 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007541
7542 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7543 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7544}
7545
7546
7547/*---------------------------------------------------------------------
7548 *
7549 * Function: Write EEPROM
7550 *
7551 * Description: Write a word to the EEPROM at the specified
7552 * address.
7553 *
7554 *---------------------------------------------------------------------*/
7555
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007556static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007557{
7558
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007559 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007560 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007561
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007562 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 -07007563 (SEE_MS | SEE_CS));
7564
7565
7566
James Bottomley 47b5d692005-04-24 02:38:05 -05007567 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007568
7569
7570 ee_value |= (SEE_MS + SEE_CS);
7571
7572 for(i = 0x8000; i != 0; i>>=1) {
7573
7574 if (i & ee_data)
7575 ee_value |= SEE_DO;
7576 else
7577 ee_value &= ~SEE_DO;
7578
7579 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7580 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7581 ee_value |= SEE_CLK; /* Clock data! */
7582 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7583 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7584 ee_value &= ~SEE_CLK;
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7587 }
7588 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7589 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7590
James Bottomley 47b5d692005-04-24 02:38:05 -05007591 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007592
7593 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7594 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7596}
7597
7598/*---------------------------------------------------------------------
7599 *
7600 * Function: Read EEPROM
7601 *
7602 * Description: Read a word from the EEPROM at the desired
7603 * address.
7604 *
7605 *---------------------------------------------------------------------*/
7606
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007607static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007608{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007609 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007610
7611 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007612 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007613 do
7614 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007615 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007616
7617 if(ee_data1 == ee_data2)
7618 return(ee_data1);
7619
7620 ee_data1 = ee_data2;
7621 i++;
7622
7623 }while(i < 4);
7624
7625 return(ee_data1);
7626}
7627
7628/*---------------------------------------------------------------------
7629 *
7630 * Function: Read EEPROM Original
7631 *
7632 * Description: Read a word from the EEPROM at the desired
7633 * address.
7634 *
7635 *---------------------------------------------------------------------*/
7636
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007637static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007638{
7639
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007640 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007641 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007642
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007643 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 -07007644 (SEE_MS | SEE_CS));
7645
7646
James Bottomley 47b5d692005-04-24 02:38:05 -05007647 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007648
7649
7650 ee_value |= (SEE_MS + SEE_CS);
7651 ee_data = 0;
7652
7653 for(i = 1; i <= 16; i++) {
7654
7655 ee_value |= SEE_CLK; /* Clock data! */
7656 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7657 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7658 ee_value &= ~SEE_CLK;
7659 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7661
7662 ee_data <<= 1;
7663
7664 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7665 ee_data |= 1;
7666 }
7667
7668 ee_value &= ~(SEE_MS + SEE_CS);
7669 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7671
7672 return(ee_data);
7673}
7674
7675
7676/*---------------------------------------------------------------------
7677 *
7678 * Function: Send EE command and Address to the EEPROM
7679 *
7680 * Description: Transfers the correct command and sends the address
7681 * to the eeprom.
7682 *
7683 *---------------------------------------------------------------------*/
7684
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007685static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007686{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007687 unsigned char ee_value;
7688 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007689
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007690 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007691
7692
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007693 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007694
7695
7696 ee_value = SEE_MS;
7697 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7698
7699 ee_value |= SEE_CS; /* Set CS to EEPROM */
7700 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7701
7702
7703 for(i = 0x04; i != 0; i>>=1) {
7704
7705 if (i & ee_cmd)
7706 ee_value |= SEE_DO;
7707 else
7708 ee_value &= ~SEE_DO;
7709
7710 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712 ee_value |= SEE_CLK; /* Clock data! */
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 ee_value &= ~SEE_CLK;
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 }
7719
7720
7721 if (narrow_flg)
7722 i = 0x0080;
7723
7724 else
7725 i = 0x0200;
7726
7727
7728 while (i != 0) {
7729
7730 if (i & ee_addr)
7731 ee_value |= SEE_DO;
7732 else
7733 ee_value &= ~SEE_DO;
7734
7735 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7736 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7737 ee_value |= SEE_CLK; /* Clock data! */
7738 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7739 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7740 ee_value &= ~SEE_CLK;
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743
7744 i >>= 1;
7745 }
7746}
7747
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007748static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007749{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007750 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007751 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007752 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007753 for (i=0; i < ID_STRING_LENGTH; i++)
7754 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007755 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007756 for(j=0; j < 8; j++)
7757 {
7758 if ((crc ^ ch) & 1)
7759 crc = (crc >> 1) ^ CRCMASK;
7760 else
7761 crc >>= 1;
7762 ch >>= 1;
7763 }
7764 }
7765 return(crc);
7766}
7767
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007768static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007769{
7770 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007771 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007772 lrc = 0;
7773 for(i = 0; i < ID_STRING_LENGTH; i++)
7774 lrc ^= buffer[i];
7775 return(lrc);
7776}
7777
7778
7779
7780/*
7781 The following inline definitions avoid type conflicts.
7782*/
7783
7784static inline unsigned char
7785FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7786{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007787 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007788}
7789
7790
7791static inline FlashPoint_CardHandle_T
7792FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7793{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007794 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007795}
7796
7797static inline void
7798FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7799{
7800 FlashPoint_ReleaseHostAdapter(CardHandle);
7801}
7802
7803
7804static inline void
7805FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7806{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007807 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007808}
7809
7810
7811static inline void
7812FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7813{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007814 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007815}
7816
7817
7818static inline boolean
7819FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7820{
7821 return FlashPoint_InterruptPending(CardHandle);
7822}
7823
7824
7825static inline int
7826FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7827{
7828 return FlashPoint_HandleInterrupt(CardHandle);
7829}
7830
7831
7832#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7833#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7834#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7835#define FlashPoint_StartCCB FlashPoint__StartCCB
7836#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7837#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7838#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7839
7840
Linus Torvalds1da177e2005-04-16 15:20:36 -07007841#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7842
7843
7844/*
7845 Define prototypes for the FlashPoint SCCB Manager Functions.
7846*/
7847
7848extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7849extern FlashPoint_CardHandle_T
7850 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7851extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7852extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7853extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7854extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7855extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007856
7857
7858#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */