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