]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/scsi/FlashPoint.c
[SCSI] drivers/scsi/FlashPoint.c: remove unused things
[net-next-2.6.git] / drivers / scsi / FlashPoint.c
CommitLineData
1da177e4
LT
1/*
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
1da177e4
LT
25#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)
1da177e4
LT
35
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
1da177e4 50
1da177e4
LT
51
52#define CRCMASK 0xA001
53
1da177e4
LT
54
55
1da177e4
LT
56#define FAILURE 0xFFFFFFFFL
57
58
59typedef unsigned char UCHAR;
60typedef unsigned short USHORT;
61typedef unsigned int UINT;
62typedef unsigned long ULONG;
1da177e4
LT
63
64
1da177e4 65typedef unsigned short * ushort_ptr;
1da177e4 66
1da177e4
LT
67
68#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
1da177e4 76
1da177e4
LT
77
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
1da177e4 83
47b5d69c
JB
84typedef struct _SCCB *PSCCB;
85typedef void (*CALL_BK_FN)(PSCCB);
1da177e4
LT
86
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
47b5d69c 112typedef SCCBMGR_INFO * PSCCBMGR_INFO;
1da177e4
LT
113
114
47b5d69c
JB
115#define SCSI_PARITY_ENA 0x0001
116#define LOW_BYTE_TERM 0x0010
117#define HIGH_BYTE_TERM 0x0020
118#define BUSTYPE_PCI 0x3
1da177e4
LT
119
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
1da177e4 133
32357988 134/* SCCB struct used for both SCCB and UCB manager compiles!
1da177e4
LT
135 * 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;
1da177e4
LT
183 } SCCB;
184
1da177e4
LT
185
186#pragma pack()
187
188
189
1da177e4
LT
190#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. */
1da177e4
LT
198#define SCCB_DATA_XFER_OUT 0x10 /* Write */
199#define SCCB_DATA_XFER_IN 0x08 /* Read */
200
201
1da177e4
LT
202#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
1da177e4 215#define ABORT_ST 11
1da177e4
LT
216
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
1da177e4
LT
227#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
1da177e4
LT
234#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
235
1da177e4
LT
236#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
1da177e4
LT
242
243
244#define SCCB_IN_PROCESS 0x00
245#define SCCB_SUCCESS 0x01
246#define SCCB_ABORT 0x02
1da177e4 247#define SCCB_ERROR 0x04
1da177e4 248
1da177e4
LT
249
250
1da177e4
LT
251#define ORION_FW_REV 3110
252
1da177e4
LT
253
254
1da177e4 255#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
1da177e4
LT
256
257#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
258
1da177e4 259
47b5d69c
JB
260#define MAX_SCSI_TAR 16
261#define MAX_LUN 32
262#define LUN_MASK 0x1f
1da177e4 263
1da177e4 264#define SG_BUF_CNT 16 /*Number of prefetched elements. */
1da177e4
LT
265
266#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
1da177e4
LT
267
268
47b5d69c
JB
269#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)
1da177e4
LT
275
276
277#define TAR_SYNC_MASK (BIT(7)+BIT(6))
1da177e4
LT
278#define SYNC_TRYING BIT(6)
279#define SYNC_SUPPORTED (BIT(7)+BIT(6))
280
281#define TAR_WIDE_MASK (BIT(5)+BIT(4))
1da177e4
LT
282#define WIDE_ENABLED BIT(4)
283#define WIDE_NEGOCIATED BIT(5)
284
285#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
1da177e4
LT
286#define TAG_Q_TRYING BIT(2)
287#define TAG_Q_REJECT BIT(3)
1da177e4
LT
288
289#define TAR_ALLOW_DISC BIT(0)
290
291
292#define EE_SYNC_MASK (BIT(0)+BIT(1))
1da177e4
LT
293#define EE_SYNC_5MB BIT(0)
294#define EE_SYNC_10MB BIT(1)
295#define EE_SYNC_20MB (BIT(0)+BIT(1))
296
1da177e4
LT
297#define EE_WIDE_SCSI BIT(7)
298
299
47b5d69c 300typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
1da177e4
LT
301
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. */
1da177e4 321 ULONG niBaseAddr; /* Port Address of card */
1da177e4
LT
322 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
1da177e4 330typedef NVRAMINFO *PNVRamInfo;
1da177e4
LT
331
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;
1da177e4 340 PSCCBMGR_INFO cardInfo;
1da177e4 341
1da177e4 342 ULONG ioPort;
1da177e4
LT
343
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
1da177e4 356typedef struct SCCBcard *PSCCBcard;
1da177e4
LT
357
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
1da177e4
LT
372
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
1da177e4
LT
383#define MISC_CODE 0x14
384#define CLR_P_FLAG 0x18
1da177e4 385
1da177e4
LT
386
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
85ae97d8 401} SCCBSCAM_INFO;
1da177e4 402
1da177e4 403
1da177e4 404#define SCSI_REQUEST_SENSE 0x03
1da177e4
LT
405#define SCSI_READ 0x08
406#define SCSI_WRITE 0x0A
1da177e4 407#define SCSI_START_STOP_UNIT 0x1B
1da177e4
LT
408#define SCSI_READ_EXTENDED 0x28
409#define SCSI_WRITE_EXTENDED 0x2A
1da177e4 410#define SCSI_WRITE_AND_VERIFY 0x2E
1da177e4
LT
411
412
413
414#define SSGOOD 0x00
415#define SSCHECK 0x02
1da177e4
LT
416#define SSQ_FULL 0x28
417
418
1da177e4
LT
419
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
1da177e4
LT
426#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
1da177e4
LT
440#define SMWDTR 0x03
441#define SM8BIT 0x00
442#define SM16BIT 0x01
1da177e4
LT
443#define SMIGNORWR 0x23 /* Ignore Wide Residue */
444
445
1da177e4
LT
446
447
448
1da177e4
LT
449
450
451
452#define SIX_BYTE_CMD 0x06
1da177e4
LT
453#define TWELVE_BYTE_CMD 0x0C
454
455#define ASYNC 0x00
1da177e4
LT
456#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
457
1da177e4
LT
458
459#define EEPROM_WD_CNT 256
460
461#define EEPROM_CHECK_SUM 0
462#define FW_SIGNATURE 2
463#define MODEL_NUMB_0 4
1da177e4 464#define MODEL_NUMB_2 6
1da177e4 465#define MODEL_NUMB_4 8
1da177e4
LT
466#define SYSTEM_CONFIG 16
467#define SCSI_CONFIG 17
468#define BIOS_CONFIG 18
1da177e4
LT
469#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
1da177e4
LT
493 #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
1da177e4
LT
511
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
1da177e4 527 #define hp_sub_device_id_0 0x06 /* LSB */
1da177e4
LT
528
529
1da177e4
LT
530
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
1da177e4 537
1da177e4
LT
538
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 */
1da177e4 545
1da177e4 546
1da177e4 547
1da177e4
LT
548
549
1da177e4 550
1da177e4 551
1da177e4 552
1da177e4
LT
553
554 #define hp_host_blk_cnt 0x13
555
1da177e4
LT
556 #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
1da177e4
LT
561
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 */
1da177e4
LT
566
567
568 #define hp_xfer_cnt_lo 0x18
1da177e4
LT
569 #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 */
1da177e4
LT
574
575
576 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
1da177e4
LT
577
578 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
1da177e4
LT
579
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))
1da177e4
LT
584
585 #define hp_host_addr_lo 0x1C
1da177e4 586 #define hp_host_addr_hmi 0x1E
1da177e4 587
1da177e4
LT
588 #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
1da177e4 605
1da177e4 606
1da177e4
LT
607
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 */
1da177e4
LT
615 #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
1da177e4
LT
620
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)
1da177e4
LT
626 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
627 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
628
1da177e4 629
1da177e4 630
1da177e4
LT
631
632 #define hp_pci_stat_cfg 0x2D
633
1da177e4 634 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
1da177e4 635
1da177e4 636
1da177e4 637
1da177e4 638
1da177e4 639
1da177e4 640
1da177e4 641
1da177e4
LT
642
643 #define hp_rev_num 0x33
644
1da177e4
LT
645
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 */
1da177e4
LT
654 #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
1da177e4
LT
663 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
664 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
1da177e4 665 #define INT_ASSERTED BIT(5) /* */
1da177e4
LT
666
667
668 #define hp_fifo_cnt 0x38
1da177e4 669
1da177e4
LT
670
671
672
1da177e4
LT
673 #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))
1da177e4 709 #define S_MSGO_PH (BIT(2)+BIT(1) )
1da177e4
LT
710 #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
1da177e4
LT
717 #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
1da177e4
LT
738 #define SCSI_INI BIT(6)
739 #define SCAM_EN BIT(5)
1da177e4
LT
740 #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
1da177e4 746 #define hp_xfercnt_2 0x4A
1da177e4
LT
747
748 #define hp_fifodata_0 0x4C
1da177e4
LT
749 #define hp_addstat 0x4E
750
751 #define SCAM_TIMER BIT(7)
1da177e4
LT
752 #define SCSI_MODE8 BIT(3)
753 #define SCSI_PAR_ERR BIT(0)
754
755 #define hp_prgmcnt_0 0x4F
756
1da177e4
LT
757
758 #define hp_selfid_0 0x50
759 #define hp_selfid_1 0x51
760 #define hp_arb_id 0x52
761
1da177e4
LT
762
763 #define hp_select_id 0x53
764
1da177e4
LT
765
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
1da177e4 787 #define NARROW_SCSI BIT(4)
1da177e4
LT
788 #define DEFAULT_OFFSET 0x0F
789
790 #define hp_autostart_0 0x64
791 #define hp_autostart_1 0x65
1da177e4
LT
792 #define hp_autostart_3 0x67
793
794
795
1da177e4
LT
796 #define AUTO_IMMED BIT(5)
797 #define SELECT BIT(6)
1da177e4 798 #define END_DATA (BIT(7)+BIT(6))
1da177e4
LT
799
800 #define hp_gp_reg_0 0x68
801 #define hp_gp_reg_1 0x69
1da177e4
LT
802 #define hp_gp_reg_3 0x6B
803
804 #define hp_seltimeout 0x6C
805
806
1da177e4
LT
807 #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 */
1da177e4
LT
813
814 #define hp_clkctrl_0 0x6D
815
816 #define PWR_DWN BIT(6)
817 #define ACTdeassert BIT(4)
1da177e4 818 #define CLK_40MHZ (BIT(1) + BIT(0))
1da177e4
LT
819
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
1da177e4 828 #define FIFO_EMPTY BIT(6)
1da177e4
LT
829
830 #define hp_portctrl_1 0x72
831
1da177e4
LT
832 #define CHK_SCSI_P BIT(3)
833 #define HOST_MODE8 BIT(0)
1da177e4
LT
834
835 #define hp_xfer_pad 0x73
836
837 #define ID_UNLOCK BIT(3)
1da177e4
LT
838
839 #define hp_scsidata_0 0x74
840 #define hp_scsidata_1 0x75
1da177e4 841
1da177e4 842
1da177e4
LT
843
844 #define hp_aramBase 0x80
845 #define BIOS_DATA_OFFSET 0x60
846 #define BIOS_RELATIVE_CARD 0x64
847
848
849
850
1da177e4
LT
851 #define AR3 (BITW(9) + BITW(8))
852 #define SDATA BITW(10)
853
1da177e4
LT
854
855 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
856
857 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
858
1da177e4 859
1da177e4
LT
860
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))
1da177e4
LT
872
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
1da177e4 884 #define FIFO_0 BITW(10)
1da177e4
LT
885
886
887 #define MPM_OP BITW(15) /* Match phase and move data */
888
1da177e4
LT
889
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)
1da177e4
LT
898 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
899
900
1da177e4 901
1da177e4 902
1da177e4 903
1da177e4 904
1da177e4 905
1da177e4
LT
906
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)
1da177e4
LT
915
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 */
1da177e4
LT
929 #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. */
1da177e4
LT
934 #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
1da177e4
LT
947 #define DISCONNECT_START 0x10/2
948 #define END_DATA_START 0x14/2
1da177e4 949 #define CMD_ONLY_STRT CMDPZ/2
1da177e4
LT
950 #define SELCHK_STRT SELCHK/2
951
952
953
954
1da177e4 955
1da177e4
LT
956
957
1da177e4 958
1da177e4
LT
959
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 */
1da177e4
LT
965#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)))
1da177e4
LT
972
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
1da177e4 980
1da177e4
LT
981
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
1da177e4 999
47b5d69c
JB
1000static 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);
1da177e4 1014
47b5d69c
JB
1015static void FPT_SendMsg(ULONG port, UCHAR message);
1016static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1017 UCHAR error_code);
1da177e4 1018
47b5d69c
JB
1019static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1020static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1da177e4 1021
47b5d69c
JB
1022static 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);
1da177e4
LT
1025
1026
47b5d69c
JB
1027static 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[]);
1da177e4 1038
1da177e4 1039
47b5d69c
JB
1040static 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);
1da177e4
LT
1047
1048
1da177e4 1049
47b5d69c
JB
1050static 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);
1da177e4 1057
47b5d69c
JB
1058static 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);
1da177e4 1061
1da177e4 1062
1da177e4 1063
1da177e4 1064
47b5d69c
JB
1065static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1066static void FPT_BusMasterInit(ULONG p_port);
1067static void FPT_DiagEEPROM(ULONG p_port);
1da177e4 1068
1da177e4 1069
1da177e4
LT
1070
1071
47b5d69c
JB
1072static 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);
1da177e4 1077
1da177e4 1078
47b5d69c
JB
1079static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1080 PSCCBcard pCurrCard, USHORT p_int);
1da177e4 1081
47b5d69c
JB
1082static void FPT_SccbMgrTableInitAll(void);
1083static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1084static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
1da177e4 1085
1da177e4
LT
1086
1087
47b5d69c 1088static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
1da177e4 1089
47b5d69c
JB
1090static 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[]);
1da177e4 1105
1da177e4 1106
47b5d69c
JB
1107static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1108static void FPT_autoLoadDefaultMap(ULONG p_port);
1da177e4
LT
1109
1110
1111
1da177e4 1112
47b5d69c
JB
1113static 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 } };
1da177e4 1117
1da177e4 1118
47b5d69c
JB
1119static 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};
1da177e4 1124
47b5d69c 1125static USHORT FPT_default_intena = 0;
1da177e4
LT
1126
1127
47b5d69c 1128static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
1da177e4 1129
1da177e4
LT
1130
1131/*---------------------------------------------------------------------
1132 *
1133 * Function: SccbMgr_sense_adapter
1134 *
1135 * Description: Setup and/or Search for cards and return info to caller.
1136 *
1137 *---------------------------------------------------------------------*/
1138
47b5d69c 1139static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
1da177e4 1140{
1da177e4 1141 static UCHAR first_time = 1;
1da177e4
LT
1142
1143 UCHAR i,j,id,ScamFlg;
1144 USHORT temp,temp2,temp3,temp4,temp5,temp6;
1da177e4 1145 ULONG ioport;
1da177e4
LT
1146 PNVRamInfo pCurrNvRam;
1147
1da177e4 1148 ioport = pCardInfo->si_baseaddr;
1da177e4
LT
1149
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 {
47b5d69c 1177 FPT_SccbMgrTableInitAll();
1da177e4 1178 first_time = 0;
47b5d69c 1179 FPT_mbCards = 0;
1da177e4
LT
1180 }
1181
47b5d69c
JB
1182 if(FPT_RdStack(ioport, 0) != 0x00) {
1183 if(FPT_ChkIfChipInitialized(ioport) == 0)
1da177e4
LT
1184 {
1185 pCurrNvRam = NULL;
1186 WR_HARPOON(ioport+hp_semaphore, 0x00);
47b5d69c
JB
1187 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1188 FPT_DiagEEPROM(ioport);
1da177e4
LT
1189 }
1190 else
1191 {
47b5d69c
JB
1192 if(FPT_mbCards < MAX_MB_CARDS) {
1193 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1194 FPT_mbCards++;
1da177e4 1195 pCurrNvRam->niBaseAddr = ioport;
47b5d69c 1196 FPT_RNVRamData(pCurrNvRam);
1da177e4
LT
1197 }else
1198 return((int) FAILURE);
1199 }
1200 }else
1201 pCurrNvRam = NULL;
1da177e4
LT
1202
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
47b5d69c 1209 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1da177e4
LT
1210 (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
47b5d69c 1227 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1da177e4
LT
1228
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
47b5d69c 1266 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1da177e4
LT
1267
1268 if(pCurrNvRam)
1269 ScamFlg = pCurrNvRam->niScamConf;
1270 else
47b5d69c 1271 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1da177e4
LT
1272
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{
47b5d69c 1330 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1da177e4 1331 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
47b5d69c 1332 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1da177e4
LT
1333
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
47b5d69c
JB
1394 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;
1da177e4
LT
1402
1403 pCardInfo->si_present = 0x01;
1404
1da177e4
LT
1405 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
47b5d69c 1417static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
1da177e4
LT
1418{
1419 PSCCBcard CurrCard = NULL;
1420 PNVRamInfo pCurrNvRam;
1421 UCHAR i,j,thisCard, ScamFlg;
1422 USHORT temp,sync_bit_map,id;
1da177e4 1423 ULONG ioport;
1da177e4 1424
1da177e4 1425 ioport = pCardInfo->si_baseaddr;
1da177e4
LT
1426
1427 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1428
1429 if (thisCard == MAX_CARDS) {
1430
1431 return(FAILURE);
1432 }
1433
47b5d69c 1434 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1da177e4 1435
47b5d69c
JB
1436 CurrCard = &FPT_BL_Card[thisCard];
1437 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1da177e4
LT
1438 break;
1439 }
1440
47b5d69c 1441 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1da177e4 1442
47b5d69c
JB
1443 FPT_BL_Card[thisCard].ioPort = ioport;
1444 CurrCard = &FPT_BL_Card[thisCard];
1da177e4 1445
47b5d69c
JB
1446 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];
1da177e4 1450 }
47b5d69c 1451 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1da177e4
LT
1452 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{
47b5d69c 1465 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1da177e4
LT
1466 }
1467
1468
47b5d69c
JB
1469 FPT_BusMasterInit(ioport);
1470 FPT_XbowInit(ioport, ScamFlg);
1da177e4 1471
47b5d69c 1472 FPT_autoLoadDefaultMap(ioport);
1da177e4
LT
1473
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
47b5d69c 1499 FPT_sresb(ioport,thisCard);
1da177e4 1500
47b5d69c 1501 FPT_scini(thisCard, pCardInfo->si_id, 0);
1da177e4 1502 }
1da177e4 1503
1da177e4 1504
1da177e4 1505
47b5d69c
JB
1506 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1507 CurrCard->globalFlags |= F_NO_FILTER;
1da177e4 1508
47b5d69c
JB
1509 if(pCurrNvRam){
1510 if(pCurrNvRam->niSysConf & 0x10)
1511 CurrCard->globalFlags |= F_GREEN_PC;
1512 }
1513 else{
1514 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1515 CurrCard->globalFlags |= F_GREEN_PC;
1516 }
1da177e4 1517
47b5d69c
JB
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{
1525 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1526 CurrCard->globalFlags |= F_DO_RENEGO;
1527 }
1da177e4 1528
47b5d69c
JB
1529 if(pCurrNvRam){
1530 if(pCurrNvRam->niScsiConf & 0x08)
1531 CurrCard->globalFlags |= F_CONLUN_IO;
1532 }
1533 else{
1534 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1535 CurrCard->globalFlags |= F_CONLUN_IO;
1da177e4
LT
1536 }
1537
1da177e4 1538
47b5d69c 1539 temp = pCardInfo->si_per_targ_no_disc;
1da177e4 1540
47b5d69c 1541 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1da177e4 1542
47b5d69c
JB
1543 if (temp & id)
1544 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1545 }
1da177e4 1546
47b5d69c 1547 sync_bit_map = 0x0001;
1da177e4 1548
47b5d69c 1549 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1da177e4 1550
47b5d69c
JB
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
1556 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1da177e4 1557
47b5d69c 1558 for (i = 0; i < 2; temp >>=8,i++) {
1da177e4 1559
47b5d69c 1560 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1da177e4 1561
47b5d69c
JB
1562 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
1563 }
1da177e4 1564
47b5d69c
JB
1565 else {
1566 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1567 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1568 (UCHAR)(temp & ~EE_SYNC_MASK);
1569 }
1da177e4 1570
47b5d69c
JB
1571/* 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){
1da177e4 1575
47b5d69c 1576 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1da177e4 1577
47b5d69c 1578 }
1da177e4 1579
47b5d69c
JB
1580 else { /* NARROW SCSI */
1581 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1582 }
1da177e4 1583
1da177e4 1584
47b5d69c 1585 sync_bit_map <<= 1;
1da177e4 1586
1da177e4 1587
1da177e4 1588
47b5d69c
JB
1589 }
1590 }
1da177e4 1591
47b5d69c
JB
1592 WR_HARPOON((ioport+hp_semaphore),
1593 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1da177e4 1594
47b5d69c
JB
1595 return((ULONG)CurrCard);
1596}
1597
1598static void SccbMgr_unload_card(ULONG pCurrCard)
1da177e4
LT
1599{
1600 UCHAR i;
1da177e4
LT
1601 ULONG portBase;
1602 ULONG regOffset;
1da177e4 1603 ULONG scamData;
1da177e4 1604 ULONG *pScamTbl;
1da177e4
LT
1605 PNVRamInfo pCurrNvRam;
1606
1607 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1608
1609 if(pCurrNvRam){
47b5d69c
JB
1610 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);
1da177e4
LT
1615
1616 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
47b5d69c 1617 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
1da177e4
LT
1618
1619 portBase = pCurrNvRam->niBaseAddr;
1620
1621 for(i = 0; i < MAX_SCSI_TAR; i++){
1622 regOffset = hp_aramBase + 64 + i*4;
1da177e4 1623 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1da177e4
LT
1624 scamData = *pScamTbl;
1625 WR_HARP32(portBase, regOffset, scamData);
1626 }
1627
1628 }else{
47b5d69c 1629 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1da177e4
LT
1630 }
1631}
1da177e4
LT
1632
1633
47b5d69c 1634static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1da177e4
LT
1635{
1636 UCHAR i;
1da177e4
LT
1637 ULONG portBase;
1638 ULONG regOffset;
1da177e4 1639 ULONG scamData;
1da177e4 1640 ULONG *pScamTbl;
1da177e4 1641
47b5d69c
JB
1642 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);
1da177e4
LT
1647
1648 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
47b5d69c 1649 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
1da177e4
LT
1650
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);
1da177e4 1656 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1da177e4
LT
1657 *pScamTbl = scamData;
1658 }
1659
1660}
1661
47b5d69c 1662static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
1da177e4
LT
1663{
1664 WR_HARPOON(portBase + hp_stack_addr, index);
1665 return(RD_HARPOON(portBase + hp_stack_data));
1666}
1667
47b5d69c 1668static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
1da177e4
LT
1669{
1670 WR_HARPOON(portBase + hp_stack_addr, index);
1671 WR_HARPOON(portBase + hp_stack_data, data);
1672}
1673
1674
47b5d69c 1675static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
1da177e4 1676{
47b5d69c
JB
1677 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1678 return(0);
1da177e4
LT
1679 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1680 != CLKCTRL_DEFAULT)
47b5d69c 1681 return(0);
1da177e4
LT
1682 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1683 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
47b5d69c
JB
1684 return(1);
1685 return(0);
1da177e4
LT
1686
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 *---------------------------------------------------------------------*/
47b5d69c 1697static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
1da177e4 1698{
1da177e4 1699 ULONG ioport;
1da177e4
LT
1700 UCHAR thisCard, lun;
1701 PSCCB pSaveSccb;
1702 CALL_BK_FN callback;
1703
1da177e4
LT
1704 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1705 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1706
1da177e4
LT
1707 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1708 {
1709
1da177e4
LT
1710 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);
1da177e4 1715
1da177e4
LT
1716 return;
1717 }
1718
47b5d69c 1719 FPT_sinits(p_Sccb,thisCard);
1da177e4
LT
1720
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;
47b5d69c 1744 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1745 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1746 }
1747 else
1748 {
47b5d69c 1749 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1750 }
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;
47b5d69c 1759 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1760 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1761 }
1762 else
1763 {
47b5d69c 1764 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1765 }
1766 }
1767
1768 else {
1769
1770 MDISABLE_INT(ioport);
1771
1772 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
47b5d69c 1773 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1da177e4
LT
1774 lun = p_Sccb->Lun;
1775 else
1776 lun = 0;
1777 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
47b5d69c
JB
1778 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1779 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1780 == 0)) {
1da177e4
LT
1781
1782 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1783 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1da177e4
LT
1784 }
1785
1786 else {
1787
1788 if(p_Sccb->OperationCode == RESET_COMMAND)
1789 {
1790 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1791 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1792 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1793 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1794 }
1795 else
1796 {
47b5d69c 1797 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1798 }
1799 }
1800
1801
1802 MENABLE_INT(ioport);
1803 }
1804
1da177e4
LT
1805}
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 *---------------------------------------------------------------------*/
47b5d69c 1817static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
1da177e4 1818{
1da177e4 1819 ULONG ioport;
1da177e4
LT
1820
1821 UCHAR thisCard;
1822 CALL_BK_FN callback;
1823 UCHAR TID;
1824 PSCCB pSaveSCCB;
1825 PSCCBMgr_tar_info currTar_Info;
1826
1827
1da177e4
LT
1828 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1829
1830 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1831
47b5d69c 1832 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1da177e4
LT
1833 {
1834
47b5d69c 1835 if (FPT_queueFindSccb(p_Sccb,thisCard))
1da177e4
LT
1836 {
1837
1da177e4
LT
1838 ((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
1da177e4
LT
1844 p_Sccb->SccbStatus = SCCB_ABORT;
1845 callback = p_Sccb->SccbCallback;
1846 callback(p_Sccb);
1da177e4
LT
1847
1848 return(0);
1849 }
1850
1851 else
1852 {
1da177e4
LT
1853 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;
1da177e4
LT
1873 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1874
1875 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1876 {
1877 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1878 FPT_ssel(ioport, thisCard);
1da177e4
LT
1879 }
1880 else
1881 {
1882 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1883 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1884 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1da177e4
LT
1885 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1886 }
1887 }
1888 MENABLE_INT(ioport);
1889 return(0);
1890 }
1891 else
1892 {
47b5d69c 1893 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1da177e4 1894
47b5d69c 1895 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1da177e4
LT
1896 == 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 *---------------------------------------------------------------------*/
47b5d69c 1917static UCHAR SccbMgr_my_int(ULONG pCurrCard)
1da177e4 1918{
1da177e4 1919 ULONG ioport;
1da177e4
LT
1920
1921 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1922
1923 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1924 {
47b5d69c 1925 return(1);
1da177e4
LT
1926 }
1927
1928 else
1929
47b5d69c 1930 return(0);
1da177e4
LT
1931}
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 *---------------------------------------------------------------------*/
47b5d69c 1944static int SccbMgr_isr(ULONG pCurrCard)
1da177e4
LT
1945{
1946 PSCCB currSCCB;
1947 UCHAR thisCard,result,bm_status, bm_int_st;
1948 USHORT hp_int;
1949 UCHAR i, target;
1da177e4 1950 ULONG ioport;
1da177e4
LT
1951
1952 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1953 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1954
1955 MDISABLE_INT(ioport);
1956
1da177e4
LT
1957 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
47b5d69c 1964 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1da177e4
LT
1965 bm_status)
1966 {
1967
1968 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1969
1da177e4 1970 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
47b5d69c 1971 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1da177e4
LT
1972 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1973 bm_status = 0;
1974
1975 if (result) {
1976
1da177e4 1977 MENABLE_INT(ioport);
1da177e4
LT
1978 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
47b5d69c 1996 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
1997
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
47b5d69c 2004 FPT_autoCmdCmplt(ioport,thisCard);
1da177e4
LT
2005
2006 }
2007
2008
2009 else if (hp_int & ITAR_DISC)
2010 {
2011
2012 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2013
47b5d69c 2014 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
2015
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;
47b5d69c 2027 FPT_queueDisconnect(currSCCB,thisCard);
1da177e4
LT
2028
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 {
1da177e4 2046 MENABLE_INT(ioport);
1da177e4
LT
2047 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 {
47b5d69c 2066 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
2067 }
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;
47b5d69c 2078 FPT_queueDisconnect(currSCCB,thisCard);
1da177e4
LT
2079 }
2080
47b5d69c
JB
2081 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2082 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2083
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));
47b5d69c 2091 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2092
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 {
47b5d69c 2101 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2102 }
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
47b5d69c 2126 FPT_schkdd(ioport,thisCard);
1da177e4
LT
2127
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
47b5d69c 2137 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
1da177e4
LT
2138 }
2139
47b5d69c 2140 FPT_phaseBusFree(ioport,thisCard);
1da177e4
LT
2141 }
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
47b5d69c 2160 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
1da177e4
LT
2161 }
2162
2163 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2164 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
47b5d69c 2165 FPT_ssel(ioport,thisCard);
1da177e4
LT
2166 }
2167
2168 break;
2169
2170 }
2171
2172 } /*end while */
2173
1da177e4 2174 MENABLE_INT(ioport);
1da177e4
LT
2175
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 *---------------------------------------------------------------------*/
47b5d69c
JB
2189static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2190 PSCCBcard pCurrCard, USHORT p_int)
1da177e4 2191{
47b5d69c
JB
2192 UCHAR temp, ScamFlg;
2193 PSCCBMgr_tar_info currTar_Info;
2194 PNVRamInfo pCurrNvRam;
1da177e4
LT
2195
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
47b5d69c 2204 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
1da177e4
LT
2205 }
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
47b5d69c 2223 FPT_sxfrp(p_port,p_card);
1da177e4
LT
2224
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 {
47b5d69c 2232 FPT_phaseDecode(p_port,p_card);
1da177e4
LT
2233 }
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
47b5d69c 2247 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
1da177e4
LT
2248 }
2249
2250
2251 DISABLE_AUTO(p_port);
2252
47b5d69c 2253 FPT_sresb(p_port,p_card);
1da177e4
LT
2254
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{
47b5d69c 2262 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
1da177e4
LT
2263 }
2264
47b5d69c 2265 FPT_XbowInit(p_port, ScamFlg);
1da177e4 2266
47b5d69c 2267 FPT_scini(p_card, pCurrCard->ourId, 0);
1da177e4
LT
2268
2269 return(0xFF);
2270 }
2271
2272
2273 else if (p_int & FIFO) {
2274
2275 WRW_HARPOON((p_port+hp_intstat), FIFO);
2276
1da177e4 2277 if (pCurrCard->currentSCCB != NULL)
47b5d69c 2278 FPT_sxfrp(p_port,p_card);
1da177e4
LT
2279 }
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
47b5d69c 2292 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2293 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2294 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
47b5d69c 2295 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
1da177e4 2296 else
47b5d69c 2297 currTar_Info->TarLUNBusy[0] = 0;
1da177e4
LT
2298
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
47b5d69c 2311 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
1da177e4 2312
47b5d69c 2313 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
1da177e4 2314
1da177e4
LT
2315 }
2316
47b5d69c 2317 else if (p_int & SCAM_SEL)
1da177e4 2318 {
1da177e4 2319
47b5d69c
JB
2320 FPT_scarb(p_port,LEVEL2_TAR);
2321 FPT_scsel(p_port);
2322 FPT_scasid(p_card, p_port);
1da177e4 2323
47b5d69c 2324 FPT_scbusf(p_port);
1da177e4 2325
47b5d69c 2326 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
1da177e4
LT
2327 }
2328
47b5d69c 2329 return(0x00);
1da177e4
LT
2330}
2331
1da177e4
LT
2332
2333/*---------------------------------------------------------------------
2334 *
2335 * Function: SccbMgrTableInit
2336 *
2337 * Description: Initialize all Sccb manager data structures.
2338 *
2339 *---------------------------------------------------------------------*/
2340
47b5d69c 2341static void FPT_SccbMgrTableInitAll()
1da177e4
LT
2342{
2343 UCHAR thisCard;
2344
2345 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2346 {
47b5d69c 2347 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
1da177e4 2348
47b5d69c
JB
2349 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;
1da177e4
LT
2354 }
2355}
2356
2357
2358/*---------------------------------------------------------------------
2359 *
2360 * Function: SccbMgrTableInit
2361 *
2362 * Description: Initialize all Sccb manager data structures.
2363 *
2364 *---------------------------------------------------------------------*/
2365
47b5d69c 2366static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
1da177e4
LT
2367{
2368 UCHAR scsiID, qtag;
2369
2370 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2371 {
47b5d69c 2372 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
2373 }
2374
2375 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2376 {
47b5d69c
JB
2377 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2378 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2379 FPT_SccbMgrTableInitTarget(p_card, scsiID);
1da177e4
LT
2380 }
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
47b5d69c 2401static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
1da177e4
LT
2402{
2403
2404 UCHAR lun, qtag;
2405 PSCCBMgr_tar_info currTar_Info;
2406
47b5d69c 2407 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2408
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;
47b5d69c 2415 currTar_Info->TarLUN_CA = 0;
1da177e4
LT
2416
2417
2418 for (lun = 0; lun < MAX_LUN; lun++)
2419 {
47b5d69c 2420 currTar_Info->TarLUNBusy[lun] = 0;
1da177e4
LT
2421 currTar_Info->LunDiscQ_Idx[lun] = 0;
2422 }
2423
2424 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2425 {
47b5d69c 2426 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
1da177e4 2427 {
47b5d69c 2428 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
1da177e4 2429 {
47b5d69c
JB
2430 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2431 FPT_BL_Card[p_card].discQCount--;
1da177e4
LT
2432 }
2433 }
2434 }
2435}
2436
1da177e4
LT
2437
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
47b5d69c 2447static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
1da177e4
LT
2448{
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 *
47b5d69c 2514 * Function: FPT_ssel
1da177e4
LT
2515 *
2516 * Description: Load up automation and select target device.
2517 *
2518 *---------------------------------------------------------------------*/
2519
47b5d69c 2520static void FPT_ssel(ULONG port, UCHAR p_card)
1da177e4
LT
2521{
2522
1da177e4 2523 UCHAR auto_loaded, i, target, *theCCB;
1da177e4 2524
1da177e4 2525 ULONG cdb_reg;
1da177e4
LT
2526 PSCCBcard CurrCard;
2527 PSCCB currSCCB;
2528 PSCCBMgr_tar_info currTar_Info;
2529 UCHAR lastTag, lun;
2530
47b5d69c 2531 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
2532 currSCCB = CurrCard->currentSCCB;
2533 target = currSCCB->TargID;
47b5d69c 2534 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2535 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
1da177e4
LT
2551 if (CurrCard->globalFlags & F_TAG_STARTED)
2552 {
2553 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2554 {
47b5d69c 2555 if ((currTar_Info->TarLUN_CA == 0)
1da177e4
LT
2556 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2557 == TAG_Q_TRYING))
2558 {
2559
2560 if (currTar_Info->TarTagQ_Cnt !=0)
2561 {
47b5d69c
JB
2562 currTar_Info->TarLUNBusy[lun] = 1;
2563 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2564 SGRAM_ACCESS(port);
2565 return;
2566 }
2567
2568 else {
47b5d69c 2569 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2570 }
2571
2572 } /*End non-tagged */
2573
2574 else {
47b5d69c 2575 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2576 }
2577
2578 } /*!Use cmd Q Tagged */
2579
2580 else {
47b5d69c 2581 if (currTar_Info->TarLUN_CA == 1)
1da177e4 2582 {
47b5d69c 2583 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2584 SGRAM_ACCESS(port);
2585 return;
2586 }
2587
47b5d69c 2588 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2589
2590 } /*else use cmd Q tagged */
2591
2592 } /*if glob tagged started */
2593
2594 else {
47b5d69c 2595 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2596 }
2597
1da177e4
LT
2598
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 {
47b5d69c
JB
2606 currTar_Info->TarLUNBusy[lun] = 1;
2607 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2608 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 {
47b5d69c
JB
2625 currTar_Info->TarLUNBusy[lun] = 1;
2626 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2627 SGRAM_ACCESS(port);
2628 return;
2629 }
2630 }
2631
2632
2633
47b5d69c 2634 auto_loaded = 0;
1da177e4
LT
2635
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));
47b5d69c 2648 auto_loaded = 1;
1da177e4
LT
2649 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
1da177e4
LT
2657 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2658 {
2659 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2660 }
1da177e4 2661
47b5d69c
JB
2662 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2663 FPT_SccbMgrTableInitTarget(p_card, target);
1da177e4
LT
2664
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));
47b5d69c 2682 auto_loaded = 1;
1da177e4
LT
2683
2684 }
2685
1da177e4 2686 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
47b5d69c 2687 auto_loaded = FPT_siwidn(port,p_card);
1da177e4
LT
2688 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2689 }
2690
1da177e4
LT
2691 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2692 == SYNC_SUPPORTED)) {
47b5d69c 2693 auto_loaded = FPT_sisyncn(port,p_card, 0);
1da177e4
LT
2694 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2695 }
2696
2697
2698 if (!auto_loaded)
2699 {
2700
1da177e4
LT
2701 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
47b5d69c 2724 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2725 }
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 {
47b5d69c
JB
2753 currTar_Info->TarLUNBusy[lun] = 1;
2754 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2755 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 {
1da177e4
LT
2767
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));
1da177e4 2776 }
1da177e4
LT
2777
2778
1da177e4 2779 theCCB = (UCHAR *)&currSCCB->Cdb[0];
1da177e4
LT
2780
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
1da177e4
LT
2795 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2796 WR_HARPOON(port+hp_xferstat, 0x00);
1da177e4
LT
2797
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 *
47b5d69c 2825 * Function: FPT_sres
1da177e4
LT
2826 *
2827 * Description: Hookup the correct CCB and handle the incoming messages.
2828 *
2829 *---------------------------------------------------------------------*/
2830
47b5d69c 2831static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
1da177e4
LT
2832{
2833
1da177e4 2834 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
1da177e4
LT
2835
2836
2837 PSCCBMgr_tar_info currTar_Info;
2838 PSCCB currSCCB;
2839
2840
2841
2842
2843 if(pCurrCard->currentSCCB != NULL)
2844 {
47b5d69c 2845 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2846 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 {
47b5d69c 2866 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
1da177e4
LT
2867 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 {
47b5d69c 2876 currTar_Info->TarLUNBusy[0] = 0;
1da177e4
LT
2877 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
47b5d69c 2894 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
2895 }
2896
1da177e4 2897 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
1da177e4
LT
2898
2899
2900 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
47b5d69c 2901 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2902
2903
2904 msgRetryCount = 0;
2905 do
2906 {
2907
47b5d69c 2908 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2909 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
47b5d69c 2926 message = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2927 if (message)
2928 {
2929
2930 if (message <= (0x80 | LUN_MASK))
2931 {
2932 lun = message & (UCHAR)LUN_MASK;
2933
1da177e4
LT
2934 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
47b5d69c 2944 message = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2945 if (message)
2946 {
2947 ACCEPT_MSG(port);
2948 }
2949
2950 else
47b5d69c 2951 message = 0;
1da177e4 2952
47b5d69c 2953 if(message != 0)
1da177e4 2954 {
47b5d69c 2955 tag = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2956
2957 if (!(tag))
47b5d69c 2958 message = 0;
1da177e4
LT
2959 }
2960
2961 } /*C.A. exists! */
2962
2963 } /*End Q cnt != 0 */
2964
2965 } /*End Tag cmds supported! */
1da177e4
LT
2966
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
47b5d69c 2980 message = 0;
1da177e4
LT
2981 }
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 }
1da177e4 2993
47b5d69c 2994 if(message == 0)
1da177e4
LT
2995 {
2996 msgRetryCount++;
2997 if(msgRetryCount == 1)
2998 {
47b5d69c 2999 FPT_SendMsg(port, SMPARITY);
1da177e4
LT
3000 }
3001 else
3002 {
47b5d69c 3003 FPT_SendMsg(port, SMDEV_RESET);
1da177e4 3004
47b5d69c 3005 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
1da177e4 3006
47b5d69c 3007 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
1da177e4
LT
3008 {
3009
47b5d69c 3010 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
3011
3012 }
3013
47b5d69c 3014 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
1da177e4
LT
3015 {
3016
47b5d69c 3017 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
3018 }
3019
3020
47b5d69c
JB
3021 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3022 FPT_SccbMgrTableInitTarget(p_card,our_target);
1da177e4
LT
3023 return;
3024 }
3025 }
47b5d69c 3026 }while(message == 0);
1da177e4
LT
3027
3028
3029
3030 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3031 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3032 {
47b5d69c 3033 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
3034 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 {
47b5d69c 3046 currTar_Info->TarLUNBusy[0] = 1;
1da177e4
LT
3047
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 */
47b5d69c 3082 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
1da177e4
LT
3083 }
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
47b5d69c 3092static void FPT_SendMsg(ULONG port, UCHAR message)
1da177e4
LT
3093{
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 *
47b5d69c 3135 * Function: FPT_sdecm
1da177e4
LT
3136 *
3137 * Description: Determine the proper responce to the message from the
3138 * target device.
3139 *
3140 *---------------------------------------------------------------------*/
47b5d69c 3141static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
1da177e4
LT
3142{
3143 PSCCB currSCCB;
3144 PSCCBcard CurrCard;
3145 PSCCBMgr_tar_info currTar_Info;
3146
47b5d69c 3147 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
3148 currSCCB = CurrCard->currentSCCB;
3149
47b5d69c 3150 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3151
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
47b5d69c 3158 FPT_hostDataXferRestart(currSCCB);
1da177e4
LT
3159 }
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
1da177e4
LT
3214 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 }
1da177e4
LT
3224
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))
47b5d69c 3255 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
1da177e4 3256 else
47b5d69c 3257 currTar_Info->TarLUNBusy[0] = 1;
1da177e4
LT
3258
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);
47b5d69c 3285 FPT_shandem(port,p_card,currSCCB);
1da177e4
LT
3286 }
3287
3288 else if (message == SMIGNORWR)
3289 {
3290
3291 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3292
47b5d69c 3293 message = FPT_sfm(port,currSCCB);
1da177e4
LT
3294
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 *
47b5d69c 3315 * Function: FPT_shandem
1da177e4
LT
3316 *
3317 * Description: Decide what to do with the extended message.
3318 *
3319 *---------------------------------------------------------------------*/
47b5d69c 3320static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
1da177e4
LT
3321{
3322 UCHAR length,message;
3323
47b5d69c 3324 length = FPT_sfm(port,pCurrSCCB);
1da177e4
LT
3325 if (length)
3326 {
3327
3328 ACCEPT_MSG(port);
47b5d69c 3329 message = FPT_sfm(port,pCurrSCCB);
1da177e4
LT
3330 if (message)
3331 {
3332
3333 if (message == SMSYNC)
3334 {
3335
3336 if (length == 0x03)
3337 {
3338
3339 ACCEPT_MSG(port);
47b5d69c 3340 FPT_stsyncn(port,p_card);
1da177e4
LT
3341 }
3342 else
3343 {
3344
3345 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3346 ACCEPT_MSG_ATN(port);
3347 }
3348 }
1da177e4
LT
3349 else if (message == SMWDTR)
3350 {
3351
3352 if (length == 0x02)
3353 {
3354
3355 ACCEPT_MSG(port);
47b5d69c 3356 FPT_stwidn(port,p_card);
1da177e4
LT
3357 }
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 }
1da177e4
LT
3367 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 *
47b5d69c 3392 * Function: FPT_sisyncn
1da177e4
LT
3393 *
3394 * Description: Read in a message byte from the SCSI bus, and check
3395 * for a parity error.
3396 *
3397 *---------------------------------------------------------------------*/
3398
47b5d69c 3399static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
1da177e4
LT
3400{
3401 PSCCB currSCCB;
3402 PSCCBMgr_tar_info currTar_Info;
3403
47b5d69c
JB
3404 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3405 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3406
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
47b5d69c 3441 if(syncFlag == 0)
1da177e4
LT
3442 {
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
47b5d69c 3453 return(1);
1da177e4
LT
3454 }
3455
3456 else {
3457
3458 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3459 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
47b5d69c 3460 return(0);
1da177e4
LT
3461 }
3462}
3463
3464
3465
3466/*---------------------------------------------------------------------
3467 *
47b5d69c 3468 * Function: FPT_stsyncn
1da177e4
LT
3469 *
3470 * Description: The has sent us a Sync Nego message so handle it as
3471 * necessary.
3472 *
3473 *---------------------------------------------------------------------*/
47b5d69c 3474static void FPT_stsyncn(ULONG port, UCHAR p_card)
1da177e4
LT
3475{
3476 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3477 PSCCB currSCCB;
3478 PSCCBMgr_tar_info currTar_Info;
3479
47b5d69c
JB
3480 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3481 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3482
47b5d69c 3483 sync_msg = FPT_sfm(port,currSCCB);
1da177e4
LT
3484
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
47b5d69c 3494 offset = FPT_sfm(port,currSCCB);
1da177e4
LT
3495
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
1da177e4
LT
3564 if (currTar_Info->TarStatus & WIDE_ENABLED)
3565
3566 sync_reg |= offset;
3567
3568 else
3569
3570 sync_reg |= (offset | NARROW_SCSI);
3571
47b5d69c 3572 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
1da177e4
LT
3573
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
47b5d69c 3591 FPT_sisyncr(port,sync_msg,offset);
1da177e4
LT
3592
3593 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3594 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3595 }
3596}
3597
3598
3599/*---------------------------------------------------------------------
3600 *
47b5d69c 3601 * Function: FPT_sisyncr
1da177e4
LT
3602 *
3603 * Description: Answer the targets sync message.
3604 *
3605 *---------------------------------------------------------------------*/
47b5d69c 3606static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
1da177e4
LT
3607{
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
1da177e4
LT
3628/*---------------------------------------------------------------------
3629 *
47b5d69c 3630 * Function: FPT_siwidn
1da177e4
LT
3631 *
3632 * Description: Read in a message byte from the SCSI bus, and check
3633 * for a parity error.
3634 *
3635 *---------------------------------------------------------------------*/
3636
47b5d69c 3637static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
1da177e4
LT
3638{
3639 PSCCB currSCCB;
3640 PSCCBMgr_tar_info currTar_Info;
3641
47b5d69c
JB
3642 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3643 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3644
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
47b5d69c 3666 return(1);
1da177e4
LT
3667 }
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;
47b5d69c 3675 return(0);
1da177e4
LT
3676 }
3677}
3678
3679
3680
3681/*---------------------------------------------------------------------
3682 *
47b5d69c 3683 * Function: FPT_stwidn
1da177e4
LT
3684 *
3685 * Description: The has sent us a Wide Nego message so handle it as
3686 * necessary.
3687 *
3688 *---------------------------------------------------------------------*/
47b5d69c 3689static void FPT_stwidn(ULONG port, UCHAR p_card)
1da177e4
LT
3690{
3691 UCHAR width;
3692 PSCCB currSCCB;
3693 PSCCBMgr_tar_info currTar_Info;
3694
47b5d69c
JB
3695 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3696 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3697
47b5d69c 3698 width = FPT_sfm(port,currSCCB);
1da177e4
LT
3699
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
47b5d69c 3720 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
1da177e4
LT
3721
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);
47b5d69c 3734 FPT_sisyncn(port,p_card, 1);
1da177e4
LT
3735 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
47b5d69c 3755 FPT_siwidr(port,width);
1da177e4
LT
3756
3757 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3758 }
3759}
3760
3761
3762/*---------------------------------------------------------------------
3763 *
47b5d69c 3764 * Function: FPT_siwidr
1da177e4
LT
3765 *
3766 * Description: Answer the targets Wide nego message.
3767 *
3768 *---------------------------------------------------------------------*/
47b5d69c 3769static void FPT_siwidr(ULONG port, UCHAR width)
1da177e4
LT
3770{
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
1da177e4
LT
3788
3789
3790/*---------------------------------------------------------------------
3791 *
47b5d69c 3792 * Function: FPT_sssyncv
1da177e4
LT
3793 *
3794 * Description: Write the desired value to the Sync Register for the
3795 * ID specified.
3796 *
3797 *---------------------------------------------------------------------*/
47b5d69c
JB
3798static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
3799 PSCCBMgr_tar_info currTar_Info)
1da177e4
LT
3800{
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 *
47b5d69c 3865 * Function: FPT_sresb
1da177e4
LT
3866 *
3867 * Description: Reset the desired card's SCSI bus.
3868 *
3869 *---------------------------------------------------------------------*/
47b5d69c 3870static void FPT_sresb(ULONG port, UCHAR p_card)
1da177e4
LT
3871{
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
47b5d69c 3894 FPT_Wait(port, TO_5ms);
1da177e4
LT
3895
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 {
47b5d69c 3902 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4
LT
3903
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
47b5d69c 3915 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
1da177e4 3916
47b5d69c 3917 FPT_SccbMgrTableInitTarget(p_card, scsiID);
1da177e4
LT
3918 }
3919
47b5d69c
JB
3920 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
1da177e4 3923 | F_NEW_SCCB_CMD);
47b5d69c
JB
3924 FPT_BL_Card[p_card].cmdCounter = 0x00;
3925 FPT_BL_Card[p_card].discQCount = 0x00;
3926 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
1da177e4
LT
3927
3928 for(i = 0; i < QUEUE_DEPTH; i++)
47b5d69c 3929 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
1da177e4
LT
3930
3931 WR_HARPOON(port+hp_page_ctrl,
3932 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3933
3934}
3935
3936/*---------------------------------------------------------------------
3937 *
47b5d69c 3938 * Function: FPT_ssenss
1da177e4
LT
3939 *
3940 * Description: Setup for the Auto Sense command.
3941 *
3942 *---------------------------------------------------------------------*/
47b5d69c 3943static void FPT_ssenss(PSCCBcard pCurrCard)
1da177e4
LT
3944{
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 *
47b5d69c 3985 * Function: FPT_sxfrp
1da177e4
LT
3986 *
3987 * Description: Transfer data into the bit bucket until the device
3988 * decides to switch phase.
3989 *
3990 *---------------------------------------------------------------------*/
3991
47b5d69c 3992static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
1da177e4
LT
3993{
3994 UCHAR curr_phz;
3995
3996
3997 DISABLE_AUTO(p_port);
3998
47b5d69c 3999 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
1da177e4 4000
47b5d69c 4001 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
1da177e4
LT
4002
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 *
47b5d69c 4067 * Function: FPT_schkdd
1da177e4
LT
4068 *
4069 * Description: Make sure data has been flushed from both FIFOs and abort
4070 * the operations if necessary.
4071 *
4072 *---------------------------------------------------------------------*/
4073
47b5d69c 4074static void FPT_schkdd(ULONG port, UCHAR p_card)
1da177e4
LT
4075{
4076 USHORT TimeOutLoop;
4077 UCHAR sPhase;
4078
4079 PSCCB currSCCB;
4080
47b5d69c 4081 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4082
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
47b5d69c 4119 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4
LT
4120
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) {
47b5d69c 4153 FPT_phaseDataIn(port,p_card);
1da177e4
LT
4154 }
4155
4156 else {
47b5d69c 4157 FPT_phaseDataOut(port,p_card);
1da177e4
LT
4158 }
4159 }
4160 else
4161 {
47b5d69c 4162 FPT_sxfrp(port,p_card);
1da177e4
LT
4163 if (!(RDW_HARPOON((port+hp_intstat)) &
4164 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4165 {
4166 WRW_HARPOON((port+hp_intstat), AUTO_INT);
47b5d69c 4167 FPT_phaseDecode(port,p_card);
1da177e4
LT
4168 }
4169 }
4170
4171 }
4172
4173 else {
4174 WR_HARPOON(port+hp_portctrl_0, 0x00);
4175 }
4176}
4177
4178
4179/*---------------------------------------------------------------------
4180 *
47b5d69c 4181 * Function: FPT_sinits
1da177e4
LT
4182 *
4183 * Description: Setup SCCB manager fields in this SCCB.
4184 *
4185 *---------------------------------------------------------------------*/
4186
47b5d69c 4187static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
1da177e4
LT
4188{
4189 PSCCBMgr_tar_info currTar_Info;
4190
4191 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4192 {
4193 return;
4194 }
47b5d69c 4195 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4
LT
4196
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/*
47b5d69c 4226 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
1da177e4
LT
4227 (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
1da177e4
LT
4259/*---------------------------------------------------------------------
4260 *
4261 * Function: Phase Decode
4262 *
4263 * Description: Determine the phase and call the appropriate function.
4264 *
4265 *---------------------------------------------------------------------*/
4266
47b5d69c 4267static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
1da177e4
LT
4268{
4269 unsigned char phase_ref;
47b5d69c 4270 void (*phase) (ULONG, UCHAR);
1da177e4
LT
4271
4272
4273 DISABLE_AUTO(p_port);
4274
4275 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4276
47b5d69c 4277 phase = FPT_s_PhaseTbl[phase_ref];
1da177e4
LT
4278
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
47b5d69c 4292static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
1da177e4
LT
4293{
4294
4295 PSCCB currSCCB;
4296
47b5d69c 4297 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4298 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
47b5d69c 4312 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4313
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
47b5d69c 4321 FPT_sxfrp(port,p_card);
1da177e4 4322 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
47b5d69c 4323 FPT_phaseDecode(port,p_card);
1da177e4
LT
4324 }
4325}
4326
4327
4328/*---------------------------------------------------------------------
4329 *
4330 * Function: Data In Phase
4331 *
4332 * Description: Startup the BusMaster and the XBOW.
4333 *
4334 *---------------------------------------------------------------------*/
4335
47b5d69c 4336static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
1da177e4
LT
4337{
4338
4339 PSCCB currSCCB;
4340
47b5d69c 4341 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4342
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
47b5d69c 4359 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4360
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
47b5d69c 4368 FPT_sxfrp(port,p_card);
1da177e4 4369 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
47b5d69c 4370 FPT_phaseDecode(port,p_card);
1da177e4
LT
4371
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
47b5d69c 4383static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
1da177e4
LT
4384{
4385 PSCCB currSCCB;
1da177e4 4386 ULONG cdb_reg;
1da177e4
LT
4387 UCHAR i;
4388
47b5d69c 4389 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4390
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
47b5d69c 4435static void FPT_phaseStatus(ULONG port, UCHAR p_card)
1da177e4
LT
4436{
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
47b5d69c 4457static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
1da177e4
LT
4458{
4459 UCHAR message,scsiID;
4460 PSCCB currSCCB;
4461 PSCCBMgr_tar_info currTar_Info;
4462
47b5d69c 4463 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4464
4465 if (currSCCB != NULL) {
4466
4467 message = currSCCB->Sccb_scsimsg;
4468 scsiID = currSCCB->TargID;
4469
4470 if (message == SMDEV_RESET)
4471 {
4472
4473
47b5d69c 4474 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4 4475 currTar_Info->TarSyncCtrl = 0;
47b5d69c 4476 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
1da177e4 4477
47b5d69c 4478 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
1da177e4
LT
4479 {
4480
47b5d69c 4481 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
4482
4483 }
4484
47b5d69c 4485 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
1da177e4
LT
4486 {
4487
47b5d69c 4488 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
4489 }
4490
4491
47b5d69c
JB
4492 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4493 FPT_SccbMgrTableInitTarget(p_card,scsiID);
1da177e4
LT
4494 }
4495 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4496 {
4497 currSCCB->HostStatus = SCCB_COMPLETE;
47b5d69c 4498 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
1da177e4 4499 {
47b5d69c
JB
4500 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4501 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
1da177e4
LT
4502 }
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
47b5d69c 4514 FPT_ssel(port,p_card);
1da177e4
LT
4515 return;
4516 }
4517 }
4518 else
4519 {
4520
4521
4522 if (message == SMABORT)
4523
47b5d69c 4524 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
1da177e4
LT
4525 }
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
47b5d69c
JB
4559 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;
1da177e4 4562 else
47b5d69c 4563 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4564
47b5d69c 4565 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
1da177e4
LT
4566 }
4567
4568 else
4569 {
47b5d69c 4570 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4
LT
4571 }
4572 }
4573
4574 else
4575 {
4576
47b5d69c 4577 FPT_sxfrp(port,p_card);
1da177e4
LT
4578 }
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 {
47b5d69c 4591 FPT_sxfrp(port,p_card);
1da177e4
LT
4592 }
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
47b5d69c 4605static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
1da177e4
LT
4606{
4607 UCHAR message;
4608 PSCCB currSCCB;
4609
47b5d69c 4610 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4611
47b5d69c 4612 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
1da177e4
LT
4613 {
4614
47b5d69c 4615 FPT_phaseChkFifo(port, p_card);
1da177e4
LT
4616 }
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
47b5d69c 4629 message = FPT_sfm(port,currSCCB);
1da177e4
LT
4630 if (message)
4631 {
4632
4633
47b5d69c 4634 FPT_sdecm(message,port,p_card);
1da177e4
LT
4635
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
47b5d69c 4658static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
1da177e4
LT
4659{
4660 PSCCB currSCCB;
4661
47b5d69c 4662 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4663
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
47b5d69c 4686static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
1da177e4
LT
4687{
4688 ULONG xfercnt;
4689 PSCCB currSCCB;
4690
47b5d69c 4691 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4692
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
47b5d69c 4713 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4 4714
47b5d69c 4715 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4716
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
1da177e4 4725 GET_XFER_CNT(port,xfercnt);
1da177e4
LT
4726
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
47b5d69c 4745 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4
LT
4746
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 *---------------------------------------------------------------------*/
47b5d69c 4764static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
1da177e4
LT
4765{
4766 PSCCB currSCCB;
4767
47b5d69c 4768 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4769
4770 if (currSCCB != NULL)
4771 {
4772
4773 DISABLE_AUTO(port);
4774
4775
4776 if (currSCCB->OperationCode == RESET_COMMAND)
4777 {
4778
47b5d69c
JB
4779 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;
1da177e4 4782 else
47b5d69c 4783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4784
47b5d69c 4785 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 4786
47b5d69c 4787 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
4788
4789 }
4790
4791 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4792 {
47b5d69c 4793 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
1da177e4 4794 (UCHAR)SYNC_SUPPORTED;
47b5d69c 4795 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
1da177e4
LT
4796 }
4797
4798 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4799 {
47b5d69c
JB
4800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4801 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
1da177e4
LT
4802 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4803
47b5d69c 4804 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
1da177e4
LT
4805 }
4806
1da177e4
LT
4807 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 {
47b5d69c
JB
4816 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4817 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
1da177e4
LT
4818 }
4819
4820 else
4821 {
4822 return;
4823 }
4824 }
1da177e4
LT
4825
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
47b5d69c
JB
4836 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;
1da177e4 4839 else
47b5d69c 4840 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4841
47b5d69c 4842 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4
LT
4843 return;
4844 }
4845
4846
47b5d69c 4847 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4
LT
4848
4849 } /*end if !=null */
4850}
4851
4852
4853
4854
1da177e4
LT
4855/*---------------------------------------------------------------------
4856 *
4857 * Function: Auto Load Default Map
4858 *
4859 * Description: Load the Automation RAM with the defualt map values.
4860 *
4861 *---------------------------------------------------------------------*/
47b5d69c 4862static void FPT_autoLoadDefaultMap(ULONG p_port)
1da177e4 4863{
1da177e4 4864 ULONG map_addr;
1da177e4
LT
4865
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
47b5d69c 4970static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
1da177e4
LT
4971{
4972 PSCCB currSCCB;
4973 UCHAR status_byte;
4974
47b5d69c 4975 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4976
4977 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4978
47b5d69c 4979 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
1da177e4
LT
4980
4981 if (status_byte != SSGOOD) {
4982
4983 if (status_byte == SSQ_FULL) {
4984
4985
47b5d69c
JB
4986 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)))
1da177e4 4988 {
47b5d69c
JB
4989 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;
1da177e4
LT
4993 }
4994 else
4995 {
47b5d69c 4996 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
4997 if(currSCCB->Sccb_tag)
4998 {
47b5d69c
JB
4999 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;
1da177e4
LT
5002 }else
5003 {
47b5d69c
JB
5004 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;
1da177e4
LT
5007 }
5008 }
5009
5010 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
5011
47b5d69c 5012 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
5013
5014 return;
5015 }
5016
5017 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5018 {
47b5d69c 5019 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
1da177e4
LT
5020 (UCHAR)SYNC_SUPPORTED;
5021
47b5d69c
JB
5022 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5023 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5024
47b5d69c
JB
5025 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)))
1da177e4 5027 {
47b5d69c
JB
5028 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;
1da177e4
LT
5032 }
5033 else
5034 {
47b5d69c 5035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5036 if(currSCCB->Sccb_tag)
5037 {
47b5d69c
JB
5038 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;
1da177e4
LT
5041 }else
5042 {
47b5d69c
JB
5043 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;
1da177e4
LT
5046 }
5047 }
5048 return;
5049
5050 }
5051
5052 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5053 {
5054
47b5d69c
JB
5055 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5056 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
1da177e4
LT
5057 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5058
47b5d69c
JB
5059 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5060 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5061
47b5d69c
JB
5062 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)))
1da177e4 5064 {
47b5d69c
JB
5065 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;
1da177e4
LT
5069 }
5070 else
5071 {
47b5d69c 5072 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5073 if(currSCCB->Sccb_tag)
5074 {
47b5d69c
JB
5075 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;
1da177e4
LT
5078 }else
5079 {
47b5d69c
JB
5080 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;
1da177e4
LT
5083 }
5084 }
5085 return;
5086
5087 }
5088
5089 if (status_byte == SSCHECK)
5090 {
47b5d69c 5091 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
1da177e4 5092 {
47b5d69c 5093 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
1da177e4 5094 {
47b5d69c 5095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
1da177e4 5096 }
47b5d69c 5097 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
1da177e4 5098 {
47b5d69c 5099 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
5100 }
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
47b5d69c
JB
5111 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5112 = 1;
1da177e4
LT
5113
5114
1da177e4
LT
5115 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5116
5117 if (currSCCB->RequestSenseLength == 0)
5118 currSCCB->RequestSenseLength = 14;
5119
47b5d69c
JB
5120 FPT_ssenss(&FPT_BL_Card[p_card]);
5121 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5122
47b5d69c
JB
5123 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)))
1da177e4 5125 {
47b5d69c
JB
5126 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;
1da177e4
LT
5130 }
5131 else
5132 {
47b5d69c 5133 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5134 if(currSCCB->Sccb_tag)
5135 {
47b5d69c
JB
5136 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;
1da177e4
LT
5139 }else
5140 {
47b5d69c
JB
5141 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;
1da177e4
LT
5144 }
5145 }
5146 return;
5147 }
1da177e4
LT
5148 }
5149 }
5150 }
5151
5152
47b5d69c
JB
5153 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;
1da177e4 5156 else
47b5d69c 5157 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4
LT
5158
5159
47b5d69c 5160 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 5161}
1da177e4
LT
5162
5163#define SHORT_WAIT 0x0000000F
5164#define LONG_WAIT 0x0000FFFFL
5165
1da177e4
LT
5166
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
47b5d69c 5185static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
1da177e4
LT
5186{
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
47b5d69c 5201 FPT_busMstrSGDataXferStart(port, currSCCB);
1da177e4
LT
5202 }
5203
5204 else
5205 {
5206 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5207 {
5208 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5209
47b5d69c 5210 FPT_busMstrDataXferStart(port, currSCCB);
1da177e4
LT
5211 }
5212 }
5213}
5214
5215
5216/*---------------------------------------------------------------------
5217 *
5218 * Function: BusMaster Scatter Gather Data Transfer Start
5219 *
5220 * Description:
5221 *
5222 *---------------------------------------------------------------------*/
47b5d69c 5223static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
1da177e4
LT
5224{
5225 ULONG count,addr,tmpSGCnt;
5226 UINT sg_index;
5227 UCHAR sg_count, i;
1da177e4 5228 ULONG reg_offset;
1da177e4
LT
5229
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
1da177e4
LT
5254 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));
1da177e4
LT
5262
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 *---------------------------------------------------------------------*/
47b5d69c 5328static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
1da177e4
LT
5329{
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
1da177e4 5345 HP_SETUP_ADDR_CNT(p_port,addr,count);
1da177e4
LT
5346
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 *---------------------------------------------------------------------*/
47b5d69c 5381static UCHAR FPT_busMstrTimeOut(ULONG p_port)
1da177e4
LT
5382{
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) {
47b5d69c 5403 return(1);
1da177e4
LT
5404 }
5405
5406 else {
47b5d69c 5407 return(0);
1da177e4
LT
5408 }
5409}
5410
5411
5412/*---------------------------------------------------------------------
5413 *
5414 * Function: Host Data Transfer Abort
5415 *
5416 * Description: Abort any in progress transfer.
5417 *
5418 *---------------------------------------------------------------------*/
47b5d69c 5419static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
1da177e4
LT
5420{
5421
5422 ULONG timeout;
5423 ULONG remain_cnt;
5424 UINT sg_ptr;
5425
47b5d69c 5426 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
1da177e4
LT
5427
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
47b5d69c 5442 if (FPT_busMstrTimeOut(port)) {
1da177e4
LT
5443
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;
1da177e4
LT
5458 }
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
1da177e4
LT
5486 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5487 DataPointer) + (sg_ptr * 2)))) {
5488
5489 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5490 DataPointer) + (sg_ptr * 2)));
5491 }
1da177e4
LT
5492
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
47b5d69c 5531 FPT_busMstrTimeOut(port);
1da177e4
LT
5532 }
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;
1da177e4
LT
5543 }
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
47b5d69c 5583 FPT_busMstrTimeOut(port);
1da177e4
LT
5584 }
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;
1da177e4
LT
5594 }
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
47b5d69c 5617 FPT_busMstrTimeOut(port);
1da177e4
LT
5618 }
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;
1da177e4
LT
5629 }
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 *---------------------------------------------------------------------*/
47b5d69c 5677static void FPT_hostDataXferRestart(PSCCB currSCCB)
1da177e4
LT
5678{
5679 ULONG data_count;
5680 UINT sg_index;
1da177e4 5681 ULONG *sg_ptr;
1da177e4
LT
5682
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
1da177e4 5690 sg_ptr = (ULONG *)currSCCB->DataPointer;
1da177e4
LT
5691
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}
1da177e4
LT
5715
5716
5717
1da177e4
LT
5718/*---------------------------------------------------------------------
5719 *
47b5d69c 5720 * Function: FPT_scini
1da177e4
LT
5721 *
5722 * Description: Setup all data structures necessary for SCAM selection.
5723 *
5724 *---------------------------------------------------------------------*/
5725
47b5d69c 5726static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
1da177e4
LT
5727{
5728
1da177e4 5729 UCHAR loser,assigned_id;
1da177e4 5730 ULONG p_port;
1da177e4
LT
5731
5732 UCHAR i,k,ScamFlg ;
5733 PSCCBcard currCard;
5734 PNVRamInfo pCurrNvRam;
5735
47b5d69c 5736 currCard = &FPT_BL_Card[p_card];
1da177e4
LT
5737 p_port = currCard->ioPort;
5738 pCurrNvRam = currCard->pNvRamInfo;
5739
5740
5741 if(pCurrNvRam){
5742 ScamFlg = pCurrNvRam->niScamConf;
5743 i = pCurrNvRam->niSysConf;
5744 }
5745 else{
47b5d69c
JB
5746 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5747 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
1da177e4
LT
5748 }
5749 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5750 return;
5751
47b5d69c 5752 FPT_inisci(p_card,p_port, p_our_id);
1da177e4
LT
5753
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)
47b5d69c 5758 FPT_Wait1Second(p_port);
1da177e4 5759 else
47b5d69c 5760 FPT_Wait(p_port, TO_250ms); */
1da177e4 5761
47b5d69c 5762 FPT_Wait1Second(p_port);
1da177e4
LT
5763
5764 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5765 {
47b5d69c 5766 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
1da177e4 5767
47b5d69c 5768 FPT_scsel(p_port);
1da177e4
LT
5769
5770 do {
47b5d69c
JB
5771 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]);
1da177e4
LT
5774 } while ( loser == 0xFF );
5775
47b5d69c 5776 FPT_scbusf(p_port);
1da177e4
LT
5777
5778 if ((p_power_up) && (!loser))
5779 {
47b5d69c
JB
5780 FPT_sresb(p_port,p_card);
5781 FPT_Wait(p_port, TO_250ms);
1da177e4 5782
47b5d69c 5783 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
1da177e4 5784
47b5d69c 5785 FPT_scsel(p_port);
1da177e4
LT
5786
5787 do {
47b5d69c
JB
5788 FPT_scxferc(p_port, SYNC_PTRN);
5789 FPT_scxferc(p_port, DOM_MSTR);
5790 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
1da177e4
LT
5791 id_string[0]);
5792 } while ( loser == 0xFF );
5793
47b5d69c 5794 FPT_scbusf(p_port);
1da177e4
LT
5795 }
5796 }
5797
5798 else
5799 {
47b5d69c 5800 loser = 0;
1da177e4
LT
5801 }
5802
5803
5804 if (!loser)
5805 {
5806
47b5d69c 5807 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
1da177e4
LT
5808
5809
5810 if (ScamFlg & SCAM_ENABLED)
5811 {
5812
5813 for (i=0; i < MAX_SCSI_TAR; i++)
5814 {
47b5d69c
JB
5815 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5816 (FPT_scamInfo[i].state == ID_UNUSED))
1da177e4 5817 {
47b5d69c 5818 if (FPT_scsell(p_port,i))
1da177e4 5819 {
47b5d69c
JB
5820 FPT_scamInfo[i].state = LEGACY;
5821 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5822 (FPT_scamInfo[i].id_string[1] != 0xFA))
1da177e4
LT
5823 {
5824
47b5d69c
JB
5825 FPT_scamInfo[i].id_string[0] = 0xFF;
5826 FPT_scamInfo[i].id_string[1] = 0xFA;
1da177e4
LT
5827 if(pCurrNvRam == NULL)
5828 currCard->globalFlags |= F_UPDATE_EEPROM;
5829 }
5830 }
5831 }
5832 }
5833
47b5d69c
JB
5834 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);
1da177e4
LT
5839 }
5840
1da177e4
LT
5841 }
5842
5843 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5844 {
47b5d69c
JB
5845 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5846 assigned_id = 0;
5847 FPT_scwtsel(p_port);
1da177e4
LT
5848
5849 do {
47b5d69c 5850 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
1da177e4 5851
47b5d69c 5852 i = FPT_scxferc(p_port,0x00);
1da177e4
LT
5853 if (i == ASSIGN_ID)
5854 {
47b5d69c 5855 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
1da177e4 5856 {
47b5d69c
JB
5857 i = FPT_scxferc(p_port,0x00);
5858 if (FPT_scvalq(i))
1da177e4 5859 {
47b5d69c 5860 k = FPT_scxferc(p_port,0x00);
1da177e4 5861
47b5d69c 5862 if (FPT_scvalq(k))
1da177e4
LT
5863 {
5864 currCard->ourId =
5865 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
47b5d69c
JB
5866 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]
1da177e4 5869 = SLV_TYPE_CODE0;
47b5d69c 5870 assigned_id = 1;
1da177e4
LT
5871 }
5872 }
5873 }
5874 }
5875
5876 else if (i == SET_P_FLAG)
5877 {
47b5d69c
JB
5878 if (!(FPT_scsendi(p_port,
5879 &FPT_scamInfo[p_our_id].id_string[0])))
5880 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
1da177e4
LT
5881 }
5882 }while (!assigned_id);
5883
47b5d69c 5884 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
1da177e4
LT
5885 }
5886
1da177e4
LT
5887 if (ScamFlg & SCAM_ENABLED)
5888 {
47b5d69c 5889 FPT_scbusf(p_port);
1da177e4
LT
5890 if (currCard->globalFlags & F_UPDATE_EEPROM)
5891 {
47b5d69c 5892 FPT_scsavdi(p_card, p_port);
1da177e4
LT
5893 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5894 }
5895 }
5896
5897
1da177e4
LT
5898/*
5899 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5900 {
47b5d69c
JB
5901 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5902 (FPT_scamInfo[i].state == LEGACY))
1da177e4
LT
5903 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 *
47b5d69c 5916 * Function: FPT_scarb
1da177e4
LT
5917 *
5918 * Description: Gain control of the bus and wait SCAM select time (250ms)
5919 *
5920 *---------------------------------------------------------------------*/
5921
47b5d69c 5922static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
1da177e4
LT
5923{
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)
47b5d69c 5931 return(0);
1da177e4
LT
5932
5933 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
47b5d69c 5934 return(0);
1da177e4
LT
5935
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));
47b5d69c 5942 return(0);
1da177e4
LT
5943 }
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)));
47b5d69c 5952 return(0);
1da177e4
LT
5953 }
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);
1da177e4 5961 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
1da177e4
LT
5962 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
47b5d69c 5969 FPT_Wait(p_port,TO_250ms);
1da177e4 5970
47b5d69c 5971 return(1);
1da177e4
LT
5972}
5973
5974
5975/*---------------------------------------------------------------------
5976 *
47b5d69c 5977 * Function: FPT_scbusf
1da177e4
LT
5978 *
5979 * Description: Release the SCSI bus and disable SCAM selection.
5980 *
5981 *---------------------------------------------------------------------*/
5982
47b5d69c 5983static void FPT_scbusf(ULONG p_port)
1da177e4
LT
5984{
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
1da177e4 6003 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
1da177e4
LT
6004
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 *
47b5d69c 6013 * Function: FPT_scasid
1da177e4
LT
6014 *
6015 * Description: Assign an ID to all the SCAM devices.
6016 *
6017 *---------------------------------------------------------------------*/
6018
47b5d69c 6019static void FPT_scasid(UCHAR p_card, ULONG p_port)
1da177e4 6020{
1da177e4 6021 UCHAR temp_id_string[ID_STRING_LENGTH];
1da177e4
LT
6022
6023 UCHAR i,k,scam_id;
6024 UCHAR crcBytes[3];
6025 PNVRamInfo pCurrNvRam;
6026 ushort_ptr pCrcBytes;
6027
47b5d69c 6028 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4 6029
47b5d69c 6030 i=0;
1da177e4
LT
6031
6032 while (!i)
6033 {
6034
6035 for (k=0; k < ID_STRING_LENGTH; k++)
6036 {
6037 temp_id_string[k] = (UCHAR) 0x00;
6038 }
6039
47b5d69c
JB
6040 FPT_scxferc(p_port,SYNC_PTRN);
6041 FPT_scxferc(p_port,ASSIGN_ID);
1da177e4 6042
47b5d69c 6043 if (!(FPT_sciso(p_port,&temp_id_string[0])))
1da177e4
LT
6044 {
6045 if(pCurrNvRam){
6046 pCrcBytes = (ushort_ptr)&crcBytes[0];
47b5d69c
JB
6047 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6048 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
1da177e4
LT
6049 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 }
47b5d69c 6055 i = FPT_scmachid(p_card,temp_id_string);
1da177e4
LT
6056
6057 if (i == CLR_PRIORITY)
6058 {
47b5d69c
JB
6059 FPT_scxferc(p_port,MISC_CODE);
6060 FPT_scxferc(p_port,CLR_P_FLAG);
6061 i = 0; /*Not the last ID yet. */
1da177e4
LT
6062 }
6063
6064 else if (i != NO_ID_AVAIL)
6065 {
6066 if (i < 8 )
47b5d69c 6067 FPT_scxferc(p_port,ID_0_7);
1da177e4 6068 else
47b5d69c 6069 FPT_scxferc(p_port,ID_8_F);
1da177e4
LT
6070
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
47b5d69c 6078 FPT_scxferc(p_port,scam_id);
1da177e4 6079
47b5d69c 6080 i = 0; /*Not the last ID yet. */
1da177e4
LT
6081 }
6082 }
6083
6084 else
6085 {
47b5d69c 6086 i = 1;
1da177e4
LT
6087 }
6088
6089 } /*End while */
6090
47b5d69c
JB
6091 FPT_scxferc(p_port,SYNC_PTRN);
6092 FPT_scxferc(p_port,CFG_CMPLT);
1da177e4
LT
6093}
6094
6095
6096
6097
6098
6099/*---------------------------------------------------------------------
6100 *
47b5d69c 6101 * Function: FPT_scsel
1da177e4
LT
6102 *
6103 * Description: Select all the SCAM devices.
6104 *
6105 *---------------------------------------------------------------------*/
6106
47b5d69c 6107static void FPT_scsel(ULONG p_port)
1da177e4
LT
6108{
6109
6110 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
47b5d69c 6111 FPT_scwiros(p_port, SCSI_MSG);
1da177e4
LT
6112
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));
47b5d69c 6122 FPT_scwiros(p_port, SCSI_SEL);
1da177e4
LT
6123
6124 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6125 ~(UCHAR)BIT(6)));
47b5d69c 6126 FPT_scwirod(p_port, BIT(6));
1da177e4
LT
6127
6128 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6129}
6130
6131
6132
6133/*---------------------------------------------------------------------
6134 *
47b5d69c 6135 * Function: FPT_scxferc
1da177e4
LT
6136 *
6137 * Description: Handshake the p_data (DB4-0) across the bus.
6138 *
6139 *---------------------------------------------------------------------*/
6140
47b5d69c 6141static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
1da177e4
LT
6142{
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
47b5d69c 6153 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
1da177e4
LT
6154 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
47b5d69c 6166 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
1da177e4
LT
6167
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
47b5d69c 6177 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
1da177e4
LT
6178
6179 return(ret_data);
6180}
6181
6182
6183/*---------------------------------------------------------------------
6184 *
47b5d69c 6185 * Function: FPT_scsendi
1da177e4
LT
6186 *
6187 * Description: Transfer our Identification string to determine if we
6188 * will be the dominant master.
6189 *
6190 *---------------------------------------------------------------------*/
6191
47b5d69c 6192static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
1da177e4
LT
6193{
6194 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6195
47b5d69c 6196 defer = 0;
1da177e4
LT
6197
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)
47b5d69c 6203 ret_data = FPT_scxferc(p_port,00);
1da177e4
LT
6204
6205 else if (p_id_string[byte_cnt] & bit_cnt)
6206
47b5d69c 6207 ret_data = FPT_scxferc(p_port,02);
1da177e4
LT
6208
6209 else {
6210
47b5d69c 6211 ret_data = FPT_scxferc(p_port,01);
1da177e4 6212 if (ret_data & 02)
47b5d69c 6213 defer = 1;
1da177e4
LT
6214 }
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 *
47b5d69c 6239 * Function: FPT_sciso
1da177e4
LT
6240 *
6241 * Description: Transfer the Identification string.
6242 *
6243 *---------------------------------------------------------------------*/
6244
47b5d69c 6245static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
1da177e4
LT
6246{
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
47b5d69c 6255 ret_data = FPT_scxferc(p_port,0);
1da177e4
LT
6256
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;
47b5d69c
JB
6275 FPT_scxferc(p_port, SYNC_PTRN);
6276 FPT_scxferc(p_port, ASSIGN_ID);
1da177e4
LT
6277 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 *
47b5d69c 6299 * Function: FPT_scwirod
1da177e4
LT
6300 *
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
47b5d69c 6306static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
1da177e4
LT
6307{
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 *
47b5d69c 6328 * Function: FPT_scwiros
1da177e4
LT
6329 *
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
47b5d69c 6335static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
1da177e4
LT
6336{
6337 UCHAR i;
6338
47b5d69c
JB
6339 i = 0;
6340 while ( i < MAX_SCSI_TAR ) {
1da177e4 6341
47b5d69c 6342 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
1da177e4 6343
47b5d69c 6344 i = 0;
1da177e4 6345
47b5d69c 6346 else
1da177e4 6347
47b5d69c 6348 i++;
1da177e4 6349
1da177e4 6350 }
47b5d69c 6351}
1da177e4 6352
1da177e4 6353
47b5d69c
JB
6354/*---------------------------------------------------------------------
6355 *
6356 * Function: FPT_scvalq
6357 *
6358 * Description: Make sure we received a valid data byte.
6359 *
6360 *---------------------------------------------------------------------*/
1da177e4 6361
47b5d69c
JB
6362static UCHAR FPT_scvalq(UCHAR p_quintet)
6363{
6364 UCHAR count;
1da177e4 6365
47b5d69c
JB
6366 for (count=1; count < 0x08; count<<=1) {
6367 if (!(p_quintet & count))
6368 p_quintet -= 0x80;
1da177e4 6369 }
47b5d69c
JB
6370
6371 if (p_quintet & 0x18)
6372 return(0);
6373
6374 else
6375 return(1);
1da177e4
LT
6376}
6377
47b5d69c 6378
1da177e4
LT
6379/*---------------------------------------------------------------------
6380 *
47b5d69c 6381 * Function: FPT_scsell
1da177e4
LT
6382 *
6383 * Description: Select the specified device ID using a selection timeout
47b5d69c
JB
6384 * less than 4ms. If somebody responds then it is a legacy
6385 * drive and this ID must be marked as such.
1da177e4
LT
6386 *
6387 *---------------------------------------------------------------------*/
6388
47b5d69c 6389static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
1da177e4 6390{
47b5d69c 6391 ULONG i;
1da177e4
LT
6392
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));
47b5d69c 6399 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
1da177e4
LT
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)
47b5d69c 6421 FPT_Wait(p_port, TO_250ms);
1da177e4
LT
6422
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
47b5d69c 6438 return(0); /*No legacy device */
1da177e4
LT
6439 }
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
47b5d69c 6456 return(1); /*Found one of them oldies! */
1da177e4
LT
6457 }
6458}
1da177e4
LT
6459
6460/*---------------------------------------------------------------------
6461 *
47b5d69c 6462 * Function: FPT_scwtsel
1da177e4
LT
6463 *
6464 * Description: Wait to be selected by another SCAM initiator.
6465 *
6466 *---------------------------------------------------------------------*/
6467
47b5d69c 6468static void FPT_scwtsel(ULONG p_port)
1da177e4
LT
6469{
6470 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6471}
6472
6473
6474/*---------------------------------------------------------------------
6475 *
47b5d69c 6476 * Function: FPT_inisci
1da177e4
LT
6477 *
6478 * Description: Setup the data Structure with the info from the EEPROM.
6479 *
6480 *---------------------------------------------------------------------*/
6481
47b5d69c 6482static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
1da177e4
LT
6483{
6484 UCHAR i,k,max_id;
6485 USHORT ee_data;
6486 PNVRamInfo pCurrNvRam;
6487
47b5d69c 6488 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4
LT
6489
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++)
47b5d69c 6500 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
1da177e4 6501 for(k = 4; k < ID_STRING_LENGTH; k++)
47b5d69c 6502 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
1da177e4 6503
47b5d69c
JB
6504 if(FPT_scamInfo[i].id_string[0] == 0x00)
6505 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4 6506 else
47b5d69c 6507 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6508
6509 }
6510 }else {
6511 for (i=0; i < max_id; i++)
6512 {
6513 for (k=0; k < ID_STRING_LENGTH; k+=2)
6514 {
47b5d69c 6515 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
1da177e4 6516 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
47b5d69c 6517 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
1da177e4 6518 ee_data >>= 8;
47b5d69c 6519 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
1da177e4
LT
6520 }
6521
47b5d69c
JB
6522 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6523 (FPT_scamInfo[i].id_string[0] == 0xFF))
1da177e4 6524
47b5d69c 6525 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4
LT
6526
6527 else
47b5d69c 6528 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6529
6530 }
6531 }
6532 for(k = 0; k < ID_STRING_LENGTH; k++)
47b5d69c 6533 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
1da177e4
LT
6534
6535}
6536
6537/*---------------------------------------------------------------------
6538 *
47b5d69c 6539 * Function: FPT_scmachid
1da177e4
LT
6540 *
6541 * Description: Match the Device ID string with our values stored in
6542 * the EEPROM.
6543 *
6544 *---------------------------------------------------------------------*/
6545
47b5d69c 6546static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
1da177e4
LT
6547{
6548
6549 UCHAR i,k,match;
6550
6551
6552 for (i=0; i < MAX_SCSI_TAR; i++) {
6553
47b5d69c 6554 match = 1;
1da177e4
LT
6555
6556 for (k=0; k < ID_STRING_LENGTH; k++)
6557 {
47b5d69c
JB
6558 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6559 match = 0;
1da177e4
LT
6560 }
6561
6562 if (match)
6563 {
47b5d69c 6564 FPT_scamInfo[i].state = ID_ASSIGNED;
1da177e4
LT
6565 return(i);
6566 }
6567
1da177e4
LT
6568 }
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
47b5d69c 6586 if (FPT_scamInfo[match].state == ID_UNUSED)
1da177e4
LT
6587 {
6588 for (k=0; k < ID_STRING_LENGTH; k++)
6589 {
47b5d69c 6590 FPT_scamInfo[match].id_string[k] = p_id_string[k];
1da177e4
LT
6591 }
6592
47b5d69c 6593 FPT_scamInfo[match].state = ID_ASSIGNED;
1da177e4 6594
47b5d69c
JB
6595 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6596 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
1da177e4
LT
6597 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
47b5d69c 6636 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
1da177e4
LT
6637 {
6638 for (k=0; k < ID_STRING_LENGTH; k++)
6639 {
47b5d69c 6640 FPT_scamInfo[match].id_string[k] = p_id_string[k];
1da177e4
LT
6641 }
6642
47b5d69c
JB
6643 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;
1da177e4
LT
6647 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 *
47b5d69c 6669 * Function: FPT_scsavdi
1da177e4
LT
6670 *
6671 * Description: Save off the device SCAM ID strings.
6672 *
6673 *---------------------------------------------------------------------*/
6674
47b5d69c 6675static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
1da177e4
LT
6676{
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 {
47b5d69c 6685 sum_data += FPT_utilEERead(p_port, i);
1da177e4
LT
6686 }
6687
6688
47b5d69c 6689 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
1da177e4
LT
6690
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 {
47b5d69c 6702 ee_data = FPT_scamInfo[i].id_string[k+1];
1da177e4 6703 ee_data <<= 8;
47b5d69c 6704 ee_data |= FPT_scamInfo[i].id_string[k];
1da177e4 6705 sum_data += ee_data;
47b5d69c 6706 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
1da177e4
LT
6707 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6708 }
6709 }
6710
6711
47b5d69c
JB
6712 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6713 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
1da177e4 6714}
1da177e4
LT
6715
6716/*---------------------------------------------------------------------
6717 *
47b5d69c 6718 * Function: FPT_XbowInit
1da177e4
LT
6719 *
6720 * Description: Setup the Xbow for normal operation.
6721 *
6722 *---------------------------------------------------------------------*/
6723
47b5d69c 6724static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
1da177e4
LT
6725{
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
47b5d69c 6746 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
1da177e4
LT
6747 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6748
6749 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
47b5d69c 6750 FPT_default_intena |= SCAM_SEL;
1da177e4 6751
47b5d69c 6752 WRW_HARPOON((port+hp_intena), FPT_default_intena);
1da177e4
LT
6753
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
1da177e4
LT
6761 WR_HARPOON(port+hp_page_ctrl, i);
6762
6763}
6764
6765
6766/*---------------------------------------------------------------------
6767 *
47b5d69c 6768 * Function: FPT_BusMasterInit
1da177e4
LT
6769 *
6770 * Description: Initialize the BusMaster for normal operations.
6771 *
6772 *---------------------------------------------------------------------*/
6773
47b5d69c 6774static void FPT_BusMasterInit(ULONG p_port)
1da177e4
LT
6775{
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
1da177e4
LT
6789 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 *
47b5d69c 6798 * Function: FPT_DiagEEPROM
1da177e4
LT
6799 *
6800 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6801 * necessary.
6802 *
6803 *---------------------------------------------------------------------*/
6804
47b5d69c 6805static void FPT_DiagEEPROM(ULONG p_port)
1da177e4
LT
6806{
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
47b5d69c 6814 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
1da177e4
LT
6815
6816 if (temp == 0x4641) {
6817
6818 for (index = 2; index < max_wd_cnt; index++) {
6819
47b5d69c 6820 temp += FPT_utilEERead(p_port, index);
1da177e4
LT
6821
6822 }
6823
47b5d69c 6824 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
1da177e4
LT
6825
6826 return; /*EEPROM is Okay so return now! */
6827 }
6828 }
6829
6830
47b5d69c 6831 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
1da177e4
LT
6832
6833 for (index = 0; index < max_wd_cnt; index++) {
6834
47b5d69c 6835 FPT_utilEEWrite(p_port, 0x0000, index);
1da177e4
LT
6836 }
6837
6838 temp = 0;
6839
47b5d69c 6840 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
1da177e4 6841 temp += 0x4641;
47b5d69c 6842 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
1da177e4 6843 temp += 0x3920;
47b5d69c 6844 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
1da177e4 6845 temp += 0x3033;
47b5d69c 6846 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
1da177e4 6847 temp += 0x2020;
47b5d69c 6848 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
1da177e4 6849 temp += 0x70D3;
47b5d69c 6850 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
1da177e4 6851 temp += 0x0010;
47b5d69c 6852 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
1da177e4 6853 temp += 0x0003;
47b5d69c 6854 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
1da177e4
LT
6855 temp += 0x0007;
6856
47b5d69c 6857 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
1da177e4 6858 temp += 0x0000;
47b5d69c 6859 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
1da177e4 6860 temp += 0x0000;
47b5d69c 6861 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
1da177e4
LT
6862 temp += 0x0000;
6863
47b5d69c 6864 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
1da177e4 6865 temp += 0x4242;
47b5d69c 6866 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
1da177e4 6867 temp += 0x4242;
47b5d69c 6868 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
1da177e4 6869 temp += 0x4242;
47b5d69c 6870 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
1da177e4 6871 temp += 0x4242;
47b5d69c 6872 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
1da177e4 6873 temp += 0x4242;
47b5d69c 6874 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
1da177e4 6875 temp += 0x4242;
47b5d69c 6876 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
1da177e4 6877 temp += 0x4242;
47b5d69c 6878 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
1da177e4
LT
6879 temp += 0x4242;
6880
6881
47b5d69c 6882 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
1da177e4 6883 temp += 0x6C46;
47b5d69c 6884 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
1da177e4 6885 temp += 0x7361;
47b5d69c 6886 FPT_utilEEWrite(p_port, 0x5068, 68/2);
1da177e4 6887 temp += 0x5068;
47b5d69c 6888 FPT_utilEEWrite(p_port, 0x696F, 70/2);
1da177e4 6889 temp += 0x696F;
47b5d69c 6890 FPT_utilEEWrite(p_port, 0x746E, 72/2);
1da177e4 6891 temp += 0x746E;
47b5d69c 6892 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
1da177e4 6893 temp += 0x4C20;
47b5d69c 6894 FPT_utilEEWrite(p_port, 0x2054, 76/2);
1da177e4 6895 temp += 0x2054;
47b5d69c 6896 FPT_utilEEWrite(p_port, 0x2020, 78/2);
1da177e4
LT
6897 temp += 0x2020;
6898
6899 index = ((EE_SCAMBASE/2)+(7*16));
47b5d69c 6900 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
1da177e4
LT
6901 temp += (0x0700+TYPE_CODE0);
6902 index++;
47b5d69c 6903 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
1da177e4
LT
6904 temp += 0x5542; /* BUSLOGIC */
6905 index++;
47b5d69c 6906 FPT_utilEEWrite(p_port, 0x4C53, index);
1da177e4
LT
6907 temp += 0x4C53;
6908 index++;
47b5d69c 6909 FPT_utilEEWrite(p_port, 0x474F, index);
1da177e4
LT
6910 temp += 0x474F;
6911 index++;
47b5d69c 6912 FPT_utilEEWrite(p_port, 0x4349, index);
1da177e4
LT
6913 temp += 0x4349;
6914 index++;
47b5d69c 6915 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
1da177e4
LT
6916 temp += 0x5442; /* BT- 930 */
6917 index++;
47b5d69c 6918 FPT_utilEEWrite(p_port, 0x202D, index);
1da177e4
LT
6919 temp += 0x202D;
6920 index++;
47b5d69c 6921 FPT_utilEEWrite(p_port, 0x3339, index);
1da177e4
LT
6922 temp += 0x3339;
6923 index++; /*Serial # */
47b5d69c 6924 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
1da177e4
LT
6925 temp += 0x2030;
6926 index++;
47b5d69c 6927 FPT_utilEEWrite(p_port, 0x5453, index);
1da177e4
LT
6928 temp += 0x5453;
6929 index++;
47b5d69c 6930 FPT_utilEEWrite(p_port, 0x5645, index);
1da177e4
LT
6931 temp += 0x5645;
6932 index++;
47b5d69c 6933 FPT_utilEEWrite(p_port, 0x2045, index);
1da177e4
LT
6934 temp += 0x2045;
6935 index++;
47b5d69c 6936 FPT_utilEEWrite(p_port, 0x202F, index);
1da177e4
LT
6937 temp += 0x202F;
6938 index++;
47b5d69c 6939 FPT_utilEEWrite(p_port, 0x4F4A, index);
1da177e4
LT
6940 temp += 0x4F4A;
6941 index++;
47b5d69c 6942 FPT_utilEEWrite(p_port, 0x204E, index);
1da177e4
LT
6943 temp += 0x204E;
6944 index++;
47b5d69c 6945 FPT_utilEEWrite(p_port, 0x3539, index);
1da177e4
LT
6946 temp += 0x3539;
6947
6948
6949
47b5d69c 6950 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
1da177e4 6951
47b5d69c 6952 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
1da177e4
LT
6953
6954}
6955
1da177e4
LT
6956
6957/*---------------------------------------------------------------------
6958 *
6959 * Function: Queue Search Select
6960 *
6961 * Description: Try to find a new command to execute.
6962 *
6963 *---------------------------------------------------------------------*/
6964
47b5d69c 6965static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
1da177e4
LT
6966{
6967 UCHAR scan_ptr, lun;
6968 PSCCBMgr_tar_info currTar_Info;
6969 PSCCB pOldSccb;
6970
6971 scan_ptr = pCurrCard->scanIndex;
6972 do
6973 {
47b5d69c 6974 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
1da177e4
LT
6975 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 {
47b5d69c 6987 if(currTar_Info->TarLUNBusy[lun] == 0)
1da177e4
LT
6988 {
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) &&
47b5d69c 7046 (currTar_Info->TarLUNBusy[0] == 0))
1da177e4
LT
7047 {
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
47b5d69c 7096static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
1da177e4
LT
7097{
7098 UCHAR thisTarg;
7099 PSCCBMgr_tar_info currTar_Info;
7100
7101 if (pCurrCard->currentSCCB != NULL)
7102 {
7103 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
47b5d69c 7104 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7105
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
47b5d69c
JB
7135static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7136 UCHAR p_card)
1da177e4
LT
7137{
7138
1da177e4
LT
7139 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
47b5d69c 7183 FPT_utilUpdateResidual(p_sccb);
1da177e4
LT
7184 }
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 {
47b5d69c 7201 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4
LT
7202 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}
1da177e4
LT
7228
7229
7230/*---------------------------------------------------------------------
7231 *
7232 * Function: Queue Disconnect
7233 *
7234 * Description: Add SCCB to our disconnect array.
7235 *
7236 *---------------------------------------------------------------------*/
47b5d69c 7237static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
1da177e4
LT
7238{
7239 PSCCBMgr_tar_info currTar_Info;
7240
47b5d69c 7241 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4 7242
47b5d69c 7243 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
1da177e4
LT
7244 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7245 {
47b5d69c 7246 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
1da177e4
LT
7247 }
7248 else
7249 {
7250 if (p_sccb->Sccb_tag)
7251 {
47b5d69c
JB
7252 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++;
1da177e4
LT
7255 }else
7256 {
47b5d69c 7257 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
1da177e4
LT
7258 }
7259 }
47b5d69c 7260 FPT_BL_Card[p_card].currentSCCB = NULL;
1da177e4
LT
7261}
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
47b5d69c 7272static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
1da177e4
LT
7273{
7274 UCHAR qtag,thisTarg;
7275 PSCCB currSCCB;
7276 PSCCBMgr_tar_info currTar_Info;
7277
47b5d69c 7278 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
7279 if(currSCCB != NULL)
7280 {
7281 thisTarg = (UCHAR)currSCCB->TargID;
47b5d69c 7282 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7283
7284 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7285
47b5d69c
JB
7286 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7287 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
1da177e4
LT
7288 {
7289
47b5d69c 7290 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
1da177e4 7291
47b5d69c 7292 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
1da177e4 7293
47b5d69c 7294 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
7295 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
47b5d69c
JB
7311static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7312 UCHAR error_code)
1da177e4
LT
7313{
7314 UCHAR qtag;
7315 PSCCBMgr_tar_info currTar_Info;
7316
47b5d69c 7317 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7318
7319 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7320
47b5d69c
JB
7321 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7322 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
1da177e4
LT
7323 {
7324
47b5d69c 7325 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
1da177e4 7326
47b5d69c 7327 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
1da177e4 7328
47b5d69c 7329 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
7330 currTar_Info->TarTagQ_Cnt--;
7331
7332 }
7333 }
7334
7335}
7336
7337
7338
7339
7340
47b5d69c 7341static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
1da177e4
LT
7342{
7343 PSCCBMgr_tar_info currTar_Info;
47b5d69c 7344 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4
LT
7345
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
47b5d69c 7375static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
1da177e4
LT
7376{
7377 PSCCB q_ptr;
7378 PSCCBMgr_tar_info currTar_Info;
7379
47b5d69c 7380 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4
LT
7381
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
47b5d69c 7409 return(1);
1da177e4
LT
7410 }
7411
7412 else {
7413 q_ptr = q_ptr->Sccb_forwardlink;
7414 }
7415 }
7416
7417
47b5d69c 7418 return(0);
1da177e4
LT
7419
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
47b5d69c 7436static void FPT_utilUpdateResidual(PSCCB p_SCCB)
1da177e4
LT
7437{
7438 ULONG partial_cnt;
7439 UINT sg_index;
1da177e4 7440 ULONG *sg_ptr;
1da177e4
LT
7441
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
1da177e4 7453 sg_ptr = (ULONG *)p_SCCB->DataPointer;
1da177e4
LT
7454
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
47b5d69c 7486static void FPT_Wait1Second(ULONG p_port)
1da177e4
LT
7487{
7488 UCHAR i;
7489
7490 for(i=0; i < 4; i++) {
7491
47b5d69c 7492 FPT_Wait(p_port, TO_250ms);
1da177e4
LT
7493
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 *
47b5d69c 7505 * Function: FPT_Wait
1da177e4
LT
7506 *
7507 * Description: Wait the desired delay.
7508 *
7509 *---------------------------------------------------------------------*/
7510
47b5d69c 7511static void FPT_Wait(ULONG p_port, UCHAR p_delay)
1da177e4
LT
7512{
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);
47b5d69c 7523 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
1da177e4
LT
7524
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);
47b5d69c 7542 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
1da177e4
LT
7543
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
47b5d69c 7559static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
1da177e4
LT
7560{
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
47b5d69c 7567 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
1da177e4
LT
7568
7569 else
7570
7571
47b5d69c 7572 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
1da177e4
LT
7573
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
47b5d69c 7588static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
1da177e4
LT
7589{
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
47b5d69c 7599 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
1da177e4
LT
7600
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
47b5d69c 7623 FPT_Wait(p_port, TO_10ms);
1da177e4
LT
7624
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
47b5d69c 7639static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
1da177e4
LT
7640{
7641 USHORT i, ee_data1, ee_data2;
7642
7643 i = 0;
47b5d69c 7644 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4
LT
7645 do
7646 {
47b5d69c 7647 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4
LT
7648
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
47b5d69c 7669static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
1da177e4
LT
7670{
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
47b5d69c 7679 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
1da177e4
LT
7680
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
47b5d69c 7717static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
1da177e4
LT
7718{
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
47b5d69c 7780static USHORT FPT_CalcCrc16(UCHAR buffer[])
1da177e4
LT
7781{
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
47b5d69c 7800static UCHAR FPT_CalcLrc(UCHAR buffer[])
1da177e4
LT
7801{
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
1da177e4
LT
7873#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);
1da177e4
LT
7888
7889
7890#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */