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