blob: 9969fef8fd5259752c340fac2795f900452487f6 [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
James Bottomley 47b5d692005-04-24 02:38:05 -0500271typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
273
274typedef struct SCCBMgr_tar_info {
275
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800276 struct sccb * TarSelQ_Head;
277 struct sccb * TarSelQ_Tail;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800278 unsigned char TarLUN_CA; /*Contingent Allgiance */
279 unsigned char TarTagQ_Cnt;
280 unsigned char TarSelQ_Cnt;
281 unsigned char TarStatus;
282 unsigned char TarEEValue;
283 unsigned char TarSyncCtrl;
284 unsigned char TarReserved[2]; /* for alignment */
285 unsigned char LunDiscQ_Idx[MAX_LUN];
286 unsigned char TarLUNBusy[MAX_LUN];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287} SCCBMGR_TAR_INFO;
288
289typedef struct NVRAMInfo {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800290 unsigned char niModel; /* Model No. of card */
291 unsigned char niCardNo; /* Card no. */
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800292 unsigned long niBaseAddr; /* Port Address of card */
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800293 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
294 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
295 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
296 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
297 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
298 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299}NVRAMINFO;
300
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302
303#define MODEL_LT 1
304#define MODEL_DL 2
305#define MODEL_LW 3
306#define MODEL_DW 4
307
308
309typedef struct SCCBcard {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800310 struct sccb * currentSCCB;
Alexey Dobriyan7f101662006-03-08 00:14:30 -0800311 struct sccb_mgr_info * cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800313 unsigned long ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800315 unsigned short cmdCounter;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800316 unsigned char discQCount;
317 unsigned char tagQ_Lst;
318 unsigned char cardIndex;
319 unsigned char scanIndex;
320 unsigned char globalFlags;
321 unsigned char ourId;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 PNVRamInfo pNvRamInfo;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800323 struct sccb * discQ_Tbl[QUEUE_DEPTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
325}SCCBCARD;
326
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
329
330#define F_TAG_STARTED 0x01
331#define F_CONLUN_IO 0x02
332#define F_DO_RENEGO 0x04
333#define F_NO_FILTER 0x08
334#define F_GREEN_PC 0x10
335#define F_HOST_XFER_ACT 0x20
336#define F_NEW_SCCB_CMD 0x40
337#define F_UPDATE_EEPROM 0x80
338
339
340#define ID_STRING_LENGTH 32
341#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
342
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
344#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
345
346#define ASSIGN_ID 0x00
347#define SET_P_FLAG 0x01
348#define CFG_CMPLT 0x03
349#define DOM_MSTR 0x0F
350#define SYNC_PTRN 0x1F
351
352#define ID_0_7 0x18
353#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354#define MISC_CODE 0x14
355#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358
359#define INIT_SELTD 0x01
360#define LEVEL2_TAR 0x02
361
362
363enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
364 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
365 CLR_PRIORITY,NO_ID_AVAIL };
366
367typedef struct SCCBscam_info {
368
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800369 unsigned char id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 enum scam_id_st state;
371
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800372} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376#define SCSI_READ 0x08
377#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379#define SCSI_READ_EXTENDED 0x28
380#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383
384
385#define SSGOOD 0x00
386#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387#define SSQ_FULL 0x28
388
389
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
391
392#define SMCMD_COMP 0x00
393#define SMEXT 0x01
394#define SMSAVE_DATA_PTR 0x02
395#define SMREST_DATA_PTR 0x03
396#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397#define SMABORT 0x06
398#define SMREJECT 0x07
399#define SMNO_OP 0x08
400#define SMPARITY 0x09
401#define SMDEV_RESET 0x0C
402#define SMABORT_TAG 0x0D
403#define SMINIT_RECOVERY 0x0F
404#define SMREL_RECOVERY 0x10
405
406#define SMIDENT 0x80
407#define DISC_PRIV 0x40
408
409
410#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411#define SMWDTR 0x03
412#define SM8BIT 0x00
413#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414#define SMIGNORWR 0x23 /* Ignore Wide Residue */
415
416
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418
419
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
421
422
423#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424#define TWELVE_BYTE_CMD 0x0C
425
426#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
428
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430#define EEPROM_WD_CNT 256
431
432#define EEPROM_CHECK_SUM 0
433#define FW_SIGNATURE 2
434#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437#define SYSTEM_CONFIG 16
438#define SCSI_CONFIG 17
439#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440#define SCAM_CONFIG 20
441#define ADAPTER_SCSI_ID 24
442
443
444#define IGNORE_B_SCAN 32
445#define SEND_START_ENA 34
446#define DEVICE_ENABLE 36
447
448#define SYNC_RATE_TBL 38
449#define SYNC_RATE_TBL01 38
450#define SYNC_RATE_TBL23 40
451#define SYNC_RATE_TBL45 42
452#define SYNC_RATE_TBL67 44
453#define SYNC_RATE_TBL89 46
454#define SYNC_RATE_TBLab 48
455#define SYNC_RATE_TBLcd 50
456#define SYNC_RATE_TBLef 52
457
458
459
460#define EE_SCAMBASE 256
461
462
463
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 #define SCAM_ENABLED BIT(2)
465 #define SCAM_LEVEL2 BIT(3)
466
467
468 #define RENEGO_ENA BITW(10)
469 #define CONNIO_ENA BITW(11)
470 #define GREEN_PC_ENA BITW(12)
471
472
473 #define AUTO_RATE_00 00
474 #define AUTO_RATE_05 01
475 #define AUTO_RATE_10 02
476 #define AUTO_RATE_20 03
477
478 #define WIDE_NEGO_BIT BIT(7)
479 #define DISC_ENABLE_BIT BIT(6)
480
481
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
483 #define hp_vendor_id_0 0x00 /* LSB */
484 #define ORION_VEND_0 0x4B
485
486 #define hp_vendor_id_1 0x01 /* MSB */
487 #define ORION_VEND_1 0x10
488
489 #define hp_device_id_0 0x02 /* LSB */
490 #define ORION_DEV_0 0x30
491
492 #define hp_device_id_1 0x03 /* MSB */
493 #define ORION_DEV_1 0x81
494
495 /* Sub Vendor ID and Sub Device ID only available in
496 Harpoon Version 2 and higher */
497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501
502 #define hp_semaphore 0x0C
503 #define SCCB_MGR_ACTIVE BIT(0)
504 #define TICKLE_ME BIT(1)
505 #define SCCB_MGR_PRESENT BIT(3)
506 #define BIOS_IN_USE BIT(4)
507
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
510 #define hp_sys_ctrl 0x0F
511
512 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
513 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
514 #define HALT_MACH BIT(3) /*Halt State Machine */
515 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
517
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800521
522
523
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524
525 #define hp_host_blk_cnt 0x13
526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
528
529 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
530
531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
533 #define hp_int_mask 0x17
534
535 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
536 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
538
539 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 #define hp_xfer_cnt_hi 0x1A
541 #define hp_xfer_cmd 0x1B
542
543 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
544 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
546
547 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
551 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
552
553 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
554 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555
556 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 #define hp_ee_ctrl 0x22
560
561 #define EXT_ARB_ACK BIT(7)
562 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
563 #define SEE_MS BIT(5)
564 #define SEE_CS BIT(3)
565 #define SEE_CLK BIT(2)
566 #define SEE_DO BIT(1)
567 #define SEE_DI BIT(0)
568
569 #define EE_READ 0x06
570 #define EE_WRITE 0x05
571 #define EWEN 0x04
572 #define EWEN_ADDR 0x03C0
573 #define EWDS 0x04
574 #define EWDS_ADDR 0x0000
575
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578
579
580
581
582 #define hp_bm_ctrl 0x26
583
584 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
585 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
587 #define FAST_SINGLE BIT(6) /*?? */
588
589 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
590
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592 #define hp_sg_addr 0x28
593 #define hp_page_ctrl 0x29
594
595 #define SCATTER_EN BIT(0)
596 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
598 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
599
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602
603 #define hp_pci_stat_cfg 0x2D
604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 #define hp_rev_num 0x33
615
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
617 #define hp_stack_data 0x34
618 #define hp_stack_addr 0x35
619
620 #define hp_ext_status 0x36
621
622 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
623 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
624 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 #define CMD_ABORTED BIT(4) /*Command aborted */
626 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
627 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
628 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
629 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
630 BM_PARITY_ERR | PIO_OVERRUN)
631
632 #define hp_int_status 0x37
633
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
635 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637
638
639 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
642
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 #define hp_intena 0x40
645
646 #define RESET BITW(7)
647 #define PROG_HLT BITW(6)
648 #define PARITY BITW(5)
649 #define FIFO BITW(4)
650 #define SEL BITW(3)
651 #define SCAM_SEL BITW(2)
652 #define RSEL BITW(1)
653 #define TIMEOUT BITW(0)
654 #define BUS_FREE BITW(15)
655 #define XFER_CNT_0 BITW(14)
656 #define PHASE BITW(13)
657 #define IUNKWN BITW(12)
658 #define ICMD_COMP BITW(11)
659 #define ITICKLE BITW(10)
660 #define IDO_STRT BITW(9)
661 #define ITAR_DISC BITW(8)
662 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
663 #define CLR_ALL_INT 0xFFFF
664 #define CLR_ALL_INT_1 0xFF00
665
666 #define hp_intstat 0x42
667
668 #define hp_scsisig 0x44
669
670 #define SCSI_SEL BIT(7)
671 #define SCSI_BSY BIT(6)
672 #define SCSI_REQ BIT(5)
673 #define SCSI_ACK BIT(4)
674 #define SCSI_ATN BIT(3)
675 #define SCSI_CD BIT(2)
676 #define SCSI_MSG BIT(1)
677 #define SCSI_IOBIT BIT(0)
678
679 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
682 #define S_DATAI_PH ( BIT(0))
683 #define S_DATAO_PH 0x00
684 #define S_ILL_PH ( BIT(1) )
685
686 #define hp_scsictrl_0 0x45
687
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 #define SEL_TAR BIT(6)
689 #define ENA_ATN BIT(4)
690 #define ENA_RESEL BIT(2)
691 #define SCSI_RST BIT(1)
692 #define ENA_SCAM_SEL BIT(0)
693
694
695
696 #define hp_portctrl_0 0x46
697
698 #define SCSI_PORT BIT(7)
699 #define SCSI_INBIT BIT(6)
700 #define DMA_PORT BIT(5)
701 #define DMA_RD BIT(4)
702 #define HOST_PORT BIT(3)
703 #define HOST_WRT BIT(2)
704 #define SCSI_BUS_EN BIT(1)
705 #define START_TO BIT(0)
706
707 #define hp_scsireset 0x47
708
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 #define SCSI_INI BIT(6)
710 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 #define DMA_RESET BIT(3)
712 #define HPSCSI_RESET BIT(2)
713 #define PROG_RESET BIT(1)
714 #define FIFO_CLR BIT(0)
715
716 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718
719 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 #define hp_addstat 0x4E
721
722 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 #define SCSI_MODE8 BIT(3)
724 #define SCSI_PAR_ERR BIT(0)
725
726 #define hp_prgmcnt_0 0x4F
727
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
729 #define hp_selfid_0 0x50
730 #define hp_selfid_1 0x51
731 #define hp_arb_id 0x52
732
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
734 #define hp_select_id 0x53
735
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736
737 #define hp_synctarg_base 0x54
738 #define hp_synctarg_12 0x54
739 #define hp_synctarg_13 0x55
740 #define hp_synctarg_14 0x56
741 #define hp_synctarg_15 0x57
742
743 #define hp_synctarg_8 0x58
744 #define hp_synctarg_9 0x59
745 #define hp_synctarg_10 0x5A
746 #define hp_synctarg_11 0x5B
747
748 #define hp_synctarg_4 0x5C
749 #define hp_synctarg_5 0x5D
750 #define hp_synctarg_6 0x5E
751 #define hp_synctarg_7 0x5F
752
753 #define hp_synctarg_0 0x60
754 #define hp_synctarg_1 0x61
755 #define hp_synctarg_2 0x62
756 #define hp_synctarg_3 0x63
757
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 #define DEFAULT_OFFSET 0x0F
760
761 #define hp_autostart_0 0x64
762 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 #define hp_autostart_3 0x67
764
765
766
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 #define AUTO_IMMED BIT(5)
768 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770
771 #define hp_gp_reg_0 0x68
772 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 #define hp_gp_reg_3 0x6B
774
775 #define hp_seltimeout 0x6C
776
777
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 #define TO_4ms 0x67 /* 3.9959ms */
779
780 #define TO_5ms 0x03 /* 4.9152ms */
781 #define TO_10ms 0x07 /* 11.xxxms */
782 #define TO_250ms 0x99 /* 250.68ms */
783 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
785 #define hp_clkctrl_0 0x6D
786
787 #define PWR_DWN BIT(6)
788 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
791 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
792
793 #define hp_fiforead 0x6E
794 #define hp_fifowrite 0x6F
795
796 #define hp_offsetctr 0x70
797 #define hp_xferstat 0x71
798
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 #define hp_portctrl_1 0x72
802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 #define CHK_SCSI_P BIT(3)
804 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
806 #define hp_xfer_pad 0x73
807
808 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
810 #define hp_scsidata_0 0x74
811 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
815 #define hp_aramBase 0x80
816 #define BIOS_DATA_OFFSET 0x60
817 #define BIOS_RELATIVE_CARD 0x64
818
819
820
821
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 #define AR3 (BITW(9) + BITW(8))
823 #define SDATA BITW(10)
824
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
826 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
827
828 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
829
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831
832 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
833
834 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
835
836
837 #define ADATA_OUT 0x00
838 #define ADATA_IN BITW(8)
839 #define ACOMMAND BITW(10)
840 #define ASTATUS (BITW(10)+BITW(8))
841 #define AMSG_OUT (BITW(10)+BITW(9))
842 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843
844
845 #define BRH_OP BITW(13) /* Branch */
846
847
848 #define ALWAYS 0x00
849 #define EQUAL BITW(8)
850 #define NOT_EQ BITW(9)
851
852 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
853
854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
857
858 #define MPM_OP BITW(15) /* Match phase and move data */
859
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
861 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
862
863
864 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
865
866
867 #define D_AR0 0x00
868 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
870
871
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
878
879 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
880
881 #define SSI_OP (BITW(15)+BITW(11))
882
883
884 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
885 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
888 #define SSI_ITICKLE (ITICKLE >> 8)
889
890 #define SSI_IUNKWN (IUNKWN >> 8)
891 #define SSI_INO_CC (IUNKWN >> 8)
892 #define SSI_IRFAIL (IUNKWN >> 8)
893
894
895 #define NP 0x10 /*Next Phase */
896 #define NTCMD 0x02 /*Non- Tagged Command start */
897 #define CMDPZ 0x04 /*Command phase */
898 #define DINT 0x12 /*Data Out/In interrupt */
899 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 #define DC 0x19 /*Disconnect Message */
901 #define ST 0x1D /*Status Phase */
902 #define UNKNWN 0x24 /*Unknown bus action */
903 #define CC 0x25 /*Command Completion failure */
904 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
906
907
908 #define ID_MSG_STRT hp_aramBase + 0x00
909 #define NON_TAG_ID_MSG hp_aramBase + 0x06
910 #define CMD_STRT hp_aramBase + 0x08
911 #define SYNC_MSGS hp_aramBase + 0x08
912
913
914
915
916
917 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 #define DISCONNECT_START 0x10/2
919 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 #define SELCHK_STRT SELCHK/2
922
923
924
925
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800929
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
932/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
933 xfercnt <<= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800934 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 */
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800936#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 -0700937 addr >>= 16,\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800938 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 WR_HARP32(port,hp_xfercnt_0,count),\
Alexey Dobriyanc823fee2006-03-08 00:14:25 -0800940 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 count >>= 16,\
942 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
944#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
945 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
946
947
948#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
949 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
950
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
953#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
954 WR_HARPOON(port+hp_scsireset, 0x00))
955
956#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
957 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
958
959#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
960 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
961
962#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
963 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
964
965#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
966 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
967
968
969
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800971static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
972static void FPT_ssel(unsigned long port, unsigned char p_card);
973static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800974static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800975static void FPT_stsyncn(unsigned long port, unsigned char p_card);
976static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
977static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -0500978 PSCCBMgr_tar_info currTar_Info);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800979static void FPT_sresb(unsigned long port, unsigned char p_card);
980static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
981static void FPT_schkdd(unsigned long port, unsigned char p_card);
982static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
983static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
984static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800986static void FPT_SendMsg(unsigned long port, unsigned char message);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800987static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
988 unsigned char error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800990static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
James Bottomley 47b5d692005-04-24 02:38:05 -0500991static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -0800993static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
994static void FPT_stwidn(unsigned long port, unsigned char p_card);
995static void FPT_siwidr(unsigned long port, unsigned char width);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
997
Alexey Dobriyandb038cf2006-03-08 00:14:24 -0800998static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -0800999static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
1000static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001001 unsigned char p_card);
1002static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1003static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001004static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1005static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1006static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001007static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001008static unsigned char FPT_CalcLrc(unsigned char buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
1010
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001011static void FPT_Wait1Second(unsigned long p_port);
1012static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1013static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1014static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1015static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1016static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1017static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019
1020
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001021static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1022static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1023static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1024static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1025static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1026static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1027static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001029static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1030static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1031static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
1033
1034
1035
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001036static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1037static void FPT_BusMasterInit(unsigned long p_port);
1038static void FPT_DiagEEPROM(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040
1041
1042
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001043static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001044static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1045static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1046static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1047static void FPT_hostDataXferRestart(struct sccb * currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001050static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001051 PSCCBcard pCurrCard, unsigned short p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052
James Bottomley 47b5d692005-04-24 02:38:05 -05001053static void FPT_SccbMgrTableInitAll(void);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001054static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1055static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
1057
1058
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001059static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001061static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1062static void FPT_scbusf(unsigned long p_port);
1063static void FPT_scsel(unsigned long p_port);
1064static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1065static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1066static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1067static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1068static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1069static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001070static unsigned char FPT_scvalq(unsigned char p_quintet);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001071static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1072static void FPT_scwtsel(unsigned long p_port);
1073static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1074static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001075static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
1077
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001078static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1079static void FPT_autoLoadDefaultMap(unsigned long p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080
1081
1082
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
James Bottomley 47b5d692005-04-24 02:38:05 -05001084static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1085static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1086static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1087static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001090static unsigned char FPT_mbCards = 0;
1091static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
James Bottomley 47b5d692005-04-24 02:38:05 -05001092 ' ', 'B', 'T', '-', '9', '3', '0', \
1093 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1094 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001096static unsigned short FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
1098
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001099static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
1102/*---------------------------------------------------------------------
1103 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001104 * Function: FlashPoint_ProbeHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 *
1106 * Description: Setup and/or Search for cards and return info to caller.
1107 *
1108 *---------------------------------------------------------------------*/
1109
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001110static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001112 static unsigned char first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001114 unsigned char i,j,id,ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001115 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001116 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 PNVRamInfo pCurrNvRam;
1118
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120
1121
1122 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1123 return((int)FAILURE);
1124
1125 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1126 return((int)FAILURE);
1127
1128 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1129 return((int)FAILURE);
1130
1131 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1132 return((int)FAILURE);
1133
1134
1135 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1136
1137/* For new Harpoon then check for sub_device ID LSB
1138 the bits(0-3) must be all ZERO for compatible with
1139 current version of SCCBMgr, else skip this Harpoon
1140 device. */
1141
1142 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1143 return((int)FAILURE);
1144 }
1145
1146 if (first_time)
1147 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001148 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001150 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 }
1152
James Bottomley 47b5d692005-04-24 02:38:05 -05001153 if(FPT_RdStack(ioport, 0) != 0x00) {
1154 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 {
1156 pCurrNvRam = NULL;
1157 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001158 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1159 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 }
1161 else
1162 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001163 if(FPT_mbCards < MAX_MB_CARDS) {
1164 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1165 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001167 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 }else
1169 return((int) FAILURE);
1170 }
1171 }else
1172 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173
1174 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1175 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1176
1177 if(pCurrNvRam)
1178 pCardInfo->si_id = pCurrNvRam->niAdapId;
1179 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001180 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1181 (unsigned char)0x0FF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
1183 pCardInfo->si_lun = 0x00;
1184 pCardInfo->si_fw_revision = ORION_FW_REV;
1185 temp2 = 0x0000;
1186 temp3 = 0x0000;
1187 temp4 = 0x0000;
1188 temp5 = 0x0000;
1189 temp6 = 0x0000;
1190
1191 for (id = 0; id < (16/2); id++) {
1192
1193 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001194 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1196 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1197 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001198 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
1200 for (i = 0; i < 2; temp >>=8,i++) {
1201
1202 temp2 >>= 1;
1203 temp3 >>= 1;
1204 temp4 >>= 1;
1205 temp5 >>= 1;
1206 temp6 >>= 1;
1207 switch (temp & 0x3)
1208 {
1209 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1210 temp6 |= 0x8000; /* Fall through */
1211 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1212 temp5 |= 0x8000; /* Fall through */
1213 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1214 temp2 |= 0x8000; /* Fall through */
1215 case AUTO_RATE_00: /* Asynchronous */
1216 break;
1217 }
1218
1219 if (temp & DISC_ENABLE_BIT)
1220 temp3 |= 0x8000;
1221
1222 if (temp & WIDE_NEGO_BIT)
1223 temp4 |= 0x8000;
1224
1225 }
1226 }
1227
1228 pCardInfo->si_per_targ_init_sync = temp2;
1229 pCardInfo->si_per_targ_no_disc = temp3;
1230 pCardInfo->si_per_targ_wide_nego = temp4;
1231 pCardInfo->si_per_targ_fast_nego = temp5;
1232 pCardInfo->si_per_targ_ultra_nego = temp6;
1233
1234 if(pCurrNvRam)
1235 i = pCurrNvRam->niSysConf;
1236 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001237 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238
1239 if(pCurrNvRam)
1240 ScamFlg = pCurrNvRam->niScamConf;
1241 else
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001242 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
1244 pCardInfo->si_flags = 0x0000;
1245
1246 if (i & 0x01)
1247 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1248
1249 if (!(i & 0x02))
1250 pCardInfo->si_flags |= SOFT_RESET;
1251
1252 if (i & 0x10)
1253 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1254
1255 if (ScamFlg & SCAM_ENABLED)
1256 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1257
1258 if (ScamFlg & SCAM_LEVEL2)
1259 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1260
1261 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1262 if (i & 0x04) {
1263 j |= SCSI_TERM_ENA_L;
1264 }
1265 WR_HARPOON(ioport+hp_bm_ctrl, j );
1266
1267 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1268 if (i & 0x08) {
1269 j |= SCSI_TERM_ENA_H;
1270 }
1271 WR_HARPOON(ioport+hp_ee_ctrl, j );
1272
1273 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1274
1275 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1276
1277 pCardInfo->si_card_family = HARPOON_FAMILY;
1278 pCardInfo->si_bustype = BUSTYPE_PCI;
1279
1280 if(pCurrNvRam){
1281 pCardInfo->si_card_model[0] = '9';
1282 switch(pCurrNvRam->niModel & 0x0f){
1283 case MODEL_LT:
1284 pCardInfo->si_card_model[1] = '3';
1285 pCardInfo->si_card_model[2] = '0';
1286 break;
1287 case MODEL_LW:
1288 pCardInfo->si_card_model[1] = '5';
1289 pCardInfo->si_card_model[2] = '0';
1290 break;
1291 case MODEL_DL:
1292 pCardInfo->si_card_model[1] = '3';
1293 pCardInfo->si_card_model[2] = '2';
1294 break;
1295 case MODEL_DW:
1296 pCardInfo->si_card_model[1] = '5';
1297 pCardInfo->si_card_model[2] = '2';
1298 break;
1299 }
1300 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001301 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001302 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001303 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001305 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1306 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 }
1308
1309 if (pCardInfo->si_card_model[1] == '3')
1310 {
1311 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1312 pCardInfo->si_flags |= LOW_BYTE_TERM;
1313 }
1314 else if (pCardInfo->si_card_model[2] == '0')
1315 {
1316 temp = RD_HARPOON(ioport+hp_xfer_pad);
1317 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1318 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1319 pCardInfo->si_flags |= LOW_BYTE_TERM;
1320 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1321 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1322 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1323 WR_HARPOON(ioport+hp_xfer_pad, temp);
1324 }
1325 else
1326 {
1327 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1328 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1329 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1331 temp3 = 0;
1332 for (i = 0; i < 8; i++)
1333 {
1334 temp3 <<= 1;
1335 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1336 temp3 |= 1;
1337 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1338 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1339 }
1340 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1341 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1342 if (!(temp3 & BIT(7)))
1343 pCardInfo->si_flags |= LOW_BYTE_TERM;
1344 if (!(temp3 & BIT(6)))
1345 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1346 }
1347
1348
1349 ARAM_ACCESS(ioport);
1350
1351 for ( i = 0; i < 4; i++ ) {
1352
1353 pCardInfo->si_XlatInfo[i] =
1354 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1355 }
1356
1357 /* return with -1 if no sort, else return with
1358 logical card number sorted by BIOS (zero-based) */
1359
1360 pCardInfo->si_relative_cardnum =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001361 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
1363 SGRAM_ACCESS(ioport);
1364
James Bottomley 47b5d692005-04-24 02:38:05 -05001365 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1366 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1367 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1368 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1369 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1370 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1371 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1372 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
1374 pCardInfo->si_present = 0x01;
1375
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 return(0);
1377}
1378
1379
1380/*---------------------------------------------------------------------
1381 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001382 * Function: FlashPoint_HardwareResetHostAdapter
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 *
1384 * Description: Setup adapter for normal operation (hard reset).
1385 *
1386 *---------------------------------------------------------------------*/
1387
Alexey Dobriyan7f101662006-03-08 00:14:30 -08001388static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389{
1390 PSCCBcard CurrCard = NULL;
1391 PNVRamInfo pCurrNvRam;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001392 unsigned char i,j,thisCard, ScamFlg;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001393 unsigned short temp,sync_bit_map,id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001394 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
1398 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1399
1400 if (thisCard == MAX_CARDS) {
1401
1402 return(FAILURE);
1403 }
1404
James Bottomley 47b5d692005-04-24 02:38:05 -05001405 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
James Bottomley 47b5d692005-04-24 02:38:05 -05001407 CurrCard = &FPT_BL_Card[thisCard];
1408 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 break;
1410 }
1411
James Bottomley 47b5d692005-04-24 02:38:05 -05001412 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413
James Bottomley 47b5d692005-04-24 02:38:05 -05001414 FPT_BL_Card[thisCard].ioPort = ioport;
1415 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
James Bottomley 47b5d692005-04-24 02:38:05 -05001417 if(FPT_mbCards)
1418 for(i = 0; i < FPT_mbCards; i++){
1419 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1420 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001422 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 CurrCard->cardIndex = thisCard;
1424 CurrCard->cardInfo = pCardInfo;
1425
1426 break;
1427 }
1428 }
1429
1430 pCurrNvRam = CurrCard->pNvRamInfo;
1431
1432 if(pCurrNvRam){
1433 ScamFlg = pCurrNvRam->niScamConf;
1434 }
1435 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001436 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 }
1438
1439
James Bottomley 47b5d692005-04-24 02:38:05 -05001440 FPT_BusMasterInit(ioport);
1441 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
James Bottomley 47b5d692005-04-24 02:38:05 -05001443 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
1445
1446 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1447
1448 WR_HARPOON(ioport+hp_selfid_0, id);
1449 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1450 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1451 CurrCard->ourId = pCardInfo->si_id;
1452
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001453 i = (unsigned char) pCardInfo->si_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 if (i & SCSI_PARITY_ENA)
1455 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1456
1457 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1458 if (i & LOW_BYTE_TERM)
1459 j |= SCSI_TERM_ENA_L;
1460 WR_HARPOON(ioport+hp_bm_ctrl, j);
1461
1462 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1463 if (i & HIGH_BYTE_TERM)
1464 j |= SCSI_TERM_ENA_H;
1465 WR_HARPOON(ioport+hp_ee_ctrl, j );
1466
1467
1468 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1469
James Bottomley 47b5d692005-04-24 02:38:05 -05001470 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
James Bottomley 47b5d692005-04-24 02:38:05 -05001472 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 }
1474
1475
1476
1477 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1478 CurrCard->globalFlags |= F_NO_FILTER;
1479
1480 if(pCurrNvRam){
1481 if(pCurrNvRam->niSysConf & 0x10)
1482 CurrCard->globalFlags |= F_GREEN_PC;
1483 }
1484 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001485 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 CurrCard->globalFlags |= F_GREEN_PC;
1487 }
1488
1489 /* Set global flag to indicate Re-Negotiation to be done on all
1490 ckeck condition */
1491 if(pCurrNvRam){
1492 if(pCurrNvRam->niScsiConf & 0x04)
1493 CurrCard->globalFlags |= F_DO_RENEGO;
1494 }
1495 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001496 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 CurrCard->globalFlags |= F_DO_RENEGO;
1498 }
1499
1500 if(pCurrNvRam){
1501 if(pCurrNvRam->niScsiConf & 0x08)
1502 CurrCard->globalFlags |= F_CONLUN_IO;
1503 }
1504 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001505 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 CurrCard->globalFlags |= F_CONLUN_IO;
1507 }
1508
1509
1510 temp = pCardInfo->si_per_targ_no_disc;
1511
1512 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1513
1514 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001515 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 }
1517
1518 sync_bit_map = 0x0001;
1519
1520 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1521
1522 if(pCurrNvRam){
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001523 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1525 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1526 }else
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001527 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528
1529 for (i = 0; i < 2; temp >>=8,i++) {
1530
1531 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1532
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001533 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 }
1535
1536 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001537 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1538 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001539 (unsigned char)(temp & ~EE_SYNC_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 }
1541
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1543 (id*2+i >= 8)){
1544*/
1545 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1546
James Bottomley 47b5d692005-04-24 02:38:05 -05001547 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
1549 }
1550
1551 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001552 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 }
1554
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555
1556 sync_bit_map <<= 1;
1557
1558
1559
1560 }
1561 }
1562
1563 WR_HARPOON((ioport+hp_semaphore),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001564 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001566 return((unsigned long)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567}
1568
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001569static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001571 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001572 unsigned long portBase;
1573 unsigned long regOffset;
1574 unsigned long scamData;
1575 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 PNVRamInfo pCurrNvRam;
1577
1578 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1579
1580 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001581 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1585 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
1587 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001588 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
1590 portBase = pCurrNvRam->niBaseAddr;
1591
1592 for(i = 0; i < MAX_SCSI_TAR; i++){
1593 regOffset = hp_aramBase + 64 + i*4;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001594 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 scamData = *pScamTbl;
1596 WR_HARP32(portBase, regOffset, scamData);
1597 }
1598
1599 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001600 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 }
1602}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603
1604
James Bottomley 47b5d692005-04-24 02:38:05 -05001605static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001607 unsigned char i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001608 unsigned long portBase;
1609 unsigned long regOffset;
1610 unsigned long scamData;
1611 unsigned long *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612
James Bottomley 47b5d692005-04-24 02:38:05 -05001613 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1614 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1615 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1616 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1617 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618
1619 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001620 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
1622 portBase = pNvRamInfo->niBaseAddr;
1623
1624 for(i = 0; i < MAX_SCSI_TAR; i++){
1625 regOffset = hp_aramBase + 64 + i*4;
1626 RD_HARP32(portBase, regOffset, scamData);
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001627 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 *pScamTbl = scamData;
1629 }
1630
1631}
1632
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001633static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634{
1635 WR_HARPOON(portBase + hp_stack_addr, index);
1636 return(RD_HARPOON(portBase + hp_stack_data));
1637}
1638
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001639static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640{
1641 WR_HARPOON(portBase + hp_stack_addr, index);
1642 WR_HARPOON(portBase + hp_stack_data, data);
1643}
1644
1645
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001646static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647{
James Bottomley 47b5d692005-04-24 02:38:05 -05001648 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1649 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1651 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001652 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1654 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001655 return(1);
1656 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657
1658}
1659/*---------------------------------------------------------------------
1660 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001661 * Function: FlashPoint_StartCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 *
1663 * Description: Start a command pointed to by p_Sccb. When the
1664 * command is completed it will be returned via the
1665 * callback function.
1666 *
1667 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001668static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001670 unsigned long ioport;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001671 unsigned char thisCard, lun;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001672 struct sccb * pSaveSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 CALL_BK_FN callback;
1674
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1676 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1679 {
1680
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 p_Sccb->HostStatus = SCCB_COMPLETE;
1682 p_Sccb->SccbStatus = SCCB_ERROR;
1683 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1684 if (callback)
1685 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 return;
1688 }
1689
James Bottomley 47b5d692005-04-24 02:38:05 -05001690 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692
1693 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1694 {
1695 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1696 | SCCB_MGR_ACTIVE));
1697
1698 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1699 {
1700 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1701 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1702 }
1703 }
1704
1705 ((PSCCBcard)pCurrCard)->cmdCounter++;
1706
1707 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1708
1709 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1710 | TICKLE_ME));
1711 if(p_Sccb->OperationCode == RESET_COMMAND)
1712 {
1713 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1714 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001715 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1717 }
1718 else
1719 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001720 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 }
1722 }
1723
1724 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1725
1726 if(p_Sccb->OperationCode == RESET_COMMAND)
1727 {
1728 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1729 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001730 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1732 }
1733 else
1734 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001735 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 }
1737 }
1738
1739 else {
1740
1741 MDISABLE_INT(ioport);
1742
1743 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001744 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 lun = p_Sccb->Lun;
1746 else
1747 lun = 0;
1748 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001749 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1750 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1751 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
1753 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001754 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 }
1756
1757 else {
1758
1759 if(p_Sccb->OperationCode == RESET_COMMAND)
1760 {
1761 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1762 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001763 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1765 }
1766 else
1767 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001768 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 }
1770 }
1771
1772
1773 MENABLE_INT(ioport);
1774 }
1775
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776}
1777
1778
1779/*---------------------------------------------------------------------
1780 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001781 * Function: FlashPoint_AbortCCB
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 *
1783 * Description: Abort the command pointed to by p_Sccb. When the
1784 * command is completed it will be returned via the
1785 * callback function.
1786 *
1787 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001788static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001790 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001792 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 CALL_BK_FN callback;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001794 unsigned char TID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001795 struct sccb * pSaveSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 PSCCBMgr_tar_info currTar_Info;
1797
1798
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1800
1801 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1802
James Bottomley 47b5d692005-04-24 02:38:05 -05001803 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 {
1805
James Bottomley 47b5d692005-04-24 02:38:05 -05001806 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 {
1808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 ((PSCCBcard)pCurrCard)->cmdCounter--;
1810
1811 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1812 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001813 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 p_Sccb->SccbStatus = SCCB_ABORT;
1816 callback = p_Sccb->SccbCallback;
1817 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818
1819 return(0);
1820 }
1821
1822 else
1823 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1825 {
1826 p_Sccb->SccbStatus = SCCB_ABORT;
1827 return(0);
1828
1829 }
1830
1831 else
1832 {
1833
1834 TID = p_Sccb->TargID;
1835
1836
1837 if(p_Sccb->Sccb_tag)
1838 {
1839 MDISABLE_INT(ioport);
1840 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1841 {
1842 p_Sccb->SccbStatus = SCCB_ABORT;
1843 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1845
1846 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1847 {
1848 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001849 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 }
1851 else
1852 {
1853 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1854 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001855 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1857 }
1858 }
1859 MENABLE_INT(ioport);
1860 return(0);
1861 }
1862 else
1863 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001864 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
James Bottomley 47b5d692005-04-24 02:38:05 -05001866 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 == p_Sccb)
1868 {
1869 p_Sccb->SccbStatus = SCCB_ABORT;
1870 return(0);
1871 }
1872 }
1873 }
1874 }
1875 }
1876 return(-1);
1877}
1878
1879
1880/*---------------------------------------------------------------------
1881 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001882 * Function: FlashPoint_InterruptPending
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 *
1884 * Description: Do a quick check to determine if there is a pending
1885 * interrupt for this card and disable the IRQ Pin if so.
1886 *
1887 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001888static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001890 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891
1892 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1893
1894 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1895 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001896 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 }
1898
1899 else
1900
James Bottomley 47b5d692005-04-24 02:38:05 -05001901 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902}
1903
1904
1905
1906/*---------------------------------------------------------------------
1907 *
Alexey Dobriyand8b6b8b2006-03-08 00:14:23 -08001908 * Function: FlashPoint_HandleInterrupt
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 *
1910 * Description: This is our entry point when an interrupt is generated
1911 * by the card and the upper level driver passes it on to
1912 * us.
1913 *
1914 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001915static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08001917 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001918 unsigned char thisCard,result,bm_status, bm_int_st;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08001919 unsigned short hp_int;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001920 unsigned char i, target;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08001921 unsigned long ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922
1923 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1924 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1925
1926 MDISABLE_INT(ioport);
1927
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08001929 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 else
1931 bm_status = 0;
1932
1933 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1934
James Bottomley 47b5d692005-04-24 02:38:05 -05001935 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 bm_status)
1937 {
1938
1939 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1940
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001942 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1944 bm_status = 0;
1945
1946 if (result) {
1947
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 return(result);
1950 }
1951 }
1952
1953
1954 else if (hp_int & ICMD_COMP) {
1955
1956 if ( !(hp_int & BUS_FREE) ) {
1957 /* Wait for the BusFree before starting a new command. We
1958 must also check for being reselected since the BusFree
1959 may not show up if another device reselects us in 1.5us or
1960 less. SRR Wednesday, 3/8/1995.
1961 */
1962 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1963 }
1964
1965 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1966
James Bottomley 47b5d692005-04-24 02:38:05 -05001967 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968
1969/* WRW_HARPOON((ioport+hp_intstat),
1970 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1971 */
1972
1973 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1974
James Bottomley 47b5d692005-04-24 02:38:05 -05001975 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
1977 }
1978
1979
1980 else if (hp_int & ITAR_DISC)
1981 {
1982
1983 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1984
James Bottomley 47b5d692005-04-24 02:38:05 -05001985 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986
1987 }
1988
1989 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1990
1991 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1992 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1993
1994 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1995 }
1996
1997 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05001998 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
2000 /* Wait for the BusFree before starting a new command. We
2001 must also check for being reselected since the BusFree
2002 may not show up if another device reselects us in 1.5us or
2003 less. SRR Wednesday, 3/8/1995.
2004 */
2005 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2006 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2007 RD_HARPOON((ioport+hp_scsisig)) ==
2008 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2009
2010 /*
2011 The additional loop exit condition above detects a timing problem
2012 with the revision D/E harpoon chips. The caller should reset the
2013 host adapter to recover when 0xFE is returned.
2014 */
2015 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2016 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 return 0xFE;
2019 }
2020
2021 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2022
2023
2024 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2025
2026 }
2027
2028
2029 else if (hp_int & RSEL) {
2030
2031 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2032
2033 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2034 {
2035 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2036 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002037 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 }
2039
2040 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2041 {
2042 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2043 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2044 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2045 }
2046
2047 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2048 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002049 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 }
2051
James Bottomley 47b5d692005-04-24 02:38:05 -05002052 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2053 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054
2055 }
2056
2057
2058 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2059 {
2060
2061 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002062 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
2064 }
2065
2066
2067 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2068 {
2069 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002070 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002072 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 }
2074 else
2075 {
2076 /* Harpoon problem some SCSI target device respond to selection
2077 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2078 to latch the correct Target ID into reg. x53.
2079 The work around require to correct this reg. But when write to this
2080 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2081 need to read this reg first then restore it later. After update to 0x53 */
2082
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002083 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2084 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2085 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2086 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2087 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088 WR_HARPOON(ioport+hp_fifowrite, i);
2089 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2090 }
2091 }
2092
2093 else if (hp_int & XFER_CNT_0) {
2094
2095 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2096
James Bottomley 47b5d692005-04-24 02:38:05 -05002097 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098
2099 }
2100
2101
2102 else if (hp_int & BUS_FREE) {
2103
2104 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2105
2106 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2107
James Bottomley 47b5d692005-04-24 02:38:05 -05002108 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 }
2110
James Bottomley 47b5d692005-04-24 02:38:05 -05002111 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 }
2113
2114
2115 else if (hp_int & ITICKLE) {
2116
2117 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2118 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2119 }
2120
2121
2122
2123 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2124
2125
2126 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2127
2128
2129 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2130
James Bottomley 47b5d692005-04-24 02:38:05 -05002131 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132 }
2133
2134 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2135 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002136 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 }
2138
2139 break;
2140
2141 }
2142
2143 } /*end while */
2144
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146
2147 return(0);
2148}
2149
2150/*---------------------------------------------------------------------
2151 *
2152 * Function: Sccb_bad_isr
2153 *
2154 * Description: Some type of interrupt has occurred which is slightly
2155 * out of the ordinary. We will now decode it fully, in
2156 * this routine. This is broken up in an attempt to save
2157 * processing time.
2158 *
2159 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002160static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002161 PSCCBcard pCurrCard, unsigned short p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002163 unsigned char temp, ScamFlg;
James Bottomley 47b5d692005-04-24 02:38:05 -05002164 PSCCBMgr_tar_info currTar_Info;
2165 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
2167
2168 if (RD_HARPOON(p_port+hp_ext_status) &
2169 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2170 {
2171
2172 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2173 {
2174
James Bottomley 47b5d692005-04-24 02:38:05 -05002175 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 }
2177
2178 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2179
2180 {
2181 WR_HARPOON(p_port+hp_pci_stat_cfg,
2182 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2183
2184 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2185
2186 }
2187
2188 if (pCurrCard->currentSCCB != NULL)
2189 {
2190
2191 if (!pCurrCard->currentSCCB->HostStatus)
2192 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2193
James Bottomley 47b5d692005-04-24 02:38:05 -05002194 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002196 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002198 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2200
2201 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2202 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002203 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 }
2205 }
2206 }
2207
2208
2209 else if (p_int & RESET)
2210 {
2211
2212 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2213 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2214 if (pCurrCard->currentSCCB != NULL) {
2215
2216 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2217
James Bottomley 47b5d692005-04-24 02:38:05 -05002218 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219 }
2220
2221
2222 DISABLE_AUTO(p_port);
2223
James Bottomley 47b5d692005-04-24 02:38:05 -05002224 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225
2226 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2227
2228 pCurrNvRam = pCurrCard->pNvRamInfo;
2229 if(pCurrNvRam){
2230 ScamFlg = pCurrNvRam->niScamConf;
2231 }
2232 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002233 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 }
2235
James Bottomley 47b5d692005-04-24 02:38:05 -05002236 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
James Bottomley 47b5d692005-04-24 02:38:05 -05002238 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239
2240 return(0xFF);
2241 }
2242
2243
2244 else if (p_int & FIFO) {
2245
2246 WRW_HARPOON((p_port+hp_intstat), FIFO);
2247
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002249 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 }
2251
2252 else if (p_int & TIMEOUT)
2253 {
2254
2255 DISABLE_AUTO(p_port);
2256
2257 WRW_HARPOON((p_port+hp_intstat),
2258 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2259
2260 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2261
2262
James Bottomley 47b5d692005-04-24 02:38:05 -05002263 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2265 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002266 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002268 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269
2270
2271 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2272 {
2273 currTar_Info->TarSyncCtrl = 0;
2274 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2275 }
2276
2277 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2278 {
2279 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2280 }
2281
James Bottomley 47b5d692005-04-24 02:38:05 -05002282 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283
James Bottomley 47b5d692005-04-24 02:38:05 -05002284 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285
2286 }
2287
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 else if (p_int & SCAM_SEL)
2289 {
2290
James Bottomley 47b5d692005-04-24 02:38:05 -05002291 FPT_scarb(p_port,LEVEL2_TAR);
2292 FPT_scsel(p_port);
2293 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294
James Bottomley 47b5d692005-04-24 02:38:05 -05002295 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296
2297 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2298 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299
2300 return(0x00);
2301}
2302
2303
2304/*---------------------------------------------------------------------
2305 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 * Function: SccbMgrTableInit
2307 *
2308 * Description: Initialize all Sccb manager data structures.
2309 *
2310 *---------------------------------------------------------------------*/
2311
James Bottomley 47b5d692005-04-24 02:38:05 -05002312static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002314 unsigned char thisCard;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315
2316 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2317 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002318 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319
James Bottomley 47b5d692005-04-24 02:38:05 -05002320 FPT_BL_Card[thisCard].ioPort = 0x00;
2321 FPT_BL_Card[thisCard].cardInfo = NULL;
2322 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2323 FPT_BL_Card[thisCard].ourId = 0x00;
2324 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 }
2326}
2327
2328
2329/*---------------------------------------------------------------------
2330 *
2331 * Function: SccbMgrTableInit
2332 *
2333 * Description: Initialize all Sccb manager data structures.
2334 *
2335 *---------------------------------------------------------------------*/
2336
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002337static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002339 unsigned char scsiID, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340
2341 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2342 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002343 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344 }
2345
2346 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2347 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002348 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2349 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2350 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351 }
2352
2353 pCurrCard->scanIndex = 0x00;
2354 pCurrCard->currentSCCB = NULL;
2355 pCurrCard->globalFlags = 0x00;
2356 pCurrCard->cmdCounter = 0x00;
2357 pCurrCard->tagQ_Lst = 0x01;
2358 pCurrCard->discQCount = 0;
2359
2360
2361}
2362
2363
2364/*---------------------------------------------------------------------
2365 *
2366 * Function: SccbMgrTableInit
2367 *
2368 * Description: Initialize all Sccb manager data structures.
2369 *
2370 *---------------------------------------------------------------------*/
2371
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002372static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373{
2374
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002375 unsigned char lun, qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 PSCCBMgr_tar_info currTar_Info;
2377
James Bottomley 47b5d692005-04-24 02:38:05 -05002378 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379
2380 currTar_Info->TarSelQ_Cnt = 0;
2381 currTar_Info->TarSyncCtrl = 0;
2382
2383 currTar_Info->TarSelQ_Head = NULL;
2384 currTar_Info->TarSelQ_Tail = NULL;
2385 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002386 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002387
2388
2389 for (lun = 0; lun < MAX_LUN; lun++)
2390 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002391 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 currTar_Info->LunDiscQ_Idx[lun] = 0;
2393 }
2394
2395 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2396 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002397 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002399 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002401 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2402 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403 }
2404 }
2405 }
2406}
2407
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
2409/*---------------------------------------------------------------------
2410 *
2411 * Function: sfetm
2412 *
2413 * Description: Read in a message byte from the SCSI bus, and check
2414 * for a parity error.
2415 *
2416 *---------------------------------------------------------------------*/
2417
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002418static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002420 unsigned char message;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002421 unsigned short TimeOutLoop;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
2423 TimeOutLoop = 0;
2424 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2425 (TimeOutLoop++ < 20000) ){}
2426
2427
2428 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2429
2430 message = RD_HARPOON(port+hp_scsidata_0);
2431
2432 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2433
2434
2435 if (TimeOutLoop > 20000)
2436 message = 0x00; /* force message byte = 0 if Time Out on Req */
2437
2438 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2439 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2440 {
2441 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2442 WR_HARPOON(port+hp_xferstat, 0);
2443 WR_HARPOON(port+hp_fiforead, 0);
2444 WR_HARPOON(port+hp_fifowrite, 0);
2445 if (pCurrSCCB != NULL)
2446 {
2447 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2448 }
2449 message = 0x00;
2450 do
2451 {
2452 ACCEPT_MSG_ATN(port);
2453 TimeOutLoop = 0;
2454 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2455 (TimeOutLoop++ < 20000) ){}
2456 if (TimeOutLoop > 20000)
2457 {
2458 WRW_HARPOON((port+hp_intstat), PARITY);
2459 return(message);
2460 }
2461 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2462 {
2463 WRW_HARPOON((port+hp_intstat), PARITY);
2464 return(message);
2465 }
2466 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2467
2468 RD_HARPOON(port+hp_scsidata_0);
2469
2470 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2471
2472 }while(1);
2473
2474 }
2475 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2476 WR_HARPOON(port+hp_xferstat, 0);
2477 WR_HARPOON(port+hp_fiforead, 0);
2478 WR_HARPOON(port+hp_fifowrite, 0);
2479 return(message);
2480}
2481
2482
2483/*---------------------------------------------------------------------
2484 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002485 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 *
2487 * Description: Load up automation and select target device.
2488 *
2489 *---------------------------------------------------------------------*/
2490
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002491static void FPT_ssel(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492{
2493
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002494 unsigned char auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002496 unsigned long cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 PSCCBcard CurrCard;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002498 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002500 unsigned char lastTag, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501
James Bottomley 47b5d692005-04-24 02:38:05 -05002502 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 currSCCB = CurrCard->currentSCCB;
2504 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002505 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 lastTag = CurrCard->tagQ_Lst;
2507
2508 ARAM_ACCESS(port);
2509
2510
2511 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2512 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2513
2514 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2515 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2516
2517 lun = currSCCB->Lun;
2518 else
2519 lun = 0;
2520
2521
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 if (CurrCard->globalFlags & F_TAG_STARTED)
2523 {
2524 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2525 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002526 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2528 == TAG_Q_TRYING))
2529 {
2530
2531 if (currTar_Info->TarTagQ_Cnt !=0)
2532 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002533 currTar_Info->TarLUNBusy[lun] = 1;
2534 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 SGRAM_ACCESS(port);
2536 return;
2537 }
2538
2539 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002540 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 }
2542
2543 } /*End non-tagged */
2544
2545 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002546 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547 }
2548
2549 } /*!Use cmd Q Tagged */
2550
2551 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002552 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002553 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002554 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 SGRAM_ACCESS(port);
2556 return;
2557 }
2558
James Bottomley 47b5d692005-04-24 02:38:05 -05002559 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560
2561 } /*else use cmd Q tagged */
2562
2563 } /*if glob tagged started */
2564
2565 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002566 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 }
2568
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
2570
2571 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2572 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2573 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2574 {
2575 if(CurrCard->discQCount >= QUEUE_DEPTH)
2576 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002577 currTar_Info->TarLUNBusy[lun] = 1;
2578 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 SGRAM_ACCESS(port);
2580 return;
2581 }
2582 for (i = 1; i < QUEUE_DEPTH; i++)
2583 {
2584 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2585 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2586 {
2587 CurrCard->tagQ_Lst = lastTag;
2588 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2589 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2590 CurrCard->discQCount++;
2591 break;
2592 }
2593 }
2594 if(i == QUEUE_DEPTH)
2595 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002596 currTar_Info->TarLUNBusy[lun] = 1;
2597 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598 SGRAM_ACCESS(port);
2599 return;
2600 }
2601 }
2602
2603
2604
James Bottomley 47b5d692005-04-24 02:38:05 -05002605 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606
2607 WR_HARPOON(port+hp_select_id, target);
2608 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2609
2610 if (currSCCB->OperationCode == RESET_COMMAND) {
2611 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2612 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2613
2614 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2615
2616 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2617
2618 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002619 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002620 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2621
2622 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2623 {
2624 currTar_Info->TarSyncCtrl = 0;
2625 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2626 }
2627
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2629 {
2630 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2631 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632
James Bottomley 47b5d692005-04-24 02:38:05 -05002633 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2634 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635
2636 }
2637
2638 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2639 {
2640 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2641 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2642
2643 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2644
2645 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002646 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2647 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648 WRW_HARPOON((port+SYNC_MSGS+2),
2649 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2650 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2651
2652 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002653 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654
2655 }
2656
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002658 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2660 }
2661
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2663 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002664 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2666 }
2667
2668
2669 if (!auto_loaded)
2670 {
2671
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 if (currSCCB->ControlByte & F_USE_CMD_Q)
2673 {
2674
2675 CurrCard->globalFlags |= F_TAG_STARTED;
2676
2677 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2678 == TAG_Q_REJECT)
2679 {
2680 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2681
2682 /* Fix up the start instruction with a jump to
2683 Non-Tag-CMD handling */
2684 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2685
2686 WRW_HARPOON((port+NON_TAG_ID_MSG),
2687 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2688
2689 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2690
2691 /* Setup our STATE so we know what happend when
2692 the wheels fall off. */
2693 currSCCB->Sccb_scsistat = SELECT_ST;
2694
James Bottomley 47b5d692005-04-24 02:38:05 -05002695 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696 }
2697
2698 else
2699 {
2700 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2701
2702 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002703 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2704 >> 6) | (unsigned char)0x20)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705
2706 for (i = 1; i < QUEUE_DEPTH; i++)
2707 {
2708 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2709 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2710 {
2711 WRW_HARPOON((port+ID_MSG_STRT+6),
2712 (MPM_OP+AMSG_OUT+lastTag));
2713 CurrCard->tagQ_Lst = lastTag;
2714 currSCCB->Sccb_tag = lastTag;
2715 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2716 CurrCard->discQCount++;
2717 break;
2718 }
2719 }
2720
2721
2722 if ( i == QUEUE_DEPTH )
2723 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002724 currTar_Info->TarLUNBusy[lun] = 1;
2725 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726 SGRAM_ACCESS(port);
2727 return;
2728 }
2729
2730 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2731
2732 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2733 }
2734 }
2735
2736 else
2737 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738
2739 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2740
2741 WRW_HARPOON((port+NON_TAG_ID_MSG),
2742 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2743
2744 currSCCB->Sccb_scsistat = SELECT_ST;
2745
2746 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748
2749
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002750 theCCB = (unsigned char *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
2752 cdb_reg = port + CMD_STRT;
2753
2754 for (i=0; i < currSCCB->CdbLength; i++)
2755 {
2756 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2757 cdb_reg +=2;
2758 theCCB++;
2759 }
2760
2761 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2762 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2763
2764 } /* auto_loaded */
2765
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002766 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002768
2769 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2770
2771 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2772
2773
2774 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2775 {
2776 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2777 }
2778 else
2779 {
2780
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002781/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782 auto_loaded |= AUTO_IMMED; */
2783 auto_loaded = AUTO_IMMED;
2784
2785 DISABLE_AUTO(port);
2786
2787 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2788 }
2789
2790 SGRAM_ACCESS(port);
2791}
2792
2793
2794/*---------------------------------------------------------------------
2795 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002796 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 *
2798 * Description: Hookup the correct CCB and handle the incoming messages.
2799 *
2800 *---------------------------------------------------------------------*/
2801
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08002802static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803{
2804
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002805 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806
2807
2808 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08002809 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002810
2811
2812
2813
2814 if(pCurrCard->currentSCCB != NULL)
2815 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002816 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 DISABLE_AUTO(port);
2818
2819
2820 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2821
2822
2823 currSCCB = pCurrCard->currentSCCB;
2824 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2825 {
2826 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2827 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2828 }
2829 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2830 {
2831 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2832 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2833 }
2834 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2835 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2836 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002837 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 if(currSCCB->Sccb_scsistat != ABORT_ST)
2839 {
2840 pCurrCard->discQCount--;
2841 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2842 = NULL;
2843 }
2844 }
2845 else
2846 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002847 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 if(currSCCB->Sccb_tag)
2849 {
2850 if(currSCCB->Sccb_scsistat != ABORT_ST)
2851 {
2852 pCurrCard->discQCount--;
2853 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2854 }
2855 }else
2856 {
2857 if(currSCCB->Sccb_scsistat != ABORT_ST)
2858 {
2859 pCurrCard->discQCount--;
2860 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2861 }
2862 }
2863 }
2864
James Bottomley 47b5d692005-04-24 02:38:05 -05002865 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 }
2867
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08002868 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869
2870
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002871 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002872 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873
2874
2875 msgRetryCount = 0;
2876 do
2877 {
2878
James Bottomley 47b5d692005-04-24 02:38:05 -05002879 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002880 tag = 0;
2881
2882
2883 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2884 {
2885 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2886 {
2887
2888 WRW_HARPOON((port+hp_intstat), PHASE);
2889 return;
2890 }
2891 }
2892
2893 WRW_HARPOON((port+hp_intstat), PHASE);
2894 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2895 {
2896
James Bottomley 47b5d692005-04-24 02:38:05 -05002897 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898 if (message)
2899 {
2900
2901 if (message <= (0x80 | LUN_MASK))
2902 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08002903 lun = message & (unsigned char)LUN_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2906 {
2907 if (currTar_Info->TarTagQ_Cnt != 0)
2908 {
2909
2910 if (!(currTar_Info->TarLUN_CA))
2911 {
2912 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2913
2914
James Bottomley 47b5d692005-04-24 02:38:05 -05002915 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 if (message)
2917 {
2918 ACCEPT_MSG(port);
2919 }
2920
2921 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002922 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923
James Bottomley 47b5d692005-04-24 02:38:05 -05002924 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002926 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927
2928 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002929 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 }
2931
2932 } /*C.A. exists! */
2933
2934 } /*End Q cnt != 0 */
2935
2936 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937
2938 } /*End valid ID message. */
2939
2940 else
2941 {
2942
2943 ACCEPT_MSG_ATN(port);
2944 }
2945
2946 } /* End good id message. */
2947
2948 else
2949 {
2950
James Bottomley 47b5d692005-04-24 02:38:05 -05002951 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952 }
2953 }
2954 else
2955 {
2956 ACCEPT_MSG_ATN(port);
2957
2958 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2959 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2960 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2961
2962 return;
2963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964
James Bottomley 47b5d692005-04-24 02:38:05 -05002965 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 {
2967 msgRetryCount++;
2968 if(msgRetryCount == 1)
2969 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002970 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002971 }
2972 else
2973 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002974 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975
James Bottomley 47b5d692005-04-24 02:38:05 -05002976 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977
James Bottomley 47b5d692005-04-24 02:38:05 -05002978 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 {
2980
James Bottomley 47b5d692005-04-24 02:38:05 -05002981 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982
2983 }
2984
James Bottomley 47b5d692005-04-24 02:38:05 -05002985 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 {
2987
James Bottomley 47b5d692005-04-24 02:38:05 -05002988 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989 }
2990
2991
James Bottomley 47b5d692005-04-24 02:38:05 -05002992 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2993 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994 return;
2995 }
2996 }
James Bottomley 47b5d692005-04-24 02:38:05 -05002997 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998
2999
3000
3001 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3002 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3003 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003004 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3006 if(pCurrCard->currentSCCB != NULL)
3007 {
3008 ACCEPT_MSG(port);
3009 }
3010 else
3011 {
3012 ACCEPT_MSG_ATN(port);
3013 }
3014 }
3015 else
3016 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003017 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
3019
3020 if (tag)
3021 {
3022 if (pCurrCard->discQ_Tbl[tag] != NULL)
3023 {
3024 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3025 currTar_Info->TarTagQ_Cnt--;
3026 ACCEPT_MSG(port);
3027 }
3028 else
3029 {
3030 ACCEPT_MSG_ATN(port);
3031 }
3032 }else
3033 {
3034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3035 if(pCurrCard->currentSCCB != NULL)
3036 {
3037 ACCEPT_MSG(port);
3038 }
3039 else
3040 {
3041 ACCEPT_MSG_ATN(port);
3042 }
3043 }
3044 }
3045
3046 if(pCurrCard->currentSCCB != NULL)
3047 {
3048 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3049 {
3050 /* During Abort Tag command, the target could have got re-selected
3051 and completed the command. Check the select Q and remove the CCB
3052 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003053 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 }
3055 }
3056
3057
3058 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3059 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3060 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3061}
3062
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003063static void FPT_SendMsg(unsigned long port, unsigned char message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064{
3065 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3066 {
3067 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3068 {
3069
3070 WRW_HARPOON((port+hp_intstat), PHASE);
3071 return;
3072 }
3073 }
3074
3075 WRW_HARPOON((port+hp_intstat), PHASE);
3076 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3077 {
3078 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3079
3080
3081 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3082
3083 WR_HARPOON(port+hp_scsidata_0,message);
3084
3085 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3086
3087 ACCEPT_MSG(port);
3088
3089 WR_HARPOON(port+hp_portctrl_0, 0x00);
3090
3091 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3092 (message == SMABORT_TAG) )
3093 {
3094 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3095
3096 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3097 {
3098 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3099 }
3100 }
3101 }
3102}
3103
3104/*---------------------------------------------------------------------
3105 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003106 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 *
3108 * Description: Determine the proper responce to the message from the
3109 * target device.
3110 *
3111 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003112static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003114 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 PSCCBcard CurrCard;
3116 PSCCBMgr_tar_info currTar_Info;
3117
James Bottomley 47b5d692005-04-24 02:38:05 -05003118 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 currSCCB = CurrCard->currentSCCB;
3120
James Bottomley 47b5d692005-04-24 02:38:05 -05003121 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122
3123 if (message == SMREST_DATA_PTR)
3124 {
3125 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3126 {
3127 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3128
James Bottomley 47b5d692005-04-24 02:38:05 -05003129 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 }
3131
3132 ACCEPT_MSG(port);
3133 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3134 }
3135
3136 else if (message == SMCMD_COMP)
3137 {
3138
3139
3140 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3141 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003142 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3143 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 }
3145
3146 ACCEPT_MSG(port);
3147
3148 }
3149
3150 else if ((message == SMNO_OP) || (message >= SMIDENT)
3151 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3152 {
3153
3154 ACCEPT_MSG(port);
3155 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3156 }
3157
3158 else if (message == SMREJECT)
3159 {
3160
3161 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3162 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3163 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3164 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3165
3166 {
3167 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3168
3169 ACCEPT_MSG(port);
3170
3171
3172 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3173 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3174
3175 if(currSCCB->Lun == 0x00)
3176 {
3177 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3178 {
3179
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003180 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181
3182 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3183 }
3184
Linus Torvalds1da177e2005-04-16 15:20:36 -07003185 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3186 {
3187
3188
3189 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3190 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3191
3192 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3193
3194 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195
3196 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3197 {
3198 currTar_Info->TarStatus = (currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003199 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200
3201
3202 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3203 CurrCard->discQCount--;
3204 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3205 currSCCB->Sccb_tag = 0x00;
3206
3207 }
3208 }
3209
3210 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3211 {
3212
3213
3214 if(currSCCB->Lun == 0x00)
3215 {
3216 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3217 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3218 }
3219 }
3220
3221 else
3222 {
3223
3224 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3225 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003226 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003228 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229
3230
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003231 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003232
3233 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3234
3235 }
3236 }
3237
3238 else
3239 {
3240 ACCEPT_MSG(port);
3241
3242 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3243 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3244
3245 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3246 {
3247 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3248 }
3249 }
3250 }
3251
3252 else if (message == SMEXT)
3253 {
3254
3255 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003256 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257 }
3258
3259 else if (message == SMIGNORWR)
3260 {
3261
3262 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3263
James Bottomley 47b5d692005-04-24 02:38:05 -05003264 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003265
3266 if(currSCCB->Sccb_scsimsg != SMPARITY)
3267 ACCEPT_MSG(port);
3268 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3269 }
3270
3271
3272 else
3273 {
3274
3275 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3276 currSCCB->Sccb_scsimsg = SMREJECT;
3277
3278 ACCEPT_MSG_ATN(port);
3279 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3280 }
3281}
3282
3283
3284/*---------------------------------------------------------------------
3285 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003286 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003287 *
3288 * Description: Decide what to do with the extended message.
3289 *
3290 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003291static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003292{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003293 unsigned char length,message;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294
James Bottomley 47b5d692005-04-24 02:38:05 -05003295 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296 if (length)
3297 {
3298
3299 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003300 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301 if (message)
3302 {
3303
3304 if (message == SMSYNC)
3305 {
3306
3307 if (length == 0x03)
3308 {
3309
3310 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003311 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312 }
3313 else
3314 {
3315
3316 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3317 ACCEPT_MSG_ATN(port);
3318 }
3319 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003320 else if (message == SMWDTR)
3321 {
3322
3323 if (length == 0x02)
3324 {
3325
3326 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003327 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003328 }
3329 else
3330 {
3331
3332 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3333 ACCEPT_MSG_ATN(port);
3334
3335 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3336 }
3337 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338 else
3339 {
3340
3341 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3342 ACCEPT_MSG_ATN(port);
3343
3344 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3345 }
3346 }
3347 else
3348 {
3349 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3350 ACCEPT_MSG(port);
3351 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3352 }
3353 }else
3354 {
3355 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3356 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3357 }
3358}
3359
3360
3361/*---------------------------------------------------------------------
3362 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003363 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364 *
3365 * Description: Read in a message byte from the SCSI bus, and check
3366 * for a parity error.
3367 *
3368 *---------------------------------------------------------------------*/
3369
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003370static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003371{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003372 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373 PSCCBMgr_tar_info currTar_Info;
3374
James Bottomley 47b5d692005-04-24 02:38:05 -05003375 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3376 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003377
3378 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3379
3380
3381 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003382 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003383
3384 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3385
3386 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3387 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3388 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3389
3390
3391 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3392
3393 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3394
3395 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3396
3397 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3398
3399 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3400
3401 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3402
3403 else
3404 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3405
3406
3407 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3408 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3409 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3410
3411
James Bottomley 47b5d692005-04-24 02:38:05 -05003412 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003413 {
3414 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3415 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003416 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417 }
3418 else
3419 {
3420 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3421 }
3422
3423
James Bottomley 47b5d692005-04-24 02:38:05 -05003424 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003425 }
3426
3427 else {
3428
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003429 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003431 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003432 }
3433}
3434
3435
3436
3437/*---------------------------------------------------------------------
3438 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003439 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440 *
3441 * Description: The has sent us a Sync Nego message so handle it as
3442 * necessary.
3443 *
3444 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003445static void FPT_stsyncn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003447 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003448 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 PSCCBMgr_tar_info currTar_Info;
3450
James Bottomley 47b5d692005-04-24 02:38:05 -05003451 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3452 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003453
James Bottomley 47b5d692005-04-24 02:38:05 -05003454 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003455
3456 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3457 {
3458 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3459 return;
3460 }
3461
3462 ACCEPT_MSG(port);
3463
3464
James Bottomley 47b5d692005-04-24 02:38:05 -05003465 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466
3467 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3468 {
3469 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3470 return;
3471 }
3472
3473 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3474
3475 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3476
3477 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3478
3479 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3480
3481 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3482
3483 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3484 else
3485
3486 our_sync_msg = 0; /* Message = Async */
3487
3488 if (sync_msg < our_sync_msg) {
3489 sync_msg = our_sync_msg; /*if faster, then set to max. */
3490 }
3491
3492 if (offset == ASYNC)
3493 sync_msg = ASYNC;
3494
3495 if (offset > MAX_OFFSET)
3496 offset = MAX_OFFSET;
3497
3498 sync_reg = 0x00;
3499
3500 if (sync_msg > 12)
3501
3502 sync_reg = 0x20; /* Use 10MB/s */
3503
3504 if (sync_msg > 25)
3505
3506 sync_reg = 0x40; /* Use 6.6MB/s */
3507
3508 if (sync_msg > 38)
3509
3510 sync_reg = 0x60; /* Use 5MB/s */
3511
3512 if (sync_msg > 50)
3513
3514 sync_reg = 0x80; /* Use 4MB/s */
3515
3516 if (sync_msg > 62)
3517
3518 sync_reg = 0xA0; /* Use 3.33MB/s */
3519
3520 if (sync_msg > 75)
3521
3522 sync_reg = 0xC0; /* Use 2.85MB/s */
3523
3524 if (sync_msg > 87)
3525
3526 sync_reg = 0xE0; /* Use 2.5MB/s */
3527
3528 if (sync_msg > 100) {
3529
3530 sync_reg = 0x00; /* Use ASYNC */
3531 offset = 0x00;
3532 }
3533
3534
Linus Torvalds1da177e2005-04-16 15:20:36 -07003535 if (currTar_Info->TarStatus & WIDE_ENABLED)
3536
3537 sync_reg |= offset;
3538
3539 else
3540
3541 sync_reg |= (offset | NARROW_SCSI);
3542
James Bottomley 47b5d692005-04-24 02:38:05 -05003543 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544
3545
3546 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3547
3548
3549 ACCEPT_MSG(port);
3550
3551 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003552 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553
3554 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3555 }
3556
3557 else {
3558
3559
3560 ACCEPT_MSG_ATN(port);
3561
James Bottomley 47b5d692005-04-24 02:38:05 -05003562 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003563
3564 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003565 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003566 }
3567}
3568
3569
3570/*---------------------------------------------------------------------
3571 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003572 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573 *
3574 * Description: Answer the targets sync message.
3575 *
3576 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003577static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003578{
3579 ARAM_ACCESS(port);
3580 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3581 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3582 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3583 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3584 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3585 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3586 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3587 SGRAM_ACCESS(port);
3588
3589 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3590 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3591
3592 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3593
3594 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3595}
3596
3597
3598
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599/*---------------------------------------------------------------------
3600 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003601 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602 *
3603 * Description: Read in a message byte from the SCSI bus, and check
3604 * for a parity error.
3605 *
3606 *---------------------------------------------------------------------*/
3607
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003608static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003610 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003611 PSCCBMgr_tar_info currTar_Info;
3612
James Bottomley 47b5d692005-04-24 02:38:05 -05003613 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3614 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003615
3616 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3617
3618
3619 WRW_HARPOON((port+ID_MSG_STRT),
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003620 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003621
3622 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3623
3624 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3625 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3626 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3627 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3628 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3629 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3630
3631 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3632
3633
3634 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003635 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003636
James Bottomley 47b5d692005-04-24 02:38:05 -05003637 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638 }
3639
3640 else {
3641
3642 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003643 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644
3645 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003646 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003647 }
3648}
3649
3650
3651
3652/*---------------------------------------------------------------------
3653 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003654 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655 *
3656 * Description: The has sent us a Wide Nego message so handle it as
3657 * necessary.
3658 *
3659 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003660static void FPT_stwidn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003661{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003662 unsigned char width;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003663 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003664 PSCCBMgr_tar_info currTar_Info;
3665
James Bottomley 47b5d692005-04-24 02:38:05 -05003666 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3667 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003668
James Bottomley 47b5d692005-04-24 02:38:05 -05003669 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670
3671 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3672 {
3673 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3674 return;
3675 }
3676
3677
3678 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3679 width = 0;
3680
3681 if (width) {
3682 currTar_Info->TarStatus |= WIDE_ENABLED;
3683 width = 0;
3684 }
3685 else {
3686 width = NARROW_SCSI;
3687 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3688 }
3689
3690
James Bottomley 47b5d692005-04-24 02:38:05 -05003691 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003692
3693
3694 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3695 {
3696
3697
3698
3699 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3700
3701 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3702 {
3703 ACCEPT_MSG_ATN(port);
3704 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003705 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003706 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3707 SGRAM_ACCESS(port);
3708 }
3709 else
3710 {
3711 ACCEPT_MSG(port);
3712 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3713 }
3714 }
3715
3716 else {
3717
3718
3719 ACCEPT_MSG_ATN(port);
3720
3721 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3722 width = SM16BIT;
3723 else
3724 width = SM8BIT;
3725
James Bottomley 47b5d692005-04-24 02:38:05 -05003726 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003727
3728 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3729 }
3730}
3731
3732
3733/*---------------------------------------------------------------------
3734 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003735 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003736 *
3737 * Description: Answer the targets Wide nego message.
3738 *
3739 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003740static void FPT_siwidr(unsigned long port, unsigned char width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003741{
3742 ARAM_ACCESS(port);
3743 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3744 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3745 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3746 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3747 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3748 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3749 SGRAM_ACCESS(port);
3750
3751 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3752 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3753
3754 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3755
3756 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3757}
3758
Linus Torvalds1da177e2005-04-16 15:20:36 -07003759
3760
3761/*---------------------------------------------------------------------
3762 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003763 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003764 *
3765 * Description: Write the desired value to the Sync Register for the
3766 * ID specified.
3767 *
3768 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003769static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
James Bottomley 47b5d692005-04-24 02:38:05 -05003770 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003771{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003772 unsigned char index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773
3774 index = p_id;
3775
3776 switch (index) {
3777
3778 case 0:
3779 index = 12; /* hp_synctarg_0 */
3780 break;
3781 case 1:
3782 index = 13; /* hp_synctarg_1 */
3783 break;
3784 case 2:
3785 index = 14; /* hp_synctarg_2 */
3786 break;
3787 case 3:
3788 index = 15; /* hp_synctarg_3 */
3789 break;
3790 case 4:
3791 index = 8; /* hp_synctarg_4 */
3792 break;
3793 case 5:
3794 index = 9; /* hp_synctarg_5 */
3795 break;
3796 case 6:
3797 index = 10; /* hp_synctarg_6 */
3798 break;
3799 case 7:
3800 index = 11; /* hp_synctarg_7 */
3801 break;
3802 case 8:
3803 index = 4; /* hp_synctarg_8 */
3804 break;
3805 case 9:
3806 index = 5; /* hp_synctarg_9 */
3807 break;
3808 case 10:
3809 index = 6; /* hp_synctarg_10 */
3810 break;
3811 case 11:
3812 index = 7; /* hp_synctarg_11 */
3813 break;
3814 case 12:
3815 index = 0; /* hp_synctarg_12 */
3816 break;
3817 case 13:
3818 index = 1; /* hp_synctarg_13 */
3819 break;
3820 case 14:
3821 index = 2; /* hp_synctarg_14 */
3822 break;
3823 case 15:
3824 index = 3; /* hp_synctarg_15 */
3825
3826 }
3827
3828 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3829
3830 currTar_Info->TarSyncCtrl = p_sync_value;
3831}
3832
3833
3834/*---------------------------------------------------------------------
3835 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003836 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003837 *
3838 * Description: Reset the desired card's SCSI bus.
3839 *
3840 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003841static void FPT_sresb(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003842{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003843 unsigned char scsiID, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003844
3845 PSCCBMgr_tar_info currTar_Info;
3846
3847 WR_HARPOON(port+hp_page_ctrl,
3848 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3849 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3850
3851 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3852
3853 scsiID = RD_HARPOON(port+hp_seltimeout);
3854 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3855 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3856
3857 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3858
3859 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3860
3861 WR_HARPOON(port+hp_seltimeout,scsiID);
3862
3863 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3864
James Bottomley 47b5d692005-04-24 02:38:05 -05003865 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866
3867 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3868
3869 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3870
3871 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3872 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003873 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874
3875 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3876 {
3877 currTar_Info->TarSyncCtrl = 0;
3878 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3879 }
3880
3881 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3882 {
3883 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3884 }
3885
James Bottomley 47b5d692005-04-24 02:38:05 -05003886 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003887
James Bottomley 47b5d692005-04-24 02:38:05 -05003888 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003889 }
3890
James Bottomley 47b5d692005-04-24 02:38:05 -05003891 FPT_BL_Card[p_card].scanIndex = 0x00;
3892 FPT_BL_Card[p_card].currentSCCB = NULL;
3893 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003894 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003895 FPT_BL_Card[p_card].cmdCounter = 0x00;
3896 FPT_BL_Card[p_card].discQCount = 0x00;
3897 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898
3899 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003900 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003901
3902 WR_HARPOON(port+hp_page_ctrl,
3903 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3904
3905}
3906
3907/*---------------------------------------------------------------------
3908 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003909 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 *
3911 * Description: Setup for the Auto Sense command.
3912 *
3913 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003914static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003915{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003916 unsigned char i;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08003917 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918
3919 currSCCB = pCurrCard->currentSCCB;
3920
3921
3922 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3923
3924 for (i = 0; i < 6; i++) {
3925
3926 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3927 }
3928
3929 currSCCB->CdbLength = SIX_BYTE_CMD;
3930 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003931 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003932 currSCCB->Cdb[2] = 0x00;
3933 currSCCB->Cdb[3] = 0x00;
3934 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3935 currSCCB->Cdb[5] = 0x00;
3936
3937 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3938
3939 currSCCB->Sccb_ATC = 0x00;
3940
3941 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3942
3943 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3944
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003945 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946
3947 currSCCB->ControlByte = 0x00;
3948
3949 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3950}
3951
3952
3953
3954/*---------------------------------------------------------------------
3955 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003956 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003957 *
3958 * Description: Transfer data into the bit bucket until the device
3959 * decides to switch phase.
3960 *
3961 *---------------------------------------------------------------------*/
3962
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08003963static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003964{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003965 unsigned char curr_phz;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966
3967
3968 DISABLE_AUTO(p_port);
3969
James Bottomley 47b5d692005-04-24 02:38:05 -05003970 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971
James Bottomley 47b5d692005-04-24 02:38:05 -05003972 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003973
3974 }
3975
3976 /* If the Automation handled the end of the transfer then do not
3977 match the phase or we will get out of sync with the ISR. */
3978
3979 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3980 return;
3981
3982 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3983
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003984 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003985
3986 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3987
3988
3989 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3990
3991 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003992 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08003994 if (curr_phz & (unsigned char)SCSI_IOBIT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995 {
3996 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3997
3998 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3999 {
4000 RD_HARPOON(p_port+hp_fifodata_0);
4001 }
4002 }
4003 else
4004 {
4005 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4006 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4007 {
4008 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4009 }
4010 }
4011 } /* End of While loop for padding data I/O phase */
4012
4013 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4014 {
4015 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4016 break;
4017 }
4018
4019 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4020 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4021 {
4022 RD_HARPOON(p_port+hp_fifodata_0);
4023 }
4024
4025 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4026 {
4027 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4028 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4029
4030 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4031 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4032 }
4033}
4034
4035
4036/*---------------------------------------------------------------------
4037 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004038 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004039 *
4040 * Description: Make sure data has been flushed from both FIFOs and abort
4041 * the operations if necessary.
4042 *
4043 *---------------------------------------------------------------------*/
4044
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004045static void FPT_schkdd(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004046{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004047 unsigned short TimeOutLoop;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004048 unsigned char sPhase;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004049
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004050 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004051
James Bottomley 47b5d692005-04-24 02:38:05 -05004052 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004053
4054
4055 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4056 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4057 return;
4058 }
4059
4060
4061
4062 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4063 {
4064
4065 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4066
4067 currSCCB->Sccb_XferCnt = 1;
4068
4069 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08004070 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004071 WR_HARPOON(port+hp_xferstat, 0x00);
4072 }
4073
4074 else
4075 {
4076
4077 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4078
4079 currSCCB->Sccb_XferCnt = 0;
4080 }
4081
4082 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4083 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4084
4085 currSCCB->HostStatus = SCCB_PARITY_ERR;
4086 WRW_HARPOON((port+hp_intstat), PARITY);
4087 }
4088
4089
James Bottomley 47b5d692005-04-24 02:38:05 -05004090 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004091
4092
4093 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4094
4095 TimeOutLoop = 0;
4096
4097 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4098 {
4099 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4100 return;
4101 }
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004102 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004103 break;
4104 }
4105 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4106 return;
4107 }
4108 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4109 break;
4110 }
4111
4112 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4113 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004114 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07004115 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4116 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4117 {
4118
4119 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4120
4121 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4122 {
4123 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004124 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004125 }
4126
4127 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004128 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004129 }
4130 }
4131 else
4132 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004133 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004134 if (!(RDW_HARPOON((port+hp_intstat)) &
4135 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4136 {
4137 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004138 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004139 }
4140 }
4141
4142 }
4143
4144 else {
4145 WR_HARPOON(port+hp_portctrl_0, 0x00);
4146 }
4147}
4148
4149
4150/*---------------------------------------------------------------------
4151 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004152 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004153 *
4154 * Description: Setup SCCB manager fields in this SCCB.
4155 *
4156 *---------------------------------------------------------------------*/
4157
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004158static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004159{
4160 PSCCBMgr_tar_info currTar_Info;
4161
4162 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4163 {
4164 return;
4165 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004166 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004167
4168 p_sccb->Sccb_XferState = 0x00;
4169 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4170
4171 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4172 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4173
4174 p_sccb->Sccb_SGoffset = 0;
4175 p_sccb->Sccb_XferState = F_SG_XFER;
4176 p_sccb->Sccb_XferCnt = 0x00;
4177 }
4178
4179 if (p_sccb->DataLength == 0x00)
4180
4181 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4182
4183 if (p_sccb->ControlByte & F_USE_CMD_Q)
4184 {
4185 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4186 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4187
4188 else
4189 currTar_Info->TarStatus |= TAG_Q_TRYING;
4190 }
4191
4192/* For !single SCSI device in system & device allow Disconnect
4193 or command is tag_q type then send Cmd with Disconnect Enable
4194 else send Cmd with Disconnect Disable */
4195
4196/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004197 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004198 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4199 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4200*/
4201 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4202 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004203 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004204 }
4205
4206 else {
4207
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004208 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004209 }
4210
4211 p_sccb->HostStatus = 0x00;
4212 p_sccb->TargetStatus = 0x00;
4213 p_sccb->Sccb_tag = 0x00;
4214 p_sccb->Sccb_MGRFlags = 0x00;
4215 p_sccb->Sccb_sgseg = 0x00;
4216 p_sccb->Sccb_ATC = 0x00;
4217 p_sccb->Sccb_savedATC = 0x00;
4218/*
4219 p_sccb->SccbVirtDataPtr = 0x00;
4220 p_sccb->Sccb_forwardlink = NULL;
4221 p_sccb->Sccb_backlink = NULL;
4222 */
4223 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4224 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4225 p_sccb->Sccb_scsimsg = SMNO_OP;
4226
4227}
4228
4229
Linus Torvalds1da177e2005-04-16 15:20:36 -07004230/*---------------------------------------------------------------------
4231 *
4232 * Function: Phase Decode
4233 *
4234 * Description: Determine the phase and call the appropriate function.
4235 *
4236 *---------------------------------------------------------------------*/
4237
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004238static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004239{
4240 unsigned char phase_ref;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004241 void (*phase) (unsigned long, unsigned char);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004242
4243
4244 DISABLE_AUTO(p_port);
4245
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004246 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004247
James Bottomley 47b5d692005-04-24 02:38:05 -05004248 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004249
4250 (*phase)(p_port, p_card); /* Call the correct phase func */
4251}
4252
4253
4254
4255/*---------------------------------------------------------------------
4256 *
4257 * Function: Data Out Phase
4258 *
4259 * Description: Start up both the BusMaster and Xbow.
4260 *
4261 *---------------------------------------------------------------------*/
4262
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004263static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004264{
4265
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004266 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004267
James Bottomley 47b5d692005-04-24 02:38:05 -05004268 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004269 if (currSCCB == NULL)
4270 {
4271 return; /* Exit if No SCCB record */
4272 }
4273
4274 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4275 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4276
4277 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4278
4279 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4280
4281 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4282
James Bottomley 47b5d692005-04-24 02:38:05 -05004283 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004284
4285 if (currSCCB->Sccb_XferCnt == 0) {
4286
4287
4288 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4289 (currSCCB->HostStatus == SCCB_COMPLETE))
4290 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4291
James Bottomley 47b5d692005-04-24 02:38:05 -05004292 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004294 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295 }
4296}
4297
4298
4299/*---------------------------------------------------------------------
4300 *
4301 * Function: Data In Phase
4302 *
4303 * Description: Startup the BusMaster and the XBOW.
4304 *
4305 *---------------------------------------------------------------------*/
4306
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004307static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308{
4309
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004310 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004311
James Bottomley 47b5d692005-04-24 02:38:05 -05004312 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313
4314 if (currSCCB == NULL)
4315 {
4316 return; /* Exit if No SCCB record */
4317 }
4318
4319
4320 currSCCB->Sccb_scsistat = DATA_IN_ST;
4321 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4322 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4323
4324 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4325
4326 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4327
4328 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4329
James Bottomley 47b5d692005-04-24 02:38:05 -05004330 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331
4332 if (currSCCB->Sccb_XferCnt == 0) {
4333
4334
4335 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4336 (currSCCB->HostStatus == SCCB_COMPLETE))
4337 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4338
James Bottomley 47b5d692005-04-24 02:38:05 -05004339 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004341 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342
4343 }
4344}
4345
4346/*---------------------------------------------------------------------
4347 *
4348 * Function: Command Phase
4349 *
4350 * Description: Load the CDB into the automation and start it up.
4351 *
4352 *---------------------------------------------------------------------*/
4353
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004354static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004355{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004356 struct sccb * currSCCB;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004357 unsigned long cdb_reg;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004358 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004359
James Bottomley 47b5d692005-04-24 02:38:05 -05004360 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361
4362 if (currSCCB->OperationCode == RESET_COMMAND) {
4363
4364 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4365 currSCCB->CdbLength = SIX_BYTE_CMD;
4366 }
4367
4368 WR_HARPOON(p_port+hp_scsisig, 0x00);
4369
4370 ARAM_ACCESS(p_port);
4371
4372
4373 cdb_reg = p_port + CMD_STRT;
4374
4375 for (i=0; i < currSCCB->CdbLength; i++) {
4376
4377 if (currSCCB->OperationCode == RESET_COMMAND)
4378
4379 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4380
4381 else
4382 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4383 cdb_reg +=2;
4384 }
4385
4386 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4387 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4388
4389 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4390
4391 currSCCB->Sccb_scsistat = COMMAND_ST;
4392
4393 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4394 SGRAM_ACCESS(p_port);
4395}
4396
4397
4398/*---------------------------------------------------------------------
4399 *
4400 * Function: Status phase
4401 *
4402 * Description: Bring in the status and command complete message bytes
4403 *
4404 *---------------------------------------------------------------------*/
4405
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004406static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004407{
4408 /* Start-up the automation to finish off this command and let the
4409 isr handle the interrupt for command complete when it comes in.
4410 We could wait here for the interrupt to be generated?
4411 */
4412
4413 WR_HARPOON(port+hp_scsisig, 0x00);
4414
4415 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4416}
4417
4418
4419/*---------------------------------------------------------------------
4420 *
4421 * Function: Phase Message Out
4422 *
4423 * Description: Send out our message (if we have one) and handle whatever
4424 * else is involed.
4425 *
4426 *---------------------------------------------------------------------*/
4427
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004428static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004429{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004430 unsigned char message,scsiID;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004431 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004432 PSCCBMgr_tar_info currTar_Info;
4433
James Bottomley 47b5d692005-04-24 02:38:05 -05004434 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004435
4436 if (currSCCB != NULL) {
4437
4438 message = currSCCB->Sccb_scsimsg;
4439 scsiID = currSCCB->TargID;
4440
4441 if (message == SMDEV_RESET)
4442 {
4443
4444
James Bottomley 47b5d692005-04-24 02:38:05 -05004445 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004446 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004447 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448
James Bottomley 47b5d692005-04-24 02:38:05 -05004449 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004450 {
4451
James Bottomley 47b5d692005-04-24 02:38:05 -05004452 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004453
4454 }
4455
James Bottomley 47b5d692005-04-24 02:38:05 -05004456 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004457 {
4458
James Bottomley 47b5d692005-04-24 02:38:05 -05004459 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004460 }
4461
4462
James Bottomley 47b5d692005-04-24 02:38:05 -05004463 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4464 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004465 }
4466 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4467 {
4468 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004469 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004470 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004471 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4472 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004473 }
4474
4475 }
4476
4477 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4478 {
4479
4480
4481 if(message == SMNO_OP)
4482 {
4483 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4484
James Bottomley 47b5d692005-04-24 02:38:05 -05004485 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 return;
4487 }
4488 }
4489 else
4490 {
4491
4492
4493 if (message == SMABORT)
4494
James Bottomley 47b5d692005-04-24 02:38:05 -05004495 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004496 }
4497
4498 }
4499 else
4500 {
4501 message = SMABORT;
4502 }
4503
4504 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4505
4506
4507 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4508
4509 WR_HARPOON(port+hp_scsidata_0,message);
4510
4511 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4512
4513 ACCEPT_MSG(port);
4514
4515 WR_HARPOON(port+hp_portctrl_0, 0x00);
4516
4517 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4518 (message == SMABORT_TAG) )
4519 {
4520
4521 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4522
4523 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4524 {
4525 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4526
4527 if (currSCCB != NULL)
4528 {
4529
James Bottomley 47b5d692005-04-24 02:38:05 -05004530 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4531 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4532 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004533 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004534 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004535
James Bottomley 47b5d692005-04-24 02:38:05 -05004536 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004537 }
4538
4539 else
4540 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004541 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004542 }
4543 }
4544
4545 else
4546 {
4547
James Bottomley 47b5d692005-04-24 02:38:05 -05004548 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004549 }
4550 }
4551
4552 else
4553 {
4554
4555 if(message == SMPARITY)
4556 {
4557 currSCCB->Sccb_scsimsg = SMNO_OP;
4558 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4559 }
4560 else
4561 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004562 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004563 }
4564 }
4565}
4566
4567
4568/*---------------------------------------------------------------------
4569 *
4570 * Function: Message In phase
4571 *
4572 * Description: Bring in the message and determine what to do with it.
4573 *
4574 *---------------------------------------------------------------------*/
4575
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004576static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004577{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004578 unsigned char message;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004579 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004580
James Bottomley 47b5d692005-04-24 02:38:05 -05004581 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004582
James Bottomley 47b5d692005-04-24 02:38:05 -05004583 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004584 {
4585
James Bottomley 47b5d692005-04-24 02:38:05 -05004586 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004587 }
4588
4589 message = RD_HARPOON(port+hp_scsidata_0);
4590 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4591 {
4592
4593 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4594
4595 }
4596
4597 else
4598 {
4599
James Bottomley 47b5d692005-04-24 02:38:05 -05004600 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004601 if (message)
4602 {
4603
4604
James Bottomley 47b5d692005-04-24 02:38:05 -05004605 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004606
4607 }
4608 else
4609 {
4610 if(currSCCB->Sccb_scsimsg != SMPARITY)
4611 ACCEPT_MSG(port);
4612 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4613 }
4614 }
4615
4616}
4617
4618
4619/*---------------------------------------------------------------------
4620 *
4621 * Function: Illegal phase
4622 *
4623 * Description: Target switched to some illegal phase, so all we can do
4624 * is report an error back to the host (if that is possible)
4625 * and send an ABORT message to the misbehaving target.
4626 *
4627 *---------------------------------------------------------------------*/
4628
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004629static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004631 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004632
James Bottomley 47b5d692005-04-24 02:38:05 -05004633 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004634
4635 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4636 if (currSCCB != NULL) {
4637
4638 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4639 currSCCB->Sccb_scsistat = ABORT_ST;
4640 currSCCB->Sccb_scsimsg = SMABORT;
4641 }
4642
4643 ACCEPT_MSG_ATN(port);
4644}
4645
4646
4647
4648/*---------------------------------------------------------------------
4649 *
4650 * Function: Phase Check FIFO
4651 *
4652 * Description: Make sure data has been flushed from both FIFOs and abort
4653 * the operations if necessary.
4654 *
4655 *---------------------------------------------------------------------*/
4656
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004657static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004658{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004659 unsigned long xfercnt;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004660 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004661
James Bottomley 47b5d692005-04-24 02:38:05 -05004662 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004663
4664 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4665 {
4666
4667 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4668 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4669
4670
4671 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4672 {
4673 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4674
4675 currSCCB->Sccb_XferCnt = 0;
4676
4677 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4678 (currSCCB->HostStatus == SCCB_COMPLETE))
4679 {
4680 currSCCB->HostStatus = SCCB_PARITY_ERR;
4681 WRW_HARPOON((port+hp_intstat), PARITY);
4682 }
4683
James Bottomley 47b5d692005-04-24 02:38:05 -05004684 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004685
James Bottomley 47b5d692005-04-24 02:38:05 -05004686 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687
4688 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4689 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4690
4691 }
4692 } /*End Data In specific code. */
4693
4694
4695
Linus Torvalds1da177e2005-04-16 15:20:36 -07004696 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004697
4698
4699 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4700
4701
4702 WR_HARPOON(port+hp_portctrl_0, 0x00);
4703
4704 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4705
4706 currSCCB->Sccb_XferCnt = xfercnt;
4707
4708 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4709 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4710
4711 currSCCB->HostStatus = SCCB_PARITY_ERR;
4712 WRW_HARPOON((port+hp_intstat), PARITY);
4713 }
4714
4715
James Bottomley 47b5d692005-04-24 02:38:05 -05004716 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004717
4718
4719 WR_HARPOON(port+hp_fifowrite, 0x00);
4720 WR_HARPOON(port+hp_fiforead, 0x00);
4721 WR_HARPOON(port+hp_xferstat, 0x00);
4722
4723 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4724}
4725
4726
4727/*---------------------------------------------------------------------
4728 *
4729 * Function: Phase Bus Free
4730 *
4731 * Description: We just went bus free so figure out if it was
4732 * because of command complete or from a disconnect.
4733 *
4734 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004735static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004736{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004737 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004738
James Bottomley 47b5d692005-04-24 02:38:05 -05004739 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004740
4741 if (currSCCB != NULL)
4742 {
4743
4744 DISABLE_AUTO(port);
4745
4746
4747 if (currSCCB->OperationCode == RESET_COMMAND)
4748 {
4749
James Bottomley 47b5d692005-04-24 02:38:05 -05004750 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4751 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4752 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004753 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004754 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004755
James Bottomley 47b5d692005-04-24 02:38:05 -05004756 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004757
James Bottomley 47b5d692005-04-24 02:38:05 -05004758 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004759
4760 }
4761
4762 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4763 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004765 (unsigned char)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004766 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004767 }
4768
4769 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4770 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004771 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4772 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004773 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4774
James Bottomley 47b5d692005-04-24 02:38:05 -05004775 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004776 }
4777
Linus Torvalds1da177e2005-04-16 15:20:36 -07004778 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4779 {
4780 /* Make sure this is not a phony BUS_FREE. If we were
4781 reselected or if BUSY is NOT on then this is a
4782 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4783
4784 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4785 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4786 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004787 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004789 }
4790
4791 else
4792 {
4793 return;
4794 }
4795 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004796
4797 else
4798 {
4799
4800 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4801
4802 if (!currSCCB->HostStatus)
4803 {
4804 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4805 }
4806
James Bottomley 47b5d692005-04-24 02:38:05 -05004807 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4808 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4809 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004810 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004811 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004812
James Bottomley 47b5d692005-04-24 02:38:05 -05004813 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004814 return;
4815 }
4816
4817
James Bottomley 47b5d692005-04-24 02:38:05 -05004818 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004819
4820 } /*end if !=null */
4821}
4822
4823
4824
4825
Linus Torvalds1da177e2005-04-16 15:20:36 -07004826/*---------------------------------------------------------------------
4827 *
4828 * Function: Auto Load Default Map
4829 *
4830 * Description: Load the Automation RAM with the defualt map values.
4831 *
4832 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004833static void FPT_autoLoadDefaultMap(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004834{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004835 unsigned long map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004836
4837 ARAM_ACCESS(p_port);
4838 map_addr = p_port + hp_aramBase;
4839
4840 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4841 map_addr +=2;
4842 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4843 map_addr +=2;
4844 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4845 map_addr +=2;
4846 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4847 map_addr +=2;
4848 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4849 map_addr +=2;
4850 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4851 map_addr +=2;
4852 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4853 map_addr +=2;
4854 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4855 map_addr +=2;
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4857 map_addr +=2;
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4859 map_addr +=2;
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4861 map_addr +=2;
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4863 map_addr +=2;
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4865 map_addr +=2;
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4867 map_addr +=2;
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4869 map_addr +=2;
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4871 map_addr +=2;
4872 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4873 map_addr +=2;
4874 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4875 map_addr +=2; /*This means AYNC DATA IN */
4876 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4877 map_addr +=2;
4878 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4879 map_addr +=2;
4880 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4881 map_addr +=2;
4882 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4883 map_addr +=2;
4884 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4885 map_addr +=2;
4886 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4887 map_addr +=2;
4888 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4889 map_addr +=2;
4890 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4891 map_addr +=2;
4892 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4893 map_addr +=2;
4894 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4895 map_addr +=2;
4896 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4897 map_addr +=2;
4898 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4899 map_addr +=2;
4900 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4901 map_addr +=2;
4902 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4903 map_addr +=2;
4904 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4905 map_addr +=2;
4906 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4907 map_addr +=2;
4908 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4909 map_addr +=2;
4910 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4911 map_addr +=2;
4912
4913 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4920 map_addr +=2; /* DIDN'T GET ONE */
4921 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4922 map_addr +=2;
4923 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4924 map_addr +=2;
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4926
4927
4928
4929 SGRAM_ACCESS(p_port);
4930}
4931
4932/*---------------------------------------------------------------------
4933 *
4934 * Function: Auto Command Complete
4935 *
4936 * Description: Post command back to host and find another command
4937 * to execute.
4938 *
4939 *---------------------------------------------------------------------*/
4940
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08004941static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004942{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08004943 struct sccb * currSCCB;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004944 unsigned char status_byte;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004945
James Bottomley 47b5d692005-04-24 02:38:05 -05004946 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004947
4948 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4949
James Bottomley 47b5d692005-04-24 02:38:05 -05004950 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004951
4952 if (status_byte != SSGOOD) {
4953
4954 if (status_byte == SSQ_FULL) {
4955
4956
James Bottomley 47b5d692005-04-24 02:38:05 -05004957 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4958 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004959 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004960 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4961 if(FPT_BL_Card[p_card].discQCount != 0)
4962 FPT_BL_Card[p_card].discQCount--;
4963 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 -07004964 }
4965 else
4966 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004967 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004968 if(currSCCB->Sccb_tag)
4969 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004970 if(FPT_BL_Card[p_card].discQCount != 0)
4971 FPT_BL_Card[p_card].discQCount--;
4972 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004973 }else
4974 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004975 if(FPT_BL_Card[p_card].discQCount != 0)
4976 FPT_BL_Card[p_card].discQCount--;
4977 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004978 }
4979 }
4980
4981 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4982
James Bottomley 47b5d692005-04-24 02:38:05 -05004983 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004984
4985 return;
4986 }
4987
4988 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4989 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004990 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08004991 (unsigned char)SYNC_SUPPORTED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004992
James Bottomley 47b5d692005-04-24 02:38:05 -05004993 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4994 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004995
James Bottomley 47b5d692005-04-24 02:38:05 -05004996 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4997 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004998 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004999 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5000 if(FPT_BL_Card[p_card].discQCount != 0)
5001 FPT_BL_Card[p_card].discQCount--;
5002 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 -07005003 }
5004 else
5005 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005006 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005007 if(currSCCB->Sccb_tag)
5008 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005009 if(FPT_BL_Card[p_card].discQCount != 0)
5010 FPT_BL_Card[p_card].discQCount--;
5011 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005012 }else
5013 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005014 if(FPT_BL_Card[p_card].discQCount != 0)
5015 FPT_BL_Card[p_card].discQCount--;
5016 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005017 }
5018 }
5019 return;
5020
5021 }
5022
5023 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5024 {
5025
James Bottomley 47b5d692005-04-24 02:38:05 -05005026 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5027 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005028 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5029
James Bottomley 47b5d692005-04-24 02:38:05 -05005030 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5031 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005032
James Bottomley 47b5d692005-04-24 02:38:05 -05005033 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5034 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005035 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005036 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5037 if(FPT_BL_Card[p_card].discQCount != 0)
5038 FPT_BL_Card[p_card].discQCount--;
5039 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 -07005040 }
5041 else
5042 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005043 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005044 if(currSCCB->Sccb_tag)
5045 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005046 if(FPT_BL_Card[p_card].discQCount != 0)
5047 FPT_BL_Card[p_card].discQCount--;
5048 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005049 }else
5050 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005051 if(FPT_BL_Card[p_card].discQCount != 0)
5052 FPT_BL_Card[p_card].discQCount--;
5053 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005054 }
5055 }
5056 return;
5057
5058 }
5059
5060 if (status_byte == SSCHECK)
5061 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005062 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005063 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005064 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005065 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005066 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005067 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005068 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005069 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005070 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005071 }
5072 }
5073 }
5074
5075 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5076
5077 currSCCB->SccbStatus = SCCB_ERROR;
5078 currSCCB->TargetStatus = status_byte;
5079
5080 if (status_byte == SSCHECK) {
5081
James Bottomley 47b5d692005-04-24 02:38:05 -05005082 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5083 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005084
5085
Linus Torvalds1da177e2005-04-16 15:20:36 -07005086 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5087
5088 if (currSCCB->RequestSenseLength == 0)
5089 currSCCB->RequestSenseLength = 14;
5090
James Bottomley 47b5d692005-04-24 02:38:05 -05005091 FPT_ssenss(&FPT_BL_Card[p_card]);
5092 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005093
James Bottomley 47b5d692005-04-24 02:38:05 -05005094 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5095 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005096 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005097 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5098 if(FPT_BL_Card[p_card].discQCount != 0)
5099 FPT_BL_Card[p_card].discQCount--;
5100 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 -07005101 }
5102 else
5103 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005104 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005105 if(currSCCB->Sccb_tag)
5106 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005107 if(FPT_BL_Card[p_card].discQCount != 0)
5108 FPT_BL_Card[p_card].discQCount--;
5109 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005110 }else
5111 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005112 if(FPT_BL_Card[p_card].discQCount != 0)
5113 FPT_BL_Card[p_card].discQCount--;
5114 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005115 }
5116 }
5117 return;
5118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005119 }
5120 }
5121 }
5122
5123
James Bottomley 47b5d692005-04-24 02:38:05 -05005124 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5125 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5126 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005127 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005128 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005129
5130
James Bottomley 47b5d692005-04-24 02:38:05 -05005131 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005132}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005133
5134#define SHORT_WAIT 0x0000000F
5135#define LONG_WAIT 0x0000FFFFL
5136
Linus Torvalds1da177e2005-04-16 15:20:36 -07005137
5138/*---------------------------------------------------------------------
5139 *
5140 * Function: Data Transfer Processor
5141 *
5142 * Description: This routine performs two tasks.
5143 * (1) Start data transfer by calling HOST_DATA_XFER_START
5144 * function. Once data transfer is started, (2) Depends
5145 * on the type of data transfer mode Scatter/Gather mode
5146 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5147 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5148 * data transfer done. In Scatter/Gather mode, this routine
5149 * checks bus master command complete and dual rank busy
5150 * bit to keep chaining SC transfer command. Similarly,
5151 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5152 * (F_HOST_XFER_ACT bit) for data transfer done.
5153 *
5154 *---------------------------------------------------------------------*/
5155
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005156static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005157{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005158 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005159
5160 currSCCB = pCurrCard->currentSCCB;
5161
5162 if (currSCCB->Sccb_XferState & F_SG_XFER)
5163 {
5164 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5165
5166 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005167 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005168 currSCCB->Sccb_SGoffset = 0x00;
5169 }
5170 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5171
James Bottomley 47b5d692005-04-24 02:38:05 -05005172 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005173 }
5174
5175 else
5176 {
5177 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5178 {
5179 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5180
James Bottomley 47b5d692005-04-24 02:38:05 -05005181 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005182 }
5183 }
5184}
5185
5186
5187/*---------------------------------------------------------------------
5188 *
5189 * Function: BusMaster Scatter Gather Data Transfer Start
5190 *
5191 * Description:
5192 *
5193 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005194static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005195{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005196 unsigned long count,addr,tmpSGCnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005197 unsigned int sg_index;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005198 unsigned char sg_count, i;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005199 unsigned long reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005200
5201
5202 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5203
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005204 count = ((unsigned long) HOST_RD_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005205 }
5206
5207 else {
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005208 count = ((unsigned long) HOST_WRT_CMD)<<24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209 }
5210
5211 sg_count = 0;
5212 tmpSGCnt = 0;
5213 sg_index = pcurrSCCB->Sccb_sgseg;
5214 reg_offset = hp_aramBase;
5215
5216
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005217 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005218
5219
5220 WR_HARPOON(p_port+hp_page_ctrl, i);
5221
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005222 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005223 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005225 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226 (sg_index * 2));
5227
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005228 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229 (sg_index * 2));
5230
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005231 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
Linus Torvalds1da177e2005-04-16 15:20:36 -07005232 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005233
5234
5235 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5236
5237 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5238 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5239
5240 tmpSGCnt = count & 0x00FFFFFFL;
5241 }
5242
5243 WR_HARP32(p_port,reg_offset,addr);
5244 reg_offset +=4;
5245
5246 WR_HARP32(p_port,reg_offset,count);
5247 reg_offset +=4;
5248
5249 count &= 0xFF000000L;
5250 sg_index++;
5251 sg_count++;
5252
5253 } /*End While */
5254
5255 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5256
5257 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5258
5259 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5260
5261 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5262
5263
5264 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5265 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5266 }
5267
5268 else {
5269
5270
5271 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5272 (tmpSGCnt & 0x000000001))
5273 {
5274
5275 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5276 tmpSGCnt--;
5277 }
5278
5279
5280 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5281
5282 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5283 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5284 }
5285
5286
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005287 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005288
5289}
5290
5291
5292/*---------------------------------------------------------------------
5293 *
5294 * Function: BusMaster Data Transfer Start
5295 *
5296 * Description:
5297 *
5298 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005299static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005300{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005301 unsigned long addr,count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005302
5303 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5304
5305 count = pcurrSCCB->Sccb_XferCnt;
5306
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005307 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005308 }
5309
5310 else {
5311 addr = pcurrSCCB->SensePointer;
5312 count = pcurrSCCB->RequestSenseLength;
5313
5314 }
5315
Linus Torvalds1da177e2005-04-16 15:20:36 -07005316 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005317
5318
5319 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5320
5321 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5322 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5323
5324 WR_HARPOON(p_port+hp_xfer_cmd,
5325 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5326 }
5327
5328 else {
5329
5330 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5331 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5332
5333 WR_HARPOON(p_port+hp_xfer_cmd,
5334 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5335
5336 }
5337}
5338
5339
5340/*---------------------------------------------------------------------
5341 *
5342 * Function: BusMaster Timeout Handler
5343 *
5344 * Description: This function is called after a bus master command busy time
5345 * out is detected. This routines issue halt state machine
5346 * with a software time out for command busy. If command busy
5347 * is still asserted at the end of the time out, it issues
5348 * hard abort with another software time out. It hard abort
5349 * command busy is also time out, it'll just give up.
5350 *
5351 *---------------------------------------------------------------------*/
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005352static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005353{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005354 unsigned long timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005355
5356 timeout = LONG_WAIT;
5357
5358 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5359
5360 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5361
5362
5363
5364 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5365 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5366
5367 timeout = LONG_WAIT;
5368 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5369 }
5370
5371 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5372
5373 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005374 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375 }
5376
5377 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005378 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005379 }
5380}
5381
5382
5383/*---------------------------------------------------------------------
5384 *
5385 * Function: Host Data Transfer Abort
5386 *
5387 * Description: Abort any in progress transfer.
5388 *
5389 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005390static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005391{
5392
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005393 unsigned long timeout;
5394 unsigned long remain_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08005395 unsigned int sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005396
James Bottomley 47b5d692005-04-24 02:38:05 -05005397 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005398
5399 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5400
5401
5402 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5403
5404 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5405 timeout = LONG_WAIT;
5406
5407 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5408
5409 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5410
5411 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5412
James Bottomley 47b5d692005-04-24 02:38:05 -05005413 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005414
5415 if (pCurrSCCB->HostStatus == 0x00)
5416
5417 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5418
5419 }
5420
5421 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5422
5423 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5424
5425 if (pCurrSCCB->HostStatus == 0x00)
5426
5427 {
5428 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005429 }
5430 }
5431 }
5432 }
5433
5434 else if (pCurrSCCB->Sccb_XferCnt) {
5435
5436 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5437
5438
5439 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5440 ~SCATTER_EN));
5441
5442 WR_HARPOON(port+hp_sg_addr,0x00);
5443
5444 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5445
Alexey Dobriyance793212006-03-08 00:14:26 -08005446 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005447
Alexey Dobriyance793212006-03-08 00:14:26 -08005448 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005449 }
5450
5451 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5452
5453 while (remain_cnt < 0x01000000L) {
5454
5455 sg_ptr--;
5456
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005457 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458 DataPointer) + (sg_ptr * 2)))) {
5459
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005460 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
Linus Torvalds1da177e2005-04-16 15:20:36 -07005461 DataPointer) + (sg_ptr * 2)));
5462 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005463
5464 else {
5465
5466 break;
5467 }
5468 }
5469
5470
5471
5472 if (remain_cnt < 0x01000000L) {
5473
5474
5475 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5476
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005477 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005478
5479
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005480 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
Linus Torvalds1da177e2005-04-16 15:20:36 -07005481 && (remain_cnt == 0))
5482
5483 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5484 }
5485
5486 else {
5487
5488
5489 if (pCurrSCCB->HostStatus == 0x00) {
5490
5491 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5492 }
5493 }
5494 }
5495
5496
5497 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5498
5499
5500 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5501
James Bottomley 47b5d692005-04-24 02:38:05 -05005502 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005503 }
5504
5505 else {
5506
5507 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5508
5509 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5510
5511 if (pCurrSCCB->HostStatus == 0x00) {
5512
5513 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005514 }
5515 }
5516 }
5517
5518 }
5519 }
5520
5521 else {
5522
5523
5524 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5525
5526 timeout = SHORT_WAIT;
5527
5528 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5529 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5530 timeout--) {}
5531 }
5532
5533 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5534
5535 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5536 FLUSH_XFER_CNTR));
5537
5538 timeout = LONG_WAIT;
5539
5540 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5541 timeout--) {}
5542
5543 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5544 ~FLUSH_XFER_CNTR));
5545
5546
5547 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5548
5549 if (pCurrSCCB->HostStatus == 0x00) {
5550
5551 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5552 }
5553
James Bottomley 47b5d692005-04-24 02:38:05 -05005554 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005555 }
5556 }
5557
5558 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5559
5560 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5561
5562 if (pCurrSCCB->HostStatus == 0x00) {
5563
5564 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005565 }
5566 }
5567 }
5568 }
5569
5570 }
5571
5572 else {
5573
5574
5575 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5576
5577 timeout = LONG_WAIT;
5578
5579 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5580
5581 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5582
5583 if (pCurrSCCB->HostStatus == 0x00) {
5584
5585 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5586 }
5587
James Bottomley 47b5d692005-04-24 02:38:05 -05005588 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005589 }
5590 }
5591
5592
5593 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5594
5595 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5596
5597 if (pCurrSCCB->HostStatus == 0x00) {
5598
5599 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005600 }
5601 }
5602
5603 }
5604
5605 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5606
5607 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5608 ~SCATTER_EN));
5609
5610 WR_HARPOON(port+hp_sg_addr,0x00);
5611
5612 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5613
5614 pCurrSCCB->Sccb_SGoffset = 0x00;
5615
5616
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005617 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005618 pCurrSCCB->DataLength) {
5619
5620 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5621
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005622 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005623
5624 }
5625 }
5626
5627 else {
5628
5629 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5630
5631 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5632 }
5633 }
5634
5635 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5636}
5637
5638
5639
5640/*---------------------------------------------------------------------
5641 *
5642 * Function: Host Data Transfer Restart
5643 *
5644 * Description: Reset the available count due to a restore data
5645 * pointers message.
5646 *
5647 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08005648static void FPT_hostDataXferRestart(struct sccb * currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005649{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005650 unsigned long data_count;
Alexey Dobriyance793212006-03-08 00:14:26 -08005651 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005652 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005653
5654 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5655
5656 currSCCB->Sccb_XferCnt = 0;
5657
5658 sg_index = 0xffff; /*Index by long words into sg list. */
5659 data_count = 0; /*Running count of SG xfer counts. */
5660
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005661 sg_ptr = (unsigned long *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005662
5663 while (data_count < currSCCB->Sccb_ATC) {
5664
5665 sg_index++;
5666 data_count += *(sg_ptr+(sg_index * 2));
5667 }
5668
5669 if (data_count == currSCCB->Sccb_ATC) {
5670
5671 currSCCB->Sccb_SGoffset = 0;
5672 sg_index++;
5673 }
5674
5675 else {
5676 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5677 }
5678
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08005679 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005680 }
5681
5682 else {
5683 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5684 }
5685}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005686
5687
5688
Linus Torvalds1da177e2005-04-16 15:20:36 -07005689/*---------------------------------------------------------------------
5690 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005691 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005692 *
5693 * Description: Setup all data structures necessary for SCAM selection.
5694 *
5695 *---------------------------------------------------------------------*/
5696
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005697static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005698{
5699
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005700 unsigned char loser,assigned_id;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005701 unsigned long p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005702
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005703 unsigned char i,k,ScamFlg ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005704 PSCCBcard currCard;
5705 PNVRamInfo pCurrNvRam;
5706
James Bottomley 47b5d692005-04-24 02:38:05 -05005707 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005708 p_port = currCard->ioPort;
5709 pCurrNvRam = currCard->pNvRamInfo;
5710
5711
5712 if(pCurrNvRam){
5713 ScamFlg = pCurrNvRam->niScamConf;
5714 i = pCurrNvRam->niSysConf;
5715 }
5716 else{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005717 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5718 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005719 }
5720 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5721 return;
5722
James Bottomley 47b5d692005-04-24 02:38:05 -05005723 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005724
5725 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5726 too slow to return to SCAM selection */
5727
5728 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005729 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005730 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005731 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005732
James Bottomley 47b5d692005-04-24 02:38:05 -05005733 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005734
5735 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5736 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005737 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005738
James Bottomley 47b5d692005-04-24 02:38:05 -05005739 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005740
5741 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005742 FPT_scxferc(p_port,SYNC_PTRN);
5743 FPT_scxferc(p_port,DOM_MSTR);
5744 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005745 } while ( loser == 0xFF );
5746
James Bottomley 47b5d692005-04-24 02:38:05 -05005747 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005748
5749 if ((p_power_up) && (!loser))
5750 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005751 FPT_sresb(p_port,p_card);
5752 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753
James Bottomley 47b5d692005-04-24 02:38:05 -05005754 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005755
James Bottomley 47b5d692005-04-24 02:38:05 -05005756 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005757
5758 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005759 FPT_scxferc(p_port, SYNC_PTRN);
5760 FPT_scxferc(p_port, DOM_MSTR);
5761 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005762 id_string[0]);
5763 } while ( loser == 0xFF );
5764
James Bottomley 47b5d692005-04-24 02:38:05 -05005765 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005766 }
5767 }
5768
5769 else
5770 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005771 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005772 }
5773
5774
5775 if (!loser)
5776 {
5777
James Bottomley 47b5d692005-04-24 02:38:05 -05005778 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005779
5780
5781 if (ScamFlg & SCAM_ENABLED)
5782 {
5783
5784 for (i=0; i < MAX_SCSI_TAR; i++)
5785 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005786 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5787 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005788 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005789 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005790 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005791 FPT_scamInfo[i].state = LEGACY;
5792 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5793 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005794 {
5795
James Bottomley 47b5d692005-04-24 02:38:05 -05005796 FPT_scamInfo[i].id_string[0] = 0xFF;
5797 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005798 if(pCurrNvRam == NULL)
5799 currCard->globalFlags |= F_UPDATE_EEPROM;
5800 }
5801 }
5802 }
5803 }
5804
James Bottomley 47b5d692005-04-24 02:38:05 -05005805 FPT_sresb(p_port,p_card);
5806 FPT_Wait1Second(p_port);
5807 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5808 FPT_scsel(p_port);
5809 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005810 }
5811
Linus Torvalds1da177e2005-04-16 15:20:36 -07005812 }
5813
5814 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5815 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005816 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5817 assigned_id = 0;
5818 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005819
5820 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005821 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005822
James Bottomley 47b5d692005-04-24 02:38:05 -05005823 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005824 if (i == ASSIGN_ID)
5825 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005826 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005827 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005828 i = FPT_scxferc(p_port,0x00);
5829 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005830 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005831 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005832
James Bottomley 47b5d692005-04-24 02:38:05 -05005833 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005834 {
5835 currCard->ourId =
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005836 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005837 FPT_inisci(p_card, p_port, p_our_id);
5838 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5839 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005840 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005841 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005842 }
5843 }
5844 }
5845 }
5846
5847 else if (i == SET_P_FLAG)
5848 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005849 if (!(FPT_scsendi(p_port,
5850 &FPT_scamInfo[p_our_id].id_string[0])))
5851 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005852 }
5853 }while (!assigned_id);
5854
James Bottomley 47b5d692005-04-24 02:38:05 -05005855 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 }
5857
Linus Torvalds1da177e2005-04-16 15:20:36 -07005858 if (ScamFlg & SCAM_ENABLED)
5859 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005860 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005861 if (currCard->globalFlags & F_UPDATE_EEPROM)
5862 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005863 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005864 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5865 }
5866 }
5867
5868
Linus Torvalds1da177e2005-04-16 15:20:36 -07005869/*
5870 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5871 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005872 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5873 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005874 k++;
5875 }
5876
5877 if (k==2)
5878 currCard->globalFlags |= F_SINGLE_DEVICE;
5879 else
5880 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5881*/
5882}
5883
5884
5885/*---------------------------------------------------------------------
5886 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005887 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005888 *
5889 * Description: Gain control of the bus and wait SCAM select time (250ms)
5890 *
5891 *---------------------------------------------------------------------*/
5892
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005893static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005894{
5895 if (p_sel_type == INIT_SELTD)
5896 {
5897
5898 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5899
5900
5901 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005902 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005903
5904 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005905 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005906
5907 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5908
5909 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5910
5911 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5912 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005913 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005914 }
5915
5916
5917 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5918
5919 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5920
5921 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5922 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005923 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005924 }
5925 }
5926
5927
5928 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5929 & ~ACTdeassert));
5930 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5931 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005933 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5934
5935 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5936
5937 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5938 & ~SCSI_BSY));
5939
James Bottomley 47b5d692005-04-24 02:38:05 -05005940 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005941
James Bottomley 47b5d692005-04-24 02:38:05 -05005942 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005943}
5944
5945
5946/*---------------------------------------------------------------------
5947 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005948 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005949 *
5950 * Description: Release the SCSI bus and disable SCAM selection.
5951 *
5952 *---------------------------------------------------------------------*/
5953
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005954static void FPT_scbusf(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005955{
5956 WR_HARPOON(p_port+hp_page_ctrl,
5957 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5958
5959
5960 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5961
5962 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5963 & ~SCSI_BUS_EN));
5964
5965 WR_HARPOON(p_port+hp_scsisig, 0x00);
5966
5967
5968 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5969 & ~SCAM_EN));
5970
5971 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5972 | ACTdeassert));
5973
Linus Torvalds1da177e2005-04-16 15:20:36 -07005974 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005975
5976 WR_HARPOON(p_port+hp_page_ctrl,
5977 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5978}
5979
5980
5981
5982/*---------------------------------------------------------------------
5983 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005984 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07005985 *
5986 * Description: Assign an ID to all the SCAM devices.
5987 *
5988 *---------------------------------------------------------------------*/
5989
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08005990static void FPT_scasid(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005991{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005992 unsigned char temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005993
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08005994 unsigned char i,k,scam_id;
5995 unsigned char crcBytes[3];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005996 PNVRamInfo pCurrNvRam;
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08005997 unsigned short * pCrcBytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005998
James Bottomley 47b5d692005-04-24 02:38:05 -05005999 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006000
James Bottomley 47b5d692005-04-24 02:38:05 -05006001 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006002
6003 while (!i)
6004 {
6005
6006 for (k=0; k < ID_STRING_LENGTH; k++)
6007 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006008 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006009 }
6010
James Bottomley 47b5d692005-04-24 02:38:05 -05006011 FPT_scxferc(p_port,SYNC_PTRN);
6012 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006013
James Bottomley 47b5d692005-04-24 02:38:05 -05006014 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006015 {
6016 if(pCurrNvRam){
Alexey Dobriyanfd1e29e2006-03-08 00:14:27 -08006017 pCrcBytes = (unsigned short *)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006018 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6019 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006020 temp_id_string[1] = crcBytes[2];
6021 temp_id_string[2] = crcBytes[0];
6022 temp_id_string[3] = crcBytes[1];
6023 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006024 temp_id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006025 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006026 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006027
6028 if (i == CLR_PRIORITY)
6029 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006030 FPT_scxferc(p_port,MISC_CODE);
6031 FPT_scxferc(p_port,CLR_P_FLAG);
6032 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006033 }
6034
6035 else if (i != NO_ID_AVAIL)
6036 {
6037 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006038 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006039 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006040 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006041
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006042 scam_id = (i & (unsigned char) 0x07);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006043
6044
6045 for (k=1; k < 0x08; k <<= 1)
6046 if (!( k & i ))
6047 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6048
James Bottomley 47b5d692005-04-24 02:38:05 -05006049 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006050
James Bottomley 47b5d692005-04-24 02:38:05 -05006051 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006052 }
6053 }
6054
6055 else
6056 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006057 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006058 }
6059
6060 } /*End while */
6061
James Bottomley 47b5d692005-04-24 02:38:05 -05006062 FPT_scxferc(p_port,SYNC_PTRN);
6063 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006064}
6065
6066
6067
6068
6069
6070/*---------------------------------------------------------------------
6071 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006072 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006073 *
6074 * Description: Select all the SCAM devices.
6075 *
6076 *---------------------------------------------------------------------*/
6077
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006078static void FPT_scsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006079{
6080
6081 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006082 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006083
6084 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6085
6086
6087 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006088 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6089 (unsigned char)(BIT(7)+BIT(6))));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006090
6091
6092 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006093 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006094
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006095 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6096 ~(unsigned char)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006097 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006098
6099 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6100}
6101
6102
6103
6104/*---------------------------------------------------------------------
6105 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006106 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006107 *
6108 * Description: Handshake the p_data (DB4-0) across the bus.
6109 *
6110 *---------------------------------------------------------------------*/
6111
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006112static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006113{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006114 unsigned char curr_data, ret_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006115
6116 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6117
6118 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6119
6120 curr_data &= ~BIT(7);
6121
6122 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6123
James Bottomley 47b5d692005-04-24 02:38:05 -05006124 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006125 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6126
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006127 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006128
6129 curr_data |= BIT(6);
6130
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132
6133 curr_data &= ~BIT(5);
6134
6135 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6136
James Bottomley 47b5d692005-04-24 02:38:05 -05006137 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006138
6139 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6140 curr_data |= BIT(7);
6141
6142 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6143
6144 curr_data &= ~BIT(6);
6145
6146 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6147
James Bottomley 47b5d692005-04-24 02:38:05 -05006148 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006149
6150 return(ret_data);
6151}
6152
6153
6154/*---------------------------------------------------------------------
6155 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006156 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006157 *
6158 * Description: Transfer our Identification string to determine if we
6159 * will be the dominant master.
6160 *
6161 *---------------------------------------------------------------------*/
6162
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006163static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006164{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006165 unsigned char ret_data,byte_cnt,bit_cnt,defer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006166
James Bottomley 47b5d692005-04-24 02:38:05 -05006167 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006168
6169 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6170
6171 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6172
6173 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006174 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006175
6176 else if (p_id_string[byte_cnt] & bit_cnt)
6177
James Bottomley 47b5d692005-04-24 02:38:05 -05006178 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006179
6180 else {
6181
James Bottomley 47b5d692005-04-24 02:38:05 -05006182 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006183 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006184 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006185 }
6186
6187 if ((ret_data & 0x1C) == 0x10)
6188 return(0x00); /*End of isolation stage, we won! */
6189
6190 if (ret_data & 0x1C)
6191 return(0xFF);
6192
6193 if ((defer) && (!(ret_data & 0x1F)))
6194 return(0x01); /*End of isolation stage, we lost. */
6195
6196 } /*bit loop */
6197
6198 } /*byte loop */
6199
6200 if (defer)
6201 return(0x01); /*We lost */
6202 else
6203 return(0); /*We WON! Yeeessss! */
6204}
6205
6206
6207
6208/*---------------------------------------------------------------------
6209 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006210 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006211 *
6212 * Description: Transfer the Identification string.
6213 *
6214 *---------------------------------------------------------------------*/
6215
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006216static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006217{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006218 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006219
6220 the_data = 0;
6221
6222 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6223
6224 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6225
James Bottomley 47b5d692005-04-24 02:38:05 -05006226 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006227
6228 if (ret_data & 0xFC)
6229 return(0xFF);
6230
6231 else {
6232
6233 the_data <<= 1;
6234 if (ret_data & BIT(1)) {
6235 the_data |= 1;
6236 }
6237 }
6238
6239 if ((ret_data & 0x1F) == 0)
6240 {
6241/*
6242 if(bit_cnt != 0 || bit_cnt != 8)
6243 {
6244 byte_cnt = 0;
6245 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006246 FPT_scxferc(p_port, SYNC_PTRN);
6247 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006248 continue;
6249 }
6250*/
6251 if (byte_cnt)
6252 return(0x00);
6253 else
6254 return(0xFF);
6255 }
6256
6257 } /*bit loop */
6258
6259 p_id_string[byte_cnt] = the_data;
6260
6261 } /*byte loop */
6262
6263 return(0);
6264}
6265
6266
6267
6268/*---------------------------------------------------------------------
6269 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006270 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006271 *
6272 * Description: Sample the SCSI data bus making sure the signal has been
6273 * deasserted for the correct number of consecutive samples.
6274 *
6275 *---------------------------------------------------------------------*/
6276
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006277static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006278{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006279 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006280
6281 i = 0;
6282 while ( i < MAX_SCSI_TAR ) {
6283
6284 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6285
6286 i = 0;
6287
6288 else
6289
6290 i++;
6291
6292 }
6293}
6294
6295
6296
6297/*---------------------------------------------------------------------
6298 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006299 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006300 *
6301 * Description: Sample the SCSI Signal lines making sure the signal has been
6302 * deasserted for the correct number of consecutive samples.
6303 *
6304 *---------------------------------------------------------------------*/
6305
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006306static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006307{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006308 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006309
6310 i = 0;
6311 while ( i < MAX_SCSI_TAR ) {
6312
6313 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6314
6315 i = 0;
6316
6317 else
6318
6319 i++;
6320
6321 }
6322}
6323
6324
6325/*---------------------------------------------------------------------
6326 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006327 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006328 *
6329 * Description: Make sure we received a valid data byte.
6330 *
6331 *---------------------------------------------------------------------*/
6332
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006333static unsigned char FPT_scvalq(unsigned char p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006334{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006335 unsigned char count;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336
6337 for (count=1; count < 0x08; count<<=1) {
6338 if (!(p_quintet & count))
6339 p_quintet -= 0x80;
6340 }
6341
6342 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006343 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006344
6345 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006346 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006347}
6348
6349
6350/*---------------------------------------------------------------------
6351 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006352 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006353 *
6354 * Description: Select the specified device ID using a selection timeout
6355 * less than 4ms. If somebody responds then it is a legacy
6356 * drive and this ID must be marked as such.
6357 *
6358 *---------------------------------------------------------------------*/
6359
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006360static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006361{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006362 unsigned long i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363
6364 WR_HARPOON(p_port+hp_page_ctrl,
6365 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6366
6367 ARAM_ACCESS(p_port);
6368
6369 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6370 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6371
6372
6373 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6374 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6375 }
6376 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6377
6378 WRW_HARPOON((p_port+hp_intstat),
6379 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6380
6381 WR_HARPOON(p_port+hp_select_id, targ_id);
6382
6383 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6384 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6385 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6386
6387
6388 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6389 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6390
6391 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006392 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006393
6394 DISABLE_AUTO(p_port);
6395
6396 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6397 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6398
6399 SGRAM_ACCESS(p_port);
6400
6401 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6402
6403 WRW_HARPOON((p_port+hp_intstat),
6404 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6405
6406 WR_HARPOON(p_port+hp_page_ctrl,
6407 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6408
James Bottomley 47b5d692005-04-24 02:38:05 -05006409 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006410 }
6411
6412 else {
6413
6414 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6415 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6416 {
6417 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6418 ACCEPT_MSG(p_port);
6419 }
6420 }
6421
6422 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6423
6424 WR_HARPOON(p_port+hp_page_ctrl,
6425 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6426
James Bottomley 47b5d692005-04-24 02:38:05 -05006427 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006428 }
6429}
6430
Linus Torvalds1da177e2005-04-16 15:20:36 -07006431/*---------------------------------------------------------------------
6432 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006433 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006434 *
6435 * Description: Wait to be selected by another SCAM initiator.
6436 *
6437 *---------------------------------------------------------------------*/
6438
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006439static void FPT_scwtsel(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006440{
6441 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6442}
6443
6444
6445/*---------------------------------------------------------------------
6446 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006447 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006448 *
6449 * Description: Setup the data Structure with the info from the EEPROM.
6450 *
6451 *---------------------------------------------------------------------*/
6452
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006453static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006454{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006455 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006456 unsigned short ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457 PNVRamInfo pCurrNvRam;
6458
James Bottomley 47b5d692005-04-24 02:38:05 -05006459 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460
6461 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6462 max_id = 0x08;
6463
6464 else
6465 max_id = 0x10;
6466
6467 if(pCurrNvRam){
6468 for(i = 0; i < max_id; i++){
6469
6470 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006471 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006472 for(k = 4; k < ID_STRING_LENGTH; k++)
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006473 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006474
James Bottomley 47b5d692005-04-24 02:38:05 -05006475 if(FPT_scamInfo[i].id_string[0] == 0x00)
6476 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006477 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006478 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006479
6480 }
6481 }else {
6482 for (i=0; i < max_id; i++)
6483 {
6484 for (k=0; k < ID_STRING_LENGTH; k+=2)
6485 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006486 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6487 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006488 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489 ee_data >>= 8;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006490 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006491 }
6492
James Bottomley 47b5d692005-04-24 02:38:05 -05006493 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6494 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006495
James Bottomley 47b5d692005-04-24 02:38:05 -05006496 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006497
6498 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006499 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006500
6501 }
6502 }
6503 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006504 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006505
6506}
6507
6508/*---------------------------------------------------------------------
6509 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006510 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006511 *
6512 * Description: Match the Device ID string with our values stored in
6513 * the EEPROM.
6514 *
6515 *---------------------------------------------------------------------*/
6516
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006517static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518{
6519
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006520 unsigned char i,k,match;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006521
6522
6523 for (i=0; i < MAX_SCSI_TAR; i++) {
6524
James Bottomley 47b5d692005-04-24 02:38:05 -05006525 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526
6527 for (k=0; k < ID_STRING_LENGTH; k++)
6528 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006529 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6530 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006531 }
6532
6533 if (match)
6534 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006535 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006536 return(i);
6537 }
6538
Linus Torvalds1da177e2005-04-16 15:20:36 -07006539 }
6540
6541
6542
6543 if (p_id_string[0] & BIT(5))
6544 i = 8;
6545 else
6546 i = MAX_SCSI_TAR;
6547
6548 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006549 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006550 else
6551 match = 7;
6552
6553 while (i > 0)
6554 {
6555 i--;
6556
James Bottomley 47b5d692005-04-24 02:38:05 -05006557 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006558 {
6559 for (k=0; k < ID_STRING_LENGTH; k++)
6560 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006561 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006562 }
6563
James Bottomley 47b5d692005-04-24 02:38:05 -05006564 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565
James Bottomley 47b5d692005-04-24 02:38:05 -05006566 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6567 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568 return(match);
6569
6570 }
6571
6572
6573 match--;
6574
6575 if (match == 0xFF)
6576 {
6577 if (p_id_string[0] & BIT(5))
6578 match = 7;
6579 else
6580 match = MAX_SCSI_TAR-1;
6581 }
6582 }
6583
6584
6585
6586 if (p_id_string[0] & BIT(7))
6587 {
6588 return(CLR_PRIORITY);
6589 }
6590
6591
6592 if (p_id_string[0] & BIT(5))
6593 i = 8;
6594 else
6595 i = MAX_SCSI_TAR;
6596
6597 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006598 match = p_id_string[1] & (unsigned char) 0x1F;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006599 else
6600 match = 7;
6601
6602 while (i > 0)
6603 {
6604
6605 i--;
6606
James Bottomley 47b5d692005-04-24 02:38:05 -05006607 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006608 {
6609 for (k=0; k < ID_STRING_LENGTH; k++)
6610 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006611 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006612 }
6613
James Bottomley 47b5d692005-04-24 02:38:05 -05006614 FPT_scamInfo[match].id_string[0] |= BIT(7);
6615 FPT_scamInfo[match].state = ID_ASSIGNED;
6616 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6617 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006618 return(match);
6619
6620 }
6621
6622
6623 match--;
6624
6625 if (match == 0xFF)
6626 {
6627 if (p_id_string[0] & BIT(5))
6628 match = 7;
6629 else
6630 match = MAX_SCSI_TAR-1;
6631 }
6632 }
6633
6634 return(NO_ID_AVAIL);
6635}
6636
6637
6638/*---------------------------------------------------------------------
6639 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006640 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006641 *
6642 * Description: Save off the device SCAM ID strings.
6643 *
6644 *---------------------------------------------------------------------*/
6645
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006646static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006647{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006648 unsigned char i,k,max_id;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006649 unsigned short ee_data,sum_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006650
6651
6652 sum_data = 0x0000;
6653
6654 for (i = 1; i < EE_SCAMBASE/2; i++)
6655 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006656 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006657 }
6658
6659
James Bottomley 47b5d692005-04-24 02:38:05 -05006660 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006661
6662 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6663 max_id = 0x08;
6664
6665 else
6666 max_id = 0x10;
6667
6668 for (i=0; i < max_id; i++)
6669 {
6670
6671 for (k=0; k < ID_STRING_LENGTH; k+=2)
6672 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006673 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006674 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006675 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676 sum_data += ee_data;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006677 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6678 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006679 }
6680 }
6681
6682
James Bottomley 47b5d692005-04-24 02:38:05 -05006683 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6684 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006685}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686
6687/*---------------------------------------------------------------------
6688 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006689 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690 *
6691 * Description: Setup the Xbow for normal operation.
6692 *
6693 *---------------------------------------------------------------------*/
6694
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006695static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006696{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006697unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006698
6699 i = RD_HARPOON(port+hp_page_ctrl);
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006700 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006701
6702 WR_HARPOON(port+hp_scsireset,0x00);
6703 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6704
6705 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6706 FIFO_CLR));
6707
6708 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6709
6710 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6711
6712 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6713 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6714
6715 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6716
James Bottomley 47b5d692005-04-24 02:38:05 -05006717 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006718 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6719
6720 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006721 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006722
James Bottomley 47b5d692005-04-24 02:38:05 -05006723 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006724
6725 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6726
6727 /* Turn on SCSI_MODE8 for narrow cards to fix the
6728 strapping issue with the DUAL CHANNEL card */
6729 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6730 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6731
Linus Torvalds1da177e2005-04-16 15:20:36 -07006732 WR_HARPOON(port+hp_page_ctrl, i);
6733
6734}
6735
6736
6737/*---------------------------------------------------------------------
6738 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006739 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006740 *
6741 * Description: Initialize the BusMaster for normal operations.
6742 *
6743 *---------------------------------------------------------------------*/
6744
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006745static void FPT_BusMasterInit(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006746{
6747
6748
6749 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6750 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6751
6752 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6753
6754
6755 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6756
6757 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6758
6759
Linus Torvalds1da177e2005-04-16 15:20:36 -07006760 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6761 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6762 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6763 ~SCATTER_EN));
6764}
6765
6766
6767/*---------------------------------------------------------------------
6768 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006769 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006770 *
6771 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6772 * necessary.
6773 *
6774 *---------------------------------------------------------------------*/
6775
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08006776static void FPT_DiagEEPROM(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006777{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08006778 unsigned short index,temp,max_wd_cnt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006779
6780 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6781 max_wd_cnt = EEPROM_WD_CNT;
6782 else
6783 max_wd_cnt = EEPROM_WD_CNT * 2;
6784
James Bottomley 47b5d692005-04-24 02:38:05 -05006785 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006786
6787 if (temp == 0x4641) {
6788
6789 for (index = 2; index < max_wd_cnt; index++) {
6790
James Bottomley 47b5d692005-04-24 02:38:05 -05006791 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006792
6793 }
6794
James Bottomley 47b5d692005-04-24 02:38:05 -05006795 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006796
6797 return; /*EEPROM is Okay so return now! */
6798 }
6799 }
6800
6801
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006802 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006803
6804 for (index = 0; index < max_wd_cnt; index++) {
6805
James Bottomley 47b5d692005-04-24 02:38:05 -05006806 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006807 }
6808
6809 temp = 0;
6810
James Bottomley 47b5d692005-04-24 02:38:05 -05006811 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006812 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006813 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006814 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006815 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006816 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006817 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006818 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006819 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006820 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006821 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006822 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006823 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006824 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006825 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006826 temp += 0x0007;
6827
James Bottomley 47b5d692005-04-24 02:38:05 -05006828 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006829 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006830 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006831 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006832 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006833 temp += 0x0000;
6834
James Bottomley 47b5d692005-04-24 02:38:05 -05006835 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006837 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006838 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006839 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006840 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006841 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006842 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006844 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006846 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006848 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006850 temp += 0x4242;
6851
6852
James Bottomley 47b5d692005-04-24 02:38:05 -05006853 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006854 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006855 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006856 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006857 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006859 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006861 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006863 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006864 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006865 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006866 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006867 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006868 temp += 0x2020;
6869
6870 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006871 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006872 temp += (0x0700+TYPE_CODE0);
6873 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006874 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 temp += 0x5542; /* BUSLOGIC */
6876 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006877 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006878 temp += 0x4C53;
6879 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006880 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006881 temp += 0x474F;
6882 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006883 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006884 temp += 0x4349;
6885 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006886 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887 temp += 0x5442; /* BT- 930 */
6888 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006889 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006890 temp += 0x202D;
6891 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006892 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006893 temp += 0x3339;
6894 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006895 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006896 temp += 0x2030;
6897 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006898 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006899 temp += 0x5453;
6900 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006901 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006902 temp += 0x5645;
6903 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006904 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006905 temp += 0x2045;
6906 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006907 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006908 temp += 0x202F;
6909 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006910 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006911 temp += 0x4F4A;
6912 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006913 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006914 temp += 0x204E;
6915 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006916 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006917 temp += 0x3539;
6918
6919
6920
James Bottomley 47b5d692005-04-24 02:38:05 -05006921 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006922
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006923 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006924
6925}
6926
Linus Torvalds1da177e2005-04-16 15:20:36 -07006927
6928/*---------------------------------------------------------------------
6929 *
6930 * Function: Queue Search Select
6931 *
6932 * Description: Try to find a new command to execute.
6933 *
6934 *---------------------------------------------------------------------*/
6935
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006936static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006937{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08006938 unsigned char scan_ptr, lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006939 PSCCBMgr_tar_info currTar_Info;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006940 struct sccb * pOldSccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006941
6942 scan_ptr = pCurrCard->scanIndex;
6943 do
6944 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006945 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006946 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6947 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6948 {
6949 if (currTar_Info->TarSelQ_Cnt != 0)
6950 {
6951
6952 scan_ptr++;
6953 if (scan_ptr == MAX_SCSI_TAR)
6954 scan_ptr = 0;
6955
6956 for(lun=0; lun < MAX_LUN; lun++)
6957 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006958 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006959 {
6960
6961 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6962 pOldSccb = NULL;
6963
6964 while((pCurrCard->currentSCCB != NULL) &&
6965 (lun != pCurrCard->currentSCCB->Lun))
6966 {
6967 pOldSccb = pCurrCard->currentSCCB;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006968 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006969 Sccb_forwardlink;
6970 }
6971 if(pCurrCard->currentSCCB == NULL)
6972 continue;
6973 if(pOldSccb != NULL)
6974 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006975 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006976 Sccb_forwardlink;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006977 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
Linus Torvalds1da177e2005-04-16 15:20:36 -07006978 Sccb_backlink;
6979 currTar_Info->TarSelQ_Cnt--;
6980 }
6981 else
6982 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006983 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006984
6985 if (currTar_Info->TarSelQ_Head == NULL)
6986 {
6987 currTar_Info->TarSelQ_Tail = NULL;
6988 currTar_Info->TarSelQ_Cnt = 0;
6989 }
6990 else
6991 {
6992 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08006993 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006994 }
6995 }
6996 pCurrCard->scanIndex = scan_ptr;
6997
6998 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6999
7000 break;
7001 }
7002 }
7003 }
7004
7005 else
7006 {
7007 scan_ptr++;
7008 if (scan_ptr == MAX_SCSI_TAR) {
7009 scan_ptr = 0;
7010 }
7011 }
7012
7013 }
7014 else
7015 {
7016 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007017 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007018 {
7019
7020 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7021
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007022 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007023
7024 if (currTar_Info->TarSelQ_Head == NULL)
7025 {
7026 currTar_Info->TarSelQ_Tail = NULL;
7027 currTar_Info->TarSelQ_Cnt = 0;
7028 }
7029 else
7030 {
7031 currTar_Info->TarSelQ_Cnt--;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007032 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007033 }
7034
7035 scan_ptr++;
7036 if (scan_ptr == MAX_SCSI_TAR)
7037 scan_ptr = 0;
7038
7039 pCurrCard->scanIndex = scan_ptr;
7040
7041 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7042
7043 break;
7044 }
7045
7046 else
7047 {
7048 scan_ptr++;
7049 if (scan_ptr == MAX_SCSI_TAR)
7050 {
7051 scan_ptr = 0;
7052 }
7053 }
7054 }
7055 } while (scan_ptr != pCurrCard->scanIndex);
7056}
7057
7058
7059/*---------------------------------------------------------------------
7060 *
7061 * Function: Queue Select Fail
7062 *
7063 * Description: Add the current SCCB to the head of the Queue.
7064 *
7065 *---------------------------------------------------------------------*/
7066
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007067static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007068{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007069 unsigned char thisTarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007070 PSCCBMgr_tar_info currTar_Info;
7071
7072 if (pCurrCard->currentSCCB != NULL)
7073 {
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007074 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007075 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007076
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007077 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007078
7079 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7080
7081 if (currTar_Info->TarSelQ_Cnt == 0)
7082 {
7083 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7084 }
7085
7086 else
7087 {
7088 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7089 }
7090
7091
7092 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7093
7094 pCurrCard->currentSCCB = NULL;
7095 currTar_Info->TarSelQ_Cnt++;
7096 }
7097}
7098/*---------------------------------------------------------------------
7099 *
7100 * Function: Queue Command Complete
7101 *
7102 * Description: Call the callback function with the current SCCB.
7103 *
7104 *---------------------------------------------------------------------*/
7105
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007106static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007107 unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007108{
7109
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007110 unsigned char i, SCSIcmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007111 CALL_BK_FN callback;
7112 PSCCBMgr_tar_info currTar_Info;
7113
7114 SCSIcmd = p_sccb->Cdb[0];
7115
7116
7117 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7118
7119 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7120 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7121 (p_sccb->TargetStatus != SSCHECK))
7122
7123 if ((SCSIcmd == SCSI_READ) ||
7124 (SCSIcmd == SCSI_WRITE) ||
7125 (SCSIcmd == SCSI_READ_EXTENDED) ||
7126 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7127 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7128 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7129 (pCurrCard->globalFlags & F_NO_FILTER)
7130 )
7131 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7132 }
7133
7134
7135 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7136 {
7137 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7138 p_sccb->SccbStatus = SCCB_ERROR;
7139 else
7140 p_sccb->SccbStatus = SCCB_SUCCESS;
7141 }
7142
7143 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7144
7145 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7146 for (i=0; i < 6; i++) {
7147 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7148 }
7149 }
7150
7151 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7152 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7153
James Bottomley 47b5d692005-04-24 02:38:05 -05007154 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007155 }
7156
7157 pCurrCard->cmdCounter--;
7158 if (!pCurrCard->cmdCounter) {
7159
7160 if (pCurrCard->globalFlags & F_GREEN_PC) {
7161 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7162 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7163 }
7164
7165 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7166 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7167
7168 }
7169
7170 if(pCurrCard->discQCount != 0)
7171 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007172 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007173 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7174 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7175 {
7176 pCurrCard->discQCount--;
7177 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7178 }
7179 else
7180 {
7181 if(p_sccb->Sccb_tag)
7182 {
7183 pCurrCard->discQCount--;
7184 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7185 }else
7186 {
7187 pCurrCard->discQCount--;
7188 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7189 }
7190 }
7191
7192 }
7193
7194 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7195 callback(p_sccb);
7196 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7197 pCurrCard->currentSCCB = NULL;
7198}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007199
7200
7201/*---------------------------------------------------------------------
7202 *
7203 * Function: Queue Disconnect
7204 *
7205 * Description: Add SCCB to our disconnect array.
7206 *
7207 *---------------------------------------------------------------------*/
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007208static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007209{
7210 PSCCBMgr_tar_info currTar_Info;
7211
James Bottomley 47b5d692005-04-24 02:38:05 -05007212 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007213
James Bottomley 47b5d692005-04-24 02:38:05 -05007214 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007215 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7216 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007217 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007218 }
7219 else
7220 {
7221 if (p_sccb->Sccb_tag)
7222 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007223 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7224 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7225 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007226 }else
7227 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007228 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007229 }
7230 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007231 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007232}
7233
7234
7235/*---------------------------------------------------------------------
7236 *
7237 * Function: Queue Flush SCCB
7238 *
7239 * Description: Flush all SCCB's back to the host driver for this target.
7240 *
7241 *---------------------------------------------------------------------*/
7242
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007243static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007244{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007245 unsigned char qtag,thisTarg;
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007246 struct sccb * currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007247 PSCCBMgr_tar_info currTar_Info;
7248
James Bottomley 47b5d692005-04-24 02:38:05 -05007249 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007250 if(currSCCB != NULL)
7251 {
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007252 thisTarg = (unsigned char)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007253 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007254
7255 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7256
James Bottomley 47b5d692005-04-24 02:38:05 -05007257 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7258 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007259 {
7260
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007261 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007262
James Bottomley 47b5d692005-04-24 02:38:05 -05007263 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007264
James Bottomley 47b5d692005-04-24 02:38:05 -05007265 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007266 currTar_Info->TarTagQ_Cnt--;
7267
7268 }
7269 }
7270 }
7271
7272}
7273
7274/*---------------------------------------------------------------------
7275 *
7276 * Function: Queue Flush Target SCCB
7277 *
7278 * Description: Flush all SCCB's back to the host driver for this target.
7279 *
7280 *---------------------------------------------------------------------*/
7281
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007282static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7283 unsigned char error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007284{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007285 unsigned char qtag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007286 PSCCBMgr_tar_info currTar_Info;
7287
James Bottomley 47b5d692005-04-24 02:38:05 -05007288 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007289
7290 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7291
James Bottomley 47b5d692005-04-24 02:38:05 -05007292 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7293 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007294 {
7295
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007296 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007297
James Bottomley 47b5d692005-04-24 02:38:05 -05007298 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007299
James Bottomley 47b5d692005-04-24 02:38:05 -05007300 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007301 currTar_Info->TarTagQ_Cnt--;
7302
7303 }
7304 }
7305
7306}
7307
7308
7309
7310
7311
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007312static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007313{
7314 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007315 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007316
7317 p_SCCB->Sccb_forwardlink = NULL;
7318
7319 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7320
7321 if (currTar_Info->TarSelQ_Cnt == 0) {
7322
7323 currTar_Info->TarSelQ_Head = p_SCCB;
7324 }
7325
7326 else {
7327
7328 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7329 }
7330
7331
7332 currTar_Info->TarSelQ_Tail = p_SCCB;
7333 currTar_Info->TarSelQ_Cnt++;
7334}
7335
7336
7337/*---------------------------------------------------------------------
7338 *
7339 * Function: Queue Find SCCB
7340 *
7341 * Description: Search the target select Queue for this SCCB, and
7342 * remove it if found.
7343 *
7344 *---------------------------------------------------------------------*/
7345
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007346static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007347{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007348 struct sccb * q_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007349 PSCCBMgr_tar_info currTar_Info;
7350
James Bottomley 47b5d692005-04-24 02:38:05 -05007351 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007352
7353 q_ptr = currTar_Info->TarSelQ_Head;
7354
7355 while(q_ptr != NULL) {
7356
7357 if (q_ptr == p_SCCB) {
7358
7359
7360 if (currTar_Info->TarSelQ_Head == q_ptr) {
7361
7362 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7363 }
7364
7365 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7366
7367 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7368 }
7369
7370 if (q_ptr->Sccb_forwardlink != NULL) {
7371 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7372 }
7373
7374 if (q_ptr->Sccb_backlink != NULL) {
7375 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7376 }
7377
7378 currTar_Info->TarSelQ_Cnt--;
7379
James Bottomley 47b5d692005-04-24 02:38:05 -05007380 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007381 }
7382
7383 else {
7384 q_ptr = q_ptr->Sccb_forwardlink;
7385 }
7386 }
7387
7388
James Bottomley 47b5d692005-04-24 02:38:05 -05007389 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007390
7391}
7392
7393
7394/*---------------------------------------------------------------------
7395 *
7396 * Function: Utility Update Residual Count
7397 *
7398 * Description: Update the XferCnt to the remaining byte count.
7399 * If we transferred all the data then just write zero.
7400 * If Non-SG transfer then report Total Cnt - Actual Transfer
7401 * Cnt. For SG transfers add the count fields of all
7402 * remaining SG elements, as well as any partial remaining
7403 * element.
7404 *
7405 *---------------------------------------------------------------------*/
7406
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007407static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007408{
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007409 unsigned long partial_cnt;
Alexey Dobriyance793212006-03-08 00:14:26 -08007410 unsigned int sg_index;
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007411 unsigned long *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007412
7413 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7414
7415 p_SCCB->DataLength = 0x0000;
7416 }
7417
7418 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7419
7420 partial_cnt = 0x0000;
7421
7422 sg_index = p_SCCB->Sccb_sgseg;
7423
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007424 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007425
7426 if (p_SCCB->Sccb_SGoffset) {
7427
7428 partial_cnt = p_SCCB->Sccb_SGoffset;
7429 sg_index++;
7430 }
7431
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007432 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
Linus Torvalds1da177e2005-04-16 15:20:36 -07007433 p_SCCB->DataLength ) {
7434
7435 partial_cnt += *(sg_ptr+(sg_index * 2));
7436 sg_index++;
7437 }
7438
7439 p_SCCB->DataLength = partial_cnt;
7440 }
7441
7442 else {
7443
7444 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7445 }
7446}
7447
7448
7449/*---------------------------------------------------------------------
7450 *
7451 * Function: Wait 1 Second
7452 *
7453 * Description: Wait for 1 second.
7454 *
7455 *---------------------------------------------------------------------*/
7456
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007457static void FPT_Wait1Second(unsigned long p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007458{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007459 unsigned char i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007460
7461 for(i=0; i < 4; i++) {
7462
James Bottomley 47b5d692005-04-24 02:38:05 -05007463 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007464
7465 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7466 break;
7467
7468 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7469 break;
7470 }
7471}
7472
7473
7474/*---------------------------------------------------------------------
7475 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007476 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007477 *
7478 * Description: Wait the desired delay.
7479 *
7480 *---------------------------------------------------------------------*/
7481
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007482static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007483{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007484 unsigned char old_timer;
7485 unsigned char green_flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007486
7487 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7488
7489 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7490 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7491
7492 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7493 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007494 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007495
7496
7497 WR_HARPOON(p_port+hp_portctrl_0,
7498 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7499
7500 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7501
7502 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7503 break;
7504
7505 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7506 break;
7507 }
7508
7509 WR_HARPOON(p_port+hp_portctrl_0,
7510 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7511
7512 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007513 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007514
7515 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7516
7517 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7518}
7519
7520
7521/*---------------------------------------------------------------------
7522 *
7523 * Function: Enable/Disable Write to EEPROM
7524 *
7525 * Description: The EEPROM must first be enabled for writes
7526 * A total of 9 clocks are needed.
7527 *
7528 *---------------------------------------------------------------------*/
7529
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007530static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007531{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007532 unsigned char ee_value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007533
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007534 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 -07007535
7536 if (p_mode)
7537
James Bottomley 47b5d692005-04-24 02:38:05 -05007538 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007539
7540 else
7541
7542
James Bottomley 47b5d692005-04-24 02:38:05 -05007543 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007544
7545 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7546 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7547}
7548
7549
7550/*---------------------------------------------------------------------
7551 *
7552 * Function: Write EEPROM
7553 *
7554 * Description: Write a word to the EEPROM at the specified
7555 * address.
7556 *
7557 *---------------------------------------------------------------------*/
7558
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007559static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007560{
7561
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007562 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007563 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007564
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007565 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 -07007566 (SEE_MS | SEE_CS));
7567
7568
7569
James Bottomley 47b5d692005-04-24 02:38:05 -05007570 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007571
7572
7573 ee_value |= (SEE_MS + SEE_CS);
7574
7575 for(i = 0x8000; i != 0; i>>=1) {
7576
7577 if (i & ee_data)
7578 ee_value |= SEE_DO;
7579 else
7580 ee_value &= ~SEE_DO;
7581
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; /* Clock data! */
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7587 ee_value &= ~SEE_CLK;
7588 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7589 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7590 }
7591 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7592 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7593
James Bottomley 47b5d692005-04-24 02:38:05 -05007594 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007595
7596 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7597 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7599}
7600
7601/*---------------------------------------------------------------------
7602 *
7603 * Function: Read EEPROM
7604 *
7605 * Description: Read a word from the EEPROM at the desired
7606 * address.
7607 *
7608 *---------------------------------------------------------------------*/
7609
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007610static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007611{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007612 unsigned short i, ee_data1, ee_data2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007613
7614 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007615 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007616 do
7617 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007618 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007619
7620 if(ee_data1 == ee_data2)
7621 return(ee_data1);
7622
7623 ee_data1 = ee_data2;
7624 i++;
7625
7626 }while(i < 4);
7627
7628 return(ee_data1);
7629}
7630
7631/*---------------------------------------------------------------------
7632 *
7633 * Function: Read EEPROM Original
7634 *
7635 * Description: Read a word from the EEPROM at the desired
7636 * address.
7637 *
7638 *---------------------------------------------------------------------*/
7639
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007640static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007641{
7642
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007643 unsigned char ee_value;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007644 unsigned short i, ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007645
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007646 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 -07007647 (SEE_MS | SEE_CS));
7648
7649
James Bottomley 47b5d692005-04-24 02:38:05 -05007650 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007651
7652
7653 ee_value |= (SEE_MS + SEE_CS);
7654 ee_data = 0;
7655
7656 for(i = 1; i <= 16; i++) {
7657
7658 ee_value |= SEE_CLK; /* Clock data! */
7659 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7661 ee_value &= ~SEE_CLK;
7662 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7663 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7664
7665 ee_data <<= 1;
7666
7667 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7668 ee_data |= 1;
7669 }
7670
7671 ee_value &= ~(SEE_MS + SEE_CS);
7672 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7674
7675 return(ee_data);
7676}
7677
7678
7679/*---------------------------------------------------------------------
7680 *
7681 * Function: Send EE command and Address to the EEPROM
7682 *
7683 * Description: Transfers the correct command and sends the address
7684 * to the eeprom.
7685 *
7686 *---------------------------------------------------------------------*/
7687
Alexey Dobriyand63a4cc2006-03-08 00:14:26 -08007688static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007689{
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007690 unsigned char ee_value;
7691 unsigned char narrow_flg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007692
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007693 unsigned short i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007694
7695
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007696 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007697
7698
7699 ee_value = SEE_MS;
7700 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7701
7702 ee_value |= SEE_CS; /* Set CS to EEPROM */
7703 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7704
7705
7706 for(i = 0x04; i != 0; i>>=1) {
7707
7708 if (i & ee_cmd)
7709 ee_value |= SEE_DO;
7710 else
7711 ee_value &= ~SEE_DO;
7712
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; /* Clock data! */
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 ee_value &= ~SEE_CLK;
7719 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7720 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7721 }
7722
7723
7724 if (narrow_flg)
7725 i = 0x0080;
7726
7727 else
7728 i = 0x0200;
7729
7730
7731 while (i != 0) {
7732
7733 if (i & ee_addr)
7734 ee_value |= SEE_DO;
7735 else
7736 ee_value &= ~SEE_DO;
7737
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; /* Clock data! */
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 ee_value &= ~SEE_CLK;
7744 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7745 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7746
7747 i >>= 1;
7748 }
7749}
7750
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007751static unsigned short FPT_CalcCrc16(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007752{
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007753 unsigned short crc=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007754 int i,j;
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007755 unsigned short ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007756 for (i=0; i < ID_STRING_LENGTH; i++)
7757 {
Alexey Dobriyanc823fee2006-03-08 00:14:25 -08007758 ch = (unsigned short) buffer[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007759 for(j=0; j < 8; j++)
7760 {
7761 if ((crc ^ ch) & 1)
7762 crc = (crc >> 1) ^ CRCMASK;
7763 else
7764 crc >>= 1;
7765 ch >>= 1;
7766 }
7767 }
7768 return(crc);
7769}
7770
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007771static unsigned char FPT_CalcLrc(unsigned char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007772{
7773 int i;
Alexey Dobriyandb038cf2006-03-08 00:14:24 -08007774 unsigned char lrc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007775 lrc = 0;
7776 for(i = 0; i < ID_STRING_LENGTH; i++)
7777 lrc ^= buffer[i];
7778 return(lrc);
7779}
7780
7781
7782
7783/*
7784 The following inline definitions avoid type conflicts.
7785*/
7786
7787static inline unsigned char
7788FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7789{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007790 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007791}
7792
7793
7794static inline FlashPoint_CardHandle_T
7795FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7796{
Alexey Dobriyan7f101662006-03-08 00:14:30 -08007797 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007798}
7799
7800static inline void
7801FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7802{
7803 FlashPoint_ReleaseHostAdapter(CardHandle);
7804}
7805
7806
7807static inline void
7808FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7809{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007810 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007811}
7812
7813
7814static inline void
7815FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7816{
Alexey Dobriyan69eb2ea2006-03-08 00:14:29 -08007817 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007818}
7819
7820
7821static inline boolean
7822FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7823{
7824 return FlashPoint_InterruptPending(CardHandle);
7825}
7826
7827
7828static inline int
7829FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7830{
7831 return FlashPoint_HandleInterrupt(CardHandle);
7832}
7833
7834
7835#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7836#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7837#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7838#define FlashPoint_StartCCB FlashPoint__StartCCB
7839#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7840#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7841#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7842
7843
Linus Torvalds1da177e2005-04-16 15:20:36 -07007844#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7845
7846
7847/*
7848 Define prototypes for the FlashPoint SCCB Manager Functions.
7849*/
7850
7851extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7852extern FlashPoint_CardHandle_T
7853 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7854extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7855extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7856extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7857extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7858extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007859
7860
7861#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */