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