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