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