]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/scsi/FlashPoint.c
[SCSI] drivers/scsi/FlashPoint.c: remove trivial wrappers
[mirror_ubuntu-bionic-kernel.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
1da177e4
LT
29
30
1da177e4 31
1da177e4
LT
32
33
1da177e4 34
1da177e4
LT
35
36#define CRCMASK 0xA001
37
1da177e4
LT
38
39
1da177e4
LT
40#define FAILURE 0xFFFFFFFFL
41
42
43typedef unsigned char UCHAR;
44typedef unsigned short USHORT;
45typedef unsigned int UINT;
46typedef unsigned long ULONG;
1da177e4
LT
47
48
1da177e4 49typedef unsigned short * ushort_ptr;
1da177e4 50
1da177e4
LT
51
52#define s08bits char
53#define s16bits short
54#define s32bits long
55
56#define u08bits unsigned s08bits
57#define u16bits unsigned s16bits
58#define u32bits unsigned s32bits
59
1da177e4 60
1da177e4
LT
61
62#define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
63#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
64
65
66
1da177e4 67
47b5d69c
JB
68typedef struct _SCCB *PSCCB;
69typedef void (*CALL_BK_FN)(PSCCB);
1da177e4
LT
70
71
72typedef struct SCCBMgr_info {
73 ULONG si_baseaddr;
74 UCHAR si_present;
75 UCHAR si_intvect;
76 UCHAR si_id;
77 UCHAR si_lun;
78 USHORT si_fw_revision;
79 USHORT si_per_targ_init_sync;
80 USHORT si_per_targ_fast_nego;
81 USHORT si_per_targ_ultra_nego;
82 USHORT si_per_targ_no_disc;
83 USHORT si_per_targ_wide_nego;
84 USHORT si_flags;
85 UCHAR si_card_family;
86 UCHAR si_bustype;
87 UCHAR si_card_model[3];
88 UCHAR si_relative_cardnum;
89 UCHAR si_reserved[4];
90 ULONG si_OS_reserved;
91 UCHAR si_XlatInfo[4];
92 ULONG si_reserved2[5];
93 ULONG si_secondary_range;
94} SCCBMGR_INFO;
95
47b5d69c 96typedef SCCBMGR_INFO * PSCCBMGR_INFO;
1da177e4
LT
97
98
47b5d69c
JB
99#define SCSI_PARITY_ENA 0x0001
100#define LOW_BYTE_TERM 0x0010
101#define HIGH_BYTE_TERM 0x0020
102#define BUSTYPE_PCI 0x3
1da177e4
LT
103
104#define SUPPORT_16TAR_32LUN 0x0002
105#define SOFT_RESET 0x0004
106#define EXTENDED_TRANSLATION 0x0008
107#define POST_ALL_UNDERRRUNS 0x0040
108#define FLAG_SCAM_ENABLED 0x0080
109#define FLAG_SCAM_LEVEL2 0x0100
110
111
112
113
114#define HARPOON_FAMILY 0x02
115
116
1da177e4 117
32357988 118/* SCCB struct used for both SCCB and UCB manager compiles!
1da177e4
LT
119 * The UCB Manager treats the SCCB as it's 'native hardware structure'
120 */
121
122
123#pragma pack(1)
124typedef struct _SCCB {
125 UCHAR OperationCode;
126 UCHAR ControlByte;
127 UCHAR CdbLength;
128 UCHAR RequestSenseLength;
129 ULONG DataLength;
130 ULONG DataPointer;
131 UCHAR CcbRes[2];
132 UCHAR HostStatus;
133 UCHAR TargetStatus;
134 UCHAR TargID;
135 UCHAR Lun;
136 UCHAR Cdb[12];
137 UCHAR CcbRes1;
138 UCHAR Reserved1;
139 ULONG Reserved2;
140 ULONG SensePointer;
141
142
143 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
144 ULONG SccbIOPort; /* Identifies board base port */
145 UCHAR SccbStatus;
146 UCHAR SCCBRes2;
147 USHORT SccbOSFlags;
148
149
150 ULONG Sccb_XferCnt; /* actual transfer count */
151 ULONG Sccb_ATC;
152 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
153 ULONG Sccb_res1;
154 USHORT Sccb_MGRFlags;
155 USHORT Sccb_sgseg;
156 UCHAR Sccb_scsimsg; /* identify msg for selection */
157 UCHAR Sccb_tag;
158 UCHAR Sccb_scsistat;
159 UCHAR Sccb_idmsg; /* image of last msg in */
160 PSCCB Sccb_forwardlink;
161 PSCCB Sccb_backlink;
162 ULONG Sccb_savedATC;
163 UCHAR Save_Cdb[6];
164 UCHAR Save_CdbLen;
165 UCHAR Sccb_XferState;
166 ULONG Sccb_SGoffset;
1da177e4
LT
167 } SCCB;
168
1da177e4
LT
169
170#pragma pack()
171
172
173
1da177e4
LT
174#define SCATTER_GATHER_COMMAND 0x02
175#define RESIDUAL_COMMAND 0x03
176#define RESIDUAL_SG_COMMAND 0x04
177#define RESET_COMMAND 0x81
178
179
180#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
181#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
1da177e4
LT
182#define SCCB_DATA_XFER_OUT 0x10 /* Write */
183#define SCCB_DATA_XFER_IN 0x08 /* Read */
184
185
1da177e4
LT
186#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
187
188
189#define BUS_FREE_ST 0
190#define SELECT_ST 1
191#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
192#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
193#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
194#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
195#define COMMAND_ST 6
196#define DATA_OUT_ST 7
197#define DATA_IN_ST 8
198#define DISCONNECT_ST 9
1da177e4 199#define ABORT_ST 11
1da177e4
LT
200
201
202#define F_HOST_XFER_DIR 0x01
203#define F_ALL_XFERRED 0x02
204#define F_SG_XFER 0x04
205#define F_AUTO_SENSE 0x08
206#define F_ODD_BALL_CNT 0x10
207#define F_NO_DATA_YET 0x80
208
209
210#define F_STATUSLOADED 0x01
1da177e4
LT
211#define F_DEV_SELECTED 0x04
212
213
214#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
215#define SCCB_DATA_UNDER_RUN 0x0C
216#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
217#define SCCB_DATA_OVER_RUN 0x12
1da177e4
LT
218#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
219
1da177e4
LT
220#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
221#define SCCB_BM_ERR 0x30 /* BusMaster error. */
222#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
223
224
225
1da177e4
LT
226
227
228#define SCCB_IN_PROCESS 0x00
229#define SCCB_SUCCESS 0x01
230#define SCCB_ABORT 0x02
1da177e4 231#define SCCB_ERROR 0x04
1da177e4 232
1da177e4
LT
233
234
1da177e4
LT
235#define ORION_FW_REV 3110
236
1da177e4
LT
237
238
1da177e4 239#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
1da177e4
LT
240
241#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
242
1da177e4 243
47b5d69c
JB
244#define MAX_SCSI_TAR 16
245#define MAX_LUN 32
246#define LUN_MASK 0x1f
1da177e4 247
1da177e4 248#define SG_BUF_CNT 16 /*Number of prefetched elements. */
1da177e4
LT
249
250#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
1da177e4
LT
251
252
d8b6b8bd
AD
253#define RD_HARPOON(ioport) inb((u32bits)ioport)
254#define RDW_HARPOON(ioport) inw((u32bits)ioport)
255#define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
256#define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
257#define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
258#define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
1da177e4
LT
259
260
261#define TAR_SYNC_MASK (BIT(7)+BIT(6))
1da177e4
LT
262#define SYNC_TRYING BIT(6)
263#define SYNC_SUPPORTED (BIT(7)+BIT(6))
264
265#define TAR_WIDE_MASK (BIT(5)+BIT(4))
1da177e4
LT
266#define WIDE_ENABLED BIT(4)
267#define WIDE_NEGOCIATED BIT(5)
268
269#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
1da177e4
LT
270#define TAG_Q_TRYING BIT(2)
271#define TAG_Q_REJECT BIT(3)
1da177e4
LT
272
273#define TAR_ALLOW_DISC BIT(0)
274
275
276#define EE_SYNC_MASK (BIT(0)+BIT(1))
1da177e4
LT
277#define EE_SYNC_5MB BIT(0)
278#define EE_SYNC_10MB BIT(1)
279#define EE_SYNC_20MB (BIT(0)+BIT(1))
280
1da177e4
LT
281#define EE_WIDE_SCSI BIT(7)
282
283
47b5d69c 284typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
1da177e4
LT
285
286
287typedef struct SCCBMgr_tar_info {
288
289 PSCCB TarSelQ_Head;
290 PSCCB TarSelQ_Tail;
291 UCHAR TarLUN_CA; /*Contingent Allgiance */
292 UCHAR TarTagQ_Cnt;
293 UCHAR TarSelQ_Cnt;
294 UCHAR TarStatus;
295 UCHAR TarEEValue;
296 UCHAR TarSyncCtrl;
297 UCHAR TarReserved[2]; /* for alignment */
298 UCHAR LunDiscQ_Idx[MAX_LUN];
299 UCHAR TarLUNBusy[MAX_LUN];
300} SCCBMGR_TAR_INFO;
301
302typedef struct NVRAMInfo {
303 UCHAR niModel; /* Model No. of card */
304 UCHAR niCardNo; /* Card no. */
1da177e4 305 ULONG niBaseAddr; /* Port Address of card */
1da177e4
LT
306 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
307 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
308 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
309 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
310 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
311 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
312}NVRAMINFO;
313
1da177e4 314typedef NVRAMINFO *PNVRamInfo;
1da177e4
LT
315
316#define MODEL_LT 1
317#define MODEL_DL 2
318#define MODEL_LW 3
319#define MODEL_DW 4
320
321
322typedef struct SCCBcard {
323 PSCCB currentSCCB;
1da177e4 324 PSCCBMGR_INFO cardInfo;
1da177e4 325
1da177e4 326 ULONG ioPort;
1da177e4
LT
327
328 USHORT cmdCounter;
329 UCHAR discQCount;
330 UCHAR tagQ_Lst;
331 UCHAR cardIndex;
332 UCHAR scanIndex;
333 UCHAR globalFlags;
334 UCHAR ourId;
335 PNVRamInfo pNvRamInfo;
336 PSCCB discQ_Tbl[QUEUE_DEPTH];
337
338}SCCBCARD;
339
1da177e4 340typedef struct SCCBcard *PSCCBcard;
1da177e4
LT
341
342
343#define F_TAG_STARTED 0x01
344#define F_CONLUN_IO 0x02
345#define F_DO_RENEGO 0x04
346#define F_NO_FILTER 0x08
347#define F_GREEN_PC 0x10
348#define F_HOST_XFER_ACT 0x20
349#define F_NEW_SCCB_CMD 0x40
350#define F_UPDATE_EEPROM 0x80
351
352
353#define ID_STRING_LENGTH 32
354#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
355
1da177e4
LT
356
357#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
358
359#define ASSIGN_ID 0x00
360#define SET_P_FLAG 0x01
361#define CFG_CMPLT 0x03
362#define DOM_MSTR 0x0F
363#define SYNC_PTRN 0x1F
364
365#define ID_0_7 0x18
366#define ID_8_F 0x11
1da177e4
LT
367#define MISC_CODE 0x14
368#define CLR_P_FLAG 0x18
1da177e4 369
1da177e4
LT
370
371
372#define INIT_SELTD 0x01
373#define LEVEL2_TAR 0x02
374
375
376enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
377 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
378 CLR_PRIORITY,NO_ID_AVAIL };
379
380typedef struct SCCBscam_info {
381
382 UCHAR id_string[ID_STRING_LENGTH];
383 enum scam_id_st state;
384
85ae97d8 385} SCCBSCAM_INFO;
1da177e4 386
1da177e4 387
1da177e4 388#define SCSI_REQUEST_SENSE 0x03
1da177e4
LT
389#define SCSI_READ 0x08
390#define SCSI_WRITE 0x0A
1da177e4 391#define SCSI_START_STOP_UNIT 0x1B
1da177e4
LT
392#define SCSI_READ_EXTENDED 0x28
393#define SCSI_WRITE_EXTENDED 0x2A
1da177e4 394#define SCSI_WRITE_AND_VERIFY 0x2E
1da177e4
LT
395
396
397
398#define SSGOOD 0x00
399#define SSCHECK 0x02
1da177e4
LT
400#define SSQ_FULL 0x28
401
402
1da177e4
LT
403
404
405#define SMCMD_COMP 0x00
406#define SMEXT 0x01
407#define SMSAVE_DATA_PTR 0x02
408#define SMREST_DATA_PTR 0x03
409#define SMDISC 0x04
1da177e4
LT
410#define SMABORT 0x06
411#define SMREJECT 0x07
412#define SMNO_OP 0x08
413#define SMPARITY 0x09
414#define SMDEV_RESET 0x0C
415#define SMABORT_TAG 0x0D
416#define SMINIT_RECOVERY 0x0F
417#define SMREL_RECOVERY 0x10
418
419#define SMIDENT 0x80
420#define DISC_PRIV 0x40
421
422
423#define SMSYNC 0x01
1da177e4
LT
424#define SMWDTR 0x03
425#define SM8BIT 0x00
426#define SM16BIT 0x01
1da177e4
LT
427#define SMIGNORWR 0x23 /* Ignore Wide Residue */
428
429
1da177e4
LT
430
431
432
1da177e4
LT
433
434
435
436#define SIX_BYTE_CMD 0x06
1da177e4
LT
437#define TWELVE_BYTE_CMD 0x0C
438
439#define ASYNC 0x00
1da177e4
LT
440#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
441
1da177e4
LT
442
443#define EEPROM_WD_CNT 256
444
445#define EEPROM_CHECK_SUM 0
446#define FW_SIGNATURE 2
447#define MODEL_NUMB_0 4
1da177e4 448#define MODEL_NUMB_2 6
1da177e4 449#define MODEL_NUMB_4 8
1da177e4
LT
450#define SYSTEM_CONFIG 16
451#define SCSI_CONFIG 17
452#define BIOS_CONFIG 18
1da177e4
LT
453#define SCAM_CONFIG 20
454#define ADAPTER_SCSI_ID 24
455
456
457#define IGNORE_B_SCAN 32
458#define SEND_START_ENA 34
459#define DEVICE_ENABLE 36
460
461#define SYNC_RATE_TBL 38
462#define SYNC_RATE_TBL01 38
463#define SYNC_RATE_TBL23 40
464#define SYNC_RATE_TBL45 42
465#define SYNC_RATE_TBL67 44
466#define SYNC_RATE_TBL89 46
467#define SYNC_RATE_TBLab 48
468#define SYNC_RATE_TBLcd 50
469#define SYNC_RATE_TBLef 52
470
471
472
473#define EE_SCAMBASE 256
474
475
476
1da177e4
LT
477 #define SCAM_ENABLED BIT(2)
478 #define SCAM_LEVEL2 BIT(3)
479
480
481 #define RENEGO_ENA BITW(10)
482 #define CONNIO_ENA BITW(11)
483 #define GREEN_PC_ENA BITW(12)
484
485
486 #define AUTO_RATE_00 00
487 #define AUTO_RATE_05 01
488 #define AUTO_RATE_10 02
489 #define AUTO_RATE_20 03
490
491 #define WIDE_NEGO_BIT BIT(7)
492 #define DISC_ENABLE_BIT BIT(6)
493
494
1da177e4
LT
495
496 #define hp_vendor_id_0 0x00 /* LSB */
497 #define ORION_VEND_0 0x4B
498
499 #define hp_vendor_id_1 0x01 /* MSB */
500 #define ORION_VEND_1 0x10
501
502 #define hp_device_id_0 0x02 /* LSB */
503 #define ORION_DEV_0 0x30
504
505 #define hp_device_id_1 0x03 /* MSB */
506 #define ORION_DEV_1 0x81
507
508 /* Sub Vendor ID and Sub Device ID only available in
509 Harpoon Version 2 and higher */
510
1da177e4 511 #define hp_sub_device_id_0 0x06 /* LSB */
1da177e4
LT
512
513
1da177e4
LT
514
515 #define hp_semaphore 0x0C
516 #define SCCB_MGR_ACTIVE BIT(0)
517 #define TICKLE_ME BIT(1)
518 #define SCCB_MGR_PRESENT BIT(3)
519 #define BIOS_IN_USE BIT(4)
520
1da177e4 521
1da177e4
LT
522
523 #define hp_sys_ctrl 0x0F
524
525 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
526 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
527 #define HALT_MACH BIT(3) /*Halt State Machine */
528 #define HARD_ABORT BIT(4) /*Hard Abort */
1da177e4 529
1da177e4 530
1da177e4 531
1da177e4
LT
532
533
1da177e4 534
1da177e4 535
1da177e4 536
1da177e4
LT
537
538 #define hp_host_blk_cnt 0x13
539
1da177e4
LT
540 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
541
542 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
543
544
1da177e4
LT
545
546 #define hp_int_mask 0x17
547
548 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
549 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
1da177e4
LT
550
551
552 #define hp_xfer_cnt_lo 0x18
1da177e4
LT
553 #define hp_xfer_cnt_hi 0x1A
554 #define hp_xfer_cmd 0x1B
555
556 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
557 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
1da177e4
LT
558
559
560 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
1da177e4
LT
561
562 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
1da177e4
LT
563
564 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
565
566 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
567 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
1da177e4
LT
568
569 #define hp_host_addr_lo 0x1C
1da177e4 570 #define hp_host_addr_hmi 0x1E
1da177e4 571
1da177e4
LT
572 #define hp_ee_ctrl 0x22
573
574 #define EXT_ARB_ACK BIT(7)
575 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
576 #define SEE_MS BIT(5)
577 #define SEE_CS BIT(3)
578 #define SEE_CLK BIT(2)
579 #define SEE_DO BIT(1)
580 #define SEE_DI BIT(0)
581
582 #define EE_READ 0x06
583 #define EE_WRITE 0x05
584 #define EWEN 0x04
585 #define EWEN_ADDR 0x03C0
586 #define EWDS 0x04
587 #define EWDS_ADDR 0x0000
588
1da177e4 589
1da177e4 590
1da177e4
LT
591
592
593
594
595 #define hp_bm_ctrl 0x26
596
597 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
598 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
1da177e4
LT
599 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
600 #define FAST_SINGLE BIT(6) /*?? */
601
602 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
603
1da177e4
LT
604
605 #define hp_sg_addr 0x28
606 #define hp_page_ctrl 0x29
607
608 #define SCATTER_EN BIT(0)
609 #define SGRAM_ARAM BIT(1)
1da177e4
LT
610 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
611 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
612
1da177e4 613
1da177e4 614
1da177e4
LT
615
616 #define hp_pci_stat_cfg 0x2D
617
1da177e4 618 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
1da177e4 619
1da177e4 620
1da177e4 621
1da177e4 622
1da177e4 623
1da177e4 624
1da177e4 625
1da177e4
LT
626
627 #define hp_rev_num 0x33
628
1da177e4
LT
629
630 #define hp_stack_data 0x34
631 #define hp_stack_addr 0x35
632
633 #define hp_ext_status 0x36
634
635 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
636 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
637 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
1da177e4
LT
638 #define CMD_ABORTED BIT(4) /*Command aborted */
639 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
640 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
641 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
642 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
643 BM_PARITY_ERR | PIO_OVERRUN)
644
645 #define hp_int_status 0x37
646
1da177e4
LT
647 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
648 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
1da177e4 649 #define INT_ASSERTED BIT(5) /* */
1da177e4
LT
650
651
652 #define hp_fifo_cnt 0x38
1da177e4 653
1da177e4
LT
654
655
656
1da177e4
LT
657 #define hp_intena 0x40
658
659 #define RESET BITW(7)
660 #define PROG_HLT BITW(6)
661 #define PARITY BITW(5)
662 #define FIFO BITW(4)
663 #define SEL BITW(3)
664 #define SCAM_SEL BITW(2)
665 #define RSEL BITW(1)
666 #define TIMEOUT BITW(0)
667 #define BUS_FREE BITW(15)
668 #define XFER_CNT_0 BITW(14)
669 #define PHASE BITW(13)
670 #define IUNKWN BITW(12)
671 #define ICMD_COMP BITW(11)
672 #define ITICKLE BITW(10)
673 #define IDO_STRT BITW(9)
674 #define ITAR_DISC BITW(8)
675 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
676 #define CLR_ALL_INT 0xFFFF
677 #define CLR_ALL_INT_1 0xFF00
678
679 #define hp_intstat 0x42
680
681 #define hp_scsisig 0x44
682
683 #define SCSI_SEL BIT(7)
684 #define SCSI_BSY BIT(6)
685 #define SCSI_REQ BIT(5)
686 #define SCSI_ACK BIT(4)
687 #define SCSI_ATN BIT(3)
688 #define SCSI_CD BIT(2)
689 #define SCSI_MSG BIT(1)
690 #define SCSI_IOBIT BIT(0)
691
692 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
1da177e4 693 #define S_MSGO_PH (BIT(2)+BIT(1) )
1da177e4
LT
694 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
695 #define S_DATAI_PH ( BIT(0))
696 #define S_DATAO_PH 0x00
697 #define S_ILL_PH ( BIT(1) )
698
699 #define hp_scsictrl_0 0x45
700
1da177e4
LT
701 #define SEL_TAR BIT(6)
702 #define ENA_ATN BIT(4)
703 #define ENA_RESEL BIT(2)
704 #define SCSI_RST BIT(1)
705 #define ENA_SCAM_SEL BIT(0)
706
707
708
709 #define hp_portctrl_0 0x46
710
711 #define SCSI_PORT BIT(7)
712 #define SCSI_INBIT BIT(6)
713 #define DMA_PORT BIT(5)
714 #define DMA_RD BIT(4)
715 #define HOST_PORT BIT(3)
716 #define HOST_WRT BIT(2)
717 #define SCSI_BUS_EN BIT(1)
718 #define START_TO BIT(0)
719
720 #define hp_scsireset 0x47
721
1da177e4
LT
722 #define SCSI_INI BIT(6)
723 #define SCAM_EN BIT(5)
1da177e4
LT
724 #define DMA_RESET BIT(3)
725 #define HPSCSI_RESET BIT(2)
726 #define PROG_RESET BIT(1)
727 #define FIFO_CLR BIT(0)
728
729 #define hp_xfercnt_0 0x48
1da177e4 730 #define hp_xfercnt_2 0x4A
1da177e4
LT
731
732 #define hp_fifodata_0 0x4C
1da177e4
LT
733 #define hp_addstat 0x4E
734
735 #define SCAM_TIMER BIT(7)
1da177e4
LT
736 #define SCSI_MODE8 BIT(3)
737 #define SCSI_PAR_ERR BIT(0)
738
739 #define hp_prgmcnt_0 0x4F
740
1da177e4
LT
741
742 #define hp_selfid_0 0x50
743 #define hp_selfid_1 0x51
744 #define hp_arb_id 0x52
745
1da177e4
LT
746
747 #define hp_select_id 0x53
748
1da177e4
LT
749
750 #define hp_synctarg_base 0x54
751 #define hp_synctarg_12 0x54
752 #define hp_synctarg_13 0x55
753 #define hp_synctarg_14 0x56
754 #define hp_synctarg_15 0x57
755
756 #define hp_synctarg_8 0x58
757 #define hp_synctarg_9 0x59
758 #define hp_synctarg_10 0x5A
759 #define hp_synctarg_11 0x5B
760
761 #define hp_synctarg_4 0x5C
762 #define hp_synctarg_5 0x5D
763 #define hp_synctarg_6 0x5E
764 #define hp_synctarg_7 0x5F
765
766 #define hp_synctarg_0 0x60
767 #define hp_synctarg_1 0x61
768 #define hp_synctarg_2 0x62
769 #define hp_synctarg_3 0x63
770
1da177e4 771 #define NARROW_SCSI BIT(4)
1da177e4
LT
772 #define DEFAULT_OFFSET 0x0F
773
774 #define hp_autostart_0 0x64
775 #define hp_autostart_1 0x65
1da177e4
LT
776 #define hp_autostart_3 0x67
777
778
779
1da177e4
LT
780 #define AUTO_IMMED BIT(5)
781 #define SELECT BIT(6)
1da177e4 782 #define END_DATA (BIT(7)+BIT(6))
1da177e4
LT
783
784 #define hp_gp_reg_0 0x68
785 #define hp_gp_reg_1 0x69
1da177e4
LT
786 #define hp_gp_reg_3 0x6B
787
788 #define hp_seltimeout 0x6C
789
790
1da177e4
LT
791 #define TO_4ms 0x67 /* 3.9959ms */
792
793 #define TO_5ms 0x03 /* 4.9152ms */
794 #define TO_10ms 0x07 /* 11.xxxms */
795 #define TO_250ms 0x99 /* 250.68ms */
796 #define TO_290ms 0xB1 /* 289.99ms */
1da177e4
LT
797
798 #define hp_clkctrl_0 0x6D
799
800 #define PWR_DWN BIT(6)
801 #define ACTdeassert BIT(4)
1da177e4 802 #define CLK_40MHZ (BIT(1) + BIT(0))
1da177e4
LT
803
804 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
805
806 #define hp_fiforead 0x6E
807 #define hp_fifowrite 0x6F
808
809 #define hp_offsetctr 0x70
810 #define hp_xferstat 0x71
811
1da177e4 812 #define FIFO_EMPTY BIT(6)
1da177e4
LT
813
814 #define hp_portctrl_1 0x72
815
1da177e4
LT
816 #define CHK_SCSI_P BIT(3)
817 #define HOST_MODE8 BIT(0)
1da177e4
LT
818
819 #define hp_xfer_pad 0x73
820
821 #define ID_UNLOCK BIT(3)
1da177e4
LT
822
823 #define hp_scsidata_0 0x74
824 #define hp_scsidata_1 0x75
1da177e4 825
1da177e4 826
1da177e4
LT
827
828 #define hp_aramBase 0x80
829 #define BIOS_DATA_OFFSET 0x60
830 #define BIOS_RELATIVE_CARD 0x64
831
832
833
834
1da177e4
LT
835 #define AR3 (BITW(9) + BITW(8))
836 #define SDATA BITW(10)
837
1da177e4
LT
838
839 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
840
841 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
842
1da177e4 843
1da177e4
LT
844
845 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
846
847 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
848
849
850 #define ADATA_OUT 0x00
851 #define ADATA_IN BITW(8)
852 #define ACOMMAND BITW(10)
853 #define ASTATUS (BITW(10)+BITW(8))
854 #define AMSG_OUT (BITW(10)+BITW(9))
855 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
1da177e4
LT
856
857
858 #define BRH_OP BITW(13) /* Branch */
859
860
861 #define ALWAYS 0x00
862 #define EQUAL BITW(8)
863 #define NOT_EQ BITW(9)
864
865 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
866
867
1da177e4 868 #define FIFO_0 BITW(10)
1da177e4
LT
869
870
871 #define MPM_OP BITW(15) /* Match phase and move data */
872
1da177e4
LT
873
874 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
875
876
877 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
878
879
880 #define D_AR0 0x00
881 #define D_AR1 BIT(0)
1da177e4
LT
882 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
883
884
1da177e4 885
1da177e4 886
1da177e4 887
1da177e4 888
1da177e4 889
1da177e4
LT
890
891
892 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
893
894 #define SSI_OP (BITW(15)+BITW(11))
895
896
897 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
898 #define SSI_IDO_STRT (IDO_STRT >> 8)
1da177e4
LT
899
900 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
901 #define SSI_ITICKLE (ITICKLE >> 8)
902
903 #define SSI_IUNKWN (IUNKWN >> 8)
904 #define SSI_INO_CC (IUNKWN >> 8)
905 #define SSI_IRFAIL (IUNKWN >> 8)
906
907
908 #define NP 0x10 /*Next Phase */
909 #define NTCMD 0x02 /*Non- Tagged Command start */
910 #define CMDPZ 0x04 /*Command phase */
911 #define DINT 0x12 /*Data Out/In interrupt */
912 #define DI 0x13 /*Data Out */
1da177e4
LT
913 #define DC 0x19 /*Disconnect Message */
914 #define ST 0x1D /*Status Phase */
915 #define UNKNWN 0x24 /*Unknown bus action */
916 #define CC 0x25 /*Command Completion failure */
917 #define TICK 0x26 /*New target reselected us. */
1da177e4
LT
918 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
919
920
921 #define ID_MSG_STRT hp_aramBase + 0x00
922 #define NON_TAG_ID_MSG hp_aramBase + 0x06
923 #define CMD_STRT hp_aramBase + 0x08
924 #define SYNC_MSGS hp_aramBase + 0x08
925
926
927
928
929
930 #define TAG_STRT 0x00
1da177e4
LT
931 #define DISCONNECT_START 0x10/2
932 #define END_DATA_START 0x14/2
1da177e4 933 #define CMD_ONLY_STRT CMDPZ/2
1da177e4
LT
934 #define SELCHK_STRT SELCHK/2
935
936
937
938
1da177e4 939
1da177e4
LT
940
941
1da177e4 942
1da177e4
LT
943
944#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
945/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
946 xfercnt <<= 16,\
947 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
948 */
1da177e4
LT
949#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
950 addr >>= 16,\
951 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
952 WR_HARP32(port,hp_xfercnt_0,count),\
953 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
954 count >>= 16,\
955 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
1da177e4
LT
956
957#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
958 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
959
960
961#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
962 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
963
1da177e4 964
1da177e4
LT
965
966#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
967 WR_HARPOON(port+hp_scsireset, 0x00))
968
969#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
970 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
971
972#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
973 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
974
975#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
976 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
977
978#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
979 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
980
981
982
1da177e4 983
47b5d69c
JB
984static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
985static void FPT_ssel(ULONG port, UCHAR p_card);
986static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
987static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
988static void FPT_stsyncn(ULONG port, UCHAR p_card);
989static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
990static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
991 PSCCBMgr_tar_info currTar_Info);
992static void FPT_sresb(ULONG port, UCHAR p_card);
993static void FPT_sxfrp(ULONG p_port, UCHAR p_card);
994static void FPT_schkdd(ULONG port, UCHAR p_card);
995static UCHAR FPT_RdStack(ULONG port, UCHAR index);
996static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
997static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
1da177e4 998
47b5d69c
JB
999static void FPT_SendMsg(ULONG port, UCHAR message);
1000static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1001 UCHAR error_code);
1da177e4 1002
47b5d69c
JB
1003static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1004static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1da177e4 1005
47b5d69c
JB
1006static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1007static void FPT_stwidn(ULONG port, UCHAR p_card);
1008static void FPT_siwidr(ULONG port, UCHAR width);
1da177e4
LT
1009
1010
47b5d69c
JB
1011static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1012static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1013static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1014 UCHAR p_card);
1015static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1016static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1017static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1018static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1019static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1020static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1021static UCHAR FPT_CalcLrc(UCHAR buffer[]);
1da177e4 1022
1da177e4 1023
47b5d69c
JB
1024static void FPT_Wait1Second(ULONG p_port);
1025static void FPT_Wait(ULONG p_port, UCHAR p_delay);
1026static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1027static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1028static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1029static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1030static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
1da177e4
LT
1031
1032
1da177e4 1033
47b5d69c
JB
1034static void FPT_phaseDataOut(ULONG port, UCHAR p_card);
1035static void FPT_phaseDataIn(ULONG port, UCHAR p_card);
1036static void FPT_phaseCommand(ULONG port, UCHAR p_card);
1037static void FPT_phaseStatus(ULONG port, UCHAR p_card);
1038static void FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1039static void FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1040static void FPT_phaseIllegal(ULONG port, UCHAR p_card);
1da177e4 1041
47b5d69c
JB
1042static void FPT_phaseDecode(ULONG port, UCHAR p_card);
1043static void FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1044static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
1da177e4 1045
1da177e4 1046
1da177e4 1047
1da177e4 1048
47b5d69c
JB
1049static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1050static void FPT_BusMasterInit(ULONG p_port);
1051static void FPT_DiagEEPROM(ULONG p_port);
1da177e4 1052
1da177e4 1053
1da177e4
LT
1054
1055
47b5d69c
JB
1056static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1057static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1058static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1059static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1060static void FPT_hostDataXferRestart(PSCCB currSCCB);
1da177e4 1061
1da177e4 1062
47b5d69c
JB
1063static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1064 PSCCBcard pCurrCard, USHORT p_int);
1da177e4 1065
47b5d69c
JB
1066static void FPT_SccbMgrTableInitAll(void);
1067static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1068static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
1da177e4 1069
1da177e4
LT
1070
1071
47b5d69c 1072static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
1da177e4 1073
47b5d69c
JB
1074static int FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1075static void FPT_scbusf(ULONG p_port);
1076static void FPT_scsel(ULONG p_port);
1077static void FPT_scasid(UCHAR p_card, ULONG p_port);
1078static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1079static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1080static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1081static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1082static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1083static UCHAR FPT_scvalq(UCHAR p_quintet);
1084static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1085static void FPT_scwtsel(ULONG p_port);
1086static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1087static void FPT_scsavdi(UCHAR p_card, ULONG p_port);
1088static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
1da177e4 1089
1da177e4 1090
47b5d69c
JB
1091static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1092static void FPT_autoLoadDefaultMap(ULONG p_port);
1da177e4
LT
1093
1094
1095
1da177e4 1096
47b5d69c
JB
1097static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1098static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1099static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1100static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1da177e4 1101
1da177e4 1102
47b5d69c
JB
1103static UCHAR FPT_mbCards = 0;
1104static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1105 ' ', 'B', 'T', '-', '9', '3', '0', \
1106 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1107 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1da177e4 1108
47b5d69c 1109static USHORT FPT_default_intena = 0;
1da177e4
LT
1110
1111
47b5d69c 1112static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
1da177e4 1113
1da177e4
LT
1114
1115/*---------------------------------------------------------------------
1116 *
d8b6b8bd 1117 * Function: FlashPoint_ProbeHostAdapter
1da177e4
LT
1118 *
1119 * Description: Setup and/or Search for cards and return info to caller.
1120 *
1121 *---------------------------------------------------------------------*/
1122
d8b6b8bd 1123static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1da177e4 1124{
1da177e4 1125 static UCHAR first_time = 1;
1da177e4
LT
1126
1127 UCHAR i,j,id,ScamFlg;
1128 USHORT temp,temp2,temp3,temp4,temp5,temp6;
1da177e4 1129 ULONG ioport;
1da177e4
LT
1130 PNVRamInfo pCurrNvRam;
1131
1da177e4 1132 ioport = pCardInfo->si_baseaddr;
1da177e4
LT
1133
1134
1135 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1136 return((int)FAILURE);
1137
1138 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1139 return((int)FAILURE);
1140
1141 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1142 return((int)FAILURE);
1143
1144 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1145 return((int)FAILURE);
1146
1147
1148 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1149
1150/* For new Harpoon then check for sub_device ID LSB
1151 the bits(0-3) must be all ZERO for compatible with
1152 current version of SCCBMgr, else skip this Harpoon
1153 device. */
1154
1155 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1156 return((int)FAILURE);
1157 }
1158
1159 if (first_time)
1160 {
47b5d69c 1161 FPT_SccbMgrTableInitAll();
1da177e4 1162 first_time = 0;
47b5d69c 1163 FPT_mbCards = 0;
1da177e4
LT
1164 }
1165
47b5d69c
JB
1166 if(FPT_RdStack(ioport, 0) != 0x00) {
1167 if(FPT_ChkIfChipInitialized(ioport) == 0)
1da177e4
LT
1168 {
1169 pCurrNvRam = NULL;
1170 WR_HARPOON(ioport+hp_semaphore, 0x00);
47b5d69c
JB
1171 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1172 FPT_DiagEEPROM(ioport);
1da177e4
LT
1173 }
1174 else
1175 {
47b5d69c
JB
1176 if(FPT_mbCards < MAX_MB_CARDS) {
1177 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1178 FPT_mbCards++;
1da177e4 1179 pCurrNvRam->niBaseAddr = ioport;
47b5d69c 1180 FPT_RNVRamData(pCurrNvRam);
1da177e4
LT
1181 }else
1182 return((int) FAILURE);
1183 }
1184 }else
1185 pCurrNvRam = NULL;
1da177e4
LT
1186
1187 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1188 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1189
1190 if(pCurrNvRam)
1191 pCardInfo->si_id = pCurrNvRam->niAdapId;
1192 else
47b5d69c 1193 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1da177e4
LT
1194 (UCHAR)0x0FF);
1195
1196 pCardInfo->si_lun = 0x00;
1197 pCardInfo->si_fw_revision = ORION_FW_REV;
1198 temp2 = 0x0000;
1199 temp3 = 0x0000;
1200 temp4 = 0x0000;
1201 temp5 = 0x0000;
1202 temp6 = 0x0000;
1203
1204 for (id = 0; id < (16/2); id++) {
1205
1206 if(pCurrNvRam){
1207 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1208 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1209 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1210 }else
47b5d69c 1211 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1da177e4
LT
1212
1213 for (i = 0; i < 2; temp >>=8,i++) {
1214
1215 temp2 >>= 1;
1216 temp3 >>= 1;
1217 temp4 >>= 1;
1218 temp5 >>= 1;
1219 temp6 >>= 1;
1220 switch (temp & 0x3)
1221 {
1222 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1223 temp6 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1225 temp5 |= 0x8000; /* Fall through */
1226 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1227 temp2 |= 0x8000; /* Fall through */
1228 case AUTO_RATE_00: /* Asynchronous */
1229 break;
1230 }
1231
1232 if (temp & DISC_ENABLE_BIT)
1233 temp3 |= 0x8000;
1234
1235 if (temp & WIDE_NEGO_BIT)
1236 temp4 |= 0x8000;
1237
1238 }
1239 }
1240
1241 pCardInfo->si_per_targ_init_sync = temp2;
1242 pCardInfo->si_per_targ_no_disc = temp3;
1243 pCardInfo->si_per_targ_wide_nego = temp4;
1244 pCardInfo->si_per_targ_fast_nego = temp5;
1245 pCardInfo->si_per_targ_ultra_nego = temp6;
1246
1247 if(pCurrNvRam)
1248 i = pCurrNvRam->niSysConf;
1249 else
47b5d69c 1250 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1da177e4
LT
1251
1252 if(pCurrNvRam)
1253 ScamFlg = pCurrNvRam->niScamConf;
1254 else
47b5d69c 1255 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1da177e4
LT
1256
1257 pCardInfo->si_flags = 0x0000;
1258
1259 if (i & 0x01)
1260 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1261
1262 if (!(i & 0x02))
1263 pCardInfo->si_flags |= SOFT_RESET;
1264
1265 if (i & 0x10)
1266 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1267
1268 if (ScamFlg & SCAM_ENABLED)
1269 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1270
1271 if (ScamFlg & SCAM_LEVEL2)
1272 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1273
1274 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1275 if (i & 0x04) {
1276 j |= SCSI_TERM_ENA_L;
1277 }
1278 WR_HARPOON(ioport+hp_bm_ctrl, j );
1279
1280 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1281 if (i & 0x08) {
1282 j |= SCSI_TERM_ENA_H;
1283 }
1284 WR_HARPOON(ioport+hp_ee_ctrl, j );
1285
1286 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1287
1288 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1289
1290 pCardInfo->si_card_family = HARPOON_FAMILY;
1291 pCardInfo->si_bustype = BUSTYPE_PCI;
1292
1293 if(pCurrNvRam){
1294 pCardInfo->si_card_model[0] = '9';
1295 switch(pCurrNvRam->niModel & 0x0f){
1296 case MODEL_LT:
1297 pCardInfo->si_card_model[1] = '3';
1298 pCardInfo->si_card_model[2] = '0';
1299 break;
1300 case MODEL_LW:
1301 pCardInfo->si_card_model[1] = '5';
1302 pCardInfo->si_card_model[2] = '0';
1303 break;
1304 case MODEL_DL:
1305 pCardInfo->si_card_model[1] = '3';
1306 pCardInfo->si_card_model[2] = '2';
1307 break;
1308 case MODEL_DW:
1309 pCardInfo->si_card_model[1] = '5';
1310 pCardInfo->si_card_model[2] = '2';
1311 break;
1312 }
1313 }else{
47b5d69c 1314 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1da177e4 1315 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
47b5d69c 1316 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1da177e4
LT
1317
1318 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
1319 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
1320 }
1321
1322 if (pCardInfo->si_card_model[1] == '3')
1323 {
1324 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1325 pCardInfo->si_flags |= LOW_BYTE_TERM;
1326 }
1327 else if (pCardInfo->si_card_model[2] == '0')
1328 {
1329 temp = RD_HARPOON(ioport+hp_xfer_pad);
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1331 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1332 pCardInfo->si_flags |= LOW_BYTE_TERM;
1333 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1334 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1335 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1336 WR_HARPOON(ioport+hp_xfer_pad, temp);
1337 }
1338 else
1339 {
1340 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1341 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1342 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1343 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1344 temp3 = 0;
1345 for (i = 0; i < 8; i++)
1346 {
1347 temp3 <<= 1;
1348 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1349 temp3 |= 1;
1350 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1351 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1352 }
1353 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1354 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1355 if (!(temp3 & BIT(7)))
1356 pCardInfo->si_flags |= LOW_BYTE_TERM;
1357 if (!(temp3 & BIT(6)))
1358 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1359 }
1360
1361
1362 ARAM_ACCESS(ioport);
1363
1364 for ( i = 0; i < 4; i++ ) {
1365
1366 pCardInfo->si_XlatInfo[i] =
1367 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1368 }
1369
1370 /* return with -1 if no sort, else return with
1371 logical card number sorted by BIOS (zero-based) */
1372
1373 pCardInfo->si_relative_cardnum =
1374 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1375
1376 SGRAM_ACCESS(ioport);
1377
47b5d69c
JB
1378 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1379 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1380 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1381 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1382 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1383 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1384 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1385 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1da177e4
LT
1386
1387 pCardInfo->si_present = 0x01;
1388
1da177e4
LT
1389 return(0);
1390}
1391
1392
1393/*---------------------------------------------------------------------
1394 *
d8b6b8bd 1395 * Function: FlashPoint_HardwareResetHostAdapter
1da177e4
LT
1396 *
1397 * Description: Setup adapter for normal operation (hard reset).
1398 *
1399 *---------------------------------------------------------------------*/
1400
d8b6b8bd 1401static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1da177e4
LT
1402{
1403 PSCCBcard CurrCard = NULL;
1404 PNVRamInfo pCurrNvRam;
1405 UCHAR i,j,thisCard, ScamFlg;
1406 USHORT temp,sync_bit_map,id;
1da177e4 1407 ULONG ioport;
1da177e4 1408
1da177e4 1409 ioport = pCardInfo->si_baseaddr;
1da177e4
LT
1410
1411 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1412
1413 if (thisCard == MAX_CARDS) {
1414
1415 return(FAILURE);
1416 }
1417
47b5d69c 1418 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1da177e4 1419
47b5d69c
JB
1420 CurrCard = &FPT_BL_Card[thisCard];
1421 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1da177e4
LT
1422 break;
1423 }
1424
47b5d69c 1425 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1da177e4 1426
47b5d69c
JB
1427 FPT_BL_Card[thisCard].ioPort = ioport;
1428 CurrCard = &FPT_BL_Card[thisCard];
1da177e4 1429
47b5d69c
JB
1430 if(FPT_mbCards)
1431 for(i = 0; i < FPT_mbCards; i++){
1432 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1433 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1da177e4 1434 }
47b5d69c 1435 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1da177e4
LT
1436 CurrCard->cardIndex = thisCard;
1437 CurrCard->cardInfo = pCardInfo;
1438
1439 break;
1440 }
1441 }
1442
1443 pCurrNvRam = CurrCard->pNvRamInfo;
1444
1445 if(pCurrNvRam){
1446 ScamFlg = pCurrNvRam->niScamConf;
1447 }
1448 else{
47b5d69c 1449 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1da177e4
LT
1450 }
1451
1452
47b5d69c
JB
1453 FPT_BusMasterInit(ioport);
1454 FPT_XbowInit(ioport, ScamFlg);
1da177e4 1455
47b5d69c 1456 FPT_autoLoadDefaultMap(ioport);
1da177e4
LT
1457
1458
1459 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1460
1461 WR_HARPOON(ioport+hp_selfid_0, id);
1462 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1463 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1464 CurrCard->ourId = pCardInfo->si_id;
1465
1466 i = (UCHAR) pCardInfo->si_flags;
1467 if (i & SCSI_PARITY_ENA)
1468 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1469
1470 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1471 if (i & LOW_BYTE_TERM)
1472 j |= SCSI_TERM_ENA_L;
1473 WR_HARPOON(ioport+hp_bm_ctrl, j);
1474
1475 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1476 if (i & HIGH_BYTE_TERM)
1477 j |= SCSI_TERM_ENA_H;
1478 WR_HARPOON(ioport+hp_ee_ctrl, j );
1479
1480
1481 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1482
47b5d69c 1483 FPT_sresb(ioport,thisCard);
1da177e4 1484
47b5d69c 1485 FPT_scini(thisCard, pCardInfo->si_id, 0);
1da177e4 1486 }
1da177e4 1487
1da177e4 1488
1da177e4 1489
47b5d69c
JB
1490 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1491 CurrCard->globalFlags |= F_NO_FILTER;
1da177e4 1492
47b5d69c
JB
1493 if(pCurrNvRam){
1494 if(pCurrNvRam->niSysConf & 0x10)
1495 CurrCard->globalFlags |= F_GREEN_PC;
1496 }
1497 else{
1498 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1499 CurrCard->globalFlags |= F_GREEN_PC;
1500 }
1da177e4 1501
47b5d69c
JB
1502 /* Set global flag to indicate Re-Negotiation to be done on all
1503 ckeck condition */
1504 if(pCurrNvRam){
1505 if(pCurrNvRam->niScsiConf & 0x04)
1506 CurrCard->globalFlags |= F_DO_RENEGO;
1507 }
1508 else{
1509 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1510 CurrCard->globalFlags |= F_DO_RENEGO;
1511 }
1da177e4 1512
47b5d69c
JB
1513 if(pCurrNvRam){
1514 if(pCurrNvRam->niScsiConf & 0x08)
1515 CurrCard->globalFlags |= F_CONLUN_IO;
1516 }
1517 else{
1518 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1519 CurrCard->globalFlags |= F_CONLUN_IO;
1da177e4
LT
1520 }
1521
1da177e4 1522
47b5d69c 1523 temp = pCardInfo->si_per_targ_no_disc;
1da177e4 1524
47b5d69c 1525 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1da177e4 1526
47b5d69c
JB
1527 if (temp & id)
1528 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1529 }
1da177e4 1530
47b5d69c 1531 sync_bit_map = 0x0001;
1da177e4 1532
47b5d69c 1533 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1da177e4 1534
47b5d69c
JB
1535 if(pCurrNvRam){
1536 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1537 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1538 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1539 }else
1540 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1da177e4 1541
47b5d69c 1542 for (i = 0; i < 2; temp >>=8,i++) {
1da177e4 1543
47b5d69c 1544 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1da177e4 1545
47b5d69c
JB
1546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
1547 }
1da177e4 1548
47b5d69c
JB
1549 else {
1550 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1551 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1552 (UCHAR)(temp & ~EE_SYNC_MASK);
1553 }
1da177e4 1554
47b5d69c
JB
1555/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1556 (id*2+i >= 8)){
1557*/
1558 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1da177e4 1559
47b5d69c 1560 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1da177e4 1561
47b5d69c 1562 }
1da177e4 1563
47b5d69c
JB
1564 else { /* NARROW SCSI */
1565 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1566 }
1da177e4 1567
1da177e4 1568
47b5d69c 1569 sync_bit_map <<= 1;
1da177e4 1570
1da177e4 1571
1da177e4 1572
47b5d69c
JB
1573 }
1574 }
1da177e4 1575
47b5d69c
JB
1576 WR_HARPOON((ioport+hp_semaphore),
1577 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1da177e4 1578
47b5d69c
JB
1579 return((ULONG)CurrCard);
1580}
1581
d8b6b8bd 1582static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
1da177e4
LT
1583{
1584 UCHAR i;
1da177e4
LT
1585 ULONG portBase;
1586 ULONG regOffset;
1da177e4 1587 ULONG scamData;
1da177e4 1588 ULONG *pScamTbl;
1da177e4
LT
1589 PNVRamInfo pCurrNvRam;
1590
1591 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1592
1593 if(pCurrNvRam){
47b5d69c
JB
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1597 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1598 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1da177e4
LT
1599
1600 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
47b5d69c 1601 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
1da177e4
LT
1602
1603 portBase = pCurrNvRam->niBaseAddr;
1604
1605 for(i = 0; i < MAX_SCSI_TAR; i++){
1606 regOffset = hp_aramBase + 64 + i*4;
1da177e4 1607 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1da177e4
LT
1608 scamData = *pScamTbl;
1609 WR_HARP32(portBase, regOffset, scamData);
1610 }
1611
1612 }else{
47b5d69c 1613 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1da177e4
LT
1614 }
1615}
1da177e4
LT
1616
1617
47b5d69c 1618static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1da177e4
LT
1619{
1620 UCHAR i;
1da177e4
LT
1621 ULONG portBase;
1622 ULONG regOffset;
1da177e4 1623 ULONG scamData;
1da177e4 1624 ULONG *pScamTbl;
1da177e4 1625
47b5d69c
JB
1626 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1627 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1628 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1629 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1630 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1da177e4
LT
1631
1632 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
47b5d69c 1633 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
1da177e4
LT
1634
1635 portBase = pNvRamInfo->niBaseAddr;
1636
1637 for(i = 0; i < MAX_SCSI_TAR; i++){
1638 regOffset = hp_aramBase + 64 + i*4;
1639 RD_HARP32(portBase, regOffset, scamData);
1da177e4 1640 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1da177e4
LT
1641 *pScamTbl = scamData;
1642 }
1643
1644}
1645
47b5d69c 1646static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
1da177e4
LT
1647{
1648 WR_HARPOON(portBase + hp_stack_addr, index);
1649 return(RD_HARPOON(portBase + hp_stack_data));
1650}
1651
47b5d69c 1652static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
1da177e4
LT
1653{
1654 WR_HARPOON(portBase + hp_stack_addr, index);
1655 WR_HARPOON(portBase + hp_stack_data, data);
1656}
1657
1658
47b5d69c 1659static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
1da177e4 1660{
47b5d69c
JB
1661 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1662 return(0);
1da177e4
LT
1663 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1664 != CLKCTRL_DEFAULT)
47b5d69c 1665 return(0);
1da177e4
LT
1666 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1667 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
47b5d69c
JB
1668 return(1);
1669 return(0);
1da177e4
LT
1670
1671}
1672/*---------------------------------------------------------------------
1673 *
d8b6b8bd 1674 * Function: FlashPoint_StartCCB
1da177e4
LT
1675 *
1676 * Description: Start a command pointed to by p_Sccb. When the
1677 * command is completed it will be returned via the
1678 * callback function.
1679 *
1680 *---------------------------------------------------------------------*/
d8b6b8bd 1681static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
1da177e4 1682{
1da177e4 1683 ULONG ioport;
1da177e4
LT
1684 UCHAR thisCard, lun;
1685 PSCCB pSaveSccb;
1686 CALL_BK_FN callback;
1687
1da177e4
LT
1688 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1689 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1690
1da177e4
LT
1691 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1692 {
1693
1da177e4
LT
1694 p_Sccb->HostStatus = SCCB_COMPLETE;
1695 p_Sccb->SccbStatus = SCCB_ERROR;
1696 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1697 if (callback)
1698 callback(p_Sccb);
1da177e4 1699
1da177e4
LT
1700 return;
1701 }
1702
47b5d69c 1703 FPT_sinits(p_Sccb,thisCard);
1da177e4
LT
1704
1705
1706 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1707 {
1708 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1709 | SCCB_MGR_ACTIVE));
1710
1711 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1712 {
1713 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1714 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1715 }
1716 }
1717
1718 ((PSCCBcard)pCurrCard)->cmdCounter++;
1719
1720 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1721
1722 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1723 | TICKLE_ME));
1724 if(p_Sccb->OperationCode == RESET_COMMAND)
1725 {
1726 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1727 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1728 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1729 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1730 }
1731 else
1732 {
47b5d69c 1733 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1734 }
1735 }
1736
1737 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1738
1739 if(p_Sccb->OperationCode == RESET_COMMAND)
1740 {
1741 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1742 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1743 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1744 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1745 }
1746 else
1747 {
47b5d69c 1748 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1749 }
1750 }
1751
1752 else {
1753
1754 MDISABLE_INT(ioport);
1755
1756 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
47b5d69c 1757 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1da177e4
LT
1758 lun = p_Sccb->Lun;
1759 else
1760 lun = 0;
1761 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
47b5d69c
JB
1762 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1763 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1764 == 0)) {
1da177e4
LT
1765
1766 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1767 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1da177e4
LT
1768 }
1769
1770 else {
1771
1772 if(p_Sccb->OperationCode == RESET_COMMAND)
1773 {
1774 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1775 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1776 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1da177e4
LT
1777 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1778 }
1779 else
1780 {
47b5d69c 1781 FPT_queueAddSccb(p_Sccb,thisCard);
1da177e4
LT
1782 }
1783 }
1784
1785
1786 MENABLE_INT(ioport);
1787 }
1788
1da177e4
LT
1789}
1790
1791
1792/*---------------------------------------------------------------------
1793 *
d8b6b8bd 1794 * Function: FlashPoint_AbortCCB
1da177e4
LT
1795 *
1796 * Description: Abort the command pointed to by p_Sccb. When the
1797 * command is completed it will be returned via the
1798 * callback function.
1799 *
1800 *---------------------------------------------------------------------*/
d8b6b8bd 1801static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
1da177e4 1802{
1da177e4 1803 ULONG ioport;
1da177e4
LT
1804
1805 UCHAR thisCard;
1806 CALL_BK_FN callback;
1807 UCHAR TID;
1808 PSCCB pSaveSCCB;
1809 PSCCBMgr_tar_info currTar_Info;
1810
1811
1da177e4
LT
1812 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1813
1814 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1815
47b5d69c 1816 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1da177e4
LT
1817 {
1818
47b5d69c 1819 if (FPT_queueFindSccb(p_Sccb,thisCard))
1da177e4
LT
1820 {
1821
1da177e4
LT
1822 ((PSCCBcard)pCurrCard)->cmdCounter--;
1823
1824 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1825 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1826 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1827
1da177e4
LT
1828 p_Sccb->SccbStatus = SCCB_ABORT;
1829 callback = p_Sccb->SccbCallback;
1830 callback(p_Sccb);
1da177e4
LT
1831
1832 return(0);
1833 }
1834
1835 else
1836 {
1da177e4
LT
1837 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1838 {
1839 p_Sccb->SccbStatus = SCCB_ABORT;
1840 return(0);
1841
1842 }
1843
1844 else
1845 {
1846
1847 TID = p_Sccb->TargID;
1848
1849
1850 if(p_Sccb->Sccb_tag)
1851 {
1852 MDISABLE_INT(ioport);
1853 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1854 {
1855 p_Sccb->SccbStatus = SCCB_ABORT;
1856 p_Sccb->Sccb_scsistat = ABORT_ST;
1da177e4
LT
1857 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1858
1859 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1860 {
1861 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1862 FPT_ssel(ioport, thisCard);
1da177e4
LT
1863 }
1864 else
1865 {
1866 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1867 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
47b5d69c 1868 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1da177e4
LT
1869 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1870 }
1871 }
1872 MENABLE_INT(ioport);
1873 return(0);
1874 }
1875 else
1876 {
47b5d69c 1877 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1da177e4 1878
47b5d69c 1879 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1da177e4
LT
1880 == p_Sccb)
1881 {
1882 p_Sccb->SccbStatus = SCCB_ABORT;
1883 return(0);
1884 }
1885 }
1886 }
1887 }
1888 }
1889 return(-1);
1890}
1891
1892
1893/*---------------------------------------------------------------------
1894 *
d8b6b8bd 1895 * Function: FlashPoint_InterruptPending
1da177e4
LT
1896 *
1897 * Description: Do a quick check to determine if there is a pending
1898 * interrupt for this card and disable the IRQ Pin if so.
1899 *
1900 *---------------------------------------------------------------------*/
d8b6b8bd 1901static UCHAR FlashPoint_InterruptPending(ULONG pCurrCard)
1da177e4 1902{
1da177e4 1903 ULONG ioport;
1da177e4
LT
1904
1905 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1906
1907 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1908 {
47b5d69c 1909 return(1);
1da177e4
LT
1910 }
1911
1912 else
1913
47b5d69c 1914 return(0);
1da177e4
LT
1915}
1916
1917
1918
1919/*---------------------------------------------------------------------
1920 *
d8b6b8bd 1921 * Function: FlashPoint_HandleInterrupt
1da177e4
LT
1922 *
1923 * Description: This is our entry point when an interrupt is generated
1924 * by the card and the upper level driver passes it on to
1925 * us.
1926 *
1927 *---------------------------------------------------------------------*/
d8b6b8bd 1928static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
1da177e4
LT
1929{
1930 PSCCB currSCCB;
1931 UCHAR thisCard,result,bm_status, bm_int_st;
1932 USHORT hp_int;
1933 UCHAR i, target;
1da177e4 1934 ULONG ioport;
1da177e4
LT
1935
1936 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1937 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1938
1939 MDISABLE_INT(ioport);
1940
1da177e4
LT
1941 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1942 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
1943 else
1944 bm_status = 0;
1945
1946 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1947
47b5d69c 1948 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1da177e4
LT
1949 bm_status)
1950 {
1951
1952 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1953
1da177e4 1954 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
47b5d69c 1955 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1da177e4
LT
1956 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1957 bm_status = 0;
1958
1959 if (result) {
1960
1da177e4 1961 MENABLE_INT(ioport);
1da177e4
LT
1962 return(result);
1963 }
1964 }
1965
1966
1967 else if (hp_int & ICMD_COMP) {
1968
1969 if ( !(hp_int & BUS_FREE) ) {
1970 /* Wait for the BusFree before starting a new command. We
1971 must also check for being reselected since the BusFree
1972 may not show up if another device reselects us in 1.5us or
1973 less. SRR Wednesday, 3/8/1995.
1974 */
1975 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1976 }
1977
1978 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1979
47b5d69c 1980 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
1981
1982/* WRW_HARPOON((ioport+hp_intstat),
1983 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1984 */
1985
1986 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1987
47b5d69c 1988 FPT_autoCmdCmplt(ioport,thisCard);
1da177e4
LT
1989
1990 }
1991
1992
1993 else if (hp_int & ITAR_DISC)
1994 {
1995
1996 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1997
47b5d69c 1998 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
1999
2000 }
2001
2002 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2003
2004 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2005 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2006
2007 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2008 }
2009
2010 currSCCB->Sccb_scsistat = DISCONNECT_ST;
47b5d69c 2011 FPT_queueDisconnect(currSCCB,thisCard);
1da177e4
LT
2012
2013 /* Wait for the BusFree before starting a new command. We
2014 must also check for being reselected since the BusFree
2015 may not show up if another device reselects us in 1.5us or
2016 less. SRR Wednesday, 3/8/1995.
2017 */
2018 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2019 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2020 RD_HARPOON((ioport+hp_scsisig)) ==
2021 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2022
2023 /*
2024 The additional loop exit condition above detects a timing problem
2025 with the revision D/E harpoon chips. The caller should reset the
2026 host adapter to recover when 0xFE is returned.
2027 */
2028 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2029 {
1da177e4 2030 MENABLE_INT(ioport);
1da177e4
LT
2031 return 0xFE;
2032 }
2033
2034 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2035
2036
2037 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2038
2039 }
2040
2041
2042 else if (hp_int & RSEL) {
2043
2044 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2045
2046 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2047 {
2048 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2049 {
47b5d69c 2050 FPT_phaseChkFifo(ioport, thisCard);
1da177e4
LT
2051 }
2052
2053 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2054 {
2055 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2056 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2057 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2058 }
2059
2060 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2061 currSCCB->Sccb_scsistat = DISCONNECT_ST;
47b5d69c 2062 FPT_queueDisconnect(currSCCB,thisCard);
1da177e4
LT
2063 }
2064
47b5d69c
JB
2065 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2066 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2067
2068 }
2069
2070
2071 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2072 {
2073
2074 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
47b5d69c 2075 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2076
2077 }
2078
2079
2080 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2081 {
2082 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2083 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
2084 {
47b5d69c 2085 FPT_phaseDecode(ioport,thisCard);
1da177e4
LT
2086 }
2087 else
2088 {
2089 /* Harpoon problem some SCSI target device respond to selection
2090 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2091 to latch the correct Target ID into reg. x53.
2092 The work around require to correct this reg. But when write to this
2093 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2094 need to read this reg first then restore it later. After update to 0x53 */
2095
2096 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
2097 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
2098 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
2099 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
2100 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
2101 WR_HARPOON(ioport+hp_fifowrite, i);
2102 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2103 }
2104 }
2105
2106 else if (hp_int & XFER_CNT_0) {
2107
2108 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2109
47b5d69c 2110 FPT_schkdd(ioport,thisCard);
1da177e4
LT
2111
2112 }
2113
2114
2115 else if (hp_int & BUS_FREE) {
2116
2117 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2118
2119 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2120
47b5d69c 2121 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
1da177e4
LT
2122 }
2123
47b5d69c 2124 FPT_phaseBusFree(ioport,thisCard);
1da177e4
LT
2125 }
2126
2127
2128 else if (hp_int & ITICKLE) {
2129
2130 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2131 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2132 }
2133
2134
2135
2136 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2137
2138
2139 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2140
2141
2142 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2143
47b5d69c 2144 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
1da177e4
LT
2145 }
2146
2147 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2148 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
47b5d69c 2149 FPT_ssel(ioport,thisCard);
1da177e4
LT
2150 }
2151
2152 break;
2153
2154 }
2155
2156 } /*end while */
2157
1da177e4 2158 MENABLE_INT(ioport);
1da177e4
LT
2159
2160 return(0);
2161}
2162
2163/*---------------------------------------------------------------------
2164 *
2165 * Function: Sccb_bad_isr
2166 *
2167 * Description: Some type of interrupt has occurred which is slightly
2168 * out of the ordinary. We will now decode it fully, in
2169 * this routine. This is broken up in an attempt to save
2170 * processing time.
2171 *
2172 *---------------------------------------------------------------------*/
47b5d69c
JB
2173static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2174 PSCCBcard pCurrCard, USHORT p_int)
1da177e4 2175{
47b5d69c
JB
2176 UCHAR temp, ScamFlg;
2177 PSCCBMgr_tar_info currTar_Info;
2178 PNVRamInfo pCurrNvRam;
1da177e4
LT
2179
2180
2181 if (RD_HARPOON(p_port+hp_ext_status) &
2182 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2183 {
2184
2185 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2186 {
2187
47b5d69c 2188 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
1da177e4
LT
2189 }
2190
2191 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2192
2193 {
2194 WR_HARPOON(p_port+hp_pci_stat_cfg,
2195 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2196
2197 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2198
2199 }
2200
2201 if (pCurrCard->currentSCCB != NULL)
2202 {
2203
2204 if (!pCurrCard->currentSCCB->HostStatus)
2205 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2206
47b5d69c 2207 FPT_sxfrp(p_port,p_card);
1da177e4
LT
2208
2209 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
2210 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2211 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
2212 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2213
2214 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2215 {
47b5d69c 2216 FPT_phaseDecode(p_port,p_card);
1da177e4
LT
2217 }
2218 }
2219 }
2220
2221
2222 else if (p_int & RESET)
2223 {
2224
2225 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2226 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2227 if (pCurrCard->currentSCCB != NULL) {
2228
2229 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2230
47b5d69c 2231 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
1da177e4
LT
2232 }
2233
2234
2235 DISABLE_AUTO(p_port);
2236
47b5d69c 2237 FPT_sresb(p_port,p_card);
1da177e4
LT
2238
2239 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2240
2241 pCurrNvRam = pCurrCard->pNvRamInfo;
2242 if(pCurrNvRam){
2243 ScamFlg = pCurrNvRam->niScamConf;
2244 }
2245 else{
47b5d69c 2246 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
1da177e4
LT
2247 }
2248
47b5d69c 2249 FPT_XbowInit(p_port, ScamFlg);
1da177e4 2250
47b5d69c 2251 FPT_scini(p_card, pCurrCard->ourId, 0);
1da177e4
LT
2252
2253 return(0xFF);
2254 }
2255
2256
2257 else if (p_int & FIFO) {
2258
2259 WRW_HARPOON((p_port+hp_intstat), FIFO);
2260
1da177e4 2261 if (pCurrCard->currentSCCB != NULL)
47b5d69c 2262 FPT_sxfrp(p_port,p_card);
1da177e4
LT
2263 }
2264
2265 else if (p_int & TIMEOUT)
2266 {
2267
2268 DISABLE_AUTO(p_port);
2269
2270 WRW_HARPOON((p_port+hp_intstat),
2271 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2272
2273 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2274
2275
47b5d69c 2276 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2277 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2278 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
47b5d69c 2279 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
1da177e4 2280 else
47b5d69c 2281 currTar_Info->TarLUNBusy[0] = 0;
1da177e4
LT
2282
2283
2284 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2285 {
2286 currTar_Info->TarSyncCtrl = 0;
2287 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2288 }
2289
2290 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2291 {
2292 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2293 }
2294
47b5d69c 2295 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
1da177e4 2296
47b5d69c 2297 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
1da177e4 2298
1da177e4
LT
2299 }
2300
47b5d69c 2301 else if (p_int & SCAM_SEL)
1da177e4 2302 {
1da177e4 2303
47b5d69c
JB
2304 FPT_scarb(p_port,LEVEL2_TAR);
2305 FPT_scsel(p_port);
2306 FPT_scasid(p_card, p_port);
1da177e4 2307
47b5d69c 2308 FPT_scbusf(p_port);
1da177e4 2309
47b5d69c 2310 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
1da177e4
LT
2311 }
2312
47b5d69c 2313 return(0x00);
1da177e4
LT
2314}
2315
1da177e4
LT
2316
2317/*---------------------------------------------------------------------
2318 *
2319 * Function: SccbMgrTableInit
2320 *
2321 * Description: Initialize all Sccb manager data structures.
2322 *
2323 *---------------------------------------------------------------------*/
2324
47b5d69c 2325static void FPT_SccbMgrTableInitAll()
1da177e4
LT
2326{
2327 UCHAR thisCard;
2328
2329 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2330 {
47b5d69c 2331 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
1da177e4 2332
47b5d69c
JB
2333 FPT_BL_Card[thisCard].ioPort = 0x00;
2334 FPT_BL_Card[thisCard].cardInfo = NULL;
2335 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2336 FPT_BL_Card[thisCard].ourId = 0x00;
2337 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
1da177e4
LT
2338 }
2339}
2340
2341
2342/*---------------------------------------------------------------------
2343 *
2344 * Function: SccbMgrTableInit
2345 *
2346 * Description: Initialize all Sccb manager data structures.
2347 *
2348 *---------------------------------------------------------------------*/
2349
47b5d69c 2350static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
1da177e4
LT
2351{
2352 UCHAR scsiID, qtag;
2353
2354 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2355 {
47b5d69c 2356 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
2357 }
2358
2359 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2360 {
47b5d69c
JB
2361 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2362 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2363 FPT_SccbMgrTableInitTarget(p_card, scsiID);
1da177e4
LT
2364 }
2365
2366 pCurrCard->scanIndex = 0x00;
2367 pCurrCard->currentSCCB = NULL;
2368 pCurrCard->globalFlags = 0x00;
2369 pCurrCard->cmdCounter = 0x00;
2370 pCurrCard->tagQ_Lst = 0x01;
2371 pCurrCard->discQCount = 0;
2372
2373
2374}
2375
2376
2377/*---------------------------------------------------------------------
2378 *
2379 * Function: SccbMgrTableInit
2380 *
2381 * Description: Initialize all Sccb manager data structures.
2382 *
2383 *---------------------------------------------------------------------*/
2384
47b5d69c 2385static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
1da177e4
LT
2386{
2387
2388 UCHAR lun, qtag;
2389 PSCCBMgr_tar_info currTar_Info;
2390
47b5d69c 2391 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2392
2393 currTar_Info->TarSelQ_Cnt = 0;
2394 currTar_Info->TarSyncCtrl = 0;
2395
2396 currTar_Info->TarSelQ_Head = NULL;
2397 currTar_Info->TarSelQ_Tail = NULL;
2398 currTar_Info->TarTagQ_Cnt = 0;
47b5d69c 2399 currTar_Info->TarLUN_CA = 0;
1da177e4
LT
2400
2401
2402 for (lun = 0; lun < MAX_LUN; lun++)
2403 {
47b5d69c 2404 currTar_Info->TarLUNBusy[lun] = 0;
1da177e4
LT
2405 currTar_Info->LunDiscQ_Idx[lun] = 0;
2406 }
2407
2408 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2409 {
47b5d69c 2410 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
1da177e4 2411 {
47b5d69c 2412 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
1da177e4 2413 {
47b5d69c
JB
2414 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2415 FPT_BL_Card[p_card].discQCount--;
1da177e4
LT
2416 }
2417 }
2418 }
2419}
2420
1da177e4
LT
2421
2422/*---------------------------------------------------------------------
2423 *
2424 * Function: sfetm
2425 *
2426 * Description: Read in a message byte from the SCSI bus, and check
2427 * for a parity error.
2428 *
2429 *---------------------------------------------------------------------*/
2430
47b5d69c 2431static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
1da177e4
LT
2432{
2433 UCHAR message;
2434 USHORT TimeOutLoop;
2435
2436 TimeOutLoop = 0;
2437 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2438 (TimeOutLoop++ < 20000) ){}
2439
2440
2441 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2442
2443 message = RD_HARPOON(port+hp_scsidata_0);
2444
2445 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2446
2447
2448 if (TimeOutLoop > 20000)
2449 message = 0x00; /* force message byte = 0 if Time Out on Req */
2450
2451 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2452 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2453 {
2454 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2455 WR_HARPOON(port+hp_xferstat, 0);
2456 WR_HARPOON(port+hp_fiforead, 0);
2457 WR_HARPOON(port+hp_fifowrite, 0);
2458 if (pCurrSCCB != NULL)
2459 {
2460 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2461 }
2462 message = 0x00;
2463 do
2464 {
2465 ACCEPT_MSG_ATN(port);
2466 TimeOutLoop = 0;
2467 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2468 (TimeOutLoop++ < 20000) ){}
2469 if (TimeOutLoop > 20000)
2470 {
2471 WRW_HARPOON((port+hp_intstat), PARITY);
2472 return(message);
2473 }
2474 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2475 {
2476 WRW_HARPOON((port+hp_intstat), PARITY);
2477 return(message);
2478 }
2479 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2480
2481 RD_HARPOON(port+hp_scsidata_0);
2482
2483 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2484
2485 }while(1);
2486
2487 }
2488 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2489 WR_HARPOON(port+hp_xferstat, 0);
2490 WR_HARPOON(port+hp_fiforead, 0);
2491 WR_HARPOON(port+hp_fifowrite, 0);
2492 return(message);
2493}
2494
2495
2496/*---------------------------------------------------------------------
2497 *
47b5d69c 2498 * Function: FPT_ssel
1da177e4
LT
2499 *
2500 * Description: Load up automation and select target device.
2501 *
2502 *---------------------------------------------------------------------*/
2503
47b5d69c 2504static void FPT_ssel(ULONG port, UCHAR p_card)
1da177e4
LT
2505{
2506
1da177e4 2507 UCHAR auto_loaded, i, target, *theCCB;
1da177e4 2508
1da177e4 2509 ULONG cdb_reg;
1da177e4
LT
2510 PSCCBcard CurrCard;
2511 PSCCB currSCCB;
2512 PSCCBMgr_tar_info currTar_Info;
2513 UCHAR lastTag, lun;
2514
47b5d69c 2515 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
2516 currSCCB = CurrCard->currentSCCB;
2517 target = currSCCB->TargID;
47b5d69c 2518 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
1da177e4
LT
2519 lastTag = CurrCard->tagQ_Lst;
2520
2521 ARAM_ACCESS(port);
2522
2523
2524 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2525 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2526
2527 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2528 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2529
2530 lun = currSCCB->Lun;
2531 else
2532 lun = 0;
2533
2534
1da177e4
LT
2535 if (CurrCard->globalFlags & F_TAG_STARTED)
2536 {
2537 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2538 {
47b5d69c 2539 if ((currTar_Info->TarLUN_CA == 0)
1da177e4
LT
2540 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2541 == TAG_Q_TRYING))
2542 {
2543
2544 if (currTar_Info->TarTagQ_Cnt !=0)
2545 {
47b5d69c
JB
2546 currTar_Info->TarLUNBusy[lun] = 1;
2547 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2548 SGRAM_ACCESS(port);
2549 return;
2550 }
2551
2552 else {
47b5d69c 2553 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2554 }
2555
2556 } /*End non-tagged */
2557
2558 else {
47b5d69c 2559 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2560 }
2561
2562 } /*!Use cmd Q Tagged */
2563
2564 else {
47b5d69c 2565 if (currTar_Info->TarLUN_CA == 1)
1da177e4 2566 {
47b5d69c 2567 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2568 SGRAM_ACCESS(port);
2569 return;
2570 }
2571
47b5d69c 2572 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2573
2574 } /*else use cmd Q tagged */
2575
2576 } /*if glob tagged started */
2577
2578 else {
47b5d69c 2579 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2580 }
2581
1da177e4
LT
2582
2583
2584 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2585 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2586 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2587 {
2588 if(CurrCard->discQCount >= QUEUE_DEPTH)
2589 {
47b5d69c
JB
2590 currTar_Info->TarLUNBusy[lun] = 1;
2591 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2592 SGRAM_ACCESS(port);
2593 return;
2594 }
2595 for (i = 1; i < QUEUE_DEPTH; i++)
2596 {
2597 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2598 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2599 {
2600 CurrCard->tagQ_Lst = lastTag;
2601 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2602 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2603 CurrCard->discQCount++;
2604 break;
2605 }
2606 }
2607 if(i == QUEUE_DEPTH)
2608 {
47b5d69c
JB
2609 currTar_Info->TarLUNBusy[lun] = 1;
2610 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2611 SGRAM_ACCESS(port);
2612 return;
2613 }
2614 }
2615
2616
2617
47b5d69c 2618 auto_loaded = 0;
1da177e4
LT
2619
2620 WR_HARPOON(port+hp_select_id, target);
2621 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2622
2623 if (currSCCB->OperationCode == RESET_COMMAND) {
2624 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2625 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2626
2627 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2628
2629 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2630
2631 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
47b5d69c 2632 auto_loaded = 1;
1da177e4
LT
2633 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2634
2635 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2636 {
2637 currTar_Info->TarSyncCtrl = 0;
2638 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2639 }
2640
1da177e4
LT
2641 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2642 {
2643 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2644 }
1da177e4 2645
47b5d69c
JB
2646 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2647 FPT_SccbMgrTableInitTarget(p_card, target);
1da177e4
LT
2648
2649 }
2650
2651 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2652 {
2653 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2654 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2655
2656 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2657
2658 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2659 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2660 >> 6) | (UCHAR)0x20)));
2661 WRW_HARPOON((port+SYNC_MSGS+2),
2662 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2663 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2664
2665 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
47b5d69c 2666 auto_loaded = 1;
1da177e4
LT
2667
2668 }
2669
1da177e4 2670 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
47b5d69c 2671 auto_loaded = FPT_siwidn(port,p_card);
1da177e4
LT
2672 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2673 }
2674
1da177e4
LT
2675 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2676 == SYNC_SUPPORTED)) {
47b5d69c 2677 auto_loaded = FPT_sisyncn(port,p_card, 0);
1da177e4
LT
2678 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2679 }
2680
2681
2682 if (!auto_loaded)
2683 {
2684
1da177e4
LT
2685 if (currSCCB->ControlByte & F_USE_CMD_Q)
2686 {
2687
2688 CurrCard->globalFlags |= F_TAG_STARTED;
2689
2690 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2691 == TAG_Q_REJECT)
2692 {
2693 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2694
2695 /* Fix up the start instruction with a jump to
2696 Non-Tag-CMD handling */
2697 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2698
2699 WRW_HARPOON((port+NON_TAG_ID_MSG),
2700 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2701
2702 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2703
2704 /* Setup our STATE so we know what happend when
2705 the wheels fall off. */
2706 currSCCB->Sccb_scsistat = SELECT_ST;
2707
47b5d69c 2708 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
2709 }
2710
2711 else
2712 {
2713 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2714
2715 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2716 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2717 >> 6) | (UCHAR)0x20)));
2718
2719 for (i = 1; i < QUEUE_DEPTH; i++)
2720 {
2721 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2722 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2723 {
2724 WRW_HARPOON((port+ID_MSG_STRT+6),
2725 (MPM_OP+AMSG_OUT+lastTag));
2726 CurrCard->tagQ_Lst = lastTag;
2727 currSCCB->Sccb_tag = lastTag;
2728 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2729 CurrCard->discQCount++;
2730 break;
2731 }
2732 }
2733
2734
2735 if ( i == QUEUE_DEPTH )
2736 {
47b5d69c
JB
2737 currTar_Info->TarLUNBusy[lun] = 1;
2738 FPT_queueSelectFail(CurrCard,p_card);
1da177e4
LT
2739 SGRAM_ACCESS(port);
2740 return;
2741 }
2742
2743 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2744
2745 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2746 }
2747 }
2748
2749 else
2750 {
1da177e4
LT
2751
2752 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2753
2754 WRW_HARPOON((port+NON_TAG_ID_MSG),
2755 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2756
2757 currSCCB->Sccb_scsistat = SELECT_ST;
2758
2759 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
1da177e4 2760 }
1da177e4
LT
2761
2762
1da177e4 2763 theCCB = (UCHAR *)&currSCCB->Cdb[0];
1da177e4
LT
2764
2765 cdb_reg = port + CMD_STRT;
2766
2767 for (i=0; i < currSCCB->CdbLength; i++)
2768 {
2769 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2770 cdb_reg +=2;
2771 theCCB++;
2772 }
2773
2774 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2775 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2776
2777 } /* auto_loaded */
2778
1da177e4
LT
2779 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2780 WR_HARPOON(port+hp_xferstat, 0x00);
1da177e4
LT
2781
2782 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2783
2784 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2785
2786
2787 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2788 {
2789 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2790 }
2791 else
2792 {
2793
2794/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
2795 auto_loaded |= AUTO_IMMED; */
2796 auto_loaded = AUTO_IMMED;
2797
2798 DISABLE_AUTO(port);
2799
2800 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2801 }
2802
2803 SGRAM_ACCESS(port);
2804}
2805
2806
2807/*---------------------------------------------------------------------
2808 *
47b5d69c 2809 * Function: FPT_sres
1da177e4
LT
2810 *
2811 * Description: Hookup the correct CCB and handle the incoming messages.
2812 *
2813 *---------------------------------------------------------------------*/
2814
47b5d69c 2815static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
1da177e4
LT
2816{
2817
1da177e4 2818 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
1da177e4
LT
2819
2820
2821 PSCCBMgr_tar_info currTar_Info;
2822 PSCCB currSCCB;
2823
2824
2825
2826
2827 if(pCurrCard->currentSCCB != NULL)
2828 {
47b5d69c 2829 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
1da177e4
LT
2830 DISABLE_AUTO(port);
2831
2832
2833 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2834
2835
2836 currSCCB = pCurrCard->currentSCCB;
2837 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2838 {
2839 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2840 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2841 }
2842 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2843 {
2844 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2845 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2846 }
2847 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2848 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2849 {
47b5d69c 2850 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
1da177e4
LT
2851 if(currSCCB->Sccb_scsistat != ABORT_ST)
2852 {
2853 pCurrCard->discQCount--;
2854 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2855 = NULL;
2856 }
2857 }
2858 else
2859 {
47b5d69c 2860 currTar_Info->TarLUNBusy[0] = 0;
1da177e4
LT
2861 if(currSCCB->Sccb_tag)
2862 {
2863 if(currSCCB->Sccb_scsistat != ABORT_ST)
2864 {
2865 pCurrCard->discQCount--;
2866 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2867 }
2868 }else
2869 {
2870 if(currSCCB->Sccb_scsistat != ABORT_ST)
2871 {
2872 pCurrCard->discQCount--;
2873 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2874 }
2875 }
2876 }
2877
47b5d69c 2878 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
2879 }
2880
1da177e4 2881 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
1da177e4
LT
2882
2883
2884 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
47b5d69c 2885 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2886
2887
2888 msgRetryCount = 0;
2889 do
2890 {
2891
47b5d69c 2892 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
1da177e4
LT
2893 tag = 0;
2894
2895
2896 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2897 {
2898 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2899 {
2900
2901 WRW_HARPOON((port+hp_intstat), PHASE);
2902 return;
2903 }
2904 }
2905
2906 WRW_HARPOON((port+hp_intstat), PHASE);
2907 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2908 {
2909
47b5d69c 2910 message = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2911 if (message)
2912 {
2913
2914 if (message <= (0x80 | LUN_MASK))
2915 {
2916 lun = message & (UCHAR)LUN_MASK;
2917
1da177e4
LT
2918 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2919 {
2920 if (currTar_Info->TarTagQ_Cnt != 0)
2921 {
2922
2923 if (!(currTar_Info->TarLUN_CA))
2924 {
2925 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2926
2927
47b5d69c 2928 message = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2929 if (message)
2930 {
2931 ACCEPT_MSG(port);
2932 }
2933
2934 else
47b5d69c 2935 message = 0;
1da177e4 2936
47b5d69c 2937 if(message != 0)
1da177e4 2938 {
47b5d69c 2939 tag = FPT_sfm(port,pCurrCard->currentSCCB);
1da177e4
LT
2940
2941 if (!(tag))
47b5d69c 2942 message = 0;
1da177e4
LT
2943 }
2944
2945 } /*C.A. exists! */
2946
2947 } /*End Q cnt != 0 */
2948
2949 } /*End Tag cmds supported! */
1da177e4
LT
2950
2951 } /*End valid ID message. */
2952
2953 else
2954 {
2955
2956 ACCEPT_MSG_ATN(port);
2957 }
2958
2959 } /* End good id message. */
2960
2961 else
2962 {
2963
47b5d69c 2964 message = 0;
1da177e4
LT
2965 }
2966 }
2967 else
2968 {
2969 ACCEPT_MSG_ATN(port);
2970
2971 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2972 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2973 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2974
2975 return;
2976 }
1da177e4 2977
47b5d69c 2978 if(message == 0)
1da177e4
LT
2979 {
2980 msgRetryCount++;
2981 if(msgRetryCount == 1)
2982 {
47b5d69c 2983 FPT_SendMsg(port, SMPARITY);
1da177e4
LT
2984 }
2985 else
2986 {
47b5d69c 2987 FPT_SendMsg(port, SMDEV_RESET);
1da177e4 2988
47b5d69c 2989 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
1da177e4 2990
47b5d69c 2991 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
1da177e4
LT
2992 {
2993
47b5d69c 2994 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
2995
2996 }
2997
47b5d69c 2998 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
1da177e4
LT
2999 {
3000
47b5d69c 3001 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
3002 }
3003
3004
47b5d69c
JB
3005 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3006 FPT_SccbMgrTableInitTarget(p_card,our_target);
1da177e4
LT
3007 return;
3008 }
3009 }
47b5d69c 3010 }while(message == 0);
1da177e4
LT
3011
3012
3013
3014 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3015 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3016 {
47b5d69c 3017 currTar_Info->TarLUNBusy[lun] = 1;
1da177e4
LT
3018 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3019 if(pCurrCard->currentSCCB != NULL)
3020 {
3021 ACCEPT_MSG(port);
3022 }
3023 else
3024 {
3025 ACCEPT_MSG_ATN(port);
3026 }
3027 }
3028 else
3029 {
47b5d69c 3030 currTar_Info->TarLUNBusy[0] = 1;
1da177e4
LT
3031
3032
3033 if (tag)
3034 {
3035 if (pCurrCard->discQ_Tbl[tag] != NULL)
3036 {
3037 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3038 currTar_Info->TarTagQ_Cnt--;
3039 ACCEPT_MSG(port);
3040 }
3041 else
3042 {
3043 ACCEPT_MSG_ATN(port);
3044 }
3045 }else
3046 {
3047 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3048 if(pCurrCard->currentSCCB != NULL)
3049 {
3050 ACCEPT_MSG(port);
3051 }
3052 else
3053 {
3054 ACCEPT_MSG_ATN(port);
3055 }
3056 }
3057 }
3058
3059 if(pCurrCard->currentSCCB != NULL)
3060 {
3061 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3062 {
3063 /* During Abort Tag command, the target could have got re-selected
3064 and completed the command. Check the select Q and remove the CCB
3065 if it is in the Select Q */
47b5d69c 3066 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
1da177e4
LT
3067 }
3068 }
3069
3070
3071 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3072 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3073 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3074}
3075
47b5d69c 3076static void FPT_SendMsg(ULONG port, UCHAR message)
1da177e4
LT
3077{
3078 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3079 {
3080 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3081 {
3082
3083 WRW_HARPOON((port+hp_intstat), PHASE);
3084 return;
3085 }
3086 }
3087
3088 WRW_HARPOON((port+hp_intstat), PHASE);
3089 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3090 {
3091 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3092
3093
3094 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3095
3096 WR_HARPOON(port+hp_scsidata_0,message);
3097
3098 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3099
3100 ACCEPT_MSG(port);
3101
3102 WR_HARPOON(port+hp_portctrl_0, 0x00);
3103
3104 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3105 (message == SMABORT_TAG) )
3106 {
3107 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3108
3109 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3110 {
3111 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3112 }
3113 }
3114 }
3115}
3116
3117/*---------------------------------------------------------------------
3118 *
47b5d69c 3119 * Function: FPT_sdecm
1da177e4
LT
3120 *
3121 * Description: Determine the proper responce to the message from the
3122 * target device.
3123 *
3124 *---------------------------------------------------------------------*/
47b5d69c 3125static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
1da177e4
LT
3126{
3127 PSCCB currSCCB;
3128 PSCCBcard CurrCard;
3129 PSCCBMgr_tar_info currTar_Info;
3130
47b5d69c 3131 CurrCard = &FPT_BL_Card[p_card];
1da177e4
LT
3132 currSCCB = CurrCard->currentSCCB;
3133
47b5d69c 3134 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3135
3136 if (message == SMREST_DATA_PTR)
3137 {
3138 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3139 {
3140 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3141
47b5d69c 3142 FPT_hostDataXferRestart(currSCCB);
1da177e4
LT
3143 }
3144
3145 ACCEPT_MSG(port);
3146 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3147 }
3148
3149 else if (message == SMCMD_COMP)
3150 {
3151
3152
3153 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3154 {
3155 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
3156 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
3157 }
3158
3159 ACCEPT_MSG(port);
3160
3161 }
3162
3163 else if ((message == SMNO_OP) || (message >= SMIDENT)
3164 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3165 {
3166
3167 ACCEPT_MSG(port);
3168 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3169 }
3170
3171 else if (message == SMREJECT)
3172 {
3173
3174 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3175 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3176 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3177 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3178
3179 {
3180 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3181
3182 ACCEPT_MSG(port);
3183
3184
3185 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3186 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3187
3188 if(currSCCB->Lun == 0x00)
3189 {
3190 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3191 {
3192
3193 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3194
3195 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3196 }
3197
1da177e4
LT
3198 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3199 {
3200
3201
3202 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3203 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3204
3205 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3206
3207 }
1da177e4
LT
3208
3209 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3210 {
3211 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3212 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3213
3214
3215 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3216 CurrCard->discQCount--;
3217 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3218 currSCCB->Sccb_tag = 0x00;
3219
3220 }
3221 }
3222
3223 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3224 {
3225
3226
3227 if(currSCCB->Lun == 0x00)
3228 {
3229 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3230 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3231 }
3232 }
3233
3234 else
3235 {
3236
3237 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3238 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
47b5d69c 3239 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
1da177e4 3240 else
47b5d69c 3241 currTar_Info->TarLUNBusy[0] = 1;
1da177e4
LT
3242
3243
3244 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
3245
3246 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3247
3248 }
3249 }
3250
3251 else
3252 {
3253 ACCEPT_MSG(port);
3254
3255 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3256 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3257
3258 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3259 {
3260 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3261 }
3262 }
3263 }
3264
3265 else if (message == SMEXT)
3266 {
3267
3268 ACCEPT_MSG(port);
47b5d69c 3269 FPT_shandem(port,p_card,currSCCB);
1da177e4
LT
3270 }
3271
3272 else if (message == SMIGNORWR)
3273 {
3274
3275 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3276
47b5d69c 3277 message = FPT_sfm(port,currSCCB);
1da177e4
LT
3278
3279 if(currSCCB->Sccb_scsimsg != SMPARITY)
3280 ACCEPT_MSG(port);
3281 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3282 }
3283
3284
3285 else
3286 {
3287
3288 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3289 currSCCB->Sccb_scsimsg = SMREJECT;
3290
3291 ACCEPT_MSG_ATN(port);
3292 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3293 }
3294}
3295
3296
3297/*---------------------------------------------------------------------
3298 *
47b5d69c 3299 * Function: FPT_shandem
1da177e4
LT
3300 *
3301 * Description: Decide what to do with the extended message.
3302 *
3303 *---------------------------------------------------------------------*/
47b5d69c 3304static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
1da177e4
LT
3305{
3306 UCHAR length,message;
3307
47b5d69c 3308 length = FPT_sfm(port,pCurrSCCB);
1da177e4
LT
3309 if (length)
3310 {
3311
3312 ACCEPT_MSG(port);
47b5d69c 3313 message = FPT_sfm(port,pCurrSCCB);
1da177e4
LT
3314 if (message)
3315 {
3316
3317 if (message == SMSYNC)
3318 {
3319
3320 if (length == 0x03)
3321 {
3322
3323 ACCEPT_MSG(port);
47b5d69c 3324 FPT_stsyncn(port,p_card);
1da177e4
LT
3325 }
3326 else
3327 {
3328
3329 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3330 ACCEPT_MSG_ATN(port);
3331 }
3332 }
1da177e4
LT
3333 else if (message == SMWDTR)
3334 {
3335
3336 if (length == 0x02)
3337 {
3338
3339 ACCEPT_MSG(port);
47b5d69c 3340 FPT_stwidn(port,p_card);
1da177e4
LT
3341 }
3342 else
3343 {
3344
3345 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3346 ACCEPT_MSG_ATN(port);
3347
3348 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3349 }
3350 }
1da177e4
LT
3351 else
3352 {
3353
3354 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3355 ACCEPT_MSG_ATN(port);
3356
3357 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3358 }
3359 }
3360 else
3361 {
3362 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3363 ACCEPT_MSG(port);
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3365 }
3366 }else
3367 {
3368 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3369 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3370 }
3371}
3372
3373
3374/*---------------------------------------------------------------------
3375 *
47b5d69c 3376 * Function: FPT_sisyncn
1da177e4
LT
3377 *
3378 * Description: Read in a message byte from the SCSI bus, and check
3379 * for a parity error.
3380 *
3381 *---------------------------------------------------------------------*/
3382
47b5d69c 3383static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
1da177e4
LT
3384{
3385 PSCCB currSCCB;
3386 PSCCBMgr_tar_info currTar_Info;
3387
47b5d69c
JB
3388 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3389 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3390
3391 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3392
3393
3394 WRW_HARPOON((port+ID_MSG_STRT),
3395 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3396
3397 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3398
3399 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3400 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3401 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3402
3403
3404 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3405
3406 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3407
3408 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3409
3410 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3411
3412 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3413
3414 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3415
3416 else
3417 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3418
3419
3420 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3421 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3422 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3423
3424
47b5d69c 3425 if(syncFlag == 0)
1da177e4
LT
3426 {
3427 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3428 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3429 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
3430 }
3431 else
3432 {
3433 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3434 }
3435
3436
47b5d69c 3437 return(1);
1da177e4
LT
3438 }
3439
3440 else {
3441
3442 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3443 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
47b5d69c 3444 return(0);
1da177e4
LT
3445 }
3446}
3447
3448
3449
3450/*---------------------------------------------------------------------
3451 *
47b5d69c 3452 * Function: FPT_stsyncn
1da177e4
LT
3453 *
3454 * Description: The has sent us a Sync Nego message so handle it as
3455 * necessary.
3456 *
3457 *---------------------------------------------------------------------*/
47b5d69c 3458static void FPT_stsyncn(ULONG port, UCHAR p_card)
1da177e4
LT
3459{
3460 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3461 PSCCB currSCCB;
3462 PSCCBMgr_tar_info currTar_Info;
3463
47b5d69c
JB
3464 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3465 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3466
47b5d69c 3467 sync_msg = FPT_sfm(port,currSCCB);
1da177e4
LT
3468
3469 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3470 {
3471 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3472 return;
3473 }
3474
3475 ACCEPT_MSG(port);
3476
3477
47b5d69c 3478 offset = FPT_sfm(port,currSCCB);
1da177e4
LT
3479
3480 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3481 {
3482 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3483 return;
3484 }
3485
3486 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3487
3488 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3489
3490 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3491
3492 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3493
3494 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3495
3496 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3497 else
3498
3499 our_sync_msg = 0; /* Message = Async */
3500
3501 if (sync_msg < our_sync_msg) {
3502 sync_msg = our_sync_msg; /*if faster, then set to max. */
3503 }
3504
3505 if (offset == ASYNC)
3506 sync_msg = ASYNC;
3507
3508 if (offset > MAX_OFFSET)
3509 offset = MAX_OFFSET;
3510
3511 sync_reg = 0x00;
3512
3513 if (sync_msg > 12)
3514
3515 sync_reg = 0x20; /* Use 10MB/s */
3516
3517 if (sync_msg > 25)
3518
3519 sync_reg = 0x40; /* Use 6.6MB/s */
3520
3521 if (sync_msg > 38)
3522
3523 sync_reg = 0x60; /* Use 5MB/s */
3524
3525 if (sync_msg > 50)
3526
3527 sync_reg = 0x80; /* Use 4MB/s */
3528
3529 if (sync_msg > 62)
3530
3531 sync_reg = 0xA0; /* Use 3.33MB/s */
3532
3533 if (sync_msg > 75)
3534
3535 sync_reg = 0xC0; /* Use 2.85MB/s */
3536
3537 if (sync_msg > 87)
3538
3539 sync_reg = 0xE0; /* Use 2.5MB/s */
3540
3541 if (sync_msg > 100) {
3542
3543 sync_reg = 0x00; /* Use ASYNC */
3544 offset = 0x00;
3545 }
3546
3547
1da177e4
LT
3548 if (currTar_Info->TarStatus & WIDE_ENABLED)
3549
3550 sync_reg |= offset;
3551
3552 else
3553
3554 sync_reg |= (offset | NARROW_SCSI);
3555
47b5d69c 3556 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
1da177e4
LT
3557
3558
3559 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3560
3561
3562 ACCEPT_MSG(port);
3563
3564 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3565 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3566
3567 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3568 }
3569
3570 else {
3571
3572
3573 ACCEPT_MSG_ATN(port);
3574
47b5d69c 3575 FPT_sisyncr(port,sync_msg,offset);
1da177e4
LT
3576
3577 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3578 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3579 }
3580}
3581
3582
3583/*---------------------------------------------------------------------
3584 *
47b5d69c 3585 * Function: FPT_sisyncr
1da177e4
LT
3586 *
3587 * Description: Answer the targets sync message.
3588 *
3589 *---------------------------------------------------------------------*/
47b5d69c 3590static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
1da177e4
LT
3591{
3592 ARAM_ACCESS(port);
3593 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3594 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3595 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3596 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3597 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3598 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3599 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3600 SGRAM_ACCESS(port);
3601
3602 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3603 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3604
3605 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3606
3607 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3608}
3609
3610
3611
1da177e4
LT
3612/*---------------------------------------------------------------------
3613 *
47b5d69c 3614 * Function: FPT_siwidn
1da177e4
LT
3615 *
3616 * Description: Read in a message byte from the SCSI bus, and check
3617 * for a parity error.
3618 *
3619 *---------------------------------------------------------------------*/
3620
47b5d69c 3621static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
1da177e4
LT
3622{
3623 PSCCB currSCCB;
3624 PSCCBMgr_tar_info currTar_Info;
3625
47b5d69c
JB
3626 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3627 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4
LT
3628
3629 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3630
3631
3632 WRW_HARPOON((port+ID_MSG_STRT),
3633 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3634
3635 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3636
3637 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3638 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3639 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3640 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3641 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3642 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3643
3644 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3645
3646
3647 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3648 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
3649
47b5d69c 3650 return(1);
1da177e4
LT
3651 }
3652
3653 else {
3654
3655 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3656 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3657
3658 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
47b5d69c 3659 return(0);
1da177e4
LT
3660 }
3661}
3662
3663
3664
3665/*---------------------------------------------------------------------
3666 *
47b5d69c 3667 * Function: FPT_stwidn
1da177e4
LT
3668 *
3669 * Description: The has sent us a Wide Nego message so handle it as
3670 * necessary.
3671 *
3672 *---------------------------------------------------------------------*/
47b5d69c 3673static void FPT_stwidn(ULONG port, UCHAR p_card)
1da177e4
LT
3674{
3675 UCHAR width;
3676 PSCCB currSCCB;
3677 PSCCBMgr_tar_info currTar_Info;
3678
47b5d69c
JB
3679 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3680 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
1da177e4 3681
47b5d69c 3682 width = FPT_sfm(port,currSCCB);
1da177e4
LT
3683
3684 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3685 {
3686 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3687 return;
3688 }
3689
3690
3691 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3692 width = 0;
3693
3694 if (width) {
3695 currTar_Info->TarStatus |= WIDE_ENABLED;
3696 width = 0;
3697 }
3698 else {
3699 width = NARROW_SCSI;
3700 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3701 }
3702
3703
47b5d69c 3704 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
1da177e4
LT
3705
3706
3707 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3708 {
3709
3710
3711
3712 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3713
3714 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3715 {
3716 ACCEPT_MSG_ATN(port);
3717 ARAM_ACCESS(port);
47b5d69c 3718 FPT_sisyncn(port,p_card, 1);
1da177e4
LT
3719 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3720 SGRAM_ACCESS(port);
3721 }
3722 else
3723 {
3724 ACCEPT_MSG(port);
3725 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3726 }
3727 }
3728
3729 else {
3730
3731
3732 ACCEPT_MSG_ATN(port);
3733
3734 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3735 width = SM16BIT;
3736 else
3737 width = SM8BIT;
3738
47b5d69c 3739 FPT_siwidr(port,width);
1da177e4
LT
3740
3741 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3742 }
3743}
3744
3745
3746/*---------------------------------------------------------------------
3747 *
47b5d69c 3748 * Function: FPT_siwidr
1da177e4
LT
3749 *
3750 * Description: Answer the targets Wide nego message.
3751 *
3752 *---------------------------------------------------------------------*/
47b5d69c 3753static void FPT_siwidr(ULONG port, UCHAR width)
1da177e4
LT
3754{
3755 ARAM_ACCESS(port);
3756 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3757 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3758 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3759 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3760 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3761 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3762 SGRAM_ACCESS(port);
3763
3764 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3765 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3766
3767 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3768
3769 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3770}
3771
1da177e4
LT
3772
3773
3774/*---------------------------------------------------------------------
3775 *
47b5d69c 3776 * Function: FPT_sssyncv
1da177e4
LT
3777 *
3778 * Description: Write the desired value to the Sync Register for the
3779 * ID specified.
3780 *
3781 *---------------------------------------------------------------------*/
47b5d69c
JB
3782static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
3783 PSCCBMgr_tar_info currTar_Info)
1da177e4
LT
3784{
3785 UCHAR index;
3786
3787 index = p_id;
3788
3789 switch (index) {
3790
3791 case 0:
3792 index = 12; /* hp_synctarg_0 */
3793 break;
3794 case 1:
3795 index = 13; /* hp_synctarg_1 */
3796 break;
3797 case 2:
3798 index = 14; /* hp_synctarg_2 */
3799 break;
3800 case 3:
3801 index = 15; /* hp_synctarg_3 */
3802 break;
3803 case 4:
3804 index = 8; /* hp_synctarg_4 */
3805 break;
3806 case 5:
3807 index = 9; /* hp_synctarg_5 */
3808 break;
3809 case 6:
3810 index = 10; /* hp_synctarg_6 */
3811 break;
3812 case 7:
3813 index = 11; /* hp_synctarg_7 */
3814 break;
3815 case 8:
3816 index = 4; /* hp_synctarg_8 */
3817 break;
3818 case 9:
3819 index = 5; /* hp_synctarg_9 */
3820 break;
3821 case 10:
3822 index = 6; /* hp_synctarg_10 */
3823 break;
3824 case 11:
3825 index = 7; /* hp_synctarg_11 */
3826 break;
3827 case 12:
3828 index = 0; /* hp_synctarg_12 */
3829 break;
3830 case 13:
3831 index = 1; /* hp_synctarg_13 */
3832 break;
3833 case 14:
3834 index = 2; /* hp_synctarg_14 */
3835 break;
3836 case 15:
3837 index = 3; /* hp_synctarg_15 */
3838
3839 }
3840
3841 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3842
3843 currTar_Info->TarSyncCtrl = p_sync_value;
3844}
3845
3846
3847/*---------------------------------------------------------------------
3848 *
47b5d69c 3849 * Function: FPT_sresb
1da177e4
LT
3850 *
3851 * Description: Reset the desired card's SCSI bus.
3852 *
3853 *---------------------------------------------------------------------*/
47b5d69c 3854static void FPT_sresb(ULONG port, UCHAR p_card)
1da177e4
LT
3855{
3856 UCHAR scsiID, i;
3857
3858 PSCCBMgr_tar_info currTar_Info;
3859
3860 WR_HARPOON(port+hp_page_ctrl,
3861 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3862 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3863
3864 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3865
3866 scsiID = RD_HARPOON(port+hp_seltimeout);
3867 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3868 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3869
3870 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3871
3872 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3873
3874 WR_HARPOON(port+hp_seltimeout,scsiID);
3875
3876 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3877
47b5d69c 3878 FPT_Wait(port, TO_5ms);
1da177e4
LT
3879
3880 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3881
3882 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3883
3884 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3885 {
47b5d69c 3886 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4
LT
3887
3888 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3889 {
3890 currTar_Info->TarSyncCtrl = 0;
3891 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3892 }
3893
3894 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3895 {
3896 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3897 }
3898
47b5d69c 3899 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
1da177e4 3900
47b5d69c 3901 FPT_SccbMgrTableInitTarget(p_card, scsiID);
1da177e4
LT
3902 }
3903
47b5d69c
JB
3904 FPT_BL_Card[p_card].scanIndex = 0x00;
3905 FPT_BL_Card[p_card].currentSCCB = NULL;
3906 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
1da177e4 3907 | F_NEW_SCCB_CMD);
47b5d69c
JB
3908 FPT_BL_Card[p_card].cmdCounter = 0x00;
3909 FPT_BL_Card[p_card].discQCount = 0x00;
3910 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
1da177e4
LT
3911
3912 for(i = 0; i < QUEUE_DEPTH; i++)
47b5d69c 3913 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
1da177e4
LT
3914
3915 WR_HARPOON(port+hp_page_ctrl,
3916 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3917
3918}
3919
3920/*---------------------------------------------------------------------
3921 *
47b5d69c 3922 * Function: FPT_ssenss
1da177e4
LT
3923 *
3924 * Description: Setup for the Auto Sense command.
3925 *
3926 *---------------------------------------------------------------------*/
47b5d69c 3927static void FPT_ssenss(PSCCBcard pCurrCard)
1da177e4
LT
3928{
3929 UCHAR i;
3930 PSCCB currSCCB;
3931
3932 currSCCB = pCurrCard->currentSCCB;
3933
3934
3935 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3936
3937 for (i = 0; i < 6; i++) {
3938
3939 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3940 }
3941
3942 currSCCB->CdbLength = SIX_BYTE_CMD;
3943 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3944 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
3945 currSCCB->Cdb[2] = 0x00;
3946 currSCCB->Cdb[3] = 0x00;
3947 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3948 currSCCB->Cdb[5] = 0x00;
3949
3950 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3951
3952 currSCCB->Sccb_ATC = 0x00;
3953
3954 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3955
3956 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3957
3958 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
3959
3960 currSCCB->ControlByte = 0x00;
3961
3962 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3963}
3964
3965
3966
3967/*---------------------------------------------------------------------
3968 *
47b5d69c 3969 * Function: FPT_sxfrp
1da177e4
LT
3970 *
3971 * Description: Transfer data into the bit bucket until the device
3972 * decides to switch phase.
3973 *
3974 *---------------------------------------------------------------------*/
3975
47b5d69c 3976static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
1da177e4
LT
3977{
3978 UCHAR curr_phz;
3979
3980
3981 DISABLE_AUTO(p_port);
3982
47b5d69c 3983 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
1da177e4 3984
47b5d69c 3985 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
1da177e4
LT
3986
3987 }
3988
3989 /* If the Automation handled the end of the transfer then do not
3990 match the phase or we will get out of sync with the ISR. */
3991
3992 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3993 return;
3994
3995 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3996
3997 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
3998
3999 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4000
4001
4002 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4003
4004 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4005 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
4006 {
4007 if (curr_phz & (UCHAR)SCSI_IOBIT)
4008 {
4009 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4010
4011 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4012 {
4013 RD_HARPOON(p_port+hp_fifodata_0);
4014 }
4015 }
4016 else
4017 {
4018 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4019 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4020 {
4021 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4022 }
4023 }
4024 } /* End of While loop for padding data I/O phase */
4025
4026 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4027 {
4028 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4029 break;
4030 }
4031
4032 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4033 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4034 {
4035 RD_HARPOON(p_port+hp_fifodata_0);
4036 }
4037
4038 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4039 {
4040 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4041 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4042
4043 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4044 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4045 }
4046}
4047
4048
4049/*---------------------------------------------------------------------
4050 *
47b5d69c 4051 * Function: FPT_schkdd
1da177e4
LT
4052 *
4053 * Description: Make sure data has been flushed from both FIFOs and abort
4054 * the operations if necessary.
4055 *
4056 *---------------------------------------------------------------------*/
4057
47b5d69c 4058static void FPT_schkdd(ULONG port, UCHAR p_card)
1da177e4
LT
4059{
4060 USHORT TimeOutLoop;
4061 UCHAR sPhase;
4062
4063 PSCCB currSCCB;
4064
47b5d69c 4065 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4066
4067
4068 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4069 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4070 return;
4071 }
4072
4073
4074
4075 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4076 {
4077
4078 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4079
4080 currSCCB->Sccb_XferCnt = 1;
4081
4082 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4083 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4084 WR_HARPOON(port+hp_xferstat, 0x00);
4085 }
4086
4087 else
4088 {
4089
4090 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4091
4092 currSCCB->Sccb_XferCnt = 0;
4093 }
4094
4095 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4096 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4097
4098 currSCCB->HostStatus = SCCB_PARITY_ERR;
4099 WRW_HARPOON((port+hp_intstat), PARITY);
4100 }
4101
4102
47b5d69c 4103 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4
LT
4104
4105
4106 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4107
4108 TimeOutLoop = 0;
4109
4110 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4111 {
4112 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4113 return;
4114 }
4115 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
4116 break;
4117 }
4118 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4119 return;
4120 }
4121 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4122 break;
4123 }
4124
4125 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4126 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4127 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
4128 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4129 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4130 {
4131
4132 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4133
4134 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4135 {
4136 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
47b5d69c 4137 FPT_phaseDataIn(port,p_card);
1da177e4
LT
4138 }
4139
4140 else {
47b5d69c 4141 FPT_phaseDataOut(port,p_card);
1da177e4
LT
4142 }
4143 }
4144 else
4145 {
47b5d69c 4146 FPT_sxfrp(port,p_card);
1da177e4
LT
4147 if (!(RDW_HARPOON((port+hp_intstat)) &
4148 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4149 {
4150 WRW_HARPOON((port+hp_intstat), AUTO_INT);
47b5d69c 4151 FPT_phaseDecode(port,p_card);
1da177e4
LT
4152 }
4153 }
4154
4155 }
4156
4157 else {
4158 WR_HARPOON(port+hp_portctrl_0, 0x00);
4159 }
4160}
4161
4162
4163/*---------------------------------------------------------------------
4164 *
47b5d69c 4165 * Function: FPT_sinits
1da177e4
LT
4166 *
4167 * Description: Setup SCCB manager fields in this SCCB.
4168 *
4169 *---------------------------------------------------------------------*/
4170
47b5d69c 4171static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
1da177e4
LT
4172{
4173 PSCCBMgr_tar_info currTar_Info;
4174
4175 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4176 {
4177 return;
4178 }
47b5d69c 4179 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4
LT
4180
4181 p_sccb->Sccb_XferState = 0x00;
4182 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4183
4184 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4185 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4186
4187 p_sccb->Sccb_SGoffset = 0;
4188 p_sccb->Sccb_XferState = F_SG_XFER;
4189 p_sccb->Sccb_XferCnt = 0x00;
4190 }
4191
4192 if (p_sccb->DataLength == 0x00)
4193
4194 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4195
4196 if (p_sccb->ControlByte & F_USE_CMD_Q)
4197 {
4198 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4199 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4200
4201 else
4202 currTar_Info->TarStatus |= TAG_Q_TRYING;
4203 }
4204
4205/* For !single SCSI device in system & device allow Disconnect
4206 or command is tag_q type then send Cmd with Disconnect Enable
4207 else send Cmd with Disconnect Disable */
4208
4209/*
47b5d69c 4210 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
1da177e4
LT
4211 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4212 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4213*/
4214 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4215 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4216 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4217 }
4218
4219 else {
4220
4221 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
4222 }
4223
4224 p_sccb->HostStatus = 0x00;
4225 p_sccb->TargetStatus = 0x00;
4226 p_sccb->Sccb_tag = 0x00;
4227 p_sccb->Sccb_MGRFlags = 0x00;
4228 p_sccb->Sccb_sgseg = 0x00;
4229 p_sccb->Sccb_ATC = 0x00;
4230 p_sccb->Sccb_savedATC = 0x00;
4231/*
4232 p_sccb->SccbVirtDataPtr = 0x00;
4233 p_sccb->Sccb_forwardlink = NULL;
4234 p_sccb->Sccb_backlink = NULL;
4235 */
4236 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4237 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4238 p_sccb->Sccb_scsimsg = SMNO_OP;
4239
4240}
4241
4242
1da177e4
LT
4243/*---------------------------------------------------------------------
4244 *
4245 * Function: Phase Decode
4246 *
4247 * Description: Determine the phase and call the appropriate function.
4248 *
4249 *---------------------------------------------------------------------*/
4250
47b5d69c 4251static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
1da177e4
LT
4252{
4253 unsigned char phase_ref;
47b5d69c 4254 void (*phase) (ULONG, UCHAR);
1da177e4
LT
4255
4256
4257 DISABLE_AUTO(p_port);
4258
4259 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4260
47b5d69c 4261 phase = FPT_s_PhaseTbl[phase_ref];
1da177e4
LT
4262
4263 (*phase)(p_port, p_card); /* Call the correct phase func */
4264}
4265
4266
4267
4268/*---------------------------------------------------------------------
4269 *
4270 * Function: Data Out Phase
4271 *
4272 * Description: Start up both the BusMaster and Xbow.
4273 *
4274 *---------------------------------------------------------------------*/
4275
47b5d69c 4276static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
1da177e4
LT
4277{
4278
4279 PSCCB currSCCB;
4280
47b5d69c 4281 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4282 if (currSCCB == NULL)
4283 {
4284 return; /* Exit if No SCCB record */
4285 }
4286
4287 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4288 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4289
4290 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4291
4292 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4293
4294 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4295
47b5d69c 4296 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4297
4298 if (currSCCB->Sccb_XferCnt == 0) {
4299
4300
4301 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4302 (currSCCB->HostStatus == SCCB_COMPLETE))
4303 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4304
47b5d69c 4305 FPT_sxfrp(port,p_card);
1da177e4 4306 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
47b5d69c 4307 FPT_phaseDecode(port,p_card);
1da177e4
LT
4308 }
4309}
4310
4311
4312/*---------------------------------------------------------------------
4313 *
4314 * Function: Data In Phase
4315 *
4316 * Description: Startup the BusMaster and the XBOW.
4317 *
4318 *---------------------------------------------------------------------*/
4319
47b5d69c 4320static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
1da177e4
LT
4321{
4322
4323 PSCCB currSCCB;
4324
47b5d69c 4325 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4326
4327 if (currSCCB == NULL)
4328 {
4329 return; /* Exit if No SCCB record */
4330 }
4331
4332
4333 currSCCB->Sccb_scsistat = DATA_IN_ST;
4334 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4335 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4336
4337 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4338
4339 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4340
4341 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4342
47b5d69c 4343 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4344
4345 if (currSCCB->Sccb_XferCnt == 0) {
4346
4347
4348 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4349 (currSCCB->HostStatus == SCCB_COMPLETE))
4350 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4351
47b5d69c 4352 FPT_sxfrp(port,p_card);
1da177e4 4353 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
47b5d69c 4354 FPT_phaseDecode(port,p_card);
1da177e4
LT
4355
4356 }
4357}
4358
4359/*---------------------------------------------------------------------
4360 *
4361 * Function: Command Phase
4362 *
4363 * Description: Load the CDB into the automation and start it up.
4364 *
4365 *---------------------------------------------------------------------*/
4366
47b5d69c 4367static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
1da177e4
LT
4368{
4369 PSCCB currSCCB;
1da177e4 4370 ULONG cdb_reg;
1da177e4
LT
4371 UCHAR i;
4372
47b5d69c 4373 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4374
4375 if (currSCCB->OperationCode == RESET_COMMAND) {
4376
4377 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4378 currSCCB->CdbLength = SIX_BYTE_CMD;
4379 }
4380
4381 WR_HARPOON(p_port+hp_scsisig, 0x00);
4382
4383 ARAM_ACCESS(p_port);
4384
4385
4386 cdb_reg = p_port + CMD_STRT;
4387
4388 for (i=0; i < currSCCB->CdbLength; i++) {
4389
4390 if (currSCCB->OperationCode == RESET_COMMAND)
4391
4392 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4393
4394 else
4395 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4396 cdb_reg +=2;
4397 }
4398
4399 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4400 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4401
4402 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4403
4404 currSCCB->Sccb_scsistat = COMMAND_ST;
4405
4406 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4407 SGRAM_ACCESS(p_port);
4408}
4409
4410
4411/*---------------------------------------------------------------------
4412 *
4413 * Function: Status phase
4414 *
4415 * Description: Bring in the status and command complete message bytes
4416 *
4417 *---------------------------------------------------------------------*/
4418
47b5d69c 4419static void FPT_phaseStatus(ULONG port, UCHAR p_card)
1da177e4
LT
4420{
4421 /* Start-up the automation to finish off this command and let the
4422 isr handle the interrupt for command complete when it comes in.
4423 We could wait here for the interrupt to be generated?
4424 */
4425
4426 WR_HARPOON(port+hp_scsisig, 0x00);
4427
4428 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4429}
4430
4431
4432/*---------------------------------------------------------------------
4433 *
4434 * Function: Phase Message Out
4435 *
4436 * Description: Send out our message (if we have one) and handle whatever
4437 * else is involed.
4438 *
4439 *---------------------------------------------------------------------*/
4440
47b5d69c 4441static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
1da177e4
LT
4442{
4443 UCHAR message,scsiID;
4444 PSCCB currSCCB;
4445 PSCCBMgr_tar_info currTar_Info;
4446
47b5d69c 4447 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4448
4449 if (currSCCB != NULL) {
4450
4451 message = currSCCB->Sccb_scsimsg;
4452 scsiID = currSCCB->TargID;
4453
4454 if (message == SMDEV_RESET)
4455 {
4456
4457
47b5d69c 4458 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
1da177e4 4459 currTar_Info->TarSyncCtrl = 0;
47b5d69c 4460 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
1da177e4 4461
47b5d69c 4462 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
1da177e4
LT
4463 {
4464
47b5d69c 4465 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
1da177e4
LT
4466
4467 }
4468
47b5d69c 4469 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
1da177e4
LT
4470 {
4471
47b5d69c 4472 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
4473 }
4474
4475
47b5d69c
JB
4476 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4477 FPT_SccbMgrTableInitTarget(p_card,scsiID);
1da177e4
LT
4478 }
4479 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4480 {
4481 currSCCB->HostStatus = SCCB_COMPLETE;
47b5d69c 4482 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
1da177e4 4483 {
47b5d69c
JB
4484 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4485 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
1da177e4
LT
4486 }
4487
4488 }
4489
4490 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4491 {
4492
4493
4494 if(message == SMNO_OP)
4495 {
4496 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4497
47b5d69c 4498 FPT_ssel(port,p_card);
1da177e4
LT
4499 return;
4500 }
4501 }
4502 else
4503 {
4504
4505
4506 if (message == SMABORT)
4507
47b5d69c 4508 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
1da177e4
LT
4509 }
4510
4511 }
4512 else
4513 {
4514 message = SMABORT;
4515 }
4516
4517 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4518
4519
4520 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4521
4522 WR_HARPOON(port+hp_scsidata_0,message);
4523
4524 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4525
4526 ACCEPT_MSG(port);
4527
4528 WR_HARPOON(port+hp_portctrl_0, 0x00);
4529
4530 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4531 (message == SMABORT_TAG) )
4532 {
4533
4534 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4535
4536 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4537 {
4538 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4539
4540 if (currSCCB != NULL)
4541 {
4542
47b5d69c
JB
4543 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4544 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4545 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4546 else
47b5d69c 4547 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4548
47b5d69c 4549 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
1da177e4
LT
4550 }
4551
4552 else
4553 {
47b5d69c 4554 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4
LT
4555 }
4556 }
4557
4558 else
4559 {
4560
47b5d69c 4561 FPT_sxfrp(port,p_card);
1da177e4
LT
4562 }
4563 }
4564
4565 else
4566 {
4567
4568 if(message == SMPARITY)
4569 {
4570 currSCCB->Sccb_scsimsg = SMNO_OP;
4571 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4572 }
4573 else
4574 {
47b5d69c 4575 FPT_sxfrp(port,p_card);
1da177e4
LT
4576 }
4577 }
4578}
4579
4580
4581/*---------------------------------------------------------------------
4582 *
4583 * Function: Message In phase
4584 *
4585 * Description: Bring in the message and determine what to do with it.
4586 *
4587 *---------------------------------------------------------------------*/
4588
47b5d69c 4589static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
1da177e4
LT
4590{
4591 UCHAR message;
4592 PSCCB currSCCB;
4593
47b5d69c 4594 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4 4595
47b5d69c 4596 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
1da177e4
LT
4597 {
4598
47b5d69c 4599 FPT_phaseChkFifo(port, p_card);
1da177e4
LT
4600 }
4601
4602 message = RD_HARPOON(port+hp_scsidata_0);
4603 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4604 {
4605
4606 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4607
4608 }
4609
4610 else
4611 {
4612
47b5d69c 4613 message = FPT_sfm(port,currSCCB);
1da177e4
LT
4614 if (message)
4615 {
4616
4617
47b5d69c 4618 FPT_sdecm(message,port,p_card);
1da177e4
LT
4619
4620 }
4621 else
4622 {
4623 if(currSCCB->Sccb_scsimsg != SMPARITY)
4624 ACCEPT_MSG(port);
4625 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4626 }
4627 }
4628
4629}
4630
4631
4632/*---------------------------------------------------------------------
4633 *
4634 * Function: Illegal phase
4635 *
4636 * Description: Target switched to some illegal phase, so all we can do
4637 * is report an error back to the host (if that is possible)
4638 * and send an ABORT message to the misbehaving target.
4639 *
4640 *---------------------------------------------------------------------*/
4641
47b5d69c 4642static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
1da177e4
LT
4643{
4644 PSCCB currSCCB;
4645
47b5d69c 4646 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4647
4648 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4649 if (currSCCB != NULL) {
4650
4651 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4652 currSCCB->Sccb_scsistat = ABORT_ST;
4653 currSCCB->Sccb_scsimsg = SMABORT;
4654 }
4655
4656 ACCEPT_MSG_ATN(port);
4657}
4658
4659
4660
4661/*---------------------------------------------------------------------
4662 *
4663 * Function: Phase Check FIFO
4664 *
4665 * Description: Make sure data has been flushed from both FIFOs and abort
4666 * the operations if necessary.
4667 *
4668 *---------------------------------------------------------------------*/
4669
47b5d69c 4670static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
1da177e4
LT
4671{
4672 ULONG xfercnt;
4673 PSCCB currSCCB;
4674
47b5d69c 4675 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4676
4677 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4678 {
4679
4680 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4681 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4682
4683
4684 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4685 {
4686 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4687
4688 currSCCB->Sccb_XferCnt = 0;
4689
4690 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4691 (currSCCB->HostStatus == SCCB_COMPLETE))
4692 {
4693 currSCCB->HostStatus = SCCB_PARITY_ERR;
4694 WRW_HARPOON((port+hp_intstat), PARITY);
4695 }
4696
47b5d69c 4697 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4 4698
47b5d69c 4699 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
1da177e4
LT
4700
4701 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4702 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4703
4704 }
4705 } /*End Data In specific code. */
4706
4707
4708
1da177e4 4709 GET_XFER_CNT(port,xfercnt);
1da177e4
LT
4710
4711
4712 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4713
4714
4715 WR_HARPOON(port+hp_portctrl_0, 0x00);
4716
4717 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4718
4719 currSCCB->Sccb_XferCnt = xfercnt;
4720
4721 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4722 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4723
4724 currSCCB->HostStatus = SCCB_PARITY_ERR;
4725 WRW_HARPOON((port+hp_intstat), PARITY);
4726 }
4727
4728
47b5d69c 4729 FPT_hostDataXferAbort(port,p_card,currSCCB);
1da177e4
LT
4730
4731
4732 WR_HARPOON(port+hp_fifowrite, 0x00);
4733 WR_HARPOON(port+hp_fiforead, 0x00);
4734 WR_HARPOON(port+hp_xferstat, 0x00);
4735
4736 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4737}
4738
4739
4740/*---------------------------------------------------------------------
4741 *
4742 * Function: Phase Bus Free
4743 *
4744 * Description: We just went bus free so figure out if it was
4745 * because of command complete or from a disconnect.
4746 *
4747 *---------------------------------------------------------------------*/
47b5d69c 4748static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
1da177e4
LT
4749{
4750 PSCCB currSCCB;
4751
47b5d69c 4752 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4753
4754 if (currSCCB != NULL)
4755 {
4756
4757 DISABLE_AUTO(port);
4758
4759
4760 if (currSCCB->OperationCode == RESET_COMMAND)
4761 {
4762
47b5d69c
JB
4763 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4764 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4766 else
47b5d69c 4767 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4768
47b5d69c 4769 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 4770
47b5d69c 4771 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
4772
4773 }
4774
4775 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4776 {
47b5d69c 4777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
1da177e4 4778 (UCHAR)SYNC_SUPPORTED;
47b5d69c 4779 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
1da177e4
LT
4780 }
4781
4782 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4783 {
47b5d69c
JB
4784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4785 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
1da177e4
LT
4786 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4787
47b5d69c 4788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
1da177e4
LT
4789 }
4790
1da177e4
LT
4791 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4792 {
4793 /* Make sure this is not a phony BUS_FREE. If we were
4794 reselected or if BUSY is NOT on then this is a
4795 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4796
4797 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4798 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4799 {
47b5d69c
JB
4800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4801 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
1da177e4
LT
4802 }
4803
4804 else
4805 {
4806 return;
4807 }
4808 }
1da177e4
LT
4809
4810 else
4811 {
4812
4813 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4814
4815 if (!currSCCB->HostStatus)
4816 {
4817 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4818 }
4819
47b5d69c
JB
4820 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4821 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4822 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 4823 else
47b5d69c 4824 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4 4825
47b5d69c 4826 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4
LT
4827 return;
4828 }
4829
4830
47b5d69c 4831 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4
LT
4832
4833 } /*end if !=null */
4834}
4835
4836
4837
4838
1da177e4
LT
4839/*---------------------------------------------------------------------
4840 *
4841 * Function: Auto Load Default Map
4842 *
4843 * Description: Load the Automation RAM with the defualt map values.
4844 *
4845 *---------------------------------------------------------------------*/
47b5d69c 4846static void FPT_autoLoadDefaultMap(ULONG p_port)
1da177e4 4847{
1da177e4 4848 ULONG map_addr;
1da177e4
LT
4849
4850 ARAM_ACCESS(p_port);
4851 map_addr = p_port + hp_aramBase;
4852
4853 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4854 map_addr +=2;
4855 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4856 map_addr +=2;
4857 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4858 map_addr +=2;
4859 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4860 map_addr +=2;
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4862 map_addr +=2;
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4864 map_addr +=2;
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4866 map_addr +=2;
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4868 map_addr +=2;
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4870 map_addr +=2;
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4872 map_addr +=2;
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4874 map_addr +=2;
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4876 map_addr +=2;
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4878 map_addr +=2;
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4880 map_addr +=2;
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4882 map_addr +=2;
4883 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4884 map_addr +=2;
4885 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4886 map_addr +=2;
4887 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4888 map_addr +=2; /*This means AYNC DATA IN */
4889 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4890 map_addr +=2;
4891 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4892 map_addr +=2;
4893 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4894 map_addr +=2;
4895 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4896 map_addr +=2;
4897 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4898 map_addr +=2;
4899 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4900 map_addr +=2;
4901 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4902 map_addr +=2;
4903 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4904 map_addr +=2;
4905 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4906 map_addr +=2;
4907 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4908 map_addr +=2;
4909 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4910 map_addr +=2;
4911 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4912 map_addr +=2;
4913 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4914 map_addr +=2;
4915 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4916 map_addr +=2;
4917 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4918 map_addr +=2;
4919 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4920 map_addr +=2;
4921 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4922 map_addr +=2;
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4924 map_addr +=2;
4925
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4927 map_addr +=2;
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4929 map_addr +=2;
4930 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4931 map_addr +=2;
4932 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4933 map_addr +=2; /* DIDN'T GET ONE */
4934 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4935 map_addr +=2;
4936 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4937 map_addr +=2;
4938 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4939
4940
4941
4942 SGRAM_ACCESS(p_port);
4943}
4944
4945/*---------------------------------------------------------------------
4946 *
4947 * Function: Auto Command Complete
4948 *
4949 * Description: Post command back to host and find another command
4950 * to execute.
4951 *
4952 *---------------------------------------------------------------------*/
4953
47b5d69c 4954static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
1da177e4
LT
4955{
4956 PSCCB currSCCB;
4957 UCHAR status_byte;
4958
47b5d69c 4959 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
4960
4961 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4962
47b5d69c 4963 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
1da177e4
LT
4964
4965 if (status_byte != SSGOOD) {
4966
4967 if (status_byte == SSQ_FULL) {
4968
4969
47b5d69c
JB
4970 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4971 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 4972 {
47b5d69c
JB
4973 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4974 if(FPT_BL_Card[p_card].discQCount != 0)
4975 FPT_BL_Card[p_card].discQCount--;
4976 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
4977 }
4978 else
4979 {
47b5d69c 4980 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
4981 if(currSCCB->Sccb_tag)
4982 {
47b5d69c
JB
4983 if(FPT_BL_Card[p_card].discQCount != 0)
4984 FPT_BL_Card[p_card].discQCount--;
4985 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
4986 }else
4987 {
47b5d69c
JB
4988 if(FPT_BL_Card[p_card].discQCount != 0)
4989 FPT_BL_Card[p_card].discQCount--;
4990 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
4991 }
4992 }
4993
4994 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4995
47b5d69c 4996 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
1da177e4
LT
4997
4998 return;
4999 }
5000
5001 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5002 {
47b5d69c 5003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
1da177e4
LT
5004 (UCHAR)SYNC_SUPPORTED;
5005
47b5d69c
JB
5006 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5007 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5008
47b5d69c
JB
5009 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5010 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 5011 {
47b5d69c
JB
5012 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5013 if(FPT_BL_Card[p_card].discQCount != 0)
5014 FPT_BL_Card[p_card].discQCount--;
5015 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
5016 }
5017 else
5018 {
47b5d69c 5019 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5020 if(currSCCB->Sccb_tag)
5021 {
47b5d69c
JB
5022 if(FPT_BL_Card[p_card].discQCount != 0)
5023 FPT_BL_Card[p_card].discQCount--;
5024 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
5025 }else
5026 {
47b5d69c
JB
5027 if(FPT_BL_Card[p_card].discQCount != 0)
5028 FPT_BL_Card[p_card].discQCount--;
5029 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
5030 }
5031 }
5032 return;
5033
5034 }
5035
5036 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5037 {
5038
47b5d69c
JB
5039 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5040 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
1da177e4
LT
5041 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5042
47b5d69c
JB
5043 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5044 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5045
47b5d69c
JB
5046 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5047 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 5048 {
47b5d69c
JB
5049 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5050 if(FPT_BL_Card[p_card].discQCount != 0)
5051 FPT_BL_Card[p_card].discQCount--;
5052 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
5053 }
5054 else
5055 {
47b5d69c 5056 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5057 if(currSCCB->Sccb_tag)
5058 {
47b5d69c
JB
5059 if(FPT_BL_Card[p_card].discQCount != 0)
5060 FPT_BL_Card[p_card].discQCount--;
5061 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
5062 }else
5063 {
47b5d69c
JB
5064 if(FPT_BL_Card[p_card].discQCount != 0)
5065 FPT_BL_Card[p_card].discQCount--;
5066 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
5067 }
5068 }
5069 return;
5070
5071 }
5072
5073 if (status_byte == SSCHECK)
5074 {
47b5d69c 5075 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
1da177e4 5076 {
47b5d69c 5077 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
1da177e4 5078 {
47b5d69c 5079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
1da177e4 5080 }
47b5d69c 5081 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
1da177e4 5082 {
47b5d69c 5083 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
1da177e4
LT
5084 }
5085 }
5086 }
5087
5088 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5089
5090 currSCCB->SccbStatus = SCCB_ERROR;
5091 currSCCB->TargetStatus = status_byte;
5092
5093 if (status_byte == SSCHECK) {
5094
47b5d69c
JB
5095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5096 = 1;
1da177e4
LT
5097
5098
1da177e4
LT
5099 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5100
5101 if (currSCCB->RequestSenseLength == 0)
5102 currSCCB->RequestSenseLength = 14;
5103
47b5d69c
JB
5104 FPT_ssenss(&FPT_BL_Card[p_card]);
5105 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
1da177e4 5106
47b5d69c
JB
5107 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5108 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
1da177e4 5109 {
47b5d69c
JB
5110 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5111 if(FPT_BL_Card[p_card].discQCount != 0)
5112 FPT_BL_Card[p_card].discQCount--;
5113 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
1da177e4
LT
5114 }
5115 else
5116 {
47b5d69c 5117 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
1da177e4
LT
5118 if(currSCCB->Sccb_tag)
5119 {
47b5d69c
JB
5120 if(FPT_BL_Card[p_card].discQCount != 0)
5121 FPT_BL_Card[p_card].discQCount--;
5122 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
1da177e4
LT
5123 }else
5124 {
47b5d69c
JB
5125 if(FPT_BL_Card[p_card].discQCount != 0)
5126 FPT_BL_Card[p_card].discQCount--;
5127 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
1da177e4
LT
5128 }
5129 }
5130 return;
5131 }
1da177e4
LT
5132 }
5133 }
5134 }
5135
5136
47b5d69c
JB
5137 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5138 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5139 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
1da177e4 5140 else
47b5d69c 5141 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
1da177e4
LT
5142
5143
47b5d69c 5144 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
1da177e4 5145}
1da177e4
LT
5146
5147#define SHORT_WAIT 0x0000000F
5148#define LONG_WAIT 0x0000FFFFL
5149
1da177e4
LT
5150
5151/*---------------------------------------------------------------------
5152 *
5153 * Function: Data Transfer Processor
5154 *
5155 * Description: This routine performs two tasks.
5156 * (1) Start data transfer by calling HOST_DATA_XFER_START
5157 * function. Once data transfer is started, (2) Depends
5158 * on the type of data transfer mode Scatter/Gather mode
5159 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5160 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5161 * data transfer done. In Scatter/Gather mode, this routine
5162 * checks bus master command complete and dual rank busy
5163 * bit to keep chaining SC transfer command. Similarly,
5164 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5165 * (F_HOST_XFER_ACT bit) for data transfer done.
5166 *
5167 *---------------------------------------------------------------------*/
5168
47b5d69c 5169static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
1da177e4
LT
5170{
5171 PSCCB currSCCB;
5172
5173 currSCCB = pCurrCard->currentSCCB;
5174
5175 if (currSCCB->Sccb_XferState & F_SG_XFER)
5176 {
5177 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5178
5179 {
5180 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
5181 currSCCB->Sccb_SGoffset = 0x00;
5182 }
5183 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5184
47b5d69c 5185 FPT_busMstrSGDataXferStart(port, currSCCB);
1da177e4
LT
5186 }
5187
5188 else
5189 {
5190 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5191 {
5192 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5193
47b5d69c 5194 FPT_busMstrDataXferStart(port, currSCCB);
1da177e4
LT
5195 }
5196 }
5197}
5198
5199
5200/*---------------------------------------------------------------------
5201 *
5202 * Function: BusMaster Scatter Gather Data Transfer Start
5203 *
5204 * Description:
5205 *
5206 *---------------------------------------------------------------------*/
47b5d69c 5207static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
1da177e4
LT
5208{
5209 ULONG count,addr,tmpSGCnt;
5210 UINT sg_index;
5211 UCHAR sg_count, i;
1da177e4 5212 ULONG reg_offset;
1da177e4
LT
5213
5214
5215 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5216
5217 count = ((ULONG) HOST_RD_CMD)<<24;
5218 }
5219
5220 else {
5221 count = ((ULONG) HOST_WRT_CMD)<<24;
5222 }
5223
5224 sg_count = 0;
5225 tmpSGCnt = 0;
5226 sg_index = pcurrSCCB->Sccb_sgseg;
5227 reg_offset = hp_aramBase;
5228
5229
5230 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5231
5232
5233 WR_HARPOON(p_port+hp_page_ctrl, i);
5234
5235 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
5236 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5237
1da177e4
LT
5238 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5239 (sg_index * 2));
5240
5241 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5242 (sg_index * 2));
5243
5244 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5245 ((sg_index * 2) + 1));
1da177e4
LT
5246
5247
5248 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5249
5250 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5251 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5252
5253 tmpSGCnt = count & 0x00FFFFFFL;
5254 }
5255
5256 WR_HARP32(p_port,reg_offset,addr);
5257 reg_offset +=4;
5258
5259 WR_HARP32(p_port,reg_offset,count);
5260 reg_offset +=4;
5261
5262 count &= 0xFF000000L;
5263 sg_index++;
5264 sg_count++;
5265
5266 } /*End While */
5267
5268 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5269
5270 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5271
5272 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5273
5274 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5275
5276
5277 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5278 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5279 }
5280
5281 else {
5282
5283
5284 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5285 (tmpSGCnt & 0x000000001))
5286 {
5287
5288 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5289 tmpSGCnt--;
5290 }
5291
5292
5293 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5294
5295 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5296 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5297 }
5298
5299
5300 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
5301
5302}
5303
5304
5305/*---------------------------------------------------------------------
5306 *
5307 * Function: BusMaster Data Transfer Start
5308 *
5309 * Description:
5310 *
5311 *---------------------------------------------------------------------*/
47b5d69c 5312static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
1da177e4
LT
5313{
5314 ULONG addr,count;
5315
5316 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5317
5318 count = pcurrSCCB->Sccb_XferCnt;
5319
5320 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5321 }
5322
5323 else {
5324 addr = pcurrSCCB->SensePointer;
5325 count = pcurrSCCB->RequestSenseLength;
5326
5327 }
5328
1da177e4 5329 HP_SETUP_ADDR_CNT(p_port,addr,count);
1da177e4
LT
5330
5331
5332 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5333
5334 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5335 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5336
5337 WR_HARPOON(p_port+hp_xfer_cmd,
5338 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5339 }
5340
5341 else {
5342
5343 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5344 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5345
5346 WR_HARPOON(p_port+hp_xfer_cmd,
5347 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5348
5349 }
5350}
5351
5352
5353/*---------------------------------------------------------------------
5354 *
5355 * Function: BusMaster Timeout Handler
5356 *
5357 * Description: This function is called after a bus master command busy time
5358 * out is detected. This routines issue halt state machine
5359 * with a software time out for command busy. If command busy
5360 * is still asserted at the end of the time out, it issues
5361 * hard abort with another software time out. It hard abort
5362 * command busy is also time out, it'll just give up.
5363 *
5364 *---------------------------------------------------------------------*/
47b5d69c 5365static UCHAR FPT_busMstrTimeOut(ULONG p_port)
1da177e4
LT
5366{
5367 ULONG timeout;
5368
5369 timeout = LONG_WAIT;
5370
5371 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5372
5373 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5374
5375
5376
5377 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5378 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5379
5380 timeout = LONG_WAIT;
5381 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5382 }
5383
5384 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5385
5386 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
47b5d69c 5387 return(1);
1da177e4
LT
5388 }
5389
5390 else {
47b5d69c 5391 return(0);
1da177e4
LT
5392 }
5393}
5394
5395
5396/*---------------------------------------------------------------------
5397 *
5398 * Function: Host Data Transfer Abort
5399 *
5400 * Description: Abort any in progress transfer.
5401 *
5402 *---------------------------------------------------------------------*/
47b5d69c 5403static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
1da177e4
LT
5404{
5405
5406 ULONG timeout;
5407 ULONG remain_cnt;
5408 UINT sg_ptr;
5409
47b5d69c 5410 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
1da177e4
LT
5411
5412 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5413
5414
5415 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5416
5417 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5418 timeout = LONG_WAIT;
5419
5420 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5421
5422 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5423
5424 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5425
47b5d69c 5426 if (FPT_busMstrTimeOut(port)) {
1da177e4
LT
5427
5428 if (pCurrSCCB->HostStatus == 0x00)
5429
5430 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5431
5432 }
5433
5434 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5435
5436 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5437
5438 if (pCurrSCCB->HostStatus == 0x00)
5439
5440 {
5441 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5442 }
5443 }
5444 }
5445 }
5446
5447 else if (pCurrSCCB->Sccb_XferCnt) {
5448
5449 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5450
5451
5452 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5453 ~SCATTER_EN));
5454
5455 WR_HARPOON(port+hp_sg_addr,0x00);
5456
5457 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5458
5459 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5460
5461 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5462 }
5463
5464 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5465
5466 while (remain_cnt < 0x01000000L) {
5467
5468 sg_ptr--;
5469
1da177e4
LT
5470 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5471 DataPointer) + (sg_ptr * 2)))) {
5472
5473 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5474 DataPointer) + (sg_ptr * 2)));
5475 }
1da177e4
LT
5476
5477 else {
5478
5479 break;
5480 }
5481 }
5482
5483
5484
5485 if (remain_cnt < 0x01000000L) {
5486
5487
5488 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5489
5490 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5491
5492
5493 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5494 && (remain_cnt == 0))
5495
5496 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5497 }
5498
5499 else {
5500
5501
5502 if (pCurrSCCB->HostStatus == 0x00) {
5503
5504 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5505 }
5506 }
5507 }
5508
5509
5510 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5511
5512
5513 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5514
47b5d69c 5515 FPT_busMstrTimeOut(port);
1da177e4
LT
5516 }
5517
5518 else {
5519
5520 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5521
5522 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5523
5524 if (pCurrSCCB->HostStatus == 0x00) {
5525
5526 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5527 }
5528 }
5529 }
5530
5531 }
5532 }
5533
5534 else {
5535
5536
5537 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5538
5539 timeout = SHORT_WAIT;
5540
5541 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5542 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5543 timeout--) {}
5544 }
5545
5546 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5547
5548 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5549 FLUSH_XFER_CNTR));
5550
5551 timeout = LONG_WAIT;
5552
5553 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5554 timeout--) {}
5555
5556 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5557 ~FLUSH_XFER_CNTR));
5558
5559
5560 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5561
5562 if (pCurrSCCB->HostStatus == 0x00) {
5563
5564 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5565 }
5566
47b5d69c 5567 FPT_busMstrTimeOut(port);
1da177e4
LT
5568 }
5569 }
5570
5571 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5572
5573 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5574
5575 if (pCurrSCCB->HostStatus == 0x00) {
5576
5577 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5578 }
5579 }
5580 }
5581 }
5582
5583 }
5584
5585 else {
5586
5587
5588 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5589
5590 timeout = LONG_WAIT;
5591
5592 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5593
5594 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5595
5596 if (pCurrSCCB->HostStatus == 0x00) {
5597
5598 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5599 }
5600
47b5d69c 5601 FPT_busMstrTimeOut(port);
1da177e4
LT
5602 }
5603 }
5604
5605
5606 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5607
5608 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5609
5610 if (pCurrSCCB->HostStatus == 0x00) {
5611
5612 pCurrSCCB->HostStatus = SCCB_BM_ERR;
1da177e4
LT
5613 }
5614 }
5615
5616 }
5617
5618 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5619
5620 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5621 ~SCATTER_EN));
5622
5623 WR_HARPOON(port+hp_sg_addr,0x00);
5624
5625 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5626
5627 pCurrSCCB->Sccb_SGoffset = 0x00;
5628
5629
5630 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5631 pCurrSCCB->DataLength) {
5632
5633 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5634
5635 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5636
5637 }
5638 }
5639
5640 else {
5641
5642 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5643
5644 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5645 }
5646 }
5647
5648 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5649}
5650
5651
5652
5653/*---------------------------------------------------------------------
5654 *
5655 * Function: Host Data Transfer Restart
5656 *
5657 * Description: Reset the available count due to a restore data
5658 * pointers message.
5659 *
5660 *---------------------------------------------------------------------*/
47b5d69c 5661static void FPT_hostDataXferRestart(PSCCB currSCCB)
1da177e4
LT
5662{
5663 ULONG data_count;
5664 UINT sg_index;
1da177e4 5665 ULONG *sg_ptr;
1da177e4
LT
5666
5667 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5668
5669 currSCCB->Sccb_XferCnt = 0;
5670
5671 sg_index = 0xffff; /*Index by long words into sg list. */
5672 data_count = 0; /*Running count of SG xfer counts. */
5673
1da177e4 5674 sg_ptr = (ULONG *)currSCCB->DataPointer;
1da177e4
LT
5675
5676 while (data_count < currSCCB->Sccb_ATC) {
5677
5678 sg_index++;
5679 data_count += *(sg_ptr+(sg_index * 2));
5680 }
5681
5682 if (data_count == currSCCB->Sccb_ATC) {
5683
5684 currSCCB->Sccb_SGoffset = 0;
5685 sg_index++;
5686 }
5687
5688 else {
5689 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5690 }
5691
5692 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5693 }
5694
5695 else {
5696 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5697 }
5698}
1da177e4
LT
5699
5700
5701
1da177e4
LT
5702/*---------------------------------------------------------------------
5703 *
47b5d69c 5704 * Function: FPT_scini
1da177e4
LT
5705 *
5706 * Description: Setup all data structures necessary for SCAM selection.
5707 *
5708 *---------------------------------------------------------------------*/
5709
47b5d69c 5710static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
1da177e4
LT
5711{
5712
1da177e4 5713 UCHAR loser,assigned_id;
1da177e4 5714 ULONG p_port;
1da177e4
LT
5715
5716 UCHAR i,k,ScamFlg ;
5717 PSCCBcard currCard;
5718 PNVRamInfo pCurrNvRam;
5719
47b5d69c 5720 currCard = &FPT_BL_Card[p_card];
1da177e4
LT
5721 p_port = currCard->ioPort;
5722 pCurrNvRam = currCard->pNvRamInfo;
5723
5724
5725 if(pCurrNvRam){
5726 ScamFlg = pCurrNvRam->niScamConf;
5727 i = pCurrNvRam->niSysConf;
5728 }
5729 else{
47b5d69c
JB
5730 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5731 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
1da177e4
LT
5732 }
5733 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5734 return;
5735
47b5d69c 5736 FPT_inisci(p_card,p_port, p_our_id);
1da177e4
LT
5737
5738 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5739 too slow to return to SCAM selection */
5740
5741 /* if (p_power_up)
47b5d69c 5742 FPT_Wait1Second(p_port);
1da177e4 5743 else
47b5d69c 5744 FPT_Wait(p_port, TO_250ms); */
1da177e4 5745
47b5d69c 5746 FPT_Wait1Second(p_port);
1da177e4
LT
5747
5748 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5749 {
47b5d69c 5750 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
1da177e4 5751
47b5d69c 5752 FPT_scsel(p_port);
1da177e4
LT
5753
5754 do {
47b5d69c
JB
5755 FPT_scxferc(p_port,SYNC_PTRN);
5756 FPT_scxferc(p_port,DOM_MSTR);
5757 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
1da177e4
LT
5758 } while ( loser == 0xFF );
5759
47b5d69c 5760 FPT_scbusf(p_port);
1da177e4
LT
5761
5762 if ((p_power_up) && (!loser))
5763 {
47b5d69c
JB
5764 FPT_sresb(p_port,p_card);
5765 FPT_Wait(p_port, TO_250ms);
1da177e4 5766
47b5d69c 5767 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
1da177e4 5768
47b5d69c 5769 FPT_scsel(p_port);
1da177e4
LT
5770
5771 do {
47b5d69c
JB
5772 FPT_scxferc(p_port, SYNC_PTRN);
5773 FPT_scxferc(p_port, DOM_MSTR);
5774 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
1da177e4
LT
5775 id_string[0]);
5776 } while ( loser == 0xFF );
5777
47b5d69c 5778 FPT_scbusf(p_port);
1da177e4
LT
5779 }
5780 }
5781
5782 else
5783 {
47b5d69c 5784 loser = 0;
1da177e4
LT
5785 }
5786
5787
5788 if (!loser)
5789 {
5790
47b5d69c 5791 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
1da177e4
LT
5792
5793
5794 if (ScamFlg & SCAM_ENABLED)
5795 {
5796
5797 for (i=0; i < MAX_SCSI_TAR; i++)
5798 {
47b5d69c
JB
5799 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5800 (FPT_scamInfo[i].state == ID_UNUSED))
1da177e4 5801 {
47b5d69c 5802 if (FPT_scsell(p_port,i))
1da177e4 5803 {
47b5d69c
JB
5804 FPT_scamInfo[i].state = LEGACY;
5805 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5806 (FPT_scamInfo[i].id_string[1] != 0xFA))
1da177e4
LT
5807 {
5808
47b5d69c
JB
5809 FPT_scamInfo[i].id_string[0] = 0xFF;
5810 FPT_scamInfo[i].id_string[1] = 0xFA;
1da177e4
LT
5811 if(pCurrNvRam == NULL)
5812 currCard->globalFlags |= F_UPDATE_EEPROM;
5813 }
5814 }
5815 }
5816 }
5817
47b5d69c
JB
5818 FPT_sresb(p_port,p_card);
5819 FPT_Wait1Second(p_port);
5820 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5821 FPT_scsel(p_port);
5822 FPT_scasid(p_card, p_port);
1da177e4
LT
5823 }
5824
1da177e4
LT
5825 }
5826
5827 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5828 {
47b5d69c
JB
5829 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5830 assigned_id = 0;
5831 FPT_scwtsel(p_port);
1da177e4
LT
5832
5833 do {
47b5d69c 5834 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
1da177e4 5835
47b5d69c 5836 i = FPT_scxferc(p_port,0x00);
1da177e4
LT
5837 if (i == ASSIGN_ID)
5838 {
47b5d69c 5839 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
1da177e4 5840 {
47b5d69c
JB
5841 i = FPT_scxferc(p_port,0x00);
5842 if (FPT_scvalq(i))
1da177e4 5843 {
47b5d69c 5844 k = FPT_scxferc(p_port,0x00);
1da177e4 5845
47b5d69c 5846 if (FPT_scvalq(k))
1da177e4
LT
5847 {
5848 currCard->ourId =
5849 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
47b5d69c
JB
5850 FPT_inisci(p_card, p_port, p_our_id);
5851 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5852 FPT_scamInfo[currCard->ourId].id_string[0]
1da177e4 5853 = SLV_TYPE_CODE0;
47b5d69c 5854 assigned_id = 1;
1da177e4
LT
5855 }
5856 }
5857 }
5858 }
5859
5860 else if (i == SET_P_FLAG)
5861 {
47b5d69c
JB
5862 if (!(FPT_scsendi(p_port,
5863 &FPT_scamInfo[p_our_id].id_string[0])))
5864 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
1da177e4
LT
5865 }
5866 }while (!assigned_id);
5867
47b5d69c 5868 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
1da177e4
LT
5869 }
5870
1da177e4
LT
5871 if (ScamFlg & SCAM_ENABLED)
5872 {
47b5d69c 5873 FPT_scbusf(p_port);
1da177e4
LT
5874 if (currCard->globalFlags & F_UPDATE_EEPROM)
5875 {
47b5d69c 5876 FPT_scsavdi(p_card, p_port);
1da177e4
LT
5877 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5878 }
5879 }
5880
5881
1da177e4
LT
5882/*
5883 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5884 {
47b5d69c
JB
5885 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5886 (FPT_scamInfo[i].state == LEGACY))
1da177e4
LT
5887 k++;
5888 }
5889
5890 if (k==2)
5891 currCard->globalFlags |= F_SINGLE_DEVICE;
5892 else
5893 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5894*/
5895}
5896
5897
5898/*---------------------------------------------------------------------
5899 *
47b5d69c 5900 * Function: FPT_scarb
1da177e4
LT
5901 *
5902 * Description: Gain control of the bus and wait SCAM select time (250ms)
5903 *
5904 *---------------------------------------------------------------------*/
5905
47b5d69c 5906static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
1da177e4
LT
5907{
5908 if (p_sel_type == INIT_SELTD)
5909 {
5910
5911 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5912
5913
5914 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
47b5d69c 5915 return(0);
1da177e4
LT
5916
5917 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
47b5d69c 5918 return(0);
1da177e4
LT
5919
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5921
5922 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5923
5924 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5925 ~SCSI_BSY));
47b5d69c 5926 return(0);
1da177e4
LT
5927 }
5928
5929
5930 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5931
5932 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5933
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5935 ~(SCSI_BSY | SCSI_SEL)));
47b5d69c 5936 return(0);
1da177e4
LT
5937 }
5938 }
5939
5940
5941 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5942 & ~ACTdeassert));
5943 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5944 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
1da177e4 5945 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
1da177e4
LT
5946 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5947
5948 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5949
5950 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5951 & ~SCSI_BSY));
5952
47b5d69c 5953 FPT_Wait(p_port,TO_250ms);
1da177e4 5954
47b5d69c 5955 return(1);
1da177e4
LT
5956}
5957
5958
5959/*---------------------------------------------------------------------
5960 *
47b5d69c 5961 * Function: FPT_scbusf
1da177e4
LT
5962 *
5963 * Description: Release the SCSI bus and disable SCAM selection.
5964 *
5965 *---------------------------------------------------------------------*/
5966
47b5d69c 5967static void FPT_scbusf(ULONG p_port)
1da177e4
LT
5968{
5969 WR_HARPOON(p_port+hp_page_ctrl,
5970 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5971
5972
5973 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5974
5975 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5976 & ~SCSI_BUS_EN));
5977
5978 WR_HARPOON(p_port+hp_scsisig, 0x00);
5979
5980
5981 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5982 & ~SCAM_EN));
5983
5984 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5985 | ACTdeassert));
5986
1da177e4 5987 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
1da177e4
LT
5988
5989 WR_HARPOON(p_port+hp_page_ctrl,
5990 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5991}
5992
5993
5994
5995/*---------------------------------------------------------------------
5996 *
47b5d69c 5997 * Function: FPT_scasid
1da177e4
LT
5998 *
5999 * Description: Assign an ID to all the SCAM devices.
6000 *
6001 *---------------------------------------------------------------------*/
6002
47b5d69c 6003static void FPT_scasid(UCHAR p_card, ULONG p_port)
1da177e4 6004{
1da177e4 6005 UCHAR temp_id_string[ID_STRING_LENGTH];
1da177e4
LT
6006
6007 UCHAR i,k,scam_id;
6008 UCHAR crcBytes[3];
6009 PNVRamInfo pCurrNvRam;
6010 ushort_ptr pCrcBytes;
6011
47b5d69c 6012 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4 6013
47b5d69c 6014 i=0;
1da177e4
LT
6015
6016 while (!i)
6017 {
6018
6019 for (k=0; k < ID_STRING_LENGTH; k++)
6020 {
6021 temp_id_string[k] = (UCHAR) 0x00;
6022 }
6023
47b5d69c
JB
6024 FPT_scxferc(p_port,SYNC_PTRN);
6025 FPT_scxferc(p_port,ASSIGN_ID);
1da177e4 6026
47b5d69c 6027 if (!(FPT_sciso(p_port,&temp_id_string[0])))
1da177e4
LT
6028 {
6029 if(pCurrNvRam){
6030 pCrcBytes = (ushort_ptr)&crcBytes[0];
47b5d69c
JB
6031 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6032 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
1da177e4
LT
6033 temp_id_string[1] = crcBytes[2];
6034 temp_id_string[2] = crcBytes[0];
6035 temp_id_string[3] = crcBytes[1];
6036 for(k = 4; k < ID_STRING_LENGTH; k++)
6037 temp_id_string[k] = (UCHAR) 0x00;
6038 }
47b5d69c 6039 i = FPT_scmachid(p_card,temp_id_string);
1da177e4
LT
6040
6041 if (i == CLR_PRIORITY)
6042 {
47b5d69c
JB
6043 FPT_scxferc(p_port,MISC_CODE);
6044 FPT_scxferc(p_port,CLR_P_FLAG);
6045 i = 0; /*Not the last ID yet. */
1da177e4
LT
6046 }
6047
6048 else if (i != NO_ID_AVAIL)
6049 {
6050 if (i < 8 )
47b5d69c 6051 FPT_scxferc(p_port,ID_0_7);
1da177e4 6052 else
47b5d69c 6053 FPT_scxferc(p_port,ID_8_F);
1da177e4
LT
6054
6055 scam_id = (i & (UCHAR) 0x07);
6056
6057
6058 for (k=1; k < 0x08; k <<= 1)
6059 if (!( k & i ))
6060 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6061
47b5d69c 6062 FPT_scxferc(p_port,scam_id);
1da177e4 6063
47b5d69c 6064 i = 0; /*Not the last ID yet. */
1da177e4
LT
6065 }
6066 }
6067
6068 else
6069 {
47b5d69c 6070 i = 1;
1da177e4
LT
6071 }
6072
6073 } /*End while */
6074
47b5d69c
JB
6075 FPT_scxferc(p_port,SYNC_PTRN);
6076 FPT_scxferc(p_port,CFG_CMPLT);
1da177e4
LT
6077}
6078
6079
6080
6081
6082
6083/*---------------------------------------------------------------------
6084 *
47b5d69c 6085 * Function: FPT_scsel
1da177e4
LT
6086 *
6087 * Description: Select all the SCAM devices.
6088 *
6089 *---------------------------------------------------------------------*/
6090
47b5d69c 6091static void FPT_scsel(ULONG p_port)
1da177e4
LT
6092{
6093
6094 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
47b5d69c 6095 FPT_scwiros(p_port, SCSI_MSG);
1da177e4
LT
6096
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6098
6099
6100 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6101 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
6102 (UCHAR)(BIT(7)+BIT(6))));
6103
6104
6105 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
47b5d69c 6106 FPT_scwiros(p_port, SCSI_SEL);
1da177e4
LT
6107
6108 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6109 ~(UCHAR)BIT(6)));
47b5d69c 6110 FPT_scwirod(p_port, BIT(6));
1da177e4
LT
6111
6112 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6113}
6114
6115
6116
6117/*---------------------------------------------------------------------
6118 *
47b5d69c 6119 * Function: FPT_scxferc
1da177e4
LT
6120 *
6121 * Description: Handshake the p_data (DB4-0) across the bus.
6122 *
6123 *---------------------------------------------------------------------*/
6124
47b5d69c 6125static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
1da177e4
LT
6126{
6127 UCHAR curr_data, ret_data;
6128
6129 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6130
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132
6133 curr_data &= ~BIT(7);
6134
6135 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6136
47b5d69c 6137 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
1da177e4
LT
6138 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6139
6140 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
6141
6142 curr_data |= BIT(6);
6143
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145
6146 curr_data &= ~BIT(5);
6147
6148 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6149
47b5d69c 6150 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
1da177e4
LT
6151
6152 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6153 curr_data |= BIT(7);
6154
6155 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6156
6157 curr_data &= ~BIT(6);
6158
6159 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6160
47b5d69c 6161 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
1da177e4
LT
6162
6163 return(ret_data);
6164}
6165
6166
6167/*---------------------------------------------------------------------
6168 *
47b5d69c 6169 * Function: FPT_scsendi
1da177e4
LT
6170 *
6171 * Description: Transfer our Identification string to determine if we
6172 * will be the dominant master.
6173 *
6174 *---------------------------------------------------------------------*/
6175
47b5d69c 6176static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
1da177e4
LT
6177{
6178 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6179
47b5d69c 6180 defer = 0;
1da177e4
LT
6181
6182 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6183
6184 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6185
6186 if (defer)
47b5d69c 6187 ret_data = FPT_scxferc(p_port,00);
1da177e4
LT
6188
6189 else if (p_id_string[byte_cnt] & bit_cnt)
6190
47b5d69c 6191 ret_data = FPT_scxferc(p_port,02);
1da177e4
LT
6192
6193 else {
6194
47b5d69c 6195 ret_data = FPT_scxferc(p_port,01);
1da177e4 6196 if (ret_data & 02)
47b5d69c 6197 defer = 1;
1da177e4
LT
6198 }
6199
6200 if ((ret_data & 0x1C) == 0x10)
6201 return(0x00); /*End of isolation stage, we won! */
6202
6203 if (ret_data & 0x1C)
6204 return(0xFF);
6205
6206 if ((defer) && (!(ret_data & 0x1F)))
6207 return(0x01); /*End of isolation stage, we lost. */
6208
6209 } /*bit loop */
6210
6211 } /*byte loop */
6212
6213 if (defer)
6214 return(0x01); /*We lost */
6215 else
6216 return(0); /*We WON! Yeeessss! */
6217}
6218
6219
6220
6221/*---------------------------------------------------------------------
6222 *
47b5d69c 6223 * Function: FPT_sciso
1da177e4
LT
6224 *
6225 * Description: Transfer the Identification string.
6226 *
6227 *---------------------------------------------------------------------*/
6228
47b5d69c 6229static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
1da177e4
LT
6230{
6231 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
6232
6233 the_data = 0;
6234
6235 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6236
6237 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6238
47b5d69c 6239 ret_data = FPT_scxferc(p_port,0);
1da177e4
LT
6240
6241 if (ret_data & 0xFC)
6242 return(0xFF);
6243
6244 else {
6245
6246 the_data <<= 1;
6247 if (ret_data & BIT(1)) {
6248 the_data |= 1;
6249 }
6250 }
6251
6252 if ((ret_data & 0x1F) == 0)
6253 {
6254/*
6255 if(bit_cnt != 0 || bit_cnt != 8)
6256 {
6257 byte_cnt = 0;
6258 bit_cnt = 0;
47b5d69c
JB
6259 FPT_scxferc(p_port, SYNC_PTRN);
6260 FPT_scxferc(p_port, ASSIGN_ID);
1da177e4
LT
6261 continue;
6262 }
6263*/
6264 if (byte_cnt)
6265 return(0x00);
6266 else
6267 return(0xFF);
6268 }
6269
6270 } /*bit loop */
6271
6272 p_id_string[byte_cnt] = the_data;
6273
6274 } /*byte loop */
6275
6276 return(0);
6277}
6278
6279
6280
6281/*---------------------------------------------------------------------
6282 *
47b5d69c 6283 * Function: FPT_scwirod
1da177e4
LT
6284 *
6285 * Description: Sample the SCSI data bus making sure the signal has been
6286 * deasserted for the correct number of consecutive samples.
6287 *
6288 *---------------------------------------------------------------------*/
6289
47b5d69c 6290static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
1da177e4
LT
6291{
6292 UCHAR i;
6293
6294 i = 0;
6295 while ( i < MAX_SCSI_TAR ) {
6296
6297 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6298
6299 i = 0;
6300
6301 else
6302
6303 i++;
6304
6305 }
6306}
6307
6308
6309
6310/*---------------------------------------------------------------------
6311 *
47b5d69c 6312 * Function: FPT_scwiros
1da177e4
LT
6313 *
6314 * Description: Sample the SCSI Signal lines making sure the signal has been
6315 * deasserted for the correct number of consecutive samples.
6316 *
6317 *---------------------------------------------------------------------*/
6318
47b5d69c 6319static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
1da177e4
LT
6320{
6321 UCHAR i;
6322
47b5d69c
JB
6323 i = 0;
6324 while ( i < MAX_SCSI_TAR ) {
1da177e4 6325
47b5d69c 6326 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
1da177e4 6327
47b5d69c 6328 i = 0;
1da177e4 6329
47b5d69c 6330 else
1da177e4 6331
47b5d69c 6332 i++;
1da177e4 6333
1da177e4 6334 }
47b5d69c 6335}
1da177e4 6336
1da177e4 6337
47b5d69c
JB
6338/*---------------------------------------------------------------------
6339 *
6340 * Function: FPT_scvalq
6341 *
6342 * Description: Make sure we received a valid data byte.
6343 *
6344 *---------------------------------------------------------------------*/
1da177e4 6345
47b5d69c
JB
6346static UCHAR FPT_scvalq(UCHAR p_quintet)
6347{
6348 UCHAR count;
1da177e4 6349
47b5d69c
JB
6350 for (count=1; count < 0x08; count<<=1) {
6351 if (!(p_quintet & count))
6352 p_quintet -= 0x80;
1da177e4 6353 }
47b5d69c
JB
6354
6355 if (p_quintet & 0x18)
6356 return(0);
6357
6358 else
6359 return(1);
1da177e4
LT
6360}
6361
47b5d69c 6362
1da177e4
LT
6363/*---------------------------------------------------------------------
6364 *
47b5d69c 6365 * Function: FPT_scsell
1da177e4
LT
6366 *
6367 * Description: Select the specified device ID using a selection timeout
47b5d69c
JB
6368 * less than 4ms. If somebody responds then it is a legacy
6369 * drive and this ID must be marked as such.
1da177e4
LT
6370 *
6371 *---------------------------------------------------------------------*/
6372
47b5d69c 6373static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
1da177e4 6374{
47b5d69c 6375 ULONG i;
1da177e4
LT
6376
6377 WR_HARPOON(p_port+hp_page_ctrl,
6378 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6379
6380 ARAM_ACCESS(p_port);
6381
6382 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
47b5d69c 6383 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
1da177e4
LT
6384
6385
6386 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6387 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6388 }
6389 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6390
6391 WRW_HARPOON((p_port+hp_intstat),
6392 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6393
6394 WR_HARPOON(p_port+hp_select_id, targ_id);
6395
6396 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6397 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6398 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6399
6400
6401 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6402 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6403
6404 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
47b5d69c 6405 FPT_Wait(p_port, TO_250ms);
1da177e4
LT
6406
6407 DISABLE_AUTO(p_port);
6408
6409 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6410 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6411
6412 SGRAM_ACCESS(p_port);
6413
6414 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6415
6416 WRW_HARPOON((p_port+hp_intstat),
6417 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6418
6419 WR_HARPOON(p_port+hp_page_ctrl,
6420 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6421
47b5d69c 6422 return(0); /*No legacy device */
1da177e4
LT
6423 }
6424
6425 else {
6426
6427 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6428 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6429 {
6430 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6431 ACCEPT_MSG(p_port);
6432 }
6433 }
6434
6435 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6436
6437 WR_HARPOON(p_port+hp_page_ctrl,
6438 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6439
47b5d69c 6440 return(1); /*Found one of them oldies! */
1da177e4
LT
6441 }
6442}
1da177e4
LT
6443
6444/*---------------------------------------------------------------------
6445 *
47b5d69c 6446 * Function: FPT_scwtsel
1da177e4
LT
6447 *
6448 * Description: Wait to be selected by another SCAM initiator.
6449 *
6450 *---------------------------------------------------------------------*/
6451
47b5d69c 6452static void FPT_scwtsel(ULONG p_port)
1da177e4
LT
6453{
6454 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6455}
6456
6457
6458/*---------------------------------------------------------------------
6459 *
47b5d69c 6460 * Function: FPT_inisci
1da177e4
LT
6461 *
6462 * Description: Setup the data Structure with the info from the EEPROM.
6463 *
6464 *---------------------------------------------------------------------*/
6465
47b5d69c 6466static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
1da177e4
LT
6467{
6468 UCHAR i,k,max_id;
6469 USHORT ee_data;
6470 PNVRamInfo pCurrNvRam;
6471
47b5d69c 6472 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
1da177e4
LT
6473
6474 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6475 max_id = 0x08;
6476
6477 else
6478 max_id = 0x10;
6479
6480 if(pCurrNvRam){
6481 for(i = 0; i < max_id; i++){
6482
6483 for(k = 0; k < 4; k++)
47b5d69c 6484 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
1da177e4 6485 for(k = 4; k < ID_STRING_LENGTH; k++)
47b5d69c 6486 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
1da177e4 6487
47b5d69c
JB
6488 if(FPT_scamInfo[i].id_string[0] == 0x00)
6489 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4 6490 else
47b5d69c 6491 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6492
6493 }
6494 }else {
6495 for (i=0; i < max_id; i++)
6496 {
6497 for (k=0; k < ID_STRING_LENGTH; k+=2)
6498 {
47b5d69c 6499 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
1da177e4 6500 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
47b5d69c 6501 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
1da177e4 6502 ee_data >>= 8;
47b5d69c 6503 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
1da177e4
LT
6504 }
6505
47b5d69c
JB
6506 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6507 (FPT_scamInfo[i].id_string[0] == 0xFF))
1da177e4 6508
47b5d69c 6509 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
1da177e4
LT
6510
6511 else
47b5d69c 6512 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
1da177e4
LT
6513
6514 }
6515 }
6516 for(k = 0; k < ID_STRING_LENGTH; k++)
47b5d69c 6517 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
1da177e4
LT
6518
6519}
6520
6521/*---------------------------------------------------------------------
6522 *
47b5d69c 6523 * Function: FPT_scmachid
1da177e4
LT
6524 *
6525 * Description: Match the Device ID string with our values stored in
6526 * the EEPROM.
6527 *
6528 *---------------------------------------------------------------------*/
6529
47b5d69c 6530static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
1da177e4
LT
6531{
6532
6533 UCHAR i,k,match;
6534
6535
6536 for (i=0; i < MAX_SCSI_TAR; i++) {
6537
47b5d69c 6538 match = 1;
1da177e4
LT
6539
6540 for (k=0; k < ID_STRING_LENGTH; k++)
6541 {
47b5d69c
JB
6542 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6543 match = 0;
1da177e4
LT
6544 }
6545
6546 if (match)
6547 {
47b5d69c 6548 FPT_scamInfo[i].state = ID_ASSIGNED;
1da177e4
LT
6549 return(i);
6550 }
6551
1da177e4
LT
6552 }
6553
6554
6555
6556 if (p_id_string[0] & BIT(5))
6557 i = 8;
6558 else
6559 i = MAX_SCSI_TAR;
6560
6561 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6562 match = p_id_string[1] & (UCHAR) 0x1F;
6563 else
6564 match = 7;
6565
6566 while (i > 0)
6567 {
6568 i--;
6569
47b5d69c 6570 if (FPT_scamInfo[match].state == ID_UNUSED)
1da177e4
LT
6571 {
6572 for (k=0; k < ID_STRING_LENGTH; k++)
6573 {
47b5d69c 6574 FPT_scamInfo[match].id_string[k] = p_id_string[k];
1da177e4
LT
6575 }
6576
47b5d69c 6577 FPT_scamInfo[match].state = ID_ASSIGNED;
1da177e4 6578
47b5d69c
JB
6579 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6580 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
1da177e4
LT
6581 return(match);
6582
6583 }
6584
6585
6586 match--;
6587
6588 if (match == 0xFF)
6589 {
6590 if (p_id_string[0] & BIT(5))
6591 match = 7;
6592 else
6593 match = MAX_SCSI_TAR-1;
6594 }
6595 }
6596
6597
6598
6599 if (p_id_string[0] & BIT(7))
6600 {
6601 return(CLR_PRIORITY);
6602 }
6603
6604
6605 if (p_id_string[0] & BIT(5))
6606 i = 8;
6607 else
6608 i = MAX_SCSI_TAR;
6609
6610 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6611 match = p_id_string[1] & (UCHAR) 0x1F;
6612 else
6613 match = 7;
6614
6615 while (i > 0)
6616 {
6617
6618 i--;
6619
47b5d69c 6620 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
1da177e4
LT
6621 {
6622 for (k=0; k < ID_STRING_LENGTH; k++)
6623 {
47b5d69c 6624 FPT_scamInfo[match].id_string[k] = p_id_string[k];
1da177e4
LT
6625 }
6626
47b5d69c
JB
6627 FPT_scamInfo[match].id_string[0] |= BIT(7);
6628 FPT_scamInfo[match].state = ID_ASSIGNED;
6629 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6630 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
1da177e4
LT
6631 return(match);
6632
6633 }
6634
6635
6636 match--;
6637
6638 if (match == 0xFF)
6639 {
6640 if (p_id_string[0] & BIT(5))
6641 match = 7;
6642 else
6643 match = MAX_SCSI_TAR-1;
6644 }
6645 }
6646
6647 return(NO_ID_AVAIL);
6648}
6649
6650
6651/*---------------------------------------------------------------------
6652 *
47b5d69c 6653 * Function: FPT_scsavdi
1da177e4
LT
6654 *
6655 * Description: Save off the device SCAM ID strings.
6656 *
6657 *---------------------------------------------------------------------*/
6658
47b5d69c 6659static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
1da177e4
LT
6660{
6661 UCHAR i,k,max_id;
6662 USHORT ee_data,sum_data;
6663
6664
6665 sum_data = 0x0000;
6666
6667 for (i = 1; i < EE_SCAMBASE/2; i++)
6668 {
47b5d69c 6669 sum_data += FPT_utilEERead(p_port, i);
1da177e4
LT
6670 }
6671
6672
47b5d69c 6673 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
1da177e4
LT
6674
6675 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6676 max_id = 0x08;
6677
6678 else
6679 max_id = 0x10;
6680
6681 for (i=0; i < max_id; i++)
6682 {
6683
6684 for (k=0; k < ID_STRING_LENGTH; k+=2)
6685 {
47b5d69c 6686 ee_data = FPT_scamInfo[i].id_string[k+1];
1da177e4 6687 ee_data <<= 8;
47b5d69c 6688 ee_data |= FPT_scamInfo[i].id_string[k];
1da177e4 6689 sum_data += ee_data;
47b5d69c 6690 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
1da177e4
LT
6691 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6692 }
6693 }
6694
6695
47b5d69c
JB
6696 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6697 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
1da177e4 6698}
1da177e4
LT
6699
6700/*---------------------------------------------------------------------
6701 *
47b5d69c 6702 * Function: FPT_XbowInit
1da177e4
LT
6703 *
6704 * Description: Setup the Xbow for normal operation.
6705 *
6706 *---------------------------------------------------------------------*/
6707
47b5d69c 6708static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
1da177e4
LT
6709{
6710UCHAR i;
6711
6712 i = RD_HARPOON(port+hp_page_ctrl);
6713 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
6714
6715 WR_HARPOON(port+hp_scsireset,0x00);
6716 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6717
6718 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6719 FIFO_CLR));
6720
6721 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6722
6723 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6724
6725 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6726 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6727
6728 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6729
47b5d69c 6730 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
1da177e4
LT
6731 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6732
6733 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
47b5d69c 6734 FPT_default_intena |= SCAM_SEL;
1da177e4 6735
47b5d69c 6736 WRW_HARPOON((port+hp_intena), FPT_default_intena);
1da177e4
LT
6737
6738 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6739
6740 /* Turn on SCSI_MODE8 for narrow cards to fix the
6741 strapping issue with the DUAL CHANNEL card */
6742 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6743 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6744
1da177e4
LT
6745 WR_HARPOON(port+hp_page_ctrl, i);
6746
6747}
6748
6749
6750/*---------------------------------------------------------------------
6751 *
47b5d69c 6752 * Function: FPT_BusMasterInit
1da177e4
LT
6753 *
6754 * Description: Initialize the BusMaster for normal operations.
6755 *
6756 *---------------------------------------------------------------------*/
6757
47b5d69c 6758static void FPT_BusMasterInit(ULONG p_port)
1da177e4
LT
6759{
6760
6761
6762 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6763 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6764
6765 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6766
6767
6768 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6769
6770 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6771
6772
1da177e4
LT
6773 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6774 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6775 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6776 ~SCATTER_EN));
6777}
6778
6779
6780/*---------------------------------------------------------------------
6781 *
47b5d69c 6782 * Function: FPT_DiagEEPROM
1da177e4
LT
6783 *
6784 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6785 * necessary.
6786 *
6787 *---------------------------------------------------------------------*/
6788
47b5d69c 6789static void FPT_DiagEEPROM(ULONG p_port)
1da177e4
LT
6790{
6791 USHORT index,temp,max_wd_cnt;
6792
6793 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6794 max_wd_cnt = EEPROM_WD_CNT;
6795 else
6796 max_wd_cnt = EEPROM_WD_CNT * 2;
6797
47b5d69c 6798 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
1da177e4
LT
6799
6800 if (temp == 0x4641) {
6801
6802 for (index = 2; index < max_wd_cnt; index++) {
6803
47b5d69c 6804 temp += FPT_utilEERead(p_port, index);
1da177e4
LT
6805
6806 }
6807
47b5d69c 6808 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
1da177e4
LT
6809
6810 return; /*EEPROM is Okay so return now! */
6811 }
6812 }
6813
6814
47b5d69c 6815 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
1da177e4
LT
6816
6817 for (index = 0; index < max_wd_cnt; index++) {
6818
47b5d69c 6819 FPT_utilEEWrite(p_port, 0x0000, index);
1da177e4
LT
6820 }
6821
6822 temp = 0;
6823
47b5d69c 6824 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
1da177e4 6825 temp += 0x4641;
47b5d69c 6826 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
1da177e4 6827 temp += 0x3920;
47b5d69c 6828 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
1da177e4 6829 temp += 0x3033;
47b5d69c 6830 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
1da177e4 6831 temp += 0x2020;
47b5d69c 6832 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
1da177e4 6833 temp += 0x70D3;
47b5d69c 6834 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
1da177e4 6835 temp += 0x0010;
47b5d69c 6836 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
1da177e4 6837 temp += 0x0003;
47b5d69c 6838 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
1da177e4
LT
6839 temp += 0x0007;
6840
47b5d69c 6841 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
1da177e4 6842 temp += 0x0000;
47b5d69c 6843 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
1da177e4 6844 temp += 0x0000;
47b5d69c 6845 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
1da177e4
LT
6846 temp += 0x0000;
6847
47b5d69c 6848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
1da177e4 6849 temp += 0x4242;
47b5d69c 6850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
1da177e4 6851 temp += 0x4242;
47b5d69c 6852 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
1da177e4 6853 temp += 0x4242;
47b5d69c 6854 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
1da177e4 6855 temp += 0x4242;
47b5d69c 6856 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
1da177e4 6857 temp += 0x4242;
47b5d69c 6858 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
1da177e4 6859 temp += 0x4242;
47b5d69c 6860 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
1da177e4 6861 temp += 0x4242;
47b5d69c 6862 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
1da177e4
LT
6863 temp += 0x4242;
6864
6865
47b5d69c 6866 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
1da177e4 6867 temp += 0x6C46;
47b5d69c 6868 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
1da177e4 6869 temp += 0x7361;
47b5d69c 6870 FPT_utilEEWrite(p_port, 0x5068, 68/2);
1da177e4 6871 temp += 0x5068;
47b5d69c 6872 FPT_utilEEWrite(p_port, 0x696F, 70/2);
1da177e4 6873 temp += 0x696F;
47b5d69c 6874 FPT_utilEEWrite(p_port, 0x746E, 72/2);
1da177e4 6875 temp += 0x746E;
47b5d69c 6876 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
1da177e4 6877 temp += 0x4C20;
47b5d69c 6878 FPT_utilEEWrite(p_port, 0x2054, 76/2);
1da177e4 6879 temp += 0x2054;
47b5d69c 6880 FPT_utilEEWrite(p_port, 0x2020, 78/2);
1da177e4
LT
6881 temp += 0x2020;
6882
6883 index = ((EE_SCAMBASE/2)+(7*16));
47b5d69c 6884 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
1da177e4
LT
6885 temp += (0x0700+TYPE_CODE0);
6886 index++;
47b5d69c 6887 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
1da177e4
LT
6888 temp += 0x5542; /* BUSLOGIC */
6889 index++;
47b5d69c 6890 FPT_utilEEWrite(p_port, 0x4C53, index);
1da177e4
LT
6891 temp += 0x4C53;
6892 index++;
47b5d69c 6893 FPT_utilEEWrite(p_port, 0x474F, index);
1da177e4
LT
6894 temp += 0x474F;
6895 index++;
47b5d69c 6896 FPT_utilEEWrite(p_port, 0x4349, index);
1da177e4
LT
6897 temp += 0x4349;
6898 index++;
47b5d69c 6899 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
1da177e4
LT
6900 temp += 0x5442; /* BT- 930 */
6901 index++;
47b5d69c 6902 FPT_utilEEWrite(p_port, 0x202D, index);
1da177e4
LT
6903 temp += 0x202D;
6904 index++;
47b5d69c 6905 FPT_utilEEWrite(p_port, 0x3339, index);
1da177e4
LT
6906 temp += 0x3339;
6907 index++; /*Serial # */
47b5d69c 6908 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
1da177e4
LT
6909 temp += 0x2030;
6910 index++;
47b5d69c 6911 FPT_utilEEWrite(p_port, 0x5453, index);
1da177e4
LT
6912 temp += 0x5453;
6913 index++;
47b5d69c 6914 FPT_utilEEWrite(p_port, 0x5645, index);
1da177e4
LT
6915 temp += 0x5645;
6916 index++;
47b5d69c 6917 FPT_utilEEWrite(p_port, 0x2045, index);
1da177e4
LT
6918 temp += 0x2045;
6919 index++;
47b5d69c 6920 FPT_utilEEWrite(p_port, 0x202F, index);
1da177e4
LT
6921 temp += 0x202F;
6922 index++;
47b5d69c 6923 FPT_utilEEWrite(p_port, 0x4F4A, index);
1da177e4
LT
6924 temp += 0x4F4A;
6925 index++;
47b5d69c 6926 FPT_utilEEWrite(p_port, 0x204E, index);
1da177e4
LT
6927 temp += 0x204E;
6928 index++;
47b5d69c 6929 FPT_utilEEWrite(p_port, 0x3539, index);
1da177e4
LT
6930 temp += 0x3539;
6931
6932
6933
47b5d69c 6934 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
1da177e4 6935
47b5d69c 6936 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
1da177e4
LT
6937
6938}
6939
1da177e4
LT
6940
6941/*---------------------------------------------------------------------
6942 *
6943 * Function: Queue Search Select
6944 *
6945 * Description: Try to find a new command to execute.
6946 *
6947 *---------------------------------------------------------------------*/
6948
47b5d69c 6949static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
1da177e4
LT
6950{
6951 UCHAR scan_ptr, lun;
6952 PSCCBMgr_tar_info currTar_Info;
6953 PSCCB pOldSccb;
6954
6955 scan_ptr = pCurrCard->scanIndex;
6956 do
6957 {
47b5d69c 6958 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
1da177e4
LT
6959 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6960 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6961 {
6962 if (currTar_Info->TarSelQ_Cnt != 0)
6963 {
6964
6965 scan_ptr++;
6966 if (scan_ptr == MAX_SCSI_TAR)
6967 scan_ptr = 0;
6968
6969 for(lun=0; lun < MAX_LUN; lun++)
6970 {
47b5d69c 6971 if(currTar_Info->TarLUNBusy[lun] == 0)
1da177e4
LT
6972 {
6973
6974 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6975 pOldSccb = NULL;
6976
6977 while((pCurrCard->currentSCCB != NULL) &&
6978 (lun != pCurrCard->currentSCCB->Lun))
6979 {
6980 pOldSccb = pCurrCard->currentSCCB;
6981 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6982 Sccb_forwardlink;
6983 }
6984 if(pCurrCard->currentSCCB == NULL)
6985 continue;
6986 if(pOldSccb != NULL)
6987 {
6988 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6989 Sccb_forwardlink;
6990 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6991 Sccb_backlink;
6992 currTar_Info->TarSelQ_Cnt--;
6993 }
6994 else
6995 {
6996 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6997
6998 if (currTar_Info->TarSelQ_Head == NULL)
6999 {
7000 currTar_Info->TarSelQ_Tail = NULL;
7001 currTar_Info->TarSelQ_Cnt = 0;
7002 }
7003 else
7004 {
7005 currTar_Info->TarSelQ_Cnt--;
7006 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7007 }
7008 }
7009 pCurrCard->scanIndex = scan_ptr;
7010
7011 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7012
7013 break;
7014 }
7015 }
7016 }
7017
7018 else
7019 {
7020 scan_ptr++;
7021 if (scan_ptr == MAX_SCSI_TAR) {
7022 scan_ptr = 0;
7023 }
7024 }
7025
7026 }
7027 else
7028 {
7029 if ((currTar_Info->TarSelQ_Cnt != 0) &&
47b5d69c 7030 (currTar_Info->TarLUNBusy[0] == 0))
1da177e4
LT
7031 {
7032
7033 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7034
7035 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7036
7037 if (currTar_Info->TarSelQ_Head == NULL)
7038 {
7039 currTar_Info->TarSelQ_Tail = NULL;
7040 currTar_Info->TarSelQ_Cnt = 0;
7041 }
7042 else
7043 {
7044 currTar_Info->TarSelQ_Cnt--;
7045 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7046 }
7047
7048 scan_ptr++;
7049 if (scan_ptr == MAX_SCSI_TAR)
7050 scan_ptr = 0;
7051
7052 pCurrCard->scanIndex = scan_ptr;
7053
7054 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7055
7056 break;
7057 }
7058
7059 else
7060 {
7061 scan_ptr++;
7062 if (scan_ptr == MAX_SCSI_TAR)
7063 {
7064 scan_ptr = 0;
7065 }
7066 }
7067 }
7068 } while (scan_ptr != pCurrCard->scanIndex);
7069}
7070
7071
7072/*---------------------------------------------------------------------
7073 *
7074 * Function: Queue Select Fail
7075 *
7076 * Description: Add the current SCCB to the head of the Queue.
7077 *
7078 *---------------------------------------------------------------------*/
7079
47b5d69c 7080static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
1da177e4
LT
7081{
7082 UCHAR thisTarg;
7083 PSCCBMgr_tar_info currTar_Info;
7084
7085 if (pCurrCard->currentSCCB != NULL)
7086 {
7087 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
47b5d69c 7088 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7089
7090 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7091
7092 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7093
7094 if (currTar_Info->TarSelQ_Cnt == 0)
7095 {
7096 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7097 }
7098
7099 else
7100 {
7101 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7102 }
7103
7104
7105 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7106
7107 pCurrCard->currentSCCB = NULL;
7108 currTar_Info->TarSelQ_Cnt++;
7109 }
7110}
7111/*---------------------------------------------------------------------
7112 *
7113 * Function: Queue Command Complete
7114 *
7115 * Description: Call the callback function with the current SCCB.
7116 *
7117 *---------------------------------------------------------------------*/
7118
47b5d69c
JB
7119static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7120 UCHAR p_card)
1da177e4
LT
7121{
7122
1da177e4
LT
7123 UCHAR i, SCSIcmd;
7124 CALL_BK_FN callback;
7125 PSCCBMgr_tar_info currTar_Info;
7126
7127 SCSIcmd = p_sccb->Cdb[0];
7128
7129
7130 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7131
7132 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7133 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7134 (p_sccb->TargetStatus != SSCHECK))
7135
7136 if ((SCSIcmd == SCSI_READ) ||
7137 (SCSIcmd == SCSI_WRITE) ||
7138 (SCSIcmd == SCSI_READ_EXTENDED) ||
7139 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7140 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7141 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7142 (pCurrCard->globalFlags & F_NO_FILTER)
7143 )
7144 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7145 }
7146
7147
7148 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7149 {
7150 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7151 p_sccb->SccbStatus = SCCB_ERROR;
7152 else
7153 p_sccb->SccbStatus = SCCB_SUCCESS;
7154 }
7155
7156 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7157
7158 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7159 for (i=0; i < 6; i++) {
7160 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7161 }
7162 }
7163
7164 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7165 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7166
47b5d69c 7167 FPT_utilUpdateResidual(p_sccb);
1da177e4
LT
7168 }
7169
7170 pCurrCard->cmdCounter--;
7171 if (!pCurrCard->cmdCounter) {
7172
7173 if (pCurrCard->globalFlags & F_GREEN_PC) {
7174 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7175 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7176 }
7177
7178 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7179 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7180
7181 }
7182
7183 if(pCurrCard->discQCount != 0)
7184 {
47b5d69c 7185 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4
LT
7186 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7187 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7188 {
7189 pCurrCard->discQCount--;
7190 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7191 }
7192 else
7193 {
7194 if(p_sccb->Sccb_tag)
7195 {
7196 pCurrCard->discQCount--;
7197 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7198 }else
7199 {
7200 pCurrCard->discQCount--;
7201 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7202 }
7203 }
7204
7205 }
7206
7207 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7208 callback(p_sccb);
7209 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7210 pCurrCard->currentSCCB = NULL;
7211}
1da177e4
LT
7212
7213
7214/*---------------------------------------------------------------------
7215 *
7216 * Function: Queue Disconnect
7217 *
7218 * Description: Add SCCB to our disconnect array.
7219 *
7220 *---------------------------------------------------------------------*/
47b5d69c 7221static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
1da177e4
LT
7222{
7223 PSCCBMgr_tar_info currTar_Info;
7224
47b5d69c 7225 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
1da177e4 7226
47b5d69c 7227 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
1da177e4
LT
7228 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7229 {
47b5d69c 7230 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
1da177e4
LT
7231 }
7232 else
7233 {
7234 if (p_sccb->Sccb_tag)
7235 {
47b5d69c
JB
7236 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7237 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7238 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
1da177e4
LT
7239 }else
7240 {
47b5d69c 7241 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
1da177e4
LT
7242 }
7243 }
47b5d69c 7244 FPT_BL_Card[p_card].currentSCCB = NULL;
1da177e4
LT
7245}
7246
7247
7248/*---------------------------------------------------------------------
7249 *
7250 * Function: Queue Flush SCCB
7251 *
7252 * Description: Flush all SCCB's back to the host driver for this target.
7253 *
7254 *---------------------------------------------------------------------*/
7255
47b5d69c 7256static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
1da177e4
LT
7257{
7258 UCHAR qtag,thisTarg;
7259 PSCCB currSCCB;
7260 PSCCBMgr_tar_info currTar_Info;
7261
47b5d69c 7262 currSCCB = FPT_BL_Card[p_card].currentSCCB;
1da177e4
LT
7263 if(currSCCB != NULL)
7264 {
7265 thisTarg = (UCHAR)currSCCB->TargID;
47b5d69c 7266 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7267
7268 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7269
47b5d69c
JB
7270 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7271 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
1da177e4
LT
7272 {
7273
47b5d69c 7274 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
1da177e4 7275
47b5d69c 7276 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
1da177e4 7277
47b5d69c 7278 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
7279 currTar_Info->TarTagQ_Cnt--;
7280
7281 }
7282 }
7283 }
7284
7285}
7286
7287/*---------------------------------------------------------------------
7288 *
7289 * Function: Queue Flush Target SCCB
7290 *
7291 * Description: Flush all SCCB's back to the host driver for this target.
7292 *
7293 *---------------------------------------------------------------------*/
7294
47b5d69c
JB
7295static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7296 UCHAR error_code)
1da177e4
LT
7297{
7298 UCHAR qtag;
7299 PSCCBMgr_tar_info currTar_Info;
7300
47b5d69c 7301 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
1da177e4
LT
7302
7303 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7304
47b5d69c
JB
7305 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7306 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
1da177e4
LT
7307 {
7308
47b5d69c 7309 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
1da177e4 7310
47b5d69c 7311 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
1da177e4 7312
47b5d69c 7313 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
1da177e4
LT
7314 currTar_Info->TarTagQ_Cnt--;
7315
7316 }
7317 }
7318
7319}
7320
7321
7322
7323
7324
47b5d69c 7325static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
1da177e4
LT
7326{
7327 PSCCBMgr_tar_info currTar_Info;
47b5d69c 7328 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4
LT
7329
7330 p_SCCB->Sccb_forwardlink = NULL;
7331
7332 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7333
7334 if (currTar_Info->TarSelQ_Cnt == 0) {
7335
7336 currTar_Info->TarSelQ_Head = p_SCCB;
7337 }
7338
7339 else {
7340
7341 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7342 }
7343
7344
7345 currTar_Info->TarSelQ_Tail = p_SCCB;
7346 currTar_Info->TarSelQ_Cnt++;
7347}
7348
7349
7350/*---------------------------------------------------------------------
7351 *
7352 * Function: Queue Find SCCB
7353 *
7354 * Description: Search the target select Queue for this SCCB, and
7355 * remove it if found.
7356 *
7357 *---------------------------------------------------------------------*/
7358
47b5d69c 7359static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
1da177e4
LT
7360{
7361 PSCCB q_ptr;
7362 PSCCBMgr_tar_info currTar_Info;
7363
47b5d69c 7364 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
1da177e4
LT
7365
7366 q_ptr = currTar_Info->TarSelQ_Head;
7367
7368 while(q_ptr != NULL) {
7369
7370 if (q_ptr == p_SCCB) {
7371
7372
7373 if (currTar_Info->TarSelQ_Head == q_ptr) {
7374
7375 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7376 }
7377
7378 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7379
7380 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7381 }
7382
7383 if (q_ptr->Sccb_forwardlink != NULL) {
7384 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7385 }
7386
7387 if (q_ptr->Sccb_backlink != NULL) {
7388 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7389 }
7390
7391 currTar_Info->TarSelQ_Cnt--;
7392
47b5d69c 7393 return(1);
1da177e4
LT
7394 }
7395
7396 else {
7397 q_ptr = q_ptr->Sccb_forwardlink;
7398 }
7399 }
7400
7401
47b5d69c 7402 return(0);
1da177e4
LT
7403
7404}
7405
7406
7407/*---------------------------------------------------------------------
7408 *
7409 * Function: Utility Update Residual Count
7410 *
7411 * Description: Update the XferCnt to the remaining byte count.
7412 * If we transferred all the data then just write zero.
7413 * If Non-SG transfer then report Total Cnt - Actual Transfer
7414 * Cnt. For SG transfers add the count fields of all
7415 * remaining SG elements, as well as any partial remaining
7416 * element.
7417 *
7418 *---------------------------------------------------------------------*/
7419
47b5d69c 7420static void FPT_utilUpdateResidual(PSCCB p_SCCB)
1da177e4
LT
7421{
7422 ULONG partial_cnt;
7423 UINT sg_index;
1da177e4 7424 ULONG *sg_ptr;
1da177e4
LT
7425
7426 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7427
7428 p_SCCB->DataLength = 0x0000;
7429 }
7430
7431 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7432
7433 partial_cnt = 0x0000;
7434
7435 sg_index = p_SCCB->Sccb_sgseg;
7436
1da177e4 7437 sg_ptr = (ULONG *)p_SCCB->DataPointer;
1da177e4
LT
7438
7439 if (p_SCCB->Sccb_SGoffset) {
7440
7441 partial_cnt = p_SCCB->Sccb_SGoffset;
7442 sg_index++;
7443 }
7444
7445 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7446 p_SCCB->DataLength ) {
7447
7448 partial_cnt += *(sg_ptr+(sg_index * 2));
7449 sg_index++;
7450 }
7451
7452 p_SCCB->DataLength = partial_cnt;
7453 }
7454
7455 else {
7456
7457 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7458 }
7459}
7460
7461
7462/*---------------------------------------------------------------------
7463 *
7464 * Function: Wait 1 Second
7465 *
7466 * Description: Wait for 1 second.
7467 *
7468 *---------------------------------------------------------------------*/
7469
47b5d69c 7470static void FPT_Wait1Second(ULONG p_port)
1da177e4
LT
7471{
7472 UCHAR i;
7473
7474 for(i=0; i < 4; i++) {
7475
47b5d69c 7476 FPT_Wait(p_port, TO_250ms);
1da177e4
LT
7477
7478 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7479 break;
7480
7481 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7482 break;
7483 }
7484}
7485
7486
7487/*---------------------------------------------------------------------
7488 *
47b5d69c 7489 * Function: FPT_Wait
1da177e4
LT
7490 *
7491 * Description: Wait the desired delay.
7492 *
7493 *---------------------------------------------------------------------*/
7494
47b5d69c 7495static void FPT_Wait(ULONG p_port, UCHAR p_delay)
1da177e4
LT
7496{
7497 UCHAR old_timer;
7498 UCHAR green_flag;
7499
7500 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7501
7502 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7503 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7504
7505 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7506 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
47b5d69c 7507 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
1da177e4
LT
7508
7509
7510 WR_HARPOON(p_port+hp_portctrl_0,
7511 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7512
7513 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7514
7515 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7516 break;
7517
7518 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7519 break;
7520 }
7521
7522 WR_HARPOON(p_port+hp_portctrl_0,
7523 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7524
7525 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
47b5d69c 7526 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
1da177e4
LT
7527
7528 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7529
7530 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7531}
7532
7533
7534/*---------------------------------------------------------------------
7535 *
7536 * Function: Enable/Disable Write to EEPROM
7537 *
7538 * Description: The EEPROM must first be enabled for writes
7539 * A total of 9 clocks are needed.
7540 *
7541 *---------------------------------------------------------------------*/
7542
47b5d69c 7543static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
1da177e4
LT
7544{
7545 UCHAR ee_value;
7546
7547 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7548
7549 if (p_mode)
7550
47b5d69c 7551 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
1da177e4
LT
7552
7553 else
7554
7555
47b5d69c 7556 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
1da177e4
LT
7557
7558 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7559 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7560}
7561
7562
7563/*---------------------------------------------------------------------
7564 *
7565 * Function: Write EEPROM
7566 *
7567 * Description: Write a word to the EEPROM at the specified
7568 * address.
7569 *
7570 *---------------------------------------------------------------------*/
7571
47b5d69c 7572static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
1da177e4
LT
7573{
7574
7575 UCHAR ee_value;
7576 USHORT i;
7577
7578 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7579 (SEE_MS | SEE_CS));
7580
7581
7582
47b5d69c 7583 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
1da177e4
LT
7584
7585
7586 ee_value |= (SEE_MS + SEE_CS);
7587
7588 for(i = 0x8000; i != 0; i>>=1) {
7589
7590 if (i & ee_data)
7591 ee_value |= SEE_DO;
7592 else
7593 ee_value &= ~SEE_DO;
7594
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 ee_value |= SEE_CLK; /* Clock data! */
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 ee_value &= ~SEE_CLK;
7601 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7602 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7603 }
7604 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7606
47b5d69c 7607 FPT_Wait(p_port, TO_10ms);
1da177e4
LT
7608
7609 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7610 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7611 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7612}
7613
7614/*---------------------------------------------------------------------
7615 *
7616 * Function: Read EEPROM
7617 *
7618 * Description: Read a word from the EEPROM at the desired
7619 * address.
7620 *
7621 *---------------------------------------------------------------------*/
7622
47b5d69c 7623static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
1da177e4
LT
7624{
7625 USHORT i, ee_data1, ee_data2;
7626
7627 i = 0;
47b5d69c 7628 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4
LT
7629 do
7630 {
47b5d69c 7631 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
1da177e4
LT
7632
7633 if(ee_data1 == ee_data2)
7634 return(ee_data1);
7635
7636 ee_data1 = ee_data2;
7637 i++;
7638
7639 }while(i < 4);
7640
7641 return(ee_data1);
7642}
7643
7644/*---------------------------------------------------------------------
7645 *
7646 * Function: Read EEPROM Original
7647 *
7648 * Description: Read a word from the EEPROM at the desired
7649 * address.
7650 *
7651 *---------------------------------------------------------------------*/
7652
47b5d69c 7653static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
1da177e4
LT
7654{
7655
7656 UCHAR ee_value;
7657 USHORT i, ee_data;
7658
7659 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7660 (SEE_MS | SEE_CS));
7661
7662
47b5d69c 7663 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
1da177e4
LT
7664
7665
7666 ee_value |= (SEE_MS + SEE_CS);
7667 ee_data = 0;
7668
7669 for(i = 1; i <= 16; i++) {
7670
7671 ee_value |= SEE_CLK; /* Clock data! */
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674 ee_value &= ~SEE_CLK;
7675 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7676 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7677
7678 ee_data <<= 1;
7679
7680 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7681 ee_data |= 1;
7682 }
7683
7684 ee_value &= ~(SEE_MS + SEE_CS);
7685 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7686 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7687
7688 return(ee_data);
7689}
7690
7691
7692/*---------------------------------------------------------------------
7693 *
7694 * Function: Send EE command and Address to the EEPROM
7695 *
7696 * Description: Transfers the correct command and sends the address
7697 * to the eeprom.
7698 *
7699 *---------------------------------------------------------------------*/
7700
47b5d69c 7701static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
1da177e4
LT
7702{
7703 UCHAR ee_value;
7704 UCHAR narrow_flg;
7705
7706 USHORT i;
7707
7708
7709 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7710
7711
7712 ee_value = SEE_MS;
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714
7715 ee_value |= SEE_CS; /* Set CS to EEPROM */
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717
7718
7719 for(i = 0x04; i != 0; i>>=1) {
7720
7721 if (i & ee_cmd)
7722 ee_value |= SEE_DO;
7723 else
7724 ee_value &= ~SEE_DO;
7725
7726 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 ee_value |= SEE_CLK; /* Clock data! */
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 ee_value &= ~SEE_CLK;
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7733 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7734 }
7735
7736
7737 if (narrow_flg)
7738 i = 0x0080;
7739
7740 else
7741 i = 0x0200;
7742
7743
7744 while (i != 0) {
7745
7746 if (i & ee_addr)
7747 ee_value |= SEE_DO;
7748 else
7749 ee_value &= ~SEE_DO;
7750
7751 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 ee_value |= SEE_CLK; /* Clock data! */
7754 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756 ee_value &= ~SEE_CLK;
7757 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7758 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7759
7760 i >>= 1;
7761 }
7762}
7763
47b5d69c 7764static USHORT FPT_CalcCrc16(UCHAR buffer[])
1da177e4
LT
7765{
7766 USHORT crc=0;
7767 int i,j;
7768 USHORT ch;
7769 for (i=0; i < ID_STRING_LENGTH; i++)
7770 {
7771 ch = (USHORT) buffer[i];
7772 for(j=0; j < 8; j++)
7773 {
7774 if ((crc ^ ch) & 1)
7775 crc = (crc >> 1) ^ CRCMASK;
7776 else
7777 crc >>= 1;
7778 ch >>= 1;
7779 }
7780 }
7781 return(crc);
7782}
7783
47b5d69c 7784static UCHAR FPT_CalcLrc(UCHAR buffer[])
1da177e4
LT
7785{
7786 int i;
7787 UCHAR lrc;
7788 lrc = 0;
7789 for(i = 0; i < ID_STRING_LENGTH; i++)
7790 lrc ^= buffer[i];
7791 return(lrc);
7792}
7793
7794
7795
7796/*
7797 The following inline definitions avoid type conflicts.
7798*/
7799
7800static inline unsigned char
7801FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7802{
7803 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7804}
7805
7806
7807static inline FlashPoint_CardHandle_T
7808FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7809{
7810 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7811}
7812
7813static inline void
7814FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7815{
7816 FlashPoint_ReleaseHostAdapter(CardHandle);
7817}
7818
7819
7820static inline void
7821FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7822{
7823 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7824}
7825
7826
7827static inline void
7828FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7829{
7830 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7831}
7832
7833
7834static inline boolean
7835FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7836{
7837 return FlashPoint_InterruptPending(CardHandle);
7838}
7839
7840
7841static inline int
7842FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7843{
7844 return FlashPoint_HandleInterrupt(CardHandle);
7845}
7846
7847
7848#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7849#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7850#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7851#define FlashPoint_StartCCB FlashPoint__StartCCB
7852#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7853#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7854#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7855
7856
1da177e4
LT
7857#else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7858
7859
7860/*
7861 Define prototypes for the FlashPoint SCCB Manager Functions.
7862*/
7863
7864extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7865extern FlashPoint_CardHandle_T
7866 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7867extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7868extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7869extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7870extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7871extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
1da177e4
LT
7872
7873
7874#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */