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