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