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