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