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