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