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