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