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