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