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