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