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