3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
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.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #ifdef CONFIG_SCSI_FLASHPOINT
24 #define CRCMASK 0xA001
26 #define FAILURE 0xFFFFFFFFL
29 typedef void (*CALL_BK_FN
) (struct sccb
*);
31 struct sccb_mgr_info
{
33 unsigned char si_present
;
34 unsigned char si_intvect
;
38 u16 si_per_targ_init_sync
;
39 u16 si_per_targ_fast_nego
;
40 u16 si_per_targ_ultra_nego
;
41 u16 si_per_targ_no_disc
;
42 u16 si_per_targ_wide_nego
;
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];
50 unsigned char si_XlatInfo
[4];
52 u32 si_secondary_range
;
55 #define SCSI_PARITY_ENA 0x0001
56 #define LOW_BYTE_TERM 0x0010
57 #define HIGH_BYTE_TERM 0x0020
58 #define BUSTYPE_PCI 0x3
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
67 #define HARPOON_FAMILY 0x02
69 /* SCCB struct used for both SCCB and UCB manager compiles!
70 * The UCB Manager treats the SCCB as it's 'native hardware structure'
75 unsigned char OperationCode
;
76 unsigned char ControlByte
;
77 unsigned char CdbLength
;
78 unsigned char RequestSenseLength
;
81 unsigned char CcbRes
[2];
82 unsigned char HostStatus
;
83 unsigned char TargetStatus
;
86 unsigned char Cdb
[12];
87 unsigned char CcbRes1
;
88 unsigned char Reserved1
;
92 CALL_BK_FN SccbCallback
; /* VOID (*SccbCallback)(); */
93 u32 SccbIOPort
; /* Identifies board base port */
94 unsigned char SccbStatus
;
95 unsigned char SCCBRes2
;
98 u32 Sccb_XferCnt
; /* actual transfer count */
100 u32 SccbVirtDataPtr
; /* virtual addr for OS/2 */
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
;
111 unsigned char Save_Cdb
[6];
112 unsigned char Save_CdbLen
;
113 unsigned char Sccb_XferState
;
119 #define SCATTER_GATHER_COMMAND 0x02
120 #define RESIDUAL_COMMAND 0x03
121 #define RESIDUAL_SG_COMMAND 0x04
122 #define RESET_COMMAND 0x81
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 */
129 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
131 #define BUS_FREE_ST 0
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 */
138 #define DATA_OUT_ST 7
140 #define DISCONNECT_ST 9
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
150 #define F_STATUSLOADED 0x01
151 #define F_DEV_SELECTED 0x04
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 */
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 */
163 #define SCCB_IN_PROCESS 0x00
164 #define SCCB_SUCCESS 0x01
165 #define SCCB_ABORT 0x02
166 #define SCCB_ERROR 0x04
168 #define ORION_FW_REV 3110
170 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
172 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
174 #define MAX_SCSI_TAR 16
176 #define LUN_MASK 0x1f
178 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
180 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
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))
189 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
190 #define SYNC_TRYING BIT(6)
191 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
193 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
194 #define WIDE_ENABLED BIT(4)
195 #define WIDE_NEGOCIATED BIT(5)
197 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
198 #define TAG_Q_TRYING BIT(2)
199 #define TAG_Q_REJECT BIT(3)
201 #define TAR_ALLOW_DISC BIT(0)
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))
208 #define EE_WIDE_SCSI BIT(7)
210 struct sccb_mgr_tar_info
{
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
];
226 unsigned char niModel
; /* Model No. of card */
227 unsigned char niCardNo
; /* Card no. */
228 u32 niBaseAddr
; /* Port Address of card */
229 unsigned char niSysConf
; /* Adapter Configuration byte -
230 Byte 16 of eeprom map */
231 unsigned char niScsiConf
; /* SCSI Configuration byte -
232 Byte 17 of eeprom map */
233 unsigned char niScamConf
; /* SCAM Configuration byte -
234 Byte 20 of eeprom map */
235 unsigned char niAdapId
; /* Host Adapter ID -
236 Byte 24 of eerpom map */
237 unsigned char niSyncTbl
[MAX_SCSI_TAR
/ 2]; /* Sync/Wide byte
239 unsigned char niScamTbl
[MAX_SCSI_TAR
][4]; /* Compressed Scam name
249 struct sccb
*currentSCCB
;
250 struct sccb_mgr_info
*cardInfo
;
254 unsigned short cmdCounter
;
255 unsigned char discQCount
;
256 unsigned char tagQ_Lst
;
257 unsigned char cardIndex
;
258 unsigned char scanIndex
;
259 unsigned char globalFlags
;
261 struct nvram_info
*pNvRamInfo
;
262 struct sccb
*discQ_Tbl
[QUEUE_DEPTH
];
266 #define F_TAG_STARTED 0x01
267 #define F_CONLUN_IO 0x02
268 #define F_DO_RENEGO 0x04
269 #define F_NO_FILTER 0x08
270 #define F_GREEN_PC 0x10
271 #define F_HOST_XFER_ACT 0x20
272 #define F_NEW_SCCB_CMD 0x40
273 #define F_UPDATE_EEPROM 0x80
275 #define ID_STRING_LENGTH 32
276 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
278 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
280 #define ASSIGN_ID 0x00
281 #define SET_P_FLAG 0x01
282 #define CFG_CMPLT 0x03
283 #define DOM_MSTR 0x0F
284 #define SYNC_PTRN 0x1F
288 #define MISC_CODE 0x14
289 #define CLR_P_FLAG 0x18
291 #define INIT_SELTD 0x01
292 #define LEVEL2_TAR 0x02
294 enum scam_id_st
{ ID0
, ID1
, ID2
, ID3
, ID4
, ID5
, ID6
, ID7
, ID8
, ID9
, ID10
, ID11
,
296 ID13
, ID14
, ID15
, ID_UNUSED
, ID_UNASSIGNED
, ID_ASSIGNED
, LEGACY
,
297 CLR_PRIORITY
, NO_ID_AVAIL
300 typedef struct SCCBscam_info
{
302 unsigned char id_string
[ID_STRING_LENGTH
];
303 enum scam_id_st state
;
307 #define SCSI_REQUEST_SENSE 0x03
308 #define SCSI_READ 0x08
309 #define SCSI_WRITE 0x0A
310 #define SCSI_START_STOP_UNIT 0x1B
311 #define SCSI_READ_EXTENDED 0x28
312 #define SCSI_WRITE_EXTENDED 0x2A
313 #define SCSI_WRITE_AND_VERIFY 0x2E
317 #define SSQ_FULL 0x28
319 #define SMCMD_COMP 0x00
321 #define SMSAVE_DATA_PTR 0x02
322 #define SMREST_DATA_PTR 0x03
325 #define SMREJECT 0x07
327 #define SMPARITY 0x09
328 #define SMDEV_RESET 0x0C
329 #define SMABORT_TAG 0x0D
330 #define SMINIT_RECOVERY 0x0F
331 #define SMREL_RECOVERY 0x10
334 #define DISC_PRIV 0x40
340 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
342 #define SIX_BYTE_CMD 0x06
343 #define TWELVE_BYTE_CMD 0x0C
346 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
348 #define EEPROM_WD_CNT 256
350 #define EEPROM_CHECK_SUM 0
351 #define FW_SIGNATURE 2
352 #define MODEL_NUMB_0 4
353 #define MODEL_NUMB_2 6
354 #define MODEL_NUMB_4 8
355 #define SYSTEM_CONFIG 16
356 #define SCSI_CONFIG 17
357 #define BIOS_CONFIG 18
358 #define SCAM_CONFIG 20
359 #define ADAPTER_SCSI_ID 24
361 #define IGNORE_B_SCAN 32
362 #define SEND_START_ENA 34
363 #define DEVICE_ENABLE 36
365 #define SYNC_RATE_TBL 38
366 #define SYNC_RATE_TBL01 38
367 #define SYNC_RATE_TBL23 40
368 #define SYNC_RATE_TBL45 42
369 #define SYNC_RATE_TBL67 44
370 #define SYNC_RATE_TBL89 46
371 #define SYNC_RATE_TBLab 48
372 #define SYNC_RATE_TBLcd 50
373 #define SYNC_RATE_TBLef 52
375 #define EE_SCAMBASE 256
377 #define SCAM_ENABLED BIT(2)
378 #define SCAM_LEVEL2 BIT(3)
380 #define RENEGO_ENA BIT(10)
381 #define CONNIO_ENA BIT(11)
382 #define GREEN_PC_ENA BIT(12)
384 #define AUTO_RATE_00 00
385 #define AUTO_RATE_05 01
386 #define AUTO_RATE_10 02
387 #define AUTO_RATE_20 03
389 #define WIDE_NEGO_BIT BIT(7)
390 #define DISC_ENABLE_BIT BIT(6)
392 #define hp_vendor_id_0 0x00 /* LSB */
393 #define ORION_VEND_0 0x4B
395 #define hp_vendor_id_1 0x01 /* MSB */
396 #define ORION_VEND_1 0x10
398 #define hp_device_id_0 0x02 /* LSB */
399 #define ORION_DEV_0 0x30
401 #define hp_device_id_1 0x03 /* MSB */
402 #define ORION_DEV_1 0x81
404 /* Sub Vendor ID and Sub Device ID only available in
405 Harpoon Version 2 and higher */
407 #define hp_sub_device_id_0 0x06 /* LSB */
409 #define hp_semaphore 0x0C
410 #define SCCB_MGR_ACTIVE BIT(0)
411 #define TICKLE_ME BIT(1)
412 #define SCCB_MGR_PRESENT BIT(3)
413 #define BIOS_IN_USE BIT(4)
415 #define hp_sys_ctrl 0x0F
417 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
418 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
419 #define HALT_MACH BIT(3) /*Halt State Machine */
420 #define HARD_ABORT BIT(4) /*Hard Abort */
422 #define hp_host_blk_cnt 0x13
424 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
426 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
428 #define hp_int_mask 0x17
430 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
431 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
433 #define hp_xfer_cnt_lo 0x18
434 #define hp_xfer_cnt_hi 0x1A
435 #define hp_xfer_cmd 0x1B
437 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
438 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
440 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
442 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
444 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
446 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
447 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
449 #define hp_host_addr_lo 0x1C
450 #define hp_host_addr_hmi 0x1E
452 #define hp_ee_ctrl 0x22
454 #define EXT_ARB_ACK BIT(7)
455 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
456 #define SEE_MS BIT(5)
457 #define SEE_CS BIT(3)
458 #define SEE_CLK BIT(2)
459 #define SEE_DO BIT(1)
460 #define SEE_DI BIT(0)
463 #define EE_WRITE 0x05
465 #define EWEN_ADDR 0x03C0
467 #define EWDS_ADDR 0x0000
469 #define hp_bm_ctrl 0x26
471 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
472 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
473 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
474 #define FAST_SINGLE BIT(6) /*?? */
476 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
478 #define hp_sg_addr 0x28
479 #define hp_page_ctrl 0x29
481 #define SCATTER_EN BIT(0)
482 #define SGRAM_ARAM BIT(1)
483 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
484 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
486 #define hp_pci_stat_cfg 0x2D
488 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
490 #define hp_rev_num 0x33
492 #define hp_stack_data 0x34
493 #define hp_stack_addr 0x35
495 #define hp_ext_status 0x36
497 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
498 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
499 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
500 #define CMD_ABORTED BIT(4) /*Command aborted */
501 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
502 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
503 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
504 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
505 BM_PARITY_ERR | PIO_OVERRUN)
507 #define hp_int_status 0x37
509 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
510 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
511 #define INT_ASSERTED BIT(5) /* */
513 #define hp_fifo_cnt 0x38
515 #define hp_intena 0x40
518 #define PROG_HLT BIT(6)
519 #define PARITY BIT(5)
522 #define SCAM_SEL BIT(2)
524 #define TIMEOUT BIT(0)
525 #define BUS_FREE BIT(15)
526 #define XFER_CNT_0 BIT(14)
527 #define PHASE BIT(13)
528 #define IUNKWN BIT(12)
529 #define ICMD_COMP BIT(11)
530 #define ITICKLE BIT(10)
531 #define IDO_STRT BIT(9)
532 #define ITAR_DISC BIT(8)
533 #define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
534 #define CLR_ALL_INT 0xFFFF
535 #define CLR_ALL_INT_1 0xFF00
537 #define hp_intstat 0x42
539 #define hp_scsisig 0x44
541 #define SCSI_SEL BIT(7)
542 #define SCSI_BSY BIT(6)
543 #define SCSI_REQ BIT(5)
544 #define SCSI_ACK BIT(4)
545 #define SCSI_ATN BIT(3)
546 #define SCSI_CD BIT(2)
547 #define SCSI_MSG BIT(1)
548 #define SCSI_IOBIT BIT(0)
550 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
551 #define S_MSGO_PH (BIT(2)+BIT(1) )
552 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
553 #define S_DATAI_PH ( BIT(0))
554 #define S_DATAO_PH 0x00
555 #define S_ILL_PH ( BIT(1) )
557 #define hp_scsictrl_0 0x45
559 #define SEL_TAR BIT(6)
560 #define ENA_ATN BIT(4)
561 #define ENA_RESEL BIT(2)
562 #define SCSI_RST BIT(1)
563 #define ENA_SCAM_SEL BIT(0)
565 #define hp_portctrl_0 0x46
567 #define SCSI_PORT BIT(7)
568 #define SCSI_INBIT BIT(6)
569 #define DMA_PORT BIT(5)
570 #define DMA_RD BIT(4)
571 #define HOST_PORT BIT(3)
572 #define HOST_WRT BIT(2)
573 #define SCSI_BUS_EN BIT(1)
574 #define START_TO BIT(0)
576 #define hp_scsireset 0x47
578 #define SCSI_INI BIT(6)
579 #define SCAM_EN BIT(5)
580 #define DMA_RESET BIT(3)
581 #define HPSCSI_RESET BIT(2)
582 #define PROG_RESET BIT(1)
583 #define FIFO_CLR BIT(0)
585 #define hp_xfercnt_0 0x48
586 #define hp_xfercnt_2 0x4A
588 #define hp_fifodata_0 0x4C
589 #define hp_addstat 0x4E
591 #define SCAM_TIMER BIT(7)
592 #define SCSI_MODE8 BIT(3)
593 #define SCSI_PAR_ERR BIT(0)
595 #define hp_prgmcnt_0 0x4F
597 #define hp_selfid_0 0x50
598 #define hp_selfid_1 0x51
599 #define hp_arb_id 0x52
601 #define hp_select_id 0x53
603 #define hp_synctarg_base 0x54
604 #define hp_synctarg_12 0x54
605 #define hp_synctarg_13 0x55
606 #define hp_synctarg_14 0x56
607 #define hp_synctarg_15 0x57
609 #define hp_synctarg_8 0x58
610 #define hp_synctarg_9 0x59
611 #define hp_synctarg_10 0x5A
612 #define hp_synctarg_11 0x5B
614 #define hp_synctarg_4 0x5C
615 #define hp_synctarg_5 0x5D
616 #define hp_synctarg_6 0x5E
617 #define hp_synctarg_7 0x5F
619 #define hp_synctarg_0 0x60
620 #define hp_synctarg_1 0x61
621 #define hp_synctarg_2 0x62
622 #define hp_synctarg_3 0x63
624 #define NARROW_SCSI BIT(4)
625 #define DEFAULT_OFFSET 0x0F
627 #define hp_autostart_0 0x64
628 #define hp_autostart_1 0x65
629 #define hp_autostart_3 0x67
631 #define AUTO_IMMED BIT(5)
632 #define SELECT BIT(6)
633 #define END_DATA (BIT(7)+BIT(6))
635 #define hp_gp_reg_0 0x68
636 #define hp_gp_reg_1 0x69
637 #define hp_gp_reg_3 0x6B
639 #define hp_seltimeout 0x6C
641 #define TO_4ms 0x67 /* 3.9959ms */
643 #define TO_5ms 0x03 /* 4.9152ms */
644 #define TO_10ms 0x07 /* 11.xxxms */
645 #define TO_250ms 0x99 /* 250.68ms */
646 #define TO_290ms 0xB1 /* 289.99ms */
648 #define hp_clkctrl_0 0x6D
650 #define PWR_DWN BIT(6)
651 #define ACTdeassert BIT(4)
652 #define CLK_40MHZ (BIT(1) + BIT(0))
654 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
656 #define hp_fiforead 0x6E
657 #define hp_fifowrite 0x6F
659 #define hp_offsetctr 0x70
660 #define hp_xferstat 0x71
662 #define FIFO_EMPTY BIT(6)
664 #define hp_portctrl_1 0x72
666 #define CHK_SCSI_P BIT(3)
667 #define HOST_MODE8 BIT(0)
669 #define hp_xfer_pad 0x73
671 #define ID_UNLOCK BIT(3)
673 #define hp_scsidata_0 0x74
674 #define hp_scsidata_1 0x75
676 #define hp_aramBase 0x80
677 #define BIOS_DATA_OFFSET 0x60
678 #define BIOS_RELATIVE_CARD 0x64
680 #define AR3 (BIT(9) + BIT(8))
681 #define SDATA BIT(10)
683 #define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
685 #define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
687 #define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
689 #define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
691 #define ADATA_OUT 0x00
692 #define ADATA_IN BIT(8)
693 #define ACOMMAND BIT(10)
694 #define ASTATUS (BIT(10)+BIT(8))
695 #define AMSG_OUT (BIT(10)+BIT(9))
696 #define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
698 #define BRH_OP BIT(13) /* Branch */
702 #define NOT_EQ BIT(9)
704 #define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
706 #define FIFO_0 BIT(10)
708 #define MPM_OP BIT(15) /* Match phase and move data */
710 #define MRR_OP BIT(14) /* Move DReg. to Reg. */
712 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
716 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
718 #define RAT_OP (BIT(14)+BIT(13)+BIT(11))
720 #define SSI_OP (BIT(15)+BIT(11))
722 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
723 #define SSI_IDO_STRT (IDO_STRT >> 8)
725 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
726 #define SSI_ITICKLE (ITICKLE >> 8)
728 #define SSI_IUNKWN (IUNKWN >> 8)
729 #define SSI_INO_CC (IUNKWN >> 8)
730 #define SSI_IRFAIL (IUNKWN >> 8)
732 #define NP 0x10 /*Next Phase */
733 #define NTCMD 0x02 /*Non- Tagged Command start */
734 #define CMDPZ 0x04 /*Command phase */
735 #define DINT 0x12 /*Data Out/In interrupt */
736 #define DI 0x13 /*Data Out */
737 #define DC 0x19 /*Disconnect Message */
738 #define ST 0x1D /*Status Phase */
739 #define UNKNWN 0x24 /*Unknown bus action */
740 #define CC 0x25 /*Command Completion failure */
741 #define TICK 0x26 /*New target reselected us. */
742 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
744 #define ID_MSG_STRT hp_aramBase + 0x00
745 #define NON_TAG_ID_MSG hp_aramBase + 0x06
746 #define CMD_STRT hp_aramBase + 0x08
747 #define SYNC_MSGS hp_aramBase + 0x08
749 #define TAG_STRT 0x00
750 #define DISCONNECT_START 0x10/2
751 #define END_DATA_START 0x14/2
752 #define CMD_ONLY_STRT CMDPZ/2
753 #define SELCHK_STRT SELCHK/2
755 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
756 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
758 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
760 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
762 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
763 WR_HARP32(port,hp_xfercnt_0,count),\
764 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
766 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
768 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
769 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
771 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
772 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
774 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
775 WR_HARPOON(port+hp_scsireset, 0x00))
777 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
778 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
780 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
781 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
783 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
784 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
786 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
787 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
789 static unsigned char FPT_sisyncn(u32 port
, unsigned char p_card
,
790 unsigned char syncFlag
);
791 static void FPT_ssel(u32 port
, unsigned char p_card
);
792 static void FPT_sres(u32 port
, unsigned char p_card
,
793 struct sccb_card
*pCurrCard
);
794 static void FPT_shandem(u32 port
, unsigned char p_card
,
795 struct sccb
*pCurrSCCB
);
796 static void FPT_stsyncn(u32 port
, unsigned char p_card
);
797 static void FPT_sisyncr(u32 port
, unsigned char sync_pulse
,
798 unsigned char offset
);
799 static void FPT_sssyncv(u32 p_port
, unsigned char p_id
,
800 unsigned char p_sync_value
,
801 struct sccb_mgr_tar_info
*currTar_Info
);
802 static void FPT_sresb(u32 port
, unsigned char p_card
);
803 static void FPT_sxfrp(u32 p_port
, unsigned char p_card
);
804 static void FPT_schkdd(u32 port
, unsigned char p_card
);
805 static unsigned char FPT_RdStack(u32 port
, unsigned char index
);
806 static void FPT_WrStack(u32 portBase
, unsigned char index
,
808 static unsigned char FPT_ChkIfChipInitialized(u32 ioPort
);
810 static void FPT_SendMsg(u32 port
, unsigned char message
);
811 static void FPT_queueFlushTargSccb(unsigned char p_card
, unsigned char thisTarg
,
812 unsigned char error_code
);
814 static void FPT_sinits(struct sccb
*p_sccb
, unsigned char p_card
);
815 static void FPT_RNVRamData(struct nvram_info
*pNvRamInfo
);
817 static unsigned char FPT_siwidn(u32 port
, unsigned char p_card
);
818 static void FPT_stwidn(u32 port
, unsigned char p_card
);
819 static void FPT_siwidr(u32 port
, unsigned char width
);
821 static void FPT_queueSelectFail(struct sccb_card
*pCurrCard
,
822 unsigned char p_card
);
823 static void FPT_queueDisconnect(struct sccb
*p_SCCB
, unsigned char p_card
);
824 static void FPT_queueCmdComplete(struct sccb_card
*pCurrCard
,
825 struct sccb
*p_SCCB
, unsigned char p_card
);
826 static void FPT_queueSearchSelect(struct sccb_card
*pCurrCard
,
827 unsigned char p_card
);
828 static void FPT_queueFlushSccb(unsigned char p_card
, unsigned char error_code
);
829 static void FPT_queueAddSccb(struct sccb
*p_SCCB
, unsigned char card
);
830 static unsigned char FPT_queueFindSccb(struct sccb
*p_SCCB
,
831 unsigned char p_card
);
832 static void FPT_utilUpdateResidual(struct sccb
*p_SCCB
);
833 static unsigned short FPT_CalcCrc16(unsigned char buffer
[]);
834 static unsigned char FPT_CalcLrc(unsigned char buffer
[]);
836 static void FPT_Wait1Second(u32 p_port
);
837 static void FPT_Wait(u32 p_port
, unsigned char p_delay
);
838 static void FPT_utilEEWriteOnOff(u32 p_port
, unsigned char p_mode
);
839 static void FPT_utilEEWrite(u32 p_port
, unsigned short ee_data
,
840 unsigned short ee_addr
);
841 static unsigned short FPT_utilEERead(u32 p_port
,
842 unsigned short ee_addr
);
843 static unsigned short FPT_utilEEReadOrg(u32 p_port
,
844 unsigned short ee_addr
);
845 static void FPT_utilEESendCmdAddr(u32 p_port
, unsigned char ee_cmd
,
846 unsigned short ee_addr
);
848 static void FPT_phaseDataOut(u32 port
, unsigned char p_card
);
849 static void FPT_phaseDataIn(u32 port
, unsigned char p_card
);
850 static void FPT_phaseCommand(u32 port
, unsigned char p_card
);
851 static void FPT_phaseStatus(u32 port
, unsigned char p_card
);
852 static void FPT_phaseMsgOut(u32 port
, unsigned char p_card
);
853 static void FPT_phaseMsgIn(u32 port
, unsigned char p_card
);
854 static void FPT_phaseIllegal(u32 port
, unsigned char p_card
);
856 static void FPT_phaseDecode(u32 port
, unsigned char p_card
);
857 static void FPT_phaseChkFifo(u32 port
, unsigned char p_card
);
858 static void FPT_phaseBusFree(u32 p_port
, unsigned char p_card
);
860 static void FPT_XbowInit(u32 port
, unsigned char scamFlg
);
861 static void FPT_BusMasterInit(u32 p_port
);
862 static void FPT_DiagEEPROM(u32 p_port
);
864 static void FPT_dataXferProcessor(u32 port
,
865 struct sccb_card
*pCurrCard
);
866 static void FPT_busMstrSGDataXferStart(u32 port
,
867 struct sccb
*pCurrSCCB
);
868 static void FPT_busMstrDataXferStart(u32 port
,
869 struct sccb
*pCurrSCCB
);
870 static void FPT_hostDataXferAbort(u32 port
, unsigned char p_card
,
871 struct sccb
*pCurrSCCB
);
872 static void FPT_hostDataXferRestart(struct sccb
*currSCCB
);
874 static unsigned char FPT_SccbMgr_bad_isr(u32 p_port
,
875 unsigned char p_card
,
876 struct sccb_card
*pCurrCard
,
877 unsigned short p_int
);
879 static void FPT_SccbMgrTableInitAll(void);
880 static void FPT_SccbMgrTableInitCard(struct sccb_card
*pCurrCard
,
881 unsigned char p_card
);
882 static void FPT_SccbMgrTableInitTarget(unsigned char p_card
,
883 unsigned char target
);
885 static void FPT_scini(unsigned char p_card
, unsigned char p_our_id
,
886 unsigned char p_power_up
);
888 static int FPT_scarb(u32 p_port
, unsigned char p_sel_type
);
889 static void FPT_scbusf(u32 p_port
);
890 static void FPT_scsel(u32 p_port
);
891 static void FPT_scasid(unsigned char p_card
, u32 p_port
);
892 static unsigned char FPT_scxferc(u32 p_port
, unsigned char p_data
);
893 static unsigned char FPT_scsendi(u32 p_port
,
894 unsigned char p_id_string
[]);
895 static unsigned char FPT_sciso(u32 p_port
,
896 unsigned char p_id_string
[]);
897 static void FPT_scwirod(u32 p_port
, unsigned char p_data_bit
);
898 static void FPT_scwiros(u32 p_port
, unsigned char p_data_bit
);
899 static unsigned char FPT_scvalq(unsigned char p_quintet
);
900 static unsigned char FPT_scsell(u32 p_port
, unsigned char targ_id
);
901 static void FPT_scwtsel(u32 p_port
);
902 static void FPT_inisci(unsigned char p_card
, u32 p_port
,
903 unsigned char p_our_id
);
904 static void FPT_scsavdi(unsigned char p_card
, u32 p_port
);
905 static unsigned char FPT_scmachid(unsigned char p_card
,
906 unsigned char p_id_string
[]);
908 static void FPT_autoCmdCmplt(u32 p_port
, unsigned char p_card
);
909 static void FPT_autoLoadDefaultMap(u32 p_port
);
911 static struct sccb_mgr_tar_info FPT_sccbMgrTbl
[MAX_CARDS
][MAX_SCSI_TAR
] =
913 static struct sccb_card FPT_BL_Card
[MAX_CARDS
] = { {0} };
914 static SCCBSCAM_INFO FPT_scamInfo
[MAX_SCSI_TAR
] = { {{0}} };
915 static struct nvram_info FPT_nvRamInfo
[MAX_MB_CARDS
] = { {0} };
917 static unsigned char FPT_mbCards
= 0;
918 static unsigned char FPT_scamHAString
[] =
919 { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
920 ' ', 'B', 'T', '-', '9', '3', '0',
921 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
922 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
925 static unsigned short FPT_default_intena
= 0;
927 static void (*FPT_s_PhaseTbl
[8]) (u32
, unsigned char) = {
930 /*---------------------------------------------------------------------
932 * Function: FlashPoint_ProbeHostAdapter
934 * Description: Setup and/or Search for cards and return info to caller.
936 *---------------------------------------------------------------------*/
938 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info
*pCardInfo
)
940 static unsigned char first_time
= 1;
942 unsigned char i
, j
, id
, ScamFlg
;
943 unsigned short temp
, temp2
, temp3
, temp4
, temp5
, temp6
;
945 struct nvram_info
*pCurrNvRam
;
947 ioport
= pCardInfo
->si_baseaddr
;
949 if (RD_HARPOON(ioport
+ hp_vendor_id_0
) != ORION_VEND_0
)
952 if ((RD_HARPOON(ioport
+ hp_vendor_id_1
) != ORION_VEND_1
))
955 if ((RD_HARPOON(ioport
+ hp_device_id_0
) != ORION_DEV_0
))
958 if ((RD_HARPOON(ioport
+ hp_device_id_1
) != ORION_DEV_1
))
961 if (RD_HARPOON(ioport
+ hp_rev_num
) != 0x0f) {
963 /* For new Harpoon then check for sub_device ID LSB
964 the bits(0-3) must be all ZERO for compatible with
965 current version of SCCBMgr, else skip this Harpoon
968 if (RD_HARPOON(ioport
+ hp_sub_device_id_0
) & 0x0f)
973 FPT_SccbMgrTableInitAll();
978 if (FPT_RdStack(ioport
, 0) != 0x00) {
979 if (FPT_ChkIfChipInitialized(ioport
) == 0) {
981 WR_HARPOON(ioport
+ hp_semaphore
, 0x00);
982 FPT_XbowInit(ioport
, 0); /*Must Init the SCSI before attempting */
983 FPT_DiagEEPROM(ioport
);
985 if (FPT_mbCards
< MAX_MB_CARDS
) {
986 pCurrNvRam
= &FPT_nvRamInfo
[FPT_mbCards
];
988 pCurrNvRam
->niBaseAddr
= ioport
;
989 FPT_RNVRamData(pCurrNvRam
);
996 WR_HARPOON(ioport
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
997 WR_HARPOON(ioport
+ hp_sys_ctrl
, 0x00);
1000 pCardInfo
->si_id
= pCurrNvRam
->niAdapId
;
1004 char)(FPT_utilEERead(ioport
,
1006 2)) & (unsigned char)0x0FF);
1008 pCardInfo
->si_lun
= 0x00;
1009 pCardInfo
->si_fw_revision
= ORION_FW_REV
;
1016 for (id
= 0; id
< (16 / 2); id
++) {
1019 temp
= (unsigned short)pCurrNvRam
->niSyncTbl
[id
];
1020 temp
= ((temp
& 0x03) + ((temp
<< 4) & 0xc0)) +
1021 (((temp
<< 4) & 0x0300) + ((temp
<< 8) & 0xc000));
1024 FPT_utilEERead(ioport
,
1025 (unsigned short)((SYNC_RATE_TBL
/ 2)
1028 for (i
= 0; i
< 2; temp
>>= 8, i
++) {
1035 switch (temp
& 0x3) {
1036 case AUTO_RATE_20
: /* Synchronous, 20 mega-transfers/second */
1037 temp6
|= 0x8000; /* Fall through */
1038 case AUTO_RATE_10
: /* Synchronous, 10 mega-transfers/second */
1039 temp5
|= 0x8000; /* Fall through */
1040 case AUTO_RATE_05
: /* Synchronous, 5 mega-transfers/second */
1041 temp2
|= 0x8000; /* Fall through */
1042 case AUTO_RATE_00
: /* Asynchronous */
1046 if (temp
& DISC_ENABLE_BIT
)
1049 if (temp
& WIDE_NEGO_BIT
)
1055 pCardInfo
->si_per_targ_init_sync
= temp2
;
1056 pCardInfo
->si_per_targ_no_disc
= temp3
;
1057 pCardInfo
->si_per_targ_wide_nego
= temp4
;
1058 pCardInfo
->si_per_targ_fast_nego
= temp5
;
1059 pCardInfo
->si_per_targ_ultra_nego
= temp6
;
1062 i
= pCurrNvRam
->niSysConf
;
1065 char)(FPT_utilEERead(ioport
, (SYSTEM_CONFIG
/ 2)));
1068 ScamFlg
= pCurrNvRam
->niScamConf
;
1071 (unsigned char)FPT_utilEERead(ioport
, SCAM_CONFIG
/ 2);
1073 pCardInfo
->si_flags
= 0x0000;
1076 pCardInfo
->si_flags
|= SCSI_PARITY_ENA
;
1079 pCardInfo
->si_flags
|= SOFT_RESET
;
1082 pCardInfo
->si_flags
|= EXTENDED_TRANSLATION
;
1084 if (ScamFlg
& SCAM_ENABLED
)
1085 pCardInfo
->si_flags
|= FLAG_SCAM_ENABLED
;
1087 if (ScamFlg
& SCAM_LEVEL2
)
1088 pCardInfo
->si_flags
|= FLAG_SCAM_LEVEL2
;
1090 j
= (RD_HARPOON(ioport
+ hp_bm_ctrl
) & ~SCSI_TERM_ENA_L
);
1092 j
|= SCSI_TERM_ENA_L
;
1094 WR_HARPOON(ioport
+ hp_bm_ctrl
, j
);
1096 j
= (RD_HARPOON(ioport
+ hp_ee_ctrl
) & ~SCSI_TERM_ENA_H
);
1098 j
|= SCSI_TERM_ENA_H
;
1100 WR_HARPOON(ioport
+ hp_ee_ctrl
, j
);
1102 if (!(RD_HARPOON(ioport
+ hp_page_ctrl
) & NARROW_SCSI_CARD
))
1104 pCardInfo
->si_flags
|= SUPPORT_16TAR_32LUN
;
1106 pCardInfo
->si_card_family
= HARPOON_FAMILY
;
1107 pCardInfo
->si_bustype
= BUSTYPE_PCI
;
1110 pCardInfo
->si_card_model
[0] = '9';
1111 switch (pCurrNvRam
->niModel
& 0x0f) {
1113 pCardInfo
->si_card_model
[1] = '3';
1114 pCardInfo
->si_card_model
[2] = '0';
1117 pCardInfo
->si_card_model
[1] = '5';
1118 pCardInfo
->si_card_model
[2] = '0';
1121 pCardInfo
->si_card_model
[1] = '3';
1122 pCardInfo
->si_card_model
[2] = '2';
1125 pCardInfo
->si_card_model
[1] = '5';
1126 pCardInfo
->si_card_model
[2] = '2';
1130 temp
= FPT_utilEERead(ioport
, (MODEL_NUMB_0
/ 2));
1131 pCardInfo
->si_card_model
[0] = (unsigned char)(temp
>> 8);
1132 temp
= FPT_utilEERead(ioport
, (MODEL_NUMB_2
/ 2));
1134 pCardInfo
->si_card_model
[1] = (unsigned char)(temp
& 0x00FF);
1135 pCardInfo
->si_card_model
[2] = (unsigned char)(temp
>> 8);
1138 if (pCardInfo
->si_card_model
[1] == '3') {
1139 if (RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7))
1140 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1141 } else if (pCardInfo
->si_card_model
[2] == '0') {
1142 temp
= RD_HARPOON(ioport
+ hp_xfer_pad
);
1143 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp
& ~BIT(4)));
1144 if (RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7))
1145 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1146 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp
| BIT(4)));
1147 if (RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7))
1148 pCardInfo
->si_flags
|= HIGH_BYTE_TERM
;
1149 WR_HARPOON(ioport
+ hp_xfer_pad
, temp
);
1151 temp
= RD_HARPOON(ioport
+ hp_ee_ctrl
);
1152 temp2
= RD_HARPOON(ioport
+ hp_xfer_pad
);
1153 WR_HARPOON(ioport
+ hp_ee_ctrl
, (temp
| SEE_CS
));
1154 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp2
| BIT(4)));
1156 for (i
= 0; i
< 8; i
++) {
1158 if (!(RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7)))
1160 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp2
& ~BIT(4)));
1161 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp2
| BIT(4)));
1163 WR_HARPOON(ioport
+ hp_ee_ctrl
, temp
);
1164 WR_HARPOON(ioport
+ hp_xfer_pad
, temp2
);
1165 if (!(temp3
& BIT(7)))
1166 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1167 if (!(temp3
& BIT(6)))
1168 pCardInfo
->si_flags
|= HIGH_BYTE_TERM
;
1171 ARAM_ACCESS(ioport
);
1173 for (i
= 0; i
< 4; i
++) {
1175 pCardInfo
->si_XlatInfo
[i
] =
1176 RD_HARPOON(ioport
+ hp_aramBase
+ BIOS_DATA_OFFSET
+ i
);
1179 /* return with -1 if no sort, else return with
1180 logical card number sorted by BIOS (zero-based) */
1182 pCardInfo
->si_relative_cardnum
=
1184 char)(RD_HARPOON(ioport
+ hp_aramBase
+ BIOS_RELATIVE_CARD
) - 1);
1186 SGRAM_ACCESS(ioport
);
1188 FPT_s_PhaseTbl
[0] = FPT_phaseDataOut
;
1189 FPT_s_PhaseTbl
[1] = FPT_phaseDataIn
;
1190 FPT_s_PhaseTbl
[2] = FPT_phaseIllegal
;
1191 FPT_s_PhaseTbl
[3] = FPT_phaseIllegal
;
1192 FPT_s_PhaseTbl
[4] = FPT_phaseCommand
;
1193 FPT_s_PhaseTbl
[5] = FPT_phaseStatus
;
1194 FPT_s_PhaseTbl
[6] = FPT_phaseMsgOut
;
1195 FPT_s_PhaseTbl
[7] = FPT_phaseMsgIn
;
1197 pCardInfo
->si_present
= 0x01;
1202 /*---------------------------------------------------------------------
1204 * Function: FlashPoint_HardwareResetHostAdapter
1206 * Description: Setup adapter for normal operation (hard reset).
1208 *---------------------------------------------------------------------*/
1210 static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1213 struct sccb_card
*CurrCard
= NULL
;
1214 struct nvram_info
*pCurrNvRam
;
1215 unsigned char i
, j
, thisCard
, ScamFlg
;
1216 unsigned short temp
, sync_bit_map
, id
;
1219 ioport
= pCardInfo
->si_baseaddr
;
1221 for (thisCard
= 0; thisCard
<= MAX_CARDS
; thisCard
++) {
1223 if (thisCard
== MAX_CARDS
)
1224 return (void *)FAILURE
;
1226 if (FPT_BL_Card
[thisCard
].ioPort
== ioport
) {
1228 CurrCard
= &FPT_BL_Card
[thisCard
];
1229 FPT_SccbMgrTableInitCard(CurrCard
, thisCard
);
1233 else if (FPT_BL_Card
[thisCard
].ioPort
== 0x00) {
1235 FPT_BL_Card
[thisCard
].ioPort
= ioport
;
1236 CurrCard
= &FPT_BL_Card
[thisCard
];
1239 for (i
= 0; i
< FPT_mbCards
; i
++) {
1240 if (CurrCard
->ioPort
==
1241 FPT_nvRamInfo
[i
].niBaseAddr
)
1242 CurrCard
->pNvRamInfo
=
1245 FPT_SccbMgrTableInitCard(CurrCard
, thisCard
);
1246 CurrCard
->cardIndex
= thisCard
;
1247 CurrCard
->cardInfo
= pCardInfo
;
1253 pCurrNvRam
= CurrCard
->pNvRamInfo
;
1256 ScamFlg
= pCurrNvRam
->niScamConf
;
1259 (unsigned char)FPT_utilEERead(ioport
, SCAM_CONFIG
/ 2);
1262 FPT_BusMasterInit(ioport
);
1263 FPT_XbowInit(ioport
, ScamFlg
);
1265 FPT_autoLoadDefaultMap(ioport
);
1267 for (i
= 0, id
= 0x01; i
!= pCardInfo
->si_id
; i
++, id
<<= 1) {
1270 WR_HARPOON(ioport
+ hp_selfid_0
, id
);
1271 WR_HARPOON(ioport
+ hp_selfid_1
, 0x00);
1272 WR_HARPOON(ioport
+ hp_arb_id
, pCardInfo
->si_id
);
1273 CurrCard
->ourId
= pCardInfo
->si_id
;
1275 i
= (unsigned char)pCardInfo
->si_flags
;
1276 if (i
& SCSI_PARITY_ENA
)
1277 WR_HARPOON(ioport
+ hp_portctrl_1
, (HOST_MODE8
| CHK_SCSI_P
));
1279 j
= (RD_HARPOON(ioport
+ hp_bm_ctrl
) & ~SCSI_TERM_ENA_L
);
1280 if (i
& LOW_BYTE_TERM
)
1281 j
|= SCSI_TERM_ENA_L
;
1282 WR_HARPOON(ioport
+ hp_bm_ctrl
, j
);
1284 j
= (RD_HARPOON(ioport
+ hp_ee_ctrl
) & ~SCSI_TERM_ENA_H
);
1285 if (i
& HIGH_BYTE_TERM
)
1286 j
|= SCSI_TERM_ENA_H
;
1287 WR_HARPOON(ioport
+ hp_ee_ctrl
, j
);
1289 if (!(pCardInfo
->si_flags
& SOFT_RESET
)) {
1291 FPT_sresb(ioport
, thisCard
);
1293 FPT_scini(thisCard
, pCardInfo
->si_id
, 0);
1296 if (pCardInfo
->si_flags
& POST_ALL_UNDERRRUNS
)
1297 CurrCard
->globalFlags
|= F_NO_FILTER
;
1300 if (pCurrNvRam
->niSysConf
& 0x10)
1301 CurrCard
->globalFlags
|= F_GREEN_PC
;
1303 if (FPT_utilEERead(ioport
, (SYSTEM_CONFIG
/ 2)) & GREEN_PC_ENA
)
1304 CurrCard
->globalFlags
|= F_GREEN_PC
;
1307 /* Set global flag to indicate Re-Negotiation to be done on all
1310 if (pCurrNvRam
->niScsiConf
& 0x04)
1311 CurrCard
->globalFlags
|= F_DO_RENEGO
;
1313 if (FPT_utilEERead(ioport
, (SCSI_CONFIG
/ 2)) & RENEGO_ENA
)
1314 CurrCard
->globalFlags
|= F_DO_RENEGO
;
1318 if (pCurrNvRam
->niScsiConf
& 0x08)
1319 CurrCard
->globalFlags
|= F_CONLUN_IO
;
1321 if (FPT_utilEERead(ioport
, (SCSI_CONFIG
/ 2)) & CONNIO_ENA
)
1322 CurrCard
->globalFlags
|= F_CONLUN_IO
;
1325 temp
= pCardInfo
->si_per_targ_no_disc
;
1327 for (i
= 0, id
= 1; i
< MAX_SCSI_TAR
; i
++, id
<<= 1) {
1330 FPT_sccbMgrTbl
[thisCard
][i
].TarStatus
|= TAR_ALLOW_DISC
;
1333 sync_bit_map
= 0x0001;
1335 for (id
= 0; id
< (MAX_SCSI_TAR
/ 2); id
++) {
1338 temp
= (unsigned short)pCurrNvRam
->niSyncTbl
[id
];
1339 temp
= ((temp
& 0x03) + ((temp
<< 4) & 0xc0)) +
1340 (((temp
<< 4) & 0x0300) + ((temp
<< 8) & 0xc000));
1343 FPT_utilEERead(ioport
,
1344 (unsigned short)((SYNC_RATE_TBL
/ 2)
1347 for (i
= 0; i
< 2; temp
>>= 8, i
++) {
1349 if (pCardInfo
->si_per_targ_init_sync
& sync_bit_map
) {
1351 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1353 (unsigned char)temp
;
1357 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1360 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1362 (unsigned char)(temp
& ~EE_SYNC_MASK
);
1365 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1368 if (pCardInfo
->si_per_targ_wide_nego
& sync_bit_map
) {
1370 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1376 else { /* NARROW SCSI */
1377 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1387 WR_HARPOON((ioport
+ hp_semaphore
),
1388 (unsigned char)(RD_HARPOON((ioport
+ hp_semaphore
)) |
1391 return (void *)CurrCard
;
1394 static void FlashPoint_ReleaseHostAdapter(void *pCurrCard
)
1401 struct nvram_info
*pCurrNvRam
;
1403 pCurrNvRam
= ((struct sccb_card
*)pCurrCard
)->pNvRamInfo
;
1406 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 0, pCurrNvRam
->niModel
);
1407 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 1, pCurrNvRam
->niSysConf
);
1408 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 2, pCurrNvRam
->niScsiConf
);
1409 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 3, pCurrNvRam
->niScamConf
);
1410 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 4, pCurrNvRam
->niAdapId
);
1412 for (i
= 0; i
< MAX_SCSI_TAR
/ 2; i
++)
1413 FPT_WrStack(pCurrNvRam
->niBaseAddr
,
1414 (unsigned char)(i
+ 5),
1415 pCurrNvRam
->niSyncTbl
[i
]);
1417 portBase
= pCurrNvRam
->niBaseAddr
;
1419 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
1420 regOffset
= hp_aramBase
+ 64 + i
* 4;
1421 pScamTbl
= (u32
*)&pCurrNvRam
->niScamTbl
[i
];
1422 scamData
= *pScamTbl
;
1423 WR_HARP32(portBase
, regOffset
, scamData
);
1427 FPT_WrStack(((struct sccb_card
*)pCurrCard
)->ioPort
, 0, 0);
1431 static void FPT_RNVRamData(struct nvram_info
*pNvRamInfo
)
1439 pNvRamInfo
->niModel
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 0);
1440 pNvRamInfo
->niSysConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 1);
1441 pNvRamInfo
->niScsiConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 2);
1442 pNvRamInfo
->niScamConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 3);
1443 pNvRamInfo
->niAdapId
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 4);
1445 for (i
= 0; i
< MAX_SCSI_TAR
/ 2; i
++)
1446 pNvRamInfo
->niSyncTbl
[i
] =
1447 FPT_RdStack(pNvRamInfo
->niBaseAddr
, (unsigned char)(i
+ 5));
1449 portBase
= pNvRamInfo
->niBaseAddr
;
1451 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
1452 regOffset
= hp_aramBase
+ 64 + i
* 4;
1453 RD_HARP32(portBase
, regOffset
, scamData
);
1454 pScamTbl
= (u32
*)&pNvRamInfo
->niScamTbl
[i
];
1455 *pScamTbl
= scamData
;
1460 static unsigned char FPT_RdStack(u32 portBase
, unsigned char index
)
1462 WR_HARPOON(portBase
+ hp_stack_addr
, index
);
1463 return RD_HARPOON(portBase
+ hp_stack_data
);
1466 static void FPT_WrStack(u32 portBase
, unsigned char index
, unsigned char data
)
1468 WR_HARPOON(portBase
+ hp_stack_addr
, index
);
1469 WR_HARPOON(portBase
+ hp_stack_data
, data
);
1472 static unsigned char FPT_ChkIfChipInitialized(u32 ioPort
)
1474 if ((RD_HARPOON(ioPort
+ hp_arb_id
) & 0x0f) != FPT_RdStack(ioPort
, 4))
1476 if ((RD_HARPOON(ioPort
+ hp_clkctrl_0
) & CLKCTRL_DEFAULT
)
1479 if ((RD_HARPOON(ioPort
+ hp_seltimeout
) == TO_250ms
) ||
1480 (RD_HARPOON(ioPort
+ hp_seltimeout
) == TO_290ms
))
1486 /*---------------------------------------------------------------------
1488 * Function: FlashPoint_StartCCB
1490 * Description: Start a command pointed to by p_Sccb. When the
1491 * command is completed it will be returned via the
1492 * callback function.
1494 *---------------------------------------------------------------------*/
1495 static void FlashPoint_StartCCB(void *curr_card
, struct sccb
*p_Sccb
)
1498 unsigned char thisCard
, lun
;
1499 struct sccb
*pSaveSccb
;
1500 CALL_BK_FN callback
;
1501 struct sccb_card
*pCurrCard
= curr_card
;
1503 thisCard
= pCurrCard
->cardIndex
;
1504 ioport
= pCurrCard
->ioPort
;
1506 if ((p_Sccb
->TargID
>= MAX_SCSI_TAR
) || (p_Sccb
->Lun
>= MAX_LUN
)) {
1508 p_Sccb
->HostStatus
= SCCB_COMPLETE
;
1509 p_Sccb
->SccbStatus
= SCCB_ERROR
;
1510 callback
= (CALL_BK_FN
) p_Sccb
->SccbCallback
;
1517 FPT_sinits(p_Sccb
, thisCard
);
1519 if (!pCurrCard
->cmdCounter
) {
1520 WR_HARPOON(ioport
+ hp_semaphore
,
1521 (RD_HARPOON(ioport
+ hp_semaphore
)
1522 | SCCB_MGR_ACTIVE
));
1524 if (pCurrCard
->globalFlags
& F_GREEN_PC
) {
1525 WR_HARPOON(ioport
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
1526 WR_HARPOON(ioport
+ hp_sys_ctrl
, 0x00);
1530 pCurrCard
->cmdCounter
++;
1532 if (RD_HARPOON(ioport
+ hp_semaphore
) & BIOS_IN_USE
) {
1534 WR_HARPOON(ioport
+ hp_semaphore
,
1535 (RD_HARPOON(ioport
+ hp_semaphore
)
1537 if (p_Sccb
->OperationCode
== RESET_COMMAND
) {
1539 pCurrCard
->currentSCCB
;
1540 pCurrCard
->currentSCCB
= p_Sccb
;
1541 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1542 pCurrCard
->currentSCCB
=
1545 FPT_queueAddSccb(p_Sccb
, thisCard
);
1549 else if ((RD_HARPOON(ioport
+ hp_page_ctrl
) & G_INT_DISABLE
)) {
1551 if (p_Sccb
->OperationCode
== RESET_COMMAND
) {
1553 pCurrCard
->currentSCCB
;
1554 pCurrCard
->currentSCCB
= p_Sccb
;
1555 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1556 pCurrCard
->currentSCCB
=
1559 FPT_queueAddSccb(p_Sccb
, thisCard
);
1565 MDISABLE_INT(ioport
);
1567 if ((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
1568 ((FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].
1569 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
1573 if ((pCurrCard
->currentSCCB
== NULL
) &&
1574 (FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarSelQ_Cnt
== 0)
1575 && (FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarLUNBusy
[lun
]
1578 pCurrCard
->currentSCCB
= p_Sccb
;
1579 FPT_ssel(p_Sccb
->SccbIOPort
, thisCard
);
1584 if (p_Sccb
->OperationCode
== RESET_COMMAND
) {
1585 pSaveSccb
= pCurrCard
->currentSCCB
;
1586 pCurrCard
->currentSCCB
= p_Sccb
;
1587 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
],
1589 pCurrCard
->currentSCCB
= pSaveSccb
;
1591 FPT_queueAddSccb(p_Sccb
, thisCard
);
1595 MENABLE_INT(ioport
);
1600 /*---------------------------------------------------------------------
1602 * Function: FlashPoint_AbortCCB
1604 * Description: Abort the command pointed to by p_Sccb. When the
1605 * command is completed it will be returned via the
1606 * callback function.
1608 *---------------------------------------------------------------------*/
1609 static int FlashPoint_AbortCCB(void *pCurrCard
, struct sccb
*p_Sccb
)
1613 unsigned char thisCard
;
1614 CALL_BK_FN callback
;
1616 struct sccb
*pSaveSCCB
;
1617 struct sccb_mgr_tar_info
*currTar_Info
;
1619 ioport
= ((struct sccb_card
*)pCurrCard
)->ioPort
;
1621 thisCard
= ((struct sccb_card
*)pCurrCard
)->cardIndex
;
1623 if (!(RD_HARPOON(ioport
+ hp_page_ctrl
) & G_INT_DISABLE
)) {
1625 if (FPT_queueFindSccb(p_Sccb
, thisCard
)) {
1627 ((struct sccb_card
*)pCurrCard
)->cmdCounter
--;
1629 if (!((struct sccb_card
*)pCurrCard
)->cmdCounter
)
1630 WR_HARPOON(ioport
+ hp_semaphore
,
1631 (RD_HARPOON(ioport
+ hp_semaphore
)
1633 char)(~(SCCB_MGR_ACTIVE
|
1636 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1637 callback
= p_Sccb
->SccbCallback
;
1644 if (((struct sccb_card
*)pCurrCard
)->currentSCCB
==
1646 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1653 TID
= p_Sccb
->TargID
;
1655 if (p_Sccb
->Sccb_tag
) {
1656 MDISABLE_INT(ioport
);
1657 if (((struct sccb_card
*)pCurrCard
)->
1658 discQ_Tbl
[p_Sccb
->Sccb_tag
] ==
1660 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1661 p_Sccb
->Sccb_scsistat
=
1663 p_Sccb
->Sccb_scsimsg
=
1666 if (((struct sccb_card
*)
1667 pCurrCard
)->currentSCCB
==
1669 ((struct sccb_card
*)
1671 currentSCCB
= p_Sccb
;
1679 ((struct sccb_card
*)
1681 currentSCCB
= p_Sccb
;
1682 FPT_queueSelectFail((struct sccb_card
*)pCurrCard
, thisCard
);
1683 ((struct sccb_card
*)
1685 currentSCCB
= pSaveSCCB
;
1688 MENABLE_INT(ioport
);
1692 &FPT_sccbMgrTbl
[thisCard
][p_Sccb
->
1695 if (FPT_BL_Card
[thisCard
].
1696 discQ_Tbl
[currTar_Info
->
1697 LunDiscQ_Idx
[p_Sccb
->Lun
]]
1699 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1709 /*---------------------------------------------------------------------
1711 * Function: FlashPoint_InterruptPending
1713 * Description: Do a quick check to determine if there is a pending
1714 * interrupt for this card and disable the IRQ Pin if so.
1716 *---------------------------------------------------------------------*/
1717 static unsigned char FlashPoint_InterruptPending(void *pCurrCard
)
1721 ioport
= ((struct sccb_card
*)pCurrCard
)->ioPort
;
1723 if (RD_HARPOON(ioport
+ hp_int_status
) & INT_ASSERTED
) {
1732 /*---------------------------------------------------------------------
1734 * Function: FlashPoint_HandleInterrupt
1736 * Description: This is our entry point when an interrupt is generated
1737 * by the card and the upper level driver passes it on to
1740 *---------------------------------------------------------------------*/
1741 static int FlashPoint_HandleInterrupt(void *pcard
)
1743 struct sccb
*currSCCB
;
1744 unsigned char thisCard
, result
, bm_status
, bm_int_st
;
1745 unsigned short hp_int
;
1746 unsigned char i
, target
;
1747 struct sccb_card
*pCurrCard
= pcard
;
1750 thisCard
= pCurrCard
->cardIndex
;
1751 ioport
= pCurrCard
->ioPort
;
1753 MDISABLE_INT(ioport
);
1755 if ((bm_int_st
= RD_HARPOON(ioport
+ hp_int_status
)) & EXT_STATUS_ON
)
1756 bm_status
= RD_HARPOON(ioport
+ hp_ext_status
) &
1757 (unsigned char)BAD_EXT_STATUS
;
1761 WR_HARPOON(ioport
+ hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
1763 while ((hp_int
= RDW_HARPOON((ioport
+ hp_intstat
)) &
1764 FPT_default_intena
) | bm_status
) {
1766 currSCCB
= pCurrCard
->currentSCCB
;
1768 if (hp_int
& (FIFO
| TIMEOUT
| RESET
| SCAM_SEL
) || bm_status
) {
1770 FPT_SccbMgr_bad_isr(ioport
, thisCard
, pCurrCard
,
1772 WRW_HARPOON((ioport
+ hp_intstat
),
1773 (FIFO
| TIMEOUT
| RESET
| SCAM_SEL
));
1778 MENABLE_INT(ioport
);
1783 else if (hp_int
& ICMD_COMP
) {
1785 if (!(hp_int
& BUS_FREE
)) {
1786 /* Wait for the BusFree before starting a new command. We
1787 must also check for being reselected since the BusFree
1788 may not show up if another device reselects us in 1.5us or
1789 less. SRR Wednesday, 3/8/1995.
1792 (RDW_HARPOON((ioport
+ hp_intstat
)) &
1793 (BUS_FREE
| RSEL
))) ;
1796 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
1798 FPT_phaseChkFifo(ioport
, thisCard
);
1800 /* WRW_HARPOON((ioport+hp_intstat),
1801 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1804 WRW_HARPOON((ioport
+ hp_intstat
), CLR_ALL_INT_1
);
1806 FPT_autoCmdCmplt(ioport
, thisCard
);
1810 else if (hp_int
& ITAR_DISC
) {
1812 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
1813 FPT_phaseChkFifo(ioport
, thisCard
);
1815 if (RD_HARPOON(ioport
+ hp_gp_reg_1
) ==
1818 WR_HARPOON(ioport
+ hp_gp_reg_1
, 0x00);
1819 currSCCB
->Sccb_XferState
|= F_NO_DATA_YET
;
1821 currSCCB
->Sccb_savedATC
= currSCCB
->Sccb_ATC
;
1824 currSCCB
->Sccb_scsistat
= DISCONNECT_ST
;
1825 FPT_queueDisconnect(currSCCB
, thisCard
);
1827 /* Wait for the BusFree before starting a new command. We
1828 must also check for being reselected since the BusFree
1829 may not show up if another device reselects us in 1.5us or
1830 less. SRR Wednesday, 3/8/1995.
1833 (RDW_HARPOON((ioport
+ hp_intstat
)) &
1835 && !((RDW_HARPOON((ioport
+ hp_intstat
)) & PHASE
)
1836 && RD_HARPOON((ioport
+ hp_scsisig
)) ==
1837 (SCSI_BSY
| SCSI_REQ
| SCSI_CD
| SCSI_MSG
|
1841 The additional loop exit condition above detects a timing problem
1842 with the revision D/E harpoon chips. The caller should reset the
1843 host adapter to recover when 0xFE is returned.
1846 (RDW_HARPOON((ioport
+ hp_intstat
)) &
1847 (BUS_FREE
| RSEL
))) {
1848 MENABLE_INT(ioport
);
1852 WRW_HARPOON((ioport
+ hp_intstat
),
1853 (BUS_FREE
| ITAR_DISC
));
1855 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
1859 else if (hp_int
& RSEL
) {
1861 WRW_HARPOON((ioport
+ hp_intstat
),
1862 (PROG_HLT
| RSEL
| PHASE
| BUS_FREE
));
1864 if (RDW_HARPOON((ioport
+ hp_intstat
)) & ITAR_DISC
) {
1865 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
1866 FPT_phaseChkFifo(ioport
, thisCard
);
1868 if (RD_HARPOON(ioport
+ hp_gp_reg_1
) ==
1870 WR_HARPOON(ioport
+ hp_gp_reg_1
, 0x00);
1871 currSCCB
->Sccb_XferState
|=
1873 currSCCB
->Sccb_savedATC
=
1877 WRW_HARPOON((ioport
+ hp_intstat
),
1878 (BUS_FREE
| ITAR_DISC
));
1879 currSCCB
->Sccb_scsistat
= DISCONNECT_ST
;
1880 FPT_queueDisconnect(currSCCB
, thisCard
);
1883 FPT_sres(ioport
, thisCard
, pCurrCard
);
1884 FPT_phaseDecode(ioport
, thisCard
);
1888 else if ((hp_int
& IDO_STRT
) && (!(hp_int
& BUS_FREE
))) {
1890 WRW_HARPOON((ioport
+ hp_intstat
),
1891 (IDO_STRT
| XFER_CNT_0
));
1892 FPT_phaseDecode(ioport
, thisCard
);
1896 else if ((hp_int
& IUNKWN
) || (hp_int
& PROG_HLT
)) {
1897 WRW_HARPOON((ioport
+ hp_intstat
),
1898 (PHASE
| IUNKWN
| PROG_HLT
));
1899 if ((RD_HARPOON(ioport
+ hp_prgmcnt_0
) & (unsigned char)
1900 0x3f) < (unsigned char)SELCHK
) {
1901 FPT_phaseDecode(ioport
, thisCard
);
1903 /* Harpoon problem some SCSI target device respond to selection
1904 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1905 to latch the correct Target ID into reg. x53.
1906 The work around require to correct this reg. But when write to this
1907 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1908 need to read this reg first then restore it later. After update to 0x53 */
1911 char)(RD_HARPOON(ioport
+ hp_fifowrite
));
1914 char)(RD_HARPOON(ioport
+ hp_gp_reg_3
));
1915 WR_HARPOON(ioport
+ hp_xfer_pad
,
1916 (unsigned char)ID_UNLOCK
);
1917 WR_HARPOON(ioport
+ hp_select_id
,
1918 (unsigned char)(target
| target
<<
1920 WR_HARPOON(ioport
+ hp_xfer_pad
,
1921 (unsigned char)0x00);
1922 WR_HARPOON(ioport
+ hp_fifowrite
, i
);
1923 WR_HARPOON(ioport
+ hp_autostart_3
,
1924 (AUTO_IMMED
+ TAG_STRT
));
1928 else if (hp_int
& XFER_CNT_0
) {
1930 WRW_HARPOON((ioport
+ hp_intstat
), XFER_CNT_0
);
1932 FPT_schkdd(ioport
, thisCard
);
1936 else if (hp_int
& BUS_FREE
) {
1938 WRW_HARPOON((ioport
+ hp_intstat
), BUS_FREE
);
1940 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
) {
1942 FPT_hostDataXferAbort(ioport
, thisCard
,
1946 FPT_phaseBusFree(ioport
, thisCard
);
1949 else if (hp_int
& ITICKLE
) {
1951 WRW_HARPOON((ioport
+ hp_intstat
), ITICKLE
);
1952 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
1955 if (((struct sccb_card
*)pCurrCard
)->
1956 globalFlags
& F_NEW_SCCB_CMD
) {
1958 pCurrCard
->globalFlags
&= ~F_NEW_SCCB_CMD
;
1960 if (pCurrCard
->currentSCCB
== NULL
)
1961 FPT_queueSearchSelect(pCurrCard
, thisCard
);
1963 if (pCurrCard
->currentSCCB
!= NULL
) {
1964 pCurrCard
->globalFlags
&= ~F_NEW_SCCB_CMD
;
1965 FPT_ssel(ioport
, thisCard
);
1974 MENABLE_INT(ioport
);
1979 /*---------------------------------------------------------------------
1981 * Function: Sccb_bad_isr
1983 * Description: Some type of interrupt has occurred which is slightly
1984 * out of the ordinary. We will now decode it fully, in
1985 * this routine. This is broken up in an attempt to save
1988 *---------------------------------------------------------------------*/
1989 static unsigned char FPT_SccbMgr_bad_isr(u32 p_port
, unsigned char p_card
,
1990 struct sccb_card
*pCurrCard
,
1991 unsigned short p_int
)
1993 unsigned char temp
, ScamFlg
;
1994 struct sccb_mgr_tar_info
*currTar_Info
;
1995 struct nvram_info
*pCurrNvRam
;
1997 if (RD_HARPOON(p_port
+ hp_ext_status
) &
1998 (BM_FORCE_OFF
| PCI_DEV_TMOUT
| BM_PARITY_ERR
| PIO_OVERRUN
)) {
2000 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
) {
2002 FPT_hostDataXferAbort(p_port
, p_card
,
2003 pCurrCard
->currentSCCB
);
2006 if (RD_HARPOON(p_port
+ hp_pci_stat_cfg
) & REC_MASTER_ABORT
)
2008 WR_HARPOON(p_port
+ hp_pci_stat_cfg
,
2009 (RD_HARPOON(p_port
+ hp_pci_stat_cfg
) &
2010 ~REC_MASTER_ABORT
));
2012 WR_HARPOON(p_port
+ hp_host_blk_cnt
, 0x00);
2016 if (pCurrCard
->currentSCCB
!= NULL
) {
2018 if (!pCurrCard
->currentSCCB
->HostStatus
)
2019 pCurrCard
->currentSCCB
->HostStatus
=
2022 FPT_sxfrp(p_port
, p_card
);
2024 temp
= (unsigned char)(RD_HARPOON(p_port
+ hp_ee_ctrl
) &
2025 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
));
2026 WR_HARPOON(p_port
+ hp_ee_ctrl
,
2027 ((unsigned char)temp
| SEE_MS
| SEE_CS
));
2028 WR_HARPOON(p_port
+ hp_ee_ctrl
, temp
);
2031 (RDW_HARPOON((p_port
+ hp_intstat
)) &
2032 (BUS_FREE
| RESET
))) {
2033 FPT_phaseDecode(p_port
, p_card
);
2038 else if (p_int
& RESET
) {
2040 WR_HARPOON(p_port
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
2041 WR_HARPOON(p_port
+ hp_sys_ctrl
, 0x00);
2042 if (pCurrCard
->currentSCCB
!= NULL
) {
2044 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
2046 FPT_hostDataXferAbort(p_port
, p_card
,
2047 pCurrCard
->currentSCCB
);
2050 DISABLE_AUTO(p_port
);
2052 FPT_sresb(p_port
, p_card
);
2054 while (RD_HARPOON(p_port
+ hp_scsictrl_0
) & SCSI_RST
) {
2057 pCurrNvRam
= pCurrCard
->pNvRamInfo
;
2059 ScamFlg
= pCurrNvRam
->niScamConf
;
2062 (unsigned char)FPT_utilEERead(p_port
,
2066 FPT_XbowInit(p_port
, ScamFlg
);
2068 FPT_scini(p_card
, pCurrCard
->ourId
, 0);
2073 else if (p_int
& FIFO
) {
2075 WRW_HARPOON((p_port
+ hp_intstat
), FIFO
);
2077 if (pCurrCard
->currentSCCB
!= NULL
)
2078 FPT_sxfrp(p_port
, p_card
);
2081 else if (p_int
& TIMEOUT
) {
2083 DISABLE_AUTO(p_port
);
2085 WRW_HARPOON((p_port
+ hp_intstat
),
2086 (PROG_HLT
| TIMEOUT
| SEL
| BUS_FREE
| PHASE
|
2089 pCurrCard
->currentSCCB
->HostStatus
= SCCB_SELECTION_TIMEOUT
;
2092 &FPT_sccbMgrTbl
[p_card
][pCurrCard
->currentSCCB
->TargID
];
2093 if ((pCurrCard
->globalFlags
& F_CONLUN_IO
)
2094 && ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
2096 currTar_Info
->TarLUNBusy
[pCurrCard
->currentSCCB
->Lun
] =
2099 currTar_Info
->TarLUNBusy
[0] = 0;
2101 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
) {
2102 currTar_Info
->TarSyncCtrl
= 0;
2103 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2106 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
) {
2107 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2110 FPT_sssyncv(p_port
, pCurrCard
->currentSCCB
->TargID
, NARROW_SCSI
,
2113 FPT_queueCmdComplete(pCurrCard
, pCurrCard
->currentSCCB
, p_card
);
2117 else if (p_int
& SCAM_SEL
) {
2119 FPT_scarb(p_port
, LEVEL2_TAR
);
2121 FPT_scasid(p_card
, p_port
);
2125 WRW_HARPOON((p_port
+ hp_intstat
), SCAM_SEL
);
2131 /*---------------------------------------------------------------------
2133 * Function: SccbMgrTableInit
2135 * Description: Initialize all Sccb manager data structures.
2137 *---------------------------------------------------------------------*/
2139 static void FPT_SccbMgrTableInitAll(void)
2141 unsigned char thisCard
;
2143 for (thisCard
= 0; thisCard
< MAX_CARDS
; thisCard
++) {
2144 FPT_SccbMgrTableInitCard(&FPT_BL_Card
[thisCard
], thisCard
);
2146 FPT_BL_Card
[thisCard
].ioPort
= 0x00;
2147 FPT_BL_Card
[thisCard
].cardInfo
= NULL
;
2148 FPT_BL_Card
[thisCard
].cardIndex
= 0xFF;
2149 FPT_BL_Card
[thisCard
].ourId
= 0x00;
2150 FPT_BL_Card
[thisCard
].pNvRamInfo
= NULL
;
2154 /*---------------------------------------------------------------------
2156 * Function: SccbMgrTableInit
2158 * Description: Initialize all Sccb manager data structures.
2160 *---------------------------------------------------------------------*/
2162 static void FPT_SccbMgrTableInitCard(struct sccb_card
*pCurrCard
,
2163 unsigned char p_card
)
2165 unsigned char scsiID
, qtag
;
2167 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
2168 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
2171 for (scsiID
= 0; scsiID
< MAX_SCSI_TAR
; scsiID
++) {
2172 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
= 0;
2173 FPT_sccbMgrTbl
[p_card
][scsiID
].TarEEValue
= 0;
2174 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
2177 pCurrCard
->scanIndex
= 0x00;
2178 pCurrCard
->currentSCCB
= NULL
;
2179 pCurrCard
->globalFlags
= 0x00;
2180 pCurrCard
->cmdCounter
= 0x00;
2181 pCurrCard
->tagQ_Lst
= 0x01;
2182 pCurrCard
->discQCount
= 0;
2186 /*---------------------------------------------------------------------
2188 * Function: SccbMgrTableInit
2190 * Description: Initialize all Sccb manager data structures.
2192 *---------------------------------------------------------------------*/
2194 static void FPT_SccbMgrTableInitTarget(unsigned char p_card
,
2195 unsigned char target
)
2198 unsigned char lun
, qtag
;
2199 struct sccb_mgr_tar_info
*currTar_Info
;
2201 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][target
];
2203 currTar_Info
->TarSelQ_Cnt
= 0;
2204 currTar_Info
->TarSyncCtrl
= 0;
2206 currTar_Info
->TarSelQ_Head
= NULL
;
2207 currTar_Info
->TarSelQ_Tail
= NULL
;
2208 currTar_Info
->TarTagQ_Cnt
= 0;
2209 currTar_Info
->TarLUN_CA
= 0;
2211 for (lun
= 0; lun
< MAX_LUN
; lun
++) {
2212 currTar_Info
->TarLUNBusy
[lun
] = 0;
2213 currTar_Info
->LunDiscQ_Idx
[lun
] = 0;
2216 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
2217 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] != NULL
) {
2218 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
==
2220 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
2221 FPT_BL_Card
[p_card
].discQCount
--;
2227 /*---------------------------------------------------------------------
2231 * Description: Read in a message byte from the SCSI bus, and check
2232 * for a parity error.
2234 *---------------------------------------------------------------------*/
2236 static unsigned char FPT_sfm(u32 port
, struct sccb
*pCurrSCCB
)
2238 unsigned char message
;
2239 unsigned short TimeOutLoop
;
2242 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
2243 (TimeOutLoop
++ < 20000)) {
2246 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
2248 message
= RD_HARPOON(port
+ hp_scsidata_0
);
2250 WR_HARPOON(port
+ hp_scsisig
, SCSI_ACK
+ S_MSGI_PH
);
2252 if (TimeOutLoop
> 20000)
2253 message
= 0x00; /* force message byte = 0 if Time Out on Req */
2255 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
2256 (RD_HARPOON(port
+ hp_addstat
) & SCSI_PAR_ERR
)) {
2257 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2258 WR_HARPOON(port
+ hp_xferstat
, 0);
2259 WR_HARPOON(port
+ hp_fiforead
, 0);
2260 WR_HARPOON(port
+ hp_fifowrite
, 0);
2261 if (pCurrSCCB
!= NULL
) {
2262 pCurrSCCB
->Sccb_scsimsg
= SMPARITY
;
2266 ACCEPT_MSG_ATN(port
);
2268 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
2269 (TimeOutLoop
++ < 20000)) {
2271 if (TimeOutLoop
> 20000) {
2272 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
2275 if ((RD_HARPOON(port
+ hp_scsisig
) & S_SCSI_PHZ
) !=
2277 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
2280 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
2282 RD_HARPOON(port
+ hp_scsidata_0
);
2284 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2289 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2290 WR_HARPOON(port
+ hp_xferstat
, 0);
2291 WR_HARPOON(port
+ hp_fiforead
, 0);
2292 WR_HARPOON(port
+ hp_fifowrite
, 0);
2296 /*---------------------------------------------------------------------
2298 * Function: FPT_ssel
2300 * Description: Load up automation and select target device.
2302 *---------------------------------------------------------------------*/
2304 static void FPT_ssel(u32 port
, unsigned char p_card
)
2307 unsigned char auto_loaded
, i
, target
, *theCCB
;
2310 struct sccb_card
*CurrCard
;
2311 struct sccb
*currSCCB
;
2312 struct sccb_mgr_tar_info
*currTar_Info
;
2313 unsigned char lastTag
, lun
;
2315 CurrCard
= &FPT_BL_Card
[p_card
];
2316 currSCCB
= CurrCard
->currentSCCB
;
2317 target
= currSCCB
->TargID
;
2318 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][target
];
2319 lastTag
= CurrCard
->tagQ_Lst
;
2323 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_REJECT
)
2324 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2326 if (((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2327 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
2329 lun
= currSCCB
->Lun
;
2333 if (CurrCard
->globalFlags
& F_TAG_STARTED
) {
2334 if (!(currSCCB
->ControlByte
& F_USE_CMD_Q
)) {
2335 if ((currTar_Info
->TarLUN_CA
== 0)
2336 && ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
)
2339 if (currTar_Info
->TarTagQ_Cnt
!= 0) {
2340 currTar_Info
->TarLUNBusy
[lun
] = 1;
2341 FPT_queueSelectFail(CurrCard
, p_card
);
2347 currTar_Info
->TarLUNBusy
[lun
] = 1;
2353 currTar_Info
->TarLUNBusy
[lun
] = 1;
2357 /*!Use cmd Q Tagged */
2359 if (currTar_Info
->TarLUN_CA
== 1) {
2360 FPT_queueSelectFail(CurrCard
, p_card
);
2365 currTar_Info
->TarLUNBusy
[lun
] = 1;
2367 } /*else use cmd Q tagged */
2370 /*if glob tagged started */
2372 currTar_Info
->TarLUNBusy
[lun
] = 1;
2375 if ((((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2376 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
2377 || (!(currSCCB
->ControlByte
& F_USE_CMD_Q
)))) {
2378 if (CurrCard
->discQCount
>= QUEUE_DEPTH
) {
2379 currTar_Info
->TarLUNBusy
[lun
] = 1;
2380 FPT_queueSelectFail(CurrCard
, p_card
);
2384 for (i
= 1; i
< QUEUE_DEPTH
; i
++) {
2385 if (++lastTag
>= QUEUE_DEPTH
)
2387 if (CurrCard
->discQ_Tbl
[lastTag
] == NULL
) {
2388 CurrCard
->tagQ_Lst
= lastTag
;
2389 currTar_Info
->LunDiscQ_Idx
[lun
] = lastTag
;
2390 CurrCard
->discQ_Tbl
[lastTag
] = currSCCB
;
2391 CurrCard
->discQCount
++;
2395 if (i
== QUEUE_DEPTH
) {
2396 currTar_Info
->TarLUNBusy
[lun
] = 1;
2397 FPT_queueSelectFail(CurrCard
, p_card
);
2405 WR_HARPOON(port
+ hp_select_id
, target
);
2406 WR_HARPOON(port
+ hp_gp_reg_3
, target
); /* Use by new automation logic */
2408 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
2409 WRW_HARPOON((port
+ ID_MSG_STRT
), (MPM_OP
+ AMSG_OUT
+
2411 Sccb_idmsg
& ~DISC_PRIV
)));
2413 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ NP
);
2415 currSCCB
->Sccb_scsimsg
= SMDEV_RESET
;
2417 WR_HARPOON(port
+ hp_autostart_3
, (SELECT
+ SELCHK_STRT
));
2419 currSCCB
->Sccb_scsistat
= SELECT_BDR_ST
;
2421 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
) {
2422 currTar_Info
->TarSyncCtrl
= 0;
2423 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2426 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
) {
2427 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2430 FPT_sssyncv(port
, target
, NARROW_SCSI
, currTar_Info
);
2431 FPT_SccbMgrTableInitTarget(p_card
, target
);
2435 else if (currSCCB
->Sccb_scsistat
== ABORT_ST
) {
2436 WRW_HARPOON((port
+ ID_MSG_STRT
), (MPM_OP
+ AMSG_OUT
+
2438 Sccb_idmsg
& ~DISC_PRIV
)));
2440 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ CMDPZ
);
2442 WRW_HARPOON((port
+ SYNC_MSGS
+ 0), (MPM_OP
+ AMSG_OUT
+
2447 >> 6) | (unsigned char)
2449 WRW_HARPOON((port
+ SYNC_MSGS
+ 2),
2450 (MPM_OP
+ AMSG_OUT
+ currSCCB
->Sccb_tag
));
2451 WRW_HARPOON((port
+ SYNC_MSGS
+ 4), (BRH_OP
+ ALWAYS
+ NP
));
2453 WR_HARPOON(port
+ hp_autostart_3
, (SELECT
+ SELCHK_STRT
));
2458 else if (!(currTar_Info
->TarStatus
& WIDE_NEGOCIATED
)) {
2459 auto_loaded
= FPT_siwidn(port
, p_card
);
2460 currSCCB
->Sccb_scsistat
= SELECT_WN_ST
;
2463 else if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
)
2464 == SYNC_SUPPORTED
)) {
2465 auto_loaded
= FPT_sisyncn(port
, p_card
, 0);
2466 currSCCB
->Sccb_scsistat
= SELECT_SN_ST
;
2471 if (currSCCB
->ControlByte
& F_USE_CMD_Q
) {
2473 CurrCard
->globalFlags
|= F_TAG_STARTED
;
2475 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
)
2477 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2479 /* Fix up the start instruction with a jump to
2480 Non-Tag-CMD handling */
2481 WRW_HARPOON((port
+ ID_MSG_STRT
),
2482 BRH_OP
+ ALWAYS
+ NTCMD
);
2484 WRW_HARPOON((port
+ NON_TAG_ID_MSG
),
2485 (MPM_OP
+ AMSG_OUT
+
2486 currSCCB
->Sccb_idmsg
));
2488 WR_HARPOON(port
+ hp_autostart_3
,
2489 (SELECT
+ SELCHK_STRT
));
2491 /* Setup our STATE so we know what happened when
2492 the wheels fall off. */
2493 currSCCB
->Sccb_scsistat
= SELECT_ST
;
2495 currTar_Info
->TarLUNBusy
[lun
] = 1;
2499 WRW_HARPOON((port
+ ID_MSG_STRT
),
2500 (MPM_OP
+ AMSG_OUT
+
2501 currSCCB
->Sccb_idmsg
));
2503 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2),
2504 (MPM_OP
+ AMSG_OUT
+
2505 (((unsigned char)(currSCCB
->
2508 >> 6) | (unsigned char)0x20)));
2510 for (i
= 1; i
< QUEUE_DEPTH
; i
++) {
2511 if (++lastTag
>= QUEUE_DEPTH
)
2513 if (CurrCard
->discQ_Tbl
[lastTag
] ==
2517 (MPM_OP
+ AMSG_OUT
+
2519 CurrCard
->tagQ_Lst
= lastTag
;
2520 currSCCB
->Sccb_tag
= lastTag
;
2521 CurrCard
->discQ_Tbl
[lastTag
] =
2523 CurrCard
->discQCount
++;
2528 if (i
== QUEUE_DEPTH
) {
2529 currTar_Info
->TarLUNBusy
[lun
] = 1;
2530 FPT_queueSelectFail(CurrCard
, p_card
);
2535 currSCCB
->Sccb_scsistat
= SELECT_Q_ST
;
2537 WR_HARPOON(port
+ hp_autostart_3
,
2538 (SELECT
+ SELCHK_STRT
));
2544 WRW_HARPOON((port
+ ID_MSG_STRT
),
2545 BRH_OP
+ ALWAYS
+ NTCMD
);
2547 WRW_HARPOON((port
+ NON_TAG_ID_MSG
),
2548 (MPM_OP
+ AMSG_OUT
+ currSCCB
->Sccb_idmsg
));
2550 currSCCB
->Sccb_scsistat
= SELECT_ST
;
2552 WR_HARPOON(port
+ hp_autostart_3
,
2553 (SELECT
+ SELCHK_STRT
));
2556 theCCB
= (unsigned char *)&currSCCB
->Cdb
[0];
2558 cdb_reg
= port
+ CMD_STRT
;
2560 for (i
= 0; i
< currSCCB
->CdbLength
; i
++) {
2561 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ *theCCB
));
2566 if (currSCCB
->CdbLength
!= TWELVE_BYTE_CMD
)
2567 WRW_HARPOON(cdb_reg
, (BRH_OP
+ ALWAYS
+ NP
));
2571 WRW_HARPOON((port
+ hp_fiforead
), (unsigned short)0x00);
2572 WR_HARPOON(port
+ hp_xferstat
, 0x00);
2574 WRW_HARPOON((port
+ hp_intstat
), (PROG_HLT
| TIMEOUT
| SEL
| BUS_FREE
));
2576 WR_HARPOON(port
+ hp_portctrl_0
, (SCSI_PORT
));
2578 if (!(currSCCB
->Sccb_MGRFlags
& F_DEV_SELECTED
)) {
2579 WR_HARPOON(port
+ hp_scsictrl_0
,
2580 (SEL_TAR
| ENA_ATN
| ENA_RESEL
| ENA_SCAM_SEL
));
2583 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2584 auto_loaded |= AUTO_IMMED; */
2585 auto_loaded
= AUTO_IMMED
;
2589 WR_HARPOON(port
+ hp_autostart_3
, auto_loaded
);
2595 /*---------------------------------------------------------------------
2597 * Function: FPT_sres
2599 * Description: Hookup the correct CCB and handle the incoming messages.
2601 *---------------------------------------------------------------------*/
2603 static void FPT_sres(u32 port
, unsigned char p_card
,
2604 struct sccb_card
*pCurrCard
)
2607 unsigned char our_target
, message
, lun
= 0, tag
, msgRetryCount
;
2609 struct sccb_mgr_tar_info
*currTar_Info
;
2610 struct sccb
*currSCCB
;
2612 if (pCurrCard
->currentSCCB
!= NULL
) {
2614 &FPT_sccbMgrTbl
[p_card
][pCurrCard
->currentSCCB
->TargID
];
2617 WR_HARPOON((port
+ hp_scsictrl_0
), (ENA_RESEL
| ENA_SCAM_SEL
));
2619 currSCCB
= pCurrCard
->currentSCCB
;
2620 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
2621 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2622 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
2624 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
2625 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2626 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
2628 if (((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
2629 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
2631 currTar_Info
->TarLUNBusy
[currSCCB
->Lun
] = 0;
2632 if (currSCCB
->Sccb_scsistat
!= ABORT_ST
) {
2633 pCurrCard
->discQCount
--;
2634 pCurrCard
->discQ_Tbl
[currTar_Info
->
2635 LunDiscQ_Idx
[currSCCB
->
2640 currTar_Info
->TarLUNBusy
[0] = 0;
2641 if (currSCCB
->Sccb_tag
) {
2642 if (currSCCB
->Sccb_scsistat
!= ABORT_ST
) {
2643 pCurrCard
->discQCount
--;
2644 pCurrCard
->discQ_Tbl
[currSCCB
->
2648 if (currSCCB
->Sccb_scsistat
!= ABORT_ST
) {
2649 pCurrCard
->discQCount
--;
2650 pCurrCard
->discQ_Tbl
[currTar_Info
->
2657 FPT_queueSelectFail(&FPT_BL_Card
[p_card
], p_card
);
2660 WRW_HARPOON((port
+ hp_fiforead
), (unsigned short)0x00);
2662 our_target
= (unsigned char)(RD_HARPOON(port
+ hp_select_id
) >> 4);
2663 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][our_target
];
2668 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][our_target
];
2671 while (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) {
2672 if (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) {
2674 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2679 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2680 if ((RD_HARPOON(port
+ hp_scsisig
) & S_SCSI_PHZ
) == S_MSGI_PH
) {
2682 message
= FPT_sfm(port
, pCurrCard
->currentSCCB
);
2685 if (message
<= (0x80 | LUN_MASK
)) {
2686 lun
= message
& (unsigned char)LUN_MASK
;
2689 TarStatus
& TAR_TAG_Q_MASK
) ==
2691 if (currTar_Info
->TarTagQ_Cnt
!=
2697 ACCEPT_MSG(port
); /*Release the ACK for ID msg. */
2733 /*End Tag cmds supported! */
2735 /*End valid ID message. */
2738 ACCEPT_MSG_ATN(port
);
2742 /* End good id message. */
2748 ACCEPT_MSG_ATN(port
);
2751 (RDW_HARPOON((port
+ hp_intstat
)) &
2753 && !(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)
2754 && (RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) ;
2761 if (msgRetryCount
== 1) {
2762 FPT_SendMsg(port
, SMPARITY
);
2764 FPT_SendMsg(port
, SMDEV_RESET
);
2766 FPT_sssyncv(port
, our_target
, NARROW_SCSI
,
2769 if (FPT_sccbMgrTbl
[p_card
][our_target
].
2770 TarEEValue
& EE_SYNC_MASK
) {
2772 FPT_sccbMgrTbl
[p_card
][our_target
].
2773 TarStatus
&= ~TAR_SYNC_MASK
;
2777 if (FPT_sccbMgrTbl
[p_card
][our_target
].
2778 TarEEValue
& EE_WIDE_SCSI
) {
2780 FPT_sccbMgrTbl
[p_card
][our_target
].
2781 TarStatus
&= ~TAR_WIDE_MASK
;
2784 FPT_queueFlushTargSccb(p_card
, our_target
,
2786 FPT_SccbMgrTableInitTarget(p_card
, our_target
);
2790 } while (message
== 0);
2792 if (((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
2793 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
2794 currTar_Info
->TarLUNBusy
[lun
] = 1;
2795 pCurrCard
->currentSCCB
=
2796 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[lun
]];
2797 if (pCurrCard
->currentSCCB
!= NULL
) {
2800 ACCEPT_MSG_ATN(port
);
2803 currTar_Info
->TarLUNBusy
[0] = 1;
2806 if (pCurrCard
->discQ_Tbl
[tag
] != NULL
) {
2807 pCurrCard
->currentSCCB
=
2808 pCurrCard
->discQ_Tbl
[tag
];
2809 currTar_Info
->TarTagQ_Cnt
--;
2812 ACCEPT_MSG_ATN(port
);
2815 pCurrCard
->currentSCCB
=
2816 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[0]];
2817 if (pCurrCard
->currentSCCB
!= NULL
) {
2820 ACCEPT_MSG_ATN(port
);
2825 if (pCurrCard
->currentSCCB
!= NULL
) {
2826 if (pCurrCard
->currentSCCB
->Sccb_scsistat
== ABORT_ST
) {
2827 /* During Abort Tag command, the target could have got re-selected
2828 and completed the command. Check the select Q and remove the CCB
2829 if it is in the Select Q */
2830 FPT_queueFindSccb(pCurrCard
->currentSCCB
, p_card
);
2834 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (PHASE
| RESET
)) &&
2835 !(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
) &&
2836 (RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) ;
2839 static void FPT_SendMsg(u32 port
, unsigned char message
)
2841 while (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) {
2842 if (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) {
2844 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2849 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2850 if ((RD_HARPOON(port
+ hp_scsisig
) & S_SCSI_PHZ
) == S_MSGO_PH
) {
2851 WRW_HARPOON((port
+ hp_intstat
),
2852 (BUS_FREE
| PHASE
| XFER_CNT_0
));
2854 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_BUS_EN
);
2856 WR_HARPOON(port
+ hp_scsidata_0
, message
);
2858 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2862 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
2864 if ((message
== SMABORT
) || (message
== SMDEV_RESET
) ||
2865 (message
== SMABORT_TAG
)) {
2867 (RDW_HARPOON((port
+ hp_intstat
)) &
2868 (BUS_FREE
| PHASE
))) {
2871 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
2872 WRW_HARPOON((port
+ hp_intstat
), BUS_FREE
);
2878 /*---------------------------------------------------------------------
2880 * Function: FPT_sdecm
2882 * Description: Determine the proper response to the message from the
2885 *---------------------------------------------------------------------*/
2886 static void FPT_sdecm(unsigned char message
, u32 port
, unsigned char p_card
)
2888 struct sccb
*currSCCB
;
2889 struct sccb_card
*CurrCard
;
2890 struct sccb_mgr_tar_info
*currTar_Info
;
2892 CurrCard
= &FPT_BL_Card
[p_card
];
2893 currSCCB
= CurrCard
->currentSCCB
;
2895 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
2897 if (message
== SMREST_DATA_PTR
) {
2898 if (!(currSCCB
->Sccb_XferState
& F_NO_DATA_YET
)) {
2899 currSCCB
->Sccb_ATC
= currSCCB
->Sccb_savedATC
;
2901 FPT_hostDataXferRestart(currSCCB
);
2905 WR_HARPOON(port
+ hp_autostart_1
,
2906 (AUTO_IMMED
+ DISCONNECT_START
));
2909 else if (message
== SMCMD_COMP
) {
2911 if (currSCCB
->Sccb_scsistat
== SELECT_Q_ST
) {
2912 currTar_Info
->TarStatus
&=
2913 ~(unsigned char)TAR_TAG_Q_MASK
;
2914 currTar_Info
->TarStatus
|= (unsigned char)TAG_Q_REJECT
;
2921 else if ((message
== SMNO_OP
) || (message
>= SMIDENT
)
2922 || (message
== SMINIT_RECOVERY
) || (message
== SMREL_RECOVERY
)) {
2925 WR_HARPOON(port
+ hp_autostart_1
,
2926 (AUTO_IMMED
+ DISCONNECT_START
));
2929 else if (message
== SMREJECT
) {
2931 if ((currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) ||
2932 (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) ||
2933 ((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_TRYING
)
2934 || ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) ==
2937 WRW_HARPOON((port
+ hp_intstat
), BUS_FREE
);
2941 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
2942 (!(RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
)))
2946 if (currSCCB
->Lun
== 0x00) {
2947 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
2949 currTar_Info
->TarStatus
|=
2950 (unsigned char)SYNC_SUPPORTED
;
2952 currTar_Info
->TarEEValue
&=
2956 else if (currSCCB
->Sccb_scsistat
==
2959 currTar_Info
->TarStatus
=
2961 TarStatus
& ~WIDE_ENABLED
) |
2964 currTar_Info
->TarEEValue
&=
2969 else if ((currTar_Info
->
2970 TarStatus
& TAR_TAG_Q_MASK
) ==
2972 currTar_Info
->TarStatus
=
2974 TarStatus
& ~(unsigned char)
2975 TAR_TAG_Q_MASK
) | TAG_Q_REJECT
;
2977 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2978 CurrCard
->discQCount
--;
2979 CurrCard
->discQ_Tbl
[currSCCB
->
2981 currSCCB
->Sccb_tag
= 0x00;
2986 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
2988 if (currSCCB
->Lun
== 0x00) {
2989 WRW_HARPOON((port
+ hp_intstat
),
2991 CurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
2997 if ((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2999 TarStatus
& TAR_TAG_Q_MASK
) !=
3001 currTar_Info
->TarLUNBusy
[currSCCB
->
3004 currTar_Info
->TarLUNBusy
[0] = 1;
3006 currSCCB
->ControlByte
&=
3007 ~(unsigned char)F_USE_CMD_Q
;
3009 WR_HARPOON(port
+ hp_autostart_1
,
3010 (AUTO_IMMED
+ DISCONNECT_START
));
3018 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
3019 (!(RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
)))
3023 if (!(RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
)) {
3024 WR_HARPOON(port
+ hp_autostart_1
,
3025 (AUTO_IMMED
+ DISCONNECT_START
));
3030 else if (message
== SMEXT
) {
3033 FPT_shandem(port
, p_card
, currSCCB
);
3036 else if (message
== SMIGNORWR
) {
3038 ACCEPT_MSG(port
); /* ACK the RESIDUE MSG */
3040 message
= FPT_sfm(port
, currSCCB
);
3042 if (currSCCB
->Sccb_scsimsg
!= SMPARITY
)
3044 WR_HARPOON(port
+ hp_autostart_1
,
3045 (AUTO_IMMED
+ DISCONNECT_START
));
3050 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
3051 currSCCB
->Sccb_scsimsg
= SMREJECT
;
3053 ACCEPT_MSG_ATN(port
);
3054 WR_HARPOON(port
+ hp_autostart_1
,
3055 (AUTO_IMMED
+ DISCONNECT_START
));
3059 /*---------------------------------------------------------------------
3061 * Function: FPT_shandem
3063 * Description: Decide what to do with the extended message.
3065 *---------------------------------------------------------------------*/
3066 static void FPT_shandem(u32 port
, unsigned char p_card
, struct sccb
*pCurrSCCB
)
3068 unsigned char length
, message
;
3070 length
= FPT_sfm(port
, pCurrSCCB
);
3074 message
= FPT_sfm(port
, pCurrSCCB
);
3077 if (message
== SMSYNC
) {
3079 if (length
== 0x03) {
3082 FPT_stsyncn(port
, p_card
);
3085 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3086 ACCEPT_MSG_ATN(port
);
3088 } else if (message
== SMWDTR
) {
3090 if (length
== 0x02) {
3093 FPT_stwidn(port
, p_card
);
3096 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3097 ACCEPT_MSG_ATN(port
);
3099 WR_HARPOON(port
+ hp_autostart_1
,
3105 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3106 ACCEPT_MSG_ATN(port
);
3108 WR_HARPOON(port
+ hp_autostart_1
,
3109 (AUTO_IMMED
+ DISCONNECT_START
));
3112 if (pCurrSCCB
->Sccb_scsimsg
!= SMPARITY
)
3114 WR_HARPOON(port
+ hp_autostart_1
,
3115 (AUTO_IMMED
+ DISCONNECT_START
));
3118 if (pCurrSCCB
->Sccb_scsimsg
== SMPARITY
)
3119 WR_HARPOON(port
+ hp_autostart_1
,
3120 (AUTO_IMMED
+ DISCONNECT_START
));
3124 /*---------------------------------------------------------------------
3126 * Function: FPT_sisyncn
3128 * Description: Read in a message byte from the SCSI bus, and check
3129 * for a parity error.
3131 *---------------------------------------------------------------------*/
3133 static unsigned char FPT_sisyncn(u32 port
, unsigned char p_card
,
3134 unsigned char syncFlag
)
3136 struct sccb
*currSCCB
;
3137 struct sccb_mgr_tar_info
*currTar_Info
;
3139 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3140 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3142 if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_TRYING
)) {
3144 WRW_HARPOON((port
+ ID_MSG_STRT
),
3145 (MPM_OP
+ AMSG_OUT
+
3147 Sccb_idmsg
& ~(unsigned char)DISC_PRIV
)));
3149 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ CMDPZ
);
3151 WRW_HARPOON((port
+ SYNC_MSGS
+ 0),
3152 (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3153 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x03));
3154 WRW_HARPOON((port
+ SYNC_MSGS
+ 4),
3155 (MPM_OP
+ AMSG_OUT
+ SMSYNC
));
3157 if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_20MB
)
3159 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3160 (MPM_OP
+ AMSG_OUT
+ 12));
3162 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) ==
3165 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3166 (MPM_OP
+ AMSG_OUT
+ 25));
3168 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) ==
3171 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3172 (MPM_OP
+ AMSG_OUT
+ 50));
3175 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3176 (MPM_OP
+ AMSG_OUT
+ 00));
3178 WRW_HARPOON((port
+ SYNC_MSGS
+ 8), (RAT_OP
));
3179 WRW_HARPOON((port
+ SYNC_MSGS
+ 10),
3180 (MPM_OP
+ AMSG_OUT
+ DEFAULT_OFFSET
));
3181 WRW_HARPOON((port
+ SYNC_MSGS
+ 12), (BRH_OP
+ ALWAYS
+ NP
));
3183 if (syncFlag
== 0) {
3184 WR_HARPOON(port
+ hp_autostart_3
,
3185 (SELECT
+ SELCHK_STRT
));
3186 currTar_Info
->TarStatus
=
3188 TarStatus
& ~(unsigned char)TAR_SYNC_MASK
) |
3189 (unsigned char)SYNC_TRYING
);
3191 WR_HARPOON(port
+ hp_autostart_3
,
3192 (AUTO_IMMED
+ CMD_ONLY_STRT
));
3200 currTar_Info
->TarStatus
|= (unsigned char)SYNC_SUPPORTED
;
3201 currTar_Info
->TarEEValue
&= ~EE_SYNC_MASK
;
3206 /*---------------------------------------------------------------------
3208 * Function: FPT_stsyncn
3210 * Description: The has sent us a Sync Nego message so handle it as
3213 *---------------------------------------------------------------------*/
3214 static void FPT_stsyncn(u32 port
, unsigned char p_card
)
3216 unsigned char sync_msg
, offset
, sync_reg
, our_sync_msg
;
3217 struct sccb
*currSCCB
;
3218 struct sccb_mgr_tar_info
*currTar_Info
;
3220 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3221 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3223 sync_msg
= FPT_sfm(port
, currSCCB
);
3225 if ((sync_msg
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
)) {
3226 WR_HARPOON(port
+ hp_autostart_1
,
3227 (AUTO_IMMED
+ DISCONNECT_START
));
3233 offset
= FPT_sfm(port
, currSCCB
);
3235 if ((offset
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
)) {
3236 WR_HARPOON(port
+ hp_autostart_1
,
3237 (AUTO_IMMED
+ DISCONNECT_START
));
3241 if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_20MB
)
3243 our_sync_msg
= 12; /* Setup our Message to 20mb/s */
3245 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_10MB
)
3247 our_sync_msg
= 25; /* Setup our Message to 10mb/s */
3249 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_5MB
)
3251 our_sync_msg
= 50; /* Setup our Message to 5mb/s */
3254 our_sync_msg
= 0; /* Message = Async */
3256 if (sync_msg
< our_sync_msg
) {
3257 sync_msg
= our_sync_msg
; /*if faster, then set to max. */
3260 if (offset
== ASYNC
)
3263 if (offset
> MAX_OFFSET
)
3264 offset
= MAX_OFFSET
;
3270 sync_reg
= 0x20; /* Use 10MB/s */
3274 sync_reg
= 0x40; /* Use 6.6MB/s */
3278 sync_reg
= 0x60; /* Use 5MB/s */
3282 sync_reg
= 0x80; /* Use 4MB/s */
3286 sync_reg
= 0xA0; /* Use 3.33MB/s */
3290 sync_reg
= 0xC0; /* Use 2.85MB/s */
3294 sync_reg
= 0xE0; /* Use 2.5MB/s */
3296 if (sync_msg
> 100) {
3298 sync_reg
= 0x00; /* Use ASYNC */
3302 if (currTar_Info
->TarStatus
& WIDE_ENABLED
)
3308 sync_reg
|= (offset
| NARROW_SCSI
);
3310 FPT_sssyncv(port
, currSCCB
->TargID
, sync_reg
, currTar_Info
);
3312 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
3316 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3317 ~(unsigned char)TAR_SYNC_MASK
) |
3318 (unsigned char)SYNC_SUPPORTED
);
3320 WR_HARPOON(port
+ hp_autostart_1
,
3321 (AUTO_IMMED
+ DISCONNECT_START
));
3326 ACCEPT_MSG_ATN(port
);
3328 FPT_sisyncr(port
, sync_msg
, offset
);
3330 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3331 ~(unsigned char)TAR_SYNC_MASK
) |
3332 (unsigned char)SYNC_SUPPORTED
);
3336 /*---------------------------------------------------------------------
3338 * Function: FPT_sisyncr
3340 * Description: Answer the targets sync message.
3342 *---------------------------------------------------------------------*/
3343 static void FPT_sisyncr(u32 port
, unsigned char sync_pulse
,
3344 unsigned char offset
)
3347 WRW_HARPOON((port
+ SYNC_MSGS
+ 0), (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3348 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x03));
3349 WRW_HARPOON((port
+ SYNC_MSGS
+ 4), (MPM_OP
+ AMSG_OUT
+ SMSYNC
));
3350 WRW_HARPOON((port
+ SYNC_MSGS
+ 6), (MPM_OP
+ AMSG_OUT
+ sync_pulse
));
3351 WRW_HARPOON((port
+ SYNC_MSGS
+ 8), (RAT_OP
));
3352 WRW_HARPOON((port
+ SYNC_MSGS
+ 10), (MPM_OP
+ AMSG_OUT
+ offset
));
3353 WRW_HARPOON((port
+ SYNC_MSGS
+ 12), (BRH_OP
+ ALWAYS
+ NP
));
3356 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
3357 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT_1
);
3359 WR_HARPOON(port
+ hp_autostart_3
, (AUTO_IMMED
+ CMD_ONLY_STRT
));
3361 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| AUTO_INT
))) {
3365 /*---------------------------------------------------------------------
3367 * Function: FPT_siwidn
3369 * Description: Read in a message byte from the SCSI bus, and check
3370 * for a parity error.
3372 *---------------------------------------------------------------------*/
3374 static unsigned char FPT_siwidn(u32 port
, unsigned char p_card
)
3376 struct sccb
*currSCCB
;
3377 struct sccb_mgr_tar_info
*currTar_Info
;
3379 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3380 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3382 if (!((currTar_Info
->TarStatus
& TAR_WIDE_MASK
) == WIDE_NEGOCIATED
)) {
3384 WRW_HARPOON((port
+ ID_MSG_STRT
),
3385 (MPM_OP
+ AMSG_OUT
+
3387 Sccb_idmsg
& ~(unsigned char)DISC_PRIV
)));
3389 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ CMDPZ
);
3391 WRW_HARPOON((port
+ SYNC_MSGS
+ 0),
3392 (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3393 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x02));
3394 WRW_HARPOON((port
+ SYNC_MSGS
+ 4),
3395 (MPM_OP
+ AMSG_OUT
+ SMWDTR
));
3396 WRW_HARPOON((port
+ SYNC_MSGS
+ 6), (RAT_OP
));
3397 WRW_HARPOON((port
+ SYNC_MSGS
+ 8),
3398 (MPM_OP
+ AMSG_OUT
+ SM16BIT
));
3399 WRW_HARPOON((port
+ SYNC_MSGS
+ 10), (BRH_OP
+ ALWAYS
+ NP
));
3401 WR_HARPOON(port
+ hp_autostart_3
, (SELECT
+ SELCHK_STRT
));
3403 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3404 ~(unsigned char)TAR_WIDE_MASK
) |
3405 (unsigned char)WIDE_ENABLED
);
3412 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3413 ~(unsigned char)TAR_WIDE_MASK
) |
3416 currTar_Info
->TarEEValue
&= ~EE_WIDE_SCSI
;
3421 /*---------------------------------------------------------------------
3423 * Function: FPT_stwidn
3425 * Description: The has sent us a Wide Nego message so handle it as
3428 *---------------------------------------------------------------------*/
3429 static void FPT_stwidn(u32 port
, unsigned char p_card
)
3431 unsigned char width
;
3432 struct sccb
*currSCCB
;
3433 struct sccb_mgr_tar_info
*currTar_Info
;
3435 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3436 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3438 width
= FPT_sfm(port
, currSCCB
);
3440 if ((width
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
)) {
3441 WR_HARPOON(port
+ hp_autostart_1
,
3442 (AUTO_IMMED
+ DISCONNECT_START
));
3446 if (!(currTar_Info
->TarEEValue
& EE_WIDE_SCSI
))
3450 currTar_Info
->TarStatus
|= WIDE_ENABLED
;
3453 width
= NARROW_SCSI
;
3454 currTar_Info
->TarStatus
&= ~WIDE_ENABLED
;
3457 FPT_sssyncv(port
, currSCCB
->TargID
, width
, currTar_Info
);
3459 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
3461 currTar_Info
->TarStatus
|= WIDE_NEGOCIATED
;
3464 ((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) ==
3466 ACCEPT_MSG_ATN(port
);
3468 FPT_sisyncn(port
, p_card
, 1);
3469 currSCCB
->Sccb_scsistat
= SELECT_SN_ST
;
3473 WR_HARPOON(port
+ hp_autostart_1
,
3474 (AUTO_IMMED
+ DISCONNECT_START
));
3480 ACCEPT_MSG_ATN(port
);
3482 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
)
3487 FPT_siwidr(port
, width
);
3489 currTar_Info
->TarStatus
|= (WIDE_NEGOCIATED
| WIDE_ENABLED
);
3493 /*---------------------------------------------------------------------
3495 * Function: FPT_siwidr
3497 * Description: Answer the targets Wide nego message.
3499 *---------------------------------------------------------------------*/
3500 static void FPT_siwidr(u32 port
, unsigned char width
)
3503 WRW_HARPOON((port
+ SYNC_MSGS
+ 0), (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3504 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x02));
3505 WRW_HARPOON((port
+ SYNC_MSGS
+ 4), (MPM_OP
+ AMSG_OUT
+ SMWDTR
));
3506 WRW_HARPOON((port
+ SYNC_MSGS
+ 6), (RAT_OP
));
3507 WRW_HARPOON((port
+ SYNC_MSGS
+ 8), (MPM_OP
+ AMSG_OUT
+ width
));
3508 WRW_HARPOON((port
+ SYNC_MSGS
+ 10), (BRH_OP
+ ALWAYS
+ NP
));
3511 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
3512 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT_1
);
3514 WR_HARPOON(port
+ hp_autostart_3
, (AUTO_IMMED
+ CMD_ONLY_STRT
));
3516 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| AUTO_INT
))) {
3520 /*---------------------------------------------------------------------
3522 * Function: FPT_sssyncv
3524 * Description: Write the desired value to the Sync Register for the
3527 *---------------------------------------------------------------------*/
3528 static void FPT_sssyncv(u32 p_port
, unsigned char p_id
,
3529 unsigned char p_sync_value
,
3530 struct sccb_mgr_tar_info
*currTar_Info
)
3532 unsigned char index
;
3539 index
= 12; /* hp_synctarg_0 */
3542 index
= 13; /* hp_synctarg_1 */
3545 index
= 14; /* hp_synctarg_2 */
3548 index
= 15; /* hp_synctarg_3 */
3551 index
= 8; /* hp_synctarg_4 */
3554 index
= 9; /* hp_synctarg_5 */
3557 index
= 10; /* hp_synctarg_6 */
3560 index
= 11; /* hp_synctarg_7 */
3563 index
= 4; /* hp_synctarg_8 */
3566 index
= 5; /* hp_synctarg_9 */
3569 index
= 6; /* hp_synctarg_10 */
3572 index
= 7; /* hp_synctarg_11 */
3575 index
= 0; /* hp_synctarg_12 */
3578 index
= 1; /* hp_synctarg_13 */
3581 index
= 2; /* hp_synctarg_14 */
3584 index
= 3; /* hp_synctarg_15 */
3588 WR_HARPOON(p_port
+ hp_synctarg_base
+ index
, p_sync_value
);
3590 currTar_Info
->TarSyncCtrl
= p_sync_value
;
3593 /*---------------------------------------------------------------------
3595 * Function: FPT_sresb
3597 * Description: Reset the desired card's SCSI bus.
3599 *---------------------------------------------------------------------*/
3600 static void FPT_sresb(u32 port
, unsigned char p_card
)
3602 unsigned char scsiID
, i
;
3604 struct sccb_mgr_tar_info
*currTar_Info
;
3606 WR_HARPOON(port
+ hp_page_ctrl
,
3607 (RD_HARPOON(port
+ hp_page_ctrl
) | G_INT_DISABLE
));
3608 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT
);
3610 WR_HARPOON(port
+ hp_scsictrl_0
, SCSI_RST
);
3612 scsiID
= RD_HARPOON(port
+ hp_seltimeout
);
3613 WR_HARPOON(port
+ hp_seltimeout
, TO_5ms
);
3614 WRW_HARPOON((port
+ hp_intstat
), TIMEOUT
);
3616 WR_HARPOON(port
+ hp_portctrl_0
, (SCSI_PORT
| START_TO
));
3618 while (!(RDW_HARPOON((port
+ hp_intstat
)) & TIMEOUT
)) {
3621 WR_HARPOON(port
+ hp_seltimeout
, scsiID
);
3623 WR_HARPOON(port
+ hp_scsictrl_0
, ENA_SCAM_SEL
);
3625 FPT_Wait(port
, TO_5ms
);
3627 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT
);
3629 WR_HARPOON(port
+ hp_int_mask
, (RD_HARPOON(port
+ hp_int_mask
) | 0x00));
3631 for (scsiID
= 0; scsiID
< MAX_SCSI_TAR
; scsiID
++) {
3632 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scsiID
];
3634 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
) {
3635 currTar_Info
->TarSyncCtrl
= 0;
3636 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
3639 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
) {
3640 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
3643 FPT_sssyncv(port
, scsiID
, NARROW_SCSI
, currTar_Info
);
3645 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
3648 FPT_BL_Card
[p_card
].scanIndex
= 0x00;
3649 FPT_BL_Card
[p_card
].currentSCCB
= NULL
;
3650 FPT_BL_Card
[p_card
].globalFlags
&= ~(F_TAG_STARTED
| F_HOST_XFER_ACT
3652 FPT_BL_Card
[p_card
].cmdCounter
= 0x00;
3653 FPT_BL_Card
[p_card
].discQCount
= 0x00;
3654 FPT_BL_Card
[p_card
].tagQ_Lst
= 0x01;
3656 for (i
= 0; i
< QUEUE_DEPTH
; i
++)
3657 FPT_BL_Card
[p_card
].discQ_Tbl
[i
] = NULL
;
3659 WR_HARPOON(port
+ hp_page_ctrl
,
3660 (RD_HARPOON(port
+ hp_page_ctrl
) & ~G_INT_DISABLE
));
3664 /*---------------------------------------------------------------------
3666 * Function: FPT_ssenss
3668 * Description: Setup for the Auto Sense command.
3670 *---------------------------------------------------------------------*/
3671 static void FPT_ssenss(struct sccb_card
*pCurrCard
)
3674 struct sccb
*currSCCB
;
3676 currSCCB
= pCurrCard
->currentSCCB
;
3678 currSCCB
->Save_CdbLen
= currSCCB
->CdbLength
;
3680 for (i
= 0; i
< 6; i
++) {
3682 currSCCB
->Save_Cdb
[i
] = currSCCB
->Cdb
[i
];
3685 currSCCB
->CdbLength
= SIX_BYTE_CMD
;
3686 currSCCB
->Cdb
[0] = SCSI_REQUEST_SENSE
;
3687 currSCCB
->Cdb
[1] = currSCCB
->Cdb
[1] & (unsigned char)0xE0; /*Keep LUN. */
3688 currSCCB
->Cdb
[2] = 0x00;
3689 currSCCB
->Cdb
[3] = 0x00;
3690 currSCCB
->Cdb
[4] = currSCCB
->RequestSenseLength
;
3691 currSCCB
->Cdb
[5] = 0x00;
3693 currSCCB
->Sccb_XferCnt
= (u32
)currSCCB
->RequestSenseLength
;
3695 currSCCB
->Sccb_ATC
= 0x00;
3697 currSCCB
->Sccb_XferState
|= F_AUTO_SENSE
;
3699 currSCCB
->Sccb_XferState
&= ~F_SG_XFER
;
3701 currSCCB
->Sccb_idmsg
= currSCCB
->Sccb_idmsg
& ~(unsigned char)DISC_PRIV
;
3703 currSCCB
->ControlByte
= 0x00;
3705 currSCCB
->Sccb_MGRFlags
&= F_STATUSLOADED
;
3708 /*---------------------------------------------------------------------
3710 * Function: FPT_sxfrp
3712 * Description: Transfer data into the bit bucket until the device
3713 * decides to switch phase.
3715 *---------------------------------------------------------------------*/
3717 static void FPT_sxfrp(u32 p_port
, unsigned char p_card
)
3719 unsigned char curr_phz
;
3721 DISABLE_AUTO(p_port
);
3723 if (FPT_BL_Card
[p_card
].globalFlags
& F_HOST_XFER_ACT
) {
3725 FPT_hostDataXferAbort(p_port
, p_card
,
3726 FPT_BL_Card
[p_card
].currentSCCB
);
3730 /* If the Automation handled the end of the transfer then do not
3731 match the phase or we will get out of sync with the ISR. */
3733 if (RDW_HARPOON((p_port
+ hp_intstat
)) &
3734 (BUS_FREE
| XFER_CNT_0
| AUTO_INT
))
3737 WR_HARPOON(p_port
+ hp_xfercnt_0
, 0x00);
3739 curr_phz
= RD_HARPOON(p_port
+ hp_scsisig
) & (unsigned char)S_SCSI_PHZ
;
3741 WRW_HARPOON((p_port
+ hp_intstat
), XFER_CNT_0
);
3743 WR_HARPOON(p_port
+ hp_scsisig
, curr_phz
);
3745 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & (BUS_FREE
| RESET
)) &&
3747 (RD_HARPOON(p_port
+ hp_scsisig
) & (unsigned char)S_SCSI_PHZ
)))
3749 if (curr_phz
& (unsigned char)SCSI_IOBIT
) {
3750 WR_HARPOON(p_port
+ hp_portctrl_0
,
3751 (SCSI_PORT
| HOST_PORT
| SCSI_INBIT
));
3753 if (!(RD_HARPOON(p_port
+ hp_xferstat
) & FIFO_EMPTY
)) {
3754 RD_HARPOON(p_port
+ hp_fifodata_0
);
3757 WR_HARPOON(p_port
+ hp_portctrl_0
,
3758 (SCSI_PORT
| HOST_PORT
| HOST_WRT
));
3759 if (RD_HARPOON(p_port
+ hp_xferstat
) & FIFO_EMPTY
) {
3760 WR_HARPOON(p_port
+ hp_fifodata_0
, 0xFA);
3763 } /* End of While loop for padding data I/O phase */
3765 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & (BUS_FREE
| RESET
))) {
3766 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_REQ
)
3770 WR_HARPOON(p_port
+ hp_portctrl_0
,
3771 (SCSI_PORT
| HOST_PORT
| SCSI_INBIT
));
3772 while (!(RD_HARPOON(p_port
+ hp_xferstat
) & FIFO_EMPTY
)) {
3773 RD_HARPOON(p_port
+ hp_fifodata_0
);
3776 if (!(RDW_HARPOON((p_port
+ hp_intstat
)) & (BUS_FREE
| RESET
))) {
3777 WR_HARPOON(p_port
+ hp_autostart_0
,
3778 (AUTO_IMMED
+ DISCONNECT_START
));
3779 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & AUTO_INT
)) {
3782 if (RDW_HARPOON((p_port
+ hp_intstat
)) &
3783 (ICMD_COMP
| ITAR_DISC
))
3785 (RDW_HARPOON((p_port
+ hp_intstat
)) &
3786 (BUS_FREE
| RSEL
))) ;
3790 /*---------------------------------------------------------------------
3792 * Function: FPT_schkdd
3794 * Description: Make sure data has been flushed from both FIFOs and abort
3795 * the operations if necessary.
3797 *---------------------------------------------------------------------*/
3799 static void FPT_schkdd(u32 port
, unsigned char p_card
)
3801 unsigned short TimeOutLoop
;
3802 unsigned char sPhase
;
3804 struct sccb
*currSCCB
;
3806 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3808 if ((currSCCB
->Sccb_scsistat
!= DATA_OUT_ST
) &&
3809 (currSCCB
->Sccb_scsistat
!= DATA_IN_ST
)) {
3813 if (currSCCB
->Sccb_XferState
& F_ODD_BALL_CNT
) {
3815 currSCCB
->Sccb_ATC
+= (currSCCB
->Sccb_XferCnt
- 1);
3817 currSCCB
->Sccb_XferCnt
= 1;
3819 currSCCB
->Sccb_XferState
&= ~F_ODD_BALL_CNT
;
3820 WRW_HARPOON((port
+ hp_fiforead
), (unsigned short)0x00);
3821 WR_HARPOON(port
+ hp_xferstat
, 0x00);
3826 currSCCB
->Sccb_ATC
+= currSCCB
->Sccb_XferCnt
;
3828 currSCCB
->Sccb_XferCnt
= 0;
3831 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
3832 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
3834 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
3835 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
3838 FPT_hostDataXferAbort(port
, p_card
, currSCCB
);
3840 while (RD_HARPOON(port
+ hp_scsisig
) & SCSI_ACK
) {
3845 while (RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
) {
3846 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
3849 if (RD_HARPOON(port
+ hp_offsetctr
) & (unsigned char)0x1F) {
3852 if (RDW_HARPOON((port
+ hp_intstat
)) & RESET
) {
3855 if ((RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)
3856 || (TimeOutLoop
++ > 0x3000))
3860 sPhase
= RD_HARPOON(port
+ hp_scsisig
) & (SCSI_BSY
| S_SCSI_PHZ
);
3861 if ((!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
)) ||
3862 (RD_HARPOON(port
+ hp_offsetctr
) & (unsigned char)0x1F) ||
3863 (sPhase
== (SCSI_BSY
| S_DATAO_PH
)) ||
3864 (sPhase
== (SCSI_BSY
| S_DATAI_PH
))) {
3866 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
3868 if (!(currSCCB
->Sccb_XferState
& F_ALL_XFERRED
)) {
3869 if (currSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
3870 FPT_phaseDataIn(port
, p_card
);
3874 FPT_phaseDataOut(port
, p_card
);
3877 FPT_sxfrp(port
, p_card
);
3878 if (!(RDW_HARPOON((port
+ hp_intstat
)) &
3879 (BUS_FREE
| ICMD_COMP
| ITAR_DISC
| RESET
))) {
3880 WRW_HARPOON((port
+ hp_intstat
), AUTO_INT
);
3881 FPT_phaseDecode(port
, p_card
);
3888 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
3892 /*---------------------------------------------------------------------
3894 * Function: FPT_sinits
3896 * Description: Setup SCCB manager fields in this SCCB.
3898 *---------------------------------------------------------------------*/
3900 static void FPT_sinits(struct sccb
*p_sccb
, unsigned char p_card
)
3902 struct sccb_mgr_tar_info
*currTar_Info
;
3904 if ((p_sccb
->TargID
>= MAX_SCSI_TAR
) || (p_sccb
->Lun
>= MAX_LUN
)) {
3907 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
3909 p_sccb
->Sccb_XferState
= 0x00;
3910 p_sccb
->Sccb_XferCnt
= p_sccb
->DataLength
;
3912 if ((p_sccb
->OperationCode
== SCATTER_GATHER_COMMAND
) ||
3913 (p_sccb
->OperationCode
== RESIDUAL_SG_COMMAND
)) {
3915 p_sccb
->Sccb_SGoffset
= 0;
3916 p_sccb
->Sccb_XferState
= F_SG_XFER
;
3917 p_sccb
->Sccb_XferCnt
= 0x00;
3920 if (p_sccb
->DataLength
== 0x00)
3922 p_sccb
->Sccb_XferState
|= F_ALL_XFERRED
;
3924 if (p_sccb
->ControlByte
& F_USE_CMD_Q
) {
3925 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_REJECT
)
3926 p_sccb
->ControlByte
&= ~F_USE_CMD_Q
;
3929 currTar_Info
->TarStatus
|= TAG_Q_TRYING
;
3932 /* For !single SCSI device in system & device allow Disconnect
3933 or command is tag_q type then send Cmd with Disconnect Enable
3934 else send Cmd with Disconnect Disable */
3937 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3938 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3939 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3941 if ((currTar_Info
->TarStatus
& TAR_ALLOW_DISC
) ||
3942 (currTar_Info
->TarStatus
& TAG_Q_TRYING
)) {
3943 p_sccb
->Sccb_idmsg
=
3944 (unsigned char)(SMIDENT
| DISC_PRIV
) | p_sccb
->Lun
;
3949 p_sccb
->Sccb_idmsg
= (unsigned char)SMIDENT
| p_sccb
->Lun
;
3952 p_sccb
->HostStatus
= 0x00;
3953 p_sccb
->TargetStatus
= 0x00;
3954 p_sccb
->Sccb_tag
= 0x00;
3955 p_sccb
->Sccb_MGRFlags
= 0x00;
3956 p_sccb
->Sccb_sgseg
= 0x00;
3957 p_sccb
->Sccb_ATC
= 0x00;
3958 p_sccb
->Sccb_savedATC
= 0x00;
3960 p_sccb->SccbVirtDataPtr = 0x00;
3961 p_sccb->Sccb_forwardlink = NULL;
3962 p_sccb->Sccb_backlink = NULL;
3964 p_sccb
->Sccb_scsistat
= BUS_FREE_ST
;
3965 p_sccb
->SccbStatus
= SCCB_IN_PROCESS
;
3966 p_sccb
->Sccb_scsimsg
= SMNO_OP
;
3970 /*---------------------------------------------------------------------
3972 * Function: Phase Decode
3974 * Description: Determine the phase and call the appropriate function.
3976 *---------------------------------------------------------------------*/
3978 static void FPT_phaseDecode(u32 p_port
, unsigned char p_card
)
3980 unsigned char phase_ref
;
3981 void (*phase
) (u32
, unsigned char);
3983 DISABLE_AUTO(p_port
);
3986 (unsigned char)(RD_HARPOON(p_port
+ hp_scsisig
) & S_SCSI_PHZ
);
3988 phase
= FPT_s_PhaseTbl
[phase_ref
];
3990 (*phase
) (p_port
, p_card
); /* Call the correct phase func */
3993 /*---------------------------------------------------------------------
3995 * Function: Data Out Phase
3997 * Description: Start up both the BusMaster and Xbow.
3999 *---------------------------------------------------------------------*/
4001 static void FPT_phaseDataOut(u32 port
, unsigned char p_card
)
4004 struct sccb
*currSCCB
;
4006 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4007 if (currSCCB
== NULL
) {
4008 return; /* Exit if No SCCB record */
4011 currSCCB
->Sccb_scsistat
= DATA_OUT_ST
;
4012 currSCCB
->Sccb_XferState
&= ~(F_HOST_XFER_DIR
| F_NO_DATA_YET
);
4014 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
4016 WRW_HARPOON((port
+ hp_intstat
), XFER_CNT_0
);
4018 WR_HARPOON(port
+ hp_autostart_0
, (END_DATA
+ END_DATA_START
));
4020 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4022 if (currSCCB
->Sccb_XferCnt
== 0) {
4024 if ((currSCCB
->ControlByte
& SCCB_DATA_XFER_OUT
) &&
4025 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4026 currSCCB
->HostStatus
= SCCB_DATA_OVER_RUN
;
4028 FPT_sxfrp(port
, p_card
);
4029 if (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| RESET
)))
4030 FPT_phaseDecode(port
, p_card
);
4034 /*---------------------------------------------------------------------
4036 * Function: Data In Phase
4038 * Description: Startup the BusMaster and the XBOW.
4040 *---------------------------------------------------------------------*/
4042 static void FPT_phaseDataIn(u32 port
, unsigned char p_card
)
4045 struct sccb
*currSCCB
;
4047 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4049 if (currSCCB
== NULL
) {
4050 return; /* Exit if No SCCB record */
4053 currSCCB
->Sccb_scsistat
= DATA_IN_ST
;
4054 currSCCB
->Sccb_XferState
|= F_HOST_XFER_DIR
;
4055 currSCCB
->Sccb_XferState
&= ~F_NO_DATA_YET
;
4057 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
4059 WRW_HARPOON((port
+ hp_intstat
), XFER_CNT_0
);
4061 WR_HARPOON(port
+ hp_autostart_0
, (END_DATA
+ END_DATA_START
));
4063 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4065 if (currSCCB
->Sccb_XferCnt
== 0) {
4067 if ((currSCCB
->ControlByte
& SCCB_DATA_XFER_IN
) &&
4068 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4069 currSCCB
->HostStatus
= SCCB_DATA_OVER_RUN
;
4071 FPT_sxfrp(port
, p_card
);
4072 if (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| RESET
)))
4073 FPT_phaseDecode(port
, p_card
);
4078 /*---------------------------------------------------------------------
4080 * Function: Command Phase
4082 * Description: Load the CDB into the automation and start it up.
4084 *---------------------------------------------------------------------*/
4086 static void FPT_phaseCommand(u32 p_port
, unsigned char p_card
)
4088 struct sccb
*currSCCB
;
4092 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4094 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
4096 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4097 currSCCB
->CdbLength
= SIX_BYTE_CMD
;
4100 WR_HARPOON(p_port
+ hp_scsisig
, 0x00);
4102 ARAM_ACCESS(p_port
);
4104 cdb_reg
= p_port
+ CMD_STRT
;
4106 for (i
= 0; i
< currSCCB
->CdbLength
; i
++) {
4108 if (currSCCB
->OperationCode
== RESET_COMMAND
)
4110 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ 0x00));
4113 WRW_HARPOON(cdb_reg
,
4114 (MPM_OP
+ ACOMMAND
+ currSCCB
->Cdb
[i
]));
4118 if (currSCCB
->CdbLength
!= TWELVE_BYTE_CMD
)
4119 WRW_HARPOON(cdb_reg
, (BRH_OP
+ ALWAYS
+ NP
));
4121 WR_HARPOON(p_port
+ hp_portctrl_0
, (SCSI_PORT
));
4123 currSCCB
->Sccb_scsistat
= COMMAND_ST
;
4125 WR_HARPOON(p_port
+ hp_autostart_3
, (AUTO_IMMED
| CMD_ONLY_STRT
));
4126 SGRAM_ACCESS(p_port
);
4129 /*---------------------------------------------------------------------
4131 * Function: Status phase
4133 * Description: Bring in the status and command complete message bytes
4135 *---------------------------------------------------------------------*/
4137 static void FPT_phaseStatus(u32 port
, unsigned char p_card
)
4139 /* Start-up the automation to finish off this command and let the
4140 isr handle the interrupt for command complete when it comes in.
4141 We could wait here for the interrupt to be generated?
4144 WR_HARPOON(port
+ hp_scsisig
, 0x00);
4146 WR_HARPOON(port
+ hp_autostart_0
, (AUTO_IMMED
+ END_DATA_START
));
4149 /*---------------------------------------------------------------------
4151 * Function: Phase Message Out
4153 * Description: Send out our message (if we have one) and handle whatever
4156 *---------------------------------------------------------------------*/
4158 static void FPT_phaseMsgOut(u32 port
, unsigned char p_card
)
4160 unsigned char message
, scsiID
;
4161 struct sccb
*currSCCB
;
4162 struct sccb_mgr_tar_info
*currTar_Info
;
4164 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4166 if (currSCCB
!= NULL
) {
4168 message
= currSCCB
->Sccb_scsimsg
;
4169 scsiID
= currSCCB
->TargID
;
4171 if (message
== SMDEV_RESET
) {
4173 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scsiID
];
4174 currTar_Info
->TarSyncCtrl
= 0;
4175 FPT_sssyncv(port
, scsiID
, NARROW_SCSI
, currTar_Info
);
4177 if (FPT_sccbMgrTbl
[p_card
][scsiID
].
4178 TarEEValue
& EE_SYNC_MASK
) {
4180 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
&=
4185 if (FPT_sccbMgrTbl
[p_card
][scsiID
].
4186 TarEEValue
& EE_WIDE_SCSI
) {
4188 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
&=
4192 FPT_queueFlushSccb(p_card
, SCCB_COMPLETE
);
4193 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
4194 } else if (currSCCB
->Sccb_scsistat
== ABORT_ST
) {
4195 currSCCB
->HostStatus
= SCCB_COMPLETE
;
4196 if (FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] !=
4198 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4200 FPT_sccbMgrTbl
[p_card
][scsiID
].TarTagQ_Cnt
--;
4205 else if (currSCCB
->Sccb_scsistat
< COMMAND_ST
) {
4207 if (message
== SMNO_OP
) {
4208 currSCCB
->Sccb_MGRFlags
|= F_DEV_SELECTED
;
4210 FPT_ssel(port
, p_card
);
4215 if (message
== SMABORT
)
4217 FPT_queueFlushSccb(p_card
, SCCB_COMPLETE
);
4224 WRW_HARPOON((port
+ hp_intstat
), (BUS_FREE
| PHASE
| XFER_CNT_0
));
4226 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_BUS_EN
);
4228 WR_HARPOON(port
+ hp_scsidata_0
, message
);
4230 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
4234 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
4236 if ((message
== SMABORT
) || (message
== SMDEV_RESET
) ||
4237 (message
== SMABORT_TAG
)) {
4239 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| PHASE
))) {
4242 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
4243 WRW_HARPOON((port
+ hp_intstat
), BUS_FREE
);
4245 if (currSCCB
!= NULL
) {
4247 if ((FPT_BL_Card
[p_card
].
4248 globalFlags
& F_CONLUN_IO
)
4250 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4251 TarStatus
& TAR_TAG_Q_MASK
) !=
4253 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4255 TarLUNBusy
[currSCCB
->Lun
] = 0;
4257 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4261 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],
4266 FPT_BL_Card
[p_card
].globalFlags
|=
4273 FPT_sxfrp(port
, p_card
);
4279 if (message
== SMPARITY
) {
4280 currSCCB
->Sccb_scsimsg
= SMNO_OP
;
4281 WR_HARPOON(port
+ hp_autostart_1
,
4282 (AUTO_IMMED
+ DISCONNECT_START
));
4284 FPT_sxfrp(port
, p_card
);
4289 /*---------------------------------------------------------------------
4291 * Function: Message In phase
4293 * Description: Bring in the message and determine what to do with it.
4295 *---------------------------------------------------------------------*/
4297 static void FPT_phaseMsgIn(u32 port
, unsigned char p_card
)
4299 unsigned char message
;
4300 struct sccb
*currSCCB
;
4302 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4304 if (FPT_BL_Card
[p_card
].globalFlags
& F_HOST_XFER_ACT
) {
4306 FPT_phaseChkFifo(port
, p_card
);
4309 message
= RD_HARPOON(port
+ hp_scsidata_0
);
4310 if ((message
== SMDISC
) || (message
== SMSAVE_DATA_PTR
)) {
4312 WR_HARPOON(port
+ hp_autostart_1
,
4313 (AUTO_IMMED
+ END_DATA_START
));
4319 message
= FPT_sfm(port
, currSCCB
);
4322 FPT_sdecm(message
, port
, p_card
);
4325 if (currSCCB
->Sccb_scsimsg
!= SMPARITY
)
4327 WR_HARPOON(port
+ hp_autostart_1
,
4328 (AUTO_IMMED
+ DISCONNECT_START
));
4334 /*---------------------------------------------------------------------
4336 * Function: Illegal phase
4338 * Description: Target switched to some illegal phase, so all we can do
4339 * is report an error back to the host (if that is possible)
4340 * and send an ABORT message to the misbehaving target.
4342 *---------------------------------------------------------------------*/
4344 static void FPT_phaseIllegal(u32 port
, unsigned char p_card
)
4346 struct sccb
*currSCCB
;
4348 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4350 WR_HARPOON(port
+ hp_scsisig
, RD_HARPOON(port
+ hp_scsisig
));
4351 if (currSCCB
!= NULL
) {
4353 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4354 currSCCB
->Sccb_scsistat
= ABORT_ST
;
4355 currSCCB
->Sccb_scsimsg
= SMABORT
;
4358 ACCEPT_MSG_ATN(port
);
4361 /*---------------------------------------------------------------------
4363 * Function: Phase Check FIFO
4365 * Description: Make sure data has been flushed from both FIFOs and abort
4366 * the operations if necessary.
4368 *---------------------------------------------------------------------*/
4370 static void FPT_phaseChkFifo(u32 port
, unsigned char p_card
)
4373 struct sccb
*currSCCB
;
4375 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4377 if (currSCCB
->Sccb_scsistat
== DATA_IN_ST
) {
4379 while ((!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
)) &&
4380 (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
)) {
4383 if (!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
)) {
4384 currSCCB
->Sccb_ATC
+= currSCCB
->Sccb_XferCnt
;
4386 currSCCB
->Sccb_XferCnt
= 0;
4388 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
4389 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
4390 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4391 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
4394 FPT_hostDataXferAbort(port
, p_card
, currSCCB
);
4396 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4398 while ((!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
))
4399 && (RD_HARPOON(port
+ hp_ext_status
) &
4406 /*End Data In specific code. */
4407 GET_XFER_CNT(port
, xfercnt
);
4409 WR_HARPOON(port
+ hp_xfercnt_0
, 0x00);
4411 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
4413 currSCCB
->Sccb_ATC
+= (currSCCB
->Sccb_XferCnt
- xfercnt
);
4415 currSCCB
->Sccb_XferCnt
= xfercnt
;
4417 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
4418 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
4420 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4421 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
4424 FPT_hostDataXferAbort(port
, p_card
, currSCCB
);
4426 WR_HARPOON(port
+ hp_fifowrite
, 0x00);
4427 WR_HARPOON(port
+ hp_fiforead
, 0x00);
4428 WR_HARPOON(port
+ hp_xferstat
, 0x00);
4430 WRW_HARPOON((port
+ hp_intstat
), XFER_CNT_0
);
4433 /*---------------------------------------------------------------------
4435 * Function: Phase Bus Free
4437 * Description: We just went bus free so figure out if it was
4438 * because of command complete or from a disconnect.
4440 *---------------------------------------------------------------------*/
4441 static void FPT_phaseBusFree(u32 port
, unsigned char p_card
)
4443 struct sccb
*currSCCB
;
4445 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4447 if (currSCCB
!= NULL
) {
4451 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
4453 if ((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4454 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4455 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4456 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4457 TarLUNBusy
[currSCCB
->Lun
] = 0;
4459 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4462 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
,
4465 FPT_queueSearchSelect(&FPT_BL_Card
[p_card
], p_card
);
4469 else if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
4470 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|=
4471 (unsigned char)SYNC_SUPPORTED
;
4472 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4476 else if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
4477 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
=
4478 (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4479 TarStatus
& ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
4481 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4485 else if (currSCCB
->Sccb_scsistat
== SELECT_Q_ST
) {
4486 /* Make sure this is not a phony BUS_FREE. If we were
4487 reselected or if BUSY is NOT on then this is a
4488 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4490 if ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) ||
4491 (RDW_HARPOON((port
+ hp_intstat
)) & RSEL
)) {
4492 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4493 TarStatus
&= ~TAR_TAG_Q_MASK
;
4494 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4495 TarStatus
|= TAG_Q_REJECT
;
4505 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
4507 if (!currSCCB
->HostStatus
) {
4508 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4511 if ((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4512 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4513 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4514 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4515 TarLUNBusy
[currSCCB
->Lun
] = 0;
4517 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4520 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
,
4525 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4527 } /*end if !=null */
4530 /*---------------------------------------------------------------------
4532 * Function: Auto Load Default Map
4534 * Description: Load the Automation RAM with the defualt map values.
4536 *---------------------------------------------------------------------*/
4537 static void FPT_autoLoadDefaultMap(u32 p_port
)
4541 ARAM_ACCESS(p_port
);
4542 map_addr
= p_port
+ hp_aramBase
;
4544 WRW_HARPOON(map_addr
, (MPM_OP
+ AMSG_OUT
+ 0xC0)); /*ID MESSAGE */
4546 WRW_HARPOON(map_addr
, (MPM_OP
+ AMSG_OUT
+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4548 WRW_HARPOON(map_addr
, RAT_OP
); /*RESET ATTENTION */
4550 WRW_HARPOON(map_addr
, (MPM_OP
+ AMSG_OUT
+ 0x00)); /*TAG ID MSG */
4552 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 0 */
4554 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 1 */
4556 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 2 */
4558 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 3 */
4560 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 4 */
4562 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 5 */
4564 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 6 */
4566 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 7 */
4568 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 8 */
4570 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 9 */
4572 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 10 */
4574 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 11 */
4576 WRW_HARPOON(map_addr
, (CPE_OP
+ ADATA_OUT
+ DINT
)); /*JUMP IF DATA OUT */
4578 WRW_HARPOON(map_addr
, (TCB_OP
+ FIFO_0
+ DI
)); /*JUMP IF NO DATA IN FIFO */
4579 map_addr
+= 2; /*This means AYNC DATA IN */
4580 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IDO_STRT
)); /*STOP AND INTERRUPT */
4582 WRW_HARPOON(map_addr
, (CPE_OP
+ ADATA_IN
+ DINT
)); /*JUMP IF NOT DATA IN PHZ */
4584 WRW_HARPOON(map_addr
, (CPN_OP
+ AMSG_IN
+ ST
)); /*IF NOT MSG IN CHECK 4 DATA IN */
4586 WRW_HARPOON(map_addr
, (CRD_OP
+ SDATA
+ 0x02)); /*SAVE DATA PTR MSG? */
4588 WRW_HARPOON(map_addr
, (BRH_OP
+ NOT_EQ
+ DC
)); /*GO CHECK FOR DISCONNECT MSG */
4590 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_AR1
)); /*SAVE DATA PTRS MSG */
4592 WRW_HARPOON(map_addr
, (CPN_OP
+ AMSG_IN
+ ST
)); /*IF NOT MSG IN CHECK DATA IN */
4594 WRW_HARPOON(map_addr
, (CRD_OP
+ SDATA
+ 0x04)); /*DISCONNECT MSG? */
4596 WRW_HARPOON(map_addr
, (BRH_OP
+ NOT_EQ
+ UNKNWN
)); /*UKNKNOWN MSG */
4598 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_BUCKET
)); /*XFER DISCONNECT MSG */
4600 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ITAR_DISC
)); /*STOP AND INTERRUPT */
4602 WRW_HARPOON(map_addr
, (CPN_OP
+ ASTATUS
+ UNKNWN
)); /*JUMP IF NOT STATUS PHZ. */
4604 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_AR0
)); /*GET STATUS BYTE */
4606 WRW_HARPOON(map_addr
, (CPN_OP
+ AMSG_IN
+ CC
)); /*ERROR IF NOT MSG IN PHZ */
4608 WRW_HARPOON(map_addr
, (CRD_OP
+ SDATA
+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4610 WRW_HARPOON(map_addr
, (BRH_OP
+ NOT_EQ
+ CC
)); /*ERROR IF NOT CMD COMPLETE MSG. */
4612 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_BUCKET
)); /*GET CMD COMPLETE MSG */
4614 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ICMD_COMP
)); /*END OF COMMAND */
4617 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IUNKWN
)); /*RECEIVED UNKNOWN MSG BYTE */
4619 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_INO_CC
)); /*NO COMMAND COMPLETE AFTER STATUS */
4621 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ITICKLE
)); /*BIOS Tickled the Mgr */
4623 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IRFAIL
)); /*EXPECTED ID/TAG MESSAGES AND */
4624 map_addr
+= 2; /* DIDN'T GET ONE */
4625 WRW_HARPOON(map_addr
, (CRR_OP
+ AR3
+ S_IDREG
)); /* comp SCSI SEL ID & AR3 */
4627 WRW_HARPOON(map_addr
, (BRH_OP
+ EQUAL
+ 0x00)); /*SEL ID OK then Conti. */
4629 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_INO_CC
)); /*NO COMMAND COMPLETE AFTER STATUS */
4631 SGRAM_ACCESS(p_port
);
4634 /*---------------------------------------------------------------------
4636 * Function: Auto Command Complete
4638 * Description: Post command back to host and find another command
4641 *---------------------------------------------------------------------*/
4643 static void FPT_autoCmdCmplt(u32 p_port
, unsigned char p_card
)
4645 struct sccb
*currSCCB
;
4646 unsigned char status_byte
;
4648 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4650 status_byte
= RD_HARPOON(p_port
+ hp_gp_reg_0
);
4652 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUN_CA
= 0;
4654 if (status_byte
!= SSGOOD
) {
4656 if (status_byte
== SSQ_FULL
) {
4658 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4659 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4660 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
4661 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4662 TarLUNBusy
[currSCCB
->Lun
] = 1;
4663 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4664 FPT_BL_Card
[p_card
].discQCount
--;
4665 FPT_BL_Card
[p_card
].
4666 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4668 LunDiscQ_Idx
[currSCCB
->Lun
]] =
4671 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4673 if (currSCCB
->Sccb_tag
) {
4674 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4675 FPT_BL_Card
[p_card
].
4677 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4681 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4682 FPT_BL_Card
[p_card
].
4684 FPT_BL_Card
[p_card
].
4685 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4687 LunDiscQ_Idx
[0]] = NULL
;
4691 currSCCB
->Sccb_MGRFlags
|= F_STATUSLOADED
;
4693 FPT_queueSelectFail(&FPT_BL_Card
[p_card
], p_card
);
4698 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
4699 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|=
4700 (unsigned char)SYNC_SUPPORTED
;
4702 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4704 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4706 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4707 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4708 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
4709 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4710 TarLUNBusy
[currSCCB
->Lun
] = 1;
4711 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4712 FPT_BL_Card
[p_card
].discQCount
--;
4713 FPT_BL_Card
[p_card
].
4714 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4716 LunDiscQ_Idx
[currSCCB
->Lun
]] =
4719 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4721 if (currSCCB
->Sccb_tag
) {
4722 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4723 FPT_BL_Card
[p_card
].
4725 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4729 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4730 FPT_BL_Card
[p_card
].
4732 FPT_BL_Card
[p_card
].
4733 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4735 LunDiscQ_Idx
[0]] = NULL
;
4742 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
4744 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
=
4745 (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4746 TarStatus
& ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
4748 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4750 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4752 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4753 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4754 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
4755 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4756 TarLUNBusy
[currSCCB
->Lun
] = 1;
4757 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4758 FPT_BL_Card
[p_card
].discQCount
--;
4759 FPT_BL_Card
[p_card
].
4760 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4762 LunDiscQ_Idx
[currSCCB
->Lun
]] =
4765 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4767 if (currSCCB
->Sccb_tag
) {
4768 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4769 FPT_BL_Card
[p_card
].
4771 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4775 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4776 FPT_BL_Card
[p_card
].
4778 FPT_BL_Card
[p_card
].
4779 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4781 LunDiscQ_Idx
[0]] = NULL
;
4788 if (status_byte
== SSCHECK
) {
4789 if (FPT_BL_Card
[p_card
].globalFlags
& F_DO_RENEGO
) {
4790 if (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4791 TarEEValue
& EE_SYNC_MASK
) {
4792 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4794 TarStatus
&= ~TAR_SYNC_MASK
;
4796 if (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4797 TarEEValue
& EE_WIDE_SCSI
) {
4798 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4800 TarStatus
&= ~TAR_WIDE_MASK
;
4805 if (!(currSCCB
->Sccb_XferState
& F_AUTO_SENSE
)) {
4807 currSCCB
->SccbStatus
= SCCB_ERROR
;
4808 currSCCB
->TargetStatus
= status_byte
;
4810 if (status_byte
== SSCHECK
) {
4812 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4815 if (currSCCB
->RequestSenseLength
!=
4816 NO_AUTO_REQUEST_SENSE
) {
4818 if (currSCCB
->RequestSenseLength
== 0)
4819 currSCCB
->RequestSenseLength
=
4822 FPT_ssenss(&FPT_BL_Card
[p_card
]);
4823 FPT_BL_Card
[p_card
].globalFlags
|=
4826 if (((FPT_BL_Card
[p_card
].
4827 globalFlags
& F_CONLUN_IO
)
4829 ((FPT_sccbMgrTbl
[p_card
]
4831 TarStatus
& TAR_TAG_Q_MASK
) !=
4833 FPT_sccbMgrTbl
[p_card
]
4835 TarLUNBusy
[currSCCB
->Lun
] =
4837 if (FPT_BL_Card
[p_card
].
4839 FPT_BL_Card
[p_card
].
4841 FPT_BL_Card
[p_card
].
4842 discQ_Tbl
[FPT_sccbMgrTbl
4850 FPT_sccbMgrTbl
[p_card
]
4853 if (currSCCB
->Sccb_tag
) {
4854 if (FPT_BL_Card
[p_card
].
4859 FPT_BL_Card
[p_card
].
4860 discQ_Tbl
[currSCCB
->
4864 if (FPT_BL_Card
[p_card
].
4869 FPT_BL_Card
[p_card
].
4884 if ((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4885 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4886 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4887 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->
4890 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 0;
4892 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
, p_card
);
4895 #define SHORT_WAIT 0x0000000F
4896 #define LONG_WAIT 0x0000FFFFL
4898 /*---------------------------------------------------------------------
4900 * Function: Data Transfer Processor
4902 * Description: This routine performs two tasks.
4903 * (1) Start data transfer by calling HOST_DATA_XFER_START
4904 * function. Once data transfer is started, (2) Depends
4905 * on the type of data transfer mode Scatter/Gather mode
4906 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4907 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4908 * data transfer done. In Scatter/Gather mode, this routine
4909 * checks bus master command complete and dual rank busy
4910 * bit to keep chaining SC transfer command. Similarly,
4911 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4912 * (F_HOST_XFER_ACT bit) for data transfer done.
4914 *---------------------------------------------------------------------*/
4916 static void FPT_dataXferProcessor(u32 port
, struct sccb_card
*pCurrCard
)
4918 struct sccb
*currSCCB
;
4920 currSCCB
= pCurrCard
->currentSCCB
;
4922 if (currSCCB
->Sccb_XferState
& F_SG_XFER
) {
4923 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
4925 currSCCB
->Sccb_sgseg
+= (unsigned char)SG_BUF_CNT
;
4926 currSCCB
->Sccb_SGoffset
= 0x00;
4928 pCurrCard
->globalFlags
|= F_HOST_XFER_ACT
;
4930 FPT_busMstrSGDataXferStart(port
, currSCCB
);
4934 if (!(pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)) {
4935 pCurrCard
->globalFlags
|= F_HOST_XFER_ACT
;
4937 FPT_busMstrDataXferStart(port
, currSCCB
);
4942 /*---------------------------------------------------------------------
4944 * Function: BusMaster Scatter Gather Data Transfer Start
4948 *---------------------------------------------------------------------*/
4949 static void FPT_busMstrSGDataXferStart(u32 p_port
, struct sccb
*pcurrSCCB
)
4951 u32 count
, addr
, tmpSGCnt
;
4952 unsigned int sg_index
;
4953 unsigned char sg_count
, i
;
4955 struct blogic_sg_seg
*segp
;
4957 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
)
4958 count
= ((u32
)HOST_RD_CMD
) << 24;
4960 count
= ((u32
)HOST_WRT_CMD
) << 24;
4964 sg_index
= pcurrSCCB
->Sccb_sgseg
;
4965 reg_offset
= hp_aramBase
;
4967 i
= (unsigned char)(RD_HARPOON(p_port
+ hp_page_ctrl
) &
4968 ~(SGRAM_ARAM
| SCATTER_EN
));
4970 WR_HARPOON(p_port
+ hp_page_ctrl
, i
);
4972 while ((sg_count
< (unsigned char)SG_BUF_CNT
) &&
4973 ((sg_index
* (unsigned int)SG_ELEMENT_SIZE
) <
4974 pcurrSCCB
->DataLength
)) {
4976 segp
= (struct blogic_sg_seg
*)(pcurrSCCB
->DataPointer
) +
4978 tmpSGCnt
+= segp
->segbytes
;
4979 count
|= segp
->segbytes
;
4980 addr
= segp
->segdata
;
4982 if ((!sg_count
) && (pcurrSCCB
->Sccb_SGoffset
)) {
4984 ((count
& 0x00FFFFFFL
) - pcurrSCCB
->Sccb_SGoffset
);
4986 (count
& 0xFF000000L
) | pcurrSCCB
->Sccb_SGoffset
;
4987 tmpSGCnt
= count
& 0x00FFFFFFL
;
4990 WR_HARP32(p_port
, reg_offset
, addr
);
4993 WR_HARP32(p_port
, reg_offset
, count
);
4996 count
&= 0xFF000000L
;
5002 pcurrSCCB
->Sccb_XferCnt
= tmpSGCnt
;
5004 WR_HARPOON(p_port
+ hp_sg_addr
, (sg_count
<< 4));
5006 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5008 WR_HARP32(p_port
, hp_xfercnt_0
, tmpSGCnt
);
5010 WR_HARPOON(p_port
+ hp_portctrl_0
,
5011 (DMA_PORT
| SCSI_PORT
| SCSI_INBIT
));
5012 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAI_PH
);
5017 if ((!(RD_HARPOON(p_port
+ hp_synctarg_0
) & NARROW_SCSI
)) &&
5018 (tmpSGCnt
& 0x000000001)) {
5020 pcurrSCCB
->Sccb_XferState
|= F_ODD_BALL_CNT
;
5024 WR_HARP32(p_port
, hp_xfercnt_0
, tmpSGCnt
);
5026 WR_HARPOON(p_port
+ hp_portctrl_0
,
5027 (SCSI_PORT
| DMA_PORT
| DMA_RD
));
5028 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAO_PH
);
5031 WR_HARPOON(p_port
+ hp_page_ctrl
, (unsigned char)(i
| SCATTER_EN
));
5035 /*---------------------------------------------------------------------
5037 * Function: BusMaster Data Transfer Start
5041 *---------------------------------------------------------------------*/
5042 static void FPT_busMstrDataXferStart(u32 p_port
, struct sccb
*pcurrSCCB
)
5046 if (!(pcurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
)) {
5048 count
= pcurrSCCB
->Sccb_XferCnt
;
5050 addr
= (u32
)(unsigned long)pcurrSCCB
->DataPointer
+ pcurrSCCB
->Sccb_ATC
;
5054 addr
= pcurrSCCB
->SensePointer
;
5055 count
= pcurrSCCB
->RequestSenseLength
;
5059 HP_SETUP_ADDR_CNT(p_port
, addr
, count
);
5061 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5063 WR_HARPOON(p_port
+ hp_portctrl_0
,
5064 (DMA_PORT
| SCSI_PORT
| SCSI_INBIT
));
5065 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAI_PH
);
5067 WR_HARPOON(p_port
+ hp_xfer_cmd
,
5068 (XFER_DMA_HOST
| XFER_HOST_AUTO
| XFER_DMA_8BIT
));
5073 WR_HARPOON(p_port
+ hp_portctrl_0
,
5074 (SCSI_PORT
| DMA_PORT
| DMA_RD
));
5075 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAO_PH
);
5077 WR_HARPOON(p_port
+ hp_xfer_cmd
,
5078 (XFER_HOST_DMA
| XFER_HOST_AUTO
| XFER_DMA_8BIT
));
5083 /*---------------------------------------------------------------------
5085 * Function: BusMaster Timeout Handler
5087 * Description: This function is called after a bus master command busy time
5088 * out is detected. This routines issue halt state machine
5089 * with a software time out for command busy. If command busy
5090 * is still asserted at the end of the time out, it issues
5091 * hard abort with another software time out. It hard abort
5092 * command busy is also time out, it'll just give up.
5094 *---------------------------------------------------------------------*/
5095 static unsigned char FPT_busMstrTimeOut(u32 p_port
)
5097 unsigned long timeout
;
5099 timeout
= LONG_WAIT
;
5101 WR_HARPOON(p_port
+ hp_sys_ctrl
, HALT_MACH
);
5103 while ((!(RD_HARPOON(p_port
+ hp_ext_status
) & CMD_ABORTED
))
5107 if (RD_HARPOON(p_port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5108 WR_HARPOON(p_port
+ hp_sys_ctrl
, HARD_ABORT
);
5110 timeout
= LONG_WAIT
;
5111 while ((RD_HARPOON(p_port
+ hp_ext_status
) & BM_CMD_BUSY
)
5116 RD_HARPOON(p_port
+ hp_int_status
); /*Clear command complete */
5118 if (RD_HARPOON(p_port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5127 /*---------------------------------------------------------------------
5129 * Function: Host Data Transfer Abort
5131 * Description: Abort any in progress transfer.
5133 *---------------------------------------------------------------------*/
5134 static void FPT_hostDataXferAbort(u32 port
, unsigned char p_card
,
5135 struct sccb
*pCurrSCCB
)
5138 unsigned long timeout
;
5139 unsigned long remain_cnt
;
5141 struct blogic_sg_seg
*segp
;
5143 FPT_BL_Card
[p_card
].globalFlags
&= ~F_HOST_XFER_ACT
;
5145 if (pCurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
) {
5147 if (!(RD_HARPOON(port
+ hp_int_status
) & INT_CMD_COMPL
)) {
5149 WR_HARPOON(port
+ hp_bm_ctrl
,
5150 (RD_HARPOON(port
+ hp_bm_ctrl
) |
5152 timeout
= LONG_WAIT
;
5154 while ((RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
)
5158 WR_HARPOON(port
+ hp_bm_ctrl
,
5159 (RD_HARPOON(port
+ hp_bm_ctrl
) &
5162 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5164 if (FPT_busMstrTimeOut(port
)) {
5166 if (pCurrSCCB
->HostStatus
== 0x00)
5168 pCurrSCCB
->HostStatus
=
5173 if (RD_HARPOON(port
+ hp_int_status
) &
5176 if (RD_HARPOON(port
+ hp_ext_status
) &
5179 if (pCurrSCCB
->HostStatus
==
5182 pCurrSCCB
->HostStatus
=
5189 else if (pCurrSCCB
->Sccb_XferCnt
) {
5191 if (pCurrSCCB
->Sccb_XferState
& F_SG_XFER
) {
5193 WR_HARPOON(port
+ hp_page_ctrl
,
5194 (RD_HARPOON(port
+ hp_page_ctrl
) &
5197 WR_HARPOON(port
+ hp_sg_addr
, 0x00);
5199 sg_ptr
= pCurrSCCB
->Sccb_sgseg
+ SG_BUF_CNT
;
5202 (unsigned int)(pCurrSCCB
->DataLength
/
5205 sg_ptr
= (u32
)(pCurrSCCB
->DataLength
/
5209 remain_cnt
= pCurrSCCB
->Sccb_XferCnt
;
5211 while (remain_cnt
< 0x01000000L
) {
5214 segp
= (struct blogic_sg_seg
*)(pCurrSCCB
->
5215 DataPointer
) + (sg_ptr
* 2);
5216 if (remain_cnt
> (unsigned long)segp
->segbytes
)
5218 (unsigned long)segp
->segbytes
;
5223 if (remain_cnt
< 0x01000000L
) {
5225 pCurrSCCB
->Sccb_SGoffset
= remain_cnt
;
5227 pCurrSCCB
->Sccb_sgseg
= (unsigned short)sg_ptr
;
5229 if ((unsigned long)(sg_ptr
* SG_ELEMENT_SIZE
) ==
5230 pCurrSCCB
->DataLength
&& (remain_cnt
== 0))
5232 pCurrSCCB
->Sccb_XferState
|=
5238 if (pCurrSCCB
->HostStatus
== 0x00) {
5240 pCurrSCCB
->HostStatus
=
5246 if (!(pCurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
)) {
5248 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5250 FPT_busMstrTimeOut(port
);
5255 if (RD_HARPOON(port
+ hp_int_status
) &
5258 if (RD_HARPOON(port
+ hp_ext_status
) &
5261 if (pCurrSCCB
->HostStatus
==
5264 pCurrSCCB
->HostStatus
=
5275 if ((RD_HARPOON(port
+ hp_fifo_cnt
)) >= BM_THRESHOLD
) {
5277 timeout
= SHORT_WAIT
;
5279 while ((RD_HARPOON(port
+ hp_ext_status
) &
5281 && ((RD_HARPOON(port
+ hp_fifo_cnt
)) >=
5282 BM_THRESHOLD
) && timeout
--) {
5286 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5288 WR_HARPOON(port
+ hp_bm_ctrl
,
5289 (RD_HARPOON(port
+ hp_bm_ctrl
) |
5292 timeout
= LONG_WAIT
;
5294 while ((RD_HARPOON(port
+ hp_ext_status
) &
5295 BM_CMD_BUSY
) && timeout
--) {
5298 WR_HARPOON(port
+ hp_bm_ctrl
,
5299 (RD_HARPOON(port
+ hp_bm_ctrl
) &
5302 if (RD_HARPOON(port
+ hp_ext_status
) &
5305 if (pCurrSCCB
->HostStatus
== 0x00) {
5307 pCurrSCCB
->HostStatus
=
5311 FPT_busMstrTimeOut(port
);
5315 if (RD_HARPOON(port
+ hp_int_status
) & INT_EXT_STATUS
) {
5317 if (RD_HARPOON(port
+ hp_ext_status
) &
5320 if (pCurrSCCB
->HostStatus
== 0x00) {
5322 pCurrSCCB
->HostStatus
=
5333 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5335 timeout
= LONG_WAIT
;
5337 while ((RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
)
5341 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5343 if (pCurrSCCB
->HostStatus
== 0x00) {
5345 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5348 FPT_busMstrTimeOut(port
);
5352 if (RD_HARPOON(port
+ hp_int_status
) & INT_EXT_STATUS
) {
5354 if (RD_HARPOON(port
+ hp_ext_status
) & BAD_EXT_STATUS
) {
5356 if (pCurrSCCB
->HostStatus
== 0x00) {
5358 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5364 if (pCurrSCCB
->Sccb_XferState
& F_SG_XFER
) {
5366 WR_HARPOON(port
+ hp_page_ctrl
,
5367 (RD_HARPOON(port
+ hp_page_ctrl
) &
5370 WR_HARPOON(port
+ hp_sg_addr
, 0x00);
5372 pCurrSCCB
->Sccb_sgseg
+= SG_BUF_CNT
;
5374 pCurrSCCB
->Sccb_SGoffset
= 0x00;
5376 if ((u32
)(pCurrSCCB
->Sccb_sgseg
* SG_ELEMENT_SIZE
) >=
5377 pCurrSCCB
->DataLength
) {
5379 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5380 pCurrSCCB
->Sccb_sgseg
=
5381 (unsigned short)(pCurrSCCB
->DataLength
/
5387 if (!(pCurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
))
5388 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5392 WR_HARPOON(port
+ hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
5395 /*---------------------------------------------------------------------
5397 * Function: Host Data Transfer Restart
5399 * Description: Reset the available count due to a restore data
5402 *---------------------------------------------------------------------*/
5403 static void FPT_hostDataXferRestart(struct sccb
*currSCCB
)
5405 unsigned long data_count
;
5406 unsigned int sg_index
;
5407 struct blogic_sg_seg
*segp
;
5409 if (currSCCB
->Sccb_XferState
& F_SG_XFER
) {
5411 currSCCB
->Sccb_XferCnt
= 0;
5413 sg_index
= 0xffff; /*Index by long words into sg list. */
5414 data_count
= 0; /*Running count of SG xfer counts. */
5417 while (data_count
< currSCCB
->Sccb_ATC
) {
5420 segp
= (struct blogic_sg_seg
*)(currSCCB
->DataPointer
) +
5422 data_count
+= segp
->segbytes
;
5425 if (data_count
== currSCCB
->Sccb_ATC
) {
5427 currSCCB
->Sccb_SGoffset
= 0;
5432 currSCCB
->Sccb_SGoffset
=
5433 data_count
- currSCCB
->Sccb_ATC
;
5436 currSCCB
->Sccb_sgseg
= (unsigned short)sg_index
;
5440 currSCCB
->Sccb_XferCnt
=
5441 currSCCB
->DataLength
- currSCCB
->Sccb_ATC
;
5445 /*---------------------------------------------------------------------
5447 * Function: FPT_scini
5449 * Description: Setup all data structures necessary for SCAM selection.
5451 *---------------------------------------------------------------------*/
5453 static void FPT_scini(unsigned char p_card
, unsigned char p_our_id
,
5454 unsigned char p_power_up
)
5457 unsigned char loser
, assigned_id
;
5460 unsigned char i
, k
, ScamFlg
;
5461 struct sccb_card
*currCard
;
5462 struct nvram_info
*pCurrNvRam
;
5464 currCard
= &FPT_BL_Card
[p_card
];
5465 p_port
= currCard
->ioPort
;
5466 pCurrNvRam
= currCard
->pNvRamInfo
;
5469 ScamFlg
= pCurrNvRam
->niScamConf
;
5470 i
= pCurrNvRam
->niSysConf
;
5473 (unsigned char)FPT_utilEERead(p_port
, SCAM_CONFIG
/ 2);
5475 char)(FPT_utilEERead(p_port
, (SYSTEM_CONFIG
/ 2)));
5477 if (!(i
& 0x02)) /* check if reset bus in AutoSCSI parameter set */
5480 FPT_inisci(p_card
, p_port
, p_our_id
);
5482 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5483 too slow to return to SCAM selection */
5486 FPT_Wait1Second(p_port);
5488 FPT_Wait(p_port, TO_250ms); */
5490 FPT_Wait1Second(p_port
);
5492 if ((ScamFlg
& SCAM_ENABLED
) && (ScamFlg
& SCAM_LEVEL2
)) {
5493 while (!(FPT_scarb(p_port
, INIT_SELTD
))) {
5499 FPT_scxferc(p_port
, SYNC_PTRN
);
5500 FPT_scxferc(p_port
, DOM_MSTR
);
5503 &FPT_scamInfo
[p_our_id
].id_string
[0]);
5504 } while (loser
== 0xFF);
5508 if ((p_power_up
) && (!loser
)) {
5509 FPT_sresb(p_port
, p_card
);
5510 FPT_Wait(p_port
, TO_250ms
);
5512 while (!(FPT_scarb(p_port
, INIT_SELTD
))) {
5518 FPT_scxferc(p_port
, SYNC_PTRN
);
5519 FPT_scxferc(p_port
, DOM_MSTR
);
5522 &FPT_scamInfo
[p_our_id
].
5524 } while (loser
== 0xFF);
5536 FPT_scamInfo
[p_our_id
].state
= ID_ASSIGNED
;
5538 if (ScamFlg
& SCAM_ENABLED
) {
5540 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
5541 if ((FPT_scamInfo
[i
].state
== ID_UNASSIGNED
) ||
5542 (FPT_scamInfo
[i
].state
== ID_UNUSED
)) {
5543 if (FPT_scsell(p_port
, i
)) {
5544 FPT_scamInfo
[i
].state
= LEGACY
;
5545 if ((FPT_scamInfo
[i
].
5546 id_string
[0] != 0xFF)
5547 || (FPT_scamInfo
[i
].
5548 id_string
[1] != 0xFA)) {
5551 id_string
[0] = 0xFF;
5553 id_string
[1] = 0xFA;
5554 if (pCurrNvRam
== NULL
)
5564 FPT_sresb(p_port
, p_card
);
5565 FPT_Wait1Second(p_port
);
5566 while (!(FPT_scarb(p_port
, INIT_SELTD
))) {
5569 FPT_scasid(p_card
, p_port
);
5574 else if ((loser
) && (ScamFlg
& SCAM_ENABLED
)) {
5575 FPT_scamInfo
[p_our_id
].id_string
[0] = SLV_TYPE_CODE0
;
5577 FPT_scwtsel(p_port
);
5580 while (FPT_scxferc(p_port
, 0x00) != SYNC_PTRN
) {
5583 i
= FPT_scxferc(p_port
, 0x00);
5584 if (i
== ASSIGN_ID
) {
5588 &FPT_scamInfo
[p_our_id
].id_string
[0]))) {
5589 i
= FPT_scxferc(p_port
, 0x00);
5590 if (FPT_scvalq(i
)) {
5591 k
= FPT_scxferc(p_port
, 0x00);
5593 if (FPT_scvalq(k
)) {
5606 FPT_scamInfo
[currCard
->
5608 state
= ID_ASSIGNED
;
5609 FPT_scamInfo
[currCard
->
5619 else if (i
== SET_P_FLAG
) {
5620 if (!(FPT_scsendi(p_port
,
5621 &FPT_scamInfo
[p_our_id
].
5623 FPT_scamInfo
[p_our_id
].id_string
[0] |=
5626 } while (!assigned_id
);
5628 while (FPT_scxferc(p_port
, 0x00) != CFG_CMPLT
) {
5632 if (ScamFlg
& SCAM_ENABLED
) {
5634 if (currCard
->globalFlags
& F_UPDATE_EEPROM
) {
5635 FPT_scsavdi(p_card
, p_port
);
5636 currCard
->globalFlags
&= ~F_UPDATE_EEPROM
;
5641 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5643 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5644 (FPT_scamInfo[i].state == LEGACY))
5649 currCard->globalFlags |= F_SINGLE_DEVICE;
5651 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5655 /*---------------------------------------------------------------------
5657 * Function: FPT_scarb
5659 * Description: Gain control of the bus and wait SCAM select time (250ms)
5661 *---------------------------------------------------------------------*/
5663 static int FPT_scarb(u32 p_port
, unsigned char p_sel_type
)
5665 if (p_sel_type
== INIT_SELTD
) {
5667 while (RD_HARPOON(p_port
+ hp_scsisig
) & (SCSI_SEL
| SCSI_BSY
)) {
5670 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_SEL
)
5673 if (RD_HARPOON(p_port
+ hp_scsidata_0
) != 00)
5676 WR_HARPOON(p_port
+ hp_scsisig
,
5677 (RD_HARPOON(p_port
+ hp_scsisig
) | SCSI_BSY
));
5679 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_SEL
) {
5681 WR_HARPOON(p_port
+ hp_scsisig
,
5682 (RD_HARPOON(p_port
+ hp_scsisig
) &
5687 WR_HARPOON(p_port
+ hp_scsisig
,
5688 (RD_HARPOON(p_port
+ hp_scsisig
) | SCSI_SEL
));
5690 if (RD_HARPOON(p_port
+ hp_scsidata_0
) != 00) {
5692 WR_HARPOON(p_port
+ hp_scsisig
,
5693 (RD_HARPOON(p_port
+ hp_scsisig
) &
5694 ~(SCSI_BSY
| SCSI_SEL
)));
5699 WR_HARPOON(p_port
+ hp_clkctrl_0
, (RD_HARPOON(p_port
+ hp_clkctrl_0
)
5701 WR_HARPOON(p_port
+ hp_scsireset
, SCAM_EN
);
5702 WR_HARPOON(p_port
+ hp_scsidata_0
, 0x00);
5703 WR_HARPOON(p_port
+ hp_scsidata_1
, 0x00);
5704 WR_HARPOON(p_port
+ hp_portctrl_0
, SCSI_BUS_EN
);
5706 WR_HARPOON(p_port
+ hp_scsisig
,
5707 (RD_HARPOON(p_port
+ hp_scsisig
) | SCSI_MSG
));
5709 WR_HARPOON(p_port
+ hp_scsisig
, (RD_HARPOON(p_port
+ hp_scsisig
)
5712 FPT_Wait(p_port
, TO_250ms
);
5717 /*---------------------------------------------------------------------
5719 * Function: FPT_scbusf
5721 * Description: Release the SCSI bus and disable SCAM selection.
5723 *---------------------------------------------------------------------*/
5725 static void FPT_scbusf(u32 p_port
)
5727 WR_HARPOON(p_port
+ hp_page_ctrl
,
5728 (RD_HARPOON(p_port
+ hp_page_ctrl
) | G_INT_DISABLE
));
5730 WR_HARPOON(p_port
+ hp_scsidata_0
, 0x00);
5732 WR_HARPOON(p_port
+ hp_portctrl_0
, (RD_HARPOON(p_port
+ hp_portctrl_0
)
5735 WR_HARPOON(p_port
+ hp_scsisig
, 0x00);
5737 WR_HARPOON(p_port
+ hp_scsireset
, (RD_HARPOON(p_port
+ hp_scsireset
)
5740 WR_HARPOON(p_port
+ hp_clkctrl_0
, (RD_HARPOON(p_port
+ hp_clkctrl_0
)
5743 WRW_HARPOON((p_port
+ hp_intstat
), (BUS_FREE
| AUTO_INT
| SCAM_SEL
));
5745 WR_HARPOON(p_port
+ hp_page_ctrl
,
5746 (RD_HARPOON(p_port
+ hp_page_ctrl
) & ~G_INT_DISABLE
));
5749 /*---------------------------------------------------------------------
5751 * Function: FPT_scasid
5753 * Description: Assign an ID to all the SCAM devices.
5755 *---------------------------------------------------------------------*/
5757 static void FPT_scasid(unsigned char p_card
, u32 p_port
)
5759 unsigned char temp_id_string
[ID_STRING_LENGTH
];
5761 unsigned char i
, k
, scam_id
;
5762 unsigned char crcBytes
[3];
5763 struct nvram_info
*pCurrNvRam
;
5764 unsigned short *pCrcBytes
;
5766 pCurrNvRam
= FPT_BL_Card
[p_card
].pNvRamInfo
;
5772 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
5773 temp_id_string
[k
] = (unsigned char)0x00;
5776 FPT_scxferc(p_port
, SYNC_PTRN
);
5777 FPT_scxferc(p_port
, ASSIGN_ID
);
5779 if (!(FPT_sciso(p_port
, &temp_id_string
[0]))) {
5781 pCrcBytes
= (unsigned short *)&crcBytes
[0];
5782 *pCrcBytes
= FPT_CalcCrc16(&temp_id_string
[0]);
5783 crcBytes
[2] = FPT_CalcLrc(&temp_id_string
[0]);
5784 temp_id_string
[1] = crcBytes
[2];
5785 temp_id_string
[2] = crcBytes
[0];
5786 temp_id_string
[3] = crcBytes
[1];
5787 for (k
= 4; k
< ID_STRING_LENGTH
; k
++)
5788 temp_id_string
[k
] = (unsigned char)0x00;
5790 i
= FPT_scmachid(p_card
, temp_id_string
);
5792 if (i
== CLR_PRIORITY
) {
5793 FPT_scxferc(p_port
, MISC_CODE
);
5794 FPT_scxferc(p_port
, CLR_P_FLAG
);
5795 i
= 0; /*Not the last ID yet. */
5798 else if (i
!= NO_ID_AVAIL
) {
5800 FPT_scxferc(p_port
, ID_0_7
);
5802 FPT_scxferc(p_port
, ID_8_F
);
5804 scam_id
= (i
& (unsigned char)0x07);
5806 for (k
= 1; k
< 0x08; k
<<= 1)
5808 scam_id
+= 0x08; /*Count number of zeros in DB0-3. */
5810 FPT_scxferc(p_port
, scam_id
);
5812 i
= 0; /*Not the last ID yet. */
5822 FPT_scxferc(p_port
, SYNC_PTRN
);
5823 FPT_scxferc(p_port
, CFG_CMPLT
);
5826 /*---------------------------------------------------------------------
5828 * Function: FPT_scsel
5830 * Description: Select all the SCAM devices.
5832 *---------------------------------------------------------------------*/
5834 static void FPT_scsel(u32 p_port
)
5837 WR_HARPOON(p_port
+ hp_scsisig
, SCSI_SEL
);
5838 FPT_scwiros(p_port
, SCSI_MSG
);
5840 WR_HARPOON(p_port
+ hp_scsisig
, (SCSI_SEL
| SCSI_BSY
));
5842 WR_HARPOON(p_port
+ hp_scsisig
,
5843 (SCSI_SEL
| SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
5844 WR_HARPOON(p_port
+ hp_scsidata_0
,
5845 (unsigned char)(RD_HARPOON(p_port
+ hp_scsidata_0
) |
5846 (unsigned char)(BIT(7) + BIT(6))));
5848 WR_HARPOON(p_port
+ hp_scsisig
, (SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
5849 FPT_scwiros(p_port
, SCSI_SEL
);
5851 WR_HARPOON(p_port
+ hp_scsidata_0
,
5852 (unsigned char)(RD_HARPOON(p_port
+ hp_scsidata_0
) &
5853 ~(unsigned char)BIT(6)));
5854 FPT_scwirod(p_port
, BIT(6));
5856 WR_HARPOON(p_port
+ hp_scsisig
,
5857 (SCSI_SEL
| SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
5860 /*---------------------------------------------------------------------
5862 * Function: FPT_scxferc
5864 * Description: Handshake the p_data (DB4-0) across the bus.
5866 *---------------------------------------------------------------------*/
5868 static unsigned char FPT_scxferc(u32 p_port
, unsigned char p_data
)
5870 unsigned char curr_data
, ret_data
;
5872 curr_data
= p_data
| BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5874 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5876 curr_data
&= ~BIT(7);
5878 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5880 FPT_scwirod(p_port
, BIT(7)); /*Wait for DB7 to be released. */
5881 while (!(RD_HARPOON(p_port
+ hp_scsidata_0
) & BIT(5))) ;
5883 ret_data
= (RD_HARPOON(p_port
+ hp_scsidata_0
) & (unsigned char)0x1F);
5885 curr_data
|= BIT(6);
5887 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5889 curr_data
&= ~BIT(5);
5891 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5893 FPT_scwirod(p_port
, BIT(5)); /*Wait for DB5 to be released. */
5895 curr_data
&= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5896 curr_data
|= BIT(7);
5898 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5900 curr_data
&= ~BIT(6);
5902 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5904 FPT_scwirod(p_port
, BIT(6)); /*Wait for DB6 to be released. */
5909 /*---------------------------------------------------------------------
5911 * Function: FPT_scsendi
5913 * Description: Transfer our Identification string to determine if we
5914 * will be the dominant master.
5916 *---------------------------------------------------------------------*/
5918 static unsigned char FPT_scsendi(u32 p_port
, unsigned char p_id_string
[])
5920 unsigned char ret_data
, byte_cnt
, bit_cnt
, defer
;
5924 for (byte_cnt
= 0; byte_cnt
< ID_STRING_LENGTH
; byte_cnt
++) {
5926 for (bit_cnt
= 0x80; bit_cnt
!= 0; bit_cnt
>>= 1) {
5929 ret_data
= FPT_scxferc(p_port
, 00);
5931 else if (p_id_string
[byte_cnt
] & bit_cnt
)
5933 ret_data
= FPT_scxferc(p_port
, 02);
5937 ret_data
= FPT_scxferc(p_port
, 01);
5942 if ((ret_data
& 0x1C) == 0x10)
5943 return 0x00; /*End of isolation stage, we won! */
5945 if (ret_data
& 0x1C)
5948 if ((defer
) && (!(ret_data
& 0x1F)))
5949 return 0x01; /*End of isolation stage, we lost. */
5956 return 0x01; /*We lost */
5958 return 0; /*We WON! Yeeessss! */
5961 /*---------------------------------------------------------------------
5963 * Function: FPT_sciso
5965 * Description: Transfer the Identification string.
5967 *---------------------------------------------------------------------*/
5969 static unsigned char FPT_sciso(u32 p_port
, unsigned char p_id_string
[])
5971 unsigned char ret_data
, the_data
, byte_cnt
, bit_cnt
;
5975 for (byte_cnt
= 0; byte_cnt
< ID_STRING_LENGTH
; byte_cnt
++) {
5977 for (bit_cnt
= 0; bit_cnt
< 8; bit_cnt
++) {
5979 ret_data
= FPT_scxferc(p_port
, 0);
5981 if (ret_data
& 0xFC)
5987 if (ret_data
& BIT(1)) {
5992 if ((ret_data
& 0x1F) == 0) {
5994 if(bit_cnt != 0 || bit_cnt != 8)
5998 FPT_scxferc(p_port, SYNC_PTRN);
5999 FPT_scxferc(p_port, ASSIGN_ID);
6011 p_id_string
[byte_cnt
] = the_data
;
6018 /*---------------------------------------------------------------------
6020 * Function: FPT_scwirod
6022 * Description: Sample the SCSI data bus making sure the signal has been
6023 * deasserted for the correct number of consecutive samples.
6025 *---------------------------------------------------------------------*/
6027 static void FPT_scwirod(u32 p_port
, unsigned char p_data_bit
)
6032 while (i
< MAX_SCSI_TAR
) {
6034 if (RD_HARPOON(p_port
+ hp_scsidata_0
) & p_data_bit
)
6045 /*---------------------------------------------------------------------
6047 * Function: FPT_scwiros
6049 * Description: Sample the SCSI Signal lines making sure the signal has been
6050 * deasserted for the correct number of consecutive samples.
6052 *---------------------------------------------------------------------*/
6054 static void FPT_scwiros(u32 p_port
, unsigned char p_data_bit
)
6059 while (i
< MAX_SCSI_TAR
) {
6061 if (RD_HARPOON(p_port
+ hp_scsisig
) & p_data_bit
)
6072 /*---------------------------------------------------------------------
6074 * Function: FPT_scvalq
6076 * Description: Make sure we received a valid data byte.
6078 *---------------------------------------------------------------------*/
6080 static unsigned char FPT_scvalq(unsigned char p_quintet
)
6082 unsigned char count
;
6084 for (count
= 1; count
< 0x08; count
<<= 1) {
6085 if (!(p_quintet
& count
))
6089 if (p_quintet
& 0x18)
6096 /*---------------------------------------------------------------------
6098 * Function: FPT_scsell
6100 * Description: Select the specified device ID using a selection timeout
6101 * less than 4ms. If somebody responds then it is a legacy
6102 * drive and this ID must be marked as such.
6104 *---------------------------------------------------------------------*/
6106 static unsigned char FPT_scsell(u32 p_port
, unsigned char targ_id
)
6110 WR_HARPOON(p_port
+ hp_page_ctrl
,
6111 (RD_HARPOON(p_port
+ hp_page_ctrl
) | G_INT_DISABLE
));
6113 ARAM_ACCESS(p_port
);
6115 WR_HARPOON(p_port
+ hp_addstat
,
6116 (RD_HARPOON(p_port
+ hp_addstat
) | SCAM_TIMER
));
6117 WR_HARPOON(p_port
+ hp_seltimeout
, TO_4ms
);
6119 for (i
= p_port
+ CMD_STRT
; i
< p_port
+ CMD_STRT
+ 12; i
+= 2) {
6120 WRW_HARPOON(i
, (MPM_OP
+ ACOMMAND
));
6122 WRW_HARPOON(i
, (BRH_OP
+ ALWAYS
+ NP
));
6124 WRW_HARPOON((p_port
+ hp_intstat
),
6125 (RESET
| TIMEOUT
| SEL
| BUS_FREE
| AUTO_INT
));
6127 WR_HARPOON(p_port
+ hp_select_id
, targ_id
);
6129 WR_HARPOON(p_port
+ hp_portctrl_0
, SCSI_PORT
);
6130 WR_HARPOON(p_port
+ hp_autostart_3
, (SELECT
| CMD_ONLY_STRT
));
6131 WR_HARPOON(p_port
+ hp_scsictrl_0
, (SEL_TAR
| ENA_RESEL
));
6133 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) &
6134 (RESET
| PROG_HLT
| TIMEOUT
| AUTO_INT
))) {
6137 if (RDW_HARPOON((p_port
+ hp_intstat
)) & RESET
)
6138 FPT_Wait(p_port
, TO_250ms
);
6140 DISABLE_AUTO(p_port
);
6142 WR_HARPOON(p_port
+ hp_addstat
,
6143 (RD_HARPOON(p_port
+ hp_addstat
) & ~SCAM_TIMER
));
6144 WR_HARPOON(p_port
+ hp_seltimeout
, TO_290ms
);
6146 SGRAM_ACCESS(p_port
);
6148 if (RDW_HARPOON((p_port
+ hp_intstat
)) & (RESET
| TIMEOUT
)) {
6150 WRW_HARPOON((p_port
+ hp_intstat
),
6151 (RESET
| TIMEOUT
| SEL
| BUS_FREE
| PHASE
));
6153 WR_HARPOON(p_port
+ hp_page_ctrl
,
6154 (RD_HARPOON(p_port
+ hp_page_ctrl
) &
6157 return 0; /*No legacy device */
6162 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & BUS_FREE
)) {
6163 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_REQ
) {
6164 WR_HARPOON(p_port
+ hp_scsisig
,
6165 (SCSI_ACK
+ S_ILL_PH
));
6170 WRW_HARPOON((p_port
+ hp_intstat
), CLR_ALL_INT_1
);
6172 WR_HARPOON(p_port
+ hp_page_ctrl
,
6173 (RD_HARPOON(p_port
+ hp_page_ctrl
) &
6176 return 1; /*Found one of them oldies! */
6180 /*---------------------------------------------------------------------
6182 * Function: FPT_scwtsel
6184 * Description: Wait to be selected by another SCAM initiator.
6186 *---------------------------------------------------------------------*/
6188 static void FPT_scwtsel(u32 p_port
)
6190 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & SCAM_SEL
)) {
6194 /*---------------------------------------------------------------------
6196 * Function: FPT_inisci
6198 * Description: Setup the data Structure with the info from the EEPROM.
6200 *---------------------------------------------------------------------*/
6202 static void FPT_inisci(unsigned char p_card
, u32 p_port
, unsigned char p_our_id
)
6204 unsigned char i
, k
, max_id
;
6205 unsigned short ee_data
;
6206 struct nvram_info
*pCurrNvRam
;
6208 pCurrNvRam
= FPT_BL_Card
[p_card
].pNvRamInfo
;
6210 if (RD_HARPOON(p_port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6217 for (i
= 0; i
< max_id
; i
++) {
6219 for (k
= 0; k
< 4; k
++)
6220 FPT_scamInfo
[i
].id_string
[k
] =
6221 pCurrNvRam
->niScamTbl
[i
][k
];
6222 for (k
= 4; k
< ID_STRING_LENGTH
; k
++)
6223 FPT_scamInfo
[i
].id_string
[k
] =
6224 (unsigned char)0x00;
6226 if (FPT_scamInfo
[i
].id_string
[0] == 0x00)
6227 FPT_scamInfo
[i
].state
= ID_UNUSED
; /*Default to unused ID. */
6229 FPT_scamInfo
[i
].state
= ID_UNASSIGNED
; /*Default to unassigned ID. */
6233 for (i
= 0; i
< max_id
; i
++) {
6234 for (k
= 0; k
< ID_STRING_LENGTH
; k
+= 2) {
6236 FPT_utilEERead(p_port
,
6238 short)((EE_SCAMBASE
/ 2) +
6239 (unsigned short)(i
*
6240 ((unsigned short)ID_STRING_LENGTH
/ 2)) + (unsigned short)(k
/ 2)));
6241 FPT_scamInfo
[i
].id_string
[k
] =
6242 (unsigned char)ee_data
;
6244 FPT_scamInfo
[i
].id_string
[k
+ 1] =
6245 (unsigned char)ee_data
;
6248 if ((FPT_scamInfo
[i
].id_string
[0] == 0x00) ||
6249 (FPT_scamInfo
[i
].id_string
[0] == 0xFF))
6251 FPT_scamInfo
[i
].state
= ID_UNUSED
; /*Default to unused ID. */
6254 FPT_scamInfo
[i
].state
= ID_UNASSIGNED
; /*Default to unassigned ID. */
6258 for (k
= 0; k
< ID_STRING_LENGTH
; k
++)
6259 FPT_scamInfo
[p_our_id
].id_string
[k
] = FPT_scamHAString
[k
];
6263 /*---------------------------------------------------------------------
6265 * Function: FPT_scmachid
6267 * Description: Match the Device ID string with our values stored in
6270 *---------------------------------------------------------------------*/
6272 static unsigned char FPT_scmachid(unsigned char p_card
,
6273 unsigned char p_id_string
[])
6276 unsigned char i
, k
, match
;
6278 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
6282 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
6283 if (p_id_string
[k
] != FPT_scamInfo
[i
].id_string
[k
])
6288 FPT_scamInfo
[i
].state
= ID_ASSIGNED
;
6294 if (p_id_string
[0] & BIT(5))
6299 if (((p_id_string
[0] & 0x06) == 0x02)
6300 || ((p_id_string
[0] & 0x06) == 0x04))
6301 match
= p_id_string
[1] & (unsigned char)0x1F;
6308 if (FPT_scamInfo
[match
].state
== ID_UNUSED
) {
6309 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
6310 FPT_scamInfo
[match
].id_string
[k
] =
6314 FPT_scamInfo
[match
].state
= ID_ASSIGNED
;
6316 if (FPT_BL_Card
[p_card
].pNvRamInfo
== NULL
)
6317 FPT_BL_Card
[p_card
].globalFlags
|=
6325 if (match
== 0xFF) {
6326 if (p_id_string
[0] & BIT(5))
6329 match
= MAX_SCSI_TAR
- 1;
6333 if (p_id_string
[0] & BIT(7)) {
6334 return CLR_PRIORITY
;
6337 if (p_id_string
[0] & BIT(5))
6342 if (((p_id_string
[0] & 0x06) == 0x02)
6343 || ((p_id_string
[0] & 0x06) == 0x04))
6344 match
= p_id_string
[1] & (unsigned char)0x1F;
6352 if (FPT_scamInfo
[match
].state
== ID_UNASSIGNED
) {
6353 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
6354 FPT_scamInfo
[match
].id_string
[k
] =
6358 FPT_scamInfo
[match
].id_string
[0] |= BIT(7);
6359 FPT_scamInfo
[match
].state
= ID_ASSIGNED
;
6360 if (FPT_BL_Card
[p_card
].pNvRamInfo
== NULL
)
6361 FPT_BL_Card
[p_card
].globalFlags
|=
6369 if (match
== 0xFF) {
6370 if (p_id_string
[0] & BIT(5))
6373 match
= MAX_SCSI_TAR
- 1;
6380 /*---------------------------------------------------------------------
6382 * Function: FPT_scsavdi
6384 * Description: Save off the device SCAM ID strings.
6386 *---------------------------------------------------------------------*/
6388 static void FPT_scsavdi(unsigned char p_card
, u32 p_port
)
6390 unsigned char i
, k
, max_id
;
6391 unsigned short ee_data
, sum_data
;
6395 for (i
= 1; i
< EE_SCAMBASE
/ 2; i
++) {
6396 sum_data
+= FPT_utilEERead(p_port
, i
);
6399 FPT_utilEEWriteOnOff(p_port
, 1); /* Enable write access to the EEPROM */
6401 if (RD_HARPOON(p_port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6407 for (i
= 0; i
< max_id
; i
++) {
6409 for (k
= 0; k
< ID_STRING_LENGTH
; k
+= 2) {
6410 ee_data
= FPT_scamInfo
[i
].id_string
[k
+ 1];
6412 ee_data
|= FPT_scamInfo
[i
].id_string
[k
];
6413 sum_data
+= ee_data
;
6414 FPT_utilEEWrite(p_port
, ee_data
,
6415 (unsigned short)((EE_SCAMBASE
/ 2) +
6416 (unsigned short)(i
*
6417 ((unsigned short)ID_STRING_LENGTH
/ 2)) + (unsigned short)(k
/ 2)));
6421 FPT_utilEEWrite(p_port
, sum_data
, EEPROM_CHECK_SUM
/ 2);
6422 FPT_utilEEWriteOnOff(p_port
, 0); /* Turn off write access */
6425 /*---------------------------------------------------------------------
6427 * Function: FPT_XbowInit
6429 * Description: Setup the Xbow for normal operation.
6431 *---------------------------------------------------------------------*/
6433 static void FPT_XbowInit(u32 port
, unsigned char ScamFlg
)
6437 i
= RD_HARPOON(port
+ hp_page_ctrl
);
6438 WR_HARPOON(port
+ hp_page_ctrl
, (unsigned char)(i
| G_INT_DISABLE
));
6440 WR_HARPOON(port
+ hp_scsireset
, 0x00);
6441 WR_HARPOON(port
+ hp_portctrl_1
, HOST_MODE8
);
6443 WR_HARPOON(port
+ hp_scsireset
, (DMA_RESET
| HPSCSI_RESET
| PROG_RESET
|
6446 WR_HARPOON(port
+ hp_scsireset
, SCSI_INI
);
6448 WR_HARPOON(port
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
6450 WR_HARPOON(port
+ hp_scsisig
, 0x00); /* Clear any signals we might */
6451 WR_HARPOON(port
+ hp_scsictrl_0
, ENA_SCAM_SEL
);
6453 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT
);
6455 FPT_default_intena
= RESET
| RSEL
| PROG_HLT
| TIMEOUT
|
6456 BUS_FREE
| XFER_CNT_0
| AUTO_INT
;
6458 if ((ScamFlg
& SCAM_ENABLED
) && (ScamFlg
& SCAM_LEVEL2
))
6459 FPT_default_intena
|= SCAM_SEL
;
6461 WRW_HARPOON((port
+ hp_intena
), FPT_default_intena
);
6463 WR_HARPOON(port
+ hp_seltimeout
, TO_290ms
);
6465 /* Turn on SCSI_MODE8 for narrow cards to fix the
6466 strapping issue with the DUAL CHANNEL card */
6467 if (RD_HARPOON(port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6468 WR_HARPOON(port
+ hp_addstat
, SCSI_MODE8
);
6470 WR_HARPOON(port
+ hp_page_ctrl
, i
);
6474 /*---------------------------------------------------------------------
6476 * Function: FPT_BusMasterInit
6478 * Description: Initialize the BusMaster for normal operations.
6480 *---------------------------------------------------------------------*/
6482 static void FPT_BusMasterInit(u32 p_port
)
6485 WR_HARPOON(p_port
+ hp_sys_ctrl
, DRVR_RST
);
6486 WR_HARPOON(p_port
+ hp_sys_ctrl
, 0x00);
6488 WR_HARPOON(p_port
+ hp_host_blk_cnt
, XFER_BLK64
);
6490 WR_HARPOON(p_port
+ hp_bm_ctrl
, (BMCTRL_DEFAULT
));
6492 WR_HARPOON(p_port
+ hp_ee_ctrl
, (SCSI_TERM_ENA_H
));
6494 RD_HARPOON(p_port
+ hp_int_status
); /*Clear interrupts. */
6495 WR_HARPOON(p_port
+ hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
6496 WR_HARPOON(p_port
+ hp_page_ctrl
, (RD_HARPOON(p_port
+ hp_page_ctrl
) &
6500 /*---------------------------------------------------------------------
6502 * Function: FPT_DiagEEPROM
6504 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6507 *---------------------------------------------------------------------*/
6509 static void FPT_DiagEEPROM(u32 p_port
)
6511 unsigned short index
, temp
, max_wd_cnt
;
6513 if (RD_HARPOON(p_port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6514 max_wd_cnt
= EEPROM_WD_CNT
;
6516 max_wd_cnt
= EEPROM_WD_CNT
* 2;
6518 temp
= FPT_utilEERead(p_port
, FW_SIGNATURE
/ 2);
6520 if (temp
== 0x4641) {
6522 for (index
= 2; index
< max_wd_cnt
; index
++) {
6524 temp
+= FPT_utilEERead(p_port
, index
);
6528 if (temp
== FPT_utilEERead(p_port
, EEPROM_CHECK_SUM
/ 2)) {
6530 return; /*EEPROM is Okay so return now! */
6534 FPT_utilEEWriteOnOff(p_port
, (unsigned char)1);
6536 for (index
= 0; index
< max_wd_cnt
; index
++) {
6538 FPT_utilEEWrite(p_port
, 0x0000, index
);
6543 FPT_utilEEWrite(p_port
, 0x4641, FW_SIGNATURE
/ 2);
6545 FPT_utilEEWrite(p_port
, 0x3920, MODEL_NUMB_0
/ 2);
6547 FPT_utilEEWrite(p_port
, 0x3033, MODEL_NUMB_2
/ 2);
6549 FPT_utilEEWrite(p_port
, 0x2020, MODEL_NUMB_4
/ 2);
6551 FPT_utilEEWrite(p_port
, 0x70D3, SYSTEM_CONFIG
/ 2);
6553 FPT_utilEEWrite(p_port
, 0x0010, BIOS_CONFIG
/ 2);
6555 FPT_utilEEWrite(p_port
, 0x0003, SCAM_CONFIG
/ 2);
6557 FPT_utilEEWrite(p_port
, 0x0007, ADAPTER_SCSI_ID
/ 2);
6560 FPT_utilEEWrite(p_port
, 0x0000, IGNORE_B_SCAN
/ 2);
6562 FPT_utilEEWrite(p_port
, 0x0000, SEND_START_ENA
/ 2);
6564 FPT_utilEEWrite(p_port
, 0x0000, DEVICE_ENABLE
/ 2);
6567 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL01
/ 2);
6569 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL23
/ 2);
6571 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL45
/ 2);
6573 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL67
/ 2);
6575 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL89
/ 2);
6577 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLab
/ 2);
6579 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLcd
/ 2);
6581 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLef
/ 2);
6584 FPT_utilEEWrite(p_port
, 0x6C46, 64 / 2); /*PRODUCT ID */
6586 FPT_utilEEWrite(p_port
, 0x7361, 66 / 2); /* FlashPoint LT */
6588 FPT_utilEEWrite(p_port
, 0x5068, 68 / 2);
6590 FPT_utilEEWrite(p_port
, 0x696F, 70 / 2);
6592 FPT_utilEEWrite(p_port
, 0x746E, 72 / 2);
6594 FPT_utilEEWrite(p_port
, 0x4C20, 74 / 2);
6596 FPT_utilEEWrite(p_port
, 0x2054, 76 / 2);
6598 FPT_utilEEWrite(p_port
, 0x2020, 78 / 2);
6601 index
= ((EE_SCAMBASE
/ 2) + (7 * 16));
6602 FPT_utilEEWrite(p_port
, (0x0700 + TYPE_CODE0
), index
);
6603 temp
+= (0x0700 + TYPE_CODE0
);
6605 FPT_utilEEWrite(p_port
, 0x5542, index
); /*Vendor ID code */
6606 temp
+= 0x5542; /* BUSLOGIC */
6608 FPT_utilEEWrite(p_port
, 0x4C53, index
);
6611 FPT_utilEEWrite(p_port
, 0x474F, index
);
6614 FPT_utilEEWrite(p_port
, 0x4349, index
);
6617 FPT_utilEEWrite(p_port
, 0x5442, index
); /*Vendor unique code */
6618 temp
+= 0x5442; /* BT- 930 */
6620 FPT_utilEEWrite(p_port
, 0x202D, index
);
6623 FPT_utilEEWrite(p_port
, 0x3339, index
);
6625 index
++; /*Serial # */
6626 FPT_utilEEWrite(p_port
, 0x2030, index
); /* 01234567 */
6629 FPT_utilEEWrite(p_port
, 0x5453, index
);
6632 FPT_utilEEWrite(p_port
, 0x5645, index
);
6635 FPT_utilEEWrite(p_port
, 0x2045, index
);
6638 FPT_utilEEWrite(p_port
, 0x202F, index
);
6641 FPT_utilEEWrite(p_port
, 0x4F4A, index
);
6644 FPT_utilEEWrite(p_port
, 0x204E, index
);
6647 FPT_utilEEWrite(p_port
, 0x3539, index
);
6650 FPT_utilEEWrite(p_port
, temp
, EEPROM_CHECK_SUM
/ 2);
6652 FPT_utilEEWriteOnOff(p_port
, (unsigned char)0);
6656 /*---------------------------------------------------------------------
6658 * Function: Queue Search Select
6660 * Description: Try to find a new command to execute.
6662 *---------------------------------------------------------------------*/
6664 static void FPT_queueSearchSelect(struct sccb_card
*pCurrCard
,
6665 unsigned char p_card
)
6667 unsigned char scan_ptr
, lun
;
6668 struct sccb_mgr_tar_info
*currTar_Info
;
6669 struct sccb
*pOldSccb
;
6671 scan_ptr
= pCurrCard
->scanIndex
;
6673 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scan_ptr
];
6674 if ((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
6675 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
6677 if (currTar_Info
->TarSelQ_Cnt
!= 0) {
6680 if (scan_ptr
== MAX_SCSI_TAR
)
6683 for (lun
= 0; lun
< MAX_LUN
; lun
++) {
6684 if (currTar_Info
->TarLUNBusy
[lun
] == 0) {
6686 pCurrCard
->currentSCCB
=
6687 currTar_Info
->TarSelQ_Head
;
6691 currentSCCB
!= NULL
)
6694 currentSCCB
->Lun
)) {
6698 pCurrCard
->currentSCCB
=
6704 if (pCurrCard
->currentSCCB
==
6707 if (pOldSccb
!= NULL
) {
6750 pCurrCard
->scanIndex
= scan_ptr
;
6752 pCurrCard
->globalFlags
|=
6762 if (scan_ptr
== MAX_SCSI_TAR
) {
6768 if ((currTar_Info
->TarSelQ_Cnt
!= 0) &&
6769 (currTar_Info
->TarLUNBusy
[0] == 0)) {
6771 pCurrCard
->currentSCCB
=
6772 currTar_Info
->TarSelQ_Head
;
6774 currTar_Info
->TarSelQ_Head
=
6775 (struct sccb
*)(pCurrCard
->currentSCCB
)->
6778 if (currTar_Info
->TarSelQ_Head
== NULL
) {
6779 currTar_Info
->TarSelQ_Tail
= NULL
;
6780 currTar_Info
->TarSelQ_Cnt
= 0;
6782 currTar_Info
->TarSelQ_Cnt
--;
6783 currTar_Info
->TarSelQ_Head
->
6784 Sccb_backlink
= (struct sccb
*)NULL
;
6788 if (scan_ptr
== MAX_SCSI_TAR
)
6791 pCurrCard
->scanIndex
= scan_ptr
;
6793 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
6800 if (scan_ptr
== MAX_SCSI_TAR
) {
6805 } while (scan_ptr
!= pCurrCard
->scanIndex
);
6808 /*---------------------------------------------------------------------
6810 * Function: Queue Select Fail
6812 * Description: Add the current SCCB to the head of the Queue.
6814 *---------------------------------------------------------------------*/
6816 static void FPT_queueSelectFail(struct sccb_card
*pCurrCard
,
6817 unsigned char p_card
)
6819 unsigned char thisTarg
;
6820 struct sccb_mgr_tar_info
*currTar_Info
;
6822 if (pCurrCard
->currentSCCB
!= NULL
) {
6824 (unsigned char)(((struct sccb
*)(pCurrCard
->currentSCCB
))->
6826 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
6828 pCurrCard
->currentSCCB
->Sccb_backlink
= (struct sccb
*)NULL
;
6830 pCurrCard
->currentSCCB
->Sccb_forwardlink
=
6831 currTar_Info
->TarSelQ_Head
;
6833 if (currTar_Info
->TarSelQ_Cnt
== 0) {
6834 currTar_Info
->TarSelQ_Tail
= pCurrCard
->currentSCCB
;
6838 currTar_Info
->TarSelQ_Head
->Sccb_backlink
=
6839 pCurrCard
->currentSCCB
;
6842 currTar_Info
->TarSelQ_Head
= pCurrCard
->currentSCCB
;
6844 pCurrCard
->currentSCCB
= NULL
;
6845 currTar_Info
->TarSelQ_Cnt
++;
6849 /*---------------------------------------------------------------------
6851 * Function: Queue Command Complete
6853 * Description: Call the callback function with the current SCCB.
6855 *---------------------------------------------------------------------*/
6857 static void FPT_queueCmdComplete(struct sccb_card
*pCurrCard
,
6858 struct sccb
*p_sccb
, unsigned char p_card
)
6861 unsigned char i
, SCSIcmd
;
6862 CALL_BK_FN callback
;
6863 struct sccb_mgr_tar_info
*currTar_Info
;
6865 SCSIcmd
= p_sccb
->Cdb
[0];
6867 if (!(p_sccb
->Sccb_XferState
& F_ALL_XFERRED
)) {
6870 ControlByte
& (SCCB_DATA_XFER_OUT
| SCCB_DATA_XFER_IN
))
6871 && (p_sccb
->HostStatus
== SCCB_COMPLETE
)
6872 && (p_sccb
->TargetStatus
!= SSCHECK
))
6874 if ((SCSIcmd
== SCSI_READ
) ||
6875 (SCSIcmd
== SCSI_WRITE
) ||
6876 (SCSIcmd
== SCSI_READ_EXTENDED
) ||
6877 (SCSIcmd
== SCSI_WRITE_EXTENDED
) ||
6878 (SCSIcmd
== SCSI_WRITE_AND_VERIFY
) ||
6879 (SCSIcmd
== SCSI_START_STOP_UNIT
) ||
6880 (pCurrCard
->globalFlags
& F_NO_FILTER
)
6882 p_sccb
->HostStatus
= SCCB_DATA_UNDER_RUN
;
6885 if (p_sccb
->SccbStatus
== SCCB_IN_PROCESS
) {
6886 if (p_sccb
->HostStatus
|| p_sccb
->TargetStatus
)
6887 p_sccb
->SccbStatus
= SCCB_ERROR
;
6889 p_sccb
->SccbStatus
= SCCB_SUCCESS
;
6892 if (p_sccb
->Sccb_XferState
& F_AUTO_SENSE
) {
6894 p_sccb
->CdbLength
= p_sccb
->Save_CdbLen
;
6895 for (i
= 0; i
< 6; i
++) {
6896 p_sccb
->Cdb
[i
] = p_sccb
->Save_Cdb
[i
];
6900 if ((p_sccb
->OperationCode
== RESIDUAL_SG_COMMAND
) ||
6901 (p_sccb
->OperationCode
== RESIDUAL_COMMAND
)) {
6903 FPT_utilUpdateResidual(p_sccb
);
6906 pCurrCard
->cmdCounter
--;
6907 if (!pCurrCard
->cmdCounter
) {
6909 if (pCurrCard
->globalFlags
& F_GREEN_PC
) {
6910 WR_HARPOON(pCurrCard
->ioPort
+ hp_clkctrl_0
,
6911 (PWR_DWN
| CLKCTRL_DEFAULT
));
6912 WR_HARPOON(pCurrCard
->ioPort
+ hp_sys_ctrl
, STOP_CLK
);
6915 WR_HARPOON(pCurrCard
->ioPort
+ hp_semaphore
,
6916 (RD_HARPOON(pCurrCard
->ioPort
+ hp_semaphore
) &
6921 if (pCurrCard
->discQCount
!= 0) {
6922 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
6923 if (((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
6924 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
6926 pCurrCard
->discQCount
--;
6927 pCurrCard
->discQ_Tbl
[currTar_Info
->
6928 LunDiscQ_Idx
[p_sccb
->Lun
]] = NULL
;
6930 if (p_sccb
->Sccb_tag
) {
6931 pCurrCard
->discQCount
--;
6932 pCurrCard
->discQ_Tbl
[p_sccb
->Sccb_tag
] = NULL
;
6934 pCurrCard
->discQCount
--;
6935 pCurrCard
->discQ_Tbl
[currTar_Info
->
6936 LunDiscQ_Idx
[0]] = NULL
;
6942 callback
= (CALL_BK_FN
) p_sccb
->SccbCallback
;
6944 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
6945 pCurrCard
->currentSCCB
= NULL
;
6948 /*---------------------------------------------------------------------
6950 * Function: Queue Disconnect
6952 * Description: Add SCCB to our disconnect array.
6954 *---------------------------------------------------------------------*/
6955 static void FPT_queueDisconnect(struct sccb
*p_sccb
, unsigned char p_card
)
6957 struct sccb_mgr_tar_info
*currTar_Info
;
6959 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
6961 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
6962 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
6963 FPT_BL_Card
[p_card
].discQ_Tbl
[currTar_Info
->
6964 LunDiscQ_Idx
[p_sccb
->Lun
]] =
6967 if (p_sccb
->Sccb_tag
) {
6968 FPT_BL_Card
[p_card
].discQ_Tbl
[p_sccb
->Sccb_tag
] =
6970 FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
].TarLUNBusy
[0] =
6972 FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
].TarTagQ_Cnt
++;
6974 FPT_BL_Card
[p_card
].discQ_Tbl
[currTar_Info
->
6975 LunDiscQ_Idx
[0]] = p_sccb
;
6978 FPT_BL_Card
[p_card
].currentSCCB
= NULL
;
6981 /*---------------------------------------------------------------------
6983 * Function: Queue Flush SCCB
6985 * Description: Flush all SCCB's back to the host driver for this target.
6987 *---------------------------------------------------------------------*/
6989 static void FPT_queueFlushSccb(unsigned char p_card
, unsigned char error_code
)
6991 unsigned char qtag
, thisTarg
;
6992 struct sccb
*currSCCB
;
6993 struct sccb_mgr_tar_info
*currTar_Info
;
6995 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
6996 if (currSCCB
!= NULL
) {
6997 thisTarg
= (unsigned char)currSCCB
->TargID
;
6998 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7000 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
7002 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] &&
7003 (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
==
7006 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->
7007 HostStatus
= (unsigned char)error_code
;
7009 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],
7010 FPT_BL_Card
[p_card
].
7011 discQ_Tbl
[qtag
], p_card
);
7013 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
7014 currTar_Info
->TarTagQ_Cnt
--;
7022 /*---------------------------------------------------------------------
7024 * Function: Queue Flush Target SCCB
7026 * Description: Flush all SCCB's back to the host driver for this target.
7028 *---------------------------------------------------------------------*/
7030 static void FPT_queueFlushTargSccb(unsigned char p_card
, unsigned char thisTarg
,
7031 unsigned char error_code
)
7034 struct sccb_mgr_tar_info
*currTar_Info
;
7036 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7038 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
7040 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] &&
7041 (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
== thisTarg
)) {
7043 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->HostStatus
=
7044 (unsigned char)error_code
;
7046 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],
7047 FPT_BL_Card
[p_card
].
7048 discQ_Tbl
[qtag
], p_card
);
7050 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
7051 currTar_Info
->TarTagQ_Cnt
--;
7058 static void FPT_queueAddSccb(struct sccb
*p_SCCB
, unsigned char p_card
)
7060 struct sccb_mgr_tar_info
*currTar_Info
;
7061 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_SCCB
->TargID
];
7063 p_SCCB
->Sccb_forwardlink
= NULL
;
7065 p_SCCB
->Sccb_backlink
= currTar_Info
->TarSelQ_Tail
;
7067 if (currTar_Info
->TarSelQ_Cnt
== 0) {
7069 currTar_Info
->TarSelQ_Head
= p_SCCB
;
7074 currTar_Info
->TarSelQ_Tail
->Sccb_forwardlink
= p_SCCB
;
7077 currTar_Info
->TarSelQ_Tail
= p_SCCB
;
7078 currTar_Info
->TarSelQ_Cnt
++;
7081 /*---------------------------------------------------------------------
7083 * Function: Queue Find SCCB
7085 * Description: Search the target select Queue for this SCCB, and
7086 * remove it if found.
7088 *---------------------------------------------------------------------*/
7090 static unsigned char FPT_queueFindSccb(struct sccb
*p_SCCB
,
7091 unsigned char p_card
)
7094 struct sccb_mgr_tar_info
*currTar_Info
;
7096 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_SCCB
->TargID
];
7098 q_ptr
= currTar_Info
->TarSelQ_Head
;
7100 while (q_ptr
!= NULL
) {
7102 if (q_ptr
== p_SCCB
) {
7104 if (currTar_Info
->TarSelQ_Head
== q_ptr
) {
7106 currTar_Info
->TarSelQ_Head
=
7107 q_ptr
->Sccb_forwardlink
;
7110 if (currTar_Info
->TarSelQ_Tail
== q_ptr
) {
7112 currTar_Info
->TarSelQ_Tail
=
7113 q_ptr
->Sccb_backlink
;
7116 if (q_ptr
->Sccb_forwardlink
!= NULL
) {
7117 q_ptr
->Sccb_forwardlink
->Sccb_backlink
=
7118 q_ptr
->Sccb_backlink
;
7121 if (q_ptr
->Sccb_backlink
!= NULL
) {
7122 q_ptr
->Sccb_backlink
->Sccb_forwardlink
=
7123 q_ptr
->Sccb_forwardlink
;
7126 currTar_Info
->TarSelQ_Cnt
--;
7132 q_ptr
= q_ptr
->Sccb_forwardlink
;
7140 /*---------------------------------------------------------------------
7142 * Function: Utility Update Residual Count
7144 * Description: Update the XferCnt to the remaining byte count.
7145 * If we transferred all the data then just write zero.
7146 * If Non-SG transfer then report Total Cnt - Actual Transfer
7147 * Cnt. For SG transfers add the count fields of all
7148 * remaining SG elements, as well as any partial remaining
7151 *---------------------------------------------------------------------*/
7153 static void FPT_utilUpdateResidual(struct sccb
*p_SCCB
)
7155 unsigned long partial_cnt
;
7156 unsigned int sg_index
;
7157 struct blogic_sg_seg
*segp
;
7159 if (p_SCCB
->Sccb_XferState
& F_ALL_XFERRED
) {
7161 p_SCCB
->DataLength
= 0x0000;
7164 else if (p_SCCB
->Sccb_XferState
& F_SG_XFER
) {
7166 partial_cnt
= 0x0000;
7168 sg_index
= p_SCCB
->Sccb_sgseg
;
7171 if (p_SCCB
->Sccb_SGoffset
) {
7173 partial_cnt
= p_SCCB
->Sccb_SGoffset
;
7177 while (((unsigned long)sg_index
*
7178 (unsigned long)SG_ELEMENT_SIZE
) < p_SCCB
->DataLength
) {
7179 segp
= (struct blogic_sg_seg
*)(p_SCCB
->DataPointer
) +
7181 partial_cnt
+= segp
->segbytes
;
7185 p_SCCB
->DataLength
= partial_cnt
;
7190 p_SCCB
->DataLength
-= p_SCCB
->Sccb_ATC
;
7194 /*---------------------------------------------------------------------
7196 * Function: Wait 1 Second
7198 * Description: Wait for 1 second.
7200 *---------------------------------------------------------------------*/
7202 static void FPT_Wait1Second(u32 p_port
)
7206 for (i
= 0; i
< 4; i
++) {
7208 FPT_Wait(p_port
, TO_250ms
);
7210 if ((RD_HARPOON(p_port
+ hp_scsictrl_0
) & SCSI_RST
))
7213 if ((RDW_HARPOON((p_port
+ hp_intstat
)) & SCAM_SEL
))
7218 /*---------------------------------------------------------------------
7220 * Function: FPT_Wait
7222 * Description: Wait the desired delay.
7224 *---------------------------------------------------------------------*/
7226 static void FPT_Wait(u32 p_port
, unsigned char p_delay
)
7228 unsigned char old_timer
;
7229 unsigned char green_flag
;
7231 old_timer
= RD_HARPOON(p_port
+ hp_seltimeout
);
7233 green_flag
= RD_HARPOON(p_port
+ hp_clkctrl_0
);
7234 WR_HARPOON(p_port
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
7236 WR_HARPOON(p_port
+ hp_seltimeout
, p_delay
);
7237 WRW_HARPOON((p_port
+ hp_intstat
), TIMEOUT
);
7238 WRW_HARPOON((p_port
+ hp_intena
), (FPT_default_intena
& ~TIMEOUT
));
7240 WR_HARPOON(p_port
+ hp_portctrl_0
,
7241 (RD_HARPOON(p_port
+ hp_portctrl_0
) | START_TO
));
7243 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & TIMEOUT
)) {
7245 if ((RD_HARPOON(p_port
+ hp_scsictrl_0
) & SCSI_RST
))
7248 if ((RDW_HARPOON((p_port
+ hp_intstat
)) & SCAM_SEL
))
7252 WR_HARPOON(p_port
+ hp_portctrl_0
,
7253 (RD_HARPOON(p_port
+ hp_portctrl_0
) & ~START_TO
));
7255 WRW_HARPOON((p_port
+ hp_intstat
), TIMEOUT
);
7256 WRW_HARPOON((p_port
+ hp_intena
), FPT_default_intena
);
7258 WR_HARPOON(p_port
+ hp_clkctrl_0
, green_flag
);
7260 WR_HARPOON(p_port
+ hp_seltimeout
, old_timer
);
7263 /*---------------------------------------------------------------------
7265 * Function: Enable/Disable Write to EEPROM
7267 * Description: The EEPROM must first be enabled for writes
7268 * A total of 9 clocks are needed.
7270 *---------------------------------------------------------------------*/
7272 static void FPT_utilEEWriteOnOff(u32 p_port
, unsigned char p_mode
)
7274 unsigned char ee_value
;
7277 (unsigned char)(RD_HARPOON(p_port
+ hp_ee_ctrl
) &
7278 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
));
7282 FPT_utilEESendCmdAddr(p_port
, EWEN
, EWEN_ADDR
);
7286 FPT_utilEESendCmdAddr(p_port
, EWDS
, EWDS_ADDR
);
7288 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
)); /*Turn off CS */
7289 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
); /*Turn off Master Select */
7292 /*---------------------------------------------------------------------
7294 * Function: Write EEPROM
7296 * Description: Write a word to the EEPROM at the specified
7299 *---------------------------------------------------------------------*/
7301 static void FPT_utilEEWrite(u32 p_port
, unsigned short ee_data
,
7302 unsigned short ee_addr
)
7305 unsigned char ee_value
;
7310 char)((RD_HARPOON(p_port
+ hp_ee_ctrl
) &
7311 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
)) | (SEE_MS
| SEE_CS
));
7313 FPT_utilEESendCmdAddr(p_port
, EE_WRITE
, ee_addr
);
7315 ee_value
|= (SEE_MS
+ SEE_CS
);
7317 for (i
= 0x8000; i
!= 0; i
>>= 1) {
7322 ee_value
&= ~SEE_DO
;
7324 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7325 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7326 ee_value
|= SEE_CLK
; /* Clock data! */
7327 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7328 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7329 ee_value
&= ~SEE_CLK
;
7330 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7331 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7333 ee_value
&= (EXT_ARB_ACK
| SCSI_TERM_ENA_H
);
7334 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
));
7336 FPT_Wait(p_port
, TO_10ms
);
7338 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
| SEE_CS
)); /* Set CS to EEPROM */
7339 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
)); /* Turn off CS */
7340 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
); /* Turn off Master Select */
7343 /*---------------------------------------------------------------------
7345 * Function: Read EEPROM
7347 * Description: Read a word from the EEPROM at the desired
7350 *---------------------------------------------------------------------*/
7352 static unsigned short FPT_utilEERead(u32 p_port
,
7353 unsigned short ee_addr
)
7355 unsigned short i
, ee_data1
, ee_data2
;
7358 ee_data1
= FPT_utilEEReadOrg(p_port
, ee_addr
);
7360 ee_data2
= FPT_utilEEReadOrg(p_port
, ee_addr
);
7362 if (ee_data1
== ee_data2
)
7365 ee_data1
= ee_data2
;
7373 /*---------------------------------------------------------------------
7375 * Function: Read EEPROM Original
7377 * Description: Read a word from the EEPROM at the desired
7380 *---------------------------------------------------------------------*/
7382 static unsigned short FPT_utilEEReadOrg(u32 p_port
, unsigned short ee_addr
)
7385 unsigned char ee_value
;
7386 unsigned short i
, ee_data
;
7390 char)((RD_HARPOON(p_port
+ hp_ee_ctrl
) &
7391 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
)) | (SEE_MS
| SEE_CS
));
7393 FPT_utilEESendCmdAddr(p_port
, EE_READ
, ee_addr
);
7395 ee_value
|= (SEE_MS
+ SEE_CS
);
7398 for (i
= 1; i
<= 16; i
++) {
7400 ee_value
|= SEE_CLK
; /* Clock data! */
7401 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7402 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7403 ee_value
&= ~SEE_CLK
;
7404 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7405 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7409 if (RD_HARPOON(p_port
+ hp_ee_ctrl
) & SEE_DI
)
7413 ee_value
&= ~(SEE_MS
+ SEE_CS
);
7414 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
)); /*Turn off CS */
7415 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
); /*Turn off Master Select */
7420 /*---------------------------------------------------------------------
7422 * Function: Send EE command and Address to the EEPROM
7424 * Description: Transfers the correct command and sends the address
7427 *---------------------------------------------------------------------*/
7429 static void FPT_utilEESendCmdAddr(u32 p_port
, unsigned char ee_cmd
,
7430 unsigned short ee_addr
)
7432 unsigned char ee_value
;
7433 unsigned char narrow_flg
;
7438 (unsigned char)(RD_HARPOON(p_port
+ hp_page_ctrl
) &
7442 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7444 ee_value
|= SEE_CS
; /* Set CS to EEPROM */
7445 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7447 for (i
= 0x04; i
!= 0; i
>>= 1) {
7452 ee_value
&= ~SEE_DO
;
7454 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7455 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7456 ee_value
|= SEE_CLK
; /* Clock data! */
7457 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7458 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7459 ee_value
&= ~SEE_CLK
;
7460 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7461 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7475 ee_value
&= ~SEE_DO
;
7477 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7478 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7479 ee_value
|= SEE_CLK
; /* Clock data! */
7480 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7481 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7482 ee_value
&= ~SEE_CLK
;
7483 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7484 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7490 static unsigned short FPT_CalcCrc16(unsigned char buffer
[])
7492 unsigned short crc
= 0;
7495 for (i
= 0; i
< ID_STRING_LENGTH
; i
++) {
7496 ch
= (unsigned short)buffer
[i
];
7497 for (j
= 0; j
< 8; j
++) {
7499 crc
= (crc
>> 1) ^ CRCMASK
;
7508 static unsigned char FPT_CalcLrc(unsigned char buffer
[])
7513 for (i
= 0; i
< ID_STRING_LENGTH
; i
++)
7519 The following inline definitions avoid type conflicts.
7522 static inline unsigned char
7523 FlashPoint__ProbeHostAdapter(struct fpoint_info
*FlashPointInfo
)
7525 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info
*)
7529 static inline void *
7530 FlashPoint__HardwareResetHostAdapter(struct fpoint_info
*FlashPointInfo
)
7532 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info
*)
7537 FlashPoint__ReleaseHostAdapter(void *CardHandle
)
7539 FlashPoint_ReleaseHostAdapter(CardHandle
);
7543 FlashPoint__StartCCB(void *CardHandle
, struct blogic_ccb
*CCB
)
7545 FlashPoint_StartCCB(CardHandle
, (struct sccb
*)CCB
);
7549 FlashPoint__AbortCCB(void *CardHandle
, struct blogic_ccb
*CCB
)
7551 FlashPoint_AbortCCB(CardHandle
, (struct sccb
*)CCB
);
7555 FlashPoint__InterruptPending(void *CardHandle
)
7557 return FlashPoint_InterruptPending(CardHandle
);
7561 FlashPoint__HandleInterrupt(void *CardHandle
)
7563 return FlashPoint_HandleInterrupt(CardHandle
);
7566 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7567 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7568 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7569 #define FlashPoint_StartCCB FlashPoint__StartCCB
7570 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7571 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7572 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7574 #else /* !CONFIG_SCSI_FLASHPOINT */
7577 Define prototypes for the FlashPoint SCCB Manager Functions.
7580 extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info
*);
7581 extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info
*);
7582 extern void FlashPoint_StartCCB(void *, struct blogic_ccb
*);
7583 extern int FlashPoint_AbortCCB(void *, struct blogic_ccb
*);
7584 extern bool FlashPoint_InterruptPending(void *);
7585 extern int FlashPoint_HandleInterrupt(void *);
7586 extern void FlashPoint_ReleaseHostAdapter(void *);
7588 #endif /* CONFIG_SCSI_FLASHPOINT */