blob: 38e6b71484b740bc4e9f657d943b88cd9b581bb8 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#include <linux/config.h>
20
21
22#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
23
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#define MAX_CARDS 8
26#undef BUSTYPE_PCI
27
28
29#define OS_InPortByte(port) inb(port)
30#define OS_InPortWord(port) inw(port)
31#define OS_InPortLong(port) inl(port)
32#define OS_OutPortByte(port, value) outb(value, port)
33#define OS_OutPortWord(port, value) outw(value, port)
34#define OS_OutPortLong(port, value) outl(value, port)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
36
37/*
38 Define name replacements for compatibility with the Linux BusLogic Driver.
39*/
40
41#define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter
42#define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter
43#define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter
44#define SccbMgr_start_sccb FlashPoint_StartCCB
45#define SccbMgr_abort_sccb FlashPoint_AbortCCB
46#define SccbMgr_my_int FlashPoint_InterruptPending
47#define SccbMgr_isr FlashPoint_HandleInterrupt
48
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
52#define CRCMASK 0xA001
53
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056#define FAILURE 0xFFFFFFFFL
57
58
59typedef unsigned char UCHAR;
60typedef unsigned short USHORT;
61typedef unsigned int UINT;
62typedef unsigned long ULONG;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
64
Linus Torvalds1da177e2005-04-16 15:20:36 -070065typedef unsigned short * ushort_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67
Linus Torvalds1da177e2005-04-16 15:20:36 -070068#define s08bits char
69#define s16bits short
70#define s32bits long
71
72#define u08bits unsigned s08bits
73#define u16bits unsigned s16bits
74#define u32bits unsigned s32bits
75
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78#define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
79#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
80
81
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
James Bottomley 47b5d692005-04-24 02:38:05 -050084typedef struct _SCCB *PSCCB;
85typedef void (*CALL_BK_FN)(PSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87
88typedef struct SCCBMgr_info {
89 ULONG si_baseaddr;
90 UCHAR si_present;
91 UCHAR si_intvect;
92 UCHAR si_id;
93 UCHAR si_lun;
94 USHORT si_fw_revision;
95 USHORT si_per_targ_init_sync;
96 USHORT si_per_targ_fast_nego;
97 USHORT si_per_targ_ultra_nego;
98 USHORT si_per_targ_no_disc;
99 USHORT si_per_targ_wide_nego;
100 USHORT si_flags;
101 UCHAR si_card_family;
102 UCHAR si_bustype;
103 UCHAR si_card_model[3];
104 UCHAR si_relative_cardnum;
105 UCHAR si_reserved[4];
106 ULONG si_OS_reserved;
107 UCHAR si_XlatInfo[4];
108 ULONG si_reserved2[5];
109 ULONG si_secondary_range;
110} SCCBMGR_INFO;
111
James Bottomley 47b5d692005-04-24 02:38:05 -0500112typedef SCCBMGR_INFO * PSCCBMGR_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114
James Bottomley 47b5d692005-04-24 02:38:05 -0500115#define SCSI_PARITY_ENA 0x0001
116#define LOW_BYTE_TERM 0x0010
117#define HIGH_BYTE_TERM 0x0020
118#define BUSTYPE_PCI 0x3
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
120#define SUPPORT_16TAR_32LUN 0x0002
121#define SOFT_RESET 0x0004
122#define EXTENDED_TRANSLATION 0x0008
123#define POST_ALL_UNDERRRUNS 0x0040
124#define FLAG_SCAM_ENABLED 0x0080
125#define FLAG_SCAM_LEVEL2 0x0100
126
127
128
129
130#define HARPOON_FAMILY 0x02
131
132
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Alexey Dobriyan323579882006-01-15 02:12:54 +0100134/* SCCB struct used for both SCCB and UCB manager compiles!
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 * The UCB Manager treats the SCCB as it's 'native hardware structure'
136 */
137
138
139#pragma pack(1)
140typedef struct _SCCB {
141 UCHAR OperationCode;
142 UCHAR ControlByte;
143 UCHAR CdbLength;
144 UCHAR RequestSenseLength;
145 ULONG DataLength;
146 ULONG DataPointer;
147 UCHAR CcbRes[2];
148 UCHAR HostStatus;
149 UCHAR TargetStatus;
150 UCHAR TargID;
151 UCHAR Lun;
152 UCHAR Cdb[12];
153 UCHAR CcbRes1;
154 UCHAR Reserved1;
155 ULONG Reserved2;
156 ULONG SensePointer;
157
158
159 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
160 ULONG SccbIOPort; /* Identifies board base port */
161 UCHAR SccbStatus;
162 UCHAR SCCBRes2;
163 USHORT SccbOSFlags;
164
165
166 ULONG Sccb_XferCnt; /* actual transfer count */
167 ULONG Sccb_ATC;
168 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
169 ULONG Sccb_res1;
170 USHORT Sccb_MGRFlags;
171 USHORT Sccb_sgseg;
172 UCHAR Sccb_scsimsg; /* identify msg for selection */
173 UCHAR Sccb_tag;
174 UCHAR Sccb_scsistat;
175 UCHAR Sccb_idmsg; /* image of last msg in */
176 PSCCB Sccb_forwardlink;
177 PSCCB Sccb_backlink;
178 ULONG Sccb_savedATC;
179 UCHAR Save_Cdb[6];
180 UCHAR Save_CdbLen;
181 UCHAR Sccb_XferState;
182 ULONG Sccb_SGoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 } SCCB;
184
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
186#pragma pack()
187
188
189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190#define SCATTER_GATHER_COMMAND 0x02
191#define RESIDUAL_COMMAND 0x03
192#define RESIDUAL_SG_COMMAND 0x04
193#define RESET_COMMAND 0x81
194
195
196#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
197#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198#define SCCB_DATA_XFER_OUT 0x10 /* Write */
199#define SCCB_DATA_XFER_IN 0x08 /* Read */
200
201
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
203
204
205#define BUS_FREE_ST 0
206#define SELECT_ST 1
207#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
208#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
209#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
210#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
211#define COMMAND_ST 6
212#define DATA_OUT_ST 7
213#define DATA_IN_ST 8
214#define DISCONNECT_ST 9
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215#define ABORT_ST 11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217
218#define F_HOST_XFER_DIR 0x01
219#define F_ALL_XFERRED 0x02
220#define F_SG_XFER 0x04
221#define F_AUTO_SENSE 0x08
222#define F_ODD_BALL_CNT 0x10
223#define F_NO_DATA_YET 0x80
224
225
226#define F_STATUSLOADED 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227#define F_DEV_SELECTED 0x04
228
229
230#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
231#define SCCB_DATA_UNDER_RUN 0x0C
232#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
233#define SCCB_DATA_OVER_RUN 0x12
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
235
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
237#define SCCB_BM_ERR 0x30 /* BusMaster error. */
238#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
239
240
241
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
243
244#define SCCB_IN_PROCESS 0x00
245#define SCCB_SUCCESS 0x01
246#define SCCB_ABORT 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247#define SCCB_ERROR 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
250
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251#define ORION_FW_REV 3110
252
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253
254
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
257#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
258
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259
James Bottomley 47b5d692005-04-24 02:38:05 -0500260#define MAX_SCSI_TAR 16
261#define MAX_LUN 32
262#define LUN_MASK 0x1f
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264#define SG_BUF_CNT 16 /*Number of prefetched elements. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265
266#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
268
James Bottomley 47b5d692005-04-24 02:38:05 -0500269#define RD_HARPOON(ioport) OS_InPortByte((u32bits)ioport)
270#define RDW_HARPOON(ioport) OS_InPortWord((u32bits)ioport)
271#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
272#define WR_HARPOON(ioport,val) OS_OutPortByte((u32bits)ioport,(u08bits) val)
273#define WRW_HARPOON(ioport,val) OS_OutPortWord((u32bits)ioport,(u16bits)val)
274#define WR_HARP32(ioport,offset,data) OS_OutPortLong((u32bits)(ioport + offset), data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
276
277#define TAR_SYNC_MASK (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278#define SYNC_TRYING BIT(6)
279#define SYNC_SUPPORTED (BIT(7)+BIT(6))
280
281#define TAR_WIDE_MASK (BIT(5)+BIT(4))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282#define WIDE_ENABLED BIT(4)
283#define WIDE_NEGOCIATED BIT(5)
284
285#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286#define TAG_Q_TRYING BIT(2)
287#define TAG_Q_REJECT BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288
289#define TAR_ALLOW_DISC BIT(0)
290
291
292#define EE_SYNC_MASK (BIT(0)+BIT(1))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293#define EE_SYNC_5MB BIT(0)
294#define EE_SYNC_10MB BIT(1)
295#define EE_SYNC_20MB (BIT(0)+BIT(1))
296
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297#define EE_WIDE_SCSI BIT(7)
298
299
James Bottomley 47b5d692005-04-24 02:38:05 -0500300typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302
303typedef struct SCCBMgr_tar_info {
304
305 PSCCB TarSelQ_Head;
306 PSCCB TarSelQ_Tail;
307 UCHAR TarLUN_CA; /*Contingent Allgiance */
308 UCHAR TarTagQ_Cnt;
309 UCHAR TarSelQ_Cnt;
310 UCHAR TarStatus;
311 UCHAR TarEEValue;
312 UCHAR TarSyncCtrl;
313 UCHAR TarReserved[2]; /* for alignment */
314 UCHAR LunDiscQ_Idx[MAX_LUN];
315 UCHAR TarLUNBusy[MAX_LUN];
316} SCCBMGR_TAR_INFO;
317
318typedef struct NVRAMInfo {
319 UCHAR niModel; /* Model No. of card */
320 UCHAR niCardNo; /* Card no. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 ULONG niBaseAddr; /* Port Address of card */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
323 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
324 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
325 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
326 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
327 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
328}NVRAMINFO;
329
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330typedef NVRAMINFO *PNVRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331
332#define MODEL_LT 1
333#define MODEL_DL 2
334#define MODEL_LW 3
335#define MODEL_DW 4
336
337
338typedef struct SCCBcard {
339 PSCCB currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 PSCCBMGR_INFO cardInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 ULONG ioPort;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
344 USHORT cmdCounter;
345 UCHAR discQCount;
346 UCHAR tagQ_Lst;
347 UCHAR cardIndex;
348 UCHAR scanIndex;
349 UCHAR globalFlags;
350 UCHAR ourId;
351 PNVRamInfo pNvRamInfo;
352 PSCCB discQ_Tbl[QUEUE_DEPTH];
353
354}SCCBCARD;
355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356typedef struct SCCBcard *PSCCBcard;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
358
359#define F_TAG_STARTED 0x01
360#define F_CONLUN_IO 0x02
361#define F_DO_RENEGO 0x04
362#define F_NO_FILTER 0x08
363#define F_GREEN_PC 0x10
364#define F_HOST_XFER_ACT 0x20
365#define F_NEW_SCCB_CMD 0x40
366#define F_UPDATE_EEPROM 0x80
367
368
369#define ID_STRING_LENGTH 32
370#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
371
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
373#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
374
375#define ASSIGN_ID 0x00
376#define SET_P_FLAG 0x01
377#define CFG_CMPLT 0x03
378#define DOM_MSTR 0x0F
379#define SYNC_PTRN 0x1F
380
381#define ID_0_7 0x18
382#define ID_8_F 0x11
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383#define MISC_CODE 0x14
384#define CLR_P_FLAG 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
387
388#define INIT_SELTD 0x01
389#define LEVEL2_TAR 0x02
390
391
392enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
393 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
394 CLR_PRIORITY,NO_ID_AVAIL };
395
396typedef struct SCCBscam_info {
397
398 UCHAR id_string[ID_STRING_LENGTH];
399 enum scam_id_st state;
400
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800401} SCCBSCAM_INFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404#define SCSI_REQUEST_SENSE 0x03
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405#define SCSI_READ 0x08
406#define SCSI_WRITE 0x0A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407#define SCSI_START_STOP_UNIT 0x1B
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408#define SCSI_READ_EXTENDED 0x28
409#define SCSI_WRITE_EXTENDED 0x2A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410#define SCSI_WRITE_AND_VERIFY 0x2E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
412
413
414#define SSGOOD 0x00
415#define SSCHECK 0x02
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416#define SSQ_FULL 0x28
417
418
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420
421#define SMCMD_COMP 0x00
422#define SMEXT 0x01
423#define SMSAVE_DATA_PTR 0x02
424#define SMREST_DATA_PTR 0x03
425#define SMDISC 0x04
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426#define SMABORT 0x06
427#define SMREJECT 0x07
428#define SMNO_OP 0x08
429#define SMPARITY 0x09
430#define SMDEV_RESET 0x0C
431#define SMABORT_TAG 0x0D
432#define SMINIT_RECOVERY 0x0F
433#define SMREL_RECOVERY 0x10
434
435#define SMIDENT 0x80
436#define DISC_PRIV 0x40
437
438
439#define SMSYNC 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440#define SMWDTR 0x03
441#define SM8BIT 0x00
442#define SM16BIT 0x01
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443#define SMIGNORWR 0x23 /* Ignore Wide Residue */
444
445
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
447
448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449
450
451
452#define SIX_BYTE_CMD 0x06
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453#define TWELVE_BYTE_CMD 0x0C
454
455#define ASYNC 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
457
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459#define EEPROM_WD_CNT 256
460
461#define EEPROM_CHECK_SUM 0
462#define FW_SIGNATURE 2
463#define MODEL_NUMB_0 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464#define MODEL_NUMB_2 6
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465#define MODEL_NUMB_4 8
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466#define SYSTEM_CONFIG 16
467#define SCSI_CONFIG 17
468#define BIOS_CONFIG 18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469#define SCAM_CONFIG 20
470#define ADAPTER_SCSI_ID 24
471
472
473#define IGNORE_B_SCAN 32
474#define SEND_START_ENA 34
475#define DEVICE_ENABLE 36
476
477#define SYNC_RATE_TBL 38
478#define SYNC_RATE_TBL01 38
479#define SYNC_RATE_TBL23 40
480#define SYNC_RATE_TBL45 42
481#define SYNC_RATE_TBL67 44
482#define SYNC_RATE_TBL89 46
483#define SYNC_RATE_TBLab 48
484#define SYNC_RATE_TBLcd 50
485#define SYNC_RATE_TBLef 52
486
487
488
489#define EE_SCAMBASE 256
490
491
492
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 #define SCAM_ENABLED BIT(2)
494 #define SCAM_LEVEL2 BIT(3)
495
496
497 #define RENEGO_ENA BITW(10)
498 #define CONNIO_ENA BITW(11)
499 #define GREEN_PC_ENA BITW(12)
500
501
502 #define AUTO_RATE_00 00
503 #define AUTO_RATE_05 01
504 #define AUTO_RATE_10 02
505 #define AUTO_RATE_20 03
506
507 #define WIDE_NEGO_BIT BIT(7)
508 #define DISC_ENABLE_BIT BIT(6)
509
510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
512 #define hp_vendor_id_0 0x00 /* LSB */
513 #define ORION_VEND_0 0x4B
514
515 #define hp_vendor_id_1 0x01 /* MSB */
516 #define ORION_VEND_1 0x10
517
518 #define hp_device_id_0 0x02 /* LSB */
519 #define ORION_DEV_0 0x30
520
521 #define hp_device_id_1 0x03 /* MSB */
522 #define ORION_DEV_1 0x81
523
524 /* Sub Vendor ID and Sub Device ID only available in
525 Harpoon Version 2 and higher */
526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 #define hp_sub_device_id_0 0x06 /* LSB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528
529
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
531 #define hp_semaphore 0x0C
532 #define SCCB_MGR_ACTIVE BIT(0)
533 #define TICKLE_ME BIT(1)
534 #define SCCB_MGR_PRESENT BIT(3)
535 #define BIOS_IN_USE BIT(4)
536
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538
539 #define hp_sys_ctrl 0x0F
540
541 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
542 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
543 #define HALT_MACH BIT(3) /*Halt State Machine */
544 #define HARD_ABORT BIT(4) /*Hard Abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
546
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800550
551
552
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553
554 #define hp_host_blk_cnt 0x13
555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
557
558 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
559
560
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561
562 #define hp_int_mask 0x17
563
564 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
565 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
567
568 #define hp_xfer_cnt_lo 0x18
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 #define hp_xfer_cnt_hi 0x1A
570 #define hp_xfer_cmd 0x1B
571
572 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
573 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
575
576 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
578 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
580 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
581
582 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
583 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584
585 #define hp_host_addr_lo 0x1C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 #define hp_host_addr_hmi 0x1E
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 #define hp_ee_ctrl 0x22
589
590 #define EXT_ARB_ACK BIT(7)
591 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
592 #define SEE_MS BIT(5)
593 #define SEE_CS BIT(3)
594 #define SEE_CLK BIT(2)
595 #define SEE_DO BIT(1)
596 #define SEE_DI BIT(0)
597
598 #define EE_READ 0x06
599 #define EE_WRITE 0x05
600 #define EWEN 0x04
601 #define EWEN_ADDR 0x03C0
602 #define EWDS 0x04
603 #define EWDS_ADDR 0x0000
604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
608
609
610
611 #define hp_bm_ctrl 0x26
612
613 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
614 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
616 #define FAST_SINGLE BIT(6) /*?? */
617
618 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
621 #define hp_sg_addr 0x28
622 #define hp_page_ctrl 0x29
623
624 #define SCATTER_EN BIT(0)
625 #define SGRAM_ARAM BIT(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
627 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
628
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
632 #define hp_pci_stat_cfg 0x2D
633
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
643 #define hp_rev_num 0x33
644
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645
646 #define hp_stack_data 0x34
647 #define hp_stack_addr 0x35
648
649 #define hp_ext_status 0x36
650
651 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
652 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
653 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 #define CMD_ABORTED BIT(4) /*Command aborted */
655 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
656 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
657 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
658 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
659 BM_PARITY_ERR | PIO_OVERRUN)
660
661 #define hp_int_status 0x37
662
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
664 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 #define INT_ASSERTED BIT(5) /* */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666
667
668 #define hp_fifo_cnt 0x38
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
671
672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 #define hp_intena 0x40
674
675 #define RESET BITW(7)
676 #define PROG_HLT BITW(6)
677 #define PARITY BITW(5)
678 #define FIFO BITW(4)
679 #define SEL BITW(3)
680 #define SCAM_SEL BITW(2)
681 #define RSEL BITW(1)
682 #define TIMEOUT BITW(0)
683 #define BUS_FREE BITW(15)
684 #define XFER_CNT_0 BITW(14)
685 #define PHASE BITW(13)
686 #define IUNKWN BITW(12)
687 #define ICMD_COMP BITW(11)
688 #define ITICKLE BITW(10)
689 #define IDO_STRT BITW(9)
690 #define ITAR_DISC BITW(8)
691 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
692 #define CLR_ALL_INT 0xFFFF
693 #define CLR_ALL_INT_1 0xFF00
694
695 #define hp_intstat 0x42
696
697 #define hp_scsisig 0x44
698
699 #define SCSI_SEL BIT(7)
700 #define SCSI_BSY BIT(6)
701 #define SCSI_REQ BIT(5)
702 #define SCSI_ACK BIT(4)
703 #define SCSI_ATN BIT(3)
704 #define SCSI_CD BIT(2)
705 #define SCSI_MSG BIT(1)
706 #define SCSI_IOBIT BIT(0)
707
708 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 #define S_MSGO_PH (BIT(2)+BIT(1) )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
711 #define S_DATAI_PH ( BIT(0))
712 #define S_DATAO_PH 0x00
713 #define S_ILL_PH ( BIT(1) )
714
715 #define hp_scsictrl_0 0x45
716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 #define SEL_TAR BIT(6)
718 #define ENA_ATN BIT(4)
719 #define ENA_RESEL BIT(2)
720 #define SCSI_RST BIT(1)
721 #define ENA_SCAM_SEL BIT(0)
722
723
724
725 #define hp_portctrl_0 0x46
726
727 #define SCSI_PORT BIT(7)
728 #define SCSI_INBIT BIT(6)
729 #define DMA_PORT BIT(5)
730 #define DMA_RD BIT(4)
731 #define HOST_PORT BIT(3)
732 #define HOST_WRT BIT(2)
733 #define SCSI_BUS_EN BIT(1)
734 #define START_TO BIT(0)
735
736 #define hp_scsireset 0x47
737
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 #define SCSI_INI BIT(6)
739 #define SCAM_EN BIT(5)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 #define DMA_RESET BIT(3)
741 #define HPSCSI_RESET BIT(2)
742 #define PROG_RESET BIT(1)
743 #define FIFO_CLR BIT(0)
744
745 #define hp_xfercnt_0 0x48
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 #define hp_xfercnt_2 0x4A
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747
748 #define hp_fifodata_0 0x4C
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 #define hp_addstat 0x4E
750
751 #define SCAM_TIMER BIT(7)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 #define SCSI_MODE8 BIT(3)
753 #define SCSI_PAR_ERR BIT(0)
754
755 #define hp_prgmcnt_0 0x4F
756
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757
758 #define hp_selfid_0 0x50
759 #define hp_selfid_1 0x51
760 #define hp_arb_id 0x52
761
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
763 #define hp_select_id 0x53
764
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765
766 #define hp_synctarg_base 0x54
767 #define hp_synctarg_12 0x54
768 #define hp_synctarg_13 0x55
769 #define hp_synctarg_14 0x56
770 #define hp_synctarg_15 0x57
771
772 #define hp_synctarg_8 0x58
773 #define hp_synctarg_9 0x59
774 #define hp_synctarg_10 0x5A
775 #define hp_synctarg_11 0x5B
776
777 #define hp_synctarg_4 0x5C
778 #define hp_synctarg_5 0x5D
779 #define hp_synctarg_6 0x5E
780 #define hp_synctarg_7 0x5F
781
782 #define hp_synctarg_0 0x60
783 #define hp_synctarg_1 0x61
784 #define hp_synctarg_2 0x62
785 #define hp_synctarg_3 0x63
786
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 #define NARROW_SCSI BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 #define DEFAULT_OFFSET 0x0F
789
790 #define hp_autostart_0 0x64
791 #define hp_autostart_1 0x65
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 #define hp_autostart_3 0x67
793
794
795
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 #define AUTO_IMMED BIT(5)
797 #define SELECT BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 #define END_DATA (BIT(7)+BIT(6))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799
800 #define hp_gp_reg_0 0x68
801 #define hp_gp_reg_1 0x69
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 #define hp_gp_reg_3 0x6B
803
804 #define hp_seltimeout 0x6C
805
806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 #define TO_4ms 0x67 /* 3.9959ms */
808
809 #define TO_5ms 0x03 /* 4.9152ms */
810 #define TO_10ms 0x07 /* 11.xxxms */
811 #define TO_250ms 0x99 /* 250.68ms */
812 #define TO_290ms 0xB1 /* 289.99ms */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 #define hp_clkctrl_0 0x6D
815
816 #define PWR_DWN BIT(6)
817 #define ACTdeassert BIT(4)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 #define CLK_40MHZ (BIT(1) + BIT(0))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
820 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
821
822 #define hp_fiforead 0x6E
823 #define hp_fifowrite 0x6F
824
825 #define hp_offsetctr 0x70
826 #define hp_xferstat 0x71
827
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 #define FIFO_EMPTY BIT(6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
830 #define hp_portctrl_1 0x72
831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 #define CHK_SCSI_P BIT(3)
833 #define HOST_MODE8 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834
835 #define hp_xfer_pad 0x73
836
837 #define ID_UNLOCK BIT(3)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
839 #define hp_scsidata_0 0x74
840 #define hp_scsidata_1 0x75
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843
844 #define hp_aramBase 0x80
845 #define BIOS_DATA_OFFSET 0x60
846 #define BIOS_RELATIVE_CARD 0x64
847
848
849
850
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 #define AR3 (BITW(9) + BITW(8))
852 #define SDATA BITW(10)
853
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
855 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
856
857 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
858
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860
861 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
862
863 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
864
865
866 #define ADATA_OUT 0x00
867 #define ADATA_IN BITW(8)
868 #define ACOMMAND BITW(10)
869 #define ASTATUS (BITW(10)+BITW(8))
870 #define AMSG_OUT (BITW(10)+BITW(9))
871 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
873
874 #define BRH_OP BITW(13) /* Branch */
875
876
877 #define ALWAYS 0x00
878 #define EQUAL BITW(8)
879 #define NOT_EQ BITW(9)
880
881 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
882
883
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 #define FIFO_0 BITW(10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885
886
887 #define MPM_OP BITW(15) /* Match phase and move data */
888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
890 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
891
892
893 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
894
895
896 #define D_AR0 0x00
897 #define D_AR1 BIT(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
899
900
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906
907
908 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
909
910 #define SSI_OP (BITW(15)+BITW(11))
911
912
913 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
914 #define SSI_IDO_STRT (IDO_STRT >> 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915
916 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
917 #define SSI_ITICKLE (ITICKLE >> 8)
918
919 #define SSI_IUNKWN (IUNKWN >> 8)
920 #define SSI_INO_CC (IUNKWN >> 8)
921 #define SSI_IRFAIL (IUNKWN >> 8)
922
923
924 #define NP 0x10 /*Next Phase */
925 #define NTCMD 0x02 /*Non- Tagged Command start */
926 #define CMDPZ 0x04 /*Command phase */
927 #define DINT 0x12 /*Data Out/In interrupt */
928 #define DI 0x13 /*Data Out */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 #define DC 0x19 /*Disconnect Message */
930 #define ST 0x1D /*Status Phase */
931 #define UNKNWN 0x24 /*Unknown bus action */
932 #define CC 0x25 /*Command Completion failure */
933 #define TICK 0x26 /*New target reselected us. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
935
936
937 #define ID_MSG_STRT hp_aramBase + 0x00
938 #define NON_TAG_ID_MSG hp_aramBase + 0x06
939 #define CMD_STRT hp_aramBase + 0x08
940 #define SYNC_MSGS hp_aramBase + 0x08
941
942
943
944
945
946 #define TAG_STRT 0x00
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 #define DISCONNECT_START 0x10/2
948 #define END_DATA_START 0x14/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 #define CMD_ONLY_STRT CMDPZ/2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 #define SELCHK_STRT SELCHK/2
951
952
953
954
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
956
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957
Alexey Dobriyan85ae97d82006-03-08 00:14:22 -0800958
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
961/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
962 xfercnt <<= 16,\
963 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
964 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
966 addr >>= 16,\
967 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
968 WR_HARP32(port,hp_xfercnt_0,count),\
969 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
970 count >>= 16,\
971 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
973#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
974 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
975
976
977#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
978 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
979
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981
982#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
983 WR_HARPOON(port+hp_scsireset, 0x00))
984
985#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
986 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
987
988#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
989 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
990
991#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
992 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
993
994#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
995 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
996
997
998
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999
James Bottomley 47b5d692005-04-24 02:38:05 -05001000static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
1001static void FPT_ssel(ULONG port, UCHAR p_card);
1002static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
1003static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
1004static void FPT_stsyncn(ULONG port, UCHAR p_card);
1005static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
1006static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
1007 PSCCBMgr_tar_info currTar_Info);
1008static void FPT_sresb(ULONG port, UCHAR p_card);
1009static void FPT_sxfrp(ULONG p_port, UCHAR p_card);
1010static void FPT_schkdd(ULONG port, UCHAR p_card);
1011static UCHAR FPT_RdStack(ULONG port, UCHAR index);
1012static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
1013static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014
James Bottomley 47b5d692005-04-24 02:38:05 -05001015static void FPT_SendMsg(ULONG port, UCHAR message);
1016static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1017 UCHAR error_code);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
James Bottomley 47b5d692005-04-24 02:38:05 -05001019static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1020static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
James Bottomley 47b5d692005-04-24 02:38:05 -05001022static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1023static void FPT_stwidn(ULONG port, UCHAR p_card);
1024static void FPT_siwidr(ULONG port, UCHAR width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025
1026
James Bottomley 47b5d692005-04-24 02:38:05 -05001027static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1028static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1029static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1030 UCHAR p_card);
1031static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1032static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1033static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1034static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1035static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1036static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1037static UCHAR FPT_CalcLrc(UCHAR buffer[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
1039
James Bottomley 47b5d692005-04-24 02:38:05 -05001040static void FPT_Wait1Second(ULONG p_port);
1041static void FPT_Wait(ULONG p_port, UCHAR p_delay);
1042static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1043static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1044static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1045static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1046static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
1048
1049
James Bottomley 47b5d692005-04-24 02:38:05 -05001050static void FPT_phaseDataOut(ULONG port, UCHAR p_card);
1051static void FPT_phaseDataIn(ULONG port, UCHAR p_card);
1052static void FPT_phaseCommand(ULONG port, UCHAR p_card);
1053static void FPT_phaseStatus(ULONG port, UCHAR p_card);
1054static void FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1055static void FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1056static void FPT_phaseIllegal(ULONG port, UCHAR p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
James Bottomley 47b5d692005-04-24 02:38:05 -05001058static void FPT_phaseDecode(ULONG port, UCHAR p_card);
1059static void FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1060static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
1062
1063
1064
James Bottomley 47b5d692005-04-24 02:38:05 -05001065static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1066static void FPT_BusMasterInit(ULONG p_port);
1067static void FPT_DiagEEPROM(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
1069
1070
1071
James Bottomley 47b5d692005-04-24 02:38:05 -05001072static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1073static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1074static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1075static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1076static void FPT_hostDataXferRestart(PSCCB currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078
James Bottomley 47b5d692005-04-24 02:38:05 -05001079static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1080 PSCCBcard pCurrCard, USHORT p_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
James Bottomley 47b5d692005-04-24 02:38:05 -05001082static void FPT_SccbMgrTableInitAll(void);
1083static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1084static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
1086
1087
James Bottomley 47b5d692005-04-24 02:38:05 -05001088static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
James Bottomley 47b5d692005-04-24 02:38:05 -05001090static int FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1091static void FPT_scbusf(ULONG p_port);
1092static void FPT_scsel(ULONG p_port);
1093static void FPT_scasid(UCHAR p_card, ULONG p_port);
1094static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1095static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1096static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1097static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1098static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1099static UCHAR FPT_scvalq(UCHAR p_quintet);
1100static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1101static void FPT_scwtsel(ULONG p_port);
1102static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1103static void FPT_scsavdi(UCHAR p_card, ULONG p_port);
1104static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
1106
James Bottomley 47b5d692005-04-24 02:38:05 -05001107static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1108static void FPT_autoLoadDefaultMap(ULONG p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
1110
1111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
James Bottomley 47b5d692005-04-24 02:38:05 -05001113static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1114static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1115static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1116static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118
James Bottomley 47b5d692005-04-24 02:38:05 -05001119static UCHAR FPT_mbCards = 0;
1120static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1121 ' ', 'B', 'T', '-', '9', '3', '0', \
1122 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1123 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124
James Bottomley 47b5d692005-04-24 02:38:05 -05001125static USHORT FPT_default_intena = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
1127
James Bottomley 47b5d692005-04-24 02:38:05 -05001128static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
1131/*---------------------------------------------------------------------
1132 *
1133 * Function: SccbMgr_sense_adapter
1134 *
1135 * Description: Setup and/or Search for cards and return info to caller.
1136 *
1137 *---------------------------------------------------------------------*/
1138
James Bottomley 47b5d692005-04-24 02:38:05 -05001139static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 static UCHAR first_time = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142
1143 UCHAR i,j,id,ScamFlg;
1144 USHORT temp,temp2,temp3,temp4,temp5,temp6;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 PNVRamInfo pCurrNvRam;
1147
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149
1150
1151 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1152 return((int)FAILURE);
1153
1154 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1155 return((int)FAILURE);
1156
1157 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1158 return((int)FAILURE);
1159
1160 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1161 return((int)FAILURE);
1162
1163
1164 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1165
1166/* For new Harpoon then check for sub_device ID LSB
1167 the bits(0-3) must be all ZERO for compatible with
1168 current version of SCCBMgr, else skip this Harpoon
1169 device. */
1170
1171 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1172 return((int)FAILURE);
1173 }
1174
1175 if (first_time)
1176 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001177 FPT_SccbMgrTableInitAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 first_time = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05001179 FPT_mbCards = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 }
1181
James Bottomley 47b5d692005-04-24 02:38:05 -05001182 if(FPT_RdStack(ioport, 0) != 0x00) {
1183 if(FPT_ChkIfChipInitialized(ioport) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 {
1185 pCurrNvRam = NULL;
1186 WR_HARPOON(ioport+hp_semaphore, 0x00);
James Bottomley 47b5d692005-04-24 02:38:05 -05001187 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1188 FPT_DiagEEPROM(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 }
1190 else
1191 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001192 if(FPT_mbCards < MAX_MB_CARDS) {
1193 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1194 FPT_mbCards++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 pCurrNvRam->niBaseAddr = ioport;
James Bottomley 47b5d692005-04-24 02:38:05 -05001196 FPT_RNVRamData(pCurrNvRam);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 }else
1198 return((int) FAILURE);
1199 }
1200 }else
1201 pCurrNvRam = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1204 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1205
1206 if(pCurrNvRam)
1207 pCardInfo->si_id = pCurrNvRam->niAdapId;
1208 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001209 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 (UCHAR)0x0FF);
1211
1212 pCardInfo->si_lun = 0x00;
1213 pCardInfo->si_fw_revision = ORION_FW_REV;
1214 temp2 = 0x0000;
1215 temp3 = 0x0000;
1216 temp4 = 0x0000;
1217 temp5 = 0x0000;
1218 temp6 = 0x0000;
1219
1220 for (id = 0; id < (16/2); id++) {
1221
1222 if(pCurrNvRam){
1223 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1224 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1225 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1226 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001227 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
1229 for (i = 0; i < 2; temp >>=8,i++) {
1230
1231 temp2 >>= 1;
1232 temp3 >>= 1;
1233 temp4 >>= 1;
1234 temp5 >>= 1;
1235 temp6 >>= 1;
1236 switch (temp & 0x3)
1237 {
1238 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1239 temp6 |= 0x8000; /* Fall through */
1240 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1241 temp5 |= 0x8000; /* Fall through */
1242 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1243 temp2 |= 0x8000; /* Fall through */
1244 case AUTO_RATE_00: /* Asynchronous */
1245 break;
1246 }
1247
1248 if (temp & DISC_ENABLE_BIT)
1249 temp3 |= 0x8000;
1250
1251 if (temp & WIDE_NEGO_BIT)
1252 temp4 |= 0x8000;
1253
1254 }
1255 }
1256
1257 pCardInfo->si_per_targ_init_sync = temp2;
1258 pCardInfo->si_per_targ_no_disc = temp3;
1259 pCardInfo->si_per_targ_wide_nego = temp4;
1260 pCardInfo->si_per_targ_fast_nego = temp5;
1261 pCardInfo->si_per_targ_ultra_nego = temp6;
1262
1263 if(pCurrNvRam)
1264 i = pCurrNvRam->niSysConf;
1265 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001266 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267
1268 if(pCurrNvRam)
1269 ScamFlg = pCurrNvRam->niScamConf;
1270 else
James Bottomley 47b5d692005-04-24 02:38:05 -05001271 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272
1273 pCardInfo->si_flags = 0x0000;
1274
1275 if (i & 0x01)
1276 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1277
1278 if (!(i & 0x02))
1279 pCardInfo->si_flags |= SOFT_RESET;
1280
1281 if (i & 0x10)
1282 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1283
1284 if (ScamFlg & SCAM_ENABLED)
1285 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1286
1287 if (ScamFlg & SCAM_LEVEL2)
1288 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1289
1290 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1291 if (i & 0x04) {
1292 j |= SCSI_TERM_ENA_L;
1293 }
1294 WR_HARPOON(ioport+hp_bm_ctrl, j );
1295
1296 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1297 if (i & 0x08) {
1298 j |= SCSI_TERM_ENA_H;
1299 }
1300 WR_HARPOON(ioport+hp_ee_ctrl, j );
1301
1302 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1303
1304 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1305
1306 pCardInfo->si_card_family = HARPOON_FAMILY;
1307 pCardInfo->si_bustype = BUSTYPE_PCI;
1308
1309 if(pCurrNvRam){
1310 pCardInfo->si_card_model[0] = '9';
1311 switch(pCurrNvRam->niModel & 0x0f){
1312 case MODEL_LT:
1313 pCardInfo->si_card_model[1] = '3';
1314 pCardInfo->si_card_model[2] = '0';
1315 break;
1316 case MODEL_LW:
1317 pCardInfo->si_card_model[1] = '5';
1318 pCardInfo->si_card_model[2] = '0';
1319 break;
1320 case MODEL_DL:
1321 pCardInfo->si_card_model[1] = '3';
1322 pCardInfo->si_card_model[2] = '2';
1323 break;
1324 case MODEL_DW:
1325 pCardInfo->si_card_model[1] = '5';
1326 pCardInfo->si_card_model[2] = '2';
1327 break;
1328 }
1329 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001330 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
James Bottomley 47b5d692005-04-24 02:38:05 -05001332 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333
1334 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
1335 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
1336 }
1337
1338 if (pCardInfo->si_card_model[1] == '3')
1339 {
1340 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1341 pCardInfo->si_flags |= LOW_BYTE_TERM;
1342 }
1343 else if (pCardInfo->si_card_model[2] == '0')
1344 {
1345 temp = RD_HARPOON(ioport+hp_xfer_pad);
1346 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1347 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1348 pCardInfo->si_flags |= LOW_BYTE_TERM;
1349 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1350 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1351 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1352 WR_HARPOON(ioport+hp_xfer_pad, temp);
1353 }
1354 else
1355 {
1356 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1357 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1358 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1359 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1360 temp3 = 0;
1361 for (i = 0; i < 8; i++)
1362 {
1363 temp3 <<= 1;
1364 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1365 temp3 |= 1;
1366 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1367 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1368 }
1369 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1370 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1371 if (!(temp3 & BIT(7)))
1372 pCardInfo->si_flags |= LOW_BYTE_TERM;
1373 if (!(temp3 & BIT(6)))
1374 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1375 }
1376
1377
1378 ARAM_ACCESS(ioport);
1379
1380 for ( i = 0; i < 4; i++ ) {
1381
1382 pCardInfo->si_XlatInfo[i] =
1383 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1384 }
1385
1386 /* return with -1 if no sort, else return with
1387 logical card number sorted by BIOS (zero-based) */
1388
1389 pCardInfo->si_relative_cardnum =
1390 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1391
1392 SGRAM_ACCESS(ioport);
1393
James Bottomley 47b5d692005-04-24 02:38:05 -05001394 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1395 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1396 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1397 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1398 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1399 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1400 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1401 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
1403 pCardInfo->si_present = 0x01;
1404
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 return(0);
1406}
1407
1408
1409/*---------------------------------------------------------------------
1410 *
1411 * Function: SccbMgr_config_adapter
1412 *
1413 * Description: Setup adapter for normal operation (hard reset).
1414 *
1415 *---------------------------------------------------------------------*/
1416
James Bottomley 47b5d692005-04-24 02:38:05 -05001417static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418{
1419 PSCCBcard CurrCard = NULL;
1420 PNVRamInfo pCurrNvRam;
1421 UCHAR i,j,thisCard, ScamFlg;
1422 USHORT temp,sync_bit_map,id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 ioport = pCardInfo->si_baseaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1428
1429 if (thisCard == MAX_CARDS) {
1430
1431 return(FAILURE);
1432 }
1433
James Bottomley 47b5d692005-04-24 02:38:05 -05001434 if (FPT_BL_Card[thisCard].ioPort == ioport) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435
James Bottomley 47b5d692005-04-24 02:38:05 -05001436 CurrCard = &FPT_BL_Card[thisCard];
1437 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 break;
1439 }
1440
James Bottomley 47b5d692005-04-24 02:38:05 -05001441 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
James Bottomley 47b5d692005-04-24 02:38:05 -05001443 FPT_BL_Card[thisCard].ioPort = ioport;
1444 CurrCard = &FPT_BL_Card[thisCard];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445
James Bottomley 47b5d692005-04-24 02:38:05 -05001446 if(FPT_mbCards)
1447 for(i = 0; i < FPT_mbCards; i++){
1448 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1449 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 }
James Bottomley 47b5d692005-04-24 02:38:05 -05001451 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 CurrCard->cardIndex = thisCard;
1453 CurrCard->cardInfo = pCardInfo;
1454
1455 break;
1456 }
1457 }
1458
1459 pCurrNvRam = CurrCard->pNvRamInfo;
1460
1461 if(pCurrNvRam){
1462 ScamFlg = pCurrNvRam->niScamConf;
1463 }
1464 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001465 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 }
1467
1468
James Bottomley 47b5d692005-04-24 02:38:05 -05001469 FPT_BusMasterInit(ioport);
1470 FPT_XbowInit(ioport, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
James Bottomley 47b5d692005-04-24 02:38:05 -05001472 FPT_autoLoadDefaultMap(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474
1475 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1476
1477 WR_HARPOON(ioport+hp_selfid_0, id);
1478 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1479 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1480 CurrCard->ourId = pCardInfo->si_id;
1481
1482 i = (UCHAR) pCardInfo->si_flags;
1483 if (i & SCSI_PARITY_ENA)
1484 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1485
1486 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1487 if (i & LOW_BYTE_TERM)
1488 j |= SCSI_TERM_ENA_L;
1489 WR_HARPOON(ioport+hp_bm_ctrl, j);
1490
1491 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1492 if (i & HIGH_BYTE_TERM)
1493 j |= SCSI_TERM_ENA_H;
1494 WR_HARPOON(ioport+hp_ee_ctrl, j );
1495
1496
1497 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1498
James Bottomley 47b5d692005-04-24 02:38:05 -05001499 FPT_sresb(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
James Bottomley 47b5d692005-04-24 02:38:05 -05001501 FPT_scini(thisCard, pCardInfo->si_id, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 }
1503
1504
1505
1506 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1507 CurrCard->globalFlags |= F_NO_FILTER;
1508
1509 if(pCurrNvRam){
1510 if(pCurrNvRam->niSysConf & 0x10)
1511 CurrCard->globalFlags |= F_GREEN_PC;
1512 }
1513 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001514 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 CurrCard->globalFlags |= F_GREEN_PC;
1516 }
1517
1518 /* Set global flag to indicate Re-Negotiation to be done on all
1519 ckeck condition */
1520 if(pCurrNvRam){
1521 if(pCurrNvRam->niScsiConf & 0x04)
1522 CurrCard->globalFlags |= F_DO_RENEGO;
1523 }
1524 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001525 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 CurrCard->globalFlags |= F_DO_RENEGO;
1527 }
1528
1529 if(pCurrNvRam){
1530 if(pCurrNvRam->niScsiConf & 0x08)
1531 CurrCard->globalFlags |= F_CONLUN_IO;
1532 }
1533 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001534 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 CurrCard->globalFlags |= F_CONLUN_IO;
1536 }
1537
1538
1539 temp = pCardInfo->si_per_targ_no_disc;
1540
1541 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1542
1543 if (temp & id)
James Bottomley 47b5d692005-04-24 02:38:05 -05001544 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 }
1546
1547 sync_bit_map = 0x0001;
1548
1549 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1550
1551 if(pCurrNvRam){
1552 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1553 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1554 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1555 }else
James Bottomley 47b5d692005-04-24 02:38:05 -05001556 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 for (i = 0; i < 2; temp >>=8,i++) {
1559
1560 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1561
James Bottomley 47b5d692005-04-24 02:38:05 -05001562 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 }
1564
1565 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05001566 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1567 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 (UCHAR)(temp & ~EE_SYNC_MASK);
1569 }
1570
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1572 (id*2+i >= 8)){
1573*/
1574 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1575
James Bottomley 47b5d692005-04-24 02:38:05 -05001576 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
1578 }
1579
1580 else { /* NARROW SCSI */
James Bottomley 47b5d692005-04-24 02:38:05 -05001581 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 }
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
1585 sync_bit_map <<= 1;
1586
1587
1588
1589 }
1590 }
1591
1592 WR_HARPOON((ioport+hp_semaphore),
1593 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 return((ULONG)CurrCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596}
1597
James Bottomley 47b5d692005-04-24 02:38:05 -05001598static void SccbMgr_unload_card(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599{
1600 UCHAR i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 ULONG portBase;
1602 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 PNVRamInfo pCurrNvRam;
1606
1607 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1608
1609 if(pCurrNvRam){
James Bottomley 47b5d692005-04-24 02:38:05 -05001610 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1611 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1612 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1613 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1614 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
1616 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05001617 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618
1619 portBase = pCurrNvRam->niBaseAddr;
1620
1621 for(i = 0; i < MAX_SCSI_TAR; i++){
1622 regOffset = hp_aramBase + 64 + i*4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 scamData = *pScamTbl;
1625 WR_HARP32(portBase, regOffset, scamData);
1626 }
1627
1628 }else{
James Bottomley 47b5d692005-04-24 02:38:05 -05001629 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 }
1631}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632
1633
James Bottomley 47b5d692005-04-24 02:38:05 -05001634static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635{
1636 UCHAR i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 ULONG portBase;
1638 ULONG regOffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 ULONG scamData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 ULONG *pScamTbl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
James Bottomley 47b5d692005-04-24 02:38:05 -05001642 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1643 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1644 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1645 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1646 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647
1648 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05001649 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650
1651 portBase = pNvRamInfo->niBaseAddr;
1652
1653 for(i = 0; i < MAX_SCSI_TAR; i++){
1654 regOffset = hp_aramBase + 64 + i*4;
1655 RD_HARP32(portBase, regOffset, scamData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 *pScamTbl = scamData;
1658 }
1659
1660}
1661
James Bottomley 47b5d692005-04-24 02:38:05 -05001662static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663{
1664 WR_HARPOON(portBase + hp_stack_addr, index);
1665 return(RD_HARPOON(portBase + hp_stack_data));
1666}
1667
James Bottomley 47b5d692005-04-24 02:38:05 -05001668static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669{
1670 WR_HARPOON(portBase + hp_stack_addr, index);
1671 WR_HARPOON(portBase + hp_stack_data, data);
1672}
1673
1674
James Bottomley 47b5d692005-04-24 02:38:05 -05001675static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676{
James Bottomley 47b5d692005-04-24 02:38:05 -05001677 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1678 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1680 != CLKCTRL_DEFAULT)
James Bottomley 47b5d692005-04-24 02:38:05 -05001681 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1683 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
James Bottomley 47b5d692005-04-24 02:38:05 -05001684 return(1);
1685 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
1687}
1688/*---------------------------------------------------------------------
1689 *
1690 * Function: SccbMgr_start_sccb
1691 *
1692 * Description: Start a command pointed to by p_Sccb. When the
1693 * command is completed it will be returned via the
1694 * callback function.
1695 *
1696 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05001697static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 UCHAR thisCard, lun;
1701 PSCCB pSaveSccb;
1702 CALL_BK_FN callback;
1703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1705 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1706
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1708 {
1709
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 p_Sccb->HostStatus = SCCB_COMPLETE;
1711 p_Sccb->SccbStatus = SCCB_ERROR;
1712 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1713 if (callback)
1714 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 return;
1717 }
1718
James Bottomley 47b5d692005-04-24 02:38:05 -05001719 FPT_sinits(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
1721
1722 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1723 {
1724 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1725 | SCCB_MGR_ACTIVE));
1726
1727 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1728 {
1729 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1730 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1731 }
1732 }
1733
1734 ((PSCCBcard)pCurrCard)->cmdCounter++;
1735
1736 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1737
1738 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1739 | TICKLE_ME));
1740 if(p_Sccb->OperationCode == RESET_COMMAND)
1741 {
1742 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1743 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001744 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1746 }
1747 else
1748 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001749 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 }
1751 }
1752
1753 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1754
1755 if(p_Sccb->OperationCode == RESET_COMMAND)
1756 {
1757 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1758 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001759 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1761 }
1762 else
1763 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001764 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 }
1766 }
1767
1768 else {
1769
1770 MDISABLE_INT(ioport);
1771
1772 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001773 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 lun = p_Sccb->Lun;
1775 else
1776 lun = 0;
1777 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05001778 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1779 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1780 == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
1782 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001783 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 }
1785
1786 else {
1787
1788 if(p_Sccb->OperationCode == RESET_COMMAND)
1789 {
1790 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1791 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001792 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1794 }
1795 else
1796 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001797 FPT_queueAddSccb(p_Sccb,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 }
1799 }
1800
1801
1802 MENABLE_INT(ioport);
1803 }
1804
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805}
1806
1807
1808/*---------------------------------------------------------------------
1809 *
1810 * Function: SccbMgr_abort_sccb
1811 *
1812 * Description: Abort the command pointed to by p_Sccb. When the
1813 * command is completed it will be returned via the
1814 * callback function.
1815 *
1816 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05001817static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 UCHAR thisCard;
1822 CALL_BK_FN callback;
1823 UCHAR TID;
1824 PSCCB pSaveSCCB;
1825 PSCCBMgr_tar_info currTar_Info;
1826
1827
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1829
1830 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1831
James Bottomley 47b5d692005-04-24 02:38:05 -05001832 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 {
1834
James Bottomley 47b5d692005-04-24 02:38:05 -05001835 if (FPT_queueFindSccb(p_Sccb,thisCard))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 {
1837
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 ((PSCCBcard)pCurrCard)->cmdCounter--;
1839
1840 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1841 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1842 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 p_Sccb->SccbStatus = SCCB_ABORT;
1845 callback = p_Sccb->SccbCallback;
1846 callback(p_Sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
1848 return(0);
1849 }
1850
1851 else
1852 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1854 {
1855 p_Sccb->SccbStatus = SCCB_ABORT;
1856 return(0);
1857
1858 }
1859
1860 else
1861 {
1862
1863 TID = p_Sccb->TargID;
1864
1865
1866 if(p_Sccb->Sccb_tag)
1867 {
1868 MDISABLE_INT(ioport);
1869 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1870 {
1871 p_Sccb->SccbStatus = SCCB_ABORT;
1872 p_Sccb->Sccb_scsistat = ABORT_ST;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1874
1875 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1876 {
1877 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001878 FPT_ssel(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 }
1880 else
1881 {
1882 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1883 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
James Bottomley 47b5d692005-04-24 02:38:05 -05001884 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1886 }
1887 }
1888 MENABLE_INT(ioport);
1889 return(0);
1890 }
1891 else
1892 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001893 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
James Bottomley 47b5d692005-04-24 02:38:05 -05001895 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 == p_Sccb)
1897 {
1898 p_Sccb->SccbStatus = SCCB_ABORT;
1899 return(0);
1900 }
1901 }
1902 }
1903 }
1904 }
1905 return(-1);
1906}
1907
1908
1909/*---------------------------------------------------------------------
1910 *
1911 * Function: SccbMgr_my_int
1912 *
1913 * Description: Do a quick check to determine if there is a pending
1914 * interrupt for this card and disable the IRQ Pin if so.
1915 *
1916 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05001917static UCHAR SccbMgr_my_int(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
1921 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1922
1923 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1924 {
James Bottomley 47b5d692005-04-24 02:38:05 -05001925 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 }
1927
1928 else
1929
James Bottomley 47b5d692005-04-24 02:38:05 -05001930 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931}
1932
1933
1934
1935/*---------------------------------------------------------------------
1936 *
1937 * Function: SccbMgr_isr
1938 *
1939 * Description: This is our entry point when an interrupt is generated
1940 * by the card and the upper level driver passes it on to
1941 * us.
1942 *
1943 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05001944static int SccbMgr_isr(ULONG pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945{
1946 PSCCB currSCCB;
1947 UCHAR thisCard,result,bm_status, bm_int_st;
1948 USHORT hp_int;
1949 UCHAR i, target;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 ULONG ioport;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951
1952 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1953 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1954
1955 MDISABLE_INT(ioport);
1956
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1958 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
1959 else
1960 bm_status = 0;
1961
1962 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1963
James Bottomley 47b5d692005-04-24 02:38:05 -05001964 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 bm_status)
1966 {
1967
1968 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1969
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
James Bottomley 47b5d692005-04-24 02:38:05 -05001971 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1973 bm_status = 0;
1974
1975 if (result) {
1976
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 return(result);
1979 }
1980 }
1981
1982
1983 else if (hp_int & ICMD_COMP) {
1984
1985 if ( !(hp_int & BUS_FREE) ) {
1986 /* Wait for the BusFree before starting a new command. We
1987 must also check for being reselected since the BusFree
1988 may not show up if another device reselects us in 1.5us or
1989 less. SRR Wednesday, 3/8/1995.
1990 */
1991 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1992 }
1993
1994 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1995
James Bottomley 47b5d692005-04-24 02:38:05 -05001996 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
1998/* WRW_HARPOON((ioport+hp_intstat),
1999 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
2000 */
2001
2002 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
2003
James Bottomley 47b5d692005-04-24 02:38:05 -05002004 FPT_autoCmdCmplt(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005
2006 }
2007
2008
2009 else if (hp_int & ITAR_DISC)
2010 {
2011
2012 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2013
James Bottomley 47b5d692005-04-24 02:38:05 -05002014 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015
2016 }
2017
2018 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2019
2020 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2021 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2022
2023 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2024 }
2025
2026 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002027 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028
2029 /* Wait for the BusFree before starting a new command. We
2030 must also check for being reselected since the BusFree
2031 may not show up if another device reselects us in 1.5us or
2032 less. SRR Wednesday, 3/8/1995.
2033 */
2034 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2035 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2036 RD_HARPOON((ioport+hp_scsisig)) ==
2037 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2038
2039 /*
2040 The additional loop exit condition above detects a timing problem
2041 with the revision D/E harpoon chips. The caller should reset the
2042 host adapter to recover when 0xFE is returned.
2043 */
2044 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2045 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 return 0xFE;
2048 }
2049
2050 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2051
2052
2053 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2054
2055 }
2056
2057
2058 else if (hp_int & RSEL) {
2059
2060 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2061
2062 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2063 {
2064 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2065 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002066 FPT_phaseChkFifo(ioport, thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067 }
2068
2069 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2070 {
2071 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2072 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2073 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2074 }
2075
2076 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2077 currSCCB->Sccb_scsistat = DISCONNECT_ST;
James Bottomley 47b5d692005-04-24 02:38:05 -05002078 FPT_queueDisconnect(currSCCB,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 }
2080
James Bottomley 47b5d692005-04-24 02:38:05 -05002081 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2082 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083
2084 }
2085
2086
2087 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2088 {
2089
2090 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
James Bottomley 47b5d692005-04-24 02:38:05 -05002091 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
2093 }
2094
2095
2096 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2097 {
2098 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2099 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
2100 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002101 FPT_phaseDecode(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102 }
2103 else
2104 {
2105 /* Harpoon problem some SCSI target device respond to selection
2106 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2107 to latch the correct Target ID into reg. x53.
2108 The work around require to correct this reg. But when write to this
2109 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2110 need to read this reg first then restore it later. After update to 0x53 */
2111
2112 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
2113 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
2114 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
2115 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
2116 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
2117 WR_HARPOON(ioport+hp_fifowrite, i);
2118 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2119 }
2120 }
2121
2122 else if (hp_int & XFER_CNT_0) {
2123
2124 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2125
James Bottomley 47b5d692005-04-24 02:38:05 -05002126 FPT_schkdd(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
2128 }
2129
2130
2131 else if (hp_int & BUS_FREE) {
2132
2133 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2134
2135 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2136
James Bottomley 47b5d692005-04-24 02:38:05 -05002137 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138 }
2139
James Bottomley 47b5d692005-04-24 02:38:05 -05002140 FPT_phaseBusFree(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 }
2142
2143
2144 else if (hp_int & ITICKLE) {
2145
2146 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2147 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2148 }
2149
2150
2151
2152 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2153
2154
2155 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2156
2157
2158 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2159
James Bottomley 47b5d692005-04-24 02:38:05 -05002160 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161 }
2162
2163 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2164 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
James Bottomley 47b5d692005-04-24 02:38:05 -05002165 FPT_ssel(ioport,thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 }
2167
2168 break;
2169
2170 }
2171
2172 } /*end while */
2173
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 MENABLE_INT(ioport);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
2176 return(0);
2177}
2178
2179/*---------------------------------------------------------------------
2180 *
2181 * Function: Sccb_bad_isr
2182 *
2183 * Description: Some type of interrupt has occurred which is slightly
2184 * out of the ordinary. We will now decode it fully, in
2185 * this routine. This is broken up in an attempt to save
2186 * processing time.
2187 *
2188 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05002189static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2190 PSCCBcard pCurrCard, USHORT p_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191{
James Bottomley 47b5d692005-04-24 02:38:05 -05002192 UCHAR temp, ScamFlg;
2193 PSCCBMgr_tar_info currTar_Info;
2194 PNVRamInfo pCurrNvRam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195
2196
2197 if (RD_HARPOON(p_port+hp_ext_status) &
2198 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2199 {
2200
2201 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2202 {
2203
James Bottomley 47b5d692005-04-24 02:38:05 -05002204 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 }
2206
2207 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2208
2209 {
2210 WR_HARPOON(p_port+hp_pci_stat_cfg,
2211 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2212
2213 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2214
2215 }
2216
2217 if (pCurrCard->currentSCCB != NULL)
2218 {
2219
2220 if (!pCurrCard->currentSCCB->HostStatus)
2221 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2222
James Bottomley 47b5d692005-04-24 02:38:05 -05002223 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224
2225 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
2226 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2227 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
2228 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2229
2230 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2231 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002232 FPT_phaseDecode(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 }
2234 }
2235 }
2236
2237
2238 else if (p_int & RESET)
2239 {
2240
2241 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2242 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2243 if (pCurrCard->currentSCCB != NULL) {
2244
2245 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2246
James Bottomley 47b5d692005-04-24 02:38:05 -05002247 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 }
2249
2250
2251 DISABLE_AUTO(p_port);
2252
James Bottomley 47b5d692005-04-24 02:38:05 -05002253 FPT_sresb(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254
2255 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2256
2257 pCurrNvRam = pCurrCard->pNvRamInfo;
2258 if(pCurrNvRam){
2259 ScamFlg = pCurrNvRam->niScamConf;
2260 }
2261 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05002262 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 }
2264
James Bottomley 47b5d692005-04-24 02:38:05 -05002265 FPT_XbowInit(p_port, ScamFlg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266
James Bottomley 47b5d692005-04-24 02:38:05 -05002267 FPT_scini(p_card, pCurrCard->ourId, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268
2269 return(0xFF);
2270 }
2271
2272
2273 else if (p_int & FIFO) {
2274
2275 WRW_HARPOON((p_port+hp_intstat), FIFO);
2276
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 if (pCurrCard->currentSCCB != NULL)
James Bottomley 47b5d692005-04-24 02:38:05 -05002278 FPT_sxfrp(p_port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279 }
2280
2281 else if (p_int & TIMEOUT)
2282 {
2283
2284 DISABLE_AUTO(p_port);
2285
2286 WRW_HARPOON((p_port+hp_intstat),
2287 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2288
2289 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2290
2291
James Bottomley 47b5d692005-04-24 02:38:05 -05002292 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2294 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05002295 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002296 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002297 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298
2299
2300 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2301 {
2302 currTar_Info->TarSyncCtrl = 0;
2303 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2304 }
2305
2306 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2307 {
2308 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2309 }
2310
James Bottomley 47b5d692005-04-24 02:38:05 -05002311 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
James Bottomley 47b5d692005-04-24 02:38:05 -05002313 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
2315 }
2316
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 else if (p_int & SCAM_SEL)
2318 {
2319
James Bottomley 47b5d692005-04-24 02:38:05 -05002320 FPT_scarb(p_port,LEVEL2_TAR);
2321 FPT_scsel(p_port);
2322 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323
James Bottomley 47b5d692005-04-24 02:38:05 -05002324 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325
2326 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2327 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
2329 return(0x00);
2330}
2331
2332
2333/*---------------------------------------------------------------------
2334 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335 * Function: SccbMgrTableInit
2336 *
2337 * Description: Initialize all Sccb manager data structures.
2338 *
2339 *---------------------------------------------------------------------*/
2340
James Bottomley 47b5d692005-04-24 02:38:05 -05002341static void FPT_SccbMgrTableInitAll()
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342{
2343 UCHAR thisCard;
2344
2345 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2346 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002347 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348
James Bottomley 47b5d692005-04-24 02:38:05 -05002349 FPT_BL_Card[thisCard].ioPort = 0x00;
2350 FPT_BL_Card[thisCard].cardInfo = NULL;
2351 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2352 FPT_BL_Card[thisCard].ourId = 0x00;
2353 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 }
2355}
2356
2357
2358/*---------------------------------------------------------------------
2359 *
2360 * Function: SccbMgrTableInit
2361 *
2362 * Description: Initialize all Sccb manager data structures.
2363 *
2364 *---------------------------------------------------------------------*/
2365
James Bottomley 47b5d692005-04-24 02:38:05 -05002366static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367{
2368 UCHAR scsiID, qtag;
2369
2370 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2371 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002372 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373 }
2374
2375 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2376 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002377 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2378 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2379 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002380 }
2381
2382 pCurrCard->scanIndex = 0x00;
2383 pCurrCard->currentSCCB = NULL;
2384 pCurrCard->globalFlags = 0x00;
2385 pCurrCard->cmdCounter = 0x00;
2386 pCurrCard->tagQ_Lst = 0x01;
2387 pCurrCard->discQCount = 0;
2388
2389
2390}
2391
2392
2393/*---------------------------------------------------------------------
2394 *
2395 * Function: SccbMgrTableInit
2396 *
2397 * Description: Initialize all Sccb manager data structures.
2398 *
2399 *---------------------------------------------------------------------*/
2400
James Bottomley 47b5d692005-04-24 02:38:05 -05002401static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002402{
2403
2404 UCHAR lun, qtag;
2405 PSCCBMgr_tar_info currTar_Info;
2406
James Bottomley 47b5d692005-04-24 02:38:05 -05002407 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
2409 currTar_Info->TarSelQ_Cnt = 0;
2410 currTar_Info->TarSyncCtrl = 0;
2411
2412 currTar_Info->TarSelQ_Head = NULL;
2413 currTar_Info->TarSelQ_Tail = NULL;
2414 currTar_Info->TarTagQ_Cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05002415 currTar_Info->TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416
2417
2418 for (lun = 0; lun < MAX_LUN; lun++)
2419 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002420 currTar_Info->TarLUNBusy[lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421 currTar_Info->LunDiscQ_Idx[lun] = 0;
2422 }
2423
2424 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2425 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002426 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002428 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002430 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2431 FPT_BL_Card[p_card].discQCount--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432 }
2433 }
2434 }
2435}
2436
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437
2438/*---------------------------------------------------------------------
2439 *
2440 * Function: sfetm
2441 *
2442 * Description: Read in a message byte from the SCSI bus, and check
2443 * for a parity error.
2444 *
2445 *---------------------------------------------------------------------*/
2446
James Bottomley 47b5d692005-04-24 02:38:05 -05002447static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448{
2449 UCHAR message;
2450 USHORT TimeOutLoop;
2451
2452 TimeOutLoop = 0;
2453 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2454 (TimeOutLoop++ < 20000) ){}
2455
2456
2457 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2458
2459 message = RD_HARPOON(port+hp_scsidata_0);
2460
2461 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2462
2463
2464 if (TimeOutLoop > 20000)
2465 message = 0x00; /* force message byte = 0 if Time Out on Req */
2466
2467 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2468 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2469 {
2470 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2471 WR_HARPOON(port+hp_xferstat, 0);
2472 WR_HARPOON(port+hp_fiforead, 0);
2473 WR_HARPOON(port+hp_fifowrite, 0);
2474 if (pCurrSCCB != NULL)
2475 {
2476 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2477 }
2478 message = 0x00;
2479 do
2480 {
2481 ACCEPT_MSG_ATN(port);
2482 TimeOutLoop = 0;
2483 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2484 (TimeOutLoop++ < 20000) ){}
2485 if (TimeOutLoop > 20000)
2486 {
2487 WRW_HARPOON((port+hp_intstat), PARITY);
2488 return(message);
2489 }
2490 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2491 {
2492 WRW_HARPOON((port+hp_intstat), PARITY);
2493 return(message);
2494 }
2495 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2496
2497 RD_HARPOON(port+hp_scsidata_0);
2498
2499 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2500
2501 }while(1);
2502
2503 }
2504 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2505 WR_HARPOON(port+hp_xferstat, 0);
2506 WR_HARPOON(port+hp_fiforead, 0);
2507 WR_HARPOON(port+hp_fifowrite, 0);
2508 return(message);
2509}
2510
2511
2512/*---------------------------------------------------------------------
2513 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002514 * Function: FPT_ssel
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 *
2516 * Description: Load up automation and select target device.
2517 *
2518 *---------------------------------------------------------------------*/
2519
James Bottomley 47b5d692005-04-24 02:38:05 -05002520static void FPT_ssel(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521{
2522
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 UCHAR auto_loaded, i, target, *theCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 PSCCBcard CurrCard;
2527 PSCCB currSCCB;
2528 PSCCBMgr_tar_info currTar_Info;
2529 UCHAR lastTag, lun;
2530
James Bottomley 47b5d692005-04-24 02:38:05 -05002531 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 currSCCB = CurrCard->currentSCCB;
2533 target = currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05002534 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 lastTag = CurrCard->tagQ_Lst;
2536
2537 ARAM_ACCESS(port);
2538
2539
2540 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2541 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2542
2543 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2544 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2545
2546 lun = currSCCB->Lun;
2547 else
2548 lun = 0;
2549
2550
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 if (CurrCard->globalFlags & F_TAG_STARTED)
2552 {
2553 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2554 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002555 if ((currTar_Info->TarLUN_CA == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2557 == TAG_Q_TRYING))
2558 {
2559
2560 if (currTar_Info->TarTagQ_Cnt !=0)
2561 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002562 currTar_Info->TarLUNBusy[lun] = 1;
2563 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 SGRAM_ACCESS(port);
2565 return;
2566 }
2567
2568 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002569 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570 }
2571
2572 } /*End non-tagged */
2573
2574 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002575 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576 }
2577
2578 } /*!Use cmd Q Tagged */
2579
2580 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002581 if (currTar_Info->TarLUN_CA == 1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002583 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 SGRAM_ACCESS(port);
2585 return;
2586 }
2587
James Bottomley 47b5d692005-04-24 02:38:05 -05002588 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589
2590 } /*else use cmd Q tagged */
2591
2592 } /*if glob tagged started */
2593
2594 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05002595 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596 }
2597
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598
2599
2600 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2601 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2602 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2603 {
2604 if(CurrCard->discQCount >= QUEUE_DEPTH)
2605 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002606 currTar_Info->TarLUNBusy[lun] = 1;
2607 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608 SGRAM_ACCESS(port);
2609 return;
2610 }
2611 for (i = 1; i < QUEUE_DEPTH; i++)
2612 {
2613 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2614 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2615 {
2616 CurrCard->tagQ_Lst = lastTag;
2617 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2618 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2619 CurrCard->discQCount++;
2620 break;
2621 }
2622 }
2623 if(i == QUEUE_DEPTH)
2624 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002625 currTar_Info->TarLUNBusy[lun] = 1;
2626 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 SGRAM_ACCESS(port);
2628 return;
2629 }
2630 }
2631
2632
2633
James Bottomley 47b5d692005-04-24 02:38:05 -05002634 auto_loaded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635
2636 WR_HARPOON(port+hp_select_id, target);
2637 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2638
2639 if (currSCCB->OperationCode == RESET_COMMAND) {
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+NP);
2644
2645 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2646
2647 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002648 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2650
2651 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2652 {
2653 currTar_Info->TarSyncCtrl = 0;
2654 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2655 }
2656
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2658 {
2659 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2660 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002661
James Bottomley 47b5d692005-04-24 02:38:05 -05002662 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2663 FPT_SccbMgrTableInitTarget(p_card, target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664
2665 }
2666
2667 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2668 {
2669 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2670 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2671
2672 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2673
2674 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2675 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2676 >> 6) | (UCHAR)0x20)));
2677 WRW_HARPOON((port+SYNC_MSGS+2),
2678 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2679 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2680
2681 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
James Bottomley 47b5d692005-04-24 02:38:05 -05002682 auto_loaded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
2684 }
2685
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002687 auto_loaded = FPT_siwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2689 }
2690
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2692 == SYNC_SUPPORTED)) {
James Bottomley 47b5d692005-04-24 02:38:05 -05002693 auto_loaded = FPT_sisyncn(port,p_card, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2695 }
2696
2697
2698 if (!auto_loaded)
2699 {
2700
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701 if (currSCCB->ControlByte & F_USE_CMD_Q)
2702 {
2703
2704 CurrCard->globalFlags |= F_TAG_STARTED;
2705
2706 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2707 == TAG_Q_REJECT)
2708 {
2709 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2710
2711 /* Fix up the start instruction with a jump to
2712 Non-Tag-CMD handling */
2713 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2714
2715 WRW_HARPOON((port+NON_TAG_ID_MSG),
2716 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2717
2718 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2719
2720 /* Setup our STATE so we know what happend when
2721 the wheels fall off. */
2722 currSCCB->Sccb_scsistat = SELECT_ST;
2723
James Bottomley 47b5d692005-04-24 02:38:05 -05002724 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 }
2726
2727 else
2728 {
2729 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2730
2731 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2732 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2733 >> 6) | (UCHAR)0x20)));
2734
2735 for (i = 1; i < QUEUE_DEPTH; i++)
2736 {
2737 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2738 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2739 {
2740 WRW_HARPOON((port+ID_MSG_STRT+6),
2741 (MPM_OP+AMSG_OUT+lastTag));
2742 CurrCard->tagQ_Lst = lastTag;
2743 currSCCB->Sccb_tag = lastTag;
2744 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2745 CurrCard->discQCount++;
2746 break;
2747 }
2748 }
2749
2750
2751 if ( i == QUEUE_DEPTH )
2752 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002753 currTar_Info->TarLUNBusy[lun] = 1;
2754 FPT_queueSelectFail(CurrCard,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755 SGRAM_ACCESS(port);
2756 return;
2757 }
2758
2759 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2760
2761 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2762 }
2763 }
2764
2765 else
2766 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767
2768 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2769
2770 WRW_HARPOON((port+NON_TAG_ID_MSG),
2771 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2772
2773 currSCCB->Sccb_scsistat = SELECT_ST;
2774
2775 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777
2778
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779 theCCB = (UCHAR *)&currSCCB->Cdb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002780
2781 cdb_reg = port + CMD_STRT;
2782
2783 for (i=0; i < currSCCB->CdbLength; i++)
2784 {
2785 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2786 cdb_reg +=2;
2787 theCCB++;
2788 }
2789
2790 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2791 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2792
2793 } /* auto_loaded */
2794
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2796 WR_HARPOON(port+hp_xferstat, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797
2798 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2799
2800 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2801
2802
2803 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2804 {
2805 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2806 }
2807 else
2808 {
2809
2810/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
2811 auto_loaded |= AUTO_IMMED; */
2812 auto_loaded = AUTO_IMMED;
2813
2814 DISABLE_AUTO(port);
2815
2816 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2817 }
2818
2819 SGRAM_ACCESS(port);
2820}
2821
2822
2823/*---------------------------------------------------------------------
2824 *
James Bottomley 47b5d692005-04-24 02:38:05 -05002825 * Function: FPT_sres
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 *
2827 * Description: Hookup the correct CCB and handle the incoming messages.
2828 *
2829 *---------------------------------------------------------------------*/
2830
James Bottomley 47b5d692005-04-24 02:38:05 -05002831static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832{
2833
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002835
2836
2837 PSCCBMgr_tar_info currTar_Info;
2838 PSCCB currSCCB;
2839
2840
2841
2842
2843 if(pCurrCard->currentSCCB != NULL)
2844 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002845 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 DISABLE_AUTO(port);
2847
2848
2849 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2850
2851
2852 currSCCB = pCurrCard->currentSCCB;
2853 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2854 {
2855 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2856 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2857 }
2858 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2859 {
2860 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2861 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2862 }
2863 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2864 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2865 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002866 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 if(currSCCB->Sccb_scsistat != ABORT_ST)
2868 {
2869 pCurrCard->discQCount--;
2870 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2871 = NULL;
2872 }
2873 }
2874 else
2875 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002876 currTar_Info->TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 if(currSCCB->Sccb_tag)
2878 {
2879 if(currSCCB->Sccb_scsistat != ABORT_ST)
2880 {
2881 pCurrCard->discQCount--;
2882 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2883 }
2884 }else
2885 {
2886 if(currSCCB->Sccb_scsistat != ABORT_ST)
2887 {
2888 pCurrCard->discQCount--;
2889 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2890 }
2891 }
2892 }
2893
James Bottomley 47b5d692005-04-24 02:38:05 -05002894 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 }
2896
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002898
2899
2900 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
James Bottomley 47b5d692005-04-24 02:38:05 -05002901 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902
2903
2904 msgRetryCount = 0;
2905 do
2906 {
2907
James Bottomley 47b5d692005-04-24 02:38:05 -05002908 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909 tag = 0;
2910
2911
2912 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2913 {
2914 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2915 {
2916
2917 WRW_HARPOON((port+hp_intstat), PHASE);
2918 return;
2919 }
2920 }
2921
2922 WRW_HARPOON((port+hp_intstat), PHASE);
2923 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2924 {
2925
James Bottomley 47b5d692005-04-24 02:38:05 -05002926 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 if (message)
2928 {
2929
2930 if (message <= (0x80 | LUN_MASK))
2931 {
2932 lun = message & (UCHAR)LUN_MASK;
2933
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2935 {
2936 if (currTar_Info->TarTagQ_Cnt != 0)
2937 {
2938
2939 if (!(currTar_Info->TarLUN_CA))
2940 {
2941 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2942
2943
James Bottomley 47b5d692005-04-24 02:38:05 -05002944 message = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002945 if (message)
2946 {
2947 ACCEPT_MSG(port);
2948 }
2949
2950 else
James Bottomley 47b5d692005-04-24 02:38:05 -05002951 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952
James Bottomley 47b5d692005-04-24 02:38:05 -05002953 if(message != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002955 tag = FPT_sfm(port,pCurrCard->currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956
2957 if (!(tag))
James Bottomley 47b5d692005-04-24 02:38:05 -05002958 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 }
2960
2961 } /*C.A. exists! */
2962
2963 } /*End Q cnt != 0 */
2964
2965 } /*End Tag cmds supported! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966
2967 } /*End valid ID message. */
2968
2969 else
2970 {
2971
2972 ACCEPT_MSG_ATN(port);
2973 }
2974
2975 } /* End good id message. */
2976
2977 else
2978 {
2979
James Bottomley 47b5d692005-04-24 02:38:05 -05002980 message = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 }
2982 }
2983 else
2984 {
2985 ACCEPT_MSG_ATN(port);
2986
2987 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2988 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2989 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2990
2991 return;
2992 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993
James Bottomley 47b5d692005-04-24 02:38:05 -05002994 if(message == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 {
2996 msgRetryCount++;
2997 if(msgRetryCount == 1)
2998 {
James Bottomley 47b5d692005-04-24 02:38:05 -05002999 FPT_SendMsg(port, SMPARITY);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 }
3001 else
3002 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003003 FPT_SendMsg(port, SMDEV_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004
James Bottomley 47b5d692005-04-24 02:38:05 -05003005 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006
James Bottomley 47b5d692005-04-24 02:38:05 -05003007 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 {
3009
James Bottomley 47b5d692005-04-24 02:38:05 -05003010 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011
3012 }
3013
James Bottomley 47b5d692005-04-24 02:38:05 -05003014 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 {
3016
James Bottomley 47b5d692005-04-24 02:38:05 -05003017 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 }
3019
3020
James Bottomley 47b5d692005-04-24 02:38:05 -05003021 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3022 FPT_SccbMgrTableInitTarget(p_card,our_target);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023 return;
3024 }
3025 }
James Bottomley 47b5d692005-04-24 02:38:05 -05003026 }while(message == 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027
3028
3029
3030 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3031 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3032 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003033 currTar_Info->TarLUNBusy[lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3035 if(pCurrCard->currentSCCB != NULL)
3036 {
3037 ACCEPT_MSG(port);
3038 }
3039 else
3040 {
3041 ACCEPT_MSG_ATN(port);
3042 }
3043 }
3044 else
3045 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003046 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047
3048
3049 if (tag)
3050 {
3051 if (pCurrCard->discQ_Tbl[tag] != NULL)
3052 {
3053 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3054 currTar_Info->TarTagQ_Cnt--;
3055 ACCEPT_MSG(port);
3056 }
3057 else
3058 {
3059 ACCEPT_MSG_ATN(port);
3060 }
3061 }else
3062 {
3063 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3064 if(pCurrCard->currentSCCB != NULL)
3065 {
3066 ACCEPT_MSG(port);
3067 }
3068 else
3069 {
3070 ACCEPT_MSG_ATN(port);
3071 }
3072 }
3073 }
3074
3075 if(pCurrCard->currentSCCB != NULL)
3076 {
3077 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3078 {
3079 /* During Abort Tag command, the target could have got re-selected
3080 and completed the command. Check the select Q and remove the CCB
3081 if it is in the Select Q */
James Bottomley 47b5d692005-04-24 02:38:05 -05003082 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003083 }
3084 }
3085
3086
3087 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3088 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3089 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3090}
3091
James Bottomley 47b5d692005-04-24 02:38:05 -05003092static void FPT_SendMsg(ULONG port, UCHAR message)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093{
3094 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3095 {
3096 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3097 {
3098
3099 WRW_HARPOON((port+hp_intstat), PHASE);
3100 return;
3101 }
3102 }
3103
3104 WRW_HARPOON((port+hp_intstat), PHASE);
3105 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3106 {
3107 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3108
3109
3110 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3111
3112 WR_HARPOON(port+hp_scsidata_0,message);
3113
3114 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3115
3116 ACCEPT_MSG(port);
3117
3118 WR_HARPOON(port+hp_portctrl_0, 0x00);
3119
3120 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3121 (message == SMABORT_TAG) )
3122 {
3123 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3124
3125 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3126 {
3127 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3128 }
3129 }
3130 }
3131}
3132
3133/*---------------------------------------------------------------------
3134 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003135 * Function: FPT_sdecm
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 *
3137 * Description: Determine the proper responce to the message from the
3138 * target device.
3139 *
3140 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003141static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142{
3143 PSCCB currSCCB;
3144 PSCCBcard CurrCard;
3145 PSCCBMgr_tar_info currTar_Info;
3146
James Bottomley 47b5d692005-04-24 02:38:05 -05003147 CurrCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148 currSCCB = CurrCard->currentSCCB;
3149
James Bottomley 47b5d692005-04-24 02:38:05 -05003150 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151
3152 if (message == SMREST_DATA_PTR)
3153 {
3154 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3155 {
3156 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3157
James Bottomley 47b5d692005-04-24 02:38:05 -05003158 FPT_hostDataXferRestart(currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159 }
3160
3161 ACCEPT_MSG(port);
3162 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3163 }
3164
3165 else if (message == SMCMD_COMP)
3166 {
3167
3168
3169 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3170 {
3171 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
3172 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
3173 }
3174
3175 ACCEPT_MSG(port);
3176
3177 }
3178
3179 else if ((message == SMNO_OP) || (message >= SMIDENT)
3180 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3181 {
3182
3183 ACCEPT_MSG(port);
3184 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3185 }
3186
3187 else if (message == SMREJECT)
3188 {
3189
3190 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3191 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3192 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3193 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3194
3195 {
3196 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3197
3198 ACCEPT_MSG(port);
3199
3200
3201 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3202 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3203
3204 if(currSCCB->Lun == 0x00)
3205 {
3206 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3207 {
3208
3209 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3210
3211 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3212 }
3213
Linus Torvalds1da177e2005-04-16 15:20:36 -07003214 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3215 {
3216
3217
3218 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3219 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3220
3221 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3222
3223 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224
3225 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3226 {
3227 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3228 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3229
3230
3231 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3232 CurrCard->discQCount--;
3233 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3234 currSCCB->Sccb_tag = 0x00;
3235
3236 }
3237 }
3238
3239 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3240 {
3241
3242
3243 if(currSCCB->Lun == 0x00)
3244 {
3245 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3246 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3247 }
3248 }
3249
3250 else
3251 {
3252
3253 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3254 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
James Bottomley 47b5d692005-04-24 02:38:05 -05003255 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 else
James Bottomley 47b5d692005-04-24 02:38:05 -05003257 currTar_Info->TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003258
3259
3260 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
3261
3262 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3263
3264 }
3265 }
3266
3267 else
3268 {
3269 ACCEPT_MSG(port);
3270
3271 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3272 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3273
3274 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3275 {
3276 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3277 }
3278 }
3279 }
3280
3281 else if (message == SMEXT)
3282 {
3283
3284 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003285 FPT_shandem(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003286 }
3287
3288 else if (message == SMIGNORWR)
3289 {
3290
3291 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3292
James Bottomley 47b5d692005-04-24 02:38:05 -05003293 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003294
3295 if(currSCCB->Sccb_scsimsg != SMPARITY)
3296 ACCEPT_MSG(port);
3297 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3298 }
3299
3300
3301 else
3302 {
3303
3304 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3305 currSCCB->Sccb_scsimsg = SMREJECT;
3306
3307 ACCEPT_MSG_ATN(port);
3308 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3309 }
3310}
3311
3312
3313/*---------------------------------------------------------------------
3314 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003315 * Function: FPT_shandem
Linus Torvalds1da177e2005-04-16 15:20:36 -07003316 *
3317 * Description: Decide what to do with the extended message.
3318 *
3319 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003320static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321{
3322 UCHAR length,message;
3323
James Bottomley 47b5d692005-04-24 02:38:05 -05003324 length = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003325 if (length)
3326 {
3327
3328 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003329 message = FPT_sfm(port,pCurrSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003330 if (message)
3331 {
3332
3333 if (message == SMSYNC)
3334 {
3335
3336 if (length == 0x03)
3337 {
3338
3339 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003340 FPT_stsyncn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341 }
3342 else
3343 {
3344
3345 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3346 ACCEPT_MSG_ATN(port);
3347 }
3348 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003349 else if (message == SMWDTR)
3350 {
3351
3352 if (length == 0x02)
3353 {
3354
3355 ACCEPT_MSG(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003356 FPT_stwidn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003357 }
3358 else
3359 {
3360
3361 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3362 ACCEPT_MSG_ATN(port);
3363
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3365 }
3366 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003367 else
3368 {
3369
3370 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3371 ACCEPT_MSG_ATN(port);
3372
3373 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3374 }
3375 }
3376 else
3377 {
3378 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3379 ACCEPT_MSG(port);
3380 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3381 }
3382 }else
3383 {
3384 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3385 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3386 }
3387}
3388
3389
3390/*---------------------------------------------------------------------
3391 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003392 * Function: FPT_sisyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393 *
3394 * Description: Read in a message byte from the SCSI bus, and check
3395 * for a parity error.
3396 *
3397 *---------------------------------------------------------------------*/
3398
James Bottomley 47b5d692005-04-24 02:38:05 -05003399static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003400{
3401 PSCCB currSCCB;
3402 PSCCBMgr_tar_info currTar_Info;
3403
James Bottomley 47b5d692005-04-24 02:38:05 -05003404 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3405 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003406
3407 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3408
3409
3410 WRW_HARPOON((port+ID_MSG_STRT),
3411 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3412
3413 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3414
3415 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3416 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3417 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3418
3419
3420 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3421
3422 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3423
3424 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3425
3426 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3427
3428 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3429
3430 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3431
3432 else
3433 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3434
3435
3436 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3437 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3438 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3439
3440
James Bottomley 47b5d692005-04-24 02:38:05 -05003441 if(syncFlag == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 {
3443 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3444 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3445 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
3446 }
3447 else
3448 {
3449 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3450 }
3451
3452
James Bottomley 47b5d692005-04-24 02:38:05 -05003453 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454 }
3455
3456 else {
3457
3458 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3459 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
James Bottomley 47b5d692005-04-24 02:38:05 -05003460 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003461 }
3462}
3463
3464
3465
3466/*---------------------------------------------------------------------
3467 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003468 * Function: FPT_stsyncn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469 *
3470 * Description: The has sent us a Sync Nego message so handle it as
3471 * necessary.
3472 *
3473 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003474static void FPT_stsyncn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003475{
3476 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3477 PSCCB currSCCB;
3478 PSCCBMgr_tar_info currTar_Info;
3479
James Bottomley 47b5d692005-04-24 02:38:05 -05003480 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3481 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003482
James Bottomley 47b5d692005-04-24 02:38:05 -05003483 sync_msg = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003484
3485 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3486 {
3487 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3488 return;
3489 }
3490
3491 ACCEPT_MSG(port);
3492
3493
James Bottomley 47b5d692005-04-24 02:38:05 -05003494 offset = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003495
3496 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3497 {
3498 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3499 return;
3500 }
3501
3502 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3503
3504 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3505
3506 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3507
3508 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3509
3510 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3511
3512 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3513 else
3514
3515 our_sync_msg = 0; /* Message = Async */
3516
3517 if (sync_msg < our_sync_msg) {
3518 sync_msg = our_sync_msg; /*if faster, then set to max. */
3519 }
3520
3521 if (offset == ASYNC)
3522 sync_msg = ASYNC;
3523
3524 if (offset > MAX_OFFSET)
3525 offset = MAX_OFFSET;
3526
3527 sync_reg = 0x00;
3528
3529 if (sync_msg > 12)
3530
3531 sync_reg = 0x20; /* Use 10MB/s */
3532
3533 if (sync_msg > 25)
3534
3535 sync_reg = 0x40; /* Use 6.6MB/s */
3536
3537 if (sync_msg > 38)
3538
3539 sync_reg = 0x60; /* Use 5MB/s */
3540
3541 if (sync_msg > 50)
3542
3543 sync_reg = 0x80; /* Use 4MB/s */
3544
3545 if (sync_msg > 62)
3546
3547 sync_reg = 0xA0; /* Use 3.33MB/s */
3548
3549 if (sync_msg > 75)
3550
3551 sync_reg = 0xC0; /* Use 2.85MB/s */
3552
3553 if (sync_msg > 87)
3554
3555 sync_reg = 0xE0; /* Use 2.5MB/s */
3556
3557 if (sync_msg > 100) {
3558
3559 sync_reg = 0x00; /* Use ASYNC */
3560 offset = 0x00;
3561 }
3562
3563
Linus Torvalds1da177e2005-04-16 15:20:36 -07003564 if (currTar_Info->TarStatus & WIDE_ENABLED)
3565
3566 sync_reg |= offset;
3567
3568 else
3569
3570 sync_reg |= (offset | NARROW_SCSI);
3571
James Bottomley 47b5d692005-04-24 02:38:05 -05003572 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573
3574
3575 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3576
3577
3578 ACCEPT_MSG(port);
3579
3580 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3581 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3582
3583 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3584 }
3585
3586 else {
3587
3588
3589 ACCEPT_MSG_ATN(port);
3590
James Bottomley 47b5d692005-04-24 02:38:05 -05003591 FPT_sisyncr(port,sync_msg,offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592
3593 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3594 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3595 }
3596}
3597
3598
3599/*---------------------------------------------------------------------
3600 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003601 * Function: FPT_sisyncr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602 *
3603 * Description: Answer the targets sync message.
3604 *
3605 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003606static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003607{
3608 ARAM_ACCESS(port);
3609 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3610 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3611 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3612 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3613 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3614 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3615 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3616 SGRAM_ACCESS(port);
3617
3618 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3619 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3620
3621 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3622
3623 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3624}
3625
3626
3627
Linus Torvalds1da177e2005-04-16 15:20:36 -07003628/*---------------------------------------------------------------------
3629 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003630 * Function: FPT_siwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003631 *
3632 * Description: Read in a message byte from the SCSI bus, and check
3633 * for a parity error.
3634 *
3635 *---------------------------------------------------------------------*/
3636
James Bottomley 47b5d692005-04-24 02:38:05 -05003637static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638{
3639 PSCCB currSCCB;
3640 PSCCBMgr_tar_info currTar_Info;
3641
James Bottomley 47b5d692005-04-24 02:38:05 -05003642 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3643 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003644
3645 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3646
3647
3648 WRW_HARPOON((port+ID_MSG_STRT),
3649 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3650
3651 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3652
3653 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3654 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3655 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3656 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3657 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3658 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3659
3660 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3661
3662
3663 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3664 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
3665
James Bottomley 47b5d692005-04-24 02:38:05 -05003666 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003667 }
3668
3669 else {
3670
3671 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3672 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3673
3674 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
James Bottomley 47b5d692005-04-24 02:38:05 -05003675 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003676 }
3677}
3678
3679
3680
3681/*---------------------------------------------------------------------
3682 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003683 * Function: FPT_stwidn
Linus Torvalds1da177e2005-04-16 15:20:36 -07003684 *
3685 * Description: The has sent us a Wide Nego message so handle it as
3686 * necessary.
3687 *
3688 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003689static void FPT_stwidn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690{
3691 UCHAR width;
3692 PSCCB currSCCB;
3693 PSCCBMgr_tar_info currTar_Info;
3694
James Bottomley 47b5d692005-04-24 02:38:05 -05003695 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3696 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003697
James Bottomley 47b5d692005-04-24 02:38:05 -05003698 width = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003699
3700 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3701 {
3702 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3703 return;
3704 }
3705
3706
3707 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3708 width = 0;
3709
3710 if (width) {
3711 currTar_Info->TarStatus |= WIDE_ENABLED;
3712 width = 0;
3713 }
3714 else {
3715 width = NARROW_SCSI;
3716 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3717 }
3718
3719
James Bottomley 47b5d692005-04-24 02:38:05 -05003720 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003721
3722
3723 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3724 {
3725
3726
3727
3728 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3729
3730 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3731 {
3732 ACCEPT_MSG_ATN(port);
3733 ARAM_ACCESS(port);
James Bottomley 47b5d692005-04-24 02:38:05 -05003734 FPT_sisyncn(port,p_card, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003735 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3736 SGRAM_ACCESS(port);
3737 }
3738 else
3739 {
3740 ACCEPT_MSG(port);
3741 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3742 }
3743 }
3744
3745 else {
3746
3747
3748 ACCEPT_MSG_ATN(port);
3749
3750 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3751 width = SM16BIT;
3752 else
3753 width = SM8BIT;
3754
James Bottomley 47b5d692005-04-24 02:38:05 -05003755 FPT_siwidr(port,width);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
3757 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3758 }
3759}
3760
3761
3762/*---------------------------------------------------------------------
3763 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003764 * Function: FPT_siwidr
Linus Torvalds1da177e2005-04-16 15:20:36 -07003765 *
3766 * Description: Answer the targets Wide nego message.
3767 *
3768 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003769static void FPT_siwidr(ULONG port, UCHAR width)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003770{
3771 ARAM_ACCESS(port);
3772 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3773 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3774 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3775 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3776 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3777 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3778 SGRAM_ACCESS(port);
3779
3780 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3781 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3782
3783 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3784
3785 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3786}
3787
Linus Torvalds1da177e2005-04-16 15:20:36 -07003788
3789
3790/*---------------------------------------------------------------------
3791 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003792 * Function: FPT_sssyncv
Linus Torvalds1da177e2005-04-16 15:20:36 -07003793 *
3794 * Description: Write the desired value to the Sync Register for the
3795 * ID specified.
3796 *
3797 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003798static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
3799 PSCCBMgr_tar_info currTar_Info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003800{
3801 UCHAR index;
3802
3803 index = p_id;
3804
3805 switch (index) {
3806
3807 case 0:
3808 index = 12; /* hp_synctarg_0 */
3809 break;
3810 case 1:
3811 index = 13; /* hp_synctarg_1 */
3812 break;
3813 case 2:
3814 index = 14; /* hp_synctarg_2 */
3815 break;
3816 case 3:
3817 index = 15; /* hp_synctarg_3 */
3818 break;
3819 case 4:
3820 index = 8; /* hp_synctarg_4 */
3821 break;
3822 case 5:
3823 index = 9; /* hp_synctarg_5 */
3824 break;
3825 case 6:
3826 index = 10; /* hp_synctarg_6 */
3827 break;
3828 case 7:
3829 index = 11; /* hp_synctarg_7 */
3830 break;
3831 case 8:
3832 index = 4; /* hp_synctarg_8 */
3833 break;
3834 case 9:
3835 index = 5; /* hp_synctarg_9 */
3836 break;
3837 case 10:
3838 index = 6; /* hp_synctarg_10 */
3839 break;
3840 case 11:
3841 index = 7; /* hp_synctarg_11 */
3842 break;
3843 case 12:
3844 index = 0; /* hp_synctarg_12 */
3845 break;
3846 case 13:
3847 index = 1; /* hp_synctarg_13 */
3848 break;
3849 case 14:
3850 index = 2; /* hp_synctarg_14 */
3851 break;
3852 case 15:
3853 index = 3; /* hp_synctarg_15 */
3854
3855 }
3856
3857 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3858
3859 currTar_Info->TarSyncCtrl = p_sync_value;
3860}
3861
3862
3863/*---------------------------------------------------------------------
3864 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003865 * Function: FPT_sresb
Linus Torvalds1da177e2005-04-16 15:20:36 -07003866 *
3867 * Description: Reset the desired card's SCSI bus.
3868 *
3869 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003870static void FPT_sresb(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003871{
3872 UCHAR scsiID, i;
3873
3874 PSCCBMgr_tar_info currTar_Info;
3875
3876 WR_HARPOON(port+hp_page_ctrl,
3877 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3878 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3879
3880 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3881
3882 scsiID = RD_HARPOON(port+hp_seltimeout);
3883 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3884 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3885
3886 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3887
3888 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3889
3890 WR_HARPOON(port+hp_seltimeout,scsiID);
3891
3892 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3893
James Bottomley 47b5d692005-04-24 02:38:05 -05003894 FPT_Wait(port, TO_5ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895
3896 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3897
3898 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3899
3900 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3901 {
James Bottomley 47b5d692005-04-24 02:38:05 -05003902 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003903
3904 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3905 {
3906 currTar_Info->TarSyncCtrl = 0;
3907 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3908 }
3909
3910 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3911 {
3912 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3913 }
3914
James Bottomley 47b5d692005-04-24 02:38:05 -05003915 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916
James Bottomley 47b5d692005-04-24 02:38:05 -05003917 FPT_SccbMgrTableInitTarget(p_card, scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 }
3919
James Bottomley 47b5d692005-04-24 02:38:05 -05003920 FPT_BL_Card[p_card].scanIndex = 0x00;
3921 FPT_BL_Card[p_card].currentSCCB = NULL;
3922 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003923 | F_NEW_SCCB_CMD);
James Bottomley 47b5d692005-04-24 02:38:05 -05003924 FPT_BL_Card[p_card].cmdCounter = 0x00;
3925 FPT_BL_Card[p_card].discQCount = 0x00;
3926 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003927
3928 for(i = 0; i < QUEUE_DEPTH; i++)
James Bottomley 47b5d692005-04-24 02:38:05 -05003929 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003930
3931 WR_HARPOON(port+hp_page_ctrl,
3932 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3933
3934}
3935
3936/*---------------------------------------------------------------------
3937 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003938 * Function: FPT_ssenss
Linus Torvalds1da177e2005-04-16 15:20:36 -07003939 *
3940 * Description: Setup for the Auto Sense command.
3941 *
3942 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05003943static void FPT_ssenss(PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003944{
3945 UCHAR i;
3946 PSCCB currSCCB;
3947
3948 currSCCB = pCurrCard->currentSCCB;
3949
3950
3951 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3952
3953 for (i = 0; i < 6; i++) {
3954
3955 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3956 }
3957
3958 currSCCB->CdbLength = SIX_BYTE_CMD;
3959 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3960 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
3961 currSCCB->Cdb[2] = 0x00;
3962 currSCCB->Cdb[3] = 0x00;
3963 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3964 currSCCB->Cdb[5] = 0x00;
3965
3966 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3967
3968 currSCCB->Sccb_ATC = 0x00;
3969
3970 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3971
3972 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3973
3974 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
3975
3976 currSCCB->ControlByte = 0x00;
3977
3978 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3979}
3980
3981
3982
3983/*---------------------------------------------------------------------
3984 *
James Bottomley 47b5d692005-04-24 02:38:05 -05003985 * Function: FPT_sxfrp
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986 *
3987 * Description: Transfer data into the bit bucket until the device
3988 * decides to switch phase.
3989 *
3990 *---------------------------------------------------------------------*/
3991
James Bottomley 47b5d692005-04-24 02:38:05 -05003992static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003993{
3994 UCHAR curr_phz;
3995
3996
3997 DISABLE_AUTO(p_port);
3998
James Bottomley 47b5d692005-04-24 02:38:05 -05003999 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07004000
James Bottomley 47b5d692005-04-24 02:38:05 -05004001 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002
4003 }
4004
4005 /* If the Automation handled the end of the transfer then do not
4006 match the phase or we will get out of sync with the ISR. */
4007
4008 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
4009 return;
4010
4011 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
4012
4013 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
4014
4015 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4016
4017
4018 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4019
4020 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4021 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
4022 {
4023 if (curr_phz & (UCHAR)SCSI_IOBIT)
4024 {
4025 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4026
4027 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4028 {
4029 RD_HARPOON(p_port+hp_fifodata_0);
4030 }
4031 }
4032 else
4033 {
4034 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4035 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4036 {
4037 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4038 }
4039 }
4040 } /* End of While loop for padding data I/O phase */
4041
4042 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4043 {
4044 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4045 break;
4046 }
4047
4048 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4049 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4050 {
4051 RD_HARPOON(p_port+hp_fifodata_0);
4052 }
4053
4054 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4055 {
4056 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4057 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4058
4059 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4060 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4061 }
4062}
4063
4064
4065/*---------------------------------------------------------------------
4066 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004067 * Function: FPT_schkdd
Linus Torvalds1da177e2005-04-16 15:20:36 -07004068 *
4069 * Description: Make sure data has been flushed from both FIFOs and abort
4070 * the operations if necessary.
4071 *
4072 *---------------------------------------------------------------------*/
4073
James Bottomley 47b5d692005-04-24 02:38:05 -05004074static void FPT_schkdd(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004075{
4076 USHORT TimeOutLoop;
4077 UCHAR sPhase;
4078
4079 PSCCB currSCCB;
4080
James Bottomley 47b5d692005-04-24 02:38:05 -05004081 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004082
4083
4084 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4085 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4086 return;
4087 }
4088
4089
4090
4091 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4092 {
4093
4094 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4095
4096 currSCCB->Sccb_XferCnt = 1;
4097
4098 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4099 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4100 WR_HARPOON(port+hp_xferstat, 0x00);
4101 }
4102
4103 else
4104 {
4105
4106 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4107
4108 currSCCB->Sccb_XferCnt = 0;
4109 }
4110
4111 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4112 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4113
4114 currSCCB->HostStatus = SCCB_PARITY_ERR;
4115 WRW_HARPOON((port+hp_intstat), PARITY);
4116 }
4117
4118
James Bottomley 47b5d692005-04-24 02:38:05 -05004119 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004120
4121
4122 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4123
4124 TimeOutLoop = 0;
4125
4126 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4127 {
4128 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4129 return;
4130 }
4131 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
4132 break;
4133 }
4134 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4135 return;
4136 }
4137 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4138 break;
4139 }
4140
4141 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4142 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4143 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
4144 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4145 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4146 {
4147
4148 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4149
4150 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4151 {
4152 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
James Bottomley 47b5d692005-04-24 02:38:05 -05004153 FPT_phaseDataIn(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004154 }
4155
4156 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05004157 FPT_phaseDataOut(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004158 }
4159 }
4160 else
4161 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004162 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004163 if (!(RDW_HARPOON((port+hp_intstat)) &
4164 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4165 {
4166 WRW_HARPOON((port+hp_intstat), AUTO_INT);
James Bottomley 47b5d692005-04-24 02:38:05 -05004167 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004168 }
4169 }
4170
4171 }
4172
4173 else {
4174 WR_HARPOON(port+hp_portctrl_0, 0x00);
4175 }
4176}
4177
4178
4179/*---------------------------------------------------------------------
4180 *
James Bottomley 47b5d692005-04-24 02:38:05 -05004181 * Function: FPT_sinits
Linus Torvalds1da177e2005-04-16 15:20:36 -07004182 *
4183 * Description: Setup SCCB manager fields in this SCCB.
4184 *
4185 *---------------------------------------------------------------------*/
4186
James Bottomley 47b5d692005-04-24 02:38:05 -05004187static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004188{
4189 PSCCBMgr_tar_info currTar_Info;
4190
4191 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4192 {
4193 return;
4194 }
James Bottomley 47b5d692005-04-24 02:38:05 -05004195 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004196
4197 p_sccb->Sccb_XferState = 0x00;
4198 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4199
4200 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4201 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4202
4203 p_sccb->Sccb_SGoffset = 0;
4204 p_sccb->Sccb_XferState = F_SG_XFER;
4205 p_sccb->Sccb_XferCnt = 0x00;
4206 }
4207
4208 if (p_sccb->DataLength == 0x00)
4209
4210 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4211
4212 if (p_sccb->ControlByte & F_USE_CMD_Q)
4213 {
4214 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4215 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4216
4217 else
4218 currTar_Info->TarStatus |= TAG_Q_TRYING;
4219 }
4220
4221/* For !single SCSI device in system & device allow Disconnect
4222 or command is tag_q type then send Cmd with Disconnect Enable
4223 else send Cmd with Disconnect Disable */
4224
4225/*
James Bottomley 47b5d692005-04-24 02:38:05 -05004226 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07004227 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4228 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4229*/
4230 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4231 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4232 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4233 }
4234
4235 else {
4236
4237 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
4238 }
4239
4240 p_sccb->HostStatus = 0x00;
4241 p_sccb->TargetStatus = 0x00;
4242 p_sccb->Sccb_tag = 0x00;
4243 p_sccb->Sccb_MGRFlags = 0x00;
4244 p_sccb->Sccb_sgseg = 0x00;
4245 p_sccb->Sccb_ATC = 0x00;
4246 p_sccb->Sccb_savedATC = 0x00;
4247/*
4248 p_sccb->SccbVirtDataPtr = 0x00;
4249 p_sccb->Sccb_forwardlink = NULL;
4250 p_sccb->Sccb_backlink = NULL;
4251 */
4252 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4253 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4254 p_sccb->Sccb_scsimsg = SMNO_OP;
4255
4256}
4257
4258
Linus Torvalds1da177e2005-04-16 15:20:36 -07004259/*---------------------------------------------------------------------
4260 *
4261 * Function: Phase Decode
4262 *
4263 * Description: Determine the phase and call the appropriate function.
4264 *
4265 *---------------------------------------------------------------------*/
4266
James Bottomley 47b5d692005-04-24 02:38:05 -05004267static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004268{
4269 unsigned char phase_ref;
James Bottomley 47b5d692005-04-24 02:38:05 -05004270 void (*phase) (ULONG, UCHAR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004271
4272
4273 DISABLE_AUTO(p_port);
4274
4275 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4276
James Bottomley 47b5d692005-04-24 02:38:05 -05004277 phase = FPT_s_PhaseTbl[phase_ref];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004278
4279 (*phase)(p_port, p_card); /* Call the correct phase func */
4280}
4281
4282
4283
4284/*---------------------------------------------------------------------
4285 *
4286 * Function: Data Out Phase
4287 *
4288 * Description: Start up both the BusMaster and Xbow.
4289 *
4290 *---------------------------------------------------------------------*/
4291
James Bottomley 47b5d692005-04-24 02:38:05 -05004292static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004293{
4294
4295 PSCCB currSCCB;
4296
James Bottomley 47b5d692005-04-24 02:38:05 -05004297 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004298 if (currSCCB == NULL)
4299 {
4300 return; /* Exit if No SCCB record */
4301 }
4302
4303 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4304 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4305
4306 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4307
4308 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4309
4310 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4311
James Bottomley 47b5d692005-04-24 02:38:05 -05004312 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004313
4314 if (currSCCB->Sccb_XferCnt == 0) {
4315
4316
4317 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4318 (currSCCB->HostStatus == SCCB_COMPLETE))
4319 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4320
James Bottomley 47b5d692005-04-24 02:38:05 -05004321 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004322 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004323 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004324 }
4325}
4326
4327
4328/*---------------------------------------------------------------------
4329 *
4330 * Function: Data In Phase
4331 *
4332 * Description: Startup the BusMaster and the XBOW.
4333 *
4334 *---------------------------------------------------------------------*/
4335
James Bottomley 47b5d692005-04-24 02:38:05 -05004336static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004337{
4338
4339 PSCCB currSCCB;
4340
James Bottomley 47b5d692005-04-24 02:38:05 -05004341 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004342
4343 if (currSCCB == NULL)
4344 {
4345 return; /* Exit if No SCCB record */
4346 }
4347
4348
4349 currSCCB->Sccb_scsistat = DATA_IN_ST;
4350 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4351 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4352
4353 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4354
4355 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4356
4357 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4358
James Bottomley 47b5d692005-04-24 02:38:05 -05004359 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004360
4361 if (currSCCB->Sccb_XferCnt == 0) {
4362
4363
4364 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4365 (currSCCB->HostStatus == SCCB_COMPLETE))
4366 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4367
James Bottomley 47b5d692005-04-24 02:38:05 -05004368 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004369 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
James Bottomley 47b5d692005-04-24 02:38:05 -05004370 FPT_phaseDecode(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371
4372 }
4373}
4374
4375/*---------------------------------------------------------------------
4376 *
4377 * Function: Command Phase
4378 *
4379 * Description: Load the CDB into the automation and start it up.
4380 *
4381 *---------------------------------------------------------------------*/
4382
James Bottomley 47b5d692005-04-24 02:38:05 -05004383static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004384{
4385 PSCCB currSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004386 ULONG cdb_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 UCHAR i;
4388
James Bottomley 47b5d692005-04-24 02:38:05 -05004389 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004390
4391 if (currSCCB->OperationCode == RESET_COMMAND) {
4392
4393 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4394 currSCCB->CdbLength = SIX_BYTE_CMD;
4395 }
4396
4397 WR_HARPOON(p_port+hp_scsisig, 0x00);
4398
4399 ARAM_ACCESS(p_port);
4400
4401
4402 cdb_reg = p_port + CMD_STRT;
4403
4404 for (i=0; i < currSCCB->CdbLength; i++) {
4405
4406 if (currSCCB->OperationCode == RESET_COMMAND)
4407
4408 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4409
4410 else
4411 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4412 cdb_reg +=2;
4413 }
4414
4415 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4416 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4417
4418 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4419
4420 currSCCB->Sccb_scsistat = COMMAND_ST;
4421
4422 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4423 SGRAM_ACCESS(p_port);
4424}
4425
4426
4427/*---------------------------------------------------------------------
4428 *
4429 * Function: Status phase
4430 *
4431 * Description: Bring in the status and command complete message bytes
4432 *
4433 *---------------------------------------------------------------------*/
4434
James Bottomley 47b5d692005-04-24 02:38:05 -05004435static void FPT_phaseStatus(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004436{
4437 /* Start-up the automation to finish off this command and let the
4438 isr handle the interrupt for command complete when it comes in.
4439 We could wait here for the interrupt to be generated?
4440 */
4441
4442 WR_HARPOON(port+hp_scsisig, 0x00);
4443
4444 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4445}
4446
4447
4448/*---------------------------------------------------------------------
4449 *
4450 * Function: Phase Message Out
4451 *
4452 * Description: Send out our message (if we have one) and handle whatever
4453 * else is involed.
4454 *
4455 *---------------------------------------------------------------------*/
4456
James Bottomley 47b5d692005-04-24 02:38:05 -05004457static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004458{
4459 UCHAR message,scsiID;
4460 PSCCB currSCCB;
4461 PSCCBMgr_tar_info currTar_Info;
4462
James Bottomley 47b5d692005-04-24 02:38:05 -05004463 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004464
4465 if (currSCCB != NULL) {
4466
4467 message = currSCCB->Sccb_scsimsg;
4468 scsiID = currSCCB->TargID;
4469
4470 if (message == SMDEV_RESET)
4471 {
4472
4473
James Bottomley 47b5d692005-04-24 02:38:05 -05004474 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07004475 currTar_Info->TarSyncCtrl = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05004476 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004477
James Bottomley 47b5d692005-04-24 02:38:05 -05004478 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004479 {
4480
James Bottomley 47b5d692005-04-24 02:38:05 -05004481 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004482
4483 }
4484
James Bottomley 47b5d692005-04-24 02:38:05 -05004485 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004486 {
4487
James Bottomley 47b5d692005-04-24 02:38:05 -05004488 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004489 }
4490
4491
James Bottomley 47b5d692005-04-24 02:38:05 -05004492 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4493 FPT_SccbMgrTableInitTarget(p_card,scsiID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004494 }
4495 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4496 {
4497 currSCCB->HostStatus = SCCB_COMPLETE;
James Bottomley 47b5d692005-04-24 02:38:05 -05004498 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004499 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004500 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4501 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004502 }
4503
4504 }
4505
4506 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4507 {
4508
4509
4510 if(message == SMNO_OP)
4511 {
4512 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4513
James Bottomley 47b5d692005-04-24 02:38:05 -05004514 FPT_ssel(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004515 return;
4516 }
4517 }
4518 else
4519 {
4520
4521
4522 if (message == SMABORT)
4523
James Bottomley 47b5d692005-04-24 02:38:05 -05004524 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525 }
4526
4527 }
4528 else
4529 {
4530 message = SMABORT;
4531 }
4532
4533 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4534
4535
4536 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4537
4538 WR_HARPOON(port+hp_scsidata_0,message);
4539
4540 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4541
4542 ACCEPT_MSG(port);
4543
4544 WR_HARPOON(port+hp_portctrl_0, 0x00);
4545
4546 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4547 (message == SMABORT_TAG) )
4548 {
4549
4550 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4551
4552 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4553 {
4554 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4555
4556 if (currSCCB != NULL)
4557 {
4558
James Bottomley 47b5d692005-04-24 02:38:05 -05004559 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4560 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4561 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004562 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004563 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004564
James Bottomley 47b5d692005-04-24 02:38:05 -05004565 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004566 }
4567
4568 else
4569 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004570 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004571 }
4572 }
4573
4574 else
4575 {
4576
James Bottomley 47b5d692005-04-24 02:38:05 -05004577 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004578 }
4579 }
4580
4581 else
4582 {
4583
4584 if(message == SMPARITY)
4585 {
4586 currSCCB->Sccb_scsimsg = SMNO_OP;
4587 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4588 }
4589 else
4590 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004591 FPT_sxfrp(port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004592 }
4593 }
4594}
4595
4596
4597/*---------------------------------------------------------------------
4598 *
4599 * Function: Message In phase
4600 *
4601 * Description: Bring in the message and determine what to do with it.
4602 *
4603 *---------------------------------------------------------------------*/
4604
James Bottomley 47b5d692005-04-24 02:38:05 -05004605static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004606{
4607 UCHAR message;
4608 PSCCB currSCCB;
4609
James Bottomley 47b5d692005-04-24 02:38:05 -05004610 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004611
James Bottomley 47b5d692005-04-24 02:38:05 -05004612 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004613 {
4614
James Bottomley 47b5d692005-04-24 02:38:05 -05004615 FPT_phaseChkFifo(port, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004616 }
4617
4618 message = RD_HARPOON(port+hp_scsidata_0);
4619 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4620 {
4621
4622 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4623
4624 }
4625
4626 else
4627 {
4628
James Bottomley 47b5d692005-04-24 02:38:05 -05004629 message = FPT_sfm(port,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004630 if (message)
4631 {
4632
4633
James Bottomley 47b5d692005-04-24 02:38:05 -05004634 FPT_sdecm(message,port,p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004635
4636 }
4637 else
4638 {
4639 if(currSCCB->Sccb_scsimsg != SMPARITY)
4640 ACCEPT_MSG(port);
4641 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4642 }
4643 }
4644
4645}
4646
4647
4648/*---------------------------------------------------------------------
4649 *
4650 * Function: Illegal phase
4651 *
4652 * Description: Target switched to some illegal phase, so all we can do
4653 * is report an error back to the host (if that is possible)
4654 * and send an ABORT message to the misbehaving target.
4655 *
4656 *---------------------------------------------------------------------*/
4657
James Bottomley 47b5d692005-04-24 02:38:05 -05004658static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004659{
4660 PSCCB currSCCB;
4661
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 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4665 if (currSCCB != NULL) {
4666
4667 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4668 currSCCB->Sccb_scsistat = ABORT_ST;
4669 currSCCB->Sccb_scsimsg = SMABORT;
4670 }
4671
4672 ACCEPT_MSG_ATN(port);
4673}
4674
4675
4676
4677/*---------------------------------------------------------------------
4678 *
4679 * Function: Phase Check FIFO
4680 *
4681 * Description: Make sure data has been flushed from both FIFOs and abort
4682 * the operations if necessary.
4683 *
4684 *---------------------------------------------------------------------*/
4685
James Bottomley 47b5d692005-04-24 02:38:05 -05004686static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004687{
4688 ULONG xfercnt;
4689 PSCCB currSCCB;
4690
James Bottomley 47b5d692005-04-24 02:38:05 -05004691 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004692
4693 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4694 {
4695
4696 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4697 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4698
4699
4700 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4701 {
4702 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4703
4704 currSCCB->Sccb_XferCnt = 0;
4705
4706 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4707 (currSCCB->HostStatus == SCCB_COMPLETE))
4708 {
4709 currSCCB->HostStatus = SCCB_PARITY_ERR;
4710 WRW_HARPOON((port+hp_intstat), PARITY);
4711 }
4712
James Bottomley 47b5d692005-04-24 02:38:05 -05004713 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004714
James Bottomley 47b5d692005-04-24 02:38:05 -05004715 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004716
4717 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4718 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4719
4720 }
4721 } /*End Data In specific code. */
4722
4723
4724
Linus Torvalds1da177e2005-04-16 15:20:36 -07004725 GET_XFER_CNT(port,xfercnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004726
4727
4728 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4729
4730
4731 WR_HARPOON(port+hp_portctrl_0, 0x00);
4732
4733 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4734
4735 currSCCB->Sccb_XferCnt = xfercnt;
4736
4737 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4738 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4739
4740 currSCCB->HostStatus = SCCB_PARITY_ERR;
4741 WRW_HARPOON((port+hp_intstat), PARITY);
4742 }
4743
4744
James Bottomley 47b5d692005-04-24 02:38:05 -05004745 FPT_hostDataXferAbort(port,p_card,currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004746
4747
4748 WR_HARPOON(port+hp_fifowrite, 0x00);
4749 WR_HARPOON(port+hp_fiforead, 0x00);
4750 WR_HARPOON(port+hp_xferstat, 0x00);
4751
4752 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4753}
4754
4755
4756/*---------------------------------------------------------------------
4757 *
4758 * Function: Phase Bus Free
4759 *
4760 * Description: We just went bus free so figure out if it was
4761 * because of command complete or from a disconnect.
4762 *
4763 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004764static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004765{
4766 PSCCB currSCCB;
4767
James Bottomley 47b5d692005-04-24 02:38:05 -05004768 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004769
4770 if (currSCCB != NULL)
4771 {
4772
4773 DISABLE_AUTO(port);
4774
4775
4776 if (currSCCB->OperationCode == RESET_COMMAND)
4777 {
4778
James Bottomley 47b5d692005-04-24 02:38:05 -05004779 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4780 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4781 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004782 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004784
James Bottomley 47b5d692005-04-24 02:38:05 -05004785 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004786
James Bottomley 47b5d692005-04-24 02:38:05 -05004787 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004788
4789 }
4790
4791 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4792 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004793 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Linus Torvalds1da177e2005-04-16 15:20:36 -07004794 (UCHAR)SYNC_SUPPORTED;
James Bottomley 47b5d692005-04-24 02:38:05 -05004795 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004796 }
4797
4798 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4799 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4801 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07004802 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4803
James Bottomley 47b5d692005-04-24 02:38:05 -05004804 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004805 }
4806
Linus Torvalds1da177e2005-04-16 15:20:36 -07004807 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4808 {
4809 /* Make sure this is not a phony BUS_FREE. If we were
4810 reselected or if BUSY is NOT on then this is a
4811 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4812
4813 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4814 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4815 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004816 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4817 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004818 }
4819
4820 else
4821 {
4822 return;
4823 }
4824 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004825
4826 else
4827 {
4828
4829 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4830
4831 if (!currSCCB->HostStatus)
4832 {
4833 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4834 }
4835
James Bottomley 47b5d692005-04-24 02:38:05 -05004836 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4837 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4838 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004839 else
James Bottomley 47b5d692005-04-24 02:38:05 -05004840 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004841
James Bottomley 47b5d692005-04-24 02:38:05 -05004842 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004843 return;
4844 }
4845
4846
James Bottomley 47b5d692005-04-24 02:38:05 -05004847 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004848
4849 } /*end if !=null */
4850}
4851
4852
4853
4854
Linus Torvalds1da177e2005-04-16 15:20:36 -07004855/*---------------------------------------------------------------------
4856 *
4857 * Function: Auto Load Default Map
4858 *
4859 * Description: Load the Automation RAM with the defualt map values.
4860 *
4861 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05004862static void FPT_autoLoadDefaultMap(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004863{
Linus Torvalds1da177e2005-04-16 15:20:36 -07004864 ULONG map_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004865
4866 ARAM_ACCESS(p_port);
4867 map_addr = p_port + hp_aramBase;
4868
4869 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4888 map_addr +=2;
4889 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4904 map_addr +=2; /*This means AYNC DATA IN */
4905 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4910 map_addr +=2;
4911 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4912 map_addr +=2;
4913 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4920 map_addr +=2;
4921 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4922 map_addr +=2;
4923 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4924 map_addr +=2;
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4926 map_addr +=2;
4927 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4928 map_addr +=2;
4929 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4930 map_addr +=2;
4931 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4932 map_addr +=2;
4933 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4934 map_addr +=2;
4935 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4936 map_addr +=2;
4937 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4938 map_addr +=2;
4939 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4940 map_addr +=2;
4941
4942 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4943 map_addr +=2;
4944 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4945 map_addr +=2;
4946 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4947 map_addr +=2;
4948 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4949 map_addr +=2; /* DIDN'T GET ONE */
4950 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4951 map_addr +=2;
4952 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4953 map_addr +=2;
4954 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4955
4956
4957
4958 SGRAM_ACCESS(p_port);
4959}
4960
4961/*---------------------------------------------------------------------
4962 *
4963 * Function: Auto Command Complete
4964 *
4965 * Description: Post command back to host and find another command
4966 * to execute.
4967 *
4968 *---------------------------------------------------------------------*/
4969
James Bottomley 47b5d692005-04-24 02:38:05 -05004970static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004971{
4972 PSCCB currSCCB;
4973 UCHAR status_byte;
4974
James Bottomley 47b5d692005-04-24 02:38:05 -05004975 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004976
4977 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4978
James Bottomley 47b5d692005-04-24 02:38:05 -05004979 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004980
4981 if (status_byte != SSGOOD) {
4982
4983 if (status_byte == SSQ_FULL) {
4984
4985
James Bottomley 47b5d692005-04-24 02:38:05 -05004986 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4987 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07004988 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004989 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4990 if(FPT_BL_Card[p_card].discQCount != 0)
4991 FPT_BL_Card[p_card].discQCount--;
4992 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 -07004993 }
4994 else
4995 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004996 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004997 if(currSCCB->Sccb_tag)
4998 {
James Bottomley 47b5d692005-04-24 02:38:05 -05004999 if(FPT_BL_Card[p_card].discQCount != 0)
5000 FPT_BL_Card[p_card].discQCount--;
5001 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005002 }else
5003 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005004 if(FPT_BL_Card[p_card].discQCount != 0)
5005 FPT_BL_Card[p_card].discQCount--;
5006 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005007 }
5008 }
5009
5010 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
5011
James Bottomley 47b5d692005-04-24 02:38:05 -05005012 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005013
5014 return;
5015 }
5016
5017 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5018 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005019 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
Linus Torvalds1da177e2005-04-16 15:20:36 -07005020 (UCHAR)SYNC_SUPPORTED;
5021
James Bottomley 47b5d692005-04-24 02:38:05 -05005022 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5023 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005024
James Bottomley 47b5d692005-04-24 02:38:05 -05005025 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5026 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005027 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005028 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5029 if(FPT_BL_Card[p_card].discQCount != 0)
5030 FPT_BL_Card[p_card].discQCount--;
5031 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 -07005032 }
5033 else
5034 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005036 if(currSCCB->Sccb_tag)
5037 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005038 if(FPT_BL_Card[p_card].discQCount != 0)
5039 FPT_BL_Card[p_card].discQCount--;
5040 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005041 }else
5042 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005043 if(FPT_BL_Card[p_card].discQCount != 0)
5044 FPT_BL_Card[p_card].discQCount--;
5045 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005046 }
5047 }
5048 return;
5049
5050 }
5051
5052 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5053 {
5054
James Bottomley 47b5d692005-04-24 02:38:05 -05005055 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5056 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005057 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5058
James Bottomley 47b5d692005-04-24 02:38:05 -05005059 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5060 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005061
James Bottomley 47b5d692005-04-24 02:38:05 -05005062 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5063 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005064 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005065 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5066 if(FPT_BL_Card[p_card].discQCount != 0)
5067 FPT_BL_Card[p_card].discQCount--;
5068 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 -07005069 }
5070 else
5071 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005072 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005073 if(currSCCB->Sccb_tag)
5074 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005075 if(FPT_BL_Card[p_card].discQCount != 0)
5076 FPT_BL_Card[p_card].discQCount--;
5077 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005078 }else
5079 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005080 if(FPT_BL_Card[p_card].discQCount != 0)
5081 FPT_BL_Card[p_card].discQCount--;
5082 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005083 }
5084 }
5085 return;
5086
5087 }
5088
5089 if (status_byte == SSCHECK)
5090 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005091 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005092 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005093 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005094 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005096 }
James Bottomley 47b5d692005-04-24 02:38:05 -05005097 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005098 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005099 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005100 }
5101 }
5102 }
5103
5104 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5105
5106 currSCCB->SccbStatus = SCCB_ERROR;
5107 currSCCB->TargetStatus = status_byte;
5108
5109 if (status_byte == SSCHECK) {
5110
James Bottomley 47b5d692005-04-24 02:38:05 -05005111 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5112 = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005113
5114
Linus Torvalds1da177e2005-04-16 15:20:36 -07005115 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5116
5117 if (currSCCB->RequestSenseLength == 0)
5118 currSCCB->RequestSenseLength = 14;
5119
James Bottomley 47b5d692005-04-24 02:38:05 -05005120 FPT_ssenss(&FPT_BL_Card[p_card]);
5121 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005122
James Bottomley 47b5d692005-04-24 02:38:05 -05005123 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5124 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005125 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005126 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5127 if(FPT_BL_Card[p_card].discQCount != 0)
5128 FPT_BL_Card[p_card].discQCount--;
5129 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 -07005130 }
5131 else
5132 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005133 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005134 if(currSCCB->Sccb_tag)
5135 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005136 if(FPT_BL_Card[p_card].discQCount != 0)
5137 FPT_BL_Card[p_card].discQCount--;
5138 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005139 }else
5140 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005141 if(FPT_BL_Card[p_card].discQCount != 0)
5142 FPT_BL_Card[p_card].discQCount--;
5143 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005144 }
5145 }
5146 return;
5147 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005148 }
5149 }
5150 }
5151
5152
James Bottomley 47b5d692005-04-24 02:38:05 -05005153 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5154 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5155 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005156 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005157 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005158
5159
James Bottomley 47b5d692005-04-24 02:38:05 -05005160 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005161}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005162
5163#define SHORT_WAIT 0x0000000F
5164#define LONG_WAIT 0x0000FFFFL
5165
Linus Torvalds1da177e2005-04-16 15:20:36 -07005166
5167/*---------------------------------------------------------------------
5168 *
5169 * Function: Data Transfer Processor
5170 *
5171 * Description: This routine performs two tasks.
5172 * (1) Start data transfer by calling HOST_DATA_XFER_START
5173 * function. Once data transfer is started, (2) Depends
5174 * on the type of data transfer mode Scatter/Gather mode
5175 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5176 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5177 * data transfer done. In Scatter/Gather mode, this routine
5178 * checks bus master command complete and dual rank busy
5179 * bit to keep chaining SC transfer command. Similarly,
5180 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5181 * (F_HOST_XFER_ACT bit) for data transfer done.
5182 *
5183 *---------------------------------------------------------------------*/
5184
James Bottomley 47b5d692005-04-24 02:38:05 -05005185static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005186{
5187 PSCCB currSCCB;
5188
5189 currSCCB = pCurrCard->currentSCCB;
5190
5191 if (currSCCB->Sccb_XferState & F_SG_XFER)
5192 {
5193 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5194
5195 {
5196 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
5197 currSCCB->Sccb_SGoffset = 0x00;
5198 }
5199 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5200
James Bottomley 47b5d692005-04-24 02:38:05 -05005201 FPT_busMstrSGDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005202 }
5203
5204 else
5205 {
5206 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5207 {
5208 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5209
James Bottomley 47b5d692005-04-24 02:38:05 -05005210 FPT_busMstrDataXferStart(port, currSCCB);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005211 }
5212 }
5213}
5214
5215
5216/*---------------------------------------------------------------------
5217 *
5218 * Function: BusMaster Scatter Gather Data Transfer Start
5219 *
5220 * Description:
5221 *
5222 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005223static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005224{
5225 ULONG count,addr,tmpSGCnt;
5226 UINT sg_index;
5227 UCHAR sg_count, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005228 ULONG reg_offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005229
5230
5231 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5232
5233 count = ((ULONG) HOST_RD_CMD)<<24;
5234 }
5235
5236 else {
5237 count = ((ULONG) HOST_WRT_CMD)<<24;
5238 }
5239
5240 sg_count = 0;
5241 tmpSGCnt = 0;
5242 sg_index = pcurrSCCB->Sccb_sgseg;
5243 reg_offset = hp_aramBase;
5244
5245
5246 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5247
5248
5249 WR_HARPOON(p_port+hp_page_ctrl, i);
5250
5251 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
5252 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5253
Linus Torvalds1da177e2005-04-16 15:20:36 -07005254 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5255 (sg_index * 2));
5256
5257 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5258 (sg_index * 2));
5259
5260 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5261 ((sg_index * 2) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005262
5263
5264 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5265
5266 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5267 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5268
5269 tmpSGCnt = count & 0x00FFFFFFL;
5270 }
5271
5272 WR_HARP32(p_port,reg_offset,addr);
5273 reg_offset +=4;
5274
5275 WR_HARP32(p_port,reg_offset,count);
5276 reg_offset +=4;
5277
5278 count &= 0xFF000000L;
5279 sg_index++;
5280 sg_count++;
5281
5282 } /*End While */
5283
5284 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5285
5286 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5287
5288 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5289
5290 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5291
5292
5293 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5294 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5295 }
5296
5297 else {
5298
5299
5300 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5301 (tmpSGCnt & 0x000000001))
5302 {
5303
5304 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5305 tmpSGCnt--;
5306 }
5307
5308
5309 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5310
5311 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5312 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5313 }
5314
5315
5316 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
5317
5318}
5319
5320
5321/*---------------------------------------------------------------------
5322 *
5323 * Function: BusMaster Data Transfer Start
5324 *
5325 * Description:
5326 *
5327 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005328static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005329{
5330 ULONG addr,count;
5331
5332 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5333
5334 count = pcurrSCCB->Sccb_XferCnt;
5335
5336 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5337 }
5338
5339 else {
5340 addr = pcurrSCCB->SensePointer;
5341 count = pcurrSCCB->RequestSenseLength;
5342
5343 }
5344
Linus Torvalds1da177e2005-04-16 15:20:36 -07005345 HP_SETUP_ADDR_CNT(p_port,addr,count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005346
5347
5348 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5349
5350 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5351 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5352
5353 WR_HARPOON(p_port+hp_xfer_cmd,
5354 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5355 }
5356
5357 else {
5358
5359 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5360 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5361
5362 WR_HARPOON(p_port+hp_xfer_cmd,
5363 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5364
5365 }
5366}
5367
5368
5369/*---------------------------------------------------------------------
5370 *
5371 * Function: BusMaster Timeout Handler
5372 *
5373 * Description: This function is called after a bus master command busy time
5374 * out is detected. This routines issue halt state machine
5375 * with a software time out for command busy. If command busy
5376 * is still asserted at the end of the time out, it issues
5377 * hard abort with another software time out. It hard abort
5378 * command busy is also time out, it'll just give up.
5379 *
5380 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005381static UCHAR FPT_busMstrTimeOut(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005382{
5383 ULONG timeout;
5384
5385 timeout = LONG_WAIT;
5386
5387 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5388
5389 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5390
5391
5392
5393 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5394 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5395
5396 timeout = LONG_WAIT;
5397 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5398 }
5399
5400 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5401
5402 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
James Bottomley 47b5d692005-04-24 02:38:05 -05005403 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005404 }
5405
5406 else {
James Bottomley 47b5d692005-04-24 02:38:05 -05005407 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005408 }
5409}
5410
5411
5412/*---------------------------------------------------------------------
5413 *
5414 * Function: Host Data Transfer Abort
5415 *
5416 * Description: Abort any in progress transfer.
5417 *
5418 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005419static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005420{
5421
5422 ULONG timeout;
5423 ULONG remain_cnt;
5424 UINT sg_ptr;
5425
James Bottomley 47b5d692005-04-24 02:38:05 -05005426 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005427
5428 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5429
5430
5431 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5432
5433 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5434 timeout = LONG_WAIT;
5435
5436 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5437
5438 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5439
5440 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5441
James Bottomley 47b5d692005-04-24 02:38:05 -05005442 if (FPT_busMstrTimeOut(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07005443
5444 if (pCurrSCCB->HostStatus == 0x00)
5445
5446 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5447
5448 }
5449
5450 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5451
5452 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5453
5454 if (pCurrSCCB->HostStatus == 0x00)
5455
5456 {
5457 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005458 }
5459 }
5460 }
5461 }
5462
5463 else if (pCurrSCCB->Sccb_XferCnt) {
5464
5465 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5466
5467
5468 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5469 ~SCATTER_EN));
5470
5471 WR_HARPOON(port+hp_sg_addr,0x00);
5472
5473 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5474
5475 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5476
5477 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5478 }
5479
5480 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5481
5482 while (remain_cnt < 0x01000000L) {
5483
5484 sg_ptr--;
5485
Linus Torvalds1da177e2005-04-16 15:20:36 -07005486 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5487 DataPointer) + (sg_ptr * 2)))) {
5488
5489 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5490 DataPointer) + (sg_ptr * 2)));
5491 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07005492
5493 else {
5494
5495 break;
5496 }
5497 }
5498
5499
5500
5501 if (remain_cnt < 0x01000000L) {
5502
5503
5504 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5505
5506 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5507
5508
5509 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5510 && (remain_cnt == 0))
5511
5512 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5513 }
5514
5515 else {
5516
5517
5518 if (pCurrSCCB->HostStatus == 0x00) {
5519
5520 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5521 }
5522 }
5523 }
5524
5525
5526 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5527
5528
5529 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5530
James Bottomley 47b5d692005-04-24 02:38:05 -05005531 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005532 }
5533
5534 else {
5535
5536 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5537
5538 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5539
5540 if (pCurrSCCB->HostStatus == 0x00) {
5541
5542 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005543 }
5544 }
5545 }
5546
5547 }
5548 }
5549
5550 else {
5551
5552
5553 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5554
5555 timeout = SHORT_WAIT;
5556
5557 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5558 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5559 timeout--) {}
5560 }
5561
5562 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5563
5564 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5565 FLUSH_XFER_CNTR));
5566
5567 timeout = LONG_WAIT;
5568
5569 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5570 timeout--) {}
5571
5572 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5573 ~FLUSH_XFER_CNTR));
5574
5575
5576 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5577
5578 if (pCurrSCCB->HostStatus == 0x00) {
5579
5580 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5581 }
5582
James Bottomley 47b5d692005-04-24 02:38:05 -05005583 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005584 }
5585 }
5586
5587 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5588
5589 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5590
5591 if (pCurrSCCB->HostStatus == 0x00) {
5592
5593 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005594 }
5595 }
5596 }
5597 }
5598
5599 }
5600
5601 else {
5602
5603
5604 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5605
5606 timeout = LONG_WAIT;
5607
5608 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5609
5610 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5611
5612 if (pCurrSCCB->HostStatus == 0x00) {
5613
5614 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5615 }
5616
James Bottomley 47b5d692005-04-24 02:38:05 -05005617 FPT_busMstrTimeOut(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005618 }
5619 }
5620
5621
5622 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5623
5624 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5625
5626 if (pCurrSCCB->HostStatus == 0x00) {
5627
5628 pCurrSCCB->HostStatus = SCCB_BM_ERR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005629 }
5630 }
5631
5632 }
5633
5634 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5635
5636 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5637 ~SCATTER_EN));
5638
5639 WR_HARPOON(port+hp_sg_addr,0x00);
5640
5641 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5642
5643 pCurrSCCB->Sccb_SGoffset = 0x00;
5644
5645
5646 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5647 pCurrSCCB->DataLength) {
5648
5649 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5650
5651 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5652
5653 }
5654 }
5655
5656 else {
5657
5658 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5659
5660 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5661 }
5662 }
5663
5664 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5665}
5666
5667
5668
5669/*---------------------------------------------------------------------
5670 *
5671 * Function: Host Data Transfer Restart
5672 *
5673 * Description: Reset the available count due to a restore data
5674 * pointers message.
5675 *
5676 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05005677static void FPT_hostDataXferRestart(PSCCB currSCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005678{
5679 ULONG data_count;
5680 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005681 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005682
5683 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5684
5685 currSCCB->Sccb_XferCnt = 0;
5686
5687 sg_index = 0xffff; /*Index by long words into sg list. */
5688 data_count = 0; /*Running count of SG xfer counts. */
5689
Linus Torvalds1da177e2005-04-16 15:20:36 -07005690 sg_ptr = (ULONG *)currSCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005691
5692 while (data_count < currSCCB->Sccb_ATC) {
5693
5694 sg_index++;
5695 data_count += *(sg_ptr+(sg_index * 2));
5696 }
5697
5698 if (data_count == currSCCB->Sccb_ATC) {
5699
5700 currSCCB->Sccb_SGoffset = 0;
5701 sg_index++;
5702 }
5703
5704 else {
5705 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5706 }
5707
5708 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5709 }
5710
5711 else {
5712 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5713 }
5714}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005715
5716
5717
Linus Torvalds1da177e2005-04-16 15:20:36 -07005718/*---------------------------------------------------------------------
5719 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005720 * Function: FPT_scini
Linus Torvalds1da177e2005-04-16 15:20:36 -07005721 *
5722 * Description: Setup all data structures necessary for SCAM selection.
5723 *
5724 *---------------------------------------------------------------------*/
5725
James Bottomley 47b5d692005-04-24 02:38:05 -05005726static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005727{
5728
Linus Torvalds1da177e2005-04-16 15:20:36 -07005729 UCHAR loser,assigned_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005730 ULONG p_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005731
5732 UCHAR i,k,ScamFlg ;
5733 PSCCBcard currCard;
5734 PNVRamInfo pCurrNvRam;
5735
James Bottomley 47b5d692005-04-24 02:38:05 -05005736 currCard = &FPT_BL_Card[p_card];
Linus Torvalds1da177e2005-04-16 15:20:36 -07005737 p_port = currCard->ioPort;
5738 pCurrNvRam = currCard->pNvRamInfo;
5739
5740
5741 if(pCurrNvRam){
5742 ScamFlg = pCurrNvRam->niScamConf;
5743 i = pCurrNvRam->niSysConf;
5744 }
5745 else{
James Bottomley 47b5d692005-04-24 02:38:05 -05005746 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5747 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07005748 }
5749 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5750 return;
5751
James Bottomley 47b5d692005-04-24 02:38:05 -05005752 FPT_inisci(p_card,p_port, p_our_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005753
5754 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5755 too slow to return to SCAM selection */
5756
5757 /* if (p_power_up)
James Bottomley 47b5d692005-04-24 02:38:05 -05005758 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005759 else
James Bottomley 47b5d692005-04-24 02:38:05 -05005760 FPT_Wait(p_port, TO_250ms); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005761
James Bottomley 47b5d692005-04-24 02:38:05 -05005762 FPT_Wait1Second(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005763
5764 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5765 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005766 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005767
James Bottomley 47b5d692005-04-24 02:38:05 -05005768 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005769
5770 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005771 FPT_scxferc(p_port,SYNC_PTRN);
5772 FPT_scxferc(p_port,DOM_MSTR);
5773 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005774 } while ( loser == 0xFF );
5775
James Bottomley 47b5d692005-04-24 02:38:05 -05005776 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005777
5778 if ((p_power_up) && (!loser))
5779 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005780 FPT_sresb(p_port,p_card);
5781 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005782
James Bottomley 47b5d692005-04-24 02:38:05 -05005783 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005784
James Bottomley 47b5d692005-04-24 02:38:05 -05005785 FPT_scsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005786
5787 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005788 FPT_scxferc(p_port, SYNC_PTRN);
5789 FPT_scxferc(p_port, DOM_MSTR);
5790 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
Linus Torvalds1da177e2005-04-16 15:20:36 -07005791 id_string[0]);
5792 } while ( loser == 0xFF );
5793
James Bottomley 47b5d692005-04-24 02:38:05 -05005794 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005795 }
5796 }
5797
5798 else
5799 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005800 loser = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005801 }
5802
5803
5804 if (!loser)
5805 {
5806
James Bottomley 47b5d692005-04-24 02:38:05 -05005807 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005808
5809
5810 if (ScamFlg & SCAM_ENABLED)
5811 {
5812
5813 for (i=0; i < MAX_SCSI_TAR; i++)
5814 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005815 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5816 (FPT_scamInfo[i].state == ID_UNUSED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005817 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005818 if (FPT_scsell(p_port,i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005819 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005820 FPT_scamInfo[i].state = LEGACY;
5821 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5822 (FPT_scamInfo[i].id_string[1] != 0xFA))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005823 {
5824
James Bottomley 47b5d692005-04-24 02:38:05 -05005825 FPT_scamInfo[i].id_string[0] = 0xFF;
5826 FPT_scamInfo[i].id_string[1] = 0xFA;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005827 if(pCurrNvRam == NULL)
5828 currCard->globalFlags |= F_UPDATE_EEPROM;
5829 }
5830 }
5831 }
5832 }
5833
James Bottomley 47b5d692005-04-24 02:38:05 -05005834 FPT_sresb(p_port,p_card);
5835 FPT_Wait1Second(p_port);
5836 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5837 FPT_scsel(p_port);
5838 FPT_scasid(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005839 }
5840
Linus Torvalds1da177e2005-04-16 15:20:36 -07005841 }
5842
5843 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5844 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005845 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5846 assigned_id = 0;
5847 FPT_scwtsel(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005848
5849 do {
James Bottomley 47b5d692005-04-24 02:38:05 -05005850 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005851
James Bottomley 47b5d692005-04-24 02:38:05 -05005852 i = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005853 if (i == ASSIGN_ID)
5854 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005855 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005856 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005857 i = FPT_scxferc(p_port,0x00);
5858 if (FPT_scvalq(i))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005859 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005860 k = FPT_scxferc(p_port,0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005861
James Bottomley 47b5d692005-04-24 02:38:05 -05005862 if (FPT_scvalq(k))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005863 {
5864 currCard->ourId =
5865 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
James Bottomley 47b5d692005-04-24 02:38:05 -05005866 FPT_inisci(p_card, p_port, p_our_id);
5867 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5868 FPT_scamInfo[currCard->ourId].id_string[0]
Linus Torvalds1da177e2005-04-16 15:20:36 -07005869 = SLV_TYPE_CODE0;
James Bottomley 47b5d692005-04-24 02:38:05 -05005870 assigned_id = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005871 }
5872 }
5873 }
5874 }
5875
5876 else if (i == SET_P_FLAG)
5877 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005878 if (!(FPT_scsendi(p_port,
5879 &FPT_scamInfo[p_our_id].id_string[0])))
5880 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005881 }
5882 }while (!assigned_id);
5883
James Bottomley 47b5d692005-04-24 02:38:05 -05005884 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
Linus Torvalds1da177e2005-04-16 15:20:36 -07005885 }
5886
Linus Torvalds1da177e2005-04-16 15:20:36 -07005887 if (ScamFlg & SCAM_ENABLED)
5888 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005889 FPT_scbusf(p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005890 if (currCard->globalFlags & F_UPDATE_EEPROM)
5891 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005892 FPT_scsavdi(p_card, p_port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005893 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5894 }
5895 }
5896
5897
Linus Torvalds1da177e2005-04-16 15:20:36 -07005898/*
5899 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5900 {
James Bottomley 47b5d692005-04-24 02:38:05 -05005901 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5902 (FPT_scamInfo[i].state == LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07005903 k++;
5904 }
5905
5906 if (k==2)
5907 currCard->globalFlags |= F_SINGLE_DEVICE;
5908 else
5909 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5910*/
5911}
5912
5913
5914/*---------------------------------------------------------------------
5915 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005916 * Function: FPT_scarb
Linus Torvalds1da177e2005-04-16 15:20:36 -07005917 *
5918 * Description: Gain control of the bus and wait SCAM select time (250ms)
5919 *
5920 *---------------------------------------------------------------------*/
5921
James Bottomley 47b5d692005-04-24 02:38:05 -05005922static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005923{
5924 if (p_sel_type == INIT_SELTD)
5925 {
5926
5927 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5928
5929
5930 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
James Bottomley 47b5d692005-04-24 02:38:05 -05005931 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005932
5933 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
James Bottomley 47b5d692005-04-24 02:38:05 -05005934 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005935
5936 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5937
5938 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5939
5940 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5941 ~SCSI_BSY));
James Bottomley 47b5d692005-04-24 02:38:05 -05005942 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005943 }
5944
5945
5946 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5947
5948 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5949
5950 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5951 ~(SCSI_BSY | SCSI_SEL)));
James Bottomley 47b5d692005-04-24 02:38:05 -05005952 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005953 }
5954 }
5955
5956
5957 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5958 & ~ACTdeassert));
5959 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5960 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005961 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005962 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5963
5964 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5965
5966 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5967 & ~SCSI_BSY));
5968
James Bottomley 47b5d692005-04-24 02:38:05 -05005969 FPT_Wait(p_port,TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005970
James Bottomley 47b5d692005-04-24 02:38:05 -05005971 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005972}
5973
5974
5975/*---------------------------------------------------------------------
5976 *
James Bottomley 47b5d692005-04-24 02:38:05 -05005977 * Function: FPT_scbusf
Linus Torvalds1da177e2005-04-16 15:20:36 -07005978 *
5979 * Description: Release the SCSI bus and disable SCAM selection.
5980 *
5981 *---------------------------------------------------------------------*/
5982
James Bottomley 47b5d692005-04-24 02:38:05 -05005983static void FPT_scbusf(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005984{
5985 WR_HARPOON(p_port+hp_page_ctrl,
5986 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5987
5988
5989 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5990
5991 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5992 & ~SCSI_BUS_EN));
5993
5994 WR_HARPOON(p_port+hp_scsisig, 0x00);
5995
5996
5997 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5998 & ~SCAM_EN));
5999
6000 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
6001 | ACTdeassert));
6002
Linus Torvalds1da177e2005-04-16 15:20:36 -07006003 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006004
6005 WR_HARPOON(p_port+hp_page_ctrl,
6006 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6007}
6008
6009
6010
6011/*---------------------------------------------------------------------
6012 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006013 * Function: FPT_scasid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006014 *
6015 * Description: Assign an ID to all the SCAM devices.
6016 *
6017 *---------------------------------------------------------------------*/
6018
James Bottomley 47b5d692005-04-24 02:38:05 -05006019static void FPT_scasid(UCHAR p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006020{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006021 UCHAR temp_id_string[ID_STRING_LENGTH];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006022
6023 UCHAR i,k,scam_id;
6024 UCHAR crcBytes[3];
6025 PNVRamInfo pCurrNvRam;
6026 ushort_ptr pCrcBytes;
6027
James Bottomley 47b5d692005-04-24 02:38:05 -05006028 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006029
James Bottomley 47b5d692005-04-24 02:38:05 -05006030 i=0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006031
6032 while (!i)
6033 {
6034
6035 for (k=0; k < ID_STRING_LENGTH; k++)
6036 {
6037 temp_id_string[k] = (UCHAR) 0x00;
6038 }
6039
James Bottomley 47b5d692005-04-24 02:38:05 -05006040 FPT_scxferc(p_port,SYNC_PTRN);
6041 FPT_scxferc(p_port,ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006042
James Bottomley 47b5d692005-04-24 02:38:05 -05006043 if (!(FPT_sciso(p_port,&temp_id_string[0])))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006044 {
6045 if(pCurrNvRam){
6046 pCrcBytes = (ushort_ptr)&crcBytes[0];
James Bottomley 47b5d692005-04-24 02:38:05 -05006047 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6048 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006049 temp_id_string[1] = crcBytes[2];
6050 temp_id_string[2] = crcBytes[0];
6051 temp_id_string[3] = crcBytes[1];
6052 for(k = 4; k < ID_STRING_LENGTH; k++)
6053 temp_id_string[k] = (UCHAR) 0x00;
6054 }
James Bottomley 47b5d692005-04-24 02:38:05 -05006055 i = FPT_scmachid(p_card,temp_id_string);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006056
6057 if (i == CLR_PRIORITY)
6058 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006059 FPT_scxferc(p_port,MISC_CODE);
6060 FPT_scxferc(p_port,CLR_P_FLAG);
6061 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006062 }
6063
6064 else if (i != NO_ID_AVAIL)
6065 {
6066 if (i < 8 )
James Bottomley 47b5d692005-04-24 02:38:05 -05006067 FPT_scxferc(p_port,ID_0_7);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006068 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006069 FPT_scxferc(p_port,ID_8_F);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006070
6071 scam_id = (i & (UCHAR) 0x07);
6072
6073
6074 for (k=1; k < 0x08; k <<= 1)
6075 if (!( k & i ))
6076 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6077
James Bottomley 47b5d692005-04-24 02:38:05 -05006078 FPT_scxferc(p_port,scam_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006079
James Bottomley 47b5d692005-04-24 02:38:05 -05006080 i = 0; /*Not the last ID yet. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006081 }
6082 }
6083
6084 else
6085 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006086 i = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006087 }
6088
6089 } /*End while */
6090
James Bottomley 47b5d692005-04-24 02:38:05 -05006091 FPT_scxferc(p_port,SYNC_PTRN);
6092 FPT_scxferc(p_port,CFG_CMPLT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006093}
6094
6095
6096
6097
6098
6099/*---------------------------------------------------------------------
6100 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006101 * Function: FPT_scsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006102 *
6103 * Description: Select all the SCAM devices.
6104 *
6105 *---------------------------------------------------------------------*/
6106
James Bottomley 47b5d692005-04-24 02:38:05 -05006107static void FPT_scsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006108{
6109
6110 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
James Bottomley 47b5d692005-04-24 02:38:05 -05006111 FPT_scwiros(p_port, SCSI_MSG);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006112
6113 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6114
6115
6116 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6117 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
6118 (UCHAR)(BIT(7)+BIT(6))));
6119
6120
6121 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
James Bottomley 47b5d692005-04-24 02:38:05 -05006122 FPT_scwiros(p_port, SCSI_SEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006123
6124 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6125 ~(UCHAR)BIT(6)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006126 FPT_scwirod(p_port, BIT(6));
Linus Torvalds1da177e2005-04-16 15:20:36 -07006127
6128 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6129}
6130
6131
6132
6133/*---------------------------------------------------------------------
6134 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006135 * Function: FPT_scxferc
Linus Torvalds1da177e2005-04-16 15:20:36 -07006136 *
6137 * Description: Handshake the p_data (DB4-0) across the bus.
6138 *
6139 *---------------------------------------------------------------------*/
6140
James Bottomley 47b5d692005-04-24 02:38:05 -05006141static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006142{
6143 UCHAR curr_data, ret_data;
6144
6145 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6146
6147 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6148
6149 curr_data &= ~BIT(7);
6150
6151 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6152
James Bottomley 47b5d692005-04-24 02:38:05 -05006153 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006154 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6155
6156 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
6157
6158 curr_data |= BIT(6);
6159
6160 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6161
6162 curr_data &= ~BIT(5);
6163
6164 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6165
James Bottomley 47b5d692005-04-24 02:38:05 -05006166 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006167
6168 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6169 curr_data |= BIT(7);
6170
6171 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6172
6173 curr_data &= ~BIT(6);
6174
6175 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6176
James Bottomley 47b5d692005-04-24 02:38:05 -05006177 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006178
6179 return(ret_data);
6180}
6181
6182
6183/*---------------------------------------------------------------------
6184 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006185 * Function: FPT_scsendi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006186 *
6187 * Description: Transfer our Identification string to determine if we
6188 * will be the dominant master.
6189 *
6190 *---------------------------------------------------------------------*/
6191
James Bottomley 47b5d692005-04-24 02:38:05 -05006192static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006193{
6194 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6195
James Bottomley 47b5d692005-04-24 02:38:05 -05006196 defer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006197
6198 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6199
6200 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6201
6202 if (defer)
James Bottomley 47b5d692005-04-24 02:38:05 -05006203 ret_data = FPT_scxferc(p_port,00);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006204
6205 else if (p_id_string[byte_cnt] & bit_cnt)
6206
James Bottomley 47b5d692005-04-24 02:38:05 -05006207 ret_data = FPT_scxferc(p_port,02);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006208
6209 else {
6210
James Bottomley 47b5d692005-04-24 02:38:05 -05006211 ret_data = FPT_scxferc(p_port,01);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006212 if (ret_data & 02)
James Bottomley 47b5d692005-04-24 02:38:05 -05006213 defer = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006214 }
6215
6216 if ((ret_data & 0x1C) == 0x10)
6217 return(0x00); /*End of isolation stage, we won! */
6218
6219 if (ret_data & 0x1C)
6220 return(0xFF);
6221
6222 if ((defer) && (!(ret_data & 0x1F)))
6223 return(0x01); /*End of isolation stage, we lost. */
6224
6225 } /*bit loop */
6226
6227 } /*byte loop */
6228
6229 if (defer)
6230 return(0x01); /*We lost */
6231 else
6232 return(0); /*We WON! Yeeessss! */
6233}
6234
6235
6236
6237/*---------------------------------------------------------------------
6238 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006239 * Function: FPT_sciso
Linus Torvalds1da177e2005-04-16 15:20:36 -07006240 *
6241 * Description: Transfer the Identification string.
6242 *
6243 *---------------------------------------------------------------------*/
6244
James Bottomley 47b5d692005-04-24 02:38:05 -05006245static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006246{
6247 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
6248
6249 the_data = 0;
6250
6251 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6252
6253 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6254
James Bottomley 47b5d692005-04-24 02:38:05 -05006255 ret_data = FPT_scxferc(p_port,0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006256
6257 if (ret_data & 0xFC)
6258 return(0xFF);
6259
6260 else {
6261
6262 the_data <<= 1;
6263 if (ret_data & BIT(1)) {
6264 the_data |= 1;
6265 }
6266 }
6267
6268 if ((ret_data & 0x1F) == 0)
6269 {
6270/*
6271 if(bit_cnt != 0 || bit_cnt != 8)
6272 {
6273 byte_cnt = 0;
6274 bit_cnt = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05006275 FPT_scxferc(p_port, SYNC_PTRN);
6276 FPT_scxferc(p_port, ASSIGN_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006277 continue;
6278 }
6279*/
6280 if (byte_cnt)
6281 return(0x00);
6282 else
6283 return(0xFF);
6284 }
6285
6286 } /*bit loop */
6287
6288 p_id_string[byte_cnt] = the_data;
6289
6290 } /*byte loop */
6291
6292 return(0);
6293}
6294
6295
6296
6297/*---------------------------------------------------------------------
6298 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006299 * Function: FPT_scwirod
Linus Torvalds1da177e2005-04-16 15:20:36 -07006300 *
6301 * Description: Sample the SCSI data bus making sure the signal has been
6302 * deasserted for the correct number of consecutive samples.
6303 *
6304 *---------------------------------------------------------------------*/
6305
James Bottomley 47b5d692005-04-24 02:38:05 -05006306static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006307{
6308 UCHAR i;
6309
6310 i = 0;
6311 while ( i < MAX_SCSI_TAR ) {
6312
6313 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6314
6315 i = 0;
6316
6317 else
6318
6319 i++;
6320
6321 }
6322}
6323
6324
6325
6326/*---------------------------------------------------------------------
6327 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006328 * Function: FPT_scwiros
Linus Torvalds1da177e2005-04-16 15:20:36 -07006329 *
6330 * Description: Sample the SCSI Signal lines making sure the signal has been
6331 * deasserted for the correct number of consecutive samples.
6332 *
6333 *---------------------------------------------------------------------*/
6334
James Bottomley 47b5d692005-04-24 02:38:05 -05006335static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006336{
6337 UCHAR i;
6338
6339 i = 0;
6340 while ( i < MAX_SCSI_TAR ) {
6341
6342 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6343
6344 i = 0;
6345
6346 else
6347
6348 i++;
6349
6350 }
6351}
6352
6353
6354/*---------------------------------------------------------------------
6355 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006356 * Function: FPT_scvalq
Linus Torvalds1da177e2005-04-16 15:20:36 -07006357 *
6358 * Description: Make sure we received a valid data byte.
6359 *
6360 *---------------------------------------------------------------------*/
6361
James Bottomley 47b5d692005-04-24 02:38:05 -05006362static UCHAR FPT_scvalq(UCHAR p_quintet)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006363{
6364 UCHAR count;
6365
6366 for (count=1; count < 0x08; count<<=1) {
6367 if (!(p_quintet & count))
6368 p_quintet -= 0x80;
6369 }
6370
6371 if (p_quintet & 0x18)
James Bottomley 47b5d692005-04-24 02:38:05 -05006372 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006373
6374 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006375 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006376}
6377
6378
6379/*---------------------------------------------------------------------
6380 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006381 * Function: FPT_scsell
Linus Torvalds1da177e2005-04-16 15:20:36 -07006382 *
6383 * Description: Select the specified device ID using a selection timeout
6384 * less than 4ms. If somebody responds then it is a legacy
6385 * drive and this ID must be marked as such.
6386 *
6387 *---------------------------------------------------------------------*/
6388
James Bottomley 47b5d692005-04-24 02:38:05 -05006389static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006390{
Linus Torvalds1da177e2005-04-16 15:20:36 -07006391 ULONG i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006392
6393 WR_HARPOON(p_port+hp_page_ctrl,
6394 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6395
6396 ARAM_ACCESS(p_port);
6397
6398 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6399 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6400
6401
6402 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6403 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6404 }
6405 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6406
6407 WRW_HARPOON((p_port+hp_intstat),
6408 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6409
6410 WR_HARPOON(p_port+hp_select_id, targ_id);
6411
6412 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6413 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6414 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6415
6416
6417 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6418 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6419
6420 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
James Bottomley 47b5d692005-04-24 02:38:05 -05006421 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006422
6423 DISABLE_AUTO(p_port);
6424
6425 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6426 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6427
6428 SGRAM_ACCESS(p_port);
6429
6430 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6431
6432 WRW_HARPOON((p_port+hp_intstat),
6433 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6434
6435 WR_HARPOON(p_port+hp_page_ctrl,
6436 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6437
James Bottomley 47b5d692005-04-24 02:38:05 -05006438 return(0); /*No legacy device */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006439 }
6440
6441 else {
6442
6443 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6444 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6445 {
6446 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6447 ACCEPT_MSG(p_port);
6448 }
6449 }
6450
6451 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6452
6453 WR_HARPOON(p_port+hp_page_ctrl,
6454 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6455
James Bottomley 47b5d692005-04-24 02:38:05 -05006456 return(1); /*Found one of them oldies! */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006457 }
6458}
6459
Linus Torvalds1da177e2005-04-16 15:20:36 -07006460/*---------------------------------------------------------------------
6461 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006462 * Function: FPT_scwtsel
Linus Torvalds1da177e2005-04-16 15:20:36 -07006463 *
6464 * Description: Wait to be selected by another SCAM initiator.
6465 *
6466 *---------------------------------------------------------------------*/
6467
James Bottomley 47b5d692005-04-24 02:38:05 -05006468static void FPT_scwtsel(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006469{
6470 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6471}
6472
6473
6474/*---------------------------------------------------------------------
6475 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006476 * Function: FPT_inisci
Linus Torvalds1da177e2005-04-16 15:20:36 -07006477 *
6478 * Description: Setup the data Structure with the info from the EEPROM.
6479 *
6480 *---------------------------------------------------------------------*/
6481
James Bottomley 47b5d692005-04-24 02:38:05 -05006482static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006483{
6484 UCHAR i,k,max_id;
6485 USHORT ee_data;
6486 PNVRamInfo pCurrNvRam;
6487
James Bottomley 47b5d692005-04-24 02:38:05 -05006488 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006489
6490 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6491 max_id = 0x08;
6492
6493 else
6494 max_id = 0x10;
6495
6496 if(pCurrNvRam){
6497 for(i = 0; i < max_id; i++){
6498
6499 for(k = 0; k < 4; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006500 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006501 for(k = 4; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006502 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006503
James Bottomley 47b5d692005-04-24 02:38:05 -05006504 if(FPT_scamInfo[i].id_string[0] == 0x00)
6505 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006506 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006507 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006508
6509 }
6510 }else {
6511 for (i=0; i < max_id; i++)
6512 {
6513 for (k=0; k < ID_STRING_LENGTH; k+=2)
6514 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006515 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006516 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
James Bottomley 47b5d692005-04-24 02:38:05 -05006517 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006518 ee_data >>= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006519 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006520 }
6521
James Bottomley 47b5d692005-04-24 02:38:05 -05006522 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6523 (FPT_scamInfo[i].id_string[0] == 0xFF))
Linus Torvalds1da177e2005-04-16 15:20:36 -07006524
James Bottomley 47b5d692005-04-24 02:38:05 -05006525 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006526
6527 else
James Bottomley 47b5d692005-04-24 02:38:05 -05006528 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006529
6530 }
6531 }
6532 for(k = 0; k < ID_STRING_LENGTH; k++)
James Bottomley 47b5d692005-04-24 02:38:05 -05006533 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006534
6535}
6536
6537/*---------------------------------------------------------------------
6538 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006539 * Function: FPT_scmachid
Linus Torvalds1da177e2005-04-16 15:20:36 -07006540 *
6541 * Description: Match the Device ID string with our values stored in
6542 * the EEPROM.
6543 *
6544 *---------------------------------------------------------------------*/
6545
James Bottomley 47b5d692005-04-24 02:38:05 -05006546static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07006547{
6548
6549 UCHAR i,k,match;
6550
6551
6552 for (i=0; i < MAX_SCSI_TAR; i++) {
6553
James Bottomley 47b5d692005-04-24 02:38:05 -05006554 match = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006555
6556 for (k=0; k < ID_STRING_LENGTH; k++)
6557 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006558 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6559 match = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006560 }
6561
6562 if (match)
6563 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006564 FPT_scamInfo[i].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006565 return(i);
6566 }
6567
Linus Torvalds1da177e2005-04-16 15:20:36 -07006568 }
6569
6570
6571
6572 if (p_id_string[0] & BIT(5))
6573 i = 8;
6574 else
6575 i = MAX_SCSI_TAR;
6576
6577 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6578 match = p_id_string[1] & (UCHAR) 0x1F;
6579 else
6580 match = 7;
6581
6582 while (i > 0)
6583 {
6584 i--;
6585
James Bottomley 47b5d692005-04-24 02:38:05 -05006586 if (FPT_scamInfo[match].state == ID_UNUSED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006587 {
6588 for (k=0; k < ID_STRING_LENGTH; k++)
6589 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006590 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006591 }
6592
James Bottomley 47b5d692005-04-24 02:38:05 -05006593 FPT_scamInfo[match].state = ID_ASSIGNED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006594
James Bottomley 47b5d692005-04-24 02:38:05 -05006595 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6596 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006597 return(match);
6598
6599 }
6600
6601
6602 match--;
6603
6604 if (match == 0xFF)
6605 {
6606 if (p_id_string[0] & BIT(5))
6607 match = 7;
6608 else
6609 match = MAX_SCSI_TAR-1;
6610 }
6611 }
6612
6613
6614
6615 if (p_id_string[0] & BIT(7))
6616 {
6617 return(CLR_PRIORITY);
6618 }
6619
6620
6621 if (p_id_string[0] & BIT(5))
6622 i = 8;
6623 else
6624 i = MAX_SCSI_TAR;
6625
6626 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6627 match = p_id_string[1] & (UCHAR) 0x1F;
6628 else
6629 match = 7;
6630
6631 while (i > 0)
6632 {
6633
6634 i--;
6635
James Bottomley 47b5d692005-04-24 02:38:05 -05006636 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006637 {
6638 for (k=0; k < ID_STRING_LENGTH; k++)
6639 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006640 FPT_scamInfo[match].id_string[k] = p_id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006641 }
6642
James Bottomley 47b5d692005-04-24 02:38:05 -05006643 FPT_scamInfo[match].id_string[0] |= BIT(7);
6644 FPT_scamInfo[match].state = ID_ASSIGNED;
6645 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6646 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006647 return(match);
6648
6649 }
6650
6651
6652 match--;
6653
6654 if (match == 0xFF)
6655 {
6656 if (p_id_string[0] & BIT(5))
6657 match = 7;
6658 else
6659 match = MAX_SCSI_TAR-1;
6660 }
6661 }
6662
6663 return(NO_ID_AVAIL);
6664}
6665
6666
6667/*---------------------------------------------------------------------
6668 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006669 * Function: FPT_scsavdi
Linus Torvalds1da177e2005-04-16 15:20:36 -07006670 *
6671 * Description: Save off the device SCAM ID strings.
6672 *
6673 *---------------------------------------------------------------------*/
6674
James Bottomley 47b5d692005-04-24 02:38:05 -05006675static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006676{
6677 UCHAR i,k,max_id;
6678 USHORT ee_data,sum_data;
6679
6680
6681 sum_data = 0x0000;
6682
6683 for (i = 1; i < EE_SCAMBASE/2; i++)
6684 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006685 sum_data += FPT_utilEERead(p_port, i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006686 }
6687
6688
James Bottomley 47b5d692005-04-24 02:38:05 -05006689 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006690
6691 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6692 max_id = 0x08;
6693
6694 else
6695 max_id = 0x10;
6696
6697 for (i=0; i < max_id; i++)
6698 {
6699
6700 for (k=0; k < ID_STRING_LENGTH; k+=2)
6701 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006702 ee_data = FPT_scamInfo[i].id_string[k+1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006703 ee_data <<= 8;
James Bottomley 47b5d692005-04-24 02:38:05 -05006704 ee_data |= FPT_scamInfo[i].id_string[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006705 sum_data += ee_data;
James Bottomley 47b5d692005-04-24 02:38:05 -05006706 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
Linus Torvalds1da177e2005-04-16 15:20:36 -07006707 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6708 }
6709 }
6710
6711
James Bottomley 47b5d692005-04-24 02:38:05 -05006712 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6713 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006714}
Linus Torvalds1da177e2005-04-16 15:20:36 -07006715
6716/*---------------------------------------------------------------------
6717 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006718 * Function: FPT_XbowInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006719 *
6720 * Description: Setup the Xbow for normal operation.
6721 *
6722 *---------------------------------------------------------------------*/
6723
James Bottomley 47b5d692005-04-24 02:38:05 -05006724static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006725{
6726UCHAR i;
6727
6728 i = RD_HARPOON(port+hp_page_ctrl);
6729 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
6730
6731 WR_HARPOON(port+hp_scsireset,0x00);
6732 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6733
6734 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6735 FIFO_CLR));
6736
6737 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6738
6739 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6740
6741 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6742 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6743
6744 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6745
James Bottomley 47b5d692005-04-24 02:38:05 -05006746 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
Linus Torvalds1da177e2005-04-16 15:20:36 -07006747 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6748
6749 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
James Bottomley 47b5d692005-04-24 02:38:05 -05006750 FPT_default_intena |= SCAM_SEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07006751
James Bottomley 47b5d692005-04-24 02:38:05 -05006752 WRW_HARPOON((port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006753
6754 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6755
6756 /* Turn on SCSI_MODE8 for narrow cards to fix the
6757 strapping issue with the DUAL CHANNEL card */
6758 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6759 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6760
Linus Torvalds1da177e2005-04-16 15:20:36 -07006761 WR_HARPOON(port+hp_page_ctrl, i);
6762
6763}
6764
6765
6766/*---------------------------------------------------------------------
6767 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006768 * Function: FPT_BusMasterInit
Linus Torvalds1da177e2005-04-16 15:20:36 -07006769 *
6770 * Description: Initialize the BusMaster for normal operations.
6771 *
6772 *---------------------------------------------------------------------*/
6773
James Bottomley 47b5d692005-04-24 02:38:05 -05006774static void FPT_BusMasterInit(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006775{
6776
6777
6778 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6779 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6780
6781 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6782
6783
6784 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6785
6786 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6787
6788
Linus Torvalds1da177e2005-04-16 15:20:36 -07006789 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6790 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6791 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6792 ~SCATTER_EN));
6793}
6794
6795
6796/*---------------------------------------------------------------------
6797 *
James Bottomley 47b5d692005-04-24 02:38:05 -05006798 * Function: FPT_DiagEEPROM
Linus Torvalds1da177e2005-04-16 15:20:36 -07006799 *
6800 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6801 * necessary.
6802 *
6803 *---------------------------------------------------------------------*/
6804
James Bottomley 47b5d692005-04-24 02:38:05 -05006805static void FPT_DiagEEPROM(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006806{
6807 USHORT index,temp,max_wd_cnt;
6808
6809 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6810 max_wd_cnt = EEPROM_WD_CNT;
6811 else
6812 max_wd_cnt = EEPROM_WD_CNT * 2;
6813
James Bottomley 47b5d692005-04-24 02:38:05 -05006814 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006815
6816 if (temp == 0x4641) {
6817
6818 for (index = 2; index < max_wd_cnt; index++) {
6819
James Bottomley 47b5d692005-04-24 02:38:05 -05006820 temp += FPT_utilEERead(p_port, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006821
6822 }
6823
James Bottomley 47b5d692005-04-24 02:38:05 -05006824 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07006825
6826 return; /*EEPROM is Okay so return now! */
6827 }
6828 }
6829
6830
James Bottomley 47b5d692005-04-24 02:38:05 -05006831 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006832
6833 for (index = 0; index < max_wd_cnt; index++) {
6834
James Bottomley 47b5d692005-04-24 02:38:05 -05006835 FPT_utilEEWrite(p_port, 0x0000, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006836 }
6837
6838 temp = 0;
6839
James Bottomley 47b5d692005-04-24 02:38:05 -05006840 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006841 temp += 0x4641;
James Bottomley 47b5d692005-04-24 02:38:05 -05006842 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006843 temp += 0x3920;
James Bottomley 47b5d692005-04-24 02:38:05 -05006844 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006845 temp += 0x3033;
James Bottomley 47b5d692005-04-24 02:38:05 -05006846 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006847 temp += 0x2020;
James Bottomley 47b5d692005-04-24 02:38:05 -05006848 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006849 temp += 0x70D3;
James Bottomley 47b5d692005-04-24 02:38:05 -05006850 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006851 temp += 0x0010;
James Bottomley 47b5d692005-04-24 02:38:05 -05006852 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006853 temp += 0x0003;
James Bottomley 47b5d692005-04-24 02:38:05 -05006854 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006855 temp += 0x0007;
6856
James Bottomley 47b5d692005-04-24 02:38:05 -05006857 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006858 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006859 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006860 temp += 0x0000;
James Bottomley 47b5d692005-04-24 02:38:05 -05006861 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006862 temp += 0x0000;
6863
James Bottomley 47b5d692005-04-24 02:38:05 -05006864 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006865 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006866 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006867 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006868 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006869 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006870 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006871 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006872 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006873 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006874 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006875 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006876 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006877 temp += 0x4242;
James Bottomley 47b5d692005-04-24 02:38:05 -05006878 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006879 temp += 0x4242;
6880
6881
James Bottomley 47b5d692005-04-24 02:38:05 -05006882 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006883 temp += 0x6C46;
James Bottomley 47b5d692005-04-24 02:38:05 -05006884 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006885 temp += 0x7361;
James Bottomley 47b5d692005-04-24 02:38:05 -05006886 FPT_utilEEWrite(p_port, 0x5068, 68/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006887 temp += 0x5068;
James Bottomley 47b5d692005-04-24 02:38:05 -05006888 FPT_utilEEWrite(p_port, 0x696F, 70/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006889 temp += 0x696F;
James Bottomley 47b5d692005-04-24 02:38:05 -05006890 FPT_utilEEWrite(p_port, 0x746E, 72/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006891 temp += 0x746E;
James Bottomley 47b5d692005-04-24 02:38:05 -05006892 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006893 temp += 0x4C20;
James Bottomley 47b5d692005-04-24 02:38:05 -05006894 FPT_utilEEWrite(p_port, 0x2054, 76/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006895 temp += 0x2054;
James Bottomley 47b5d692005-04-24 02:38:05 -05006896 FPT_utilEEWrite(p_port, 0x2020, 78/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006897 temp += 0x2020;
6898
6899 index = ((EE_SCAMBASE/2)+(7*16));
James Bottomley 47b5d692005-04-24 02:38:05 -05006900 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006901 temp += (0x0700+TYPE_CODE0);
6902 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006903 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006904 temp += 0x5542; /* BUSLOGIC */
6905 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006906 FPT_utilEEWrite(p_port, 0x4C53, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006907 temp += 0x4C53;
6908 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006909 FPT_utilEEWrite(p_port, 0x474F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006910 temp += 0x474F;
6911 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006912 FPT_utilEEWrite(p_port, 0x4349, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006913 temp += 0x4349;
6914 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006915 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006916 temp += 0x5442; /* BT- 930 */
6917 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006918 FPT_utilEEWrite(p_port, 0x202D, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006919 temp += 0x202D;
6920 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006921 FPT_utilEEWrite(p_port, 0x3339, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006922 temp += 0x3339;
6923 index++; /*Serial # */
James Bottomley 47b5d692005-04-24 02:38:05 -05006924 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006925 temp += 0x2030;
6926 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006927 FPT_utilEEWrite(p_port, 0x5453, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006928 temp += 0x5453;
6929 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006930 FPT_utilEEWrite(p_port, 0x5645, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006931 temp += 0x5645;
6932 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006933 FPT_utilEEWrite(p_port, 0x2045, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006934 temp += 0x2045;
6935 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006936 FPT_utilEEWrite(p_port, 0x202F, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006937 temp += 0x202F;
6938 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006939 FPT_utilEEWrite(p_port, 0x4F4A, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006940 temp += 0x4F4A;
6941 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006942 FPT_utilEEWrite(p_port, 0x204E, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006943 temp += 0x204E;
6944 index++;
James Bottomley 47b5d692005-04-24 02:38:05 -05006945 FPT_utilEEWrite(p_port, 0x3539, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006946 temp += 0x3539;
6947
6948
6949
James Bottomley 47b5d692005-04-24 02:38:05 -05006950 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006951
James Bottomley 47b5d692005-04-24 02:38:05 -05006952 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07006953
6954}
6955
Linus Torvalds1da177e2005-04-16 15:20:36 -07006956
6957/*---------------------------------------------------------------------
6958 *
6959 * Function: Queue Search Select
6960 *
6961 * Description: Try to find a new command to execute.
6962 *
6963 *---------------------------------------------------------------------*/
6964
James Bottomley 47b5d692005-04-24 02:38:05 -05006965static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006966{
6967 UCHAR scan_ptr, lun;
6968 PSCCBMgr_tar_info currTar_Info;
6969 PSCCB pOldSccb;
6970
6971 scan_ptr = pCurrCard->scanIndex;
6972 do
6973 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006974 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
Linus Torvalds1da177e2005-04-16 15:20:36 -07006975 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6976 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6977 {
6978 if (currTar_Info->TarSelQ_Cnt != 0)
6979 {
6980
6981 scan_ptr++;
6982 if (scan_ptr == MAX_SCSI_TAR)
6983 scan_ptr = 0;
6984
6985 for(lun=0; lun < MAX_LUN; lun++)
6986 {
James Bottomley 47b5d692005-04-24 02:38:05 -05006987 if(currTar_Info->TarLUNBusy[lun] == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07006988 {
6989
6990 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6991 pOldSccb = NULL;
6992
6993 while((pCurrCard->currentSCCB != NULL) &&
6994 (lun != pCurrCard->currentSCCB->Lun))
6995 {
6996 pOldSccb = pCurrCard->currentSCCB;
6997 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6998 Sccb_forwardlink;
6999 }
7000 if(pCurrCard->currentSCCB == NULL)
7001 continue;
7002 if(pOldSccb != NULL)
7003 {
7004 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
7005 Sccb_forwardlink;
7006 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
7007 Sccb_backlink;
7008 currTar_Info->TarSelQ_Cnt--;
7009 }
7010 else
7011 {
7012 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7013
7014 if (currTar_Info->TarSelQ_Head == NULL)
7015 {
7016 currTar_Info->TarSelQ_Tail = NULL;
7017 currTar_Info->TarSelQ_Cnt = 0;
7018 }
7019 else
7020 {
7021 currTar_Info->TarSelQ_Cnt--;
7022 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7023 }
7024 }
7025 pCurrCard->scanIndex = scan_ptr;
7026
7027 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7028
7029 break;
7030 }
7031 }
7032 }
7033
7034 else
7035 {
7036 scan_ptr++;
7037 if (scan_ptr == MAX_SCSI_TAR) {
7038 scan_ptr = 0;
7039 }
7040 }
7041
7042 }
7043 else
7044 {
7045 if ((currTar_Info->TarSelQ_Cnt != 0) &&
James Bottomley 47b5d692005-04-24 02:38:05 -05007046 (currTar_Info->TarLUNBusy[0] == 0))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007047 {
7048
7049 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7050
7051 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7052
7053 if (currTar_Info->TarSelQ_Head == NULL)
7054 {
7055 currTar_Info->TarSelQ_Tail = NULL;
7056 currTar_Info->TarSelQ_Cnt = 0;
7057 }
7058 else
7059 {
7060 currTar_Info->TarSelQ_Cnt--;
7061 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7062 }
7063
7064 scan_ptr++;
7065 if (scan_ptr == MAX_SCSI_TAR)
7066 scan_ptr = 0;
7067
7068 pCurrCard->scanIndex = scan_ptr;
7069
7070 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7071
7072 break;
7073 }
7074
7075 else
7076 {
7077 scan_ptr++;
7078 if (scan_ptr == MAX_SCSI_TAR)
7079 {
7080 scan_ptr = 0;
7081 }
7082 }
7083 }
7084 } while (scan_ptr != pCurrCard->scanIndex);
7085}
7086
7087
7088/*---------------------------------------------------------------------
7089 *
7090 * Function: Queue Select Fail
7091 *
7092 * Description: Add the current SCCB to the head of the Queue.
7093 *
7094 *---------------------------------------------------------------------*/
7095
James Bottomley 47b5d692005-04-24 02:38:05 -05007096static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007097{
7098 UCHAR thisTarg;
7099 PSCCBMgr_tar_info currTar_Info;
7100
7101 if (pCurrCard->currentSCCB != NULL)
7102 {
7103 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
James Bottomley 47b5d692005-04-24 02:38:05 -05007104 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007105
7106 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7107
7108 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7109
7110 if (currTar_Info->TarSelQ_Cnt == 0)
7111 {
7112 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7113 }
7114
7115 else
7116 {
7117 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7118 }
7119
7120
7121 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7122
7123 pCurrCard->currentSCCB = NULL;
7124 currTar_Info->TarSelQ_Cnt++;
7125 }
7126}
7127/*---------------------------------------------------------------------
7128 *
7129 * Function: Queue Command Complete
7130 *
7131 * Description: Call the callback function with the current SCCB.
7132 *
7133 *---------------------------------------------------------------------*/
7134
James Bottomley 47b5d692005-04-24 02:38:05 -05007135static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7136 UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007137{
7138
Linus Torvalds1da177e2005-04-16 15:20:36 -07007139 UCHAR i, SCSIcmd;
7140 CALL_BK_FN callback;
7141 PSCCBMgr_tar_info currTar_Info;
7142
7143 SCSIcmd = p_sccb->Cdb[0];
7144
7145
7146 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7147
7148 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7149 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7150 (p_sccb->TargetStatus != SSCHECK))
7151
7152 if ((SCSIcmd == SCSI_READ) ||
7153 (SCSIcmd == SCSI_WRITE) ||
7154 (SCSIcmd == SCSI_READ_EXTENDED) ||
7155 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7156 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7157 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7158 (pCurrCard->globalFlags & F_NO_FILTER)
7159 )
7160 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7161 }
7162
7163
7164 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7165 {
7166 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7167 p_sccb->SccbStatus = SCCB_ERROR;
7168 else
7169 p_sccb->SccbStatus = SCCB_SUCCESS;
7170 }
7171
7172 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7173
7174 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7175 for (i=0; i < 6; i++) {
7176 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7177 }
7178 }
7179
7180 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7181 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7182
James Bottomley 47b5d692005-04-24 02:38:05 -05007183 FPT_utilUpdateResidual(p_sccb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007184 }
7185
7186 pCurrCard->cmdCounter--;
7187 if (!pCurrCard->cmdCounter) {
7188
7189 if (pCurrCard->globalFlags & F_GREEN_PC) {
7190 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7191 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7192 }
7193
7194 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7195 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7196
7197 }
7198
7199 if(pCurrCard->discQCount != 0)
7200 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007201 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007202 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7203 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7204 {
7205 pCurrCard->discQCount--;
7206 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7207 }
7208 else
7209 {
7210 if(p_sccb->Sccb_tag)
7211 {
7212 pCurrCard->discQCount--;
7213 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7214 }else
7215 {
7216 pCurrCard->discQCount--;
7217 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7218 }
7219 }
7220
7221 }
7222
7223 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7224 callback(p_sccb);
7225 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7226 pCurrCard->currentSCCB = NULL;
7227}
Linus Torvalds1da177e2005-04-16 15:20:36 -07007228
7229
7230/*---------------------------------------------------------------------
7231 *
7232 * Function: Queue Disconnect
7233 *
7234 * Description: Add SCCB to our disconnect array.
7235 *
7236 *---------------------------------------------------------------------*/
James Bottomley 47b5d692005-04-24 02:38:05 -05007237static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007238{
7239 PSCCBMgr_tar_info currTar_Info;
7240
James Bottomley 47b5d692005-04-24 02:38:05 -05007241 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007242
James Bottomley 47b5d692005-04-24 02:38:05 -05007243 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07007244 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7245 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007246 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007247 }
7248 else
7249 {
7250 if (p_sccb->Sccb_tag)
7251 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007252 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7253 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7254 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007255 }else
7256 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007257 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007258 }
7259 }
James Bottomley 47b5d692005-04-24 02:38:05 -05007260 FPT_BL_Card[p_card].currentSCCB = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007261}
7262
7263
7264/*---------------------------------------------------------------------
7265 *
7266 * Function: Queue Flush SCCB
7267 *
7268 * Description: Flush all SCCB's back to the host driver for this target.
7269 *
7270 *---------------------------------------------------------------------*/
7271
James Bottomley 47b5d692005-04-24 02:38:05 -05007272static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007273{
7274 UCHAR qtag,thisTarg;
7275 PSCCB currSCCB;
7276 PSCCBMgr_tar_info currTar_Info;
7277
James Bottomley 47b5d692005-04-24 02:38:05 -05007278 currSCCB = FPT_BL_Card[p_card].currentSCCB;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007279 if(currSCCB != NULL)
7280 {
7281 thisTarg = (UCHAR)currSCCB->TargID;
James Bottomley 47b5d692005-04-24 02:38:05 -05007282 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007283
7284 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7285
James Bottomley 47b5d692005-04-24 02:38:05 -05007286 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7287 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007288 {
7289
James Bottomley 47b5d692005-04-24 02:38:05 -05007290 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007291
James Bottomley 47b5d692005-04-24 02:38:05 -05007292 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007293
James Bottomley 47b5d692005-04-24 02:38:05 -05007294 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007295 currTar_Info->TarTagQ_Cnt--;
7296
7297 }
7298 }
7299 }
7300
7301}
7302
7303/*---------------------------------------------------------------------
7304 *
7305 * Function: Queue Flush Target SCCB
7306 *
7307 * Description: Flush all SCCB's back to the host driver for this target.
7308 *
7309 *---------------------------------------------------------------------*/
7310
James Bottomley 47b5d692005-04-24 02:38:05 -05007311static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7312 UCHAR error_code)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007313{
7314 UCHAR qtag;
7315 PSCCBMgr_tar_info currTar_Info;
7316
James Bottomley 47b5d692005-04-24 02:38:05 -05007317 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007318
7319 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7320
James Bottomley 47b5d692005-04-24 02:38:05 -05007321 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7322 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
Linus Torvalds1da177e2005-04-16 15:20:36 -07007323 {
7324
James Bottomley 47b5d692005-04-24 02:38:05 -05007325 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007326
James Bottomley 47b5d692005-04-24 02:38:05 -05007327 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007328
James Bottomley 47b5d692005-04-24 02:38:05 -05007329 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007330 currTar_Info->TarTagQ_Cnt--;
7331
7332 }
7333 }
7334
7335}
7336
7337
7338
7339
7340
James Bottomley 47b5d692005-04-24 02:38:05 -05007341static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007342{
7343 PSCCBMgr_tar_info currTar_Info;
James Bottomley 47b5d692005-04-24 02:38:05 -05007344 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007345
7346 p_SCCB->Sccb_forwardlink = NULL;
7347
7348 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7349
7350 if (currTar_Info->TarSelQ_Cnt == 0) {
7351
7352 currTar_Info->TarSelQ_Head = p_SCCB;
7353 }
7354
7355 else {
7356
7357 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7358 }
7359
7360
7361 currTar_Info->TarSelQ_Tail = p_SCCB;
7362 currTar_Info->TarSelQ_Cnt++;
7363}
7364
7365
7366/*---------------------------------------------------------------------
7367 *
7368 * Function: Queue Find SCCB
7369 *
7370 * Description: Search the target select Queue for this SCCB, and
7371 * remove it if found.
7372 *
7373 *---------------------------------------------------------------------*/
7374
James Bottomley 47b5d692005-04-24 02:38:05 -05007375static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007376{
7377 PSCCB q_ptr;
7378 PSCCBMgr_tar_info currTar_Info;
7379
James Bottomley 47b5d692005-04-24 02:38:05 -05007380 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
Linus Torvalds1da177e2005-04-16 15:20:36 -07007381
7382 q_ptr = currTar_Info->TarSelQ_Head;
7383
7384 while(q_ptr != NULL) {
7385
7386 if (q_ptr == p_SCCB) {
7387
7388
7389 if (currTar_Info->TarSelQ_Head == q_ptr) {
7390
7391 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7392 }
7393
7394 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7395
7396 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7397 }
7398
7399 if (q_ptr->Sccb_forwardlink != NULL) {
7400 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7401 }
7402
7403 if (q_ptr->Sccb_backlink != NULL) {
7404 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7405 }
7406
7407 currTar_Info->TarSelQ_Cnt--;
7408
James Bottomley 47b5d692005-04-24 02:38:05 -05007409 return(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007410 }
7411
7412 else {
7413 q_ptr = q_ptr->Sccb_forwardlink;
7414 }
7415 }
7416
7417
James Bottomley 47b5d692005-04-24 02:38:05 -05007418 return(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007419
7420}
7421
7422
7423/*---------------------------------------------------------------------
7424 *
7425 * Function: Utility Update Residual Count
7426 *
7427 * Description: Update the XferCnt to the remaining byte count.
7428 * If we transferred all the data then just write zero.
7429 * If Non-SG transfer then report Total Cnt - Actual Transfer
7430 * Cnt. For SG transfers add the count fields of all
7431 * remaining SG elements, as well as any partial remaining
7432 * element.
7433 *
7434 *---------------------------------------------------------------------*/
7435
James Bottomley 47b5d692005-04-24 02:38:05 -05007436static void FPT_utilUpdateResidual(PSCCB p_SCCB)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007437{
7438 ULONG partial_cnt;
7439 UINT sg_index;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007440 ULONG *sg_ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007441
7442 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7443
7444 p_SCCB->DataLength = 0x0000;
7445 }
7446
7447 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7448
7449 partial_cnt = 0x0000;
7450
7451 sg_index = p_SCCB->Sccb_sgseg;
7452
Linus Torvalds1da177e2005-04-16 15:20:36 -07007453 sg_ptr = (ULONG *)p_SCCB->DataPointer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07007454
7455 if (p_SCCB->Sccb_SGoffset) {
7456
7457 partial_cnt = p_SCCB->Sccb_SGoffset;
7458 sg_index++;
7459 }
7460
7461 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7462 p_SCCB->DataLength ) {
7463
7464 partial_cnt += *(sg_ptr+(sg_index * 2));
7465 sg_index++;
7466 }
7467
7468 p_SCCB->DataLength = partial_cnt;
7469 }
7470
7471 else {
7472
7473 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7474 }
7475}
7476
7477
7478/*---------------------------------------------------------------------
7479 *
7480 * Function: Wait 1 Second
7481 *
7482 * Description: Wait for 1 second.
7483 *
7484 *---------------------------------------------------------------------*/
7485
James Bottomley 47b5d692005-04-24 02:38:05 -05007486static void FPT_Wait1Second(ULONG p_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007487{
7488 UCHAR i;
7489
7490 for(i=0; i < 4; i++) {
7491
James Bottomley 47b5d692005-04-24 02:38:05 -05007492 FPT_Wait(p_port, TO_250ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007493
7494 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7495 break;
7496
7497 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7498 break;
7499 }
7500}
7501
7502
7503/*---------------------------------------------------------------------
7504 *
James Bottomley 47b5d692005-04-24 02:38:05 -05007505 * Function: FPT_Wait
Linus Torvalds1da177e2005-04-16 15:20:36 -07007506 *
7507 * Description: Wait the desired delay.
7508 *
7509 *---------------------------------------------------------------------*/
7510
James Bottomley 47b5d692005-04-24 02:38:05 -05007511static void FPT_Wait(ULONG p_port, UCHAR p_delay)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007512{
7513 UCHAR old_timer;
7514 UCHAR green_flag;
7515
7516 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7517
7518 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7519 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7520
7521 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7522 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007523 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
Linus Torvalds1da177e2005-04-16 15:20:36 -07007524
7525
7526 WR_HARPOON(p_port+hp_portctrl_0,
7527 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7528
7529 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7530
7531 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7532 break;
7533
7534 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7535 break;
7536 }
7537
7538 WR_HARPOON(p_port+hp_portctrl_0,
7539 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7540
7541 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
James Bottomley 47b5d692005-04-24 02:38:05 -05007542 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007543
7544 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7545
7546 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7547}
7548
7549
7550/*---------------------------------------------------------------------
7551 *
7552 * Function: Enable/Disable Write to EEPROM
7553 *
7554 * Description: The EEPROM must first be enabled for writes
7555 * A total of 9 clocks are needed.
7556 *
7557 *---------------------------------------------------------------------*/
7558
James Bottomley 47b5d692005-04-24 02:38:05 -05007559static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007560{
7561 UCHAR ee_value;
7562
7563 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7564
7565 if (p_mode)
7566
James Bottomley 47b5d692005-04-24 02:38:05 -05007567 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007568
7569 else
7570
7571
James Bottomley 47b5d692005-04-24 02:38:05 -05007572 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007573
7574 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7575 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7576}
7577
7578
7579/*---------------------------------------------------------------------
7580 *
7581 * Function: Write EEPROM
7582 *
7583 * Description: Write a word to the EEPROM at the specified
7584 * address.
7585 *
7586 *---------------------------------------------------------------------*/
7587
James Bottomley 47b5d692005-04-24 02:38:05 -05007588static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007589{
7590
7591 UCHAR ee_value;
7592 USHORT i;
7593
7594 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7595 (SEE_MS | SEE_CS));
7596
7597
7598
James Bottomley 47b5d692005-04-24 02:38:05 -05007599 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007600
7601
7602 ee_value |= (SEE_MS + SEE_CS);
7603
7604 for(i = 0x8000; i != 0; i>>=1) {
7605
7606 if (i & ee_data)
7607 ee_value |= SEE_DO;
7608 else
7609 ee_value &= ~SEE_DO;
7610
7611 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7612 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7613 ee_value |= SEE_CLK; /* Clock data! */
7614 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7615 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7616 ee_value &= ~SEE_CLK;
7617 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7618 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7619 }
7620 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7621 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7622
James Bottomley 47b5d692005-04-24 02:38:05 -05007623 FPT_Wait(p_port, TO_10ms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007624
7625 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7626 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7627 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7628}
7629
7630/*---------------------------------------------------------------------
7631 *
7632 * Function: Read EEPROM
7633 *
7634 * Description: Read a word from the EEPROM at the desired
7635 * address.
7636 *
7637 *---------------------------------------------------------------------*/
7638
James Bottomley 47b5d692005-04-24 02:38:05 -05007639static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007640{
7641 USHORT i, ee_data1, ee_data2;
7642
7643 i = 0;
James Bottomley 47b5d692005-04-24 02:38:05 -05007644 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007645 do
7646 {
James Bottomley 47b5d692005-04-24 02:38:05 -05007647 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007648
7649 if(ee_data1 == ee_data2)
7650 return(ee_data1);
7651
7652 ee_data1 = ee_data2;
7653 i++;
7654
7655 }while(i < 4);
7656
7657 return(ee_data1);
7658}
7659
7660/*---------------------------------------------------------------------
7661 *
7662 * Function: Read EEPROM Original
7663 *
7664 * Description: Read a word from the EEPROM at the desired
7665 * address.
7666 *
7667 *---------------------------------------------------------------------*/
7668
James Bottomley 47b5d692005-04-24 02:38:05 -05007669static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007670{
7671
7672 UCHAR ee_value;
7673 USHORT i, ee_data;
7674
7675 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7676 (SEE_MS | SEE_CS));
7677
7678
James Bottomley 47b5d692005-04-24 02:38:05 -05007679 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007680
7681
7682 ee_value |= (SEE_MS + SEE_CS);
7683 ee_data = 0;
7684
7685 for(i = 1; i <= 16; i++) {
7686
7687 ee_value |= SEE_CLK; /* Clock data! */
7688 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7689 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7690 ee_value &= ~SEE_CLK;
7691 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7692 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7693
7694 ee_data <<= 1;
7695
7696 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7697 ee_data |= 1;
7698 }
7699
7700 ee_value &= ~(SEE_MS + SEE_CS);
7701 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7702 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7703
7704 return(ee_data);
7705}
7706
7707
7708/*---------------------------------------------------------------------
7709 *
7710 * Function: Send EE command and Address to the EEPROM
7711 *
7712 * Description: Transfers the correct command and sends the address
7713 * to the eeprom.
7714 *
7715 *---------------------------------------------------------------------*/
7716
James Bottomley 47b5d692005-04-24 02:38:05 -05007717static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07007718{
7719 UCHAR ee_value;
7720 UCHAR narrow_flg;
7721
7722 USHORT i;
7723
7724
7725 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7726
7727
7728 ee_value = SEE_MS;
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730
7731 ee_value |= SEE_CS; /* Set CS to EEPROM */
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7733
7734
7735 for(i = 0x04; i != 0; i>>=1) {
7736
7737 if (i & ee_cmd)
7738 ee_value |= SEE_DO;
7739 else
7740 ee_value &= ~SEE_DO;
7741
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 ee_value |= SEE_CLK; /* Clock data! */
7745 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 ee_value &= ~SEE_CLK;
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 }
7751
7752
7753 if (narrow_flg)
7754 i = 0x0080;
7755
7756 else
7757 i = 0x0200;
7758
7759
7760 while (i != 0) {
7761
7762 if (i & ee_addr)
7763 ee_value |= SEE_DO;
7764 else
7765 ee_value &= ~SEE_DO;
7766
7767 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7768 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7769 ee_value |= SEE_CLK; /* Clock data! */
7770 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7771 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7772 ee_value &= ~SEE_CLK;
7773 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7774 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7775
7776 i >>= 1;
7777 }
7778}
7779
James Bottomley 47b5d692005-04-24 02:38:05 -05007780static USHORT FPT_CalcCrc16(UCHAR buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007781{
7782 USHORT crc=0;
7783 int i,j;
7784 USHORT ch;
7785 for (i=0; i < ID_STRING_LENGTH; i++)
7786 {
7787 ch = (USHORT) buffer[i];
7788 for(j=0; j < 8; j++)
7789 {
7790 if ((crc ^ ch) & 1)
7791 crc = (crc >> 1) ^ CRCMASK;
7792 else
7793 crc >>= 1;
7794 ch >>= 1;
7795 }
7796 }
7797 return(crc);
7798}
7799
James Bottomley 47b5d692005-04-24 02:38:05 -05007800static UCHAR FPT_CalcLrc(UCHAR buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -07007801{
7802 int i;
7803 UCHAR lrc;
7804 lrc = 0;
7805 for(i = 0; i < ID_STRING_LENGTH; i++)
7806 lrc ^= buffer[i];
7807 return(lrc);
7808}
7809
7810
7811
7812/*
7813 The following inline definitions avoid type conflicts.
7814*/
7815
7816static inline unsigned char
7817FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7818{
7819 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7820}
7821
7822
7823static inline FlashPoint_CardHandle_T
7824FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7825{
7826 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7827}
7828
7829static inline void
7830FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7831{
7832 FlashPoint_ReleaseHostAdapter(CardHandle);
7833}
7834
7835
7836static inline void
7837FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7838{
7839 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7840}
7841
7842
7843static inline void
7844FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7845{
7846 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7847}
7848
7849
7850static inline boolean
7851FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7852{
7853 return FlashPoint_InterruptPending(CardHandle);
7854}
7855
7856
7857static inline int
7858FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7859{
7860 return FlashPoint_HandleInterrupt(CardHandle);
7861}
7862
7863
7864#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7865#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7866#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7867#define FlashPoint_StartCCB FlashPoint__StartCCB
7868#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7869#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7870#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7871
7872
Linus Torvalds1da177e2005-04-16 15:20:36 -07007873#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7874
7875
7876/*
7877 Define prototypes for the FlashPoint SCCB Manager Functions.
7878*/
7879
7880extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7881extern FlashPoint_CardHandle_T
7882 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7883extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7884extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7885extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7886extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7887extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
Linus Torvalds1da177e2005-04-16 15:20:36 -07007888
7889
7890#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */