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