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