2005-04-17 02:20:36 +04:00
/*
FlashPoint . c - - FlashPoint SCCB Manager for Linux
This file contains the FlashPoint SCCB Manager from BusLogic ' s FlashPoint
Driver Developer ' s Kit , with minor modifications by Leonard N . Zubkoff for
Linux compatibility . It was provided by BusLogic in the form of 16 separate
source files , which would have unnecessarily cluttered the scsi directory , so
the individual files have been combined into this single file .
Copyright 1995 - 1996 by Mylex Corporation . All Rights Reserved
This file is available under both the GNU General Public License
and a BSD - style copyright ; see LICENSE . FlashPoint for details .
*/
2008-03-13 15:55:08 +03:00
# ifdef CONFIG_SCSI_FLASHPOINT
2005-04-17 02:20:36 +04:00
# define MAX_CARDS 8
# undef BUSTYPE_PCI
# define CRCMASK 0xA001
# define FAILURE 0xFFFFFFFFL
2006-03-08 11:14:29 +03:00
struct sccb ;
2006-03-08 11:14:35 +03:00
typedef void ( * CALL_BK_FN ) ( struct sccb * ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:30 +03:00
struct sccb_mgr_info {
2006-03-08 11:14:35 +03:00
unsigned long si_baseaddr ;
unsigned char si_present ;
unsigned char si_intvect ;
unsigned char si_id ;
unsigned char si_lun ;
unsigned short si_fw_revision ;
unsigned short si_per_targ_init_sync ;
unsigned short si_per_targ_fast_nego ;
unsigned short si_per_targ_ultra_nego ;
unsigned short si_per_targ_no_disc ;
unsigned short si_per_targ_wide_nego ;
unsigned short si_flags ;
unsigned char si_card_family ;
unsigned char si_bustype ;
unsigned char si_card_model [ 3 ] ;
unsigned char si_relative_cardnum ;
unsigned char si_reserved [ 4 ] ;
unsigned long si_OS_reserved ;
unsigned char si_XlatInfo [ 4 ] ;
unsigned long si_reserved2 [ 5 ] ;
unsigned long si_secondary_range ;
2006-03-08 11:14:30 +03:00
} ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
# define SCSI_PARITY_ENA 0x0001
# define LOW_BYTE_TERM 0x0010
# define HIGH_BYTE_TERM 0x0020
# define BUSTYPE_PCI 0x3
2005-04-17 02:20:36 +04:00
# define SUPPORT_16TAR_32LUN 0x0002
# define SOFT_RESET 0x0004
# define EXTENDED_TRANSLATION 0x0008
# define POST_ALL_UNDERRRUNS 0x0040
# define FLAG_SCAM_ENABLED 0x0080
# define FLAG_SCAM_LEVEL2 0x0100
# define HARPOON_FAMILY 0x02
2006-01-15 04:12:54 +03:00
/* SCCB struct used for both SCCB and UCB manager compiles!
2005-04-17 02:20:36 +04:00
* The UCB Manager treats the SCCB as it ' s ' native hardware structure '
*/
# pragma pack(1)
2006-03-08 11:14:29 +03:00
struct sccb {
2006-03-08 11:14:35 +03:00
unsigned char OperationCode ;
unsigned char ControlByte ;
unsigned char CdbLength ;
unsigned char RequestSenseLength ;
unsigned long DataLength ;
unsigned long DataPointer ;
unsigned char CcbRes [ 2 ] ;
unsigned char HostStatus ;
unsigned char TargetStatus ;
unsigned char TargID ;
unsigned char Lun ;
unsigned char Cdb [ 12 ] ;
unsigned char CcbRes1 ;
unsigned char Reserved1 ;
unsigned long Reserved2 ;
unsigned long SensePointer ;
CALL_BK_FN SccbCallback ; /* VOID (*SccbCallback)(); */
unsigned long SccbIOPort ; /* Identifies board base port */
unsigned char SccbStatus ;
unsigned char SCCBRes2 ;
unsigned short SccbOSFlags ;
unsigned long Sccb_XferCnt ; /* actual transfer count */
unsigned long Sccb_ATC ;
unsigned long SccbVirtDataPtr ; /* virtual addr for OS/2 */
unsigned long Sccb_res1 ;
unsigned short Sccb_MGRFlags ;
unsigned short Sccb_sgseg ;
unsigned char Sccb_scsimsg ; /* identify msg for selection */
unsigned char Sccb_tag ;
unsigned char Sccb_scsistat ;
unsigned char Sccb_idmsg ; /* image of last msg in */
struct sccb * Sccb_forwardlink ;
struct sccb * Sccb_backlink ;
unsigned long Sccb_savedATC ;
unsigned char Save_Cdb [ 6 ] ;
unsigned char Save_CdbLen ;
unsigned char Sccb_XferState ;
unsigned long Sccb_SGoffset ;
} ;
2005-04-17 02:20:36 +04:00
# pragma pack()
# define SCATTER_GATHER_COMMAND 0x02
# define RESIDUAL_COMMAND 0x03
# define RESIDUAL_SG_COMMAND 0x04
# define RESET_COMMAND 0x81
2006-03-08 11:14:35 +03:00
# define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
# define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
# define SCCB_DATA_XFER_OUT 0x10 /* Write */
# define SCCB_DATA_XFER_IN 0x08 /* Read */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define BUS_FREE_ST 0
2005-04-17 02:20:36 +04:00
# define SELECT_ST 1
2006-03-08 11:14:35 +03:00
# define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
# define SELECT_SN_ST 3 /* Select w\ Sync Nego */
# define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
# define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
2005-04-17 02:20:36 +04:00
# define COMMAND_ST 6
# define DATA_OUT_ST 7
# define DATA_IN_ST 8
# define DISCONNECT_ST 9
# define ABORT_ST 11
# define F_HOST_XFER_DIR 0x01
# define F_ALL_XFERRED 0x02
# define F_SG_XFER 0x04
# define F_AUTO_SENSE 0x08
# define F_ODD_BALL_CNT 0x10
# define F_NO_DATA_YET 0x80
# define F_STATUSLOADED 0x01
# define F_DEV_SELECTED 0x04
2006-03-08 11:14:35 +03:00
# define SCCB_COMPLETE 0x00 /* SCCB completed without error */
2005-04-17 02:20:36 +04:00
# define SCCB_DATA_UNDER_RUN 0x0C
2006-03-08 11:14:35 +03:00
# define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
2005-04-17 02:20:36 +04:00
# define SCCB_DATA_OVER_RUN 0x12
2006-03-08 11:14:35 +03:00
# define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
# define SCCB_BM_ERR 0x30 /* BusMaster error. */
# define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
2005-04-17 02:20:36 +04:00
# define SCCB_IN_PROCESS 0x00
# define SCCB_SUCCESS 0x01
# define SCCB_ABORT 0x02
# define SCCB_ERROR 0x04
# define ORION_FW_REV 3110
2006-03-08 11:14:35 +03:00
# define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
# define MAX_SCSI_TAR 16
# define MAX_LUN 32
# define LUN_MASK 0x1f
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SG_BUF_CNT 16 /*Number of prefetched elements. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:28 +03:00
# define RD_HARPOON(ioport) inb((u32)ioport)
# define RDW_HARPOON(ioport) inw((u32)ioport)
# define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
# define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
# define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
# define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
2005-04-17 02:20:36 +04:00
# define TAR_SYNC_MASK (BIT(7)+BIT(6))
# define SYNC_TRYING BIT(6)
# define SYNC_SUPPORTED (BIT(7)+BIT(6))
# define TAR_WIDE_MASK (BIT(5)+BIT(4))
# define WIDE_ENABLED BIT(4)
# define WIDE_NEGOCIATED BIT(5)
# define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
# define TAG_Q_TRYING BIT(2)
# define TAG_Q_REJECT BIT(3)
# define TAR_ALLOW_DISC BIT(0)
# define EE_SYNC_MASK (BIT(0)+BIT(1))
# define EE_SYNC_5MB BIT(0)
# define EE_SYNC_10MB BIT(1)
# define EE_SYNC_20MB (BIT(0)+BIT(1))
# define EE_WIDE_SCSI BIT(7)
2006-03-08 11:14:31 +03:00
struct sccb_mgr_tar_info {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
struct sccb * TarSelQ_Head ;
struct sccb * TarSelQ_Tail ;
unsigned char TarLUN_CA ; /*Contingent Allgiance */
unsigned char TarTagQ_Cnt ;
unsigned char TarSelQ_Cnt ;
unsigned char TarStatus ;
unsigned char TarEEValue ;
unsigned char TarSyncCtrl ;
unsigned char TarReserved [ 2 ] ; /* for alignment */
unsigned char LunDiscQ_Idx [ MAX_LUN ] ;
unsigned char TarLUNBusy [ MAX_LUN ] ;
2006-03-08 11:14:31 +03:00
} ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:33 +03:00
struct nvram_info {
2006-03-08 11:14:35 +03:00
unsigned char niModel ; /* Model No. of card */
unsigned char niCardNo ; /* Card no. */
unsigned long niBaseAddr ; /* Port Address of card */
unsigned char niSysConf ; /* Adapter Configuration byte - Byte 16 of eeprom map */
unsigned char niScsiConf ; /* SCSI Configuration byte - Byte 17 of eeprom map */
unsigned char niScamConf ; /* SCAM Configuration byte - Byte 20 of eeprom map */
unsigned char niAdapId ; /* Host Adapter ID - Byte 24 of eerpom map */
unsigned char niSyncTbl [ MAX_SCSI_TAR / 2 ] ; /* Sync/Wide byte of targets */
unsigned char niScamTbl [ MAX_SCSI_TAR ] [ 4 ] ; /* Compressed Scam name string of Targets */
2006-03-08 11:14:33 +03:00
} ;
2005-04-17 02:20:36 +04:00
# define MODEL_LT 1
# define MODEL_DL 2
# define MODEL_LW 3
# define MODEL_DW 4
2006-03-08 11:14:34 +03:00
struct sccb_card {
2006-03-08 11:14:35 +03:00
struct sccb * currentSCCB ;
struct sccb_mgr_info * cardInfo ;
unsigned long ioPort ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
unsigned short cmdCounter ;
unsigned char discQCount ;
unsigned char tagQ_Lst ;
unsigned char cardIndex ;
unsigned char scanIndex ;
unsigned char globalFlags ;
unsigned char ourId ;
struct nvram_info * pNvRamInfo ;
struct sccb * discQ_Tbl [ QUEUE_DEPTH ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} ;
2005-04-17 02:20:36 +04:00
# define F_TAG_STARTED 0x01
# define F_CONLUN_IO 0x02
# define F_DO_RENEGO 0x04
# define F_NO_FILTER 0x08
# define F_GREEN_PC 0x10
# define F_HOST_XFER_ACT 0x20
# define F_NEW_SCCB_CMD 0x40
# define F_UPDATE_EEPROM 0x80
# define ID_STRING_LENGTH 32
2006-03-08 11:14:35 +03:00
# define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
2005-04-17 02:20:36 +04:00
# define ASSIGN_ID 0x00
# define SET_P_FLAG 0x01
# define CFG_CMPLT 0x03
# define DOM_MSTR 0x0F
# define SYNC_PTRN 0x1F
# define ID_0_7 0x18
# define ID_8_F 0x11
# define MISC_CODE 0x14
# define CLR_P_FLAG 0x18
# define INIT_SELTD 0x01
# define LEVEL2_TAR 0x02
2006-03-08 11:14:35 +03:00
enum scam_id_st { ID0 , ID1 , ID2 , ID3 , ID4 , ID5 , ID6 , ID7 , ID8 , ID9 , ID10 , ID11 ,
ID12 ,
ID13 , ID14 , ID15 , ID_UNUSED , ID_UNASSIGNED , ID_ASSIGNED , LEGACY ,
CLR_PRIORITY , NO_ID_AVAIL
} ;
2005-04-17 02:20:36 +04:00
typedef struct SCCBscam_info {
2006-03-08 11:14:35 +03:00
unsigned char id_string [ ID_STRING_LENGTH ] ;
enum scam_id_st state ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} SCCBSCAM_INFO ;
2005-04-17 02:20:36 +04:00
# define SCSI_REQUEST_SENSE 0x03
# define SCSI_READ 0x08
# define SCSI_WRITE 0x0A
# define SCSI_START_STOP_UNIT 0x1B
# define SCSI_READ_EXTENDED 0x28
# define SCSI_WRITE_EXTENDED 0x2A
# define SCSI_WRITE_AND_VERIFY 0x2E
# define SSGOOD 0x00
# define SSCHECK 0x02
# define SSQ_FULL 0x28
# define SMCMD_COMP 0x00
# define SMEXT 0x01
# define SMSAVE_DATA_PTR 0x02
# define SMREST_DATA_PTR 0x03
# define SMDISC 0x04
# define SMABORT 0x06
# define SMREJECT 0x07
# define SMNO_OP 0x08
# define SMPARITY 0x09
# define SMDEV_RESET 0x0C
# define SMABORT_TAG 0x0D
# define SMINIT_RECOVERY 0x0F
# define SMREL_RECOVERY 0x10
# define SMIDENT 0x80
# define DISC_PRIV 0x40
# define SMSYNC 0x01
# define SMWDTR 0x03
# define SM8BIT 0x00
# define SM16BIT 0x01
2006-03-08 11:14:35 +03:00
# define SMIGNORWR 0x23 /* Ignore Wide Residue */
2005-04-17 02:20:36 +04:00
# define SIX_BYTE_CMD 0x06
# define TWELVE_BYTE_CMD 0x0C
# define ASYNC 0x00
2006-03-08 11:14:35 +03:00
# define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
2005-04-17 02:20:36 +04:00
# define EEPROM_WD_CNT 256
# define EEPROM_CHECK_SUM 0
# define FW_SIGNATURE 2
# define MODEL_NUMB_0 4
# define MODEL_NUMB_2 6
# define MODEL_NUMB_4 8
# define SYSTEM_CONFIG 16
# define SCSI_CONFIG 17
# define BIOS_CONFIG 18
# define SCAM_CONFIG 20
# define ADAPTER_SCSI_ID 24
# define IGNORE_B_SCAN 32
# define SEND_START_ENA 34
# define DEVICE_ENABLE 36
# define SYNC_RATE_TBL 38
# define SYNC_RATE_TBL01 38
# define SYNC_RATE_TBL23 40
# define SYNC_RATE_TBL45 42
# define SYNC_RATE_TBL67 44
# define SYNC_RATE_TBL89 46
# define SYNC_RATE_TBLab 48
# define SYNC_RATE_TBLcd 50
# define SYNC_RATE_TBLef 52
2006-03-08 11:14:35 +03:00
# define EE_SCAMBASE 256
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCAM_ENABLED BIT(2)
# define SCAM_LEVEL2 BIT(3)
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define RENEGO_ENA BIT(10)
# define CONNIO_ENA BIT(11)
# define GREEN_PC_ENA BIT(12)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define AUTO_RATE_00 00
# define AUTO_RATE_05 01
# define AUTO_RATE_10 02
# define AUTO_RATE_20 03
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define WIDE_NEGO_BIT BIT(7)
# define DISC_ENABLE_BIT BIT(6)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_vendor_id_0 0x00 /* LSB */
# define ORION_VEND_0 0x4B
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_vendor_id_1 0x01 /* MSB */
# define ORION_VEND_1 0x10
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_device_id_0 0x02 /* LSB */
# define ORION_DEV_0 0x30
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_device_id_1 0x03 /* MSB */
# define ORION_DEV_1 0x81
2005-04-17 02:20:36 +04:00
/* Sub Vendor ID and Sub Device ID only available in
2006-03-08 11:14:35 +03:00
Harpoon Version 2 and higher */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_sub_device_id_0 0x06 /* LSB */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_semaphore 0x0C
# define SCCB_MGR_ACTIVE BIT(0)
# define TICKLE_ME BIT(1)
# define SCCB_MGR_PRESENT BIT(3)
# define BIOS_IN_USE BIT(4)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_sys_ctrl 0x0F
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
# define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
# define HALT_MACH BIT(3) /*Halt State Machine */
# define HARD_ABORT BIT(4) /*Hard Abort */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_host_blk_cnt 0x13
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_int_mask 0x17
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define INT_CMD_COMPL BIT(0) /* DMA command complete */
# define INT_EXT_STATUS BIT(1) /* Extended Status Set */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_xfer_cnt_lo 0x18
# define hp_xfer_cnt_hi 0x1A
# define hp_xfer_cmd 0x1B
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
# define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
# define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_host_addr_lo 0x1C
# define hp_host_addr_hmi 0x1E
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_ee_ctrl 0x22
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define EXT_ARB_ACK BIT(7)
# define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
# define SEE_MS BIT(5)
# define SEE_CS BIT(3)
# define SEE_CLK BIT(2)
# define SEE_DO BIT(1)
# define SEE_DI BIT(0)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define EE_READ 0x06
# define EE_WRITE 0x05
# define EWEN 0x04
# define EWEN_ADDR 0x03C0
# define EWDS 0x04
# define EWDS_ADDR 0x0000
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_bm_ctrl 0x26
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
# define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
# define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
# define FAST_SINGLE BIT(6) /*?? */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_sg_addr 0x28
# define hp_page_ctrl 0x29
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCATTER_EN BIT(0)
# define SGRAM_ARAM BIT(1)
# define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
# define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_pci_stat_cfg 0x2D
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define REC_MASTER_ABORT BIT(5) /*received Master abort */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_rev_num 0x33
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_stack_data 0x34
# define hp_stack_addr 0x35
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_ext_status 0x36
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
# define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
# define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
# define CMD_ABORTED BIT(4) /*Command aborted */
# define BM_PARITY_ERR BIT(5) /*parity error on data received */
# define PIO_OVERRUN BIT(6) /*Slave data overrun */
# define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
# define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
2005-04-17 02:20:36 +04:00
BM_PARITY_ERR | PIO_OVERRUN )
2006-03-08 11:14:35 +03:00
# define hp_int_status 0x37
# define EXT_STATUS_ON BIT(1) /*Extended status is valid */
# define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
# define INT_ASSERTED BIT(5) /* */
# define hp_fifo_cnt 0x38
# define hp_intena 0x40
2007-10-19 10:40:36 +04:00
# define RESET BIT(7)
# define PROG_HLT BIT(6)
# define PARITY BIT(5)
# define FIFO BIT(4)
# define SEL BIT(3)
# define SCAM_SEL BIT(2)
# define RSEL BIT(1)
# define TIMEOUT BIT(0)
# define BUS_FREE BIT(15)
# define XFER_CNT_0 BIT(14)
# define PHASE BIT(13)
# define IUNKWN BIT(12)
# define ICMD_COMP BIT(11)
# define ITICKLE BIT(10)
# define IDO_STRT BIT(9)
# define ITAR_DISC BIT(8)
# define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
2006-03-08 11:14:35 +03:00
# define CLR_ALL_INT 0xFFFF
# define CLR_ALL_INT_1 0xFF00
# define hp_intstat 0x42
# define hp_scsisig 0x44
# define SCSI_SEL BIT(7)
# define SCSI_BSY BIT(6)
# define SCSI_REQ BIT(5)
# define SCSI_ACK BIT(4)
# define SCSI_ATN BIT(3)
# define SCSI_CD BIT(2)
# define SCSI_MSG BIT(1)
# define SCSI_IOBIT BIT(0)
# define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
# define S_MSGO_PH (BIT(2)+BIT(1) )
# define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
# define S_DATAI_PH ( BIT(0))
# define S_DATAO_PH 0x00
# define S_ILL_PH ( BIT(1) )
# define hp_scsictrl_0 0x45
# define SEL_TAR BIT(6)
# define ENA_ATN BIT(4)
# define ENA_RESEL BIT(2)
# define SCSI_RST BIT(1)
# define ENA_SCAM_SEL BIT(0)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_portctrl_0 0x46
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCSI_PORT BIT(7)
# define SCSI_INBIT BIT(6)
# define DMA_PORT BIT(5)
# define DMA_RD BIT(4)
# define HOST_PORT BIT(3)
# define HOST_WRT BIT(2)
# define SCSI_BUS_EN BIT(1)
# define START_TO BIT(0)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_scsireset 0x47
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCSI_INI BIT(6)
# define SCAM_EN BIT(5)
# define DMA_RESET BIT(3)
# define HPSCSI_RESET BIT(2)
# define PROG_RESET BIT(1)
# define FIFO_CLR BIT(0)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_xfercnt_0 0x48
# define hp_xfercnt_2 0x4A
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_fifodata_0 0x4C
# define hp_addstat 0x4E
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SCAM_TIMER BIT(7)
# define SCSI_MODE8 BIT(3)
# define SCSI_PAR_ERR BIT(0)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_prgmcnt_0 0x4F
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_selfid_0 0x50
# define hp_selfid_1 0x51
# define hp_arb_id 0x52
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_select_id 0x53
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_synctarg_base 0x54
# define hp_synctarg_12 0x54
# define hp_synctarg_13 0x55
# define hp_synctarg_14 0x56
# define hp_synctarg_15 0x57
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_synctarg_8 0x58
# define hp_synctarg_9 0x59
# define hp_synctarg_10 0x5A
# define hp_synctarg_11 0x5B
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_synctarg_4 0x5C
# define hp_synctarg_5 0x5D
# define hp_synctarg_6 0x5E
# define hp_synctarg_7 0x5F
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_synctarg_0 0x60
# define hp_synctarg_1 0x61
# define hp_synctarg_2 0x62
# define hp_synctarg_3 0x63
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define NARROW_SCSI BIT(4)
# define DEFAULT_OFFSET 0x0F
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_autostart_0 0x64
# define hp_autostart_1 0x65
# define hp_autostart_3 0x67
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define AUTO_IMMED BIT(5)
# define SELECT BIT(6)
# define END_DATA (BIT(7)+BIT(6))
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_gp_reg_0 0x68
# define hp_gp_reg_1 0x69
# define hp_gp_reg_3 0x6B
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_seltimeout 0x6C
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define TO_4ms 0x67 /* 3.9959ms */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define TO_5ms 0x03 /* 4.9152ms */
# define TO_10ms 0x07 /* 11.xxxms */
# define TO_250ms 0x99 /* 250.68ms */
# define TO_290ms 0xB1 /* 289.99ms */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_clkctrl_0 0x6D
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define PWR_DWN BIT(6)
# define ACTdeassert BIT(4)
# define CLK_40MHZ (BIT(1) + BIT(0))
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_fiforead 0x6E
# define hp_fifowrite 0x6F
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_offsetctr 0x70
# define hp_xferstat 0x71
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define FIFO_EMPTY BIT(6)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_portctrl_1 0x72
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define CHK_SCSI_P BIT(3)
# define HOST_MODE8 BIT(0)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_xfer_pad 0x73
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define ID_UNLOCK BIT(3)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_scsidata_0 0x74
# define hp_scsidata_1 0x75
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define hp_aramBase 0x80
# define BIOS_DATA_OFFSET 0x60
# define BIOS_RELATIVE_CARD 0x64
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define AR3 (BIT(9) + BIT(8))
# define SDATA BIT(10)
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define ADATA_OUT 0x00
2007-10-19 10:40:36 +04:00
# define ADATA_IN BIT(8)
# define ACOMMAND BIT(10)
# define ASTATUS (BIT(10)+BIT(8))
# define AMSG_OUT (BIT(10)+BIT(9))
# define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define BRH_OP BIT(13) /* Branch */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define ALWAYS 0x00
2007-10-19 10:40:36 +04:00
# define EQUAL BIT(8)
# define NOT_EQ BIT(9)
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define FIFO_0 BIT(10)
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define MPM_OP BIT(15) /* Match phase and move data */
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define MRR_OP BIT(14) /* Move DReg. to Reg. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define S_IDREG (BIT(2)+BIT(1)+BIT(0))
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define D_AR0 0x00
# define D_AR1 BIT(0)
# define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define RAT_OP (BIT(14)+BIT(13)+BIT(11))
2005-04-17 02:20:36 +04:00
2007-10-19 10:40:36 +04:00
# define SSI_OP (BIT(15)+BIT(11))
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SSI_ITAR_DISC (ITAR_DISC >> 8)
# define SSI_IDO_STRT (IDO_STRT >> 8)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SSI_ICMD_COMP (ICMD_COMP >> 8)
# define SSI_ITICKLE (ITICKLE >> 8)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define SSI_IUNKWN (IUNKWN >> 8)
# define SSI_INO_CC (IUNKWN >> 8)
# define SSI_IRFAIL (IUNKWN >> 8)
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define NP 0x10 /*Next Phase */
# define NTCMD 0x02 /*Non- Tagged Command start */
# define CMDPZ 0x04 /*Command phase */
# define DINT 0x12 /*Data Out/In interrupt */
# define DI 0x13 /*Data Out */
# define DC 0x19 /*Disconnect Message */
# define ST 0x1D /*Status Phase */
# define UNKNWN 0x24 /*Unknown bus action */
# define CC 0x25 /*Command Completion failure */
# define TICK 0x26 /*New target reselected us. */
# define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define ID_MSG_STRT hp_aramBase + 0x00
# define NON_TAG_ID_MSG hp_aramBase + 0x06
# define CMD_STRT hp_aramBase + 0x08
# define SYNC_MSGS hp_aramBase + 0x08
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
# define TAG_STRT 0x00
# define DISCONNECT_START 0x10 / 2
# define END_DATA_START 0x14 / 2
# define CMD_ONLY_STRT CMDPZ / 2
# define SELCHK_STRT SELCHK / 2
2005-04-17 02:20:36 +04:00
# define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
xfercnt < < = 16 , \
2006-03-08 11:14:25 +03:00
xfercnt | = RDW_HARPOON ( ( unsigned short ) ( port + hp_xfercnt_0 ) ) )
2005-04-17 02:20:36 +04:00
*/
2006-03-08 11:14:25 +03:00
# define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
2005-04-17 02:20:36 +04:00
addr > > = 16 , \
2006-03-08 11:14:25 +03:00
WRW_HARPOON ( ( port + hp_host_addr_hmi ) , ( unsigned short ) ( addr & 0x0000FFFFL ) ) , \
2005-04-17 02:20:36 +04:00
WR_HARP32 ( port , hp_xfercnt_0 , count ) , \
2006-03-08 11:14:25 +03:00
WRW_HARPOON ( ( port + hp_xfer_cnt_lo ) , ( unsigned short ) ( count & 0x0000FFFFL ) ) , \
2005-04-17 02:20:36 +04:00
count > > = 16 , \
WR_HARPOON ( port + hp_xfer_cnt_hi , ( count & 0xFF ) ) )
# define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
WR_HARPOON ( port + hp_scsisig , S_ILL_PH ) ; }
# define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
WR_HARPOON ( port + hp_scsisig , ( S_ILL_PH | SCSI_ATN ) ) ; }
# define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
WR_HARPOON ( port + hp_scsireset , 0x00 ) )
# define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
( RD_HARPOON ( p_port + hp_page_ctrl ) | SGRAM_ARAM ) ) )
# define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ SGRAM_ARAM ) ) )
# define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
( RD_HARPOON ( p_port + hp_page_ctrl ) | G_INT_DISABLE ) ) )
# define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) )
2006-03-08 11:14:35 +03:00
static unsigned char FPT_sisyncn ( unsigned long port , unsigned char p_card ,
unsigned char syncFlag ) ;
static void FPT_ssel ( unsigned long port , unsigned char p_card ) ;
static void FPT_sres ( unsigned long port , unsigned char p_card ,
struct sccb_card * pCurrCard ) ;
static void FPT_shandem ( unsigned long port , unsigned char p_card ,
struct sccb * pCurrSCCB ) ;
static void FPT_stsyncn ( unsigned long port , unsigned char p_card ) ;
static void FPT_sisyncr ( unsigned long port , unsigned char sync_pulse ,
unsigned char offset ) ;
static void FPT_sssyncv ( unsigned long p_port , unsigned char p_id ,
unsigned char p_sync_value ,
struct sccb_mgr_tar_info * currTar_Info ) ;
static void FPT_sresb ( unsigned long port , unsigned char p_card ) ;
static void FPT_sxfrp ( unsigned long p_port , unsigned char p_card ) ;
static void FPT_schkdd ( unsigned long port , unsigned char p_card ) ;
2006-03-08 11:14:26 +03:00
static unsigned char FPT_RdStack ( unsigned long port , unsigned char index ) ;
2006-03-08 11:14:35 +03:00
static void FPT_WrStack ( unsigned long portBase , unsigned char index ,
unsigned char data ) ;
2006-03-08 11:14:26 +03:00
static unsigned char FPT_ChkIfChipInitialized ( unsigned long ioPort ) ;
static void FPT_SendMsg ( unsigned long port , unsigned char message ) ;
2006-03-08 11:14:35 +03:00
static void FPT_queueFlushTargSccb ( unsigned char p_card , unsigned char thisTarg ,
unsigned char error_code ) ;
2006-03-08 11:14:24 +03:00
2006-03-08 11:14:35 +03:00
static void FPT_sinits ( struct sccb * p_sccb , unsigned char p_card ) ;
static void FPT_RNVRamData ( struct nvram_info * pNvRamInfo ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
static unsigned char FPT_siwidn ( unsigned long port , unsigned char p_card ) ;
2006-03-08 11:14:35 +03:00
static void FPT_stwidn ( unsigned long port , unsigned char p_card ) ;
static void FPT_siwidr ( unsigned long port , unsigned char width ) ;
static void FPT_queueSelectFail ( struct sccb_card * pCurrCard ,
unsigned char p_card ) ;
static void FPT_queueDisconnect ( struct sccb * p_SCCB , unsigned char p_card ) ;
static void FPT_queueCmdComplete ( struct sccb_card * pCurrCard ,
struct sccb * p_SCCB , unsigned char p_card ) ;
static void FPT_queueSearchSelect ( struct sccb_card * pCurrCard ,
2006-03-08 11:14:24 +03:00
unsigned char p_card ) ;
2006-03-08 11:14:35 +03:00
static void FPT_queueFlushSccb ( unsigned char p_card , unsigned char error_code ) ;
static void FPT_queueAddSccb ( struct sccb * p_SCCB , unsigned char card ) ;
static unsigned char FPT_queueFindSccb ( struct sccb * p_SCCB ,
unsigned char p_card ) ;
static void FPT_utilUpdateResidual ( struct sccb * p_SCCB ) ;
2006-03-08 11:14:25 +03:00
static unsigned short FPT_CalcCrc16 ( unsigned char buffer [ ] ) ;
2006-03-08 11:14:35 +03:00
static unsigned char FPT_CalcLrc ( unsigned char buffer [ ] ) ;
static void FPT_Wait1Second ( unsigned long p_port ) ;
static void FPT_Wait ( unsigned long p_port , unsigned char p_delay ) ;
static void FPT_utilEEWriteOnOff ( unsigned long p_port , unsigned char p_mode ) ;
static void FPT_utilEEWrite ( unsigned long p_port , unsigned short ee_data ,
unsigned short ee_addr ) ;
static unsigned short FPT_utilEERead ( unsigned long p_port ,
unsigned short ee_addr ) ;
static unsigned short FPT_utilEEReadOrg ( unsigned long p_port ,
unsigned short ee_addr ) ;
static void FPT_utilEESendCmdAddr ( unsigned long p_port , unsigned char ee_cmd ,
unsigned short ee_addr ) ;
static void FPT_phaseDataOut ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseDataIn ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseCommand ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseStatus ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseMsgOut ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseMsgIn ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseIllegal ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseDecode ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseChkFifo ( unsigned long port , unsigned char p_card ) ;
static void FPT_phaseBusFree ( unsigned long p_port , unsigned char p_card ) ;
static void FPT_XbowInit ( unsigned long port , unsigned char scamFlg ) ;
static void FPT_BusMasterInit ( unsigned long p_port ) ;
static void FPT_DiagEEPROM ( unsigned long p_port ) ;
static void FPT_dataXferProcessor ( unsigned long port ,
struct sccb_card * pCurrCard ) ;
static void FPT_busMstrSGDataXferStart ( unsigned long port ,
struct sccb * pCurrSCCB ) ;
static void FPT_busMstrDataXferStart ( unsigned long port ,
struct sccb * pCurrSCCB ) ;
static void FPT_hostDataXferAbort ( unsigned long port , unsigned char p_card ,
struct sccb * pCurrSCCB ) ;
static void FPT_hostDataXferRestart ( struct sccb * currSCCB ) ;
static unsigned char FPT_SccbMgr_bad_isr ( unsigned long p_port ,
unsigned char p_card ,
struct sccb_card * pCurrCard ,
unsigned short p_int ) ;
static void FPT_SccbMgrTableInitAll ( void ) ;
static void FPT_SccbMgrTableInitCard ( struct sccb_card * pCurrCard ,
unsigned char p_card ) ;
static void FPT_SccbMgrTableInitTarget ( unsigned char p_card ,
unsigned char target ) ;
static void FPT_scini ( unsigned char p_card , unsigned char p_our_id ,
unsigned char p_power_up ) ;
static int FPT_scarb ( unsigned long p_port , unsigned char p_sel_type ) ;
static void FPT_scbusf ( unsigned long p_port ) ;
static void FPT_scsel ( unsigned long p_port ) ;
static void FPT_scasid ( unsigned char p_card , unsigned long p_port ) ;
2006-03-08 11:14:26 +03:00
static unsigned char FPT_scxferc ( unsigned long p_port , unsigned char p_data ) ;
2006-03-08 11:14:35 +03:00
static unsigned char FPT_scsendi ( unsigned long p_port ,
unsigned char p_id_string [ ] ) ;
static unsigned char FPT_sciso ( unsigned long p_port ,
unsigned char p_id_string [ ] ) ;
static void FPT_scwirod ( unsigned long p_port , unsigned char p_data_bit ) ;
static void FPT_scwiros ( unsigned long p_port , unsigned char p_data_bit ) ;
2006-03-08 11:14:24 +03:00
static unsigned char FPT_scvalq ( unsigned char p_quintet ) ;
2006-03-08 11:14:26 +03:00
static unsigned char FPT_scsell ( unsigned long p_port , unsigned char targ_id ) ;
2006-03-08 11:14:35 +03:00
static void FPT_scwtsel ( unsigned long p_port ) ;
static void FPT_inisci ( unsigned char p_card , unsigned long p_port ,
unsigned char p_our_id ) ;
static void FPT_scsavdi ( unsigned char p_card , unsigned long p_port ) ;
static unsigned char FPT_scmachid ( unsigned char p_card ,
unsigned char p_id_string [ ] ) ;
static void FPT_autoCmdCmplt ( unsigned long p_port , unsigned char p_card ) ;
static void FPT_autoLoadDefaultMap ( unsigned long p_port ) ;
static struct sccb_mgr_tar_info FPT_sccbMgrTbl [ MAX_CARDS ] [ MAX_SCSI_TAR ] =
{ { { 0 } } } ;
static struct sccb_card FPT_BL_Card [ MAX_CARDS ] = { { 0 } } ;
static SCCBSCAM_INFO FPT_scamInfo [ MAX_SCSI_TAR ] = { { { 0 } } } ;
static struct nvram_info FPT_nvRamInfo [ MAX_MB_CARDS ] = { { 0 } } ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
static unsigned char FPT_mbCards = 0 ;
2006-03-08 11:14:35 +03:00
static unsigned char FPT_scamHAString [ ] =
{ 0x63 , 0x07 , ' B ' , ' U ' , ' S ' , ' L ' , ' O ' , ' G ' , ' I ' , ' C ' ,
' ' , ' B ' , ' T ' , ' - ' , ' 9 ' , ' 3 ' , ' 0 ' ,
0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 ,
0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20 , 0x20
} ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:25 +03:00
static unsigned short FPT_default_intena = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
static void ( * FPT_s_PhaseTbl [ 8 ] ) ( unsigned long , unsigned char ) = {
0 } ;
2005-04-17 02:20:36 +04:00
/*---------------------------------------------------------------------
*
2006-03-08 11:14:23 +03:00
* Function : FlashPoint_ProbeHostAdapter
2005-04-17 02:20:36 +04:00
*
* Description : Setup and / or Search for cards and return info to caller .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static int FlashPoint_ProbeHostAdapter ( struct sccb_mgr_info * pCardInfo )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
static unsigned char first_time = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
unsigned char i , j , id , ScamFlg ;
unsigned short temp , temp2 , temp3 , temp4 , temp5 , temp6 ;
unsigned long ioport ;
struct nvram_info * pCurrNvRam ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ioport = pCardInfo - > si_baseaddr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( ioport + hp_vendor_id_0 ) ! = ORION_VEND_0 )
2006-03-08 11:14:37 +03:00
return ( int ) FAILURE ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( ioport + hp_vendor_id_1 ) ! = ORION_VEND_1 ) )
2006-03-08 11:14:37 +03:00
return ( int ) FAILURE ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( ioport + hp_device_id_0 ) ! = ORION_DEV_0 ) )
2006-03-08 11:14:37 +03:00
return ( int ) FAILURE ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( ioport + hp_device_id_1 ) ! = ORION_DEV_1 ) )
2006-03-08 11:14:37 +03:00
return ( int ) FAILURE ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( ioport + hp_rev_num ) ! = 0x0f ) {
2005-04-17 02:20:36 +04:00
/* For new Harpoon then check for sub_device ID LSB
the bits ( 0 - 3 ) must be all ZERO for compatible with
current version of SCCBMgr , else skip this Harpoon
device . */
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( ioport + hp_sub_device_id_0 ) & 0x0f )
2006-03-08 11:14:37 +03:00
return ( int ) FAILURE ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( first_time ) {
FPT_SccbMgrTableInitAll ( ) ;
first_time = 0 ;
2005-04-24 11:38:05 +04:00
FPT_mbCards = 0 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_RdStack ( ioport , 0 ) ! = 0x00 ) {
if ( FPT_ChkIfChipInitialized ( ioport ) = = 0 ) {
2005-04-17 02:20:36 +04:00
pCurrNvRam = NULL ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ioport + hp_semaphore , 0x00 ) ;
FPT_XbowInit ( ioport , 0 ) ; /*Must Init the SCSI before attempting */
2005-04-24 11:38:05 +04:00
FPT_DiagEEPROM ( ioport ) ;
2006-03-08 11:14:35 +03:00
} else {
if ( FPT_mbCards < MAX_MB_CARDS ) {
2005-04-24 11:38:05 +04:00
pCurrNvRam = & FPT_nvRamInfo [ FPT_mbCards ] ;
FPT_mbCards + + ;
2005-04-17 02:20:36 +04:00
pCurrNvRam - > niBaseAddr = ioport ;
2005-04-24 11:38:05 +04:00
FPT_RNVRamData ( pCurrNvRam ) ;
2006-03-08 11:14:35 +03:00
} else
2006-03-08 11:14:37 +03:00
return ( int ) FAILURE ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else
2005-04-17 02:20:36 +04:00
pCurrNvRam = NULL ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ioport + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( ioport + hp_sys_ctrl , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam )
2005-04-17 02:20:36 +04:00
pCardInfo - > si_id = pCurrNvRam - > niAdapId ;
else
2006-03-08 11:14:35 +03:00
pCardInfo - > si_id =
( unsigned
char ) ( FPT_utilEERead ( ioport ,
( ADAPTER_SCSI_ID /
2 ) ) & ( unsigned char ) 0x0FF ) ;
pCardInfo - > si_lun = 0x00 ;
pCardInfo - > si_fw_revision = ORION_FW_REV ;
temp2 = 0x0000 ;
temp3 = 0x0000 ;
temp4 = 0x0000 ;
temp5 = 0x0000 ;
temp6 = 0x0000 ;
for ( id = 0 ; id < ( 16 / 2 ) ; id + + ) {
if ( pCurrNvRam ) {
temp = ( unsigned short ) pCurrNvRam - > niSyncTbl [ id ] ;
temp = ( ( temp & 0x03 ) + ( ( temp < < 4 ) & 0xc0 ) ) +
( ( ( temp < < 4 ) & 0x0300 ) + ( ( temp < < 8 ) & 0xc000 ) ) ;
} else
temp =
FPT_utilEERead ( ioport ,
( unsigned short ) ( ( SYNC_RATE_TBL / 2 )
+ id ) ) ;
for ( i = 0 ; i < 2 ; temp > > = 8 , i + + ) {
temp2 > > = 1 ;
temp3 > > = 1 ;
temp4 > > = 1 ;
temp5 > > = 1 ;
temp6 > > = 1 ;
switch ( temp & 0x3 ) {
case AUTO_RATE_20 : /* Synchronous, 20 mega-transfers/second */
temp6 | = 0x8000 ; /* Fall through */
case AUTO_RATE_10 : /* Synchronous, 10 mega-transfers/second */
temp5 | = 0x8000 ; /* Fall through */
case AUTO_RATE_05 : /* Synchronous, 5 mega-transfers/second */
temp2 | = 0x8000 ; /* Fall through */
case AUTO_RATE_00 : /* Asynchronous */
break ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( temp & DISC_ENABLE_BIT )
temp3 | = 0x8000 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( temp & WIDE_NEGO_BIT )
temp4 | = 0x8000 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCardInfo - > si_per_targ_init_sync = temp2 ;
pCardInfo - > si_per_targ_no_disc = temp3 ;
pCardInfo - > si_per_targ_wide_nego = temp4 ;
pCardInfo - > si_per_targ_fast_nego = temp5 ;
pCardInfo - > si_per_targ_ultra_nego = temp6 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam )
2005-04-17 02:20:36 +04:00
i = pCurrNvRam - > niSysConf ;
else
2006-03-08 11:14:35 +03:00
i = ( unsigned
char ) ( FPT_utilEERead ( ioport , ( SYSTEM_CONFIG / 2 ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam )
2005-04-17 02:20:36 +04:00
ScamFlg = pCurrNvRam - > niScamConf ;
else
2006-03-08 11:14:35 +03:00
ScamFlg =
( unsigned char ) FPT_utilEERead ( ioport , SCAM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCardInfo - > si_flags = 0x0000 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( i & 0x01 )
pCardInfo - > si_flags | = SCSI_PARITY_ENA ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( i & 0x02 ) )
pCardInfo - > si_flags | = SOFT_RESET ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( i & 0x10 )
pCardInfo - > si_flags | = EXTENDED_TRANSLATION ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ScamFlg & SCAM_ENABLED )
pCardInfo - > si_flags | = FLAG_SCAM_ENABLED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ScamFlg & SCAM_LEVEL2 )
pCardInfo - > si_flags | = FLAG_SCAM_LEVEL2 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
j = ( RD_HARPOON ( ioport + hp_bm_ctrl ) & ~ SCSI_TERM_ENA_L ) ;
if ( i & 0x04 ) {
j | = SCSI_TERM_ENA_L ;
}
WR_HARPOON ( ioport + hp_bm_ctrl , j ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
j = ( RD_HARPOON ( ioport + hp_ee_ctrl ) & ~ SCSI_TERM_ENA_H ) ;
if ( i & 0x08 ) {
j | = SCSI_TERM_ENA_H ;
}
WR_HARPOON ( ioport + hp_ee_ctrl , j ) ;
if ( ! ( RD_HARPOON ( ioport + hp_page_ctrl ) & NARROW_SCSI_CARD ) )
pCardInfo - > si_flags | = SUPPORT_16TAR_32LUN ;
pCardInfo - > si_card_family = HARPOON_FAMILY ;
pCardInfo - > si_bustype = BUSTYPE_PCI ;
if ( pCurrNvRam ) {
pCardInfo - > si_card_model [ 0 ] = ' 9 ' ;
switch ( pCurrNvRam - > niModel & 0x0f ) {
case MODEL_LT :
pCardInfo - > si_card_model [ 1 ] = ' 3 ' ;
pCardInfo - > si_card_model [ 2 ] = ' 0 ' ;
break ;
case MODEL_LW :
pCardInfo - > si_card_model [ 1 ] = ' 5 ' ;
pCardInfo - > si_card_model [ 2 ] = ' 0 ' ;
break ;
case MODEL_DL :
pCardInfo - > si_card_model [ 1 ] = ' 3 ' ;
pCardInfo - > si_card_model [ 2 ] = ' 2 ' ;
break ;
case MODEL_DW :
pCardInfo - > si_card_model [ 1 ] = ' 5 ' ;
pCardInfo - > si_card_model [ 2 ] = ' 2 ' ;
break ;
}
} else {
temp = FPT_utilEERead ( ioport , ( MODEL_NUMB_0 / 2 ) ) ;
pCardInfo - > si_card_model [ 0 ] = ( unsigned char ) ( temp > > 8 ) ;
temp = FPT_utilEERead ( ioport , ( MODEL_NUMB_2 / 2 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCardInfo - > si_card_model [ 1 ] = ( unsigned char ) ( temp & 0x00FF ) ;
pCardInfo - > si_card_model [ 2 ] = ( unsigned char ) ( temp > > 8 ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCardInfo - > si_card_model [ 1 ] = = ' 3 ' ) {
if ( RD_HARPOON ( ioport + hp_ee_ctrl ) & BIT ( 7 ) )
pCardInfo - > si_flags | = LOW_BYTE_TERM ;
} else if ( pCardInfo - > si_card_model [ 2 ] = = ' 0 ' ) {
temp = RD_HARPOON ( ioport + hp_xfer_pad ) ;
WR_HARPOON ( ioport + hp_xfer_pad , ( temp & ~ BIT ( 4 ) ) ) ;
if ( RD_HARPOON ( ioport + hp_ee_ctrl ) & BIT ( 7 ) )
pCardInfo - > si_flags | = LOW_BYTE_TERM ;
WR_HARPOON ( ioport + hp_xfer_pad , ( temp | BIT ( 4 ) ) ) ;
if ( RD_HARPOON ( ioport + hp_ee_ctrl ) & BIT ( 7 ) )
pCardInfo - > si_flags | = HIGH_BYTE_TERM ;
WR_HARPOON ( ioport + hp_xfer_pad , temp ) ;
} else {
temp = RD_HARPOON ( ioport + hp_ee_ctrl ) ;
temp2 = RD_HARPOON ( ioport + hp_xfer_pad ) ;
WR_HARPOON ( ioport + hp_ee_ctrl , ( temp | SEE_CS ) ) ;
WR_HARPOON ( ioport + hp_xfer_pad , ( temp2 | BIT ( 4 ) ) ) ;
temp3 = 0 ;
for ( i = 0 ; i < 8 ; i + + ) {
temp3 < < = 1 ;
if ( ! ( RD_HARPOON ( ioport + hp_ee_ctrl ) & BIT ( 7 ) ) )
temp3 | = 1 ;
WR_HARPOON ( ioport + hp_xfer_pad , ( temp2 & ~ BIT ( 4 ) ) ) ;
WR_HARPOON ( ioport + hp_xfer_pad , ( temp2 | BIT ( 4 ) ) ) ;
}
WR_HARPOON ( ioport + hp_ee_ctrl , temp ) ;
WR_HARPOON ( ioport + hp_xfer_pad , temp2 ) ;
if ( ! ( temp3 & BIT ( 7 ) ) )
pCardInfo - > si_flags | = LOW_BYTE_TERM ;
if ( ! ( temp3 & BIT ( 6 ) ) )
pCardInfo - > si_flags | = HIGH_BYTE_TERM ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ARAM_ACCESS ( ioport ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
pCardInfo - > si_XlatInfo [ i ] =
RD_HARPOON ( ioport + hp_aramBase + BIOS_DATA_OFFSET + i ) ;
}
2005-04-17 02:20:36 +04:00
/* return with -1 if no sort, else return with
logical card number sorted by BIOS ( zero - based ) */
pCardInfo - > si_relative_cardnum =
2006-03-08 11:14:35 +03:00
( unsigned
char ) ( RD_HARPOON ( ioport + hp_aramBase + BIOS_RELATIVE_CARD ) - 1 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
SGRAM_ACCESS ( ioport ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_s_PhaseTbl [ 0 ] = FPT_phaseDataOut ;
FPT_s_PhaseTbl [ 1 ] = FPT_phaseDataIn ;
FPT_s_PhaseTbl [ 2 ] = FPT_phaseIllegal ;
FPT_s_PhaseTbl [ 3 ] = FPT_phaseIllegal ;
FPT_s_PhaseTbl [ 4 ] = FPT_phaseCommand ;
FPT_s_PhaseTbl [ 5 ] = FPT_phaseStatus ;
FPT_s_PhaseTbl [ 6 ] = FPT_phaseMsgOut ;
FPT_s_PhaseTbl [ 7 ] = FPT_phaseMsgIn ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCardInfo - > si_present = 0x01 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2006-03-08 11:14:23 +03:00
* Function : FlashPoint_HardwareResetHostAdapter
2005-04-17 02:20:36 +04:00
*
* Description : Setup adapter for normal operation ( hard reset ) .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned long FlashPoint_HardwareResetHostAdapter ( struct sccb_mgr_info
* pCardInfo )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb_card * CurrCard = NULL ;
struct nvram_info * pCurrNvRam ;
unsigned char i , j , thisCard , ScamFlg ;
unsigned short temp , sync_bit_map , id ;
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ioport = pCardInfo - > si_baseaddr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( thisCard = 0 ; thisCard < = MAX_CARDS ; thisCard + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( thisCard = = MAX_CARDS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return FAILURE ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ thisCard ] . ioPort = = ioport ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
CurrCard = & FPT_BL_Card [ thisCard ] ;
FPT_SccbMgrTableInitCard ( CurrCard , thisCard ) ;
break ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( FPT_BL_Card [ thisCard ] . ioPort = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ thisCard ] . ioPort = ioport ;
CurrCard = & FPT_BL_Card [ thisCard ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_mbCards )
for ( i = 0 ; i < FPT_mbCards ; i + + ) {
if ( CurrCard - > ioPort = =
FPT_nvRamInfo [ i ] . niBaseAddr )
CurrCard - > pNvRamInfo =
& FPT_nvRamInfo [ i ] ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
FPT_SccbMgrTableInitCard ( CurrCard , thisCard ) ;
CurrCard - > cardIndex = thisCard ;
CurrCard - > cardInfo = pCardInfo ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
break ;
}
}
2005-04-17 02:20:36 +04:00
pCurrNvRam = CurrCard - > pNvRamInfo ;
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
2005-04-17 02:20:36 +04:00
ScamFlg = pCurrNvRam - > niScamConf ;
2006-03-08 11:14:35 +03:00
} else {
ScamFlg =
( unsigned char ) FPT_utilEERead ( ioport , SCAM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
FPT_BusMasterInit ( ioport ) ;
FPT_XbowInit ( ioport , ScamFlg ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_autoLoadDefaultMap ( ioport ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 , id = 0x01 ; i ! = pCardInfo - > si_id ; i + + , id < < = 1 ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ioport + hp_selfid_0 , id ) ;
WR_HARPOON ( ioport + hp_selfid_1 , 0x00 ) ;
WR_HARPOON ( ioport + hp_arb_id , pCardInfo - > si_id ) ;
CurrCard - > ourId = pCardInfo - > si_id ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = ( unsigned char ) pCardInfo - > si_flags ;
if ( i & SCSI_PARITY_ENA )
WR_HARPOON ( ioport + hp_portctrl_1 , ( HOST_MODE8 | CHK_SCSI_P ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
j = ( RD_HARPOON ( ioport + hp_bm_ctrl ) & ~ SCSI_TERM_ENA_L ) ;
if ( i & LOW_BYTE_TERM )
j | = SCSI_TERM_ENA_L ;
WR_HARPOON ( ioport + hp_bm_ctrl , j ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
j = ( RD_HARPOON ( ioport + hp_ee_ctrl ) & ~ SCSI_TERM_ENA_H ) ;
if ( i & HIGH_BYTE_TERM )
j | = SCSI_TERM_ENA_H ;
WR_HARPOON ( ioport + hp_ee_ctrl , j ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( pCardInfo - > si_flags & SOFT_RESET ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sresb ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scini ( thisCard , pCardInfo - > si_id , 0 ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCardInfo - > si_flags & POST_ALL_UNDERRRUNS )
CurrCard - > globalFlags | = F_NO_FILTER ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
if ( pCurrNvRam - > niSysConf & 0x10 )
CurrCard - > globalFlags | = F_GREEN_PC ;
} else {
if ( FPT_utilEERead ( ioport , ( SYSTEM_CONFIG / 2 ) ) & GREEN_PC_ENA )
2005-04-24 11:38:05 +04:00
CurrCard - > globalFlags | = F_GREEN_PC ;
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
/* Set global flag to indicate Re-Negotiation to be done on all
2006-03-08 11:14:35 +03:00
ckeck condition */
if ( pCurrNvRam ) {
if ( pCurrNvRam - > niScsiConf & 0x04 )
CurrCard - > globalFlags | = F_DO_RENEGO ;
} else {
if ( FPT_utilEERead ( ioport , ( SCSI_CONFIG / 2 ) ) & RENEGO_ENA )
2005-04-24 11:38:05 +04:00
CurrCard - > globalFlags | = F_DO_RENEGO ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
if ( pCurrNvRam - > niScsiConf & 0x08 )
CurrCard - > globalFlags | = F_CONLUN_IO ;
} else {
if ( FPT_utilEERead ( ioport , ( SCSI_CONFIG / 2 ) ) & CONNIO_ENA )
2005-04-24 11:38:05 +04:00
CurrCard - > globalFlags | = F_CONLUN_IO ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
temp = pCardInfo - > si_per_targ_no_disc ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 , id = 1 ; i < MAX_SCSI_TAR ; i + + , id < < = 1 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( temp & id )
FPT_sccbMgrTbl [ thisCard ] [ i ] . TarStatus | = TAR_ALLOW_DISC ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_bit_map = 0x0001 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( id = 0 ; id < ( MAX_SCSI_TAR / 2 ) ; id + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
temp = ( unsigned short ) pCurrNvRam - > niSyncTbl [ id ] ;
2005-04-24 11:38:05 +04:00
temp = ( ( temp & 0x03 ) + ( ( temp < < 4 ) & 0xc0 ) ) +
2006-03-08 11:14:35 +03:00
( ( ( temp < < 4 ) & 0x0300 ) + ( ( temp < < 8 ) & 0xc000 ) ) ;
} else
temp =
FPT_utilEERead ( ioport ,
( unsigned short ) ( ( SYNC_RATE_TBL / 2 )
+ id ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < 2 ; temp > > = 8 , i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCardInfo - > si_per_targ_init_sync & sync_bit_map ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ thisCard ] [ id * 2 +
i ] . TarEEValue =
( unsigned char ) temp ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
FPT_sccbMgrTbl [ thisCard ] [ id * 2 +
i ] . TarStatus | =
SYNC_SUPPORTED ;
FPT_sccbMgrTbl [ thisCard ] [ id * 2 +
i ] . TarEEValue =
( unsigned char ) ( temp & ~ EE_SYNC_MASK ) ;
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
( id * 2 + i > = 8 ) ) {
*/
2006-03-08 11:14:35 +03:00
if ( pCardInfo - > si_per_targ_wide_nego & sync_bit_map ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ thisCard ] [ id * 2 +
i ] . TarEEValue | =
EE_WIDE_SCSI ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else { /* NARROW SCSI */
FPT_sccbMgrTbl [ thisCard ] [ id * 2 +
i ] . TarStatus | =
WIDE_NEGOCIATED ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_bit_map < < = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ( ioport + hp_semaphore ) ,
( unsigned char ) ( RD_HARPOON ( ( ioport + hp_semaphore ) ) |
SCCB_MGR_PRESENT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return ( unsigned long ) CurrCard ;
2005-04-24 11:38:05 +04:00
}
2006-03-08 11:14:26 +03:00
static void FlashPoint_ReleaseHostAdapter ( unsigned long pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char i ;
2006-03-08 11:14:26 +03:00
unsigned long portBase ;
unsigned long regOffset ;
unsigned long scamData ;
unsigned long * pScamTbl ;
2006-03-08 11:14:35 +03:00
struct nvram_info * pCurrNvRam ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:34 +03:00
pCurrNvRam = ( ( struct sccb_card * ) pCurrCard ) - > pNvRamInfo ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
2005-04-24 11:38:05 +04:00
FPT_WrStack ( pCurrNvRam - > niBaseAddr , 0 , pCurrNvRam - > niModel ) ;
FPT_WrStack ( pCurrNvRam - > niBaseAddr , 1 , pCurrNvRam - > niSysConf ) ;
FPT_WrStack ( pCurrNvRam - > niBaseAddr , 2 , pCurrNvRam - > niScsiConf ) ;
FPT_WrStack ( pCurrNvRam - > niBaseAddr , 3 , pCurrNvRam - > niScamConf ) ;
FPT_WrStack ( pCurrNvRam - > niBaseAddr , 4 , pCurrNvRam - > niAdapId ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < MAX_SCSI_TAR / 2 ; i + + )
FPT_WrStack ( pCurrNvRam - > niBaseAddr ,
( unsigned char ) ( i + 5 ) ,
pCurrNvRam - > niSyncTbl [ i ] ) ;
2005-04-17 02:20:36 +04:00
portBase = pCurrNvRam - > niBaseAddr ;
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
regOffset = hp_aramBase + 64 + i * 4 ;
pScamTbl = ( unsigned long * ) & pCurrNvRam - > niScamTbl [ i ] ;
2005-04-17 02:20:36 +04:00
scamData = * pScamTbl ;
WR_HARP32 ( portBase , regOffset , scamData ) ;
}
2006-03-08 11:14:35 +03:00
} else {
2006-03-08 11:14:34 +03:00
FPT_WrStack ( ( ( struct sccb_card * ) pCurrCard ) - > ioPort , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
static void FPT_RNVRamData ( struct nvram_info * pNvRamInfo )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char i ;
2006-03-08 11:14:26 +03:00
unsigned long portBase ;
unsigned long regOffset ;
unsigned long scamData ;
unsigned long * pScamTbl ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pNvRamInfo - > niModel = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 0 ) ;
pNvRamInfo - > niSysConf = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 1 ) ;
2005-04-24 11:38:05 +04:00
pNvRamInfo - > niScsiConf = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 2 ) ;
pNvRamInfo - > niScamConf = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 3 ) ;
2006-03-08 11:14:35 +03:00
pNvRamInfo - > niAdapId = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 4 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < MAX_SCSI_TAR / 2 ; i + + )
pNvRamInfo - > niSyncTbl [ i ] =
FPT_RdStack ( pNvRamInfo - > niBaseAddr , ( unsigned char ) ( i + 5 ) ) ;
2005-04-17 02:20:36 +04:00
portBase = pNvRamInfo - > niBaseAddr ;
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
regOffset = hp_aramBase + 64 + i * 4 ;
2005-04-17 02:20:36 +04:00
RD_HARP32 ( portBase , regOffset , scamData ) ;
2006-03-08 11:14:35 +03:00
pScamTbl = ( unsigned long * ) & pNvRamInfo - > niScamTbl [ i ] ;
2005-04-17 02:20:36 +04:00
* pScamTbl = scamData ;
}
}
2006-03-08 11:14:26 +03:00
static unsigned char FPT_RdStack ( unsigned long portBase , unsigned char index )
2005-04-17 02:20:36 +04:00
{
WR_HARPOON ( portBase + hp_stack_addr , index ) ;
2006-03-08 11:14:37 +03:00
return RD_HARPOON ( portBase + hp_stack_data ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
static void FPT_WrStack ( unsigned long portBase , unsigned char index ,
unsigned char data )
2005-04-17 02:20:36 +04:00
{
WR_HARPOON ( portBase + hp_stack_addr , index ) ;
WR_HARPOON ( portBase + hp_stack_data , data ) ;
}
2006-03-08 11:14:26 +03:00
static unsigned char FPT_ChkIfChipInitialized ( unsigned long ioPort )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( ioPort + hp_arb_id ) & 0x0f ) ! = FPT_RdStack ( ioPort , 4 ) )
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( ioPort + hp_clkctrl_0 ) & CLKCTRL_DEFAULT )
! = CLKCTRL_DEFAULT )
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( ioPort + hp_seltimeout ) = = TO_250ms ) | |
( RD_HARPOON ( ioPort + hp_seltimeout ) = = TO_290ms ) )
2006-03-08 11:14:37 +03:00
return 1 ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
2005-04-17 02:20:36 +04:00
/*---------------------------------------------------------------------
*
2006-03-08 11:14:23 +03:00
* Function : FlashPoint_StartCCB
2005-04-17 02:20:36 +04:00
*
* Description : Start a command pointed to by p_Sccb . When the
* command is completed it will be returned via the
* callback function .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FlashPoint_StartCCB ( unsigned long pCurrCard , struct sccb * p_Sccb )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long ioport ;
unsigned char thisCard , lun ;
struct sccb * pSaveSccb ;
CALL_BK_FN callback ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
thisCard = ( ( struct sccb_card * ) pCurrCard ) - > cardIndex ;
ioport = ( ( struct sccb_card * ) pCurrCard ) - > ioPort ;
2005-04-17 02:20:36 +04:00
2008-04-23 13:51:10 +04:00
if ( ( p_Sccb - > TargID > = MAX_SCSI_TAR ) | | ( p_Sccb - > Lun > = MAX_LUN ) ) {
2005-04-17 02:20:36 +04:00
p_Sccb - > HostStatus = SCCB_COMPLETE ;
p_Sccb - > SccbStatus = SCCB_ERROR ;
2006-03-08 11:14:35 +03:00
callback = ( CALL_BK_FN ) p_Sccb - > SccbCallback ;
2005-04-17 02:20:36 +04:00
if ( callback )
callback ( p_Sccb ) ;
return ;
}
2006-03-08 11:14:35 +03:00
FPT_sinits ( p_Sccb , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( ( struct sccb_card * ) pCurrCard ) - > cmdCounter ) {
WR_HARPOON ( ioport + hp_semaphore ,
( RD_HARPOON ( ioport + hp_semaphore )
| SCCB_MGR_ACTIVE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - > globalFlags & F_GREEN_PC ) {
WR_HARPOON ( ioport + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( ioport + hp_sys_ctrl , 0x00 ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
( ( struct sccb_card * ) pCurrCard ) - > cmdCounter + + ;
if ( RD_HARPOON ( ioport + hp_semaphore ) & BIOS_IN_USE ) {
WR_HARPOON ( ioport + hp_semaphore ,
( RD_HARPOON ( ioport + hp_semaphore )
| TICKLE_ME ) ) ;
if ( p_Sccb - > OperationCode = = RESET_COMMAND ) {
pSaveSccb =
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB ;
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB = p_Sccb ;
FPT_queueSelectFail ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB =
pSaveSccb ;
} else {
FPT_queueAddSccb ( p_Sccb , thisCard ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( RD_HARPOON ( ioport + hp_page_ctrl ) & G_INT_DISABLE ) ) {
if ( p_Sccb - > OperationCode = = RESET_COMMAND ) {
pSaveSccb =
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB ;
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB = p_Sccb ;
FPT_queueSelectFail ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB =
pSaveSccb ;
} else {
FPT_queueAddSccb ( p_Sccb , thisCard ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
MDISABLE_INT ( ioport ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( ( struct sccb_card * ) pCurrCard ) - > globalFlags & F_CONLUN_IO )
& &
( ( FPT_sccbMgrTbl [ thisCard ] [ p_Sccb - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) )
2005-04-17 02:20:36 +04:00
lun = p_Sccb - > Lun ;
else
lun = 0 ;
2006-03-08 11:14:35 +03:00
if ( ( ( ( struct sccb_card * ) pCurrCard ) - > currentSCCB = = NULL ) & &
( FPT_sccbMgrTbl [ thisCard ] [ p_Sccb - > TargID ] . TarSelQ_Cnt = = 0 )
& & ( FPT_sccbMgrTbl [ thisCard ] [ p_Sccb - > TargID ] . TarLUNBusy [ lun ]
= = 0 ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB = p_Sccb ;
FPT_ssel ( p_Sccb - > SccbIOPort , thisCard ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
if ( p_Sccb - > OperationCode = = RESET_COMMAND ) {
pSaveSccb =
( ( struct sccb_card * ) pCurrCard ) - >
currentSCCB ;
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB =
p_Sccb ;
FPT_queueSelectFail ( & FPT_BL_Card [ thisCard ] ,
thisCard ) ;
( ( struct sccb_card * ) pCurrCard ) - > currentSCCB =
pSaveSccb ;
} else {
FPT_queueAddSccb ( p_Sccb , thisCard ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
MENABLE_INT ( ioport ) ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2006-03-08 11:14:23 +03:00
* Function : FlashPoint_AbortCCB
2005-04-17 02:20:36 +04:00
*
* Description : Abort the command pointed to by p_Sccb . When the
* command is completed it will be returned via the
* callback function .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static int FlashPoint_AbortCCB ( unsigned long pCurrCard , struct sccb * p_Sccb )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:26 +03:00
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
unsigned char thisCard ;
2005-04-17 02:20:36 +04:00
CALL_BK_FN callback ;
2006-03-08 11:14:24 +03:00
unsigned char TID ;
2006-03-08 11:14:35 +03:00
struct sccb * pSaveSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ioport = ( ( struct sccb_card * ) pCurrCard ) - > ioPort ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:34 +03:00
thisCard = ( ( struct sccb_card * ) pCurrCard ) - > cardIndex ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( RD_HARPOON ( ioport + hp_page_ctrl ) & G_INT_DISABLE ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_queueFindSccb ( p_Sccb , thisCard ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:34 +03:00
( ( struct sccb_card * ) pCurrCard ) - > cmdCounter - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:34 +03:00
if ( ! ( ( struct sccb_card * ) pCurrCard ) - > cmdCounter )
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ioport + hp_semaphore ,
( RD_HARPOON ( ioport + hp_semaphore )
& ( unsigned
char ) ( ~ ( SCCB_MGR_ACTIVE |
TICKLE_ME ) ) ) ) ;
2005-04-17 02:20:36 +04:00
p_Sccb - > SccbStatus = SCCB_ABORT ;
callback = p_Sccb - > SccbCallback ;
callback ( p_Sccb ) ;
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else {
if ( ( ( struct sccb_card * ) pCurrCard ) - > currentSCCB = =
p_Sccb ) {
2005-04-17 02:20:36 +04:00
p_Sccb - > SccbStatus = SCCB_ABORT ;
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
TID = p_Sccb - > TargID ;
2006-03-08 11:14:35 +03:00
if ( p_Sccb - > Sccb_tag ) {
2005-04-17 02:20:36 +04:00
MDISABLE_INT ( ioport ) ;
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - >
discQ_Tbl [ p_Sccb - > Sccb_tag ] = =
p_Sccb ) {
2005-04-17 02:20:36 +04:00
p_Sccb - > SccbStatus = SCCB_ABORT ;
2006-03-08 11:14:35 +03:00
p_Sccb - > Sccb_scsistat =
ABORT_ST ;
p_Sccb - > Sccb_scsimsg =
SMABORT_TAG ;
if ( ( ( struct sccb_card * )
pCurrCard ) - > currentSCCB = =
NULL ) {
( ( struct sccb_card * )
pCurrCard ) - >
currentSCCB = p_Sccb ;
FPT_ssel ( ioport ,
thisCard ) ;
} else {
pSaveSCCB =
( ( struct sccb_card
* ) pCurrCard ) - >
currentSCCB ;
( ( struct sccb_card * )
pCurrCard ) - >
currentSCCB = p_Sccb ;
FPT_queueSelectFail ( ( struct sccb_card * ) pCurrCard , thisCard ) ;
( ( struct sccb_card * )
pCurrCard ) - >
currentSCCB = pSaveSCCB ;
2005-04-17 02:20:36 +04:00
}
}
MENABLE_INT ( ioport ) ;
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
} else {
currTar_Info =
& FPT_sccbMgrTbl [ thisCard ] [ p_Sccb - >
TargID ] ;
if ( FPT_BL_Card [ thisCard ] .
discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ p_Sccb - > Lun ] ]
= = p_Sccb ) {
2005-04-17 02:20:36 +04:00
p_Sccb - > SccbStatus = SCCB_ABORT ;
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
}
}
}
}
2006-03-08 11:14:37 +03:00
return - 1 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2006-03-08 11:14:23 +03:00
* Function : FlashPoint_InterruptPending
2005-04-17 02:20:36 +04:00
*
* Description : Do a quick check to determine if there is a pending
* interrupt for this card and disable the IRQ Pin if so .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static unsigned char FlashPoint_InterruptPending ( unsigned long pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ioport = ( ( struct sccb_card * ) pCurrCard ) - > ioPort ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( ioport + hp_int_status ) & INT_ASSERTED ) {
2006-03-08 11:14:37 +03:00
return 1 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2006-03-08 11:14:23 +03:00
* Function : FlashPoint_HandleInterrupt
2005-04-17 02:20:36 +04:00
*
* Description : This is our entry point when an interrupt is generated
* by the card and the upper level driver passes it on to
* us .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static int FlashPoint_HandleInterrupt ( unsigned long pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
unsigned char thisCard , result , bm_status , bm_int_st ;
unsigned short hp_int ;
unsigned char i , target ;
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
thisCard = ( ( struct sccb_card * ) pCurrCard ) - > cardIndex ;
ioport = ( ( struct sccb_card * ) pCurrCard ) - > ioPort ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
MDISABLE_INT ( ioport ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( bm_int_st = RD_HARPOON ( ioport + hp_int_status ) ) & EXT_STATUS_ON )
bm_status =
RD_HARPOON ( ioport +
hp_ext_status ) & ( unsigned char ) BAD_EXT_STATUS ;
else
bm_status = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ioport + hp_int_mask , ( INT_CMD_COMPL | SCSI_INTERRUPT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( hp_int =
RDW_HARPOON ( ( ioport +
hp_intstat ) ) & FPT_default_intena ) | bm_status ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = ( ( struct sccb_card * ) pCurrCard ) - > currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( hp_int & ( FIFO | TIMEOUT | RESET | SCAM_SEL ) | | bm_status ) {
result =
FPT_SccbMgr_bad_isr ( ioport , thisCard ,
( ( struct sccb_card * ) pCurrCard ) ,
hp_int ) ;
WRW_HARPOON ( ( ioport + hp_intstat ) ,
( FIFO | TIMEOUT | RESET | SCAM_SEL ) ) ;
bm_status = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( result ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
MENABLE_INT ( ioport ) ;
2006-03-08 11:14:37 +03:00
return result ;
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( hp_int & ICMD_COMP ) {
if ( ! ( hp_int & BUS_FREE ) ) {
/* Wait for the BusFree before starting a new command. We
must also check for being reselected since the BusFree
may not show up if another device reselects us in 1.5 us or
less . SRR Wednesday , 3 / 8 / 1995.
*/
while ( !
( RDW_HARPOON ( ( ioport + hp_intstat ) ) &
( BUS_FREE | RSEL ) ) ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - >
globalFlags & F_HOST_XFER_ACT )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_phaseChkFifo ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
/* WRW_HARPOON((ioport+hp_intstat),
( BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0 ) ) ;
*/
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) , CLR_ALL_INT_1 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_autoCmdCmplt ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( hp_int & ITAR_DISC ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - >
globalFlags & F_HOST_XFER_ACT ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_phaseChkFifo ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( ioport + hp_gp_reg_1 ) = = SMSAVE_DATA_PTR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ioport + hp_gp_reg_1 , 0x00 ) ;
currSCCB - > Sccb_XferState | = F_NO_DATA_YET ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_savedATC = currSCCB - > Sccb_ATC ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = DISCONNECT_ST ;
FPT_queueDisconnect ( currSCCB , thisCard ) ;
/* Wait for the BusFree before starting a new command. We
must also check for being reselected since the BusFree
may not show up if another device reselects us in 1.5 us or
less . SRR Wednesday , 3 / 8 / 1995.
*/
while ( !
( RDW_HARPOON ( ( ioport + hp_intstat ) ) &
( BUS_FREE | RSEL ) )
& & ! ( ( RDW_HARPOON ( ( ioport + hp_intstat ) ) & PHASE )
& & RD_HARPOON ( ( ioport + hp_scsisig ) ) = =
( SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
SCSI_IOBIT ) ) ) ;
/*
The additional loop exit condition above detects a timing problem
with the revision D / E harpoon chips . The caller should reset the
host adapter to recover when 0xFE is returned .
*/
if ( !
( RDW_HARPOON ( ( ioport + hp_intstat ) ) &
( BUS_FREE | RSEL ) ) ) {
MENABLE_INT ( ioport ) ;
return 0xFE ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) ,
( BUS_FREE | ITAR_DISC ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
( ( struct sccb_card * ) pCurrCard ) - > globalFlags | =
F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( hp_int & RSEL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) ,
( PROG_HLT | RSEL | PHASE | BUS_FREE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( ioport + hp_intstat ) ) & ITAR_DISC ) {
if ( ( ( struct sccb_card * ) pCurrCard ) - >
globalFlags & F_HOST_XFER_ACT ) {
FPT_phaseChkFifo ( ioport , thisCard ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( ioport + hp_gp_reg_1 ) = =
SMSAVE_DATA_PTR ) {
WR_HARPOON ( ioport + hp_gp_reg_1 , 0x00 ) ;
currSCCB - > Sccb_XferState | =
F_NO_DATA_YET ;
currSCCB - > Sccb_savedATC =
currSCCB - > Sccb_ATC ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) ,
( BUS_FREE | ITAR_DISC ) ) ;
currSCCB - > Sccb_scsistat = DISCONNECT_ST ;
FPT_queueDisconnect ( currSCCB , thisCard ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sres ( ioport , thisCard ,
( ( struct sccb_card * ) pCurrCard ) ) ;
FPT_phaseDecode ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( hp_int & IDO_STRT ) & & ( ! ( hp_int & BUS_FREE ) ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) ,
( IDO_STRT | XFER_CNT_0 ) ) ;
FPT_phaseDecode ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( hp_int & IUNKWN ) | | ( hp_int & PROG_HLT ) ) {
WRW_HARPOON ( ( ioport + hp_intstat ) ,
( PHASE | IUNKWN | PROG_HLT ) ) ;
if ( ( RD_HARPOON ( ioport + hp_prgmcnt_0 ) & ( unsigned char )
0x3f ) < ( unsigned char ) SELCHK ) {
FPT_phaseDecode ( ioport , thisCard ) ;
} else {
/* Harpoon problem some SCSI target device respond to selection
with short BUSY pulse ( < 400 ns ) this will make the Harpoon is not able
to latch the correct Target ID into reg . x53 .
The work around require to correct this reg . But when write to this
reg . ( 0x53 ) also increment the FIFO write addr reg ( 0x6f ) , thus we
need to read this reg first then restore it later . After update to 0x53 */
i = ( unsigned
char ) ( RD_HARPOON ( ioport + hp_fifowrite ) ) ;
target =
( unsigned
char ) ( RD_HARPOON ( ioport + hp_gp_reg_3 ) ) ;
WR_HARPOON ( ioport + hp_xfer_pad ,
( unsigned char ) ID_UNLOCK ) ;
WR_HARPOON ( ioport + hp_select_id ,
( unsigned char ) ( target | target < <
4 ) ) ;
WR_HARPOON ( ioport + hp_xfer_pad ,
( unsigned char ) 0x00 ) ;
WR_HARPOON ( ioport + hp_fifowrite , i ) ;
WR_HARPOON ( ioport + hp_autostart_3 ,
( AUTO_IMMED + TAG_STRT ) ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( hp_int & XFER_CNT_0 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) , XFER_CNT_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_schkdd ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( hp_int & BUS_FREE ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) , BUS_FREE ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - >
globalFlags & F_HOST_XFER_ACT ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( ioport , thisCard ,
currSCCB ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
FPT_phaseBusFree ( ioport , thisCard ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( hp_int & ITICKLE ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( ioport + hp_intstat ) , ITICKLE ) ;
( ( struct sccb_card * ) pCurrCard ) - > globalFlags | =
F_NEW_SCCB_CMD ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - >
globalFlags & F_NEW_SCCB_CMD ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
( ( struct sccb_card * ) pCurrCard ) - > globalFlags & =
~ F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - > currentSCCB = =
NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueSearchSelect ( ( ( struct sccb_card * )
pCurrCard ) , thisCard ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( struct sccb_card * ) pCurrCard ) - > currentSCCB ! =
NULL ) {
( ( struct sccb_card * ) pCurrCard ) - > globalFlags & =
~ F_NEW_SCCB_CMD ;
FPT_ssel ( ioport , thisCard ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
break ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*end while */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
MENABLE_INT ( ioport ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Sccb_bad_isr
*
* Description : Some type of interrupt has occurred which is slightly
* out of the ordinary . We will now decode it fully , in
* this routine . This is broken up in an attempt to save
* processing time .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_SccbMgr_bad_isr ( unsigned long p_port ,
unsigned char p_card ,
struct sccb_card * pCurrCard ,
unsigned short p_int )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char temp , ScamFlg ;
struct sccb_mgr_tar_info * currTar_Info ;
struct nvram_info * pCurrNvRam ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_ext_status ) &
( BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > globalFlags & F_HOST_XFER_ACT ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( p_port , p_card ,
pCurrCard - > currentSCCB ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_pci_stat_cfg ) & REC_MASTER_ABORT )
{
WR_HARPOON ( p_port + hp_pci_stat_cfg ,
( RD_HARPOON ( p_port + hp_pci_stat_cfg ) &
~ REC_MASTER_ABORT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_host_blk_cnt , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > currentSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! pCurrCard - > currentSCCB - > HostStatus )
pCurrCard - > currentSCCB - > HostStatus =
SCCB_BM_ERR ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sxfrp ( p_port , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
temp = ( unsigned char ) ( RD_HARPOON ( p_port + hp_ee_ctrl ) &
( EXT_ARB_ACK | SCSI_TERM_ENA_H ) ) ;
WR_HARPOON ( p_port + hp_ee_ctrl ,
( ( unsigned char ) temp | SEE_MS | SEE_CS ) ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , temp ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( !
( RDW_HARPOON ( ( p_port + hp_intstat ) ) &
( BUS_FREE | RESET ) ) ) {
FPT_phaseDecode ( p_port , p_card ) ;
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( p_int & RESET ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( p_port + hp_sys_ctrl , 0x00 ) ;
if ( pCurrCard - > currentSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > globalFlags & F_HOST_XFER_ACT )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( p_port , p_card ,
pCurrCard - > currentSCCB ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sresb ( p_port , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( RD_HARPOON ( p_port + hp_scsictrl_0 ) & SCSI_RST ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrNvRam = pCurrCard - > pNvRamInfo ;
if ( pCurrNvRam ) {
ScamFlg = pCurrNvRam - > niScamConf ;
} else {
ScamFlg =
( unsigned char ) FPT_utilEERead ( p_port ,
SCAM_CONFIG / 2 ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_XbowInit ( p_port , ScamFlg ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scini ( p_card , pCurrCard - > ourId , 0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0xFF ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( p_int & FIFO ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) , FIFO ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > currentSCCB ! = NULL )
FPT_sxfrp ( p_port , p_card ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( p_int & TIMEOUT ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) ,
( PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
IUNKWN ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > currentSCCB - > HostStatus = SCCB_SELECTION_TIMEOUT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info =
& FPT_sccbMgrTbl [ p_card ] [ pCurrCard - > currentSCCB - > TargID ] ;
if ( ( pCurrCard - > globalFlags & F_CONLUN_IO )
& & ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) )
currTar_Info - > TarLUNBusy [ pCurrCard - > currentSCCB - > Lun ] =
0 ;
2005-04-17 02:20:36 +04:00
else
2006-03-08 11:14:35 +03:00
currTar_Info - > TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) {
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI ) {
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( p_port , pCurrCard - > currentSCCB - > TargID , NARROW_SCSI ,
currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueCmdComplete ( pCurrCard , pCurrCard - > currentSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( p_int & SCAM_SEL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scarb ( p_port , LEVEL2_TAR ) ;
FPT_scsel ( p_port ) ;
FPT_scasid ( p_card , p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scbusf ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) , SCAM_SEL ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0x00 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : SccbMgrTableInit
*
* Description : Initialize all Sccb manager data structures .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2005-04-24 11:38:05 +04:00
static void FPT_SccbMgrTableInitAll ( )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char thisCard ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( thisCard = 0 ; thisCard < MAX_CARDS ; thisCard + + ) {
FPT_SccbMgrTableInitCard ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ thisCard ] . ioPort = 0x00 ;
FPT_BL_Card [ thisCard ] . cardInfo = NULL ;
FPT_BL_Card [ thisCard ] . cardIndex = 0xFF ;
FPT_BL_Card [ thisCard ] . ourId = 0x00 ;
FPT_BL_Card [ thisCard ] . pNvRamInfo = NULL ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : SccbMgrTableInit
*
* Description : Initialize all Sccb manager data structures .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_SccbMgrTableInitCard ( struct sccb_card * pCurrCard ,
unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char scsiID , qtag ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + ) {
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] = NULL ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
for ( scsiID = 0 ; scsiID < MAX_SCSI_TAR ; scsiID + + ) {
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarStatus = 0 ;
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarEEValue = 0 ;
FPT_SccbMgrTableInitTarget ( p_card , scsiID ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > scanIndex = 0x00 ;
pCurrCard - > currentSCCB = NULL ;
pCurrCard - > globalFlags = 0x00 ;
pCurrCard - > cmdCounter = 0x00 ;
2005-04-17 02:20:36 +04:00
pCurrCard - > tagQ_Lst = 0x01 ;
2006-03-08 11:14:35 +03:00
pCurrCard - > discQCount = 0 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : SccbMgrTableInit
*
* Description : Initialize all Sccb manager data structures .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_SccbMgrTableInitTarget ( unsigned char p_card ,
unsigned char target )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char lun , qtag ;
2006-03-08 11:14:35 +03:00
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ target ] ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarSelQ_Cnt = 0 ;
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarSelQ_Head = NULL ;
currTar_Info - > TarSelQ_Tail = NULL ;
currTar_Info - > TarTagQ_Cnt = 0 ;
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUN_CA = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( lun = 0 ; lun < MAX_LUN ; lun + + ) {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 0 ;
2005-04-17 02:20:36 +04:00
currTar_Info - > LunDiscQ_Idx [ lun ] = 0 ;
}
2006-03-08 11:14:35 +03:00
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + ) {
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] ! = NULL ) {
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > TargID = =
target ) {
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] = NULL ;
FPT_BL_Card [ p_card ] . discQCount - - ;
2005-04-17 02:20:36 +04:00
}
}
}
}
/*---------------------------------------------------------------------
*
* Function : sfetm
*
* Description : Read in a message byte from the SCSI bus , and check
* for a parity error .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_sfm ( unsigned long port , struct sccb * pCurrSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char message ;
2006-03-08 11:14:25 +03:00
unsigned short TimeOutLoop ;
2005-04-17 02:20:36 +04:00
TimeOutLoop = 0 ;
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( TimeOutLoop + + < 20000 ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
message = RD_HARPOON ( port + hp_scsidata_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , SCSI_ACK + S_MSGI_PH ) ;
2005-04-17 02:20:36 +04:00
if ( TimeOutLoop > 20000 )
2006-03-08 11:14:35 +03:00
message = 0x00 ; /* force message byte = 0 if Time Out on Req */
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( RD_HARPOON ( port + hp_addstat ) & SCSI_PAR_ERR ) ) {
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
WR_HARPOON ( port + hp_xferstat , 0 ) ;
WR_HARPOON ( port + hp_fiforead , 0 ) ;
WR_HARPOON ( port + hp_fifowrite , 0 ) ;
if ( pCurrSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
pCurrSCCB - > Sccb_scsimsg = SMPARITY ;
}
message = 0x00 ;
2006-03-08 11:14:35 +03:00
do {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG_ATN ( port ) ;
TimeOutLoop = 0 ;
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( TimeOutLoop + + < 20000 ) ) {
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( TimeOutLoop > 20000 ) {
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
2006-03-08 11:14:37 +03:00
return message ;
2006-03-08 11:14:35 +03:00
}
if ( ( RD_HARPOON ( port + hp_scsisig ) & S_SCSI_PHZ ) ! =
S_MSGI_PH ) {
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
2006-03-08 11:14:37 +03:00
return message ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
RD_HARPOON ( port + hp_scsidata_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} while ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
WR_HARPOON ( port + hp_xferstat , 0 ) ;
WR_HARPOON ( port + hp_fiforead , 0 ) ;
WR_HARPOON ( port + hp_fifowrite , 0 ) ;
2006-03-08 11:14:37 +03:00
return message ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_ssel
2005-04-17 02:20:36 +04:00
*
* Description : Load up automation and select target device .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_ssel ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char auto_loaded , i , target , * theCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
unsigned long cdb_reg ;
struct sccb_card * CurrCard ;
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
unsigned char lastTag , lun ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
CurrCard = & FPT_BL_Card [ p_card ] ;
currSCCB = CurrCard - > currentSCCB ;
target = currSCCB - > TargID ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ target ] ;
lastTag = CurrCard - > tagQ_Lst ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ARAM_ACCESS ( port ) ;
2005-04-17 02:20:36 +04:00
if ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) = = TAG_Q_REJECT )
currSCCB - > ControlByte & = ~ F_USE_CMD_Q ;
2006-03-08 11:14:35 +03:00
if ( ( ( CurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
lun = currSCCB - > Lun ;
2005-04-17 02:20:36 +04:00
else
lun = 0 ;
2006-03-08 11:14:35 +03:00
if ( CurrCard - > globalFlags & F_TAG_STARTED ) {
if ( ! ( currSCCB - > ControlByte & F_USE_CMD_Q ) ) {
if ( ( currTar_Info - > TarLUN_CA = = 0 )
& & ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK )
= = TAG_Q_TRYING ) ) {
if ( currTar_Info - > TarTagQ_Cnt ! = 0 ) {
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
FPT_queueSelectFail ( CurrCard , p_card ) ;
SGRAM_ACCESS ( port ) ;
return ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
/*End non-tagged */
else {
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
/*!Use cmd Q Tagged */
else {
if ( currTar_Info - > TarLUN_CA = = 1 ) {
FPT_queueSelectFail ( CurrCard , p_card ) ;
SGRAM_ACCESS ( port ) ;
return ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*else use cmd Q tagged */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
/*if glob tagged started */
else {
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( ( CurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) )
| | ( ! ( currSCCB - > ControlByte & F_USE_CMD_Q ) ) ) ) {
if ( CurrCard - > discQCount > = QUEUE_DEPTH ) {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2006-03-08 11:14:35 +03:00
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
2006-03-08 11:14:35 +03:00
for ( i = 1 ; i < QUEUE_DEPTH ; i + + ) {
if ( + + lastTag > = QUEUE_DEPTH )
lastTag = 1 ;
if ( CurrCard - > discQ_Tbl [ lastTag ] = = NULL ) {
2005-04-17 02:20:36 +04:00
CurrCard - > tagQ_Lst = lastTag ;
currTar_Info - > LunDiscQ_Idx [ lun ] = lastTag ;
CurrCard - > discQ_Tbl [ lastTag ] = currSCCB ;
CurrCard - > discQCount + + ;
break ;
}
}
2006-03-08 11:14:35 +03:00
if ( i = = QUEUE_DEPTH ) {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2006-03-08 11:14:35 +03:00
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
}
2006-03-08 11:14:35 +03:00
auto_loaded = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_select_id , target ) ;
WR_HARPOON ( port + hp_gp_reg_3 , target ) ; /* Use by new automation logic */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > OperationCode = = RESET_COMMAND ) {
WRW_HARPOON ( ( port + ID_MSG_STRT ) , ( MPM_OP + AMSG_OUT +
( currSCCB - >
Sccb_idmsg & ~ DISC_PRIV ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + NP ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsimsg = SMDEV_RESET ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
auto_loaded = 1 ;
currSCCB - > Sccb_scsistat = SELECT_BDR_ST ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) {
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI ) {
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( port , target , NARROW_SCSI , currTar_Info ) ;
FPT_SccbMgrTableInitTarget ( p_card , target ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( currSCCB - > Sccb_scsistat = = ABORT_ST ) {
WRW_HARPOON ( ( port + ID_MSG_STRT ) , ( MPM_OP + AMSG_OUT +
( currSCCB - >
Sccb_idmsg & ~ DISC_PRIV ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + CMDPZ ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 0 ) , ( MPM_OP + AMSG_OUT +
( ( ( unsigned
char ) ( currSCCB - >
ControlByte &
TAG_TYPE_MASK )
> > 6 ) | ( unsigned char )
0x20 ) ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 2 ) ,
( MPM_OP + AMSG_OUT + currSCCB - > Sccb_tag ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 4 ) , ( BRH_OP + ALWAYS + NP ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
auto_loaded = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ! ( currTar_Info - > TarStatus & WIDE_NEGOCIATED ) ) {
auto_loaded = FPT_siwidn ( port , p_card ) ;
currSCCB - > Sccb_scsistat = SELECT_WN_ST ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ! ( ( currTar_Info - > TarStatus & TAR_SYNC_MASK )
= = SYNC_SUPPORTED ) ) {
auto_loaded = FPT_sisyncn ( port , p_card , 0 ) ;
currSCCB - > Sccb_scsistat = SELECT_SN_ST ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! auto_loaded ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > ControlByte & F_USE_CMD_Q ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
CurrCard - > globalFlags | = F_TAG_STARTED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK )
= = TAG_Q_REJECT ) {
currSCCB - > ControlByte & = ~ F_USE_CMD_Q ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/* Fix up the start instruction with a jump to
Non - Tag - CMD handling */
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
BRH_OP + ALWAYS + NTCMD ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + NON_TAG_ID_MSG ) ,
( MPM_OP + AMSG_OUT +
currSCCB - > Sccb_idmsg ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 ,
( SELECT + SELCHK_STRT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/* Setup our STATE so we know what happend when
the wheels fall off . */
currSCCB - > Sccb_scsistat = SELECT_ST ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
( MPM_OP + AMSG_OUT +
currSCCB - > Sccb_idmsg ) ) ;
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) ,
( MPM_OP + AMSG_OUT +
( ( ( unsigned char ) ( currSCCB - >
ControlByte &
TAG_TYPE_MASK )
> > 6 ) | ( unsigned char ) 0x20 ) ) ) ;
for ( i = 1 ; i < QUEUE_DEPTH ; i + + ) {
if ( + + lastTag > = QUEUE_DEPTH )
lastTag = 1 ;
if ( CurrCard - > discQ_Tbl [ lastTag ] = =
NULL ) {
WRW_HARPOON ( ( port +
ID_MSG_STRT + 6 ) ,
( MPM_OP + AMSG_OUT +
lastTag ) ) ;
2005-04-17 02:20:36 +04:00
CurrCard - > tagQ_Lst = lastTag ;
currSCCB - > Sccb_tag = lastTag ;
2006-03-08 11:14:35 +03:00
CurrCard - > discQ_Tbl [ lastTag ] =
currSCCB ;
2005-04-17 02:20:36 +04:00
CurrCard - > discQCount + + ;
break ;
}
}
2006-03-08 11:14:35 +03:00
if ( i = = QUEUE_DEPTH ) {
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
FPT_queueSelectFail ( CurrCard , p_card ) ;
SGRAM_ACCESS ( port ) ;
return ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = SELECT_Q_ST ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 ,
( SELECT + SELCHK_STRT ) ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
BRH_OP + ALWAYS + NTCMD ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + NON_TAG_ID_MSG ) ,
( MPM_OP + AMSG_OUT + currSCCB - > Sccb_idmsg ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = SELECT_ST ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 ,
( SELECT + SELCHK_STRT ) ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
theCCB = ( unsigned char * ) & currSCCB - > Cdb [ 0 ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
cdb_reg = port + CMD_STRT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < currSCCB - > CdbLength ; i + + ) {
WRW_HARPOON ( cdb_reg , ( MPM_OP + ACOMMAND + * theCCB ) ) ;
cdb_reg + = 2 ;
theCCB + + ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > CdbLength ! = TWELVE_BYTE_CMD )
WRW_HARPOON ( cdb_reg , ( BRH_OP + ALWAYS + NP ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
/* auto_loaded */
WRW_HARPOON ( ( port + hp_fiforead ) , ( unsigned short ) 0x00 ) ;
WR_HARPOON ( port + hp_xferstat , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , ( PROG_HLT | TIMEOUT | SEL | BUS_FREE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , ( SCSI_PORT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( currSCCB - > Sccb_MGRFlags & F_DEV_SELECTED ) ) {
WR_HARPOON ( port + hp_scsictrl_0 ,
( SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL ) ) ;
} else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2005-04-17 02:20:36 +04:00
auto_loaded | = AUTO_IMMED ; */
2006-03-08 11:14:35 +03:00
auto_loaded = AUTO_IMMED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 , auto_loaded ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
SGRAM_ACCESS ( port ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sres
2005-04-17 02:20:36 +04:00
*
* Description : Hookup the correct CCB and handle the incoming messages .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_sres ( unsigned long port , unsigned char p_card ,
struct sccb_card * pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char our_target , message , lun = 0 , tag , msgRetryCount ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
struct sccb_mgr_tar_info * currTar_Info ;
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > currentSCCB ! = NULL ) {
currTar_Info =
& FPT_sccbMgrTbl [ p_card ] [ pCurrCard - > currentSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
DISABLE_AUTO ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( ( port + hp_scsictrl_0 ) , ( ENA_RESEL | ENA_SCAM_SEL ) ) ;
2005-04-17 02:20:36 +04:00
currSCCB = pCurrCard - > currentSCCB ;
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) {
2005-04-17 02:20:36 +04:00
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
currSCCB - > Sccb_scsistat = BUS_FREE_ST ;
}
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) {
2005-04-17 02:20:36 +04:00
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
currSCCB - > Sccb_scsistat = BUS_FREE_ST ;
}
2006-03-08 11:14:35 +03:00
if ( ( ( pCurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) ) ) {
currTar_Info - > TarLUNBusy [ currSCCB - > Lun ] = 0 ;
if ( currSCCB - > Sccb_scsistat ! = ABORT_ST ) {
2005-04-17 02:20:36 +04:00
pCurrCard - > discQCount - - ;
2006-03-08 11:14:35 +03:00
pCurrCard - > discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ currSCCB - >
Lun ] ]
= NULL ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
currTar_Info - > TarLUNBusy [ 0 ] = 0 ;
if ( currSCCB - > Sccb_tag ) {
if ( currSCCB - > Sccb_scsistat ! = ABORT_ST ) {
2005-04-17 02:20:36 +04:00
pCurrCard - > discQCount - - ;
2006-03-08 11:14:35 +03:00
pCurrCard - > discQ_Tbl [ currSCCB - >
Sccb_tag ] = NULL ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
if ( currSCCB - > Sccb_scsistat ! = ABORT_ST ) {
2005-04-17 02:20:36 +04:00
pCurrCard - > discQCount - - ;
2006-03-08 11:14:35 +03:00
pCurrCard - > discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ 0 ] ] =
NULL ;
2005-04-17 02:20:36 +04:00
}
}
}
2006-03-08 11:14:35 +03:00
FPT_queueSelectFail ( & FPT_BL_Card [ p_card ] , p_card ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_fiforead ) , ( unsigned short ) 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
our_target = ( unsigned char ) ( RD_HARPOON ( port + hp_select_id ) > > 4 ) ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ our_target ] ;
2005-04-17 02:20:36 +04:00
msgRetryCount = 0 ;
2006-03-08 11:14:35 +03:00
do {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ our_target ] ;
2005-04-17 02:20:36 +04:00
tag = 0 ;
2006-03-08 11:14:35 +03:00
while ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) {
if ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
2005-04-17 02:20:36 +04:00
return ;
}
}
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
if ( ( RD_HARPOON ( port + hp_scsisig ) & S_SCSI_PHZ ) = = S_MSGI_PH ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
message = FPT_sfm ( port , pCurrCard - > currentSCCB ) ;
if ( message ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( message < = ( 0x80 | LUN_MASK ) ) {
2006-03-08 11:14:24 +03:00
lun = message & ( unsigned char ) LUN_MASK ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( currTar_Info - >
TarStatus & TAR_TAG_Q_MASK ) = =
TAG_Q_TRYING ) {
if ( currTar_Info - > TarTagQ_Cnt ! =
0 ) {
if ( !
( currTar_Info - >
TarLUN_CA ) ) {
ACCEPT_MSG ( port ) ; /*Release the ACK for ID msg. */
message =
FPT_sfm
( port ,
pCurrCard - >
currentSCCB ) ;
if ( message ) {
ACCEPT_MSG
( port ) ;
2005-04-17 02:20:36 +04:00
}
else
2006-03-08 11:14:35 +03:00
message
= 0 ;
if ( message ! =
0 ) {
tag =
FPT_sfm
( port ,
pCurrCard - >
currentSCCB ) ;
if ( !
( tag ) )
message
=
0 ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
}
/*C.A. exists! */
}
/*End Q cnt != 0 */
}
/*End Tag cmds supported! */
}
/*End valid ID message. */
else {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG_ATN ( port ) ;
}
2006-03-08 11:14:35 +03:00
}
/* End good id message. */
else {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
message = 0 ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG_ATN ( port ) ;
2006-03-08 11:14:35 +03:00
while ( !
( RDW_HARPOON ( ( port + hp_intstat ) ) &
( PHASE | RESET ) )
& & ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ )
& & ( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2006-03-08 11:14:35 +03:00
if ( message = = 0 ) {
2005-04-17 02:20:36 +04:00
msgRetryCount + + ;
2006-03-08 11:14:35 +03:00
if ( msgRetryCount = = 1 ) {
2005-04-24 11:38:05 +04:00
FPT_SendMsg ( port , SMPARITY ) ;
2006-03-08 11:14:35 +03:00
} else {
2005-04-24 11:38:05 +04:00
FPT_SendMsg ( port , SMDEV_RESET ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( port , our_target , NARROW_SCSI ,
currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_sccbMgrTbl [ p_card ] [ our_target ] .
TarEEValue & EE_SYNC_MASK ) {
FPT_sccbMgrTbl [ p_card ] [ our_target ] .
TarStatus & = ~ TAR_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( FPT_sccbMgrTbl [ p_card ] [ our_target ] .
TarEEValue & EE_WIDE_SCSI ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ our_target ] .
TarStatus & = ~ TAR_WIDE_MASK ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
FPT_queueFlushTargSccb ( p_card , our_target ,
SCCB_COMPLETE ) ;
FPT_SccbMgrTableInitTarget ( p_card , our_target ) ;
2005-04-17 02:20:36 +04:00
return ;
}
}
2006-03-08 11:14:35 +03:00
} while ( message = = 0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( pCurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) ) {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2006-03-08 11:14:35 +03:00
pCurrCard - > currentSCCB =
pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ lun ] ] ;
if ( pCurrCard - > currentSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG_ATN ( port ) ;
}
2006-03-08 11:14:35 +03:00
} else {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( tag ) {
if ( pCurrCard - > discQ_Tbl [ tag ] ! = NULL ) {
pCurrCard - > currentSCCB =
pCurrCard - > discQ_Tbl [ tag ] ;
currTar_Info - > TarTagQ_Cnt - - ;
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
} else {
ACCEPT_MSG_ATN ( port ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
pCurrCard - > currentSCCB =
pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ 0 ] ] ;
if ( pCurrCard - > currentSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG_ATN ( port ) ;
}
}
}
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > currentSCCB ! = NULL ) {
if ( pCurrCard - > currentSCCB - > Sccb_scsistat = = ABORT_ST ) {
/* During Abort Tag command, the target could have got re-selected
and completed the command . Check the select Q and remove the CCB
if it is in the Select Q */
2005-04-24 11:38:05 +04:00
FPT_queueFindSccb ( pCurrCard - > currentSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( PHASE | RESET ) ) & &
! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) & &
( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:26 +03:00
static void FPT_SendMsg ( unsigned long port , unsigned char message )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
while ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) {
if ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
2005-04-17 02:20:36 +04:00
return ;
}
}
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
if ( ( RD_HARPOON ( port + hp_scsisig ) & S_SCSI_PHZ ) = = S_MSGO_PH ) {
WRW_HARPOON ( ( port + hp_intstat ) ,
( BUS_FREE | PHASE | XFER_CNT_0 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_BUS_EN ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsidata_0 , message ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
2005-04-17 02:20:36 +04:00
if ( ( message = = SMABORT ) | | ( message = = SMDEV_RESET ) | |
2006-03-08 11:14:35 +03:00
( message = = SMABORT_TAG ) ) {
while ( !
( RDW_HARPOON ( ( port + hp_intstat ) ) &
( BUS_FREE | PHASE ) ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) {
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
2005-04-17 02:20:36 +04:00
}
}
}
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sdecm
2005-04-17 02:20:36 +04:00
*
* Description : Determine the proper responce to the message from the
* target device .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_sdecm ( unsigned char message , unsigned long port ,
unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
struct sccb_card * CurrCard ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
CurrCard = & FPT_BL_Card [ p_card ] ;
2005-04-17 02:20:36 +04:00
currSCCB = CurrCard - > currentSCCB ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( message = = SMREST_DATA_PTR ) {
if ( ! ( currSCCB - > Sccb_XferState & F_NO_DATA_YET ) ) {
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_ATC = currSCCB - > Sccb_savedATC ;
2005-04-24 11:38:05 +04:00
FPT_hostDataXferRestart ( currSCCB ) ;
2005-04-17 02:20:36 +04:00
}
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else if ( message = = SMCMD_COMP ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_Q_ST ) {
currTar_Info - > TarStatus & =
~ ( unsigned char ) TAR_TAG_Q_MASK ;
2006-03-08 11:14:24 +03:00
currTar_Info - > TarStatus | = ( unsigned char ) TAG_Q_REJECT ;
2005-04-17 02:20:36 +04:00
}
ACCEPT_MSG ( port ) ;
}
2006-03-08 11:14:35 +03:00
else if ( ( message = = SMNO_OP ) | | ( message > = SMIDENT )
| | ( message = = SMINIT_RECOVERY ) | | ( message = = SMREL_RECOVERY ) ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else if ( message = = SMREJECT ) {
2005-04-17 02:20:36 +04:00
if ( ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) | |
2006-03-08 11:14:35 +03:00
( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) | |
( ( currTar_Info - > TarStatus & TAR_SYNC_MASK ) = = SYNC_TRYING )
| | ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) = =
TAG_Q_TRYING ) )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) ) )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Lun = = 0x00 ) {
if ( ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus | =
( unsigned char ) SYNC_SUPPORTED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarEEValue & =
~ EE_SYNC_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( currSCCB - > Sccb_scsistat = =
SELECT_WN_ST ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus =
( currTar_Info - >
TarStatus & ~ WIDE_ENABLED ) |
WIDE_NEGOCIATED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarEEValue & =
~ EE_WIDE_SCSI ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else if ( ( currTar_Info - >
TarStatus & TAR_TAG_Q_MASK ) = =
TAG_Q_TRYING ) {
currTar_Info - > TarStatus =
( currTar_Info - >
TarStatus & ~ ( unsigned char )
TAR_TAG_Q_MASK ) | TAG_Q_REJECT ;
2005-04-17 02:20:36 +04:00
currSCCB - > ControlByte & = ~ F_USE_CMD_Q ;
CurrCard - > discQCount - - ;
2006-03-08 11:14:35 +03:00
CurrCard - > discQ_Tbl [ currSCCB - >
Sccb_tag ] = NULL ;
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_tag = 0x00 ;
}
}
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Lun = = 0x00 ) {
WRW_HARPOON ( ( port + hp_intstat ) ,
BUS_FREE ) ;
2005-04-17 02:20:36 +04:00
CurrCard - > globalFlags | = F_NEW_SCCB_CMD ;
}
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( CurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - >
TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) )
currTar_Info - > TarLUNBusy [ currSCCB - >
Lun ] = 1 ;
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > ControlByte & =
~ ( unsigned char ) F_USE_CMD_Q ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) ) )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
}
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) ) {
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
}
}
2006-03-08 11:14:35 +03:00
else if ( message = = SMEXT ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
FPT_shandem ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else if ( message = = SMIGNORWR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ACCEPT_MSG ( port ) ; /* ACK the RESIDUE MSG */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
message = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsimsg ! = SMPARITY )
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
currSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_shandem
2005-04-17 02:20:36 +04:00
*
* Description : Decide what to do with the extended message .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_shandem ( unsigned long port , unsigned char p_card ,
struct sccb * pCurrSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char length , message ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
length = FPT_sfm ( port , pCurrSCCB ) ;
if ( length ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
message = FPT_sfm ( port , pCurrSCCB ) ;
if ( message ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( message = = SMSYNC ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( length = = 0x03 ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
FPT_stsyncn ( port , p_card ) ;
} else {
2005-04-17 02:20:36 +04:00
pCurrSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
}
2006-03-08 11:14:35 +03:00
} else if ( message = = SMWDTR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( length = = 0x02 ) {
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
FPT_stwidn ( port , p_card ) ;
} else {
2005-04-17 02:20:36 +04:00
pCurrSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED +
DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
pCurrSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
if ( pCurrSCCB - > Sccb_scsimsg ! = SMPARITY )
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
if ( pCurrSCCB - > Sccb_scsimsg = = SMPARITY )
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sisyncn
2005-04-17 02:20:36 +04:00
*
* Description : Read in a message byte from the SCSI bus , and check
* for a parity error .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_sisyncn ( unsigned long port , unsigned char p_card ,
unsigned char syncFlag )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( ( currTar_Info - > TarStatus & TAR_SYNC_MASK ) = = SYNC_TRYING ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
( MPM_OP + AMSG_OUT +
( currSCCB - >
Sccb_idmsg & ~ ( unsigned char ) DISC_PRIV ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + CMDPZ ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 0 ) ,
( MPM_OP + AMSG_OUT + SMEXT ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 2 ) , ( MPM_OP + AMSG_OUT + 0x03 ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 4 ) ,
( MPM_OP + AMSG_OUT + SMSYNC ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_20MB )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) ,
( MPM_OP + AMSG_OUT + 12 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = =
EE_SYNC_10MB )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) ,
( MPM_OP + AMSG_OUT + 25 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = =
EE_SYNC_5MB )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) ,
( MPM_OP + AMSG_OUT + 50 ) ) ;
2005-04-17 02:20:36 +04:00
else
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) ,
( MPM_OP + AMSG_OUT + 00 ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 8 ) , ( RAT_OP ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 10 ) ,
( MPM_OP + AMSG_OUT + DEFAULT_OFFSET ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 12 ) , ( BRH_OP + ALWAYS + NP ) ) ;
if ( syncFlag = = 0 ) {
WR_HARPOON ( port + hp_autostart_3 ,
( SELECT + SELCHK_STRT ) ) ;
currTar_Info - > TarStatus =
( ( currTar_Info - >
TarStatus & ~ ( unsigned char ) TAR_SYNC_MASK ) |
( unsigned char ) SYNC_TRYING ) ;
} else {
WR_HARPOON ( port + hp_autostart_3 ,
( AUTO_IMMED + CMD_ONLY_STRT ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:37 +03:00
return 1 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus | = ( unsigned char ) SYNC_SUPPORTED ;
currTar_Info - > TarEEValue & = ~ EE_SYNC_MASK ;
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_stsyncn
2005-04-17 02:20:36 +04:00
*
* Description : The has sent us a Sync Nego message so handle it as
* necessary .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_stsyncn ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char sync_msg , offset , sync_reg , our_sync_msg ;
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_msg = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( sync_msg = = 0x00 ) & & ( currSCCB - > Sccb_scsimsg = = SMPARITY ) ) {
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2006-03-08 11:14:35 +03:00
ACCEPT_MSG ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
offset = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( offset = = 0x00 ) & & ( currSCCB - > Sccb_scsimsg = = SMPARITY ) ) {
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2006-03-08 11:14:35 +03:00
if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_20MB )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
our_sync_msg = 12 ; /* Setup our Message to 20mb/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_10MB )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
our_sync_msg = 25 ; /* Setup our Message to 10mb/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_5MB )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
our_sync_msg = 50 ; /* Setup our Message to 5mb/s */
else
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
our_sync_msg = 0 ; /* Message = Async */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg < our_sync_msg ) {
sync_msg = our_sync_msg ; /*if faster, then set to max. */
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( offset = = ASYNC )
sync_msg = ASYNC ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( offset > MAX_OFFSET )
offset = MAX_OFFSET ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0x00 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 12 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0x20 ; /* Use 10MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 25 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0x40 ; /* Use 6.6MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 38 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0x60 ; /* Use 5MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 50 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0x80 ; /* Use 4MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 62 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0xA0 ; /* Use 3.33MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 75 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0xC0 ; /* Use 2.85MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 87 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0xE0 ; /* Use 2.5MB/s */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sync_msg > 100 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg = 0x00 ; /* Use ASYNC */
offset = 0x00 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarStatus & WIDE_ENABLED )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg | = offset ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sync_reg | = ( offset | NARROW_SCSI ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( port , currSCCB - > TargID , sync_reg , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ACCEPT_MSG ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
~ ( unsigned char ) TAR_SYNC_MASK ) |
( unsigned char ) SYNC_SUPPORTED ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ACCEPT_MSG_ATN ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sisyncr ( port , sync_msg , offset ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
~ ( unsigned char ) TAR_SYNC_MASK ) |
( unsigned char ) SYNC_SUPPORTED ) ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sisyncr
2005-04-17 02:20:36 +04:00
*
* Description : Answer the targets sync message .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_sisyncr ( unsigned long port , unsigned char sync_pulse ,
unsigned char offset )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
ARAM_ACCESS ( port ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 0 ) , ( MPM_OP + AMSG_OUT + SMEXT ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 2 ) , ( MPM_OP + AMSG_OUT + 0x03 ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 4 ) , ( MPM_OP + AMSG_OUT + SMSYNC ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) , ( MPM_OP + AMSG_OUT + sync_pulse ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 8 ) , ( RAT_OP ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 10 ) , ( MPM_OP + AMSG_OUT + offset ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 12 ) , ( BRH_OP + ALWAYS + NP ) ) ;
SGRAM_ACCESS ( port ) ;
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT_1 ) ;
WR_HARPOON ( port + hp_autostart_3 , ( AUTO_IMMED + CMD_ONLY_STRT ) ) ;
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | AUTO_INT ) ) ) {
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_siwidn
2005-04-17 02:20:36 +04:00
*
* Description : Read in a message byte from the SCSI bus , and check
* for a parity error .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static unsigned char FPT_siwidn ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( ( currTar_Info - > TarStatus & TAR_WIDE_MASK ) = = WIDE_NEGOCIATED ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
( MPM_OP + AMSG_OUT +
( currSCCB - >
Sccb_idmsg & ~ ( unsigned char ) DISC_PRIV ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + CMDPZ ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + SYNC_MSGS + 0 ) ,
( MPM_OP + AMSG_OUT + SMEXT ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 2 ) , ( MPM_OP + AMSG_OUT + 0x02 ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 4 ) ,
( MPM_OP + AMSG_OUT + SMWDTR ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) , ( RAT_OP ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 8 ) ,
( MPM_OP + AMSG_OUT + SM16BIT ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 10 ) , ( BRH_OP + ALWAYS + NP ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
~ ( unsigned char ) TAR_WIDE_MASK ) |
( unsigned char ) WIDE_ENABLED ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 1 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
~ ( unsigned char ) TAR_WIDE_MASK ) |
WIDE_NEGOCIATED ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarEEValue & = ~ EE_WIDE_SCSI ;
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_stwidn
2005-04-17 02:20:36 +04:00
*
* Description : The has sent us a Wide Nego message so handle it as
* necessary .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_stwidn ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char width ;
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
width = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( width = = 0x00 ) & & ( currSCCB - > Sccb_scsimsg = = SMPARITY ) ) {
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2006-03-08 11:14:35 +03:00
if ( ! ( currTar_Info - > TarEEValue & EE_WIDE_SCSI ) )
width = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( width ) {
currTar_Info - > TarStatus | = WIDE_ENABLED ;
width = 0 ;
} else {
width = NARROW_SCSI ;
currTar_Info - > TarStatus & = ~ WIDE_ENABLED ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( port , currSCCB - > TargID , width , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus | = WIDE_NEGOCIATED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( !
( ( currTar_Info - > TarStatus & TAR_SYNC_MASK ) = =
SYNC_SUPPORTED ) ) {
ACCEPT_MSG_ATN ( port ) ;
ARAM_ACCESS ( port ) ;
FPT_sisyncn ( port , p_card , 1 ) ;
currSCCB - > Sccb_scsistat = SELECT_SN_ST ;
SGRAM_ACCESS ( port ) ;
} else {
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ACCEPT_MSG_ATN ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI )
width = SM16BIT ;
else
width = SM8BIT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_siwidr ( port , width ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarStatus | = ( WIDE_NEGOCIATED | WIDE_ENABLED ) ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_siwidr
2005-04-17 02:20:36 +04:00
*
* Description : Answer the targets Wide nego message .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_siwidr ( unsigned long port , unsigned char width )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
ARAM_ACCESS ( port ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 0 ) , ( MPM_OP + AMSG_OUT + SMEXT ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 2 ) , ( MPM_OP + AMSG_OUT + 0x02 ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 4 ) , ( MPM_OP + AMSG_OUT + SMWDTR ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) , ( RAT_OP ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 8 ) , ( MPM_OP + AMSG_OUT + width ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 10 ) , ( BRH_OP + ALWAYS + NP ) ) ;
SGRAM_ACCESS ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT_1 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_3 , ( AUTO_IMMED + CMD_ONLY_STRT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | AUTO_INT ) ) ) {
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sssyncv
2005-04-17 02:20:36 +04:00
*
* Description : Write the desired value to the Sync Register for the
* ID specified .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_sssyncv ( unsigned long p_port , unsigned char p_id ,
unsigned char p_sync_value ,
struct sccb_mgr_tar_info * currTar_Info )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char index ;
index = p_id ;
switch ( index ) {
case 0 :
index = 12 ; /* hp_synctarg_0 */
break ;
case 1 :
index = 13 ; /* hp_synctarg_1 */
break ;
case 2 :
index = 14 ; /* hp_synctarg_2 */
break ;
case 3 :
index = 15 ; /* hp_synctarg_3 */
break ;
case 4 :
index = 8 ; /* hp_synctarg_4 */
break ;
case 5 :
index = 9 ; /* hp_synctarg_5 */
break ;
case 6 :
index = 10 ; /* hp_synctarg_6 */
break ;
case 7 :
index = 11 ; /* hp_synctarg_7 */
break ;
case 8 :
index = 4 ; /* hp_synctarg_8 */
break ;
case 9 :
index = 5 ; /* hp_synctarg_9 */
break ;
case 10 :
index = 6 ; /* hp_synctarg_10 */
break ;
case 11 :
index = 7 ; /* hp_synctarg_11 */
break ;
case 12 :
index = 0 ; /* hp_synctarg_12 */
break ;
case 13 :
index = 1 ; /* hp_synctarg_13 */
break ;
case 14 :
index = 2 ; /* hp_synctarg_14 */
break ;
case 15 :
index = 3 ; /* hp_synctarg_15 */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_synctarg_base + index , p_sync_value ) ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarSyncCtrl = p_sync_value ;
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sresb
2005-04-17 02:20:36 +04:00
*
* Description : Reset the desired card ' s SCSI bus .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_sresb ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char scsiID , i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_page_ctrl ,
( RD_HARPOON ( port + hp_page_ctrl ) | G_INT_DISABLE ) ) ;
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsictrl_0 , SCSI_RST ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
scsiID = RD_HARPOON ( port + hp_seltimeout ) ;
WR_HARPOON ( port + hp_seltimeout , TO_5ms ) ;
WRW_HARPOON ( ( port + hp_intstat ) , TIMEOUT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , ( SCSI_PORT | START_TO ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & TIMEOUT ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_seltimeout , scsiID ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsictrl_0 , ENA_SCAM_SEL ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_Wait ( port , TO_5ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_int_mask , ( RD_HARPOON ( port + hp_int_mask ) | 0x00 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( scsiID = 0 ; scsiID < MAX_SCSI_TAR ; scsiID + + ) {
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ scsiID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) {
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI ) {
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( port , scsiID , NARROW_SCSI , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_SccbMgrTableInitTarget ( p_card , scsiID ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . scanIndex = 0x00 ;
FPT_BL_Card [ p_card ] . currentSCCB = NULL ;
FPT_BL_Card [ p_card ] . globalFlags & = ~ ( F_TAG_STARTED | F_HOST_XFER_ACT
| F_NEW_SCCB_CMD ) ;
FPT_BL_Card [ p_card ] . cmdCounter = 0x00 ;
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQCount = 0x00 ;
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . tagQ_Lst = 0x01 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < QUEUE_DEPTH ; i + + )
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ i ] = NULL ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_page_ctrl ,
( RD_HARPOON ( port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_ssenss
2005-04-17 02:20:36 +04:00
*
* Description : Setup for the Auto Sense command .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_ssenss ( struct sccb_card * pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i ;
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = pCurrCard - > currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Save_CdbLen = currSCCB - > CdbLength ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < 6 ; i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Save_Cdb [ i ] = currSCCB - > Cdb [ i ] ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > CdbLength = SIX_BYTE_CMD ;
currSCCB - > Cdb [ 0 ] = SCSI_REQUEST_SENSE ;
currSCCB - > Cdb [ 1 ] = currSCCB - > Cdb [ 1 ] & ( unsigned char ) 0xE0 ; /*Keep LUN. */
currSCCB - > Cdb [ 2 ] = 0x00 ;
currSCCB - > Cdb [ 3 ] = 0x00 ;
currSCCB - > Cdb [ 4 ] = currSCCB - > RequestSenseLength ;
currSCCB - > Cdb [ 5 ] = 0x00 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferCnt = ( unsigned long ) currSCCB - > RequestSenseLength ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_ATC = 0x00 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferState | = F_AUTO_SENSE ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferState & = ~ F_SG_XFER ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_idmsg = currSCCB - > Sccb_idmsg & ~ ( unsigned char ) DISC_PRIV ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > ControlByte = 0x00 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_MGRFlags & = F_STATUSLOADED ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sxfrp
2005-04-17 02:20:36 +04:00
*
* Description : Transfer data into the bit bucket until the device
* decides to switch phase .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_sxfrp ( unsigned long p_port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char curr_phz ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ p_card ] . globalFlags & F_HOST_XFER_ACT ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( p_port , p_card ,
FPT_BL_Card [ p_card ] . currentSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/* If the Automation handled the end of the transfer then do not
match the phase or we will get out of sync with the ISR . */
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) &
( BUS_FREE | XFER_CNT_0 | AUTO_INT ) )
return ;
WR_HARPOON ( p_port + hp_xfercnt_0 , 0x00 ) ;
curr_phz = RD_HARPOON ( p_port + hp_scsisig ) & ( unsigned char ) S_SCSI_PHZ ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) , XFER_CNT_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , curr_phz ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) & &
( curr_phz = =
( RD_HARPOON ( p_port + hp_scsisig ) & ( unsigned char ) S_SCSI_PHZ ) ) )
{
if ( curr_phz & ( unsigned char ) SCSI_IOBIT ) {
WR_HARPOON ( p_port + hp_portctrl_0 ,
( SCSI_PORT | HOST_PORT | SCSI_INBIT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( RD_HARPOON ( p_port + hp_xferstat ) & FIFO_EMPTY ) ) {
RD_HARPOON ( p_port + hp_fifodata_0 ) ;
}
} else {
WR_HARPOON ( p_port + hp_portctrl_0 ,
( SCSI_PORT | HOST_PORT | HOST_WRT ) ) ;
if ( RD_HARPOON ( p_port + hp_xferstat ) & FIFO_EMPTY ) {
WR_HARPOON ( p_port + hp_fifodata_0 , 0xFA ) ;
}
}
} /* End of While loop for padding data I/O phase */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) ) {
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_REQ )
break ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( SCSI_PORT | HOST_PORT | SCSI_INBIT ) ) ;
while ( ! ( RD_HARPOON ( p_port + hp_xferstat ) & FIFO_EMPTY ) ) {
RD_HARPOON ( p_port + hp_fifodata_0 ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) ) {
WR_HARPOON ( p_port + hp_autostart_0 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & AUTO_INT ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) &
( ICMD_COMP | ITAR_DISC ) )
while ( !
( RDW_HARPOON ( ( p_port + hp_intstat ) ) &
( BUS_FREE | RSEL ) ) ) ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_schkdd
2005-04-17 02:20:36 +04:00
*
* Description : Make sure data has been flushed from both FIFOs and abort
* the operations if necessary .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_schkdd ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned short TimeOutLoop ;
2006-03-08 11:14:24 +03:00
unsigned char sPhase ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( currSCCB - > Sccb_scsistat ! = DATA_OUT_ST ) & &
( currSCCB - > Sccb_scsistat ! = DATA_IN_ST ) ) {
return ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_XferState & F_ODD_BALL_CNT ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_ATC + = ( currSCCB - > Sccb_XferCnt - 1 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferCnt = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferState & = ~ F_ODD_BALL_CNT ;
WRW_HARPOON ( ( port + hp_fiforead ) , ( unsigned short ) 0x00 ) ;
WR_HARPOON ( port + hp_xferstat , 0x00 ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_ATC + = currSCCB - > Sccb_XferCnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferCnt = 0 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > HostStatus = SCCB_PARITY_ERR ;
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( RD_HARPOON ( port + hp_scsisig ) & SCSI_ACK ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
TimeOutLoop = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) {
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) {
return ;
}
if ( RD_HARPOON ( port + hp_offsetctr ) & ( unsigned char ) 0x1F ) {
break ;
}
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & RESET ) {
return ;
}
if ( ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ )
| | ( TimeOutLoop + + > 0x3000 ) )
break ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sPhase = RD_HARPOON ( port + hp_scsisig ) & ( SCSI_BSY | S_SCSI_PHZ ) ;
if ( ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) ) | |
( RD_HARPOON ( port + hp_offsetctr ) & ( unsigned char ) 0x1F ) | |
( sPhase = = ( SCSI_BSY | S_DATAO_PH ) ) | |
( sPhase = = ( SCSI_BSY | S_DATAI_PH ) ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( currSCCB - > Sccb_XferState & F_ALL_XFERRED ) ) {
if ( currSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
FPT_phaseDataIn ( port , p_card ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
FPT_phaseDataOut ( port , p_card ) ;
}
} else {
FPT_sxfrp ( port , p_card ) ;
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) &
( BUS_FREE | ICMD_COMP | ITAR_DISC | RESET ) ) ) {
WRW_HARPOON ( ( port + hp_intstat ) , AUTO_INT ) ;
FPT_phaseDecode ( port , p_card ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sinits
2005-04-17 02:20:36 +04:00
*
* Description : Setup SCCB manager fields in this SCCB .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_sinits ( struct sccb * p_sccb , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2009-12-28 21:08:39 +03:00
if ( ( p_sccb - > TargID > = MAX_SCSI_TAR ) | | ( p_sccb - > Lun > = MAX_LUN ) ) {
2005-04-17 02:20:36 +04:00
return ;
}
2006-03-08 11:14:35 +03:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_sccb - > Sccb_XferState = 0x00 ;
p_sccb - > Sccb_XferCnt = p_sccb - > DataLength ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( p_sccb - > OperationCode = = SCATTER_GATHER_COMMAND ) | |
( p_sccb - > OperationCode = = RESIDUAL_SG_COMMAND ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_sccb - > Sccb_SGoffset = 0 ;
p_sccb - > Sccb_XferState = F_SG_XFER ;
p_sccb - > Sccb_XferCnt = 0x00 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_sccb - > DataLength = = 0x00 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_sccb - > Sccb_XferState | = F_ALL_XFERRED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_sccb - > ControlByte & F_USE_CMD_Q ) {
if ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) = = TAG_Q_REJECT )
p_sccb - > ControlByte & = ~ F_USE_CMD_Q ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
currTar_Info - > TarStatus | = TAG_Q_TRYING ;
}
2005-04-17 02:20:36 +04:00
/* For !single SCSI device in system & device allow Disconnect
or command is tag_q type then send Cmd with Disconnect Enable
else send Cmd with Disconnect Disable */
/*
2005-04-24 11:38:05 +04:00
if ( ( ( ! ( FPT_BL_Card [ p_card ] . globalFlags & F_SINGLE_DEVICE ) ) & &
2005-04-17 02:20:36 +04:00
( currTar_Info - > TarStatus & TAR_ALLOW_DISC ) ) | |
( currTar_Info - > TarStatus & TAG_Q_TRYING ) ) {
*/
2006-03-08 11:14:35 +03:00
if ( ( currTar_Info - > TarStatus & TAR_ALLOW_DISC ) | |
( currTar_Info - > TarStatus & TAG_Q_TRYING ) ) {
p_sccb - > Sccb_idmsg =
( unsigned char ) ( SMIDENT | DISC_PRIV ) | p_sccb - > Lun ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_sccb - > Sccb_idmsg = ( unsigned char ) SMIDENT | p_sccb - > Lun ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_sccb - > HostStatus = 0x00 ;
p_sccb - > TargetStatus = 0x00 ;
p_sccb - > Sccb_tag = 0x00 ;
p_sccb - > Sccb_MGRFlags = 0x00 ;
p_sccb - > Sccb_sgseg = 0x00 ;
p_sccb - > Sccb_ATC = 0x00 ;
p_sccb - > Sccb_savedATC = 0x00 ;
2005-04-17 02:20:36 +04:00
/*
p_sccb - > SccbVirtDataPtr = 0x00 ;
p_sccb - > Sccb_forwardlink = NULL ;
p_sccb - > Sccb_backlink = NULL ;
*/
2006-03-08 11:14:35 +03:00
p_sccb - > Sccb_scsistat = BUS_FREE_ST ;
p_sccb - > SccbStatus = SCCB_IN_PROCESS ;
p_sccb - > Sccb_scsimsg = SMNO_OP ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Phase Decode
*
* Description : Determine the phase and call the appropriate function .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseDecode ( unsigned long p_port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char phase_ref ;
void ( * phase ) ( unsigned long , unsigned char ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
phase_ref =
( unsigned char ) ( RD_HARPOON ( p_port + hp_scsisig ) & S_SCSI_PHZ ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
phase = FPT_s_PhaseTbl [ phase_ref ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
( * phase ) ( p_port , p_card ) ; /* Call the correct phase func */
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Data Out Phase
*
* Description : Start up both the BusMaster and Xbow .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseDataOut ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
if ( currSCCB = = NULL ) {
return ; /* Exit if No SCCB record */
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = DATA_OUT_ST ;
currSCCB - > Sccb_XferState & = ~ ( F_HOST_XFER_DIR | F_NO_DATA_YET ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , XFER_CNT_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_0 , ( END_DATA + END_DATA_START ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_dataXferProcessor ( port , & FPT_BL_Card [ p_card ] ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_XferCnt = = 0 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( currSCCB - > ControlByte & SCCB_DATA_XFER_OUT ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) )
currSCCB - > HostStatus = SCCB_DATA_OVER_RUN ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sxfrp ( port , p_card ) ;
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) )
FPT_phaseDecode ( port , p_card ) ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Data In Phase
*
* Description : Startup the BusMaster and the XBOW .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseDataIn ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB = = NULL ) {
return ; /* Exit if No SCCB record */
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = DATA_IN_ST ;
currSCCB - > Sccb_XferState | = F_HOST_XFER_DIR ;
currSCCB - > Sccb_XferState & = ~ F_NO_DATA_YET ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , XFER_CNT_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_0 , ( END_DATA + END_DATA_START ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_dataXferProcessor ( port , & FPT_BL_Card [ p_card ] ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_XferCnt = = 0 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( currSCCB - > ControlByte & SCCB_DATA_XFER_IN ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) )
currSCCB - > HostStatus = SCCB_DATA_OVER_RUN ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sxfrp ( port , p_card ) ;
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) )
FPT_phaseDecode ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Command Phase
*
* Description : Load the CDB into the automation and start it up .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseCommand ( unsigned long p_port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
unsigned long cdb_reg ;
unsigned char i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > OperationCode = = RESET_COMMAND ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
currSCCB - > CdbLength = SIX_BYTE_CMD ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ARAM_ACCESS ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
cdb_reg = p_port + CMD_STRT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < currSCCB - > CdbLength ; i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > OperationCode = = RESET_COMMAND )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( cdb_reg , ( MPM_OP + ACOMMAND + 0x00 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
WRW_HARPOON ( cdb_reg ,
( MPM_OP + ACOMMAND + currSCCB - > Cdb [ i ] ) ) ;
cdb_reg + = 2 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > CdbLength ! = TWELVE_BYTE_CMD )
WRW_HARPOON ( cdb_reg , ( BRH_OP + ALWAYS + NP ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 , ( SCSI_PORT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = COMMAND_ST ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_autostart_3 , ( AUTO_IMMED | CMD_ONLY_STRT ) ) ;
SGRAM_ACCESS ( p_port ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Status phase
*
* Description : Bring in the status and command complete message bytes
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseStatus ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
/* Start-up the automation to finish off this command and let the
isr handle the interrupt for command complete when it comes in .
We could wait here for the interrupt to be generated ?
*/
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_0 , ( AUTO_IMMED + END_DATA_START ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Phase Message Out
*
* Description : Send out our message ( if we have one ) and handle whatever
* else is involed .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseMsgOut ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char message , scsiID ;
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
if ( currSCCB ! = NULL ) {
message = currSCCB - > Sccb_scsimsg ;
scsiID = currSCCB - > TargID ;
2006-03-08 11:14:35 +03:00
if ( message = = SMDEV_RESET ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ scsiID ] ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarSyncCtrl = 0 ;
2006-03-08 11:14:35 +03:00
FPT_sssyncv ( port , scsiID , NARROW_SCSI , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_sccbMgrTbl [ p_card ] [ scsiID ] .
TarEEValue & EE_SYNC_MASK ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarStatus & =
~ TAR_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( FPT_sccbMgrTbl [ p_card ] [ scsiID ] .
TarEEValue & EE_WIDE_SCSI ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarStatus & =
~ TAR_WIDE_MASK ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
FPT_queueFlushSccb ( p_card , SCCB_COMPLETE ) ;
FPT_SccbMgrTableInitTarget ( p_card , scsiID ) ;
} else if ( currSCCB - > Sccb_scsistat = = ABORT_ST ) {
2005-04-17 02:20:36 +04:00
currSCCB - > HostStatus = SCCB_COMPLETE ;
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - > Sccb_tag ] ! =
NULL ) {
FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - >
Sccb_tag ] = NULL ;
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarTagQ_Cnt - - ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( currSCCB - > Sccb_scsistat < COMMAND_ST ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( message = = SMNO_OP ) {
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_MGRFlags | = F_DEV_SELECTED ;
2006-03-08 11:14:35 +03:00
FPT_ssel ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
if ( message = = SMABORT )
2006-03-08 11:14:35 +03:00
FPT_queueFlushSccb ( p_card , SCCB_COMPLETE ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
message = SMABORT ;
}
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , ( BUS_FREE | PHASE | XFER_CNT_0 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , SCSI_BUS_EN ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsidata_0 , message ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( message = = SMABORT ) | | ( message = = SMDEV_RESET ) | |
( message = = SMABORT_TAG ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | PHASE ) ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) {
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( FPT_BL_Card [ p_card ] .
globalFlags & F_CONLUN_IO )
& &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) )
FPT_sccbMgrTbl [ p_card ] [ currSCCB - >
TargID ] .
TarLUNBusy [ currSCCB - > Lun ] = 0 ;
2005-04-17 02:20:36 +04:00
else
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - >
TargID ] .
TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] ,
currSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else {
FPT_BL_Card [ p_card ] . globalFlags | =
F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sxfrp ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( message = = SMPARITY ) {
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_scsimsg = SMNO_OP ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
} else {
FPT_sxfrp ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
}
/*---------------------------------------------------------------------
*
* Function : Message In phase
*
* Description : Bring in the message and determine what to do with it .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseMsgIn ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char message ;
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ p_card ] . globalFlags & F_HOST_XFER_ACT ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_phaseChkFifo ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
message = RD_HARPOON ( port + hp_scsidata_0 ) ;
if ( ( message = = SMDISC ) | | ( message = = SMSAVE_DATA_PTR ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + END_DATA_START ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
message = FPT_sfm ( port , currSCCB ) ;
if ( message ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sdecm ( message , port , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} else {
if ( currSCCB - > Sccb_scsimsg ! = SMPARITY )
2005-04-17 02:20:36 +04:00
ACCEPT_MSG ( port ) ;
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_autostart_1 ,
( AUTO_IMMED + DISCONNECT_START ) ) ;
2005-04-17 02:20:36 +04:00
}
}
}
/*---------------------------------------------------------------------
*
* Function : Illegal phase
*
* Description : Target switched to some illegal phase , so all we can do
* is report an error back to the host ( if that is possible )
* and send an ABORT message to the misbehaving target .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseIllegal ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , RD_HARPOON ( port + hp_scsisig ) ) ;
if ( currSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
currSCCB - > Sccb_scsistat = ABORT_ST ;
currSCCB - > Sccb_scsimsg = SMABORT ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ACCEPT_MSG_ATN ( port ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Phase Check FIFO
*
* Description : Make sure data has been flushed from both FIFOs and abort
* the operations if necessary .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseChkFifo ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long xfercnt ;
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = DATA_IN_ST ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) ) & &
( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) ) {
currSCCB - > Sccb_ATC + = currSCCB - > Sccb_XferCnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferCnt = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) ) {
currSCCB - > HostStatus = SCCB_PARITY_ERR ;
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_dataXferProcessor ( port , & FPT_BL_Card [ p_card ] ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) )
& & ( RD_HARPOON ( port + hp_ext_status ) &
BM_CMD_BUSY ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/*End Data In specific code. */
GET_XFER_CNT ( port , xfercnt ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_xfercnt_0 , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_ATC + = ( currSCCB - > Sccb_XferCnt - xfercnt ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferCnt = xfercnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > HostStatus = SCCB_PARITY_ERR ;
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_hostDataXferAbort ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_fifowrite , 0x00 ) ;
WR_HARPOON ( port + hp_fiforead , 0x00 ) ;
WR_HARPOON ( port + hp_xferstat , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , XFER_CNT_0 ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Phase Bus Free
*
* Description : We just went bus free so figure out if it was
* because of command complete or from a disconnect .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_phaseBusFree ( unsigned long port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB ! = NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > OperationCode = = RESET_COMMAND ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) )
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ currSCCB - > Lun ] = 0 ;
2005-04-17 02:20:36 +04:00
else
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ 0 ] = 0 ;
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] , currSCCB ,
p_card ) ;
FPT_queueSearchSelect ( & FPT_BL_Card [ p_card ] , p_card ) ;
}
else if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus | =
( unsigned char ) SYNC_SUPPORTED ;
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & =
~ EE_SYNC_MASK ;
}
else if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus =
( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & ~ WIDE_ENABLED ) | WIDE_NEGOCIATED ;
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & =
~ EE_WIDE_SCSI ;
}
else if ( currSCCB - > Sccb_scsistat = = SELECT_Q_ST ) {
/* Make sure this is not a phony BUS_FREE. If we were
reselected or if BUSY is NOT on then this is a
valid BUS FREE . SRR Wednesday , 5 / 10 / 1995. */
if ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) | |
( RDW_HARPOON ( ( port + hp_intstat ) ) & RSEL ) ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & = ~ TAR_TAG_Q_MASK ;
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus | = TAG_Q_REJECT ;
}
else {
return ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_scsistat = BUS_FREE_ST ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! currSCCB - > HostStatus ) {
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) )
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ currSCCB - > Lun ] = 0 ;
else
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] , currSCCB ,
p_card ) ;
return ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . globalFlags | = F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*end if !=null */
}
2005-04-17 02:20:36 +04:00
/*---------------------------------------------------------------------
*
* Function : Auto Load Default Map
*
* Description : Load the Automation RAM with the defualt map values .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_autoLoadDefaultMap ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long map_addr ;
ARAM_ACCESS ( p_port ) ;
map_addr = p_port + hp_aramBase ;
WRW_HARPOON ( map_addr , ( MPM_OP + AMSG_OUT + 0xC0 ) ) ; /*ID MESSAGE */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + AMSG_OUT + 0x20 ) ) ; /*SIMPLE TAG QUEUEING MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , RAT_OP ) ; /*RESET ATTENTION */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + AMSG_OUT + 0x00 ) ) ; /*TAG ID MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 0 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 1 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 2 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 3 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 4 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 5 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 6 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 7 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 8 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 9 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 10 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MPM_OP + ACOMMAND + 0x00 ) ) ; /*CDB BYTE 11 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CPE_OP + ADATA_OUT + DINT ) ) ; /*JUMP IF DATA OUT */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( TCB_OP + FIFO_0 + DI ) ) ; /*JUMP IF NO DATA IN FIFO */
map_addr + = 2 ; /*This means AYNC DATA IN */
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_IDO_STRT ) ) ; /*STOP AND INTERRUPT */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CPE_OP + ADATA_IN + DINT ) ) ; /*JUMP IF NOT DATA IN PHZ */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CPN_OP + AMSG_IN + ST ) ) ; /*IF NOT MSG IN CHECK 4 DATA IN */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CRD_OP + SDATA + 0x02 ) ) ; /*SAVE DATA PTR MSG? */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( BRH_OP + NOT_EQ + DC ) ) ; /*GO CHECK FOR DISCONNECT MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MRR_OP + SDATA + D_AR1 ) ) ; /*SAVE DATA PTRS MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CPN_OP + AMSG_IN + ST ) ) ; /*IF NOT MSG IN CHECK DATA IN */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CRD_OP + SDATA + 0x04 ) ) ; /*DISCONNECT MSG? */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( BRH_OP + NOT_EQ + UNKNWN ) ) ; /*UKNKNOWN MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MRR_OP + SDATA + D_BUCKET ) ) ; /*XFER DISCONNECT MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_ITAR_DISC ) ) ; /*STOP AND INTERRUPT */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CPN_OP + ASTATUS + UNKNWN ) ) ; /*JUMP IF NOT STATUS PHZ. */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MRR_OP + SDATA + D_AR0 ) ) ; /*GET STATUS BYTE */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CPN_OP + AMSG_IN + CC ) ) ; /*ERROR IF NOT MSG IN PHZ */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( CRD_OP + SDATA + 0x00 ) ) ; /*CHECK FOR CMD COMPLETE MSG. */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( BRH_OP + NOT_EQ + CC ) ) ; /*ERROR IF NOT CMD COMPLETE MSG. */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( MRR_OP + SDATA + D_BUCKET ) ) ; /*GET CMD COMPLETE MSG */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_ICMD_COMP ) ) ; /*END OF COMMAND */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_IUNKWN ) ) ; /*RECEIVED UNKNOWN MSG BYTE */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_INO_CC ) ) ; /*NO COMMAND COMPLETE AFTER STATUS */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_ITICKLE ) ) ; /*BIOS Tickled the Mgr */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_IRFAIL ) ) ; /*EXPECTED ID/TAG MESSAGES AND */
map_addr + = 2 ; /* DIDN'T GET ONE */
WRW_HARPOON ( map_addr , ( CRR_OP + AR3 + S_IDREG ) ) ; /* comp SCSI SEL ID & AR3 */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( BRH_OP + EQUAL + 0x00 ) ) ; /*SEL ID OK then Conti. */
map_addr + = 2 ;
WRW_HARPOON ( map_addr , ( SSI_OP + SSI_INO_CC ) ) ; /*NO COMMAND COMPLETE AFTER STATUS */
SGRAM_ACCESS ( p_port ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Auto Command Complete
*
* Description : Post command back to host and find another command
* to execute .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_autoCmdCmplt ( unsigned long p_port , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
unsigned char status_byte ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
status_byte = RD_HARPOON ( p_port + hp_gp_reg_0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUN_CA = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( status_byte ! = SSGOOD ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( status_byte = = SSQ_FULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ currSCCB - > Lun ] = 1 ;
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQCount - - ;
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
LunDiscQ_Idx [ currSCCB - > Lun ] ] =
NULL ;
} else {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ 0 ] = 1 ;
if ( currSCCB - > Sccb_tag ) {
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - >
Sccb_tag ]
= NULL ;
} else {
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
LunDiscQ_Idx [ 0 ] ] = NULL ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_MGRFlags | = F_STATUSLOADED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueSelectFail ( & FPT_BL_Card [ p_card ] , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
return ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus | =
( unsigned char ) SYNC_SUPPORTED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & =
~ EE_SYNC_MASK ;
FPT_BL_Card [ p_card ] . globalFlags | = F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ currSCCB - > Lun ] = 1 ;
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQCount - - ;
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
LunDiscQ_Idx [ currSCCB - > Lun ] ] =
NULL ;
} else {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ 0 ] = 1 ;
if ( currSCCB - > Sccb_tag ) {
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - >
Sccb_tag ]
= NULL ;
} else {
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
LunDiscQ_Idx [ 0 ] ] = NULL ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
return ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus =
( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & ~ WIDE_ENABLED ) | WIDE_NEGOCIATED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & =
~ EE_WIDE_SCSI ;
FPT_BL_Card [ p_card ] . globalFlags | = F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ currSCCB - > Lun ] = 1 ;
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQCount - - ;
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
LunDiscQ_Idx [ currSCCB - > Lun ] ] =
NULL ;
} else {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUNBusy [ 0 ] = 1 ;
if ( currSCCB - > Sccb_tag ) {
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - >
Sccb_tag ]
= NULL ;
} else {
if ( FPT_BL_Card [ p_card ] . discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
LunDiscQ_Idx [ 0 ] ] = NULL ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
return ;
}
if ( status_byte = = SSCHECK ) {
if ( FPT_BL_Card [ p_card ] . globalFlags & F_DO_RENEGO ) {
if ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarEEValue & EE_SYNC_MASK ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - >
TargID ] .
TarStatus & = ~ TAR_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarEEValue & EE_WIDE_SCSI ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - >
TargID ] .
TarStatus & = ~ TAR_WIDE_MASK ;
2005-04-17 02:20:36 +04:00
}
}
}
2006-03-08 11:14:35 +03:00
if ( ! ( currSCCB - > Sccb_XferState & F_AUTO_SENSE ) ) {
currSCCB - > SccbStatus = SCCB_ERROR ;
currSCCB - > TargetStatus = status_byte ;
if ( status_byte = = SSCHECK ) {
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarLUN_CA = 1 ;
if ( currSCCB - > RequestSenseLength ! =
NO_AUTO_REQUEST_SENSE ) {
if ( currSCCB - > RequestSenseLength = = 0 )
currSCCB - > RequestSenseLength =
14 ;
FPT_ssenss ( & FPT_BL_Card [ p_card ] ) ;
FPT_BL_Card [ p_card ] . globalFlags | =
F_NEW_SCCB_CMD ;
if ( ( ( FPT_BL_Card [ p_card ] .
globalFlags & F_CONLUN_IO )
& &
( ( FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) ) ) {
FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
TarLUNBusy [ currSCCB - > Lun ] =
1 ;
if ( FPT_BL_Card [ p_card ] .
discQCount ! = 0 )
FPT_BL_Card [ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] .
discQ_Tbl [ FPT_sccbMgrTbl
[ p_card ]
[ currSCCB - >
TargID ] .
LunDiscQ_Idx
[ currSCCB - > Lun ] ] =
NULL ;
} else {
FPT_sccbMgrTbl [ p_card ]
[ currSCCB - > TargID ] .
TarLUNBusy [ 0 ] = 1 ;
if ( currSCCB - > Sccb_tag ) {
if ( FPT_BL_Card [ p_card ] .
discQCount ! = 0 )
FPT_BL_Card
[ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] .
discQ_Tbl [ currSCCB - >
Sccb_tag ]
= NULL ;
} else {
if ( FPT_BL_Card [ p_card ] .
discQCount ! = 0 )
FPT_BL_Card
[ p_card ] .
discQCount - - ;
FPT_BL_Card [ p_card ] .
discQ_Tbl
[ FPT_sccbMgrTbl
[ p_card ] [ currSCCB - >
TargID ] .
LunDiscQ_Idx [ 0 ] ] =
NULL ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
return ;
}
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) )
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ currSCCB - >
Lun ] = 0 ;
2005-04-17 02:20:36 +04:00
else
2006-03-08 11:14:35 +03:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] , currSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
}
# define SHORT_WAIT 0x0000000F
# define LONG_WAIT 0x0000FFFFL
/*---------------------------------------------------------------------
*
* Function : Data Transfer Processor
*
* Description : This routine performs two tasks .
* ( 1 ) Start data transfer by calling HOST_DATA_XFER_START
* function . Once data transfer is started , ( 2 ) Depends
* on the type of data transfer mode Scatter / Gather mode
* or NON Scatter / Gather mode . In NON Scatter / Gather mode ,
* this routine checks Sccb_MGRFlag ( F_HOST_XFER_ACT bit ) for
* data transfer done . In Scatter / Gather mode , this routine
* checks bus master command complete and dual rank busy
* bit to keep chaining SC transfer command . Similarly ,
* in Scatter / Gather mode , it checks Sccb_MGRFlag
* ( F_HOST_XFER_ACT bit ) for data transfer done .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_dataXferProcessor ( unsigned long port ,
struct sccb_card * pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = pCurrCard - > currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_XferState & F_SG_XFER ) {
if ( pCurrCard - > globalFlags & F_HOST_XFER_ACT )
{
currSCCB - > Sccb_sgseg + = ( unsigned char ) SG_BUF_CNT ;
currSCCB - > Sccb_SGoffset = 0x00 ;
}
pCurrCard - > globalFlags | = F_HOST_XFER_ACT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_busMstrSGDataXferStart ( port , currSCCB ) ;
}
else {
if ( ! ( pCurrCard - > globalFlags & F_HOST_XFER_ACT ) ) {
2005-04-17 02:20:36 +04:00
pCurrCard - > globalFlags | = F_HOST_XFER_ACT ;
2006-03-08 11:14:35 +03:00
FPT_busMstrDataXferStart ( port , currSCCB ) ;
}
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : BusMaster Scatter Gather Data Transfer Start
*
* Description :
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_busMstrSGDataXferStart ( unsigned long p_port ,
struct sccb * pcurrSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long count , addr , tmpSGCnt ;
unsigned int sg_index ;
unsigned char sg_count , i ;
unsigned long reg_offset ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pcurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
count = ( ( unsigned long ) HOST_RD_CMD ) < < 24 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
count = ( ( unsigned long ) HOST_WRT_CMD ) < < 24 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_count = 0 ;
tmpSGCnt = 0 ;
sg_index = pcurrSCCB - > Sccb_sgseg ;
reg_offset = hp_aramBase ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = ( unsigned char ) ( RD_HARPOON ( p_port + hp_page_ctrl ) &
~ ( SGRAM_ARAM | SCATTER_EN ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl , i ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( sg_count < ( unsigned char ) SG_BUF_CNT ) & &
( ( unsigned long ) ( sg_index * ( unsigned int ) SG_ELEMENT_SIZE ) <
pcurrSCCB - > DataLength ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
tmpSGCnt + = * ( ( ( unsigned long * ) pcurrSCCB - > DataPointer ) +
( sg_index * 2 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
count | = * ( ( ( unsigned long * ) pcurrSCCB - > DataPointer ) +
( sg_index * 2 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
addr = * ( ( ( unsigned long * ) pcurrSCCB - > DataPointer ) +
( ( sg_index * 2 ) + 1 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ! sg_count ) & & ( pcurrSCCB - > Sccb_SGoffset ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
addr + =
( ( count & 0x00FFFFFFL ) - pcurrSCCB - > Sccb_SGoffset ) ;
count =
( count & 0xFF000000L ) | pcurrSCCB - > Sccb_SGoffset ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
tmpSGCnt = count & 0x00FFFFFFL ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARP32 ( p_port , reg_offset , addr ) ;
reg_offset + = 4 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARP32 ( p_port , reg_offset , count ) ;
reg_offset + = 4 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
count & = 0xFF000000L ;
sg_index + + ;
sg_count + + ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*End While */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pcurrSCCB - > Sccb_XferCnt = tmpSGCnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_sg_addr , ( sg_count < < 4 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pcurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARP32 ( p_port , hp_xfercnt_0 , tmpSGCnt ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( DMA_PORT | SCSI_PORT | SCSI_INBIT ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAI_PH ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ! ( RD_HARPOON ( p_port + hp_synctarg_0 ) & NARROW_SCSI ) ) & &
( tmpSGCnt & 0x000000001 ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pcurrSCCB - > Sccb_XferState | = F_ODD_BALL_CNT ;
tmpSGCnt - - ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARP32 ( p_port , hp_xfercnt_0 , tmpSGCnt ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( SCSI_PORT | DMA_PORT | DMA_RD ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAO_PH ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl , ( unsigned char ) ( i | SCATTER_EN ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : BusMaster Data Transfer Start
*
* Description :
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_busMstrDataXferStart ( unsigned long p_port ,
struct sccb * pcurrSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long addr , count ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( pcurrSCCB - > Sccb_XferState & F_AUTO_SENSE ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
count = pcurrSCCB - > Sccb_XferCnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
addr =
( unsigned long ) pcurrSCCB - > DataPointer + pcurrSCCB - > Sccb_ATC ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
addr = pcurrSCCB - > SensePointer ;
count = pcurrSCCB - > RequestSenseLength ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
HP_SETUP_ADDR_CNT ( p_port , addr , count ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pcurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( DMA_PORT | SCSI_PORT | SCSI_INBIT ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAI_PH ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_xfer_cmd ,
( XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT ) ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( SCSI_PORT | DMA_PORT | DMA_RD ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAO_PH ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_xfer_cmd ,
( XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : BusMaster Timeout Handler
*
* Description : This function is called after a bus master command busy time
* out is detected . This routines issue halt state machine
* with a software time out for command busy . If command busy
* is still asserted at the end of the time out , it issues
* hard abort with another software time out . It hard abort
* command busy is also time out , it ' ll just give up .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static unsigned char FPT_busMstrTimeOut ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long timeout ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
timeout = LONG_WAIT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_sys_ctrl , HALT_MACH ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( ! ( RD_HARPOON ( p_port + hp_ext_status ) & CMD_ABORTED ) )
& & timeout - - ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_ext_status ) & BM_CMD_BUSY ) {
WR_HARPOON ( p_port + hp_sys_ctrl , HARD_ABORT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
timeout = LONG_WAIT ;
while ( ( RD_HARPOON ( p_port + hp_ext_status ) & BM_CMD_BUSY )
& & timeout - - ) {
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
RD_HARPOON ( p_port + hp_int_status ) ; /*Clear command complete */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_ext_status ) & BM_CMD_BUSY ) {
2006-03-08 11:14:37 +03:00
return 1 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Host Data Transfer Abort
*
* Description : Abort any in progress transfer .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_hostDataXferAbort ( unsigned long port , unsigned char p_card ,
struct sccb * pCurrSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long timeout ;
unsigned long remain_cnt ;
unsigned int sg_ptr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . globalFlags & = ~ F_HOST_XFER_ACT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > Sccb_XferState & F_AUTO_SENSE ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( RD_HARPOON ( port + hp_int_status ) & INT_CMD_COMPL ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_bm_ctrl ,
( RD_HARPOON ( port + hp_bm_ctrl ) |
FLUSH_XFER_CNTR ) ) ;
timeout = LONG_WAIT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY )
& & timeout - - ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_bm_ctrl ,
( RD_HARPOON ( port + hp_bm_ctrl ) &
~ FLUSH_XFER_CNTR ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_busMstrTimeOut ( port ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = = 0x00 )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus =
SCCB_BM_ERR ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_int_status ) &
INT_EXT_STATUS )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) &
BAD_EXT_STATUS )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = =
0x00 )
{
pCurrSCCB - > HostStatus =
SCCB_BM_ERR ;
}
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( pCurrSCCB - > Sccb_XferCnt ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > Sccb_XferState & F_SG_XFER ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_page_ctrl ,
( RD_HARPOON ( port + hp_page_ctrl ) &
~ SCATTER_EN ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_sg_addr , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_ptr = pCurrSCCB - > Sccb_sgseg + SG_BUF_CNT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( sg_ptr >
( unsigned int ) ( pCurrSCCB - > DataLength /
SG_ELEMENT_SIZE ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_ptr =
( unsigned int ) ( pCurrSCCB - > DataLength /
SG_ELEMENT_SIZE ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
remain_cnt = pCurrSCCB - > Sccb_XferCnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( remain_cnt < 0x01000000L ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_ptr - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( remain_cnt >
( unsigned
long ) ( * ( ( ( unsigned long * ) pCurrSCCB - >
DataPointer ) + ( sg_ptr * 2 ) ) ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
remain_cnt - =
( unsigned
long ) ( * ( ( ( unsigned long * )
pCurrSCCB - > DataPointer ) +
( sg_ptr * 2 ) ) ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
break ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( remain_cnt < 0x01000000L ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_SGoffset = remain_cnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_sgseg = ( unsigned short ) sg_ptr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( unsigned long ) ( sg_ptr * SG_ELEMENT_SIZE ) = =
pCurrSCCB - > DataLength & & ( remain_cnt = = 0 ) )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_XferState | =
F_ALL_XFERRED ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus =
SCCB_GROSS_FW_ERR ;
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( pCurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_busMstrTimeOut ( port ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_int_status ) &
INT_EXT_STATUS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) &
BAD_EXT_STATUS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = =
0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus =
SCCB_BM_ERR ;
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( port + hp_fifo_cnt ) ) > = BM_THRESHOLD ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
timeout = SHORT_WAIT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( RD_HARPOON ( port + hp_ext_status ) &
BM_CMD_BUSY )
& & ( ( RD_HARPOON ( port + hp_fifo_cnt ) ) > =
BM_THRESHOLD ) & & timeout - - ) {
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_bm_ctrl ,
( RD_HARPOON ( port + hp_bm_ctrl ) |
FLUSH_XFER_CNTR ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
timeout = LONG_WAIT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( RD_HARPOON ( port + hp_ext_status ) &
BM_CMD_BUSY ) & & timeout - - ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_bm_ctrl ,
( RD_HARPOON ( port + hp_bm_ctrl ) &
~ FLUSH_XFER_CNTR ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) &
BM_CMD_BUSY ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus =
SCCB_BM_ERR ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_busMstrTimeOut ( port ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_int_status ) & INT_EXT_STATUS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) &
BAD_EXT_STATUS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus =
SCCB_BM_ERR ;
}
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
timeout = LONG_WAIT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY )
& & timeout - - ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_busMstrTimeOut ( port ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_int_status ) & INT_EXT_STATUS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( port + hp_ext_status ) & BAD_EXT_STATUS ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrSCCB - > Sccb_XferState & F_SG_XFER ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_page_ctrl ,
( RD_HARPOON ( port + hp_page_ctrl ) &
~ SCATTER_EN ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_sg_addr , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_sgseg + = SG_BUF_CNT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_SGoffset = 0x00 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( unsigned long ) ( pCurrSCCB - > Sccb_sgseg *
SG_ELEMENT_SIZE ) > =
pCurrSCCB - > DataLength ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_XferState | = F_ALL_XFERRED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_sgseg =
( unsigned short ) ( pCurrSCCB - > DataLength /
SG_ELEMENT_SIZE ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( pCurrSCCB - > Sccb_XferState & F_AUTO_SENSE ) )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrSCCB - > Sccb_XferState | = F_ALL_XFERRED ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_int_mask , ( INT_CMD_COMPL | SCSI_INTERRUPT ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Host Data Transfer Restart
*
* Description : Reset the available count due to a restore data
* pointers message .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_hostDataXferRestart ( struct sccb * currSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long data_count ;
unsigned int sg_index ;
unsigned long * sg_ptr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currSCCB - > Sccb_XferState & F_SG_XFER ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_XferCnt = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_index = 0xffff ; /*Index by long words into sg list. */
data_count = 0 ; /*Running count of SG xfer counts. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_ptr = ( unsigned long * ) currSCCB - > DataPointer ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( data_count < currSCCB - > Sccb_ATC ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_index + + ;
data_count + = * ( sg_ptr + ( sg_index * 2 ) ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( data_count = = currSCCB - > Sccb_ATC ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_SGoffset = 0 ;
sg_index + + ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
currSCCB - > Sccb_SGoffset =
data_count - currSCCB - > Sccb_ATC ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB - > Sccb_sgseg = ( unsigned short ) sg_index ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
currSCCB - > Sccb_XferCnt =
currSCCB - > DataLength - currSCCB - > Sccb_ATC ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scini
2005-04-17 02:20:36 +04:00
*
* Description : Setup all data structures necessary for SCAM selection .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_scini ( unsigned char p_card , unsigned char p_our_id ,
unsigned char p_power_up )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char loser , assigned_id ;
unsigned long p_port ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
unsigned char i , k , ScamFlg ;
struct sccb_card * currCard ;
struct nvram_info * pCurrNvRam ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currCard = & FPT_BL_Card [ p_card ] ;
p_port = currCard - > ioPort ;
2005-04-17 02:20:36 +04:00
pCurrNvRam = currCard - > pNvRamInfo ;
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
2005-04-17 02:20:36 +04:00
ScamFlg = pCurrNvRam - > niScamConf ;
i = pCurrNvRam - > niSysConf ;
2006-03-08 11:14:35 +03:00
} else {
ScamFlg =
( unsigned char ) FPT_utilEERead ( p_port , SCAM_CONFIG / 2 ) ;
i = ( unsigned
char ) ( FPT_utilEERead ( p_port , ( SYSTEM_CONFIG / 2 ) ) ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( ! ( i & 0x02 ) ) /* check if reset bus in AutoSCSI parameter set */
2005-04-17 02:20:36 +04:00
return ;
2006-03-08 11:14:35 +03:00
FPT_inisci ( p_card , p_port , p_our_id ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
too slow to return to SCAM selection */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/* if (p_power_up)
FPT_Wait1Second ( p_port ) ;
else
FPT_Wait ( p_port , TO_250ms ) ; */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_Wait1Second ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ScamFlg & SCAM_ENABLED ) & & ( ScamFlg & SCAM_LEVEL2 ) ) {
while ( ! ( FPT_scarb ( p_port , INIT_SELTD ) ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scsel ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
do {
FPT_scxferc ( p_port , SYNC_PTRN ) ;
FPT_scxferc ( p_port , DOM_MSTR ) ;
loser =
FPT_scsendi ( p_port ,
& FPT_scamInfo [ p_our_id ] . id_string [ 0 ] ) ;
} while ( loser = = 0xFF ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scbusf ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( p_power_up ) & & ( ! loser ) ) {
FPT_sresb ( p_port , p_card ) ;
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( FPT_scarb ( p_port , INIT_SELTD ) ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scsel ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
do {
FPT_scxferc ( p_port , SYNC_PTRN ) ;
FPT_scxferc ( p_port , DOM_MSTR ) ;
loser =
FPT_scsendi ( p_port ,
& FPT_scamInfo [ p_our_id ] .
id_string [ 0 ] ) ;
} while ( loser = = 0xFF ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scbusf ( p_port ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
loser = 0 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! loser ) {
FPT_scamInfo [ p_our_id ] . state = ID_ASSIGNED ;
if ( ScamFlg & SCAM_ENABLED ) {
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
if ( ( FPT_scamInfo [ i ] . state = = ID_UNASSIGNED ) | |
( FPT_scamInfo [ i ] . state = = ID_UNUSED ) ) {
if ( FPT_scsell ( p_port , i ) ) {
FPT_scamInfo [ i ] . state = LEGACY ;
if ( ( FPT_scamInfo [ i ] .
id_string [ 0 ] ! = 0xFF )
| | ( FPT_scamInfo [ i ] .
id_string [ 1 ] ! = 0xFA ) ) {
FPT_scamInfo [ i ] .
id_string [ 0 ] = 0xFF ;
FPT_scamInfo [ i ] .
id_string [ 1 ] = 0xFA ;
if ( pCurrNvRam = = NULL )
currCard - >
globalFlags
| =
F_UPDATE_EEPROM ;
}
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_sresb ( p_port , p_card ) ;
FPT_Wait1Second ( p_port ) ;
while ( ! ( FPT_scarb ( p_port , INIT_SELTD ) ) ) {
}
FPT_scsel ( p_port ) ;
FPT_scasid ( p_card , p_port ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( ( loser ) & & ( ScamFlg & SCAM_ENABLED ) ) {
FPT_scamInfo [ p_our_id ] . id_string [ 0 ] = SLV_TYPE_CODE0 ;
assigned_id = 0 ;
FPT_scwtsel ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
do {
while ( FPT_scxferc ( p_port , 0x00 ) ! = SYNC_PTRN ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = FPT_scxferc ( p_port , 0x00 ) ;
if ( i = = ASSIGN_ID ) {
if ( !
( FPT_scsendi
( p_port ,
& FPT_scamInfo [ p_our_id ] . id_string [ 0 ] ) ) ) {
i = FPT_scxferc ( p_port , 0x00 ) ;
if ( FPT_scvalq ( i ) ) {
k = FPT_scxferc ( p_port , 0x00 ) ;
if ( FPT_scvalq ( k ) ) {
currCard - > ourId =
( ( unsigned char ) ( i
< <
3 )
+
( k &
( unsigned char ) 7 ) )
& ( unsigned char )
0x3F ;
FPT_inisci ( p_card ,
p_port ,
p_our_id ) ;
FPT_scamInfo [ currCard - >
ourId ] .
state = ID_ASSIGNED ;
FPT_scamInfo [ currCard - >
ourId ] .
id_string [ 0 ]
= SLV_TYPE_CODE0 ;
assigned_id = 1 ;
}
}
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( i = = SET_P_FLAG ) {
if ( ! ( FPT_scsendi ( p_port ,
& FPT_scamInfo [ p_our_id ] .
id_string [ 0 ] ) ) )
FPT_scamInfo [ p_our_id ] . id_string [ 0 ] | =
0x80 ;
}
} while ( ! assigned_id ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( FPT_scxferc ( p_port , 0x00 ) ! = CFG_CMPLT ) {
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ScamFlg & SCAM_ENABLED ) {
FPT_scbusf ( p_port ) ;
if ( currCard - > globalFlags & F_UPDATE_EEPROM ) {
FPT_scsavdi ( p_card , p_port ) ;
currCard - > globalFlags & = ~ F_UPDATE_EEPROM ;
}
}
2005-04-17 02:20:36 +04:00
/*
for ( i = 0 , k = 0 ; i < MAX_SCSI_TAR ; i + + )
{
2005-04-24 11:38:05 +04:00
if ( ( FPT_scamInfo [ i ] . state = = ID_ASSIGNED ) | |
( FPT_scamInfo [ i ] . state = = LEGACY ) )
2005-04-17 02:20:36 +04:00
k + + ;
}
if ( k = = 2 )
currCard - > globalFlags | = F_SINGLE_DEVICE ;
else
currCard - > globalFlags & = ~ F_SINGLE_DEVICE ;
*/
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scarb
2005-04-17 02:20:36 +04:00
*
* Description : Gain control of the bus and wait SCAM select time ( 250 ms )
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static int FPT_scarb ( unsigned long p_port , unsigned char p_sel_type )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
if ( p_sel_type = = INIT_SELTD ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( RD_HARPOON ( p_port + hp_scsisig ) & ( SCSI_SEL | SCSI_BSY ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_SEL )
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_scsidata_0 ) ! = 00 )
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( RD_HARPOON ( p_port + hp_scsisig ) | SCSI_BSY ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_SEL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( RD_HARPOON ( p_port + hp_scsisig ) &
~ SCSI_BSY ) ) ;
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( RD_HARPOON ( p_port + hp_scsisig ) | SCSI_SEL ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_scsidata_0 ) ! = 00 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( RD_HARPOON ( p_port + hp_scsisig ) &
~ ( SCSI_BSY | SCSI_SEL ) ) ) ;
2006-03-08 11:14:37 +03:00
return 0 ;
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_clkctrl_0 , ( RD_HARPOON ( p_port + hp_clkctrl_0 )
& ~ ACTdeassert ) ) ;
WR_HARPOON ( p_port + hp_scsireset , SCAM_EN ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , 0x00 ) ;
WR_HARPOON ( p_port + hp_scsidata_1 , 0x00 ) ;
WR_HARPOON ( p_port + hp_portctrl_0 , SCSI_BUS_EN ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( RD_HARPOON ( p_port + hp_scsisig ) | SCSI_MSG ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig )
& ~ SCSI_BSY ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 1 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scbusf
2005-04-17 02:20:36 +04:00
*
* Description : Release the SCSI bus and disable SCAM selection .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scbusf ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) | G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 , ( RD_HARPOON ( p_port + hp_portctrl_0 )
& ~ SCSI_BUS_EN ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsireset , ( RD_HARPOON ( p_port + hp_scsireset )
& ~ SCAM_EN ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_clkctrl_0 , ( RD_HARPOON ( p_port + hp_clkctrl_0 )
| ACTdeassert ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) , ( BUS_FREE | AUTO_INT | SCAM_SEL ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scasid
2005-04-17 02:20:36 +04:00
*
* Description : Assign an ID to all the SCAM devices .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scasid ( unsigned char p_card , unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char temp_id_string [ ID_STRING_LENGTH ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
unsigned char i , k , scam_id ;
2006-03-08 11:14:24 +03:00
unsigned char crcBytes [ 3 ] ;
2006-03-08 11:14:35 +03:00
struct nvram_info * pCurrNvRam ;
unsigned short * pCrcBytes ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
pCurrNvRam = FPT_BL_Card [ p_card ] . pNvRamInfo ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! i ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + ) {
temp_id_string [ k ] = ( unsigned char ) 0x00 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scxferc ( p_port , SYNC_PTRN ) ;
FPT_scxferc ( p_port , ASSIGN_ID ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ! ( FPT_sciso ( p_port , & temp_id_string [ 0 ] ) ) ) {
if ( pCurrNvRam ) {
2006-03-08 11:14:27 +03:00
pCrcBytes = ( unsigned short * ) & crcBytes [ 0 ] ;
2005-04-24 11:38:05 +04:00
* pCrcBytes = FPT_CalcCrc16 ( & temp_id_string [ 0 ] ) ;
crcBytes [ 2 ] = FPT_CalcLrc ( & temp_id_string [ 0 ] ) ;
2005-04-17 02:20:36 +04:00
temp_id_string [ 1 ] = crcBytes [ 2 ] ;
temp_id_string [ 2 ] = crcBytes [ 0 ] ;
temp_id_string [ 3 ] = crcBytes [ 1 ] ;
2006-03-08 11:14:35 +03:00
for ( k = 4 ; k < ID_STRING_LENGTH ; k + + )
temp_id_string [ k ] = ( unsigned char ) 0x00 ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
i = FPT_scmachid ( p_card , temp_id_string ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( i = = CLR_PRIORITY ) {
FPT_scxferc ( p_port , MISC_CODE ) ;
FPT_scxferc ( p_port , CLR_P_FLAG ) ;
i = 0 ; /*Not the last ID yet. */
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( i ! = NO_ID_AVAIL ) {
if ( i < 8 )
FPT_scxferc ( p_port , ID_0_7 ) ;
else
FPT_scxferc ( p_port , ID_8_F ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
scam_id = ( i & ( unsigned char ) 0x07 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( k = 1 ; k < 0x08 ; k < < = 1 )
if ( ! ( k & i ) )
scam_id + = 0x08 ; /*Count number of zeros in DB0-3. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scxferc ( p_port , scam_id ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = 0 ; /*Not the last ID yet. */
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
i = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*End while */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scxferc ( p_port , SYNC_PTRN ) ;
FPT_scxferc ( p_port , CFG_CMPLT ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scsel
2005-04-17 02:20:36 +04:00
*
* Description : Select all the SCAM devices .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scsel ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , SCSI_SEL ) ;
FPT_scwiros ( p_port , SCSI_MSG ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , ( SCSI_SEL | SCSI_BSY ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD ) ) ;
WR_HARPOON ( p_port + hp_scsidata_0 ,
( unsigned char ) ( RD_HARPOON ( p_port + hp_scsidata_0 ) |
( unsigned char ) ( BIT ( 7 ) + BIT ( 6 ) ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig , ( SCSI_BSY | SCSI_IOBIT | SCSI_CD ) ) ;
FPT_scwiros ( p_port , SCSI_SEL ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 ,
( unsigned char ) ( RD_HARPOON ( p_port + hp_scsidata_0 ) &
~ ( unsigned char ) BIT ( 6 ) ) ) ;
FPT_scwirod ( p_port , BIT ( 6 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsisig ,
( SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scxferc
2005-04-17 02:20:36 +04:00
*
* Description : Handshake the p_data ( DB4 - 0 ) across the bus .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static unsigned char FPT_scxferc ( unsigned long p_port , unsigned char p_data )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char curr_data , ret_data ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
curr_data = p_data | BIT ( 7 ) | BIT ( 5 ) ; /*Start with DB7 & DB5 asserted. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
curr_data & = ~ BIT ( 7 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scwirod ( p_port , BIT ( 7 ) ) ; /*Wait for DB7 to be released. */
while ( ! ( RD_HARPOON ( p_port + hp_scsidata_0 ) & BIT ( 5 ) ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ret_data = ( RD_HARPOON ( p_port + hp_scsidata_0 ) & ( unsigned char ) 0x1F ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
curr_data | = BIT ( 6 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
curr_data & = ~ BIT ( 5 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scwirod ( p_port , BIT ( 5 ) ) ; /*Wait for DB5 to be released. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
curr_data & = ~ ( BIT ( 4 ) | BIT ( 3 ) | BIT ( 2 ) | BIT ( 1 ) | BIT ( 0 ) ) ; /*Release data bits */
curr_data | = BIT ( 7 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
curr_data & = ~ BIT ( 6 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scwirod ( p_port , BIT ( 6 ) ) ; /*Wait for DB6 to be released. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return ret_data ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scsendi
2005-04-17 02:20:36 +04:00
*
* Description : Transfer our Identification string to determine if we
* will be the dominant master .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_scsendi ( unsigned long p_port ,
unsigned char p_id_string [ ] )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char ret_data , byte_cnt , bit_cnt , defer ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
defer = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( byte_cnt = 0 ; byte_cnt < ID_STRING_LENGTH ; byte_cnt + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( bit_cnt = 0x80 ; bit_cnt ! = 0 ; bit_cnt > > = 1 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( defer )
ret_data = FPT_scxferc ( p_port , 00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( p_id_string [ byte_cnt ] & bit_cnt )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ret_data = FPT_scxferc ( p_port , 02 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ret_data = FPT_scxferc ( p_port , 01 ) ;
if ( ret_data & 02 )
defer = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ret_data & 0x1C ) = = 0x10 )
2006-03-08 11:14:37 +03:00
return 0x00 ; /*End of isolation stage, we won! */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ret_data & 0x1C )
2006-03-08 11:14:37 +03:00
return 0xFF ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( defer ) & & ( ! ( ret_data & 0x1F ) ) )
2006-03-08 11:14:37 +03:00
return 0x01 ; /*End of isolation stage, we lost. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*bit loop */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*byte loop */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( defer )
2006-03-08 11:14:37 +03:00
return 0x01 ; /*We lost */
2006-03-08 11:14:35 +03:00
else
2006-03-08 11:14:37 +03:00
return 0 ; /*We WON! Yeeessss! */
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_sciso
2005-04-17 02:20:36 +04:00
*
* Description : Transfer the Identification string .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_sciso ( unsigned long p_port ,
unsigned char p_id_string [ ] )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char ret_data , the_data , byte_cnt , bit_cnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
the_data = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( byte_cnt = 0 ; byte_cnt < ID_STRING_LENGTH ; byte_cnt + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( bit_cnt = 0 ; bit_cnt < 8 ; bit_cnt + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ret_data = FPT_scxferc ( p_port , 0 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ret_data & 0xFC )
2006-03-08 11:14:37 +03:00
return 0xFF ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
the_data < < = 1 ;
if ( ret_data & BIT ( 1 ) ) {
the_data | = 1 ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ret_data & 0x1F ) = = 0 ) {
2005-04-17 02:20:36 +04:00
/*
if ( bit_cnt ! = 0 | | bit_cnt ! = 8 )
{
byte_cnt = 0 ;
bit_cnt = 0 ;
2005-04-24 11:38:05 +04:00
FPT_scxferc ( p_port , SYNC_PTRN ) ;
FPT_scxferc ( p_port , ASSIGN_ID ) ;
2005-04-17 02:20:36 +04:00
continue ;
}
*/
2006-03-08 11:14:35 +03:00
if ( byte_cnt )
2006-03-08 11:14:37 +03:00
return 0x00 ;
2006-03-08 11:14:35 +03:00
else
2006-03-08 11:14:37 +03:00
return 0xFF ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*bit loop */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_id_string [ byte_cnt ] = the_data ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
} /*byte loop */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scwirod
2005-04-17 02:20:36 +04:00
*
* Description : Sample the SCSI data bus making sure the signal has been
* deasserted for the correct number of consecutive samples .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scwirod ( unsigned long p_port , unsigned char p_data_bit )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = 0 ;
while ( i < MAX_SCSI_TAR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_scsidata_0 ) & p_data_bit )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i + + ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scwiros
2005-04-17 02:20:36 +04:00
*
* Description : Sample the SCSI Signal lines making sure the signal has been
* deasserted for the correct number of consecutive samples .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scwiros ( unsigned long p_port , unsigned char p_data_bit )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = 0 ;
while ( i < MAX_SCSI_TAR ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_scsisig ) & p_data_bit )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i + + ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-24 11:38:05 +04:00
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
/*---------------------------------------------------------------------
*
* Function : FPT_scvalq
*
* Description : Make sure we received a valid data byte .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
static unsigned char FPT_scvalq ( unsigned char p_quintet )
2005-04-24 11:38:05 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char count ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( count = 1 ; count < 0x08 ; count < < = 1 ) {
if ( ! ( p_quintet & count ) )
p_quintet - = 0x80 ;
}
2005-04-24 11:38:05 +04:00
2006-03-08 11:14:35 +03:00
if ( p_quintet & 0x18 )
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-24 11:38:05 +04:00
2006-03-08 11:14:35 +03:00
else
2006-03-08 11:14:37 +03:00
return 1 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scsell
2005-04-17 02:20:36 +04:00
*
* Description : Select the specified device ID using a selection timeout
2005-04-24 11:38:05 +04:00
* less than 4 ms . If somebody responds then it is a legacy
* drive and this ID must be marked as such .
2005-04-17 02:20:36 +04:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static unsigned char FPT_scsell ( unsigned long p_port , unsigned char targ_id )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) | G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ARAM_ACCESS ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_addstat ,
( RD_HARPOON ( p_port + hp_addstat ) | SCAM_TIMER ) ) ;
WR_HARPOON ( p_port + hp_seltimeout , TO_4ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = p_port + CMD_STRT ; i < p_port + CMD_STRT + 12 ; i + = 2 ) {
WRW_HARPOON ( i , ( MPM_OP + ACOMMAND ) ) ;
}
WRW_HARPOON ( i , ( BRH_OP + ALWAYS + NP ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) ,
( RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_select_id , targ_id ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 , SCSI_PORT ) ;
WR_HARPOON ( p_port + hp_autostart_3 , ( SELECT | CMD_ONLY_STRT ) ) ;
WR_HARPOON ( p_port + hp_scsictrl_0 , ( SEL_TAR | ENA_RESEL ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) &
( RESET | PROG_HLT | TIMEOUT | AUTO_INT ) ) ) {
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & RESET )
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
DISABLE_AUTO ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_addstat ,
( RD_HARPOON ( p_port + hp_addstat ) & ~ SCAM_TIMER ) ) ;
WR_HARPOON ( p_port + hp_seltimeout , TO_290ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
SGRAM_ACCESS ( p_port ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( RESET | TIMEOUT ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) ,
( RESET | TIMEOUT | SEL | BUS_FREE | PHASE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) &
~ G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0 ; /*No legacy device */
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & BUS_FREE ) ) {
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_REQ ) {
WR_HARPOON ( p_port + hp_scsisig ,
( SCSI_ACK + S_ILL_PH ) ) ;
ACCEPT_MSG ( p_port ) ;
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) , CLR_ALL_INT_1 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) &
~ G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 1 ; /*Found one of them oldies! */
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scwtsel
2005-04-17 02:20:36 +04:00
*
* Description : Wait to be selected by another SCAM initiator .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scwtsel ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & SCAM_SEL ) ) {
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_inisci
2005-04-17 02:20:36 +04:00
*
* Description : Setup the data Structure with the info from the EEPROM .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_inisci ( unsigned char p_card , unsigned long p_port ,
unsigned char p_our_id )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i , k , max_id ;
unsigned short ee_data ;
struct nvram_info * pCurrNvRam ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
pCurrNvRam = FPT_BL_Card [ p_card ] . pNvRamInfo ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_page_ctrl ) & NARROW_SCSI_CARD )
max_id = 0x08 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
max_id = 0x10 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrNvRam ) {
for ( i = 0 ; i < max_id ; i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( k = 0 ; k < 4 ; k + + )
FPT_scamInfo [ i ] . id_string [ k ] =
pCurrNvRam - > niScamTbl [ i ] [ k ] ;
for ( k = 4 ; k < ID_STRING_LENGTH ; k + + )
FPT_scamInfo [ i ] . id_string [ k ] =
( unsigned char ) 0x00 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_scamInfo [ i ] . id_string [ 0 ] = = 0x00 )
FPT_scamInfo [ i ] . state = ID_UNUSED ; /*Default to unused ID. */
else
FPT_scamInfo [ i ] . state = ID_UNASSIGNED ; /*Default to unassigned ID. */
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
} else {
for ( i = 0 ; i < max_id ; i + + ) {
for ( k = 0 ; k < ID_STRING_LENGTH ; k + = 2 ) {
ee_data =
FPT_utilEERead ( p_port ,
( unsigned
short ) ( ( EE_SCAMBASE / 2 ) +
( unsigned short ) ( i *
( ( unsigned short ) ID_STRING_LENGTH / 2 ) ) + ( unsigned short ) ( k / 2 ) ) ) ;
FPT_scamInfo [ i ] . id_string [ k ] =
( unsigned char ) ee_data ;
ee_data > > = 8 ;
FPT_scamInfo [ i ] . id_string [ k + 1 ] =
( unsigned char ) ee_data ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( FPT_scamInfo [ i ] . id_string [ 0 ] = = 0x00 ) | |
( FPT_scamInfo [ i ] . id_string [ 0 ] = = 0xFF ) )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scamInfo [ i ] . state = ID_UNUSED ; /*Default to unused ID. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
FPT_scamInfo [ i ] . state = ID_UNASSIGNED ; /*Default to unassigned ID. */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + )
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ p_our_id ] . id_string [ k ] = FPT_scamHAString [ k ] ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scmachid
2005-04-17 02:20:36 +04:00
*
* Description : Match the Device ID string with our values stored in
* the EEPROM .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_scmachid ( unsigned char p_card ,
unsigned char p_id_string [ ] )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i , k , match ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
match = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + ) {
if ( p_id_string [ k ] ! = FPT_scamInfo [ i ] . id_string [ k ] )
match = 0 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( match ) {
FPT_scamInfo [ i ] . state = ID_ASSIGNED ;
2006-03-08 11:14:37 +03:00
return i ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_id_string [ 0 ] & BIT ( 5 ) )
i = 8 ;
else
i = MAX_SCSI_TAR ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( p_id_string [ 0 ] & 0x06 ) = = 0x02 )
| | ( ( p_id_string [ 0 ] & 0x06 ) = = 0x04 ) )
match = p_id_string [ 1 ] & ( unsigned char ) 0x1F ;
else
match = 7 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( i > 0 ) {
i - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_scamInfo [ match ] . state = = ID_UNUSED ) {
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + ) {
FPT_scamInfo [ match ] . id_string [ k ] =
p_id_string [ k ] ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scamInfo [ match ] . state = ID_ASSIGNED ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ p_card ] . pNvRamInfo = = NULL )
FPT_BL_Card [ p_card ] . globalFlags | =
F_UPDATE_EEPROM ;
2006-03-08 11:14:37 +03:00
return match ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
match - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( match = = 0xFF ) {
if ( p_id_string [ 0 ] & BIT ( 5 ) )
match = 7 ;
else
match = MAX_SCSI_TAR - 1 ;
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( p_id_string [ 0 ] & BIT ( 7 ) ) {
2006-03-08 11:14:37 +03:00
return CLR_PRIORITY ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_id_string [ 0 ] & BIT ( 5 ) )
i = 8 ;
else
i = MAX_SCSI_TAR ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( p_id_string [ 0 ] & 0x06 ) = = 0x02 )
| | ( ( p_id_string [ 0 ] & 0x06 ) = = 0x04 ) )
match = p_id_string [ 1 ] & ( unsigned char ) 0x1F ;
else
match = 7 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( i > 0 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_scamInfo [ match ] . state = = ID_UNASSIGNED ) {
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + ) {
FPT_scamInfo [ match ] . id_string [ k ] =
p_id_string [ k ] ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_scamInfo [ match ] . id_string [ 0 ] | = BIT ( 7 ) ;
FPT_scamInfo [ match ] . state = ID_ASSIGNED ;
if ( FPT_BL_Card [ p_card ] . pNvRamInfo = = NULL )
FPT_BL_Card [ p_card ] . globalFlags | =
F_UPDATE_EEPROM ;
2006-03-08 11:14:37 +03:00
return match ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
match - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( match = = 0xFF ) {
if ( p_id_string [ 0 ] & BIT ( 5 ) )
match = 7 ;
else
match = MAX_SCSI_TAR - 1 ;
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:37 +03:00
return NO_ID_AVAIL ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_scsavdi
2005-04-17 02:20:36 +04:00
*
* Description : Save off the device SCAM ID strings .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_scsavdi ( unsigned char p_card , unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i , k , max_id ;
unsigned short ee_data , sum_data ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sum_data = 0x0000 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 1 ; i < EE_SCAMBASE / 2 ; i + + ) {
sum_data + = FPT_utilEERead ( p_port , i ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEEWriteOnOff ( p_port , 1 ) ; /* Enable write access to the EEPROM */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_page_ctrl ) & NARROW_SCSI_CARD )
max_id = 0x08 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
max_id = 0x10 ;
for ( i = 0 ; i < max_id ; i + + ) {
for ( k = 0 ; k < ID_STRING_LENGTH ; k + = 2 ) {
ee_data = FPT_scamInfo [ i ] . id_string [ k + 1 ] ;
ee_data < < = 8 ;
ee_data | = FPT_scamInfo [ i ] . id_string [ k ] ;
sum_data + = ee_data ;
FPT_utilEEWrite ( p_port , ee_data ,
( unsigned short ) ( ( EE_SCAMBASE / 2 ) +
( unsigned short ) ( i *
( ( unsigned short ) ID_STRING_LENGTH / 2 ) ) + ( unsigned short ) ( k / 2 ) ) ) ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEEWrite ( p_port , sum_data , EEPROM_CHECK_SUM / 2 ) ;
FPT_utilEEWriteOnOff ( p_port , 0 ) ; /* Turn off write access */
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_XbowInit
2005-04-17 02:20:36 +04:00
*
* Description : Setup the Xbow for normal operation .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_XbowInit ( unsigned long port , unsigned char ScamFlg )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
i = RD_HARPOON ( port + hp_page_ctrl ) ;
WR_HARPOON ( port + hp_page_ctrl , ( unsigned char ) ( i | G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsireset , 0x00 ) ;
WR_HARPOON ( port + hp_portctrl_1 , HOST_MODE8 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsireset , ( DMA_RESET | HPSCSI_RESET | PROG_RESET |
FIFO_CLR ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsireset , SCSI_INI ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_scsisig , 0x00 ) ; /* Clear any signals we might */
WR_HARPOON ( port + hp_scsictrl_0 , ENA_SCAM_SEL ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
BUS_FREE | XFER_CNT_0 | AUTO_INT ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ScamFlg & SCAM_ENABLED ) & & ( ScamFlg & SCAM_LEVEL2 ) )
2005-04-24 11:38:05 +04:00
FPT_default_intena | = SCAM_SEL ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( port + hp_intena ) , FPT_default_intena ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_seltimeout , TO_290ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
/* Turn on SCSI_MODE8 for narrow cards to fix the
strapping issue with the DUAL CHANNEL card */
if ( RD_HARPOON ( port + hp_page_ctrl ) & NARROW_SCSI_CARD )
WR_HARPOON ( port + hp_addstat , SCSI_MODE8 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( port + hp_page_ctrl , i ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_BusMasterInit
2005-04-17 02:20:36 +04:00
*
* Description : Initialize the BusMaster for normal operations .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_BusMasterInit ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_sys_ctrl , DRVR_RST ) ;
WR_HARPOON ( p_port + hp_sys_ctrl , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_host_blk_cnt , XFER_BLK64 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_bm_ctrl , ( BMCTRL_DEFAULT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_ee_ctrl , ( SCSI_TERM_ENA_H ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
RD_HARPOON ( p_port + hp_int_status ) ; /*Clear interrupts. */
WR_HARPOON ( p_port + hp_int_mask , ( INT_CMD_COMPL | SCSI_INTERRUPT ) ) ;
WR_HARPOON ( p_port + hp_page_ctrl , ( RD_HARPOON ( p_port + hp_page_ctrl ) &
~ SCATTER_EN ) ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_DiagEEPROM
2005-04-17 02:20:36 +04:00
*
* Description : Verfiy checksum and ' Key ' and initialize the EEPROM if
* necessary .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_DiagEEPROM ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned short index , temp , max_wd_cnt ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_page_ctrl ) & NARROW_SCSI_CARD )
max_wd_cnt = EEPROM_WD_CNT ;
else
max_wd_cnt = EEPROM_WD_CNT * 2 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
temp = FPT_utilEERead ( p_port , FW_SIGNATURE / 2 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( temp = = 0x4641 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( index = 2 ; index < max_wd_cnt ; index + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
temp + = FPT_utilEERead ( p_port , index ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( temp = = FPT_utilEERead ( p_port , EEPROM_CHECK_SUM / 2 ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
return ; /*EEPROM is Okay so return now! */
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEEWriteOnOff ( p_port , ( unsigned char ) 1 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( index = 0 ; index < max_wd_cnt ; index + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEEWrite ( p_port , 0x0000 , index ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
temp = 0 ;
FPT_utilEEWrite ( p_port , 0x4641 , FW_SIGNATURE / 2 ) ;
temp + = 0x4641 ;
FPT_utilEEWrite ( p_port , 0x3920 , MODEL_NUMB_0 / 2 ) ;
temp + = 0x3920 ;
FPT_utilEEWrite ( p_port , 0x3033 , MODEL_NUMB_2 / 2 ) ;
temp + = 0x3033 ;
FPT_utilEEWrite ( p_port , 0x2020 , MODEL_NUMB_4 / 2 ) ;
temp + = 0x2020 ;
FPT_utilEEWrite ( p_port , 0x70D3 , SYSTEM_CONFIG / 2 ) ;
temp + = 0x70D3 ;
FPT_utilEEWrite ( p_port , 0x0010 , BIOS_CONFIG / 2 ) ;
temp + = 0x0010 ;
FPT_utilEEWrite ( p_port , 0x0003 , SCAM_CONFIG / 2 ) ;
temp + = 0x0003 ;
FPT_utilEEWrite ( p_port , 0x0007 , ADAPTER_SCSI_ID / 2 ) ;
temp + = 0x0007 ;
FPT_utilEEWrite ( p_port , 0x0000 , IGNORE_B_SCAN / 2 ) ;
temp + = 0x0000 ;
FPT_utilEEWrite ( p_port , 0x0000 , SEND_START_ENA / 2 ) ;
temp + = 0x0000 ;
FPT_utilEEWrite ( p_port , 0x0000 , DEVICE_ENABLE / 2 ) ;
temp + = 0x0000 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL01 / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL23 / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL45 / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL67 / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL89 / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBLab / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBLcd / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBLef / 2 ) ;
temp + = 0x4242 ;
FPT_utilEEWrite ( p_port , 0x6C46 , 64 / 2 ) ; /*PRODUCT ID */
temp + = 0x6C46 ;
FPT_utilEEWrite ( p_port , 0x7361 , 66 / 2 ) ; /* FlashPoint LT */
temp + = 0x7361 ;
FPT_utilEEWrite ( p_port , 0x5068 , 68 / 2 ) ;
temp + = 0x5068 ;
FPT_utilEEWrite ( p_port , 0x696F , 70 / 2 ) ;
temp + = 0x696F ;
FPT_utilEEWrite ( p_port , 0x746E , 72 / 2 ) ;
temp + = 0x746E ;
FPT_utilEEWrite ( p_port , 0x4C20 , 74 / 2 ) ;
temp + = 0x4C20 ;
FPT_utilEEWrite ( p_port , 0x2054 , 76 / 2 ) ;
temp + = 0x2054 ;
FPT_utilEEWrite ( p_port , 0x2020 , 78 / 2 ) ;
temp + = 0x2020 ;
index = ( ( EE_SCAMBASE / 2 ) + ( 7 * 16 ) ) ;
FPT_utilEEWrite ( p_port , ( 0x0700 + TYPE_CODE0 ) , index ) ;
temp + = ( 0x0700 + TYPE_CODE0 ) ;
index + + ;
FPT_utilEEWrite ( p_port , 0x5542 , index ) ; /*Vendor ID code */
temp + = 0x5542 ; /* BUSLOGIC */
index + + ;
FPT_utilEEWrite ( p_port , 0x4C53 , index ) ;
temp + = 0x4C53 ;
index + + ;
FPT_utilEEWrite ( p_port , 0x474F , index ) ;
temp + = 0x474F ;
index + + ;
FPT_utilEEWrite ( p_port , 0x4349 , index ) ;
temp + = 0x4349 ;
index + + ;
FPT_utilEEWrite ( p_port , 0x5442 , index ) ; /*Vendor unique code */
temp + = 0x5442 ; /* BT- 930 */
index + + ;
FPT_utilEEWrite ( p_port , 0x202D , index ) ;
temp + = 0x202D ;
index + + ;
FPT_utilEEWrite ( p_port , 0x3339 , index ) ;
temp + = 0x3339 ;
index + + ; /*Serial # */
FPT_utilEEWrite ( p_port , 0x2030 , index ) ; /* 01234567 */
temp + = 0x2030 ;
index + + ;
FPT_utilEEWrite ( p_port , 0x5453 , index ) ;
temp + = 0x5453 ;
index + + ;
FPT_utilEEWrite ( p_port , 0x5645 , index ) ;
temp + = 0x5645 ;
index + + ;
FPT_utilEEWrite ( p_port , 0x2045 , index ) ;
temp + = 0x2045 ;
index + + ;
FPT_utilEEWrite ( p_port , 0x202F , index ) ;
temp + = 0x202F ;
index + + ;
FPT_utilEEWrite ( p_port , 0x4F4A , index ) ;
temp + = 0x4F4A ;
index + + ;
FPT_utilEEWrite ( p_port , 0x204E , index ) ;
temp + = 0x204E ;
index + + ;
FPT_utilEEWrite ( p_port , 0x3539 , index ) ;
temp + = 0x3539 ;
FPT_utilEEWrite ( p_port , temp , EEPROM_CHECK_SUM / 2 ) ;
FPT_utilEEWriteOnOff ( p_port , ( unsigned char ) 0 ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Queue Search Select
*
* Description : Try to find a new command to execute .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_queueSearchSelect ( struct sccb_card * pCurrCard ,
unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char scan_ptr , lun ;
struct sccb_mgr_tar_info * currTar_Info ;
struct sccb * pOldSccb ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
scan_ptr = pCurrCard - > scanIndex ;
do {
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ scan_ptr ] ;
2006-03-08 11:14:35 +03:00
if ( ( pCurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) ) {
if ( currTar_Info - > TarSelQ_Cnt ! = 0 ) {
2005-04-17 02:20:36 +04:00
scan_ptr + + ;
if ( scan_ptr = = MAX_SCSI_TAR )
scan_ptr = 0 ;
2006-03-08 11:14:35 +03:00
for ( lun = 0 ; lun < MAX_LUN ; lun + + ) {
if ( currTar_Info - > TarLUNBusy [ lun ] = = 0 ) {
pCurrCard - > currentSCCB =
currTar_Info - > TarSelQ_Head ;
2005-04-17 02:20:36 +04:00
pOldSccb = NULL ;
2006-03-08 11:14:35 +03:00
while ( ( pCurrCard - >
currentSCCB ! = NULL )
& & ( lun ! =
pCurrCard - >
currentSCCB - > Lun ) ) {
pOldSccb =
pCurrCard - >
currentSCCB ;
pCurrCard - > currentSCCB =
( struct sccb
* ) ( pCurrCard - >
currentSCCB ) - >
Sccb_forwardlink ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > currentSCCB = =
NULL )
2005-04-17 02:20:36 +04:00
continue ;
2006-03-08 11:14:35 +03:00
if ( pOldSccb ! = NULL ) {
pOldSccb - >
Sccb_forwardlink =
( struct sccb
* ) ( pCurrCard - >
currentSCCB ) - >
Sccb_forwardlink ;
pOldSccb - >
Sccb_backlink =
( struct sccb
* ) ( pCurrCard - >
currentSCCB ) - >
Sccb_backlink ;
currTar_Info - >
TarSelQ_Cnt - - ;
} else {
currTar_Info - >
TarSelQ_Head =
( struct sccb
* ) ( pCurrCard - >
currentSCCB ) - >
Sccb_forwardlink ;
if ( currTar_Info - >
TarSelQ_Head = =
NULL ) {
currTar_Info - >
TarSelQ_Tail
= NULL ;
currTar_Info - >
TarSelQ_Cnt
= 0 ;
} else {
currTar_Info - >
TarSelQ_Cnt - - ;
currTar_Info - >
TarSelQ_Head - >
Sccb_backlink
=
( struct sccb
* ) NULL ;
2005-04-17 02:20:36 +04:00
}
}
2006-03-08 11:14:35 +03:00
pCurrCard - > scanIndex = scan_ptr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > globalFlags | =
F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
break ;
2005-04-17 02:20:36 +04:00
}
}
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
scan_ptr + + ;
if ( scan_ptr = = MAX_SCSI_TAR ) {
scan_ptr = 0 ;
}
}
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
if ( ( currTar_Info - > TarSelQ_Cnt ! = 0 ) & &
2006-03-08 11:14:35 +03:00
( currTar_Info - > TarLUNBusy [ 0 ] = = 0 ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > currentSCCB =
currTar_Info - > TarSelQ_Head ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Head =
( struct sccb * ) ( pCurrCard - > currentSCCB ) - >
Sccb_forwardlink ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarSelQ_Head = = NULL ) {
2005-04-17 02:20:36 +04:00
currTar_Info - > TarSelQ_Tail = NULL ;
currTar_Info - > TarSelQ_Cnt = 0 ;
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
currTar_Info - > TarSelQ_Cnt - - ;
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Head - >
Sccb_backlink = ( struct sccb * ) NULL ;
2005-04-17 02:20:36 +04:00
}
scan_ptr + + ;
if ( scan_ptr = = MAX_SCSI_TAR )
scan_ptr = 0 ;
pCurrCard - > scanIndex = scan_ptr ;
pCurrCard - > globalFlags | = F_NEW_SCCB_CMD ;
break ;
}
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
scan_ptr + + ;
2006-03-08 11:14:35 +03:00
if ( scan_ptr = = MAX_SCSI_TAR ) {
2005-04-17 02:20:36 +04:00
scan_ptr = 0 ;
}
}
}
} while ( scan_ptr ! = pCurrCard - > scanIndex ) ;
}
/*---------------------------------------------------------------------
*
* Function : Queue Select Fail
*
* Description : Add the current SCCB to the head of the Queue .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_queueSelectFail ( struct sccb_card * pCurrCard ,
unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char thisTarg ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > currentSCCB ! = NULL ) {
thisTarg =
( unsigned char ) ( ( ( struct sccb * ) ( pCurrCard - > currentSCCB ) ) - >
TargID ) ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ thisTarg ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > currentSCCB - > Sccb_backlink = ( struct sccb * ) NULL ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > currentSCCB - > Sccb_forwardlink =
currTar_Info - > TarSelQ_Head ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarSelQ_Cnt = = 0 ) {
currTar_Info - > TarSelQ_Tail = pCurrCard - > currentSCCB ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
currTar_Info - > TarSelQ_Head - > Sccb_backlink =
pCurrCard - > currentSCCB ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Head = pCurrCard - > currentSCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > currentSCCB = NULL ;
currTar_Info - > TarSelQ_Cnt + + ;
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
2005-04-17 02:20:36 +04:00
/*---------------------------------------------------------------------
*
* Function : Queue Command Complete
*
* Description : Call the callback function with the current SCCB .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_queueCmdComplete ( struct sccb_card * pCurrCard ,
struct sccb * p_sccb , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i , SCSIcmd ;
CALL_BK_FN callback ;
struct sccb_mgr_tar_info * currTar_Info ;
SCSIcmd = p_sccb - > Cdb [ 0 ] ;
if ( ! ( p_sccb - > Sccb_XferState & F_ALL_XFERRED ) ) {
if ( ( p_sccb - >
ControlByte & ( SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN ) )
& & ( p_sccb - > HostStatus = = SCCB_COMPLETE )
& & ( p_sccb - > TargetStatus ! = SSCHECK ) )
if ( ( SCSIcmd = = SCSI_READ ) | |
( SCSIcmd = = SCSI_WRITE ) | |
( SCSIcmd = = SCSI_READ_EXTENDED ) | |
( SCSIcmd = = SCSI_WRITE_EXTENDED ) | |
( SCSIcmd = = SCSI_WRITE_AND_VERIFY ) | |
( SCSIcmd = = SCSI_START_STOP_UNIT ) | |
( pCurrCard - > globalFlags & F_NO_FILTER )
)
p_sccb - > HostStatus = SCCB_DATA_UNDER_RUN ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_sccb - > SccbStatus = = SCCB_IN_PROCESS ) {
if ( p_sccb - > HostStatus | | p_sccb - > TargetStatus )
p_sccb - > SccbStatus = SCCB_ERROR ;
else
p_sccb - > SccbStatus = SCCB_SUCCESS ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( p_sccb - > Sccb_XferState & F_AUTO_SENSE ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_sccb - > CdbLength = p_sccb - > Save_CdbLen ;
for ( i = 0 ; i < 6 ; i + + ) {
p_sccb - > Cdb [ i ] = p_sccb - > Save_Cdb [ i ] ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( p_sccb - > OperationCode = = RESIDUAL_SG_COMMAND ) | |
( p_sccb - > OperationCode = = RESIDUAL_COMMAND ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilUpdateResidual ( p_sccb ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
pCurrCard - > cmdCounter - - ;
if ( ! pCurrCard - > cmdCounter ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > globalFlags & F_GREEN_PC ) {
WR_HARPOON ( pCurrCard - > ioPort + hp_clkctrl_0 ,
( PWR_DWN | CLKCTRL_DEFAULT ) ) ;
WR_HARPOON ( pCurrCard - > ioPort + hp_sys_ctrl , STOP_CLK ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( pCurrCard - > ioPort + hp_semaphore ,
( RD_HARPOON ( pCurrCard - > ioPort + hp_semaphore ) &
~ SCCB_MGR_ACTIVE ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( pCurrCard - > discQCount ! = 0 ) {
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] ;
if ( ( ( pCurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! =
TAG_Q_TRYING ) ) ) {
2005-04-17 02:20:36 +04:00
pCurrCard - > discQCount - - ;
2006-03-08 11:14:35 +03:00
pCurrCard - > discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ p_sccb - > Lun ] ] = NULL ;
} else {
if ( p_sccb - > Sccb_tag ) {
2005-04-17 02:20:36 +04:00
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ p_sccb - > Sccb_tag ] = NULL ;
2006-03-08 11:14:35 +03:00
} else {
2005-04-17 02:20:36 +04:00
pCurrCard - > discQCount - - ;
2006-03-08 11:14:35 +03:00
pCurrCard - > discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ 0 ] ] = NULL ;
2005-04-17 02:20:36 +04:00
}
}
}
2006-03-08 11:14:35 +03:00
callback = ( CALL_BK_FN ) p_sccb - > SccbCallback ;
callback ( p_sccb ) ;
pCurrCard - > globalFlags | = F_NEW_SCCB_CMD ;
pCurrCard - > currentSCCB = NULL ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Queue Disconnect
*
* Description : Add SCCB to our disconnect array .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_queueDisconnect ( struct sccb * p_sccb , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) ) {
FPT_BL_Card [ p_card ] . discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ p_sccb - > Lun ] ] =
p_sccb ;
} else {
if ( p_sccb - > Sccb_tag ) {
FPT_BL_Card [ p_card ] . discQ_Tbl [ p_sccb - > Sccb_tag ] =
p_sccb ;
FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] . TarLUNBusy [ 0 ] =
0 ;
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] . TarTagQ_Cnt + + ;
2006-03-08 11:14:35 +03:00
} else {
FPT_BL_Card [ p_card ] . discQ_Tbl [ currTar_Info - >
LunDiscQ_Idx [ 0 ] ] = p_sccb ;
2005-04-17 02:20:36 +04:00
}
}
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . currentSCCB = NULL ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Queue Flush SCCB
*
* Description : Flush all SCCB ' s back to the host driver for this target .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_queueFlushSccb ( unsigned char p_card , unsigned char error_code )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char qtag , thisTarg ;
struct sccb * currSCCB ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
if ( currSCCB ! = NULL ) {
thisTarg = ( unsigned char ) currSCCB - > TargID ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ thisTarg ] ;
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] & &
( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > TargID = =
thisTarg ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - >
HostStatus = ( unsigned char ) error_code ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] ,
FPT_BL_Card [ p_card ] .
discQ_Tbl [ qtag ] , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] = NULL ;
currTar_Info - > TarTagQ_Cnt - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
}
}
/*---------------------------------------------------------------------
*
* Function : Queue Flush Target SCCB
*
* Description : Flush all SCCB ' s back to the host driver for this target .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_queueFlushTargSccb ( unsigned char p_card , unsigned char thisTarg ,
unsigned char error_code )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char qtag ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ thisTarg ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] & &
( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > TargID = = thisTarg ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > HostStatus =
( unsigned char ) error_code ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] ,
FPT_BL_Card [ p_card ] .
discQ_Tbl [ qtag ] , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] = NULL ;
currTar_Info - > TarTagQ_Cnt - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
}
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
static void FPT_queueAddSccb ( struct sccb * p_SCCB , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb_mgr_tar_info * currTar_Info ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ p_SCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_SCCB - > Sccb_forwardlink = NULL ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_SCCB - > Sccb_backlink = currTar_Info - > TarSelQ_Tail ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarSelQ_Cnt = = 0 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Head = p_SCCB ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Tail - > Sccb_forwardlink = p_SCCB ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Tail = p_SCCB ;
currTar_Info - > TarSelQ_Cnt + + ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Queue Find SCCB
*
* Description : Search the target select Queue for this SCCB , and
* remove it if found .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned char FPT_queueFindSccb ( struct sccb * p_SCCB ,
unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
struct sccb * q_ptr ;
struct sccb_mgr_tar_info * currTar_Info ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ p_SCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
q_ptr = currTar_Info - > TarSelQ_Head ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( q_ptr ! = NULL ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( q_ptr = = p_SCCB ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarSelQ_Head = = q_ptr ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Head =
q_ptr - > Sccb_forwardlink ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( currTar_Info - > TarSelQ_Tail = = q_ptr ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Tail =
q_ptr - > Sccb_backlink ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( q_ptr - > Sccb_forwardlink ! = NULL ) {
q_ptr - > Sccb_forwardlink - > Sccb_backlink =
q_ptr - > Sccb_backlink ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
if ( q_ptr - > Sccb_backlink ! = NULL ) {
q_ptr - > Sccb_backlink - > Sccb_forwardlink =
q_ptr - > Sccb_forwardlink ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:35 +03:00
currTar_Info - > TarSelQ_Cnt - - ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 1 ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
q_ptr = q_ptr - > Sccb_forwardlink ;
}
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Utility Update Residual Count
*
* Description : Update the XferCnt to the remaining byte count .
* If we transferred all the data then just write zero .
* If Non - SG transfer then report Total Cnt - Actual Transfer
* Cnt . For SG transfers add the count fields of all
* remaining SG elements , as well as any partial remaining
* element .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_utilUpdateResidual ( struct sccb * p_SCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned long partial_cnt ;
unsigned int sg_index ;
unsigned long * sg_ptr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_SCCB - > Sccb_XferState & F_ALL_XFERRED ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_SCCB - > DataLength = 0x0000 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else if ( p_SCCB - > Sccb_XferState & F_SG_XFER ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
partial_cnt = 0x0000 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_index = p_SCCB - > Sccb_sgseg ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
sg_ptr = ( unsigned long * ) p_SCCB - > DataPointer ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_SCCB - > Sccb_SGoffset ) {
2005-04-17 02:20:36 +04:00
partial_cnt = p_SCCB - > Sccb_SGoffset ;
sg_index + + ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ( ( unsigned long ) sg_index *
( unsigned long ) SG_ELEMENT_SIZE ) < p_SCCB - > DataLength ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
partial_cnt + = * ( sg_ptr + ( sg_index * 2 ) ) ;
2005-04-17 02:20:36 +04:00
sg_index + + ;
2006-03-08 11:14:35 +03:00
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_SCCB - > DataLength = partial_cnt ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
p_SCCB - > DataLength - = p_SCCB - > Sccb_ATC ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Wait 1 Second
*
* Description : Wait for 1 second .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_Wait1Second ( unsigned long p_port )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < 4 ; i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( p_port + hp_scsictrl_0 ) & SCSI_RST ) )
break ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & SCAM_SEL ) )
break ;
}
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
2005-04-24 11:38:05 +04:00
* Function : FPT_Wait
2005-04-17 02:20:36 +04:00
*
* Description : Wait the desired delay .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +03:00
static void FPT_Wait ( unsigned long p_port , unsigned char p_delay )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char old_timer ;
unsigned char green_flag ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
old_timer = RD_HARPOON ( p_port + hp_seltimeout ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
green_flag = RD_HARPOON ( p_port + hp_clkctrl_0 ) ;
WR_HARPOON ( p_port + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_seltimeout , p_delay ) ;
WRW_HARPOON ( ( p_port + hp_intstat ) , TIMEOUT ) ;
WRW_HARPOON ( ( p_port + hp_intena ) , ( FPT_default_intena & ~ TIMEOUT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( RD_HARPOON ( p_port + hp_portctrl_0 ) | START_TO ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & TIMEOUT ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RD_HARPOON ( p_port + hp_scsictrl_0 ) & SCSI_RST ) )
break ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & SCAM_SEL ) )
break ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( RD_HARPOON ( p_port + hp_portctrl_0 ) & ~ START_TO ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WRW_HARPOON ( ( p_port + hp_intstat ) , TIMEOUT ) ;
WRW_HARPOON ( ( p_port + hp_intena ) , FPT_default_intena ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_clkctrl_0 , green_flag ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_seltimeout , old_timer ) ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Enable / Disable Write to EEPROM
*
* Description : The EEPROM must first be enabled for writes
* A total of 9 clocks are needed .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_utilEEWriteOnOff ( unsigned long p_port , unsigned char p_mode )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char ee_value ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value =
( unsigned char ) ( RD_HARPOON ( p_port + hp_ee_ctrl ) &
( EXT_ARB_ACK | SCSI_TERM_ENA_H ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( p_mode )
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEESendCmdAddr ( p_port , EWEN , EWEN_ADDR ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEESendCmdAddr ( p_port , EWDS , EWDS_ADDR ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_ee_ctrl , ( ee_value | SEE_MS ) ) ; /*Turn off CS */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ; /*Turn off Master Select */
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Write EEPROM
*
* Description : Write a word to the EEPROM at the specified
* address .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_utilEEWrite ( unsigned long p_port , unsigned short ee_data ,
unsigned short ee_addr )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char ee_value ;
unsigned short i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value =
( unsigned
char ) ( ( RD_HARPOON ( p_port + hp_ee_ctrl ) &
( EXT_ARB_ACK | SCSI_TERM_ENA_H ) ) | ( SEE_MS | SEE_CS ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEESendCmdAddr ( p_port , EE_WRITE , ee_addr ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value | = ( SEE_MS + SEE_CS ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0x8000 ; i ! = 0 ; i > > = 1 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( i & ee_data )
ee_value | = SEE_DO ;
else
ee_value & = ~ SEE_DO ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value | = SEE_CLK ; /* Clock data! */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value & = ~ SEE_CLK ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
}
ee_value & = ( EXT_ARB_ACK | SCSI_TERM_ENA_H ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ( ee_value | SEE_MS ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_Wait ( p_port , TO_10ms ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
WR_HARPOON ( p_port + hp_ee_ctrl , ( ee_value | SEE_MS | SEE_CS ) ) ; /* Set CS to EEPROM */
WR_HARPOON ( p_port + hp_ee_ctrl , ( ee_value | SEE_MS ) ) ; /* Turn off CS */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ; /* Turn off Master Select */
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Read EEPROM
*
* Description : Read a word from the EEPROM at the desired
* address .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned short FPT_utilEERead ( unsigned long p_port ,
unsigned short ee_addr )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned short i , ee_data1 , ee_data2 ;
2005-04-17 02:20:36 +04:00
i = 0 ;
2005-04-24 11:38:05 +04:00
ee_data1 = FPT_utilEEReadOrg ( p_port , ee_addr ) ;
2006-03-08 11:14:35 +03:00
do {
2005-04-24 11:38:05 +04:00
ee_data2 = FPT_utilEEReadOrg ( p_port , ee_addr ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( ee_data1 = = ee_data2 )
2006-03-08 11:14:37 +03:00
return ee_data1 ;
2005-04-17 02:20:36 +04:00
ee_data1 = ee_data2 ;
i + + ;
2006-03-08 11:14:35 +03:00
} while ( i < 4 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return ee_data1 ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Read EEPROM Original
*
* Description : Read a word from the EEPROM at the desired
* address .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static unsigned short FPT_utilEEReadOrg ( unsigned long p_port ,
unsigned short ee_addr )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char ee_value ;
unsigned short i , ee_data ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value =
( unsigned
char ) ( ( RD_HARPOON ( p_port + hp_ee_ctrl ) &
( EXT_ARB_ACK | SCSI_TERM_ENA_H ) ) | ( SEE_MS | SEE_CS ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
FPT_utilEESendCmdAddr ( p_port , EE_READ , ee_addr ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value | = ( SEE_MS + SEE_CS ) ;
ee_data = 0 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 1 ; i < = 16 ; i + + ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value | = SEE_CLK ; /* Clock data! */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value & = ~ SEE_CLK ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_data < < = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( RD_HARPOON ( p_port + hp_ee_ctrl ) & SEE_DI )
ee_data | = 1 ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value & = ~ ( SEE_MS + SEE_CS ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ( ee_value | SEE_MS ) ) ; /*Turn off CS */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ; /*Turn off Master Select */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:37 +03:00
return ee_data ;
2005-04-17 02:20:36 +04:00
}
/*---------------------------------------------------------------------
*
* Function : Send EE command and Address to the EEPROM
*
* Description : Transfers the correct command and sends the address
* to the eeprom .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:35 +03:00
static void FPT_utilEESendCmdAddr ( unsigned long p_port , unsigned char ee_cmd ,
unsigned short ee_addr )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned char ee_value ;
unsigned char narrow_flg ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
unsigned short i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
narrow_flg =
( unsigned char ) ( RD_HARPOON ( p_port + hp_page_ctrl ) &
NARROW_SCSI_CARD ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value = SEE_MS ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
ee_value | = SEE_CS ; /* Set CS to EEPROM */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
for ( i = 0x04 ; i ! = 0 ; i > > = 1 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( i & ee_cmd )
ee_value | = SEE_DO ;
else
ee_value & = ~ SEE_DO ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value | = SEE_CLK ; /* Clock data! */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value & = ~ SEE_CLK ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
}
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( narrow_flg )
i = 0x0080 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
else
i = 0x0200 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
while ( i ! = 0 ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:35 +03:00
if ( i & ee_addr )
ee_value | = SEE_DO ;
else
ee_value & = ~ SEE_DO ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value | = SEE_CLK ; /* Clock data! */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value & = ~ SEE_CLK ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
i > > = 1 ;
}
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:25 +03:00
static unsigned short FPT_CalcCrc16 ( unsigned char buffer [ ] )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
unsigned short crc = 0 ;
int i , j ;
unsigned short ch ;
for ( i = 0 ; i < ID_STRING_LENGTH ; i + + ) {
ch = ( unsigned short ) buffer [ i ] ;
for ( j = 0 ; j < 8 ; j + + ) {
if ( ( crc ^ ch ) & 1 )
crc = ( crc > > 1 ) ^ CRCMASK ;
else
crc > > = 1 ;
ch > > = 1 ;
}
}
2006-03-08 11:14:37 +03:00
return crc ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:24 +03:00
static unsigned char FPT_CalcLrc ( unsigned char buffer [ ] )
2005-04-17 02:20:36 +04:00
{
int i ;
2006-03-08 11:14:24 +03:00
unsigned char lrc ;
2005-04-17 02:20:36 +04:00
lrc = 0 ;
2006-03-08 11:14:35 +03:00
for ( i = 0 ; i < ID_STRING_LENGTH ; i + + )
2005-04-17 02:20:36 +04:00
lrc ^ = buffer [ i ] ;
2006-03-08 11:14:37 +03:00
return lrc ;
2005-04-17 02:20:36 +04:00
}
/*
The following inline definitions avoid type conflicts .
*/
static inline unsigned char
FlashPoint__ProbeHostAdapter ( struct FlashPoint_Info * FlashPointInfo )
{
2006-03-08 11:14:35 +03:00
return FlashPoint_ProbeHostAdapter ( ( struct sccb_mgr_info * )
FlashPointInfo ) ;
2005-04-17 02:20:36 +04:00
}
static inline FlashPoint_CardHandle_T
FlashPoint__HardwareResetHostAdapter ( struct FlashPoint_Info * FlashPointInfo )
{
2006-03-08 11:14:35 +03:00
return FlashPoint_HardwareResetHostAdapter ( ( struct sccb_mgr_info * )
FlashPointInfo ) ;
2005-04-17 02:20:36 +04:00
}
static inline void
FlashPoint__ReleaseHostAdapter ( FlashPoint_CardHandle_T CardHandle )
{
2006-03-08 11:14:35 +03:00
FlashPoint_ReleaseHostAdapter ( CardHandle ) ;
2005-04-17 02:20:36 +04:00
}
static inline void
2006-03-08 11:14:35 +03:00
FlashPoint__StartCCB ( FlashPoint_CardHandle_T CardHandle ,
struct BusLogic_CCB * CCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
FlashPoint_StartCCB ( CardHandle , ( struct sccb * ) CCB ) ;
2005-04-17 02:20:36 +04:00
}
static inline void
2006-03-08 11:14:35 +03:00
FlashPoint__AbortCCB ( FlashPoint_CardHandle_T CardHandle ,
struct BusLogic_CCB * CCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:35 +03:00
FlashPoint_AbortCCB ( CardHandle , ( struct sccb * ) CCB ) ;
2005-04-17 02:20:36 +04:00
}
2007-02-06 03:39:01 +03:00
static inline bool
2005-04-17 02:20:36 +04:00
FlashPoint__InterruptPending ( FlashPoint_CardHandle_T CardHandle )
{
2006-03-08 11:14:35 +03:00
return FlashPoint_InterruptPending ( CardHandle ) ;
2005-04-17 02:20:36 +04:00
}
static inline int
FlashPoint__HandleInterrupt ( FlashPoint_CardHandle_T CardHandle )
{
2006-03-08 11:14:35 +03:00
return FlashPoint_HandleInterrupt ( CardHandle ) ;
2005-04-17 02:20:36 +04:00
}
# define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
# define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
# define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
# define FlashPoint_StartCCB FlashPoint__StartCCB
# define FlashPoint_AbortCCB FlashPoint__AbortCCB
# define FlashPoint_InterruptPending FlashPoint__InterruptPending
# define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
2008-03-13 15:55:08 +03:00
# else /* !CONFIG_SCSI_FLASHPOINT */
2005-04-17 02:20:36 +04:00
/*
Define prototypes for the FlashPoint SCCB Manager Functions .
*/
extern unsigned char FlashPoint_ProbeHostAdapter ( struct FlashPoint_Info * ) ;
extern FlashPoint_CardHandle_T
2006-03-08 11:14:35 +03:00
FlashPoint_HardwareResetHostAdapter ( struct FlashPoint_Info * ) ;
2005-04-17 02:20:36 +04:00
extern void FlashPoint_StartCCB ( FlashPoint_CardHandle_T , struct BusLogic_CCB * ) ;
extern int FlashPoint_AbortCCB ( FlashPoint_CardHandle_T , struct BusLogic_CCB * ) ;
2007-02-06 03:39:01 +03:00
extern bool FlashPoint_InterruptPending ( FlashPoint_CardHandle_T ) ;
2005-04-17 02:20:36 +04:00
extern int FlashPoint_HandleInterrupt ( FlashPoint_CardHandle_T ) ;
extern void FlashPoint_ReleaseHostAdapter ( FlashPoint_CardHandle_T ) ;
2008-03-13 15:55:08 +03:00
# endif /* CONFIG_SCSI_FLASHPOINT */