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