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