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