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