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