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