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