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 .
*/
# include <linux/config.h>
# ifndef CONFIG_SCSI_OMIT_FLASHPOINT
# define MAX_CARDS 8
# undef BUSTYPE_PCI
# define CRCMASK 0xA001
# define FAILURE 0xFFFFFFFFL
2006-03-08 11:14:24 +03:00
# define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
2006-03-08 11:14:25 +03:00
# define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:29 +03:00
struct sccb ;
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:26 +03:00
unsigned long si_baseaddr ;
2006-03-08 11:14:24 +03:00
unsigned char si_present ;
unsigned char si_intvect ;
unsigned char si_id ;
unsigned char si_lun ;
2006-03-08 11:14:25 +03:00
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 ;
2006-03-08 11:14:24 +03:00
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 ] ;
2006-03-08 11:14:26 +03:00
unsigned long si_OS_reserved ;
2006-03-08 11:14:24 +03:00
unsigned char si_XlatInfo [ 4 ] ;
2006-03-08 11:14:26 +03:00
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:24 +03:00
unsigned char OperationCode ;
unsigned char ControlByte ;
unsigned char CdbLength ;
unsigned char RequestSenseLength ;
2006-03-08 11:14:26 +03:00
unsigned long DataLength ;
unsigned long DataPointer ;
2006-03-08 11:14:24 +03:00
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 ;
2006-03-08 11:14:26 +03:00
unsigned long Reserved2 ;
unsigned long SensePointer ;
2005-04-17 02:20:36 +04:00
CALL_BK_FN SccbCallback ; /* VOID (*SccbCallback)(); */
2006-03-08 11:14:26 +03:00
unsigned long SccbIOPort ; /* Identifies board base port */
2006-03-08 11:14:24 +03:00
unsigned char SccbStatus ;
unsigned char SCCBRes2 ;
2006-03-08 11:14:25 +03:00
unsigned short SccbOSFlags ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
unsigned long Sccb_XferCnt ; /* actual transfer count */
unsigned long Sccb_ATC ;
unsigned long SccbVirtDataPtr ; /* virtual addr for OS/2 */
unsigned long Sccb_res1 ;
2006-03-08 11:14:25 +03:00
unsigned short Sccb_MGRFlags ;
unsigned short Sccb_sgseg ;
2006-03-08 11:14:24 +03:00
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 */
2006-03-08 11:14:29 +03:00
struct sccb * Sccb_forwardlink ;
struct sccb * Sccb_backlink ;
2006-03-08 11:14:26 +03:00
unsigned long Sccb_savedATC ;
2006-03-08 11:14:24 +03:00
unsigned char Save_Cdb [ 6 ] ;
unsigned char Save_CdbLen ;
unsigned char Sccb_XferState ;
2006-03-08 11:14:26 +03:00
unsigned long Sccb_SGoffset ;
2006-03-08 11:14:29 +03:00
} ;
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
# 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 */
# define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
# define BUS_FREE_ST 0
# define SELECT_ST 1
# 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 */
# 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
# define SCCB_COMPLETE 0x00 /* SCCB completed without error */
# define SCCB_DATA_UNDER_RUN 0x0C
# define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
# define SCCB_DATA_OVER_RUN 0x12
# define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
# define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
# define SCCB_BM_ERR 0x30 /* BusMaster error. */
# define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
# define SCCB_IN_PROCESS 0x00
# define SCCB_SUCCESS 0x01
# define SCCB_ABORT 0x02
# define SCCB_ERROR 0x04
# define ORION_FW_REV 3110
# define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
# define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
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
# define SG_BUF_CNT 16 /*Number of prefetched elements. */
# define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
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)
2005-04-24 11:38:05 +04:00
typedef struct SCCBMgr_tar_info * PSCCBMgr_tar_info ;
2005-04-17 02:20:36 +04:00
typedef struct SCCBMgr_tar_info {
2006-03-08 11:14:29 +03:00
struct sccb * TarSelQ_Head ;
struct sccb * TarSelQ_Tail ;
2006-03-08 11:14:24 +03:00
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 ] ;
2005-04-17 02:20:36 +04:00
} SCCBMGR_TAR_INFO ;
typedef struct NVRAMInfo {
2006-03-08 11:14:24 +03:00
unsigned char niModel ; /* Model No. of card */
unsigned char niCardNo ; /* Card no. */
2006-03-08 11:14:26 +03:00
unsigned long niBaseAddr ; /* Port Address of card */
2006-03-08 11:14:24 +03:00
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 */
2005-04-17 02:20:36 +04:00
} NVRAMINFO ;
typedef NVRAMINFO * PNVRamInfo ;
# define MODEL_LT 1
# define MODEL_DL 2
# define MODEL_LW 3
# define MODEL_DW 4
typedef struct SCCBcard {
2006-03-08 11:14:29 +03:00
struct sccb * currentSCCB ;
2006-03-08 11:14:30 +03:00
struct sccb_mgr_info * cardInfo ;
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:25 +03:00
unsigned short cmdCounter ;
2006-03-08 11:14:24 +03:00
unsigned char discQCount ;
unsigned char tagQ_Lst ;
unsigned char cardIndex ;
unsigned char scanIndex ;
unsigned char globalFlags ;
unsigned char ourId ;
2005-04-17 02:20:36 +04:00
PNVRamInfo pNvRamInfo ;
2006-03-08 11:14:29 +03:00
struct sccb * discQ_Tbl [ QUEUE_DEPTH ] ;
2005-04-17 02:20:36 +04:00
} SCCBCARD ;
typedef struct SCCBcard * PSCCBcard ;
# 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
# define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
# define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
# 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
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 } ;
typedef struct SCCBscam_info {
2006-03-08 11:14:24 +03:00
unsigned char id_string [ ID_STRING_LENGTH ] ;
2005-04-17 02:20:36 +04:00
enum scam_id_st state ;
2006-03-08 11:14:22 +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
# define SMIGNORWR 0x23 /* Ignore Wide Residue */
# define SIX_BYTE_CMD 0x06
# define TWELVE_BYTE_CMD 0x0C
# define ASYNC 0x00
# define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
# 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
# define EE_SCAMBASE 256
# define SCAM_ENABLED BIT(2)
# define SCAM_LEVEL2 BIT(3)
# define RENEGO_ENA BITW(10)
# define CONNIO_ENA BITW(11)
# define GREEN_PC_ENA BITW(12)
# define AUTO_RATE_00 00
# define AUTO_RATE_05 01
# define AUTO_RATE_10 02
# define AUTO_RATE_20 03
# define WIDE_NEGO_BIT BIT(7)
# define DISC_ENABLE_BIT BIT(6)
# define hp_vendor_id_0 0x00 /* LSB */
# define ORION_VEND_0 0x4B
# define hp_vendor_id_1 0x01 /* MSB */
# define ORION_VEND_1 0x10
# define hp_device_id_0 0x02 /* LSB */
# define ORION_DEV_0 0x30
# define hp_device_id_1 0x03 /* MSB */
# define ORION_DEV_1 0x81
/* Sub Vendor ID and Sub Device ID only available in
Harpoon Version 2 and higher */
# define hp_sub_device_id_0 0x06 /* LSB */
# 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)
# define hp_sys_ctrl 0x0F
# 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 */
# define hp_host_blk_cnt 0x13
# define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
# define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
# define hp_int_mask 0x17
# define INT_CMD_COMPL BIT(0) /* DMA command complete */
# define INT_EXT_STATUS BIT(1) /* Extended Status Set */
# define hp_xfer_cnt_lo 0x18
# define hp_xfer_cnt_hi 0x1A
# define hp_xfer_cmd 0x1B
# define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
# define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
# define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
# define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
# define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
# 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))
# define hp_host_addr_lo 0x1C
# define hp_host_addr_hmi 0x1E
# define hp_ee_ctrl 0x22
# 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)
# define EE_READ 0x06
# define EE_WRITE 0x05
# define EWEN 0x04
# define EWEN_ADDR 0x03C0
# define EWDS 0x04
# define EWDS_ADDR 0x0000
# define hp_bm_ctrl 0x26
# 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) /*?? */
# define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
# define hp_sg_addr 0x28
# define hp_page_ctrl 0x29
# 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 */
# define hp_pci_stat_cfg 0x2D
# define REC_MASTER_ABORT BIT(5) /*received Master abort */
# define hp_rev_num 0x33
# define hp_stack_data 0x34
# define hp_stack_addr 0x35
# define hp_ext_status 0x36
# 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 | \
BM_PARITY_ERR | PIO_OVERRUN )
# 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
# define RESET BITW(7)
# define PROG_HLT BITW(6)
# define PARITY BITW(5)
# define FIFO BITW(4)
# define SEL BITW(3)
# define SCAM_SEL BITW(2)
# define RSEL BITW(1)
# define TIMEOUT BITW(0)
# define BUS_FREE BITW(15)
# define XFER_CNT_0 BITW(14)
# define PHASE BITW(13)
# define IUNKWN BITW(12)
# define ICMD_COMP BITW(11)
# define ITICKLE BITW(10)
# define IDO_STRT BITW(9)
# define ITAR_DISC BITW(8)
# define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
# 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)
# define hp_portctrl_0 0x46
# 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)
# define hp_scsireset 0x47
# 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)
# define hp_xfercnt_0 0x48
# define hp_xfercnt_2 0x4A
# define hp_fifodata_0 0x4C
# define hp_addstat 0x4E
# define SCAM_TIMER BIT(7)
# define SCSI_MODE8 BIT(3)
# define SCSI_PAR_ERR BIT(0)
# define hp_prgmcnt_0 0x4F
# define hp_selfid_0 0x50
# define hp_selfid_1 0x51
# define hp_arb_id 0x52
# define hp_select_id 0x53
# 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
# define hp_synctarg_8 0x58
# define hp_synctarg_9 0x59
# define hp_synctarg_10 0x5A
# define hp_synctarg_11 0x5B
# define hp_synctarg_4 0x5C
# define hp_synctarg_5 0x5D
# define hp_synctarg_6 0x5E
# define hp_synctarg_7 0x5F
# define hp_synctarg_0 0x60
# define hp_synctarg_1 0x61
# define hp_synctarg_2 0x62
# define hp_synctarg_3 0x63
# define NARROW_SCSI BIT(4)
# define DEFAULT_OFFSET 0x0F
# define hp_autostart_0 0x64
# define hp_autostart_1 0x65
# define hp_autostart_3 0x67
# define AUTO_IMMED BIT(5)
# define SELECT BIT(6)
# define END_DATA (BIT(7)+BIT(6))
# define hp_gp_reg_0 0x68
# define hp_gp_reg_1 0x69
# define hp_gp_reg_3 0x6B
# define hp_seltimeout 0x6C
# define TO_4ms 0x67 /* 3.9959ms */
# define TO_5ms 0x03 /* 4.9152ms */
# define TO_10ms 0x07 /* 11.xxxms */
# define TO_250ms 0x99 /* 250.68ms */
# define TO_290ms 0xB1 /* 289.99ms */
# define hp_clkctrl_0 0x6D
# define PWR_DWN BIT(6)
# define ACTdeassert BIT(4)
# define CLK_40MHZ (BIT(1) + BIT(0))
# define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
# define hp_fiforead 0x6E
# define hp_fifowrite 0x6F
# define hp_offsetctr 0x70
# define hp_xferstat 0x71
# define FIFO_EMPTY BIT(6)
# define hp_portctrl_1 0x72
# define CHK_SCSI_P BIT(3)
# define HOST_MODE8 BIT(0)
# define hp_xfer_pad 0x73
# define ID_UNLOCK BIT(3)
# define hp_scsidata_0 0x74
# define hp_scsidata_1 0x75
# define hp_aramBase 0x80
# define BIOS_DATA_OFFSET 0x60
# define BIOS_RELATIVE_CARD 0x64
# define AR3 (BITW(9) + BITW(8))
# define SDATA BITW(10)
# define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
# define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
# define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
# define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
# define ADATA_OUT 0x00
# define ADATA_IN BITW(8)
# define ACOMMAND BITW(10)
# define ASTATUS (BITW(10)+BITW(8))
# define AMSG_OUT (BITW(10)+BITW(9))
# define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
# define BRH_OP BITW(13) /* Branch */
# define ALWAYS 0x00
# define EQUAL BITW(8)
# define NOT_EQ BITW(9)
# define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
# define FIFO_0 BITW(10)
# define MPM_OP BITW(15) /* Match phase and move data */
# define MRR_OP BITW(14) /* Move DReg. to Reg. */
# define S_IDREG (BIT(2)+BIT(1)+BIT(0))
# define D_AR0 0x00
# define D_AR1 BIT(0)
# define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
# define RAT_OP (BITW(14)+BITW(13)+BITW(11))
# define SSI_OP (BITW(15)+BITW(11))
# define SSI_ITAR_DISC (ITAR_DISC >> 8)
# define SSI_IDO_STRT (IDO_STRT >> 8)
# define SSI_ICMD_COMP (ICMD_COMP >> 8)
# define SSI_ITICKLE (ITICKLE >> 8)
# define SSI_IUNKWN (IUNKWN >> 8)
# define SSI_INO_CC (IUNKWN >> 8)
# define SSI_IRFAIL (IUNKWN >> 8)
# 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 */
# 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
# 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
# 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:26 +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 , PSCCBcard pCurrCard ) ;
2006-03-08 11:14:29 +03:00
static void FPT_shandem ( unsigned long port , unsigned char p_card , struct sccb * pCurrSCCB ) ;
2006-03-08 11:14:26 +03:00
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 ,
2005-04-24 11:38:05 +04:00
PSCCBMgr_tar_info currTar_Info ) ;
2006-03-08 11:14:26 +03:00
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 ) ;
static unsigned char FPT_RdStack ( unsigned long port , unsigned char index ) ;
static void FPT_WrStack ( unsigned long portBase , unsigned char index , unsigned char data ) ;
static unsigned char FPT_ChkIfChipInitialized ( unsigned long ioPort ) ;
static void FPT_SendMsg ( unsigned long port , unsigned char message ) ;
2006-03-08 11:14:24 +03:00
static void FPT_queueFlushTargSccb ( unsigned char p_card , unsigned char thisTarg ,
unsigned char error_code ) ;
2006-03-08 11:14:29 +03:00
static void FPT_sinits ( struct sccb * p_sccb , unsigned char p_card ) ;
2005-04-24 11:38:05 +04:00
static void FPT_RNVRamData ( PNVRamInfo 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 ) ;
static void FPT_stwidn ( unsigned long port , unsigned char p_card ) ;
static void FPT_siwidr ( unsigned long port , unsigned char width ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
static void FPT_queueSelectFail ( PSCCBcard pCurrCard , unsigned char p_card ) ;
2006-03-08 11:14:29 +03:00
static void FPT_queueDisconnect ( struct sccb * p_SCCB , unsigned char p_card ) ;
static void FPT_queueCmdComplete ( PSCCBcard pCurrCard , struct sccb * p_SCCB ,
2006-03-08 11:14:24 +03:00
unsigned char p_card ) ;
static void FPT_queueSearchSelect ( PSCCBcard pCurrCard , unsigned char p_card ) ;
static void FPT_queueFlushSccb ( unsigned char p_card , unsigned char error_code ) ;
2006-03-08 11:14:29 +03:00
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:24 +03:00
static unsigned char FPT_CalcLrc ( unsigned char buffer [ ] ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
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 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
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 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
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 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
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 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
static void FPT_dataXferProcessor ( unsigned long port , PSCCBcard pCurrCard ) ;
2006-03-08 11:14:29 +03:00
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 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
static unsigned char FPT_SccbMgr_bad_isr ( unsigned long p_port , unsigned char p_card ,
2006-03-08 11:14:25 +03:00
PSCCBcard pCurrCard , unsigned short p_int ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
static void FPT_SccbMgrTableInitAll ( void ) ;
2006-03-08 11:14:24 +03:00
static void FPT_SccbMgrTableInitCard ( PSCCBcard pCurrCard , unsigned char p_card ) ;
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
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:26 +03:00
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 ) ;
static unsigned char FPT_scxferc ( unsigned long p_port , unsigned char p_data ) ;
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 ) ;
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 ) ;
2006-03-08 11:14:24 +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:26 +03:00
static void FPT_autoCmdCmplt ( unsigned long p_port , unsigned char p_card ) ;
static void FPT_autoLoadDefaultMap ( unsigned long p_port ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
static SCCBMGR_TAR_INFO FPT_sccbMgrTbl [ MAX_CARDS ] [ MAX_SCSI_TAR ] = { { { 0 } } } ;
static SCCBCARD FPT_BL_Card [ MAX_CARDS ] = { { 0 } } ;
static SCCBSCAM_INFO FPT_scamInfo [ MAX_SCSI_TAR ] = { { { 0 } } } ;
static NVRAMINFO 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 ;
static unsigned char FPT_scamHAString [ ] = { 0x63 , 0x07 , ' B ' , ' U ' , ' S ' , ' L ' , ' O ' , ' G ' , ' I ' , ' C ' , \
2005-04-24 11:38:05 +04:00
' ' , ' 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:26 +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:30 +03:00
static int FlashPoint_ProbeHostAdapter ( struct sccb_mgr_info * pCardInfo )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
static unsigned char first_time = 1 ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
unsigned char i , j , id , ScamFlg ;
2006-03-08 11:14:25 +03:00
unsigned short temp , temp2 , temp3 , temp4 , temp5 , temp6 ;
2006-03-08 11:14:26 +03:00
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
PNVRamInfo pCurrNvRam ;
ioport = pCardInfo - > si_baseaddr ;
if ( RD_HARPOON ( ioport + hp_vendor_id_0 ) ! = ORION_VEND_0 )
return ( ( int ) FAILURE ) ;
if ( ( RD_HARPOON ( ioport + hp_vendor_id_1 ) ! = ORION_VEND_1 ) )
return ( ( int ) FAILURE ) ;
if ( ( RD_HARPOON ( ioport + hp_device_id_0 ) ! = ORION_DEV_0 ) )
return ( ( int ) FAILURE ) ;
if ( ( RD_HARPOON ( ioport + hp_device_id_1 ) ! = ORION_DEV_1 ) )
return ( ( int ) FAILURE ) ;
if ( RD_HARPOON ( ioport + hp_rev_num ) ! = 0x0f ) {
/* 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 . */
if ( RD_HARPOON ( ioport + hp_sub_device_id_0 ) & 0x0f )
return ( ( int ) FAILURE ) ;
}
if ( first_time )
{
2005-04-24 11:38:05 +04:00
FPT_SccbMgrTableInitAll ( ) ;
2005-04-17 02:20:36 +04:00
first_time = 0 ;
2005-04-24 11:38:05 +04:00
FPT_mbCards = 0 ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( FPT_RdStack ( ioport , 0 ) ! = 0x00 ) {
if ( FPT_ChkIfChipInitialized ( ioport ) = = 0 )
2005-04-17 02:20:36 +04:00
{
pCurrNvRam = NULL ;
WR_HARPOON ( ioport + hp_semaphore , 0x00 ) ;
2005-04-24 11:38:05 +04:00
FPT_XbowInit ( ioport , 0 ) ; /*Must Init the SCSI before attempting */
FPT_DiagEEPROM ( ioport ) ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
if ( FPT_mbCards < MAX_MB_CARDS ) {
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 ) ;
2005-04-17 02:20:36 +04:00
} else
return ( ( int ) FAILURE ) ;
}
} else
pCurrNvRam = NULL ;
WR_HARPOON ( ioport + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( ioport + hp_sys_ctrl , 0x00 ) ;
if ( pCurrNvRam )
pCardInfo - > si_id = pCurrNvRam - > niAdapId ;
else
2006-03-08 11:14:24 +03:00
pCardInfo - > si_id = ( unsigned char ) ( FPT_utilEERead ( ioport , ( ADAPTER_SCSI_ID / 2 ) ) &
( unsigned char ) 0x0FF ) ;
2005-04-17 02:20:36 +04:00
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 ) {
2006-03-08 11:14:25 +03:00
temp = ( unsigned short ) pCurrNvRam - > niSyncTbl [ id ] ;
2005-04-17 02:20:36 +04:00
temp = ( ( temp & 0x03 ) + ( ( temp < < 4 ) & 0xc0 ) ) +
( ( ( temp < < 4 ) & 0x0300 ) + ( ( temp < < 8 ) & 0xc000 ) ) ;
} else
2006-03-08 11:14:25 +03:00
temp = FPT_utilEERead ( ioport , ( unsigned short ) ( ( SYNC_RATE_TBL / 2 ) + id ) ) ;
2005-04-17 02:20:36 +04:00
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 ;
}
if ( temp & DISC_ENABLE_BIT )
temp3 | = 0x8000 ;
if ( temp & WIDE_NEGO_BIT )
temp4 | = 0x8000 ;
}
}
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 ;
if ( pCurrNvRam )
i = pCurrNvRam - > niSysConf ;
else
2006-03-08 11:14:24 +03:00
i = ( unsigned char ) ( FPT_utilEERead ( ioport , ( SYSTEM_CONFIG / 2 ) ) ) ;
2005-04-17 02:20:36 +04:00
if ( pCurrNvRam )
ScamFlg = pCurrNvRam - > niScamConf ;
else
2006-03-08 11:14:24 +03:00
ScamFlg = ( unsigned char ) FPT_utilEERead ( ioport , SCAM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
pCardInfo - > si_flags = 0x0000 ;
if ( i & 0x01 )
pCardInfo - > si_flags | = SCSI_PARITY_ENA ;
if ( ! ( i & 0x02 ) )
pCardInfo - > si_flags | = SOFT_RESET ;
if ( i & 0x10 )
pCardInfo - > si_flags | = EXTENDED_TRANSLATION ;
if ( ScamFlg & SCAM_ENABLED )
pCardInfo - > si_flags | = FLAG_SCAM_ENABLED ;
if ( ScamFlg & SCAM_LEVEL2 )
pCardInfo - > si_flags | = FLAG_SCAM_LEVEL2 ;
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 ) ;
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 {
2005-04-24 11:38:05 +04:00
temp = FPT_utilEERead ( ioport , ( MODEL_NUMB_0 / 2 ) ) ;
2006-03-08 11:14:24 +03:00
pCardInfo - > si_card_model [ 0 ] = ( unsigned char ) ( temp > > 8 ) ;
2005-04-24 11:38:05 +04:00
temp = FPT_utilEERead ( ioport , ( MODEL_NUMB_2 / 2 ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +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
}
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 ;
}
ARAM_ACCESS ( ioport ) ;
for ( i = 0 ; i < 4 ; i + + ) {
pCardInfo - > si_XlatInfo [ i ] =
RD_HARPOON ( ioport + hp_aramBase + BIOS_DATA_OFFSET + i ) ;
}
/* 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:24 +03:00
( unsigned char ) ( RD_HARPOON ( ioport + hp_aramBase + BIOS_RELATIVE_CARD ) - 1 ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( ioport ) ;
2005-04-24 11:38:05 +04: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
pCardInfo - > si_present = 0x01 ;
return ( 0 ) ;
}
/*---------------------------------------------------------------------
*
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:30 +03:00
static unsigned long FlashPoint_HardwareResetHostAdapter ( struct sccb_mgr_info * pCardInfo )
2005-04-17 02:20:36 +04:00
{
PSCCBcard CurrCard = NULL ;
PNVRamInfo pCurrNvRam ;
2006-03-08 11:14:24 +03:00
unsigned char i , j , thisCard , ScamFlg ;
2006-03-08 11:14:25 +03:00
unsigned short temp , sync_bit_map , id ;
2006-03-08 11:14:26 +03:00
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
ioport = pCardInfo - > si_baseaddr ;
for ( thisCard = 0 ; thisCard < = MAX_CARDS ; thisCard + + ) {
if ( thisCard = = MAX_CARDS ) {
return ( FAILURE ) ;
}
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ thisCard ] . ioPort = = ioport ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
CurrCard = & FPT_BL_Card [ thisCard ] ;
FPT_SccbMgrTableInitCard ( CurrCard , thisCard ) ;
2005-04-17 02:20:36 +04:00
break ;
}
2005-04-24 11:38:05 +04:00
else if ( FPT_BL_Card [ thisCard ] . ioPort = = 0x00 ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ thisCard ] . ioPort = ioport ;
CurrCard = & FPT_BL_Card [ thisCard ] ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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
}
2005-04-24 11:38:05 +04:00
FPT_SccbMgrTableInitCard ( CurrCard , thisCard ) ;
2005-04-17 02:20:36 +04:00
CurrCard - > cardIndex = thisCard ;
CurrCard - > cardInfo = pCardInfo ;
break ;
}
}
pCurrNvRam = CurrCard - > pNvRamInfo ;
if ( pCurrNvRam ) {
ScamFlg = pCurrNvRam - > niScamConf ;
}
else {
2006-03-08 11:14:24 +03:00
ScamFlg = ( unsigned char ) FPT_utilEERead ( ioport , SCAM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_BusMasterInit ( ioport ) ;
FPT_XbowInit ( ioport , ScamFlg ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_autoLoadDefaultMap ( ioport ) ;
2005-04-17 02:20:36 +04:00
for ( i = 0 , id = 0x01 ; i ! = pCardInfo - > si_id ; i + + , id < < = 1 ) { }
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 ;
2006-03-08 11:14:24 +03:00
i = ( unsigned char ) pCardInfo - > si_flags ;
2005-04-17 02:20:36 +04:00
if ( i & SCSI_PARITY_ENA )
WR_HARPOON ( ioport + hp_portctrl_1 , ( HOST_MODE8 | CHK_SCSI_P ) ) ;
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 ) ;
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 ) ;
if ( ! ( pCardInfo - > si_flags & SOFT_RESET ) ) {
2005-04-24 11:38:05 +04:00
FPT_sresb ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_scini ( thisCard , pCardInfo - > si_id , 0 ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( pCardInfo - > si_flags & POST_ALL_UNDERRRUNS )
CurrCard - > globalFlags | = F_NO_FILTER ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( pCurrNvRam ) {
if ( pCurrNvRam - > niSysConf & 0x10 )
CurrCard - > globalFlags | = F_GREEN_PC ;
}
else {
if ( FPT_utilEERead ( ioport , ( SYSTEM_CONFIG / 2 ) ) & GREEN_PC_ENA )
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
ckeck condition */
if ( pCurrNvRam ) {
if ( pCurrNvRam - > niScsiConf & 0x04 )
CurrCard - > globalFlags | = F_DO_RENEGO ;
}
else {
if ( FPT_utilEERead ( ioport , ( SCSI_CONFIG / 2 ) ) & RENEGO_ENA )
CurrCard - > globalFlags | = F_DO_RENEGO ;
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( pCurrNvRam ) {
if ( pCurrNvRam - > niScsiConf & 0x08 )
CurrCard - > globalFlags | = F_CONLUN_IO ;
}
else {
if ( FPT_utilEERead ( ioport , ( SCSI_CONFIG / 2 ) ) & CONNIO_ENA )
CurrCard - > globalFlags | = F_CONLUN_IO ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
temp = pCardInfo - > si_per_targ_no_disc ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
for ( i = 0 , id = 1 ; i < MAX_SCSI_TAR ; i + + , id < < = 1 ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( temp & id )
FPT_sccbMgrTbl [ thisCard ] [ i ] . TarStatus | = TAR_ALLOW_DISC ;
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
sync_bit_map = 0x0001 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
for ( id = 0 ; id < ( MAX_SCSI_TAR / 2 ) ; id + + ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( pCurrNvRam ) {
2006-03-08 11:14:25 +03:00
temp = ( unsigned short ) pCurrNvRam - > niSyncTbl [ id ] ;
2005-04-24 11:38:05 +04:00
temp = ( ( temp & 0x03 ) + ( ( temp < < 4 ) & 0xc0 ) ) +
( ( ( temp < < 4 ) & 0x0300 ) + ( ( temp < < 8 ) & 0xc000 ) ) ;
} else
2006-03-08 11:14:25 +03:00
temp = FPT_utilEERead ( ioport , ( unsigned short ) ( ( SYNC_RATE_TBL / 2 ) + id ) ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
for ( i = 0 ; i < 2 ; temp > > = 8 , i + + ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( pCardInfo - > si_per_targ_init_sync & sync_bit_map ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
FPT_sccbMgrTbl [ thisCard ] [ id * 2 + i ] . TarEEValue = ( unsigned char ) temp ;
2005-04-24 11:38:05 +04:00
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
else {
FPT_sccbMgrTbl [ thisCard ] [ id * 2 + i ] . TarStatus | = SYNC_SUPPORTED ;
FPT_sccbMgrTbl [ thisCard ] [ id * 2 + i ] . TarEEValue =
2006-03-08 11:14:24 +03:00
( unsigned char ) ( temp & ~ EE_SYNC_MASK ) ;
2005-04-24 11:38:05 +04:00
}
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 ) ) {
*/
if ( pCardInfo - > si_per_targ_wide_nego & sync_bit_map ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ thisCard ] [ id * 2 + i ] . TarEEValue | = EE_WIDE_SCSI ;
2005-04-17 02:20:36 +04: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
else { /* NARROW SCSI */
FPT_sccbMgrTbl [ thisCard ] [ id * 2 + i ] . TarStatus | = WIDE_NEGOCIATED ;
}
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
sync_bit_map < < = 1 ;
2005-04-17 02:20:36 +04: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
WR_HARPOON ( ( ioport + hp_semaphore ) ,
2006-03-08 11:14:24 +03:00
( unsigned char ) ( RD_HARPOON ( ( ioport + hp_semaphore ) ) | SCCB_MGR_PRESENT ) ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +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 ;
2005-04-17 02:20:36 +04:00
PNVRamInfo pCurrNvRam ;
pCurrNvRam = ( ( PSCCBcard ) pCurrCard ) - > pNvRamInfo ;
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
for ( i = 0 ; i < MAX_SCSI_TAR / 2 ; i + + )
2006-03-08 11:14:24 +03:00
FPT_WrStack ( pCurrNvRam - > niBaseAddr , ( unsigned char ) ( i + 5 ) , pCurrNvRam - > niSyncTbl [ i ] ) ;
2005-04-17 02:20:36 +04:00
portBase = pCurrNvRam - > niBaseAddr ;
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
regOffset = hp_aramBase + 64 + i * 4 ;
2006-03-08 11:14:26 +03:00
pScamTbl = ( unsigned long * ) & pCurrNvRam - > niScamTbl [ i ] ;
2005-04-17 02:20:36 +04:00
scamData = * pScamTbl ;
WR_HARP32 ( portBase , regOffset , scamData ) ;
}
} else {
2005-04-24 11:38:05 +04:00
FPT_WrStack ( ( ( PSCCBcard ) pCurrCard ) - > ioPort , 0 , 0 ) ;
2005-04-17 02:20:36 +04:00
}
}
2005-04-24 11:38:05 +04:00
static void FPT_RNVRamData ( PNVRamInfo 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
2005-04-24 11:38:05 +04:00
pNvRamInfo - > niModel = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 0 ) ;
pNvRamInfo - > niSysConf = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 1 ) ;
pNvRamInfo - > niScsiConf = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 2 ) ;
pNvRamInfo - > niScamConf = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 3 ) ;
pNvRamInfo - > niAdapId = FPT_RdStack ( pNvRamInfo - > niBaseAddr , 4 ) ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < MAX_SCSI_TAR / 2 ; i + + )
2006-03-08 11:14:24 +03:00
pNvRamInfo - > niSyncTbl [ i ] = FPT_RdStack ( pNvRamInfo - > niBaseAddr , ( unsigned char ) ( i + 5 ) ) ;
2005-04-17 02:20:36 +04:00
portBase = pNvRamInfo - > niBaseAddr ;
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
regOffset = hp_aramBase + 64 + i * 4 ;
RD_HARP32 ( portBase , regOffset , scamData ) ;
2006-03-08 11:14:26 +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 ) ;
return ( RD_HARPOON ( portBase + hp_stack_data ) ) ;
}
2006-03-08 11:14:26 +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
{
2005-04-24 11:38:05 +04:00
if ( ( RD_HARPOON ( ioPort + hp_arb_id ) & 0x0f ) ! = FPT_RdStack ( ioPort , 4 ) )
return ( 0 ) ;
2005-04-17 02:20:36 +04:00
if ( ( RD_HARPOON ( ioPort + hp_clkctrl_0 ) & CLKCTRL_DEFAULT )
! = CLKCTRL_DEFAULT )
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
2005-04-17 02:20:36 +04:00
if ( ( RD_HARPOON ( ioPort + hp_seltimeout ) = = TO_250ms ) | |
( RD_HARPOON ( ioPort + hp_seltimeout ) = = TO_290ms ) )
2005-04-24 11:38:05 +04:00
return ( 1 ) ;
return ( 0 ) ;
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:29 +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:26 +03:00
unsigned long ioport ;
2006-03-08 11:14:24 +03:00
unsigned char thisCard , lun ;
2006-03-08 11:14:29 +03:00
struct sccb * pSaveSccb ;
2005-04-17 02:20:36 +04:00
CALL_BK_FN callback ;
thisCard = ( ( PSCCBcard ) pCurrCard ) - > cardIndex ;
ioport = ( ( PSCCBcard ) pCurrCard ) - > ioPort ;
if ( ( p_Sccb - > TargID > MAX_SCSI_TAR ) | | ( p_Sccb - > Lun > MAX_LUN ) )
{
p_Sccb - > HostStatus = SCCB_COMPLETE ;
p_Sccb - > SccbStatus = SCCB_ERROR ;
callback = ( CALL_BK_FN ) p_Sccb - > SccbCallback ;
if ( callback )
callback ( p_Sccb ) ;
return ;
}
2005-04-24 11:38:05 +04:00
FPT_sinits ( p_Sccb , thisCard ) ;
2005-04-17 02:20:36 +04:00
if ( ! ( ( PSCCBcard ) pCurrCard ) - > cmdCounter )
{
WR_HARPOON ( ioport + hp_semaphore , ( RD_HARPOON ( ioport + hp_semaphore )
| SCCB_MGR_ACTIVE ) ) ;
if ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_GREEN_PC )
{
WR_HARPOON ( ioport + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( ioport + hp_sys_ctrl , 0x00 ) ;
}
}
( ( PSCCBcard ) 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 = ( ( PSCCBcard ) pCurrCard ) - > currentSCCB ;
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = p_Sccb ;
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
2005-04-17 02:20:36 +04:00
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = pSaveSccb ;
}
else
{
2005-04-24 11:38:05 +04:00
FPT_queueAddSccb ( p_Sccb , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
}
else if ( ( RD_HARPOON ( ioport + hp_page_ctrl ) & G_INT_DISABLE ) ) {
if ( p_Sccb - > OperationCode = = RESET_COMMAND )
{
pSaveSccb = ( ( PSCCBcard ) pCurrCard ) - > currentSCCB ;
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = p_Sccb ;
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
2005-04-17 02:20:36 +04:00
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = pSaveSccb ;
}
else
{
2005-04-24 11:38:05 +04:00
FPT_queueAddSccb ( p_Sccb , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
}
else {
MDISABLE_INT ( ioport ) ;
if ( ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_CONLUN_IO ) & &
2005-04-24 11:38:05 +04:00
( ( 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 ;
if ( ( ( ( PSCCBcard ) pCurrCard ) - > currentSCCB = = NULL ) & &
2005-04-24 11:38:05 +04:00
( 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
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = p_Sccb ;
2005-04-24 11:38:05 +04:00
FPT_ssel ( p_Sccb - > SccbIOPort , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else {
if ( p_Sccb - > OperationCode = = RESET_COMMAND )
{
pSaveSccb = ( ( PSCCBcard ) pCurrCard ) - > currentSCCB ;
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = p_Sccb ;
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
2005-04-17 02:20:36 +04:00
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = pSaveSccb ;
}
else
{
2005-04-24 11:38:05 +04:00
FPT_queueAddSccb ( p_Sccb , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
}
MENABLE_INT ( ioport ) ;
}
}
/*---------------------------------------------------------------------
*
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:29 +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:29 +03:00
struct sccb * pSaveSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
ioport = ( ( PSCCBcard ) pCurrCard ) - > ioPort ;
thisCard = ( ( PSCCBcard ) pCurrCard ) - > cardIndex ;
2005-04-24 11:38:05 +04:00
if ( ! ( RD_HARPOON ( ioport + hp_page_ctrl ) & G_INT_DISABLE ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
if ( FPT_queueFindSccb ( p_Sccb , thisCard ) )
2005-04-17 02:20:36 +04:00
{
( ( PSCCBcard ) pCurrCard ) - > cmdCounter - - ;
if ( ! ( ( PSCCBcard ) pCurrCard ) - > cmdCounter )
WR_HARPOON ( ioport + hp_semaphore , ( RD_HARPOON ( ioport + hp_semaphore )
2006-03-08 11:14:24 +03:00
& ( 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 ) ;
return ( 0 ) ;
}
else
{
if ( ( ( PSCCBcard ) pCurrCard ) - > currentSCCB = = p_Sccb )
{
p_Sccb - > SccbStatus = SCCB_ABORT ;
return ( 0 ) ;
}
else
{
TID = p_Sccb - > TargID ;
if ( p_Sccb - > Sccb_tag )
{
MDISABLE_INT ( ioport ) ;
if ( ( ( PSCCBcard ) pCurrCard ) - > discQ_Tbl [ p_Sccb - > Sccb_tag ] = = p_Sccb )
{
p_Sccb - > SccbStatus = SCCB_ABORT ;
p_Sccb - > Sccb_scsistat = ABORT_ST ;
p_Sccb - > Sccb_scsimsg = SMABORT_TAG ;
if ( ( ( PSCCBcard ) pCurrCard ) - > currentSCCB = = NULL )
{
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = p_Sccb ;
2005-04-24 11:38:05 +04:00
FPT_ssel ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else
{
pSaveSCCB = ( ( PSCCBcard ) pCurrCard ) - > currentSCCB ;
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = p_Sccb ;
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( ( PSCCBcard ) pCurrCard , thisCard ) ;
2005-04-17 02:20:36 +04:00
( ( PSCCBcard ) pCurrCard ) - > currentSCCB = pSaveSCCB ;
}
}
MENABLE_INT ( ioport ) ;
return ( 0 ) ;
}
else
{
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ thisCard ] [ p_Sccb - > TargID ] ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ thisCard ] . discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ p_Sccb - > Lun ] ]
2005-04-17 02:20:36 +04:00
= = p_Sccb )
{
p_Sccb - > SccbStatus = SCCB_ABORT ;
return ( 0 ) ;
}
}
}
}
}
return ( - 1 ) ;
}
/*---------------------------------------------------------------------
*
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:26 +03:00
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
ioport = ( ( PSCCBcard ) pCurrCard ) - > ioPort ;
if ( RD_HARPOON ( ioport + hp_int_status ) & INT_ASSERTED )
{
2005-04-24 11:38:05 +04:00
return ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
else
2005-04-24 11:38:05 +04: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:29 +03:00
struct sccb * currSCCB ;
2006-03-08 11:14:24 +03:00
unsigned char thisCard , result , bm_status , bm_int_st ;
2006-03-08 11:14:25 +03:00
unsigned short hp_int ;
2006-03-08 11:14:24 +03:00
unsigned char i , target ;
2006-03-08 11:14:26 +03:00
unsigned long ioport ;
2005-04-17 02:20:36 +04:00
thisCard = ( ( PSCCBcard ) pCurrCard ) - > cardIndex ;
ioport = ( ( PSCCBcard ) pCurrCard ) - > ioPort ;
MDISABLE_INT ( ioport ) ;
if ( ( bm_int_st = RD_HARPOON ( ioport + hp_int_status ) ) & EXT_STATUS_ON )
2006-03-08 11:14:24 +03:00
bm_status = RD_HARPOON ( ioport + hp_ext_status ) & ( unsigned char ) BAD_EXT_STATUS ;
2005-04-17 02:20:36 +04:00
else
bm_status = 0 ;
WR_HARPOON ( ioport + hp_int_mask , ( INT_CMD_COMPL | SCSI_INTERRUPT ) ) ;
2005-04-24 11:38:05 +04:00
while ( ( hp_int = RDW_HARPOON ( ( ioport + hp_intstat ) ) & FPT_default_intena ) |
2005-04-17 02:20:36 +04:00
bm_status )
{
currSCCB = ( ( PSCCBcard ) pCurrCard ) - > currentSCCB ;
if ( hp_int & ( FIFO | TIMEOUT | RESET | SCAM_SEL ) | | bm_status ) {
2005-04-24 11:38:05 +04:00
result = FPT_SccbMgr_bad_isr ( ioport , thisCard , ( ( PSCCBcard ) pCurrCard ) , hp_int ) ;
2005-04-17 02:20:36 +04:00
WRW_HARPOON ( ( ioport + hp_intstat ) , ( FIFO | TIMEOUT | RESET | SCAM_SEL ) ) ;
bm_status = 0 ;
if ( result ) {
MENABLE_INT ( ioport ) ;
return ( result ) ;
}
}
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 ) ) ) ;
}
if ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_HOST_XFER_ACT )
2005-04-24 11:38:05 +04: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 ) ) ;
*/
WRW_HARPOON ( ( ioport + hp_intstat ) , CLR_ALL_INT_1 ) ;
2005-04-24 11:38:05 +04:00
FPT_autoCmdCmplt ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else if ( hp_int & ITAR_DISC )
{
if ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_HOST_XFER_ACT ) {
2005-04-24 11:38:05 +04:00
FPT_phaseChkFifo ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04: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 ;
}
currSCCB - > Sccb_scsistat = DISCONNECT_ST ;
2005-04-24 11:38:05 +04:00
FPT_queueDisconnect ( currSCCB , thisCard ) ;
2005-04-17 02:20:36 +04:00
/* 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 ;
}
WRW_HARPOON ( ( ioport + hp_intstat ) , ( BUS_FREE | ITAR_DISC ) ) ;
( ( PSCCBcard ) pCurrCard ) - > globalFlags | = F_NEW_SCCB_CMD ;
}
else if ( hp_int & RSEL ) {
WRW_HARPOON ( ( ioport + hp_intstat ) , ( PROG_HLT | RSEL | PHASE | BUS_FREE ) ) ;
if ( RDW_HARPOON ( ( ioport + hp_intstat ) ) & ITAR_DISC )
{
if ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_HOST_XFER_ACT )
{
2005-04-24 11:38:05 +04:00
FPT_phaseChkFifo ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04: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 ;
}
WRW_HARPOON ( ( ioport + hp_intstat ) , ( BUS_FREE | ITAR_DISC ) ) ;
currSCCB - > Sccb_scsistat = DISCONNECT_ST ;
2005-04-24 11:38:05 +04:00
FPT_queueDisconnect ( currSCCB , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_sres ( ioport , thisCard , ( ( PSCCBcard ) pCurrCard ) ) ;
FPT_phaseDecode ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else if ( ( hp_int & IDO_STRT ) & & ( ! ( hp_int & BUS_FREE ) ) )
{
WRW_HARPOON ( ( ioport + hp_intstat ) , ( IDO_STRT | XFER_CNT_0 ) ) ;
2005-04-24 11:38:05 +04:00
FPT_phaseDecode ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else if ( ( hp_int & IUNKWN ) | | ( hp_int & PROG_HLT ) )
{
WRW_HARPOON ( ( ioport + hp_intstat ) , ( PHASE | IUNKWN | PROG_HLT ) ) ;
2006-03-08 11:14:24 +03:00
if ( ( RD_HARPOON ( ioport + hp_prgmcnt_0 ) & ( unsigned char ) 0x3f ) < ( unsigned char ) SELCHK )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_phaseDecode ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
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 */
2006-03-08 11:14:24 +03:00
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 ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( ioport + hp_fifowrite , i ) ;
WR_HARPOON ( ioport + hp_autostart_3 , ( AUTO_IMMED + TAG_STRT ) ) ;
}
}
else if ( hp_int & XFER_CNT_0 ) {
WRW_HARPOON ( ( ioport + hp_intstat ) , XFER_CNT_0 ) ;
2005-04-24 11:38:05 +04:00
FPT_schkdd ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else if ( hp_int & BUS_FREE ) {
WRW_HARPOON ( ( ioport + hp_intstat ) , BUS_FREE ) ;
if ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_HOST_XFER_ACT ) {
2005-04-24 11:38:05 +04:00
FPT_hostDataXferAbort ( ioport , thisCard , currSCCB ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_phaseBusFree ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
else if ( hp_int & ITICKLE ) {
WRW_HARPOON ( ( ioport + hp_intstat ) , ITICKLE ) ;
( ( PSCCBcard ) pCurrCard ) - > globalFlags | = F_NEW_SCCB_CMD ;
}
if ( ( ( PSCCBcard ) pCurrCard ) - > globalFlags & F_NEW_SCCB_CMD ) {
( ( PSCCBcard ) pCurrCard ) - > globalFlags & = ~ F_NEW_SCCB_CMD ;
if ( ( ( PSCCBcard ) pCurrCard ) - > currentSCCB = = NULL ) {
2005-04-24 11:38:05 +04:00
FPT_queueSearchSelect ( ( ( PSCCBcard ) pCurrCard ) , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
if ( ( ( PSCCBcard ) pCurrCard ) - > currentSCCB ! = NULL ) {
( ( PSCCBcard ) pCurrCard ) - > globalFlags & = ~ F_NEW_SCCB_CMD ;
2005-04-24 11:38:05 +04:00
FPT_ssel ( ioport , thisCard ) ;
2005-04-17 02:20:36 +04:00
}
break ;
}
} /*end while */
MENABLE_INT ( ioport ) ;
return ( 0 ) ;
}
/*---------------------------------------------------------------------
*
* 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:26 +03:00
static unsigned char FPT_SccbMgr_bad_isr ( unsigned long p_port , unsigned char p_card ,
2006-03-08 11:14:25 +03:00
PSCCBcard pCurrCard , unsigned short p_int )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char temp , ScamFlg ;
2005-04-24 11:38:05 +04:00
PSCCBMgr_tar_info currTar_Info ;
PNVRamInfo pCurrNvRam ;
2005-04-17 02:20:36 +04:00
if ( RD_HARPOON ( p_port + hp_ext_status ) &
( BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN ) )
{
if ( pCurrCard - > globalFlags & F_HOST_XFER_ACT )
{
2005-04-24 11:38:05 +04:00
FPT_hostDataXferAbort ( p_port , p_card , pCurrCard - > currentSCCB ) ;
2005-04-17 02:20:36 +04: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 ) ) ;
WR_HARPOON ( p_port + hp_host_blk_cnt , 0x00 ) ;
}
if ( pCurrCard - > currentSCCB ! = NULL )
{
if ( ! pCurrCard - > currentSCCB - > HostStatus )
pCurrCard - > currentSCCB - > HostStatus = SCCB_BM_ERR ;
2005-04-24 11:38:05 +04:00
FPT_sxfrp ( p_port , p_card ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
temp = ( unsigned char ) ( RD_HARPOON ( p_port + hp_ee_ctrl ) &
2005-04-17 02:20:36 +04:00
( EXT_ARB_ACK | SCSI_TERM_ENA_H ) ) ;
2006-03-08 11:14:24 +03:00
WR_HARPOON ( p_port + hp_ee_ctrl , ( ( unsigned char ) temp | SEE_MS | SEE_CS ) ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_ee_ctrl , temp ) ;
if ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) )
{
2005-04-24 11:38:05 +04:00
FPT_phaseDecode ( p_port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
}
else if ( p_int & RESET )
{
WR_HARPOON ( p_port + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( p_port + hp_sys_ctrl , 0x00 ) ;
if ( pCurrCard - > currentSCCB ! = NULL ) {
if ( pCurrCard - > globalFlags & F_HOST_XFER_ACT )
2005-04-24 11:38:05 +04:00
FPT_hostDataXferAbort ( p_port , p_card , pCurrCard - > currentSCCB ) ;
2005-04-17 02:20:36 +04:00
}
DISABLE_AUTO ( p_port ) ;
2005-04-24 11:38:05 +04:00
FPT_sresb ( p_port , p_card ) ;
2005-04-17 02:20:36 +04:00
while ( RD_HARPOON ( p_port + hp_scsictrl_0 ) & SCSI_RST ) { }
pCurrNvRam = pCurrCard - > pNvRamInfo ;
if ( pCurrNvRam ) {
ScamFlg = pCurrNvRam - > niScamConf ;
}
else {
2006-03-08 11:14:24 +03:00
ScamFlg = ( unsigned char ) FPT_utilEERead ( p_port , SCAM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_XbowInit ( p_port , ScamFlg ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_scini ( p_card , pCurrCard - > ourId , 0 ) ;
2005-04-17 02:20:36 +04:00
return ( 0xFF ) ;
}
else if ( p_int & FIFO ) {
WRW_HARPOON ( ( p_port + hp_intstat ) , FIFO ) ;
if ( pCurrCard - > currentSCCB ! = NULL )
2005-04-24 11:38:05 +04:00
FPT_sxfrp ( p_port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else if ( p_int & TIMEOUT )
{
DISABLE_AUTO ( p_port ) ;
WRW_HARPOON ( ( p_port + hp_intstat ) ,
( PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE | IUNKWN ) ) ;
pCurrCard - > currentSCCB - > HostStatus = SCCB_SELECTION_TIMEOUT ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ pCurrCard - > currentSCCB - > TargID ] ;
2005-04-17 02:20:36 +04: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 [ pCurrCard - > currentSCCB - > Lun ] = 0 ;
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
if ( currTar_Info - > TarEEValue & EE_SYNC_MASK )
{
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
}
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI )
{
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
}
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( p_port , pCurrCard - > currentSCCB - > TargID , NARROW_SCSI , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_queueCmdComplete ( pCurrCard , pCurrCard - > currentSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
else if ( p_int & SCAM_SEL )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04:00
FPT_scbusf ( p_port ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
WRW_HARPOON ( ( p_port + hp_intstat ) , SCAM_SEL ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04: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:24 +03:00
unsigned char thisCard ;
2005-04-17 02:20:36 +04:00
for ( thisCard = 0 ; thisCard < MAX_CARDS ; thisCard + + )
{
2005-04-24 11:38:05 +04:00
FPT_SccbMgrTableInitCard ( & FPT_BL_Card [ thisCard ] , thisCard ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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:24 +03:00
static void FPT_SccbMgrTableInitCard ( PSCCBcard pCurrCard , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char scsiID , qtag ;
2005-04-17 02:20:36 +04: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
}
for ( scsiID = 0 ; scsiID < MAX_SCSI_TAR ; scsiID + + )
{
2005-04-24 11:38:05 +04:00
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
}
pCurrCard - > scanIndex = 0x00 ;
pCurrCard - > currentSCCB = NULL ;
pCurrCard - > globalFlags = 0x00 ;
pCurrCard - > cmdCounter = 0x00 ;
pCurrCard - > tagQ_Lst = 0x01 ;
pCurrCard - > discQCount = 0 ;
}
/*---------------------------------------------------------------------
*
* Function : SccbMgrTableInit
*
* Description : Initialize all Sccb manager data structures .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:24 +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 ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
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
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 ;
}
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + )
{
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] ! = NULL )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > TargID = = target )
2005-04-17 02:20:36 +04:00
{
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:29 +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 ;
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( TimeOutLoop + + < 20000 ) ) { }
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
message = RD_HARPOON ( port + hp_scsidata_0 ) ;
WR_HARPOON ( port + hp_scsisig , SCSI_ACK + S_MSGI_PH ) ;
if ( TimeOutLoop > 20000 )
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 )
{
pCurrSCCB - > Sccb_scsimsg = SMPARITY ;
}
message = 0x00 ;
do
{
ACCEPT_MSG_ATN ( port ) ;
TimeOutLoop = 0 ;
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( TimeOutLoop + + < 20000 ) ) { }
if ( TimeOutLoop > 20000 )
{
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
return ( message ) ;
}
if ( ( RD_HARPOON ( port + hp_scsisig ) & S_SCSI_PHZ ) ! = S_MSGI_PH )
{
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
return ( message ) ;
}
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
RD_HARPOON ( port + hp_scsidata_0 ) ;
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
} while ( 1 ) ;
}
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 ) ;
return ( message ) ;
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char auto_loaded , i , target , * theCCB ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
unsigned long cdb_reg ;
2005-04-17 02:20:36 +04:00
PSCCBcard CurrCard ;
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2006-03-08 11:14:24 +03:00
unsigned char lastTag , lun ;
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 ;
target = currSCCB - > TargID ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ target ] ;
2005-04-17 02:20:36 +04:00
lastTag = CurrCard - > tagQ_Lst ;
ARAM_ACCESS ( port ) ;
if ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) = = TAG_Q_REJECT )
currSCCB - > ControlByte & = ~ F_USE_CMD_Q ;
if ( ( ( CurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) )
lun = currSCCB - > Lun ;
else
lun = 0 ;
if ( CurrCard - > globalFlags & F_TAG_STARTED )
{
if ( ! ( currSCCB - > ControlByte & F_USE_CMD_Q ) )
{
2005-04-24 11:38:05 +04:00
if ( ( currTar_Info - > TarLUN_CA = = 0 )
2005-04-17 02:20:36 +04:00
& & ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK )
= = TAG_Q_TRYING ) )
{
if ( currTar_Info - > TarTagQ_Cnt ! = 0 )
{
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
else {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2005-04-17 02:20:36 +04:00
}
} /*End non-tagged */
else {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2005-04-17 02:20:36 +04:00
}
} /*!Use cmd Q Tagged */
else {
2005-04-24 11:38:05 +04:00
if ( currTar_Info - > TarLUN_CA = = 1 )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2005-04-17 02:20:36 +04:00
} /*else use cmd Q tagged */
} /*if glob tagged started */
else {
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2005-04-17 02:20:36 +04: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 ;
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
for ( i = 1 ; i < QUEUE_DEPTH ; i + + )
{
if ( + + lastTag > = QUEUE_DEPTH ) lastTag = 1 ;
if ( CurrCard - > discQ_Tbl [ lastTag ] = = NULL )
{
CurrCard - > tagQ_Lst = lastTag ;
currTar_Info - > LunDiscQ_Idx [ lun ] = lastTag ;
CurrCard - > discQ_Tbl [ lastTag ] = currSCCB ;
CurrCard - > discQCount + + ;
break ;
}
}
if ( i = = QUEUE_DEPTH )
{
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
}
2005-04-24 11:38:05 +04:00
auto_loaded = 0 ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_select_id , target ) ;
WR_HARPOON ( port + hp_gp_reg_3 , target ) ; /* Use by new automation logic */
if ( currSCCB - > OperationCode = = RESET_COMMAND ) {
WRW_HARPOON ( ( port + ID_MSG_STRT ) , ( MPM_OP + AMSG_OUT +
( currSCCB - > Sccb_idmsg & ~ DISC_PRIV ) ) ) ;
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + NP ) ;
currSCCB - > Sccb_scsimsg = SMDEV_RESET ;
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
2005-04-24 11:38:05 +04:00
auto_loaded = 1 ;
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_scsistat = SELECT_BDR_ST ;
if ( currTar_Info - > TarEEValue & EE_SYNC_MASK )
{
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
}
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI )
{
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
}
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( port , target , NARROW_SCSI , currTar_Info ) ;
FPT_SccbMgrTableInitTarget ( p_card , target ) ;
2005-04-17 02:20:36 +04:00
}
else if ( currSCCB - > Sccb_scsistat = = ABORT_ST )
{
WRW_HARPOON ( ( port + ID_MSG_STRT ) , ( MPM_OP + AMSG_OUT +
( currSCCB - > Sccb_idmsg & ~ DISC_PRIV ) ) ) ;
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + CMDPZ ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 0 ) , ( MPM_OP + AMSG_OUT +
2006-03-08 11:14:24 +03:00
( ( ( unsigned char ) ( currSCCB - > ControlByte & TAG_TYPE_MASK )
> > 6 ) | ( unsigned char ) 0x20 ) ) ) ;
2005-04-17 02:20:36 +04:00
WRW_HARPOON ( ( port + SYNC_MSGS + 2 ) ,
( MPM_OP + AMSG_OUT + currSCCB - > Sccb_tag ) ) ;
WRW_HARPOON ( ( port + SYNC_MSGS + 4 ) , ( BRH_OP + ALWAYS + NP ) ) ;
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
2005-04-24 11:38:05 +04:00
auto_loaded = 1 ;
2005-04-17 02:20:36 +04:00
}
else if ( ! ( currTar_Info - > TarStatus & WIDE_NEGOCIATED ) ) {
2005-04-24 11:38:05 +04:00
auto_loaded = FPT_siwidn ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_scsistat = SELECT_WN_ST ;
}
else if ( ! ( ( currTar_Info - > TarStatus & TAR_SYNC_MASK )
= = SYNC_SUPPORTED ) ) {
2005-04-24 11:38:05 +04:00
auto_loaded = FPT_sisyncn ( port , p_card , 0 ) ;
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_scsistat = SELECT_SN_ST ;
}
if ( ! auto_loaded )
{
if ( currSCCB - > ControlByte & F_USE_CMD_Q )
{
CurrCard - > globalFlags | = F_TAG_STARTED ;
if ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK )
= = TAG_Q_REJECT )
{
currSCCB - > ControlByte & = ~ F_USE_CMD_Q ;
/* Fix up the start instruction with a jump to
Non - Tag - CMD handling */
WRW_HARPOON ( ( port + ID_MSG_STRT ) , BRH_OP + ALWAYS + NTCMD ) ;
WRW_HARPOON ( ( port + NON_TAG_ID_MSG ) ,
( MPM_OP + AMSG_OUT + currSCCB - > Sccb_idmsg ) ) ;
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
/* Setup our STATE so we know what happend when
the wheels fall off . */
currSCCB - > Sccb_scsistat = SELECT_ST ;
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
2005-04-17 02:20:36 +04: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 +
2006-03-08 11:14:24 +03:00
( ( ( unsigned char ) ( currSCCB - > ControlByte & TAG_TYPE_MASK )
> > 6 ) | ( unsigned char ) 0x20 ) ) ) ;
2005-04-17 02:20:36 +04:00
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 ) ) ;
CurrCard - > tagQ_Lst = lastTag ;
currSCCB - > Sccb_tag = lastTag ;
CurrCard - > discQ_Tbl [ lastTag ] = currSCCB ;
CurrCard - > discQCount + + ;
break ;
}
}
if ( i = = QUEUE_DEPTH )
{
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ lun ] = 1 ;
FPT_queueSelectFail ( CurrCard , p_card ) ;
2005-04-17 02:20:36 +04:00
SGRAM_ACCESS ( port ) ;
return ;
}
currSCCB - > Sccb_scsistat = SELECT_Q_ST ;
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
}
}
else
{
WRW_HARPOON ( ( port + ID_MSG_STRT ) , BRH_OP + ALWAYS + NTCMD ) ;
WRW_HARPOON ( ( port + NON_TAG_ID_MSG ) ,
( MPM_OP + AMSG_OUT + currSCCB - > Sccb_idmsg ) ) ;
currSCCB - > Sccb_scsistat = SELECT_ST ;
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
}
2006-03-08 11:14:24 +03:00
theCCB = ( unsigned char * ) & currSCCB - > Cdb [ 0 ] ;
2005-04-17 02:20:36 +04:00
cdb_reg = port + CMD_STRT ;
for ( i = 0 ; i < currSCCB - > CdbLength ; i + + )
{
WRW_HARPOON ( cdb_reg , ( MPM_OP + ACOMMAND + * theCCB ) ) ;
cdb_reg + = 2 ;
theCCB + + ;
}
if ( currSCCB - > CdbLength ! = TWELVE_BYTE_CMD )
WRW_HARPOON ( cdb_reg , ( BRH_OP + ALWAYS + NP ) ) ;
} /* auto_loaded */
2006-03-08 11:14:25 +03:00
WRW_HARPOON ( ( port + hp_fiforead ) , ( unsigned short ) 0x00 ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_xferstat , 0x00 ) ;
WRW_HARPOON ( ( port + hp_intstat ) , ( PROG_HLT | TIMEOUT | SEL | BUS_FREE ) ) ;
WR_HARPOON ( port + hp_portctrl_0 , ( SCSI_PORT ) ) ;
if ( ! ( currSCCB - > Sccb_MGRFlags & F_DEV_SELECTED ) )
{
WR_HARPOON ( port + hp_scsictrl_0 , ( SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL ) ) ;
}
else
{
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 ; */
auto_loaded = AUTO_IMMED ;
DISABLE_AUTO ( port ) ;
WR_HARPOON ( port + hp_autostart_3 , auto_loaded ) ;
}
SGRAM_ACCESS ( port ) ;
}
/*---------------------------------------------------------------------
*
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:26 +03:00
static void FPT_sres ( unsigned long port , unsigned char p_card , PSCCBcard pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char our_target , message , lun = 0 , tag , msgRetryCount ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
if ( pCurrCard - > currentSCCB ! = NULL )
{
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ pCurrCard - > currentSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
DISABLE_AUTO ( port ) ;
WR_HARPOON ( ( port + hp_scsictrl_0 ) , ( ENA_RESEL | ENA_SCAM_SEL ) ) ;
currSCCB = pCurrCard - > currentSCCB ;
if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST )
{
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
currSCCB - > Sccb_scsistat = BUS_FREE_ST ;
}
if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST )
{
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
currSCCB - > Sccb_scsistat = BUS_FREE_ST ;
}
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 [ currSCCB - > Lun ] = 0 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_scsistat ! = ABORT_ST )
{
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ currSCCB - > Lun ] ]
= NULL ;
}
}
else
{
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_tag )
{
if ( currSCCB - > Sccb_scsistat ! = ABORT_ST )
{
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ currSCCB - > Sccb_tag ] = NULL ;
}
} else
{
if ( currSCCB - > Sccb_scsistat ! = ABORT_ST )
{
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ 0 ] ] = NULL ;
}
}
}
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( & FPT_BL_Card [ p_card ] , p_card ) ;
2005-04-17 02:20:36 +04:00
}
2006-03-08 11:14:25 +03:00
WRW_HARPOON ( ( port + hp_fiforead ) , ( unsigned short ) 0x00 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +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 ;
do
{
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 ;
while ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) )
{
if ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) )
{
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
return ;
}
}
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
if ( ( RD_HARPOON ( port + hp_scsisig ) & S_SCSI_PHZ ) = = S_MSGI_PH )
{
2005-04-24 11:38:05 +04:00
message = FPT_sfm ( port , pCurrCard - > currentSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( message )
{
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
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. */
2005-04-24 11:38:05 +04:00
message = FPT_sfm ( port , pCurrCard - > currentSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( message )
{
ACCEPT_MSG ( port ) ;
}
else
2005-04-24 11:38:05 +04:00
message = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( message ! = 0 )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
tag = FPT_sfm ( port , pCurrCard - > currentSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( ! ( tag ) )
2005-04-24 11:38:05 +04:00
message = 0 ;
2005-04-17 02:20:36 +04:00
}
} /*C.A. exists! */
} /*End Q cnt != 0 */
} /*End Tag cmds supported! */
} /*End valid ID message. */
else
{
ACCEPT_MSG_ATN ( port ) ;
}
} /* End good id message. */
else
{
2005-04-24 11:38:05 +04:00
message = 0 ;
2005-04-17 02:20:36 +04:00
}
}
else
{
ACCEPT_MSG_ATN ( port ) ;
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( PHASE | RESET ) ) & &
! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) & &
( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) ;
return ;
}
2005-04-24 11:38:05 +04:00
if ( message = = 0 )
2005-04-17 02:20:36 +04:00
{
msgRetryCount + + ;
if ( msgRetryCount = = 1 )
{
2005-04-24 11:38:05 +04:00
FPT_SendMsg ( port , SMPARITY ) ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
FPT_SendMsg ( port , SMDEV_RESET ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( port , our_target , NARROW_SCSI , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( FPT_sccbMgrTbl [ p_card ] [ our_target ] . TarEEValue & EE_SYNC_MASK )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ our_target ] . TarStatus & = ~ TAR_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( FPT_sccbMgrTbl [ p_card ] [ our_target ] . TarEEValue & EE_WIDE_SCSI )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ our_target ] . TarStatus & = ~ TAR_WIDE_MASK ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_queueFlushTargSccb ( p_card , our_target , SCCB_COMPLETE ) ;
FPT_SccbMgrTableInitTarget ( p_card , our_target ) ;
2005-04-17 02:20:36 +04:00
return ;
}
}
2005-04-24 11:38:05 +04:00
} while ( message = = 0 ) ;
2005-04-17 02:20:36 +04: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 ;
2005-04-17 02:20:36 +04:00
pCurrCard - > currentSCCB = pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ lun ] ] ;
if ( pCurrCard - > currentSCCB ! = NULL )
{
ACCEPT_MSG ( port ) ;
}
else
{
ACCEPT_MSG_ATN ( port ) ;
}
}
else
{
2005-04-24 11:38:05 +04:00
currTar_Info - > TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
if ( tag )
{
if ( pCurrCard - > discQ_Tbl [ tag ] ! = NULL )
{
pCurrCard - > currentSCCB = pCurrCard - > discQ_Tbl [ tag ] ;
currTar_Info - > TarTagQ_Cnt - - ;
ACCEPT_MSG ( port ) ;
}
else
{
ACCEPT_MSG_ATN ( port ) ;
}
} else
{
pCurrCard - > currentSCCB = pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ 0 ] ] ;
if ( pCurrCard - > currentSCCB ! = NULL )
{
ACCEPT_MSG ( port ) ;
}
else
{
ACCEPT_MSG_ATN ( port ) ;
}
}
}
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
}
}
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( PHASE | RESET ) ) & &
! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) & &
( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) ) ;
}
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
{
while ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) )
{
if ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_BSY ) )
{
WRW_HARPOON ( ( port + hp_intstat ) , PHASE ) ;
return ;
}
}
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 ) ) ;
WR_HARPOON ( port + hp_portctrl_0 , SCSI_BUS_EN ) ;
WR_HARPOON ( port + hp_scsidata_0 , message ) ;
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
if ( ( message = = SMABORT ) | | ( message = = SMDEV_RESET ) | |
( message = = SMABORT_TAG ) )
{
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | PHASE ) ) ) { }
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE )
{
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
}
}
}
}
/*---------------------------------------------------------------------
*
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:26 +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:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBcard CurrCard ;
PSCCBMgr_tar_info currTar_Info ;
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
if ( message = = SMREST_DATA_PTR )
{
if ( ! ( currSCCB - > Sccb_XferState & F_NO_DATA_YET ) )
{
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 ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
else if ( message = = SMCMD_COMP )
{
if ( currSCCB - > Sccb_scsistat = = SELECT_Q_ST )
{
2006-03-08 11:14:24 +03:00
currTar_Info - > TarStatus & = ~ ( unsigned char ) TAR_TAG_Q_MASK ;
currTar_Info - > TarStatus | = ( unsigned char ) TAG_Q_REJECT ;
2005-04-17 02:20:36 +04:00
}
ACCEPT_MSG ( port ) ;
}
else if ( ( message = = SMNO_OP ) | | ( message > = SMIDENT )
| | ( message = = SMINIT_RECOVERY ) | | ( message = = SMREL_RECOVERY ) )
{
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
else if ( message = = SMREJECT )
{
if ( ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) | |
( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) | |
( ( currTar_Info - > TarStatus & TAR_SYNC_MASK ) = = SYNC_TRYING ) | |
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) = = TAG_Q_TRYING ) )
{
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
ACCEPT_MSG ( port ) ;
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) ) ) { }
if ( currSCCB - > Lun = = 0x00 )
{
if ( ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) )
{
2006-03-08 11:14:24 +03:00
currTar_Info - > TarStatus | = ( unsigned char ) SYNC_SUPPORTED ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarEEValue & = ~ EE_SYNC_MASK ;
}
else if ( ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST ) )
{
currTar_Info - > TarStatus = ( currTar_Info - > TarStatus &
~ WIDE_ENABLED ) | WIDE_NEGOCIATED ;
currTar_Info - > TarEEValue & = ~ EE_WIDE_SCSI ;
}
else if ( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) = = TAG_Q_TRYING )
{
currTar_Info - > TarStatus = ( currTar_Info - > TarStatus &
2006-03-08 11:14:24 +03:00
~ ( 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 - - ;
CurrCard - > discQ_Tbl [ currSCCB - > Sccb_tag ] = NULL ;
currSCCB - > Sccb_tag = 0x00 ;
}
}
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE )
{
if ( currSCCB - > Lun = = 0x00 )
{
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
CurrCard - > globalFlags | = F_NEW_SCCB_CMD ;
}
}
else
{
if ( ( CurrCard - > 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 [ 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:24 +03:00
currSCCB - > ControlByte & = ~ ( unsigned char ) F_USE_CMD_Q ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
else
{
ACCEPT_MSG ( port ) ;
while ( ( ! ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) ) & &
( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) ) ) { }
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) )
{
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
}
else if ( message = = SMEXT )
{
ACCEPT_MSG ( port ) ;
2005-04-24 11:38:05 +04:00
FPT_shandem ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
}
else if ( message = = SMIGNORWR )
{
ACCEPT_MSG ( port ) ; /* ACK the RESIDUE MSG */
2005-04-24 11:38:05 +04:00
message = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_scsimsg ! = SMPARITY )
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
else
{
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
currSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
/*---------------------------------------------------------------------
*
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:29 +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:24 +03:00
unsigned char length , message ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
length = FPT_sfm ( port , pCurrSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( length )
{
ACCEPT_MSG ( port ) ;
2005-04-24 11:38:05 +04:00
message = FPT_sfm ( port , pCurrSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( message )
{
if ( message = = SMSYNC )
{
if ( length = = 0x03 )
{
ACCEPT_MSG ( port ) ;
2005-04-24 11:38:05 +04:00
FPT_stsyncn ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else
{
pCurrSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
}
}
else if ( message = = SMWDTR )
{
if ( length = = 0x02 )
{
ACCEPT_MSG ( port ) ;
2005-04-24 11:38:05 +04:00
FPT_stwidn ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else
{
pCurrSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
else
{
pCurrSCCB - > Sccb_scsimsg = SMREJECT ;
ACCEPT_MSG_ATN ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
else
{
if ( pCurrSCCB - > Sccb_scsimsg ! = SMPARITY )
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
} else
{
if ( pCurrSCCB - > Sccb_scsimsg = = SMPARITY )
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
/*---------------------------------------------------------------------
*
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:26 +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:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2005-04-24 11:38:05 +04:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
if ( ! ( ( currTar_Info - > TarStatus & TAR_SYNC_MASK ) = = SYNC_TRYING ) ) {
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
2006-03-08 11:14:24 +03:00
( MPM_OP + AMSG_OUT + ( currSCCB - > Sccb_idmsg & ~ ( unsigned char ) DISC_PRIV ) ) ) ;
2005-04-17 02:20:36 +04:00
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + CMDPZ ) ;
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 ) ) ;
if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_20MB )
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) , ( MPM_OP + AMSG_OUT + 12 ) ) ;
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_10MB )
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) , ( MPM_OP + AMSG_OUT + 25 ) ) ;
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_5MB )
WRW_HARPOON ( ( port + SYNC_MSGS + 6 ) , ( MPM_OP + AMSG_OUT + 50 ) ) ;
else
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 ) ) ;
2005-04-24 11:38:05 +04:00
if ( syncFlag = = 0 )
2005-04-17 02:20:36 +04:00
{
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
2006-03-08 11:14:24 +03:00
~ ( unsigned char ) TAR_SYNC_MASK ) | ( unsigned char ) SYNC_TRYING ) ;
2005-04-17 02:20:36 +04:00
}
else
{
WR_HARPOON ( port + hp_autostart_3 , ( AUTO_IMMED + CMD_ONLY_STRT ) ) ;
}
2005-04-24 11:38:05 +04:00
return ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
else {
2006-03-08 11:14:24 +03:00
currTar_Info - > TarStatus | = ( unsigned char ) SYNC_SUPPORTED ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarEEValue & = ~ EE_SYNC_MASK ;
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
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:24 +03:00
unsigned char sync_msg , offset , sync_reg , our_sync_msg ;
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2005-04-24 11:38:05 +04:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
sync_msg = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( ( sync_msg = = 0x00 ) & & ( currSCCB - > Sccb_scsimsg = = SMPARITY ) )
{
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
return ;
}
ACCEPT_MSG ( port ) ;
2005-04-24 11:38:05 +04:00
offset = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( ( offset = = 0x00 ) & & ( currSCCB - > Sccb_scsimsg = = SMPARITY ) )
{
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
return ;
}
if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_20MB )
our_sync_msg = 12 ; /* Setup our Message to 20mb/s */
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_10MB )
our_sync_msg = 25 ; /* Setup our Message to 10mb/s */
else if ( ( currTar_Info - > TarEEValue & EE_SYNC_MASK ) = = EE_SYNC_5MB )
our_sync_msg = 50 ; /* Setup our Message to 5mb/s */
else
our_sync_msg = 0 ; /* Message = Async */
if ( sync_msg < our_sync_msg ) {
sync_msg = our_sync_msg ; /*if faster, then set to max. */
}
if ( offset = = ASYNC )
sync_msg = ASYNC ;
if ( offset > MAX_OFFSET )
offset = MAX_OFFSET ;
sync_reg = 0x00 ;
if ( sync_msg > 12 )
sync_reg = 0x20 ; /* Use 10MB/s */
if ( sync_msg > 25 )
sync_reg = 0x40 ; /* Use 6.6MB/s */
if ( sync_msg > 38 )
sync_reg = 0x60 ; /* Use 5MB/s */
if ( sync_msg > 50 )
sync_reg = 0x80 ; /* Use 4MB/s */
if ( sync_msg > 62 )
sync_reg = 0xA0 ; /* Use 3.33MB/s */
if ( sync_msg > 75 )
sync_reg = 0xC0 ; /* Use 2.85MB/s */
if ( sync_msg > 87 )
sync_reg = 0xE0 ; /* Use 2.5MB/s */
if ( sync_msg > 100 ) {
sync_reg = 0x00 ; /* Use ASYNC */
offset = 0x00 ;
}
if ( currTar_Info - > TarStatus & WIDE_ENABLED )
sync_reg | = offset ;
else
sync_reg | = ( offset | NARROW_SCSI ) ;
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( port , currSCCB - > TargID , sync_reg , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST ) {
ACCEPT_MSG ( port ) ;
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
2006-03-08 11:14:24 +03:00
~ ( unsigned char ) TAR_SYNC_MASK ) | ( unsigned char ) SYNC_SUPPORTED ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
else {
ACCEPT_MSG_ATN ( port ) ;
2005-04-24 11:38:05 +04:00
FPT_sisyncr ( port , sync_msg , offset ) ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
2006-03-08 11:14:24 +03:00
~ ( 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:26 +03:00
static void FPT_sisyncr ( unsigned long port , unsigned char sync_pulse , unsigned char offset )
2005-04-17 02:20:36 +04: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-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:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2005-04-24 11:38:05 +04:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
if ( ! ( ( currTar_Info - > TarStatus & TAR_WIDE_MASK ) = = WIDE_NEGOCIATED ) ) {
WRW_HARPOON ( ( port + ID_MSG_STRT ) ,
2006-03-08 11:14:24 +03:00
( MPM_OP + AMSG_OUT + ( currSCCB - > Sccb_idmsg & ~ ( unsigned char ) DISC_PRIV ) ) ) ;
2005-04-17 02:20:36 +04:00
WRW_HARPOON ( ( port + ID_MSG_STRT + 2 ) , BRH_OP + ALWAYS + CMDPZ ) ;
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 ) ) ;
WR_HARPOON ( port + hp_autostart_3 , ( SELECT + SELCHK_STRT ) ) ;
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
2006-03-08 11:14:24 +03:00
~ ( unsigned char ) TAR_WIDE_MASK ) | ( unsigned char ) WIDE_ENABLED ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
return ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
else {
currTar_Info - > TarStatus = ( ( currTar_Info - > TarStatus &
2006-03-08 11:14:24 +03:00
~ ( unsigned char ) TAR_WIDE_MASK ) | WIDE_NEGOCIATED ) ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarEEValue & = ~ EE_WIDE_SCSI ;
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
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:24 +03:00
unsigned char width ;
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2005-04-24 11:38:05 +04:00
currSCCB = FPT_BL_Card [ p_card ] . currentSCCB ;
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
width = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( ( width = = 0x00 ) & & ( currSCCB - > Sccb_scsimsg = = SMPARITY ) )
{
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
return ;
}
if ( ! ( currTar_Info - > TarEEValue & EE_WIDE_SCSI ) )
width = 0 ;
if ( width ) {
currTar_Info - > TarStatus | = WIDE_ENABLED ;
width = 0 ;
}
else {
width = NARROW_SCSI ;
currTar_Info - > TarStatus & = ~ WIDE_ENABLED ;
}
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( port , currSCCB - > TargID , width , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST )
{
currTar_Info - > TarStatus | = WIDE_NEGOCIATED ;
if ( ! ( ( currTar_Info - > TarStatus & TAR_SYNC_MASK ) = = SYNC_SUPPORTED ) )
{
ACCEPT_MSG_ATN ( port ) ;
ARAM_ACCESS ( port ) ;
2005-04-24 11:38:05 +04:00
FPT_sisyncn ( port , p_card , 1 ) ;
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_scsistat = SELECT_SN_ST ;
SGRAM_ACCESS ( port ) ;
}
else
{
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
else {
ACCEPT_MSG_ATN ( port ) ;
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI )
width = SM16BIT ;
else
width = SM8BIT ;
2005-04-24 11:38:05 +04:00
FPT_siwidr ( port , width ) ;
2005-04-17 02:20:36 +04:00
currTar_Info - > TarStatus | = ( WIDE_NEGOCIATED | WIDE_ENABLED ) ;
}
}
/*---------------------------------------------------------------------
*
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
{
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 ) ;
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-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:26 +03:00
static void FPT_sssyncv ( unsigned long p_port , unsigned char p_id , unsigned char p_sync_value ,
2005-04-24 11:38:05 +04:00
PSCCBMgr_tar_info currTar_Info )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char index ;
2005-04-17 02:20:36 +04:00
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 */
}
WR_HARPOON ( p_port + hp_synctarg_base + index , p_sync_value ) ;
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:24 +03:00
unsigned char scsiID , i ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
WR_HARPOON ( port + hp_page_ctrl ,
( RD_HARPOON ( port + hp_page_ctrl ) | G_INT_DISABLE ) ) ;
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT ) ;
WR_HARPOON ( port + hp_scsictrl_0 , SCSI_RST ) ;
scsiID = RD_HARPOON ( port + hp_seltimeout ) ;
WR_HARPOON ( port + hp_seltimeout , TO_5ms ) ;
WRW_HARPOON ( ( port + hp_intstat ) , TIMEOUT ) ;
WR_HARPOON ( port + hp_portctrl_0 , ( SCSI_PORT | START_TO ) ) ;
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & TIMEOUT ) ) { }
WR_HARPOON ( port + hp_seltimeout , scsiID ) ;
WR_HARPOON ( port + hp_scsictrl_0 , ENA_SCAM_SEL ) ;
2005-04-24 11:38:05 +04:00
FPT_Wait ( port , TO_5ms ) ;
2005-04-17 02:20:36 +04:00
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT ) ;
WR_HARPOON ( port + hp_int_mask , ( RD_HARPOON ( port + hp_int_mask ) | 0x00 ) ) ;
for ( scsiID = 0 ; scsiID < MAX_SCSI_TAR ; scsiID + + )
{
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ scsiID ] ;
2005-04-17 02:20:36 +04:00
if ( currTar_Info - > TarEEValue & EE_SYNC_MASK )
{
currTar_Info - > TarSyncCtrl = 0 ;
currTar_Info - > TarStatus & = ~ TAR_SYNC_MASK ;
}
if ( currTar_Info - > TarEEValue & EE_WIDE_SCSI )
{
currTar_Info - > TarStatus & = ~ TAR_WIDE_MASK ;
}
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( port , scsiID , NARROW_SCSI , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_SccbMgrTableInitTarget ( p_card , scsiID ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04: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
2005-04-17 02:20:36 +04:00
| F_NEW_SCCB_CMD ) ;
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . cmdCounter = 0x00 ;
FPT_BL_Card [ p_card ] . discQCount = 0x00 ;
FPT_BL_Card [ p_card ] . tagQ_Lst = 0x01 ;
2005-04-17 02:20:36 +04: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
WR_HARPOON ( port + hp_page_ctrl ,
( RD_HARPOON ( port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) ;
}
/*---------------------------------------------------------------------
*
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 .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2005-04-24 11:38:05 +04:00
static void FPT_ssenss ( PSCCBcard 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:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
currSCCB = pCurrCard - > currentSCCB ;
currSCCB - > Save_CdbLen = currSCCB - > CdbLength ;
for ( i = 0 ; i < 6 ; i + + ) {
currSCCB - > Save_Cdb [ i ] = currSCCB - > Cdb [ i ] ;
}
currSCCB - > CdbLength = SIX_BYTE_CMD ;
currSCCB - > Cdb [ 0 ] = SCSI_REQUEST_SENSE ;
2006-03-08 11:14:24 +03:00
currSCCB - > Cdb [ 1 ] = currSCCB - > Cdb [ 1 ] & ( unsigned char ) 0xE0 ; /*Keep LUN. */
2005-04-17 02:20:36 +04:00
currSCCB - > Cdb [ 2 ] = 0x00 ;
currSCCB - > Cdb [ 3 ] = 0x00 ;
currSCCB - > Cdb [ 4 ] = currSCCB - > RequestSenseLength ;
currSCCB - > Cdb [ 5 ] = 0x00 ;
currSCCB - > Sccb_XferCnt = ( unsigned long ) currSCCB - > RequestSenseLength ;
currSCCB - > Sccb_ATC = 0x00 ;
currSCCB - > Sccb_XferState | = F_AUTO_SENSE ;
currSCCB - > Sccb_XferState & = ~ F_SG_XFER ;
2006-03-08 11:14:24 +03:00
currSCCB - > Sccb_idmsg = currSCCB - > Sccb_idmsg & ~ ( unsigned char ) DISC_PRIV ;
2005-04-17 02:20:36 +04:00
currSCCB - > ControlByte = 0x00 ;
currSCCB - > Sccb_MGRFlags & = F_STATUSLOADED ;
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char curr_phz ;
2005-04-17 02:20:36 +04:00
DISABLE_AUTO ( p_port ) ;
2005-04-24 11:38:05 +04: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_hostDataXferAbort ( p_port , p_card , FPT_BL_Card [ p_card ] . currentSCCB ) ;
2005-04-17 02:20:36 +04: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 ) ;
2006-03-08 11:14:24 +03:00
curr_phz = RD_HARPOON ( p_port + hp_scsisig ) & ( unsigned char ) S_SCSI_PHZ ;
2005-04-17 02:20:36 +04:00
WRW_HARPOON ( ( p_port + hp_intstat ) , XFER_CNT_0 ) ;
WR_HARPOON ( p_port + hp_scsisig , curr_phz ) ;
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) & &
2006-03-08 11:14:24 +03:00
( 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:24 +03:00
if ( curr_phz & ( unsigned char ) SCSI_IOBIT )
2005-04-17 02:20:36 +04:00
{
WR_HARPOON ( p_port + hp_portctrl_0 , ( SCSI_PORT | HOST_PORT | SCSI_INBIT ) ) ;
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 */
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) )
{
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_REQ )
break ;
}
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 ) ;
}
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 ) ) { }
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( ICMD_COMP | ITAR_DISC ) )
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( BUS_FREE | RSEL ) ) ) ;
}
}
/*---------------------------------------------------------------------
*
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:25 +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:29 +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
if ( ( currSCCB - > Sccb_scsistat ! = DATA_OUT_ST ) & &
( currSCCB - > Sccb_scsistat ! = DATA_IN_ST ) ) {
return ;
}
if ( currSCCB - > Sccb_XferState & F_ODD_BALL_CNT )
{
currSCCB - > Sccb_ATC + = ( currSCCB - > Sccb_XferCnt - 1 ) ;
currSCCB - > Sccb_XferCnt = 1 ;
currSCCB - > Sccb_XferState & = ~ F_ODD_BALL_CNT ;
2006-03-08 11:14:25 +03:00
WRW_HARPOON ( ( port + hp_fiforead ) , ( unsigned short ) 0x00 ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_xferstat , 0x00 ) ;
}
else
{
currSCCB - > Sccb_ATC + = currSCCB - > Sccb_XferCnt ;
currSCCB - > Sccb_XferCnt = 0 ;
}
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) ) {
currSCCB - > HostStatus = SCCB_PARITY_ERR ;
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
}
2005-04-24 11:38:05 +04:00
FPT_hostDataXferAbort ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
while ( RD_HARPOON ( port + hp_scsisig ) & SCSI_ACK ) { }
TimeOutLoop = 0 ;
while ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY )
{
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE ) {
return ;
}
2006-03-08 11:14:24 +03:00
if ( RD_HARPOON ( port + hp_offsetctr ) & ( unsigned char ) 0x1F ) {
2005-04-17 02:20:36 +04:00
break ;
}
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & RESET ) {
return ;
}
if ( ( RD_HARPOON ( port + hp_scsisig ) & SCSI_REQ ) | | ( TimeOutLoop + + > 0x3000 ) )
break ;
}
sPhase = RD_HARPOON ( port + hp_scsisig ) & ( SCSI_BSY | S_SCSI_PHZ ) ;
if ( ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) ) | |
2006-03-08 11:14:24 +03:00
( RD_HARPOON ( port + hp_offsetctr ) & ( unsigned char ) 0x1F ) | |
2005-04-17 02:20:36 +04:00
( sPhase = = ( SCSI_BSY | S_DATAO_PH ) ) | |
( sPhase = = ( SCSI_BSY | S_DATAI_PH ) ) )
{
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
if ( ! ( currSCCB - > Sccb_XferState & F_ALL_XFERRED ) )
{
if ( currSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
2005-04-24 11:38:05 +04:00
FPT_phaseDataIn ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else {
2005-04-24 11:38:05 +04:00
FPT_phaseDataOut ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
else
{
2005-04-24 11:38:05 +04:00
FPT_sxfrp ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) &
( BUS_FREE | ICMD_COMP | ITAR_DISC | RESET ) ) )
{
WRW_HARPOON ( ( port + hp_intstat ) , AUTO_INT ) ;
2005-04-24 11:38:05 +04:00
FPT_phaseDecode ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
}
else {
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
}
}
/*---------------------------------------------------------------------
*
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:29 +03:00
static void FPT_sinits ( struct sccb * p_sccb , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
PSCCBMgr_tar_info currTar_Info ;
if ( ( p_sccb - > TargID > MAX_SCSI_TAR ) | | ( p_sccb - > Lun > MAX_LUN ) )
{
return ;
}
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
p_sccb - > Sccb_XferState = 0x00 ;
p_sccb - > Sccb_XferCnt = p_sccb - > DataLength ;
if ( ( p_sccb - > OperationCode = = SCATTER_GATHER_COMMAND ) | |
( p_sccb - > OperationCode = = RESIDUAL_SG_COMMAND ) ) {
p_sccb - > Sccb_SGoffset = 0 ;
p_sccb - > Sccb_XferState = F_SG_XFER ;
p_sccb - > Sccb_XferCnt = 0x00 ;
}
if ( p_sccb - > DataLength = = 0x00 )
p_sccb - > Sccb_XferState | = F_ALL_XFERRED ;
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 ;
else
currTar_Info - > TarStatus | = TAG_Q_TRYING ;
}
/* 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 ) ) {
*/
if ( ( currTar_Info - > TarStatus & TAR_ALLOW_DISC ) | |
( currTar_Info - > TarStatus & TAG_Q_TRYING ) ) {
2006-03-08 11:14:24 +03:00
p_sccb - > Sccb_idmsg = ( unsigned char ) ( SMIDENT | DISC_PRIV ) | p_sccb - > Lun ;
2005-04-17 02:20:36 +04:00
}
else {
2006-03-08 11:14:24 +03:00
p_sccb - > Sccb_idmsg = ( unsigned char ) SMIDENT | p_sccb - > Lun ;
2005-04-17 02:20:36 +04: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 ;
/*
p_sccb - > SccbVirtDataPtr = 0x00 ;
p_sccb - > Sccb_forwardlink = NULL ;
p_sccb - > Sccb_backlink = NULL ;
*/
p_sccb - > Sccb_scsistat = BUS_FREE_ST ;
p_sccb - > SccbStatus = SCCB_IN_PROCESS ;
p_sccb - > Sccb_scsimsg = SMNO_OP ;
}
/*---------------------------------------------------------------------
*
* 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
{
unsigned char phase_ref ;
2006-03-08 11:14:26 +03:00
void ( * phase ) ( unsigned long , unsigned char ) ;
2005-04-17 02:20:36 +04:00
DISABLE_AUTO ( p_port ) ;
2006-03-08 11:14:24 +03:00
phase_ref = ( unsigned char ) ( RD_HARPOON ( p_port + hp_scsisig ) & S_SCSI_PHZ ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
phase = FPT_s_PhaseTbl [ phase_ref ] ;
2005-04-17 02:20:36 +04:00
( * phase ) ( p_port , p_card ) ; /* Call the correct phase func */
}
/*---------------------------------------------------------------------
*
* 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:29 +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
if ( currSCCB = = NULL )
{
return ; /* Exit if No SCCB record */
}
currSCCB - > Sccb_scsistat = DATA_OUT_ST ;
currSCCB - > Sccb_XferState & = ~ ( F_HOST_XFER_DIR | F_NO_DATA_YET ) ;
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
WRW_HARPOON ( ( port + hp_intstat ) , XFER_CNT_0 ) ;
WR_HARPOON ( port + hp_autostart_0 , ( END_DATA + END_DATA_START ) ) ;
2005-04-24 11:38:05 +04:00
FPT_dataXferProcessor ( port , & FPT_BL_Card [ p_card ] ) ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_XferCnt = = 0 ) {
if ( ( currSCCB - > ControlByte & SCCB_DATA_XFER_OUT ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) )
currSCCB - > HostStatus = SCCB_DATA_OVER_RUN ;
2005-04-24 11:38:05 +04:00
FPT_sxfrp ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) )
2005-04-24 11:38:05 +04:00
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:29 +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
if ( currSCCB = = NULL )
{
return ; /* Exit if No SCCB record */
}
currSCCB - > Sccb_scsistat = DATA_IN_ST ;
currSCCB - > Sccb_XferState | = F_HOST_XFER_DIR ;
currSCCB - > Sccb_XferState & = ~ F_NO_DATA_YET ;
WR_HARPOON ( port + hp_portctrl_0 , SCSI_PORT ) ;
WRW_HARPOON ( ( port + hp_intstat ) , XFER_CNT_0 ) ;
WR_HARPOON ( port + hp_autostart_0 , ( END_DATA + END_DATA_START ) ) ;
2005-04-24 11:38:05 +04:00
FPT_dataXferProcessor ( port , & FPT_BL_Card [ p_card ] ) ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_XferCnt = = 0 ) {
if ( ( currSCCB - > ControlByte & SCCB_DATA_XFER_IN ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) )
currSCCB - > HostStatus = SCCB_DATA_OVER_RUN ;
2005-04-24 11:38:05 +04:00
FPT_sxfrp ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
if ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | RESET ) ) )
2005-04-24 11:38:05 +04:00
FPT_phaseDecode ( port , p_card ) ;
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:29 +03:00
struct sccb * currSCCB ;
2006-03-08 11:14:26 +03:00
unsigned long cdb_reg ;
2006-03-08 11:14:24 +03:00
unsigned char i ;
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 - > OperationCode = = RESET_COMMAND ) {
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
currSCCB - > CdbLength = SIX_BYTE_CMD ;
}
WR_HARPOON ( p_port + hp_scsisig , 0x00 ) ;
ARAM_ACCESS ( p_port ) ;
cdb_reg = p_port + CMD_STRT ;
for ( i = 0 ; i < currSCCB - > CdbLength ; i + + ) {
if ( currSCCB - > OperationCode = = RESET_COMMAND )
WRW_HARPOON ( cdb_reg , ( MPM_OP + ACOMMAND + 0x00 ) ) ;
else
WRW_HARPOON ( cdb_reg , ( MPM_OP + ACOMMAND + currSCCB - > Cdb [ i ] ) ) ;
cdb_reg + = 2 ;
}
if ( currSCCB - > CdbLength ! = TWELVE_BYTE_CMD )
WRW_HARPOON ( cdb_reg , ( BRH_OP + ALWAYS + NP ) ) ;
WR_HARPOON ( p_port + hp_portctrl_0 , ( SCSI_PORT ) ) ;
currSCCB - > Sccb_scsistat = COMMAND_ST ;
WR_HARPOON ( p_port + hp_autostart_3 , ( AUTO_IMMED | CMD_ONLY_STRT ) ) ;
SGRAM_ACCESS ( p_port ) ;
}
/*---------------------------------------------------------------------
*
* 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
{
/* 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 ?
*/
WR_HARPOON ( port + hp_scsisig , 0x00 ) ;
WR_HARPOON ( port + hp_autostart_0 , ( AUTO_IMMED + END_DATA_START ) ) ;
}
/*---------------------------------------------------------------------
*
* 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:24 +03:00
unsigned char message , scsiID ;
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
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 ;
if ( message = = SMDEV_RESET )
{
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 ;
2005-04-24 11:38:05 +04:00
FPT_sssyncv ( port , scsiID , NARROW_SCSI , currTar_Info ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarEEValue & EE_SYNC_MASK )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarStatus & = ~ TAR_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarEEValue & EE_WIDE_SCSI )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarStatus & = ~ TAR_WIDE_MASK ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_queueFlushSccb ( p_card , SCCB_COMPLETE ) ;
FPT_SccbMgrTableInitTarget ( p_card , scsiID ) ;
2005-04-17 02:20:36 +04:00
}
else if ( currSCCB - > Sccb_scsistat = = ABORT_ST )
{
currSCCB - > HostStatus = SCCB_COMPLETE ;
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - > Sccb_tag ] ! = NULL )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ currSCCB - > Sccb_tag ] = NULL ;
FPT_sccbMgrTbl [ p_card ] [ scsiID ] . TarTagQ_Cnt - - ;
2005-04-17 02:20:36 +04:00
}
}
else if ( currSCCB - > Sccb_scsistat < COMMAND_ST )
{
if ( message = = SMNO_OP )
{
currSCCB - > Sccb_MGRFlags | = F_DEV_SELECTED ;
2005-04-24 11:38:05 +04:00
FPT_ssel ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
return ;
}
}
else
{
if ( message = = SMABORT )
2005-04-24 11:38:05 +04:00
FPT_queueFlushSccb ( p_card , SCCB_COMPLETE ) ;
2005-04-17 02:20:36 +04:00
}
}
else
{
message = SMABORT ;
}
WRW_HARPOON ( ( port + hp_intstat ) , ( BUS_FREE | PHASE | XFER_CNT_0 ) ) ;
WR_HARPOON ( port + hp_portctrl_0 , SCSI_BUS_EN ) ;
WR_HARPOON ( port + hp_scsidata_0 , message ) ;
WR_HARPOON ( port + hp_scsisig , ( SCSI_ACK + S_ILL_PH ) ) ;
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
if ( ( message = = SMABORT ) | | ( message = = SMDEV_RESET ) | |
( message = = SMABORT_TAG ) )
{
while ( ! ( RDW_HARPOON ( ( port + hp_intstat ) ) & ( BUS_FREE | PHASE ) ) ) { }
if ( RDW_HARPOON ( ( port + hp_intstat ) ) & BUS_FREE )
{
WRW_HARPOON ( ( port + hp_intstat ) , BUS_FREE ) ;
if ( currSCCB ! = NULL )
{
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] , currSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . globalFlags | = F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
}
}
else
{
2005-04-24 11:38:05 +04:00
FPT_sxfrp ( port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
}
else
{
if ( message = = SMPARITY )
{
currSCCB - > Sccb_scsimsg = SMNO_OP ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
else
{
2005-04-24 11:38:05 +04:00
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:29 +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
2005-04-24 11:38:05 +04: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
}
message = RD_HARPOON ( port + hp_scsidata_0 ) ;
if ( ( message = = SMDISC ) | | ( message = = SMSAVE_DATA_PTR ) )
{
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + END_DATA_START ) ) ;
}
else
{
2005-04-24 11:38:05 +04:00
message = FPT_sfm ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
if ( message )
{
2005-04-24 11:38:05 +04:00
FPT_sdecm ( message , port , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else
{
if ( currSCCB - > Sccb_scsimsg ! = SMPARITY )
ACCEPT_MSG ( port ) ;
WR_HARPOON ( port + hp_autostart_1 , ( AUTO_IMMED + DISCONNECT_START ) ) ;
}
}
}
/*---------------------------------------------------------------------
*
* 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:29 +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
WR_HARPOON ( port + hp_scsisig , RD_HARPOON ( port + hp_scsisig ) ) ;
if ( currSCCB ! = NULL ) {
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
currSCCB - > Sccb_scsistat = ABORT_ST ;
currSCCB - > Sccb_scsimsg = SMABORT ;
}
ACCEPT_MSG_ATN ( port ) ;
}
/*---------------------------------------------------------------------
*
* 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:26 +03:00
unsigned long xfercnt ;
2006-03-08 11:14:29 +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
if ( currSCCB - > Sccb_scsistat = = DATA_IN_ST )
{
while ( ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) ) & &
( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) ) { }
if ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) )
{
currSCCB - > Sccb_ATC + = currSCCB - > Sccb_XferCnt ;
currSCCB - > Sccb_XferCnt = 0 ;
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) )
{
currSCCB - > HostStatus = SCCB_PARITY_ERR ;
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
}
2005-04-24 11:38:05 +04:00
FPT_hostDataXferAbort ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_dataXferProcessor ( port , & FPT_BL_Card [ p_card ] ) ;
2005-04-17 02:20:36 +04:00
while ( ( ! ( RD_HARPOON ( port + hp_xferstat ) & FIFO_EMPTY ) ) & &
( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) ) { }
}
} /*End Data In specific code. */
GET_XFER_CNT ( port , xfercnt ) ;
WR_HARPOON ( port + hp_xfercnt_0 , 0x00 ) ;
WR_HARPOON ( port + hp_portctrl_0 , 0x00 ) ;
currSCCB - > Sccb_ATC + = ( currSCCB - > Sccb_XferCnt - xfercnt ) ;
currSCCB - > Sccb_XferCnt = xfercnt ;
if ( ( RDW_HARPOON ( ( port + hp_intstat ) ) & PARITY ) & &
( currSCCB - > HostStatus = = SCCB_COMPLETE ) ) {
currSCCB - > HostStatus = SCCB_PARITY_ERR ;
WRW_HARPOON ( ( port + hp_intstat ) , PARITY ) ;
}
2005-04-24 11:38:05 +04:00
FPT_hostDataXferAbort ( port , p_card , currSCCB ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_fifowrite , 0x00 ) ;
WR_HARPOON ( port + hp_fiforead , 0x00 ) ;
WR_HARPOON ( port + hp_xferstat , 0x00 ) ;
WRW_HARPOON ( ( port + hp_intstat ) , XFER_CNT_0 ) ;
}
/*---------------------------------------------------------------------
*
* 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:29 +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
if ( currSCCB ! = NULL )
{
DISABLE_AUTO ( port ) ;
if ( currSCCB - > OperationCode = = RESET_COMMAND )
{
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] , currSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_queueSearchSelect ( & FPT_BL_Card [ p_card ] , p_card ) ;
2005-04-17 02:20:36 +04:00
}
else if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST )
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus | =
2006-03-08 11:14:24 +03:00
( unsigned char ) SYNC_SUPPORTED ;
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & = ~ EE_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
else if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST )
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus =
( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
2005-04-17 02:20:36 +04:00
TarStatus & ~ WIDE_ENABLED ) | WIDE_NEGOCIATED ;
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & = ~ EE_WIDE_SCSI ;
2005-04-17 02:20:36 +04:00
}
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 ) )
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus & = ~ TAR_TAG_Q_MASK ;
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus | = TAG_Q_REJECT ;
2005-04-17 02:20:36 +04:00
}
else
{
return ;
}
}
else
{
currSCCB - > Sccb_scsistat = BUS_FREE_ST ;
if ( ! currSCCB - > HostStatus )
{
currSCCB - > HostStatus = SCCB_PHASE_SEQUENCE_FAIL ;
}
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_queueCmdComplete ( & FPT_BL_Card [ p_card ] , currSCCB , p_card ) ;
2005-04-17 02:20:36 +04:00
return ;
}
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . globalFlags | = F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
} /*end if !=null */
}
/*---------------------------------------------------------------------
*
* 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:26 +03:00
unsigned long map_addr ;
2005-04-17 02:20:36 +04:00
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 ) ;
}
/*---------------------------------------------------------------------
*
* 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:29 +03:00
struct sccb * currSCCB ;
2006-03-08 11:14:24 +03:00
unsigned char status_byte ;
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
status_byte = RD_HARPOON ( p_port + hp_gp_reg_0 ) ;
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUN_CA = 0 ;
2005-04-17 02:20:36 +04:00
if ( status_byte ! = SSGOOD ) {
if ( status_byte = = SSQ_FULL ) {
2005-04-24 11:38:05 +04: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 ) ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_tag )
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
} else
{
2005-04-24 11:38:05 +04:00
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
}
}
currSCCB - > Sccb_MGRFlags | = F_STATUSLOADED ;
2005-04-24 11:38:05 +04:00
FPT_queueSelectFail ( & FPT_BL_Card [ p_card ] , p_card ) ;
2005-04-17 02:20:36 +04:00
return ;
}
if ( currSCCB - > Sccb_scsistat = = SELECT_SN_ST )
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus | =
2006-03-08 11:14:24 +03:00
( unsigned char ) SYNC_SUPPORTED ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04: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 ) ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_tag )
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
} else
{
2005-04-24 11:38:05 +04:00
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
}
}
return ;
}
if ( currSCCB - > Sccb_scsistat = = SELECT_WN_ST )
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus =
( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] .
2005-04-17 02:20:36 +04:00
TarStatus & ~ WIDE_ENABLED ) | WIDE_NEGOCIATED ;
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04: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 ) ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_tag )
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
} else
{
2005-04-24 11:38:05 +04:00
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
}
}
return ;
}
if ( status_byte = = SSCHECK )
{
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ p_card ] . globalFlags & F_DO_RENEGO )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
if ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & EE_SYNC_MASK )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus & = ~ TAR_SYNC_MASK ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarEEValue & EE_WIDE_SCSI )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarStatus & = ~ TAR_WIDE_MASK ;
2005-04-17 02:20:36 +04:00
}
}
}
if ( ! ( currSCCB - > Sccb_XferState & F_AUTO_SENSE ) ) {
currSCCB - > SccbStatus = SCCB_ERROR ;
currSCCB - > TargetStatus = status_byte ;
if ( status_byte = = SSCHECK ) {
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUN_CA
= 1 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > RequestSenseLength ! = NO_AUTO_REQUEST_SENSE ) {
if ( currSCCB - > RequestSenseLength = = 0 )
currSCCB - > RequestSenseLength = 14 ;
2005-04-24 11:38:05 +04:00
FPT_ssenss ( & FPT_BL_Card [ p_card ] ) ;
FPT_BL_Card [ p_card ] . globalFlags | = F_NEW_SCCB_CMD ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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 ) ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
}
else
{
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 1 ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_tag )
{
2005-04-24 11:38:05 +04:00
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 ;
2005-04-17 02:20:36 +04:00
} else
{
2005-04-24 11:38:05 +04:00
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
}
}
return ;
}
}
}
}
2005-04-24 11:38:05 +04: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
2005-04-24 11:38:05 +04:00
FPT_sccbMgrTbl [ p_card ] [ currSCCB - > TargID ] . TarLUNBusy [ 0 ] = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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:26 +03:00
static void FPT_dataXferProcessor ( unsigned long port , PSCCBcard pCurrCard )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
currSCCB = pCurrCard - > currentSCCB ;
if ( currSCCB - > Sccb_XferState & F_SG_XFER )
{
if ( pCurrCard - > globalFlags & F_HOST_XFER_ACT )
{
2006-03-08 11:14:24 +03:00
currSCCB - > Sccb_sgseg + = ( unsigned char ) SG_BUF_CNT ;
2005-04-17 02:20:36 +04:00
currSCCB - > Sccb_SGoffset = 0x00 ;
}
pCurrCard - > globalFlags | = F_HOST_XFER_ACT ;
2005-04-24 11:38:05 +04:00
FPT_busMstrSGDataXferStart ( port , currSCCB ) ;
2005-04-17 02:20:36 +04:00
}
else
{
if ( ! ( pCurrCard - > globalFlags & F_HOST_XFER_ACT ) )
{
pCurrCard - > globalFlags | = F_HOST_XFER_ACT ;
2005-04-24 11:38:05 +04: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:29 +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:26 +03:00
unsigned long count , addr , tmpSGCnt ;
2006-03-08 11:14:26 +03:00
unsigned int sg_index ;
2006-03-08 11:14:24 +03:00
unsigned char sg_count , i ;
2006-03-08 11:14:26 +03:00
unsigned long reg_offset ;
2005-04-17 02:20:36 +04:00
if ( pcurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
2006-03-08 11:14:26 +03:00
count = ( ( unsigned long ) HOST_RD_CMD ) < < 24 ;
2005-04-17 02:20:36 +04:00
}
else {
2006-03-08 11:14:26 +03:00
count = ( ( unsigned long ) HOST_WRT_CMD ) < < 24 ;
2005-04-17 02:20:36 +04:00
}
sg_count = 0 ;
tmpSGCnt = 0 ;
sg_index = pcurrSCCB - > Sccb_sgseg ;
reg_offset = hp_aramBase ;
2006-03-08 11:14:24 +03:00
i = ( unsigned char ) ( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ ( SGRAM_ARAM | SCATTER_EN ) ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_page_ctrl , i ) ;
2006-03-08 11:14:24 +03:00
while ( ( sg_count < ( unsigned char ) SG_BUF_CNT ) & &
2006-03-08 11:14:26 +03:00
( ( unsigned long ) ( sg_index * ( unsigned int ) SG_ELEMENT_SIZE ) < pcurrSCCB - > DataLength ) ) {
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
tmpSGCnt + = * ( ( ( unsigned long * ) pcurrSCCB - > DataPointer ) +
2005-04-17 02:20:36 +04:00
( sg_index * 2 ) ) ;
2006-03-08 11:14:26 +03:00
count | = * ( ( ( unsigned long * ) pcurrSCCB - > DataPointer ) +
2005-04-17 02:20:36 +04:00
( sg_index * 2 ) ) ;
2006-03-08 11:14:26 +03:00
addr = * ( ( ( unsigned long * ) pcurrSCCB - > DataPointer ) +
2005-04-17 02:20:36 +04:00
( ( sg_index * 2 ) + 1 ) ) ;
if ( ( ! sg_count ) & & ( pcurrSCCB - > Sccb_SGoffset ) ) {
addr + = ( ( count & 0x00FFFFFFL ) - pcurrSCCB - > Sccb_SGoffset ) ;
count = ( count & 0xFF000000L ) | pcurrSCCB - > Sccb_SGoffset ;
tmpSGCnt = count & 0x00FFFFFFL ;
}
WR_HARP32 ( p_port , reg_offset , addr ) ;
reg_offset + = 4 ;
WR_HARP32 ( p_port , reg_offset , count ) ;
reg_offset + = 4 ;
count & = 0xFF000000L ;
sg_index + + ;
sg_count + + ;
} /*End While */
pcurrSCCB - > Sccb_XferCnt = tmpSGCnt ;
WR_HARPOON ( p_port + hp_sg_addr , ( sg_count < < 4 ) ) ;
if ( pcurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
WR_HARP32 ( p_port , hp_xfercnt_0 , tmpSGCnt ) ;
WR_HARPOON ( p_port + hp_portctrl_0 , ( DMA_PORT | SCSI_PORT | SCSI_INBIT ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAI_PH ) ;
}
else {
if ( ( ! ( RD_HARPOON ( p_port + hp_synctarg_0 ) & NARROW_SCSI ) ) & &
( tmpSGCnt & 0x000000001 ) )
{
pcurrSCCB - > Sccb_XferState | = F_ODD_BALL_CNT ;
tmpSGCnt - - ;
}
WR_HARP32 ( p_port , hp_xfercnt_0 , tmpSGCnt ) ;
WR_HARPOON ( p_port + hp_portctrl_0 , ( SCSI_PORT | DMA_PORT | DMA_RD ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAO_PH ) ;
}
2006-03-08 11:14:24 +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:29 +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:26 +03:00
unsigned long addr , count ;
2005-04-17 02:20:36 +04:00
if ( ! ( pcurrSCCB - > Sccb_XferState & F_AUTO_SENSE ) ) {
count = pcurrSCCB - > Sccb_XferCnt ;
2006-03-08 11:14:26 +03:00
addr = ( unsigned long ) pcurrSCCB - > DataPointer + pcurrSCCB - > Sccb_ATC ;
2005-04-17 02:20:36 +04:00
}
else {
addr = pcurrSCCB - > SensePointer ;
count = pcurrSCCB - > RequestSenseLength ;
}
HP_SETUP_ADDR_CNT ( p_port , addr , count ) ;
if ( pcurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) {
WR_HARPOON ( p_port + hp_portctrl_0 , ( DMA_PORT | SCSI_PORT | SCSI_INBIT ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAI_PH ) ;
WR_HARPOON ( p_port + hp_xfer_cmd ,
( XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT ) ) ;
}
else {
WR_HARPOON ( p_port + hp_portctrl_0 , ( SCSI_PORT | DMA_PORT | DMA_RD ) ) ;
WR_HARPOON ( p_port + hp_scsisig , S_DATAO_PH ) ;
WR_HARPOON ( p_port + hp_xfer_cmd ,
( XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT ) ) ;
}
}
/*---------------------------------------------------------------------
*
* 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:26 +03:00
unsigned long timeout ;
2005-04-17 02:20:36 +04:00
timeout = LONG_WAIT ;
WR_HARPOON ( p_port + hp_sys_ctrl , HALT_MACH ) ;
while ( ( ! ( RD_HARPOON ( p_port + hp_ext_status ) & CMD_ABORTED ) ) & & timeout - - ) { }
if ( RD_HARPOON ( p_port + hp_ext_status ) & BM_CMD_BUSY ) {
WR_HARPOON ( p_port + hp_sys_ctrl , HARD_ABORT ) ;
timeout = LONG_WAIT ;
while ( ( RD_HARPOON ( p_port + hp_ext_status ) & BM_CMD_BUSY ) & & timeout - - ) { }
}
RD_HARPOON ( p_port + hp_int_status ) ; /*Clear command complete */
if ( RD_HARPOON ( p_port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-24 11:38:05 +04:00
return ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
else {
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
2005-04-17 02:20:36 +04:00
}
}
/*---------------------------------------------------------------------
*
* Function : Host Data Transfer Abort
*
* Description : Abort any in progress transfer .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:29 +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:26 +03:00
unsigned long timeout ;
unsigned long remain_cnt ;
2006-03-08 11:14:26 +03:00
unsigned int sg_ptr ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . globalFlags & = ~ F_HOST_XFER_ACT ;
2005-04-17 02:20:36 +04:00
if ( pCurrSCCB - > Sccb_XferState & F_AUTO_SENSE ) {
if ( ! ( RD_HARPOON ( port + hp_int_status ) & INT_CMD_COMPL ) ) {
WR_HARPOON ( port + hp_bm_ctrl , ( RD_HARPOON ( port + hp_bm_ctrl ) | FLUSH_XFER_CNTR ) ) ;
timeout = LONG_WAIT ;
while ( ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) & & timeout - - ) { }
WR_HARPOON ( port + hp_bm_ctrl , ( RD_HARPOON ( port + hp_bm_ctrl ) & ~ FLUSH_XFER_CNTR ) ) ;
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-24 11:38:05 +04:00
if ( FPT_busMstrTimeOut ( port ) ) {
2005-04-17 02:20:36 +04:00
if ( pCurrSCCB - > HostStatus = = 0x00 )
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
if ( RD_HARPOON ( port + hp_int_status ) & INT_EXT_STATUS )
if ( RD_HARPOON ( port + hp_ext_status ) & BAD_EXT_STATUS )
if ( pCurrSCCB - > HostStatus = = 0x00 )
{
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
}
}
}
else if ( pCurrSCCB - > Sccb_XferCnt ) {
if ( pCurrSCCB - > Sccb_XferState & F_SG_XFER ) {
WR_HARPOON ( port + hp_page_ctrl , ( RD_HARPOON ( port + hp_page_ctrl ) &
~ SCATTER_EN ) ) ;
WR_HARPOON ( port + hp_sg_addr , 0x00 ) ;
sg_ptr = pCurrSCCB - > Sccb_sgseg + SG_BUF_CNT ;
2006-03-08 11:14:26 +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:26 +03:00
sg_ptr = ( unsigned int ) ( pCurrSCCB - > DataLength / SG_ELEMENT_SIZE ) ;
2005-04-17 02:20:36 +04:00
}
remain_cnt = pCurrSCCB - > Sccb_XferCnt ;
while ( remain_cnt < 0x01000000L ) {
sg_ptr - - ;
2006-03-08 11:14:26 +03:00
if ( remain_cnt > ( unsigned long ) ( * ( ( ( unsigned long * ) pCurrSCCB - >
2005-04-17 02:20:36 +04:00
DataPointer ) + ( sg_ptr * 2 ) ) ) ) {
2006-03-08 11:14:26 +03:00
remain_cnt - = ( unsigned long ) ( * ( ( ( unsigned long * ) pCurrSCCB - >
2005-04-17 02:20:36 +04:00
DataPointer ) + ( sg_ptr * 2 ) ) ) ;
}
else {
break ;
}
}
if ( remain_cnt < 0x01000000L ) {
pCurrSCCB - > Sccb_SGoffset = remain_cnt ;
2006-03-08 11:14:25 +03:00
pCurrSCCB - > Sccb_sgseg = ( unsigned short ) sg_ptr ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:26 +03:00
if ( ( unsigned long ) ( sg_ptr * SG_ELEMENT_SIZE ) = = pCurrSCCB - > DataLength
2005-04-17 02:20:36 +04:00
& & ( remain_cnt = = 0 ) )
pCurrSCCB - > Sccb_XferState | = F_ALL_XFERRED ;
}
else {
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
pCurrSCCB - > HostStatus = SCCB_GROSS_FW_ERR ;
}
}
}
if ( ! ( pCurrSCCB - > Sccb_XferState & F_HOST_XFER_DIR ) ) {
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
2005-04-24 11:38:05 +04:00
FPT_busMstrTimeOut ( port ) ;
2005-04-17 02:20:36 +04:00
}
else {
if ( RD_HARPOON ( port + hp_int_status ) & INT_EXT_STATUS ) {
if ( RD_HARPOON ( port + hp_ext_status ) & BAD_EXT_STATUS ) {
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
}
}
}
}
else {
if ( ( RD_HARPOON ( port + hp_fifo_cnt ) ) > = BM_THRESHOLD ) {
timeout = SHORT_WAIT ;
while ( ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) & &
( ( RD_HARPOON ( port + hp_fifo_cnt ) ) > = BM_THRESHOLD ) & &
timeout - - ) { }
}
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
WR_HARPOON ( port + hp_bm_ctrl , ( RD_HARPOON ( port + hp_bm_ctrl ) |
FLUSH_XFER_CNTR ) ) ;
timeout = LONG_WAIT ;
while ( ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) & &
timeout - - ) { }
WR_HARPOON ( port + hp_bm_ctrl , ( RD_HARPOON ( port + hp_bm_ctrl ) &
~ FLUSH_XFER_CNTR ) ) ;
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
2005-04-24 11:38:05 +04:00
FPT_busMstrTimeOut ( port ) ;
2005-04-17 02:20:36 +04:00
}
}
if ( RD_HARPOON ( port + hp_int_status ) & INT_EXT_STATUS ) {
if ( RD_HARPOON ( port + hp_ext_status ) & BAD_EXT_STATUS ) {
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
}
}
}
}
else {
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
timeout = LONG_WAIT ;
while ( ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) & & timeout - - ) { }
if ( RD_HARPOON ( port + hp_ext_status ) & BM_CMD_BUSY ) {
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
2005-04-24 11:38:05 +04:00
FPT_busMstrTimeOut ( port ) ;
2005-04-17 02:20:36 +04:00
}
}
if ( RD_HARPOON ( port + hp_int_status ) & INT_EXT_STATUS ) {
if ( RD_HARPOON ( port + hp_ext_status ) & BAD_EXT_STATUS ) {
if ( pCurrSCCB - > HostStatus = = 0x00 ) {
pCurrSCCB - > HostStatus = SCCB_BM_ERR ;
}
}
}
if ( pCurrSCCB - > Sccb_XferState & F_SG_XFER ) {
WR_HARPOON ( port + hp_page_ctrl , ( RD_HARPOON ( port + hp_page_ctrl ) &
~ SCATTER_EN ) ) ;
WR_HARPOON ( port + hp_sg_addr , 0x00 ) ;
pCurrSCCB - > Sccb_sgseg + = SG_BUF_CNT ;
pCurrSCCB - > Sccb_SGoffset = 0x00 ;
2006-03-08 11:14:26 +03:00
if ( ( unsigned long ) ( pCurrSCCB - > Sccb_sgseg * SG_ELEMENT_SIZE ) > =
2005-04-17 02:20:36 +04:00
pCurrSCCB - > DataLength ) {
pCurrSCCB - > Sccb_XferState | = F_ALL_XFERRED ;
2006-03-08 11:14:25 +03:00
pCurrSCCB - > Sccb_sgseg = ( unsigned short ) ( pCurrSCCB - > DataLength / SG_ELEMENT_SIZE ) ;
2005-04-17 02:20:36 +04:00
}
}
else {
if ( ! ( pCurrSCCB - > Sccb_XferState & F_AUTO_SENSE ) )
pCurrSCCB - > Sccb_XferState | = F_ALL_XFERRED ;
}
}
WR_HARPOON ( port + hp_int_mask , ( INT_CMD_COMPL | SCSI_INTERRUPT ) ) ;
}
/*---------------------------------------------------------------------
*
* Function : Host Data Transfer Restart
*
* Description : Reset the available count due to a restore data
* pointers message .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:29 +03:00
static void FPT_hostDataXferRestart ( struct sccb * currSCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:26 +03:00
unsigned long data_count ;
2006-03-08 11:14:26 +03:00
unsigned int sg_index ;
2006-03-08 11:14:26 +03:00
unsigned long * sg_ptr ;
2005-04-17 02:20:36 +04:00
if ( currSCCB - > Sccb_XferState & F_SG_XFER ) {
currSCCB - > Sccb_XferCnt = 0 ;
sg_index = 0xffff ; /*Index by long words into sg list. */
data_count = 0 ; /*Running count of SG xfer counts. */
2006-03-08 11:14:26 +03:00
sg_ptr = ( unsigned long * ) currSCCB - > DataPointer ;
2005-04-17 02:20:36 +04:00
while ( data_count < currSCCB - > Sccb_ATC ) {
sg_index + + ;
data_count + = * ( sg_ptr + ( sg_index * 2 ) ) ;
}
if ( data_count = = currSCCB - > Sccb_ATC ) {
currSCCB - > Sccb_SGoffset = 0 ;
sg_index + + ;
}
else {
currSCCB - > Sccb_SGoffset = data_count - currSCCB - > Sccb_ATC ;
}
2006-03-08 11:14:25 +03:00
currSCCB - > Sccb_sgseg = ( unsigned short ) sg_index ;
2005-04-17 02:20:36 +04:00
}
else {
currSCCB - > Sccb_XferCnt = currSCCB - > DataLength - currSCCB - > Sccb_ATC ;
}
}
/*---------------------------------------------------------------------
*
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:24 +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:24 +03:00
unsigned char loser , assigned_id ;
2006-03-08 11:14:26 +03:00
unsigned long p_port ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
unsigned char i , k , ScamFlg ;
2005-04-17 02:20:36 +04:00
PSCCBcard currCard ;
PNVRamInfo pCurrNvRam ;
2005-04-24 11:38:05 +04:00
currCard = & FPT_BL_Card [ p_card ] ;
2005-04-17 02:20:36 +04:00
p_port = currCard - > ioPort ;
pCurrNvRam = currCard - > pNvRamInfo ;
if ( pCurrNvRam ) {
ScamFlg = pCurrNvRam - > niScamConf ;
i = pCurrNvRam - > niSysConf ;
}
else {
2006-03-08 11:14:24 +03:00
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
}
if ( ! ( i & 0x02 ) ) /* check if reset bus in AutoSCSI parameter set */
return ;
2005-04-24 11:38:05 +04:00
FPT_inisci ( p_card , p_port , p_our_id ) ;
2005-04-17 02:20:36 +04:00
/* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
too slow to return to SCAM selection */
/* if (p_power_up)
2005-04-24 11:38:05 +04:00
FPT_Wait1Second ( p_port ) ;
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
FPT_Wait ( p_port , TO_250ms ) ; */
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_Wait1Second ( p_port ) ;
2005-04-17 02:20:36 +04:00
if ( ( ScamFlg & SCAM_ENABLED ) & & ( ScamFlg & SCAM_LEVEL2 ) )
{
2005-04-24 11:38:05 +04:00
while ( ! ( FPT_scarb ( p_port , INIT_SELTD ) ) ) { }
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_scsel ( p_port ) ;
2005-04-17 02:20:36 +04:00
do {
2005-04-24 11:38:05 +04:00
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 ] ) ;
2005-04-17 02:20:36 +04:00
} while ( loser = = 0xFF ) ;
2005-04-24 11:38:05 +04:00
FPT_scbusf ( p_port ) ;
2005-04-17 02:20:36 +04:00
if ( ( p_power_up ) & & ( ! loser ) )
{
2005-04-24 11:38:05 +04:00
FPT_sresb ( p_port , p_card ) ;
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
while ( ! ( FPT_scarb ( p_port , INIT_SELTD ) ) ) { }
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_scsel ( p_port ) ;
2005-04-17 02:20:36 +04:00
do {
2005-04-24 11:38:05 +04:00
FPT_scxferc ( p_port , SYNC_PTRN ) ;
FPT_scxferc ( p_port , DOM_MSTR ) ;
loser = FPT_scsendi ( p_port , & FPT_scamInfo [ p_our_id ] .
2005-04-17 02:20:36 +04:00
id_string [ 0 ] ) ;
} while ( loser = = 0xFF ) ;
2005-04-24 11:38:05 +04:00
FPT_scbusf ( p_port ) ;
2005-04-17 02:20:36 +04:00
}
}
else
{
2005-04-24 11:38:05 +04:00
loser = 0 ;
2005-04-17 02:20:36 +04:00
}
if ( ! loser )
{
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ p_our_id ] . state = ID_ASSIGNED ;
2005-04-17 02:20:36 +04:00
if ( ScamFlg & SCAM_ENABLED )
{
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + )
{
2005-04-24 11:38:05 +04:00
if ( ( FPT_scamInfo [ i ] . state = = ID_UNASSIGNED ) | |
( FPT_scamInfo [ i ] . state = = ID_UNUSED ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
if ( FPT_scsell ( p_port , i ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . state = LEGACY ;
if ( ( FPT_scamInfo [ i ] . id_string [ 0 ] ! = 0xFF ) | |
( FPT_scamInfo [ i ] . id_string [ 1 ] ! = 0xFA ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . id_string [ 0 ] = 0xFF ;
FPT_scamInfo [ i ] . id_string [ 1 ] = 0xFA ;
2005-04-17 02:20:36 +04:00
if ( pCurrNvRam = = NULL )
currCard - > globalFlags | = F_UPDATE_EEPROM ;
}
}
}
}
2005-04-24 11:38:05 +04: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
}
}
else if ( ( loser ) & & ( ScamFlg & SCAM_ENABLED ) )
{
2005-04-24 11:38:05 +04:00
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
do {
2005-04-24 11:38:05 +04:00
while ( FPT_scxferc ( p_port , 0x00 ) ! = SYNC_PTRN ) { }
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
i = FPT_scxferc ( p_port , 0x00 ) ;
2005-04-17 02:20:36 +04:00
if ( i = = ASSIGN_ID )
{
2005-04-24 11:38:05 +04:00
if ( ! ( FPT_scsendi ( p_port , & FPT_scamInfo [ p_our_id ] . id_string [ 0 ] ) ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
i = FPT_scxferc ( p_port , 0x00 ) ;
if ( FPT_scvalq ( i ) )
2005-04-17 02:20:36 +04:00
{
2005-04-24 11:38:05 +04:00
k = FPT_scxferc ( p_port , 0x00 ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( FPT_scvalq ( k ) )
2005-04-17 02:20:36 +04:00
{
currCard - > ourId =
2006-03-08 11:14:24 +03:00
( ( unsigned char ) ( i < < 3 ) + ( k & ( unsigned char ) 7 ) ) & ( unsigned char ) 0x3F ;
2005-04-24 11:38:05 +04:00
FPT_inisci ( p_card , p_port , p_our_id ) ;
FPT_scamInfo [ currCard - > ourId ] . state = ID_ASSIGNED ;
FPT_scamInfo [ currCard - > ourId ] . id_string [ 0 ]
2005-04-17 02:20:36 +04:00
= SLV_TYPE_CODE0 ;
2005-04-24 11:38:05 +04:00
assigned_id = 1 ;
2005-04-17 02:20:36 +04:00
}
}
}
}
else if ( i = = SET_P_FLAG )
{
2005-04-24 11:38:05 +04:00
if ( ! ( FPT_scsendi ( p_port ,
& FPT_scamInfo [ p_our_id ] . id_string [ 0 ] ) ) )
FPT_scamInfo [ p_our_id ] . id_string [ 0 ] | = 0x80 ;
2005-04-17 02:20:36 +04:00
}
} while ( ! assigned_id ) ;
2005-04-24 11:38:05 +04:00
while ( FPT_scxferc ( p_port , 0x00 ) ! = CFG_CMPLT ) { }
2005-04-17 02:20:36 +04:00
}
if ( ScamFlg & SCAM_ENABLED )
{
2005-04-24 11:38:05 +04:00
FPT_scbusf ( p_port ) ;
2005-04-17 02:20:36 +04:00
if ( currCard - > globalFlags & F_UPDATE_EEPROM )
{
2005-04-24 11:38:05 +04:00
FPT_scsavdi ( p_card , p_port ) ;
2005-04-17 02:20:36 +04:00
currCard - > globalFlags & = ~ F_UPDATE_EEPROM ;
}
}
/*
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
{
if ( p_sel_type = = INIT_SELTD )
{
while ( RD_HARPOON ( p_port + hp_scsisig ) & ( SCSI_SEL | SCSI_BSY ) ) { }
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_SEL )
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
2005-04-17 02:20:36 +04:00
if ( RD_HARPOON ( p_port + hp_scsidata_0 ) ! = 00 )
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig ) | SCSI_BSY ) ) ;
if ( RD_HARPOON ( p_port + hp_scsisig ) & SCSI_SEL ) {
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig ) &
~ SCSI_BSY ) ) ;
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
2005-04-17 02:20:36 +04:00
}
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig ) | SCSI_SEL ) ) ;
if ( RD_HARPOON ( p_port + hp_scsidata_0 ) ! = 00 ) {
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig ) &
~ ( SCSI_BSY | SCSI_SEL ) ) ) ;
2005-04-24 11:38:05 +04:00
return ( 0 ) ;
2005-04-17 02:20:36 +04: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 ) ;
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig ) | SCSI_MSG ) ) ;
WR_HARPOON ( p_port + hp_scsisig , ( RD_HARPOON ( p_port + hp_scsisig )
& ~ SCSI_BSY ) ) ;
2005-04-24 11:38:05 +04:00
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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
{
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) | G_INT_DISABLE ) ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , 0x00 ) ;
WR_HARPOON ( p_port + hp_portctrl_0 , ( RD_HARPOON ( p_port + hp_portctrl_0 )
& ~ SCSI_BUS_EN ) ) ;
WR_HARPOON ( p_port + hp_scsisig , 0x00 ) ;
WR_HARPOON ( p_port + hp_scsireset , ( RD_HARPOON ( p_port + hp_scsireset )
& ~ SCAM_EN ) ) ;
WR_HARPOON ( p_port + hp_clkctrl_0 , ( RD_HARPOON ( p_port + hp_clkctrl_0 )
| ACTdeassert ) ) ;
WRW_HARPOON ( ( p_port + hp_intstat ) , ( BUS_FREE | AUTO_INT | SCAM_SEL ) ) ;
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) ;
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char temp_id_string [ ID_STRING_LENGTH ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
unsigned char i , k , scam_id ;
unsigned char crcBytes [ 3 ] ;
2005-04-17 02:20:36 +04:00
PNVRamInfo pCurrNvRam ;
2006-03-08 11:14:27 +03:00
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
2005-04-24 11:38:05 +04:00
i = 0 ;
2005-04-17 02:20:36 +04:00
while ( ! i )
{
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + )
{
2006-03-08 11:14:24 +03:00
temp_id_string [ k ] = ( unsigned char ) 0x00 ;
2005-04-17 02:20:36 +04:00
}
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
2005-04-24 11:38:05 +04:00
if ( ! ( FPT_sciso ( p_port , & temp_id_string [ 0 ] ) ) )
2005-04-17 02:20:36 +04:00
{
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 ] ;
for ( k = 4 ; k < ID_STRING_LENGTH ; k + + )
2006-03-08 11:14:24 +03:00
temp_id_string [ k ] = ( unsigned char ) 0x00 ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
i = FPT_scmachid ( p_card , temp_id_string ) ;
2005-04-17 02:20:36 +04:00
if ( i = = CLR_PRIORITY )
{
2005-04-24 11:38:05 +04:00
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
}
else if ( i ! = NO_ID_AVAIL )
{
if ( i < 8 )
2005-04-24 11:38:05 +04:00
FPT_scxferc ( p_port , ID_0_7 ) ;
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
FPT_scxferc ( p_port , ID_8_F ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
scam_id = ( i & ( unsigned char ) 0x07 ) ;
2005-04-17 02:20:36 +04:00
for ( k = 1 ; k < 0x08 ; k < < = 1 )
if ( ! ( k & i ) )
scam_id + = 0x08 ; /*Count number of zeros in DB0-3. */
2005-04-24 11:38:05 +04:00
FPT_scxferc ( p_port , scam_id ) ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
i = 0 ; /*Not the last ID yet. */
2005-04-17 02:20:36 +04:00
}
}
else
{
2005-04-24 11:38:05 +04:00
i = 1 ;
2005-04-17 02:20:36 +04:00
}
} /*End while */
2005-04-24 11:38:05 +04: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
{
WR_HARPOON ( p_port + hp_scsisig , SCSI_SEL ) ;
2005-04-24 11:38:05 +04:00
FPT_scwiros ( p_port , SCSI_MSG ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_scsisig , ( SCSI_SEL | SCSI_BSY ) ) ;
WR_HARPOON ( p_port + hp_scsisig , ( SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD ) ) ;
2006-03-08 11:14:24 +03:00
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
WR_HARPOON ( p_port + hp_scsisig , ( SCSI_BSY | SCSI_IOBIT | SCSI_CD ) ) ;
2005-04-24 11:38:05 +04:00
FPT_scwiros ( p_port , SCSI_SEL ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
WR_HARPOON ( p_port + hp_scsidata_0 , ( unsigned char ) ( RD_HARPOON ( p_port + hp_scsidata_0 ) &
~ ( unsigned char ) BIT ( 6 ) ) ) ;
2005-04-24 11:38:05 +04:00
FPT_scwirod ( p_port , BIT ( 6 ) ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_scsisig , ( SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD ) ) ;
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char curr_data , ret_data ;
2005-04-17 02:20:36 +04:00
curr_data = p_data | BIT ( 7 ) | BIT ( 5 ) ; /*Start with DB7 & DB5 asserted. */
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
curr_data & = ~ BIT ( 7 ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-24 11:38:05 +04:00
FPT_scwirod ( p_port , BIT ( 7 ) ) ; /*Wait for DB7 to be released. */
2005-04-17 02:20:36 +04:00
while ( ! ( RD_HARPOON ( p_port + hp_scsidata_0 ) & BIT ( 5 ) ) ) ;
2006-03-08 11:14:24 +03:00
ret_data = ( RD_HARPOON ( p_port + hp_scsidata_0 ) & ( unsigned char ) 0x1F ) ;
2005-04-17 02:20:36 +04:00
curr_data | = BIT ( 6 ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
curr_data & = ~ BIT ( 5 ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-24 11:38:05 +04:00
FPT_scwirod ( p_port , BIT ( 5 ) ) ; /*Wait for DB5 to be released. */
2005-04-17 02:20:36 +04:00
curr_data & = ~ ( BIT ( 4 ) | BIT ( 3 ) | BIT ( 2 ) | BIT ( 1 ) | BIT ( 0 ) ) ; /*Release data bits */
curr_data | = BIT ( 7 ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
curr_data & = ~ BIT ( 6 ) ;
WR_HARPOON ( p_port + hp_scsidata_0 , curr_data ) ;
2005-04-24 11:38:05 +04:00
FPT_scwirod ( p_port , BIT ( 6 ) ) ; /*Wait for DB6 to be released. */
2005-04-17 02:20:36 +04:00
return ( ret_data ) ;
}
/*---------------------------------------------------------------------
*
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:26 +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:24 +03:00
unsigned char ret_data , byte_cnt , bit_cnt , defer ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
defer = 0 ;
2005-04-17 02:20:36 +04:00
for ( byte_cnt = 0 ; byte_cnt < ID_STRING_LENGTH ; byte_cnt + + ) {
for ( bit_cnt = 0x80 ; bit_cnt ! = 0 ; bit_cnt > > = 1 ) {
if ( defer )
2005-04-24 11:38:05 +04:00
ret_data = FPT_scxferc ( p_port , 00 ) ;
2005-04-17 02:20:36 +04:00
else if ( p_id_string [ byte_cnt ] & bit_cnt )
2005-04-24 11:38:05 +04:00
ret_data = FPT_scxferc ( p_port , 02 ) ;
2005-04-17 02:20:36 +04:00
else {
2005-04-24 11:38:05 +04:00
ret_data = FPT_scxferc ( p_port , 01 ) ;
2005-04-17 02:20:36 +04:00
if ( ret_data & 02 )
2005-04-24 11:38:05 +04:00
defer = 1 ;
2005-04-17 02:20:36 +04:00
}
if ( ( ret_data & 0x1C ) = = 0x10 )
return ( 0x00 ) ; /*End of isolation stage, we won! */
if ( ret_data & 0x1C )
return ( 0xFF ) ;
if ( ( defer ) & & ( ! ( ret_data & 0x1F ) ) )
return ( 0x01 ) ; /*End of isolation stage, we lost. */
} /*bit loop */
} /*byte loop */
if ( defer )
return ( 0x01 ) ; /*We lost */
else
return ( 0 ) ; /*We WON! Yeeessss! */
}
/*---------------------------------------------------------------------
*
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:26 +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:24 +03:00
unsigned char ret_data , the_data , byte_cnt , bit_cnt ;
2005-04-17 02:20:36 +04:00
the_data = 0 ;
for ( byte_cnt = 0 ; byte_cnt < ID_STRING_LENGTH ; byte_cnt + + ) {
for ( bit_cnt = 0 ; bit_cnt < 8 ; bit_cnt + + ) {
2005-04-24 11:38:05 +04:00
ret_data = FPT_scxferc ( p_port , 0 ) ;
2005-04-17 02:20:36 +04:00
if ( ret_data & 0xFC )
return ( 0xFF ) ;
else {
the_data < < = 1 ;
if ( ret_data & BIT ( 1 ) ) {
the_data | = 1 ;
}
}
if ( ( ret_data & 0x1F ) = = 0 )
{
/*
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 ;
}
*/
if ( byte_cnt )
return ( 0x00 ) ;
else
return ( 0xFF ) ;
}
} /*bit loop */
p_id_string [ byte_cnt ] = the_data ;
} /*byte loop */
return ( 0 ) ;
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
i = 0 ;
while ( i < MAX_SCSI_TAR ) {
if ( RD_HARPOON ( p_port + hp_scsidata_0 ) & p_data_bit )
i = 0 ;
else
i + + ;
}
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
i = 0 ;
while ( i < MAX_SCSI_TAR ) {
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( RD_HARPOON ( p_port + hp_scsisig ) & p_data_bit )
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
i = 0 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
else
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
i + + ;
2005-04-17 02:20:36 +04: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:24 +03:00
unsigned char count ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
for ( count = 1 ; count < 0x08 ; count < < = 1 ) {
if ( ! ( p_quintet & count ) )
p_quintet - = 0x80 ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( p_quintet & 0x18 )
return ( 0 ) ;
else
return ( 1 ) ;
2005-04-17 02:20:36 +04: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_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:26 +03:00
unsigned long i ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) | G_INT_DISABLE ) ) ;
ARAM_ACCESS ( p_port ) ;
WR_HARPOON ( p_port + hp_addstat , ( RD_HARPOON ( p_port + hp_addstat ) | SCAM_TIMER ) ) ;
2005-04-24 11:38:05 +04:00
WR_HARPOON ( p_port + hp_seltimeout , TO_4ms ) ;
2005-04-17 02:20:36 +04: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 ) ) ;
WRW_HARPOON ( ( p_port + hp_intstat ) ,
( RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT ) ) ;
WR_HARPOON ( p_port + hp_select_id , targ_id ) ;
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 ) ) ;
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) &
( RESET | PROG_HLT | TIMEOUT | AUTO_INT ) ) ) { }
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & RESET )
2005-04-24 11:38:05 +04:00
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
DISABLE_AUTO ( p_port ) ;
WR_HARPOON ( p_port + hp_addstat , ( RD_HARPOON ( p_port + hp_addstat ) & ~ SCAM_TIMER ) ) ;
WR_HARPOON ( p_port + hp_seltimeout , TO_290ms ) ;
SGRAM_ACCESS ( p_port ) ;
if ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & ( RESET | TIMEOUT ) ) {
WRW_HARPOON ( ( p_port + hp_intstat ) ,
( RESET | TIMEOUT | SEL | BUS_FREE | PHASE ) ) ;
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) ;
2005-04-24 11:38:05 +04:00
return ( 0 ) ; /*No legacy device */
2005-04-17 02:20:36 +04:00
}
else {
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 ) ;
}
}
WRW_HARPOON ( ( p_port + hp_intstat ) , CLR_ALL_INT_1 ) ;
WR_HARPOON ( p_port + hp_page_ctrl ,
( RD_HARPOON ( p_port + hp_page_ctrl ) & ~ G_INT_DISABLE ) ) ;
2005-04-24 11:38:05 +04:00
return ( 1 ) ; /*Found one of them oldies! */
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
{
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & SCAM_SEL ) ) { }
}
/*---------------------------------------------------------------------
*
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:26 +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:24 +03:00
unsigned char i , k , max_id ;
2006-03-08 11:14:25 +03:00
unsigned short ee_data ;
2005-04-17 02:20:36 +04:00
PNVRamInfo pCurrNvRam ;
2005-04-24 11:38:05 +04:00
pCurrNvRam = FPT_BL_Card [ p_card ] . pNvRamInfo ;
2005-04-17 02:20:36 +04:00
if ( RD_HARPOON ( p_port + hp_page_ctrl ) & NARROW_SCSI_CARD )
max_id = 0x08 ;
else
max_id = 0x10 ;
if ( pCurrNvRam ) {
for ( i = 0 ; i < max_id ; i + + ) {
for ( k = 0 ; k < 4 ; k + + )
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . id_string [ k ] = pCurrNvRam - > niScamTbl [ i ] [ k ] ;
2005-04-17 02:20:36 +04:00
for ( k = 4 ; k < ID_STRING_LENGTH ; k + + )
2006-03-08 11:14:24 +03:00
FPT_scamInfo [ i ] . id_string [ k ] = ( unsigned char ) 0x00 ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( FPT_scamInfo [ i ] . id_string [ 0 ] = = 0x00 )
FPT_scamInfo [ i ] . state = ID_UNUSED ; /*Default to unused ID. */
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . state = ID_UNASSIGNED ; /*Default to unassigned ID. */
2005-04-17 02:20:36 +04:00
}
} else {
for ( i = 0 ; i < max_id ; i + + )
{
for ( k = 0 ; k < ID_STRING_LENGTH ; k + = 2 )
{
2006-03-08 11:14:25 +03:00
ee_data = FPT_utilEERead ( p_port , ( unsigned short ) ( ( EE_SCAMBASE / 2 ) +
( unsigned short ) ( i * ( ( unsigned short ) ID_STRING_LENGTH / 2 ) ) + ( unsigned short ) ( k / 2 ) ) ) ;
2006-03-08 11:14:24 +03:00
FPT_scamInfo [ i ] . id_string [ k ] = ( unsigned char ) ee_data ;
2005-04-17 02:20:36 +04:00
ee_data > > = 8 ;
2006-03-08 11:14:24 +03:00
FPT_scamInfo [ i ] . id_string [ k + 1 ] = ( unsigned char ) ee_data ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( ( FPT_scamInfo [ i ] . id_string [ 0 ] = = 0x00 ) | |
( FPT_scamInfo [ i ] . id_string [ 0 ] = = 0xFF ) )
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . state = ID_UNUSED ; /*Default to unused ID. */
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . state = ID_UNASSIGNED ; /*Default to unassigned ID. */
2005-04-17 02:20:36 +04: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:24 +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:24 +03:00
unsigned char i , k , match ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < MAX_SCSI_TAR ; i + + ) {
2005-04-24 11:38:05 +04:00
match = 1 ;
2005-04-17 02:20:36 +04:00
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + )
{
2005-04-24 11:38:05 +04:00
if ( p_id_string [ k ] ! = FPT_scamInfo [ i ] . id_string [ k ] )
match = 0 ;
2005-04-17 02:20:36 +04:00
}
if ( match )
{
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ i ] . state = ID_ASSIGNED ;
2005-04-17 02:20:36 +04:00
return ( i ) ;
}
}
if ( p_id_string [ 0 ] & BIT ( 5 ) )
i = 8 ;
else
i = MAX_SCSI_TAR ;
if ( ( ( p_id_string [ 0 ] & 0x06 ) = = 0x02 ) | | ( ( p_id_string [ 0 ] & 0x06 ) = = 0x04 ) )
2006-03-08 11:14:24 +03:00
match = p_id_string [ 1 ] & ( unsigned char ) 0x1F ;
2005-04-17 02:20:36 +04:00
else
match = 7 ;
while ( i > 0 )
{
i - - ;
2005-04-24 11:38:05 +04:00
if ( FPT_scamInfo [ match ] . state = = ID_UNUSED )
2005-04-17 02:20:36 +04:00
{
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + )
{
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ match ] . id_string [ k ] = p_id_string [ k ] ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ match ] . state = ID_ASSIGNED ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04:00
if ( FPT_BL_Card [ p_card ] . pNvRamInfo = = NULL )
FPT_BL_Card [ p_card ] . globalFlags | = F_UPDATE_EEPROM ;
2005-04-17 02:20:36 +04:00
return ( match ) ;
}
match - - ;
if ( match = = 0xFF )
{
if ( p_id_string [ 0 ] & BIT ( 5 ) )
match = 7 ;
else
match = MAX_SCSI_TAR - 1 ;
}
}
if ( p_id_string [ 0 ] & BIT ( 7 ) )
{
return ( CLR_PRIORITY ) ;
}
if ( p_id_string [ 0 ] & BIT ( 5 ) )
i = 8 ;
else
i = MAX_SCSI_TAR ;
if ( ( ( p_id_string [ 0 ] & 0x06 ) = = 0x02 ) | | ( ( p_id_string [ 0 ] & 0x06 ) = = 0x04 ) )
2006-03-08 11:14:24 +03:00
match = p_id_string [ 1 ] & ( unsigned char ) 0x1F ;
2005-04-17 02:20:36 +04:00
else
match = 7 ;
while ( i > 0 )
{
i - - ;
2005-04-24 11:38:05 +04:00
if ( FPT_scamInfo [ match ] . state = = ID_UNASSIGNED )
2005-04-17 02:20:36 +04:00
{
for ( k = 0 ; k < ID_STRING_LENGTH ; k + + )
{
2005-04-24 11:38:05 +04:00
FPT_scamInfo [ match ] . id_string [ k ] = p_id_string [ k ] ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04: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 ;
2005-04-17 02:20:36 +04:00
return ( match ) ;
}
match - - ;
if ( match = = 0xFF )
{
if ( p_id_string [ 0 ] & BIT ( 5 ) )
match = 7 ;
else
match = MAX_SCSI_TAR - 1 ;
}
}
return ( NO_ID_AVAIL ) ;
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char i , k , max_id ;
2006-03-08 11:14:25 +03:00
unsigned short ee_data , sum_data ;
2005-04-17 02:20:36 +04:00
sum_data = 0x0000 ;
for ( i = 1 ; i < EE_SCAMBASE / 2 ; i + + )
{
2005-04-24 11:38:05 +04:00
sum_data + = FPT_utilEERead ( p_port , i ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
FPT_utilEEWriteOnOff ( p_port , 1 ) ; /* Enable write access to the EEPROM */
2005-04-17 02:20:36 +04:00
if ( RD_HARPOON ( p_port + hp_page_ctrl ) & NARROW_SCSI_CARD )
max_id = 0x08 ;
else
max_id = 0x10 ;
for ( i = 0 ; i < max_id ; i + + )
{
for ( k = 0 ; k < ID_STRING_LENGTH ; k + = 2 )
{
2005-04-24 11:38:05 +04:00
ee_data = FPT_scamInfo [ i ] . id_string [ k + 1 ] ;
2005-04-17 02:20:36 +04:00
ee_data < < = 8 ;
2005-04-24 11:38:05 +04:00
ee_data | = FPT_scamInfo [ i ] . id_string [ k ] ;
2005-04-17 02:20:36 +04:00
sum_data + = ee_data ;
2006-03-08 11:14:25 +03:00
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
}
}
2005-04-24 11:38:05 +04: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:24 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
i = RD_HARPOON ( port + hp_page_ctrl ) ;
2006-03-08 11:14:24 +03:00
WR_HARPOON ( port + hp_page_ctrl , ( unsigned char ) ( i | G_INT_DISABLE ) ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_scsireset , 0x00 ) ;
WR_HARPOON ( port + hp_portctrl_1 , HOST_MODE8 ) ;
WR_HARPOON ( port + hp_scsireset , ( DMA_RESET | HPSCSI_RESET | PROG_RESET | \
FIFO_CLR ) ) ;
WR_HARPOON ( port + hp_scsireset , SCSI_INI ) ;
WR_HARPOON ( port + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( port + hp_scsisig , 0x00 ) ; /* Clear any signals we might */
WR_HARPOON ( port + hp_scsictrl_0 , ENA_SCAM_SEL ) ;
WRW_HARPOON ( ( port + hp_intstat ) , CLR_ALL_INT ) ;
2005-04-24 11:38:05 +04:00
FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
2005-04-17 02:20:36 +04:00
BUS_FREE | XFER_CNT_0 | AUTO_INT ;
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
2005-04-24 11:38:05 +04:00
WRW_HARPOON ( ( port + hp_intena ) , FPT_default_intena ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( port + hp_seltimeout , TO_290ms ) ;
/* 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 ) ;
WR_HARPOON ( port + hp_page_ctrl , i ) ;
}
/*---------------------------------------------------------------------
*
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
{
WR_HARPOON ( p_port + hp_sys_ctrl , DRVR_RST ) ;
WR_HARPOON ( p_port + hp_sys_ctrl , 0x00 ) ;
WR_HARPOON ( p_port + hp_host_blk_cnt , XFER_BLK64 ) ;
WR_HARPOON ( p_port + hp_bm_ctrl , ( BMCTRL_DEFAULT ) ) ;
WR_HARPOON ( p_port + hp_ee_ctrl , ( SCSI_TERM_ENA_H ) ) ;
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-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:25 +03:00
unsigned short index , temp , max_wd_cnt ;
2005-04-17 02:20:36 +04: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-24 11:38:05 +04:00
temp = FPT_utilEERead ( p_port , FW_SIGNATURE / 2 ) ;
2005-04-17 02:20:36 +04:00
if ( temp = = 0x4641 ) {
for ( index = 2 ; index < max_wd_cnt ; index + + ) {
2005-04-24 11:38:05 +04:00
temp + = FPT_utilEERead ( p_port , index ) ;
2005-04-17 02:20:36 +04:00
}
2005-04-24 11:38:05 +04:00
if ( temp = = FPT_utilEERead ( p_port , EEPROM_CHECK_SUM / 2 ) ) {
2005-04-17 02:20:36 +04:00
return ; /*EEPROM is Okay so return now! */
}
}
2006-03-08 11:14:24 +03:00
FPT_utilEEWriteOnOff ( p_port , ( unsigned char ) 1 ) ;
2005-04-17 02:20:36 +04:00
for ( index = 0 ; index < max_wd_cnt ; index + + ) {
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0000 , index ) ;
2005-04-17 02:20:36 +04:00
}
temp = 0 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4641 , FW_SIGNATURE / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4641 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x3920 , MODEL_NUMB_0 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x3920 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x3033 , MODEL_NUMB_2 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x3033 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x2020 , MODEL_NUMB_4 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x2020 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x70D3 , SYSTEM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x70D3 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0010 , BIOS_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x0010 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0003 , SCAM_CONFIG / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x0003 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0007 , ADAPTER_SCSI_ID / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x0007 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0000 , IGNORE_B_SCAN / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x0000 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0000 , SEND_START_ENA / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x0000 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x0000 , DEVICE_ENABLE / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x0000 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL01 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL23 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL45 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL67 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBL89 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBLab / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBLcd / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4242 , SYNC_RATE_TBLef / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4242 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x6C46 , 64 / 2 ) ; /*PRODUCT ID */
2005-04-17 02:20:36 +04:00
temp + = 0x6C46 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x7361 , 66 / 2 ) ; /* FlashPoint LT */
2005-04-17 02:20:36 +04:00
temp + = 0x7361 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x5068 , 68 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x5068 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x696F , 70 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x696F ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x746E , 72 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x746E ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4C20 , 74 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4C20 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x2054 , 76 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x2054 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x2020 , 78 / 2 ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x2020 ;
index = ( ( EE_SCAMBASE / 2 ) + ( 7 * 16 ) ) ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , ( 0x0700 + TYPE_CODE0 ) , index ) ;
2005-04-17 02:20:36 +04:00
temp + = ( 0x0700 + TYPE_CODE0 ) ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x5542 , index ) ; /*Vendor ID code */
2005-04-17 02:20:36 +04:00
temp + = 0x5542 ; /* BUSLOGIC */
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4C53 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4C53 ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x474F , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x474F ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4349 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4349 ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x5442 , index ) ; /*Vendor unique code */
2005-04-17 02:20:36 +04:00
temp + = 0x5442 ; /* BT- 930 */
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x202D , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x202D ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x3339 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x3339 ;
index + + ; /*Serial # */
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x2030 , index ) ; /* 01234567 */
2005-04-17 02:20:36 +04:00
temp + = 0x2030 ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x5453 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x5453 ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x5645 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x5645 ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x2045 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x2045 ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x202F , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x202F ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x4F4A , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x4F4A ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x204E , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x204E ;
index + + ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , 0x3539 , index ) ;
2005-04-17 02:20:36 +04:00
temp + = 0x3539 ;
2005-04-24 11:38:05 +04:00
FPT_utilEEWrite ( p_port , temp , EEPROM_CHECK_SUM / 2 ) ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
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:24 +03:00
static void FPT_queueSearchSelect ( PSCCBcard pCurrCard , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char scan_ptr , lun ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2006-03-08 11:14:29 +03:00
struct sccb * pOldSccb ;
2005-04-17 02:20:36 +04:00
scan_ptr = pCurrCard - > scanIndex ;
do
{
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ scan_ptr ] ;
2005-04-17 02:20:36 +04:00
if ( ( pCurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) )
{
if ( currTar_Info - > TarSelQ_Cnt ! = 0 )
{
scan_ptr + + ;
if ( scan_ptr = = MAX_SCSI_TAR )
scan_ptr = 0 ;
for ( lun = 0 ; lun < MAX_LUN ; lun + + )
{
2005-04-24 11:38:05 +04:00
if ( currTar_Info - > TarLUNBusy [ lun ] = = 0 )
2005-04-17 02:20:36 +04:00
{
pCurrCard - > currentSCCB = currTar_Info - > TarSelQ_Head ;
pOldSccb = NULL ;
while ( ( pCurrCard - > currentSCCB ! = NULL ) & &
( lun ! = pCurrCard - > currentSCCB - > Lun ) )
{
pOldSccb = pCurrCard - > currentSCCB ;
2006-03-08 11:14:29 +03:00
pCurrCard - > currentSCCB = ( struct sccb * ) ( pCurrCard - > currentSCCB ) - >
2005-04-17 02:20:36 +04:00
Sccb_forwardlink ;
}
if ( pCurrCard - > currentSCCB = = NULL )
continue ;
if ( pOldSccb ! = NULL )
{
2006-03-08 11:14:29 +03:00
pOldSccb - > Sccb_forwardlink = ( struct sccb * ) ( pCurrCard - > currentSCCB ) - >
2005-04-17 02:20:36 +04:00
Sccb_forwardlink ;
2006-03-08 11:14:29 +03:00
pOldSccb - > Sccb_backlink = ( struct sccb * ) ( pCurrCard - > currentSCCB ) - >
2005-04-17 02:20:36 +04:00
Sccb_backlink ;
currTar_Info - > TarSelQ_Cnt - - ;
}
else
{
2006-03-08 11:14:29 +03:00
currTar_Info - > TarSelQ_Head = ( struct sccb * ) ( pCurrCard - > currentSCCB ) - > Sccb_forwardlink ;
2005-04-17 02:20:36 +04:00
if ( currTar_Info - > TarSelQ_Head = = NULL )
{
currTar_Info - > TarSelQ_Tail = NULL ;
currTar_Info - > TarSelQ_Cnt = 0 ;
}
else
{
currTar_Info - > TarSelQ_Cnt - - ;
2006-03-08 11:14:29 +03:00
currTar_Info - > TarSelQ_Head - > Sccb_backlink = ( struct sccb * ) NULL ;
2005-04-17 02:20:36 +04:00
}
}
pCurrCard - > scanIndex = scan_ptr ;
pCurrCard - > globalFlags | = F_NEW_SCCB_CMD ;
break ;
}
}
}
else
{
scan_ptr + + ;
if ( scan_ptr = = MAX_SCSI_TAR ) {
scan_ptr = 0 ;
}
}
}
else
{
if ( ( currTar_Info - > TarSelQ_Cnt ! = 0 ) & &
2005-04-24 11:38:05 +04:00
( currTar_Info - > TarLUNBusy [ 0 ] = = 0 ) )
2005-04-17 02:20:36 +04:00
{
pCurrCard - > currentSCCB = currTar_Info - > TarSelQ_Head ;
2006-03-08 11:14:29 +03:00
currTar_Info - > TarSelQ_Head = ( struct sccb * ) ( pCurrCard - > currentSCCB ) - > Sccb_forwardlink ;
2005-04-17 02:20:36 +04:00
if ( currTar_Info - > TarSelQ_Head = = NULL )
{
currTar_Info - > TarSelQ_Tail = NULL ;
currTar_Info - > TarSelQ_Cnt = 0 ;
}
else
{
currTar_Info - > TarSelQ_Cnt - - ;
2006-03-08 11:14:29 +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 ;
}
else
{
scan_ptr + + ;
if ( scan_ptr = = MAX_SCSI_TAR )
{
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:24 +03:00
static void FPT_queueSelectFail ( PSCCBcard pCurrCard , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char thisTarg ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
if ( pCurrCard - > currentSCCB ! = NULL )
{
2006-03-08 11:14:29 +03:00
thisTarg = ( unsigned char ) ( ( ( struct sccb * ) ( pCurrCard - > currentSCCB ) ) - > TargID ) ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ thisTarg ] ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:29 +03:00
pCurrCard - > currentSCCB - > Sccb_backlink = ( struct sccb * ) NULL ;
2005-04-17 02:20:36 +04:00
pCurrCard - > currentSCCB - > Sccb_forwardlink = currTar_Info - > TarSelQ_Head ;
if ( currTar_Info - > TarSelQ_Cnt = = 0 )
{
currTar_Info - > TarSelQ_Tail = pCurrCard - > currentSCCB ;
}
else
{
currTar_Info - > TarSelQ_Head - > Sccb_backlink = pCurrCard - > currentSCCB ;
}
currTar_Info - > TarSelQ_Head = pCurrCard - > currentSCCB ;
pCurrCard - > currentSCCB = NULL ;
currTar_Info - > TarSelQ_Cnt + + ;
}
}
/*---------------------------------------------------------------------
*
* Function : Queue Command Complete
*
* Description : Call the callback function with the current SCCB .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:29 +03:00
static void FPT_queueCmdComplete ( PSCCBcard pCurrCard , struct sccb * p_sccb ,
2006-03-08 11:14:24 +03:00
unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:24 +03:00
unsigned char i , SCSIcmd ;
2005-04-17 02:20:36 +04:00
CALL_BK_FN callback ;
PSCCBMgr_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 ;
}
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 ;
}
if ( p_sccb - > Sccb_XferState & F_AUTO_SENSE ) {
p_sccb - > CdbLength = p_sccb - > Save_CdbLen ;
for ( i = 0 ; i < 6 ; i + + ) {
p_sccb - > Cdb [ i ] = p_sccb - > Save_Cdb [ i ] ;
}
}
if ( ( p_sccb - > OperationCode = = RESIDUAL_SG_COMMAND ) | |
( p_sccb - > OperationCode = = RESIDUAL_COMMAND ) ) {
2005-04-24 11:38:05 +04:00
FPT_utilUpdateResidual ( p_sccb ) ;
2005-04-17 02:20:36 +04:00
}
pCurrCard - > cmdCounter - - ;
if ( ! pCurrCard - > cmdCounter ) {
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 ) ;
}
WR_HARPOON ( pCurrCard - > ioPort + hp_semaphore ,
( RD_HARPOON ( pCurrCard - > ioPort + hp_semaphore ) & ~ SCCB_MGR_ACTIVE ) ) ;
}
if ( pCurrCard - > discQCount ! = 0 )
{
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
if ( ( ( pCurrCard - > globalFlags & F_CONLUN_IO ) & &
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) )
{
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ p_sccb - > Lun ] ] = NULL ;
}
else
{
if ( p_sccb - > Sccb_tag )
{
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ p_sccb - > Sccb_tag ] = NULL ;
} else
{
pCurrCard - > discQCount - - ;
pCurrCard - > discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ 0 ] ] = NULL ;
}
}
}
callback = ( CALL_BK_FN ) p_sccb - > SccbCallback ;
callback ( p_sccb ) ;
pCurrCard - > globalFlags | = F_NEW_SCCB_CMD ;
pCurrCard - > currentSCCB = NULL ;
}
/*---------------------------------------------------------------------
*
* Function : Queue Disconnect
*
* Description : Add SCCB to our disconnect array .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:29 +03:00
static void FPT_queueDisconnect ( struct sccb * p_sccb , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
PSCCBMgr_tar_info currTar_Info ;
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
2005-04-24 11:38:05 +04:00
if ( ( ( FPT_BL_Card [ p_card ] . globalFlags & F_CONLUN_IO ) & &
2005-04-17 02:20:36 +04:00
( ( currTar_Info - > TarStatus & TAR_TAG_Q_MASK ) ! = TAG_Q_TRYING ) ) )
{
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ currTar_Info - > LunDiscQ_Idx [ p_sccb - > Lun ] ] = p_sccb ;
2005-04-17 02:20:36 +04:00
}
else
{
if ( p_sccb - > Sccb_tag )
{
2005-04-24 11:38:05 +04:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ p_sccb - > Sccb_tag ] = p_sccb ;
FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] . TarLUNBusy [ 0 ] = 0 ;
FPT_sccbMgrTbl [ p_card ] [ p_sccb - > TargID ] . TarTagQ_Cnt + + ;
2005-04-17 02:20:36 +04:00
} else
{
2005-04-24 11:38:05 +04:00
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:24 +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:24 +03:00
unsigned char qtag , thisTarg ;
2006-03-08 11:14:29 +03:00
struct sccb * currSCCB ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
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 )
{
2006-03-08 11:14:24 +03:00
thisTarg = ( unsigned char ) currSCCB - > TargID ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ thisTarg ] ;
2005-04-17 02:20:36 +04:00
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + ) {
2005-04-24 11:38:05 +04: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:24 +03:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > HostStatus = ( unsigned char ) error_code ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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
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
currTar_Info - > TarTagQ_Cnt - - ;
}
}
}
}
/*---------------------------------------------------------------------
*
* Function : Queue Flush Target SCCB
*
* Description : Flush all SCCB ' s back to the host driver for this target .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:24 +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:24 +03:00
unsigned char qtag ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
2005-04-24 11:38:05 +04:00
currTar_Info = & FPT_sccbMgrTbl [ p_card ] [ thisTarg ] ;
2005-04-17 02:20:36 +04:00
for ( qtag = 0 ; qtag < QUEUE_DEPTH ; qtag + + ) {
2005-04-24 11:38:05 +04: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:24 +03:00
FPT_BL_Card [ p_card ] . discQ_Tbl [ qtag ] - > HostStatus = ( unsigned char ) error_code ;
2005-04-17 02:20:36 +04:00
2005-04-24 11:38:05 +04: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
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
currTar_Info - > TarTagQ_Cnt - - ;
}
}
}
2006-03-08 11:14:29 +03:00
static void FPT_queueAddSccb ( struct sccb * p_SCCB , unsigned char p_card )
2005-04-17 02:20:36 +04:00
{
PSCCBMgr_tar_info currTar_Info ;
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
p_SCCB - > Sccb_forwardlink = NULL ;
p_SCCB - > Sccb_backlink = currTar_Info - > TarSelQ_Tail ;
if ( currTar_Info - > TarSelQ_Cnt = = 0 ) {
currTar_Info - > TarSelQ_Head = p_SCCB ;
}
else {
currTar_Info - > TarSelQ_Tail - > Sccb_forwardlink = p_SCCB ;
}
currTar_Info - > TarSelQ_Tail = p_SCCB ;
currTar_Info - > TarSelQ_Cnt + + ;
}
/*---------------------------------------------------------------------
*
* Function : Queue Find SCCB
*
* Description : Search the target select Queue for this SCCB , and
* remove it if found .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:29 +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:29 +03:00
struct sccb * q_ptr ;
2005-04-17 02:20:36 +04:00
PSCCBMgr_tar_info currTar_Info ;
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
q_ptr = currTar_Info - > TarSelQ_Head ;
while ( q_ptr ! = NULL ) {
if ( q_ptr = = p_SCCB ) {
if ( currTar_Info - > TarSelQ_Head = = q_ptr ) {
currTar_Info - > TarSelQ_Head = q_ptr - > Sccb_forwardlink ;
}
if ( currTar_Info - > TarSelQ_Tail = = q_ptr ) {
currTar_Info - > TarSelQ_Tail = q_ptr - > Sccb_backlink ;
}
if ( q_ptr - > Sccb_forwardlink ! = NULL ) {
q_ptr - > Sccb_forwardlink - > Sccb_backlink = q_ptr - > Sccb_backlink ;
}
if ( q_ptr - > Sccb_backlink ! = NULL ) {
q_ptr - > Sccb_backlink - > Sccb_forwardlink = q_ptr - > Sccb_forwardlink ;
}
currTar_Info - > TarSelQ_Cnt - - ;
2005-04-24 11:38:05 +04:00
return ( 1 ) ;
2005-04-17 02:20:36 +04:00
}
else {
q_ptr = q_ptr - > Sccb_forwardlink ;
}
}
2005-04-24 11:38:05 +04: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:29 +03:00
static void FPT_utilUpdateResidual ( struct sccb * p_SCCB )
2005-04-17 02:20:36 +04:00
{
2006-03-08 11:14:26 +03:00
unsigned long partial_cnt ;
2006-03-08 11:14:26 +03:00
unsigned int sg_index ;
2006-03-08 11:14:26 +03:00
unsigned long * sg_ptr ;
2005-04-17 02:20:36 +04:00
if ( p_SCCB - > Sccb_XferState & F_ALL_XFERRED ) {
p_SCCB - > DataLength = 0x0000 ;
}
else if ( p_SCCB - > Sccb_XferState & F_SG_XFER ) {
partial_cnt = 0x0000 ;
sg_index = p_SCCB - > Sccb_sgseg ;
2006-03-08 11:14:26 +03:00
sg_ptr = ( unsigned long * ) p_SCCB - > DataPointer ;
2005-04-17 02:20:36 +04:00
if ( p_SCCB - > Sccb_SGoffset ) {
partial_cnt = p_SCCB - > Sccb_SGoffset ;
sg_index + + ;
}
2006-03-08 11:14:26 +03:00
while ( ( ( unsigned long ) sg_index * ( unsigned long ) SG_ELEMENT_SIZE ) <
2005-04-17 02:20:36 +04:00
p_SCCB - > DataLength ) {
partial_cnt + = * ( sg_ptr + ( sg_index * 2 ) ) ;
sg_index + + ;
}
p_SCCB - > DataLength = partial_cnt ;
}
else {
p_SCCB - > DataLength - = p_SCCB - > Sccb_ATC ;
}
}
/*---------------------------------------------------------------------
*
* 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:24 +03:00
unsigned char i ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < 4 ; i + + ) {
2005-04-24 11:38:05 +04:00
FPT_Wait ( p_port , TO_250ms ) ;
2005-04-17 02:20:36 +04:00
if ( ( RD_HARPOON ( p_port + hp_scsictrl_0 ) & SCSI_RST ) )
break ;
if ( ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & SCAM_SEL ) )
break ;
}
}
/*---------------------------------------------------------------------
*
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:24 +03:00
unsigned char old_timer ;
unsigned char green_flag ;
2005-04-17 02:20:36 +04:00
old_timer = RD_HARPOON ( p_port + hp_seltimeout ) ;
green_flag = RD_HARPOON ( p_port + hp_clkctrl_0 ) ;
WR_HARPOON ( p_port + hp_clkctrl_0 , CLKCTRL_DEFAULT ) ;
WR_HARPOON ( p_port + hp_seltimeout , p_delay ) ;
WRW_HARPOON ( ( p_port + hp_intstat ) , TIMEOUT ) ;
2005-04-24 11:38:05 +04:00
WRW_HARPOON ( ( p_port + hp_intena ) , ( FPT_default_intena & ~ TIMEOUT ) ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_portctrl_0 ,
( RD_HARPOON ( p_port + hp_portctrl_0 ) | START_TO ) ) ;
while ( ! ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & TIMEOUT ) ) {
if ( ( RD_HARPOON ( p_port + hp_scsictrl_0 ) & SCSI_RST ) )
break ;
if ( ( RDW_HARPOON ( ( p_port + hp_intstat ) ) & SCAM_SEL ) )
break ;
}
WR_HARPOON ( p_port + hp_portctrl_0 ,
( RD_HARPOON ( p_port + hp_portctrl_0 ) & ~ START_TO ) ) ;
WRW_HARPOON ( ( p_port + hp_intstat ) , TIMEOUT ) ;
2005-04-24 11:38:05 +04:00
WRW_HARPOON ( ( p_port + hp_intena ) , FPT_default_intena ) ;
2005-04-17 02:20:36 +04:00
WR_HARPOON ( p_port + hp_clkctrl_0 , green_flag ) ;
WR_HARPOON ( p_port + hp_seltimeout , old_timer ) ;
}
/*---------------------------------------------------------------------
*
* 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:26 +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:24 +03:00
unsigned char ee_value ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +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
if ( p_mode )
2005-04-24 11:38:05 +04:00
FPT_utilEESendCmdAddr ( p_port , EWEN , EWEN_ADDR ) ;
2005-04-17 02:20:36 +04:00
else
2005-04-24 11:38:05 +04:00
FPT_utilEESendCmdAddr ( p_port , EWDS , EWDS_ADDR ) ;
2005-04-17 02:20:36 +04: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 */
}
/*---------------------------------------------------------------------
*
* Function : Write EEPROM
*
* Description : Write a word to the EEPROM at the specified
* address .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +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:24 +03:00
unsigned char ee_value ;
2006-03-08 11:14:25 +03:00
unsigned short i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +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
( SEE_MS | SEE_CS ) ) ;
2005-04-24 11:38:05 +04:00
FPT_utilEESendCmdAddr ( p_port , EE_WRITE , ee_addr ) ;
2005-04-17 02:20:36 +04:00
ee_value | = ( SEE_MS + SEE_CS ) ;
for ( i = 0x8000 ; i ! = 0 ; i > > = 1 ) {
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-24 11:38:05 +04:00
FPT_Wait ( p_port , TO_10ms ) ;
2005-04-17 02:20:36 +04: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 */
}
/*---------------------------------------------------------------------
*
* Function : Read EEPROM
*
* Description : Read a word from the EEPROM at the desired
* address .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +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:25 +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 ) ;
2005-04-17 02:20:36 +04: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
if ( ee_data1 = = ee_data2 )
return ( ee_data1 ) ;
ee_data1 = ee_data2 ;
i + + ;
} while ( i < 4 ) ;
return ( ee_data1 ) ;
}
/*---------------------------------------------------------------------
*
* Function : Read EEPROM Original
*
* Description : Read a word from the EEPROM at the desired
* address .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2006-03-08 11:14:26 +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:24 +03:00
unsigned char ee_value ;
2006-03-08 11:14:25 +03:00
unsigned short i , ee_data ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +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
( SEE_MS | SEE_CS ) ) ;
2005-04-24 11:38:05 +04:00
FPT_utilEESendCmdAddr ( p_port , EE_READ , ee_addr ) ;
2005-04-17 02:20:36 +04:00
ee_value | = ( SEE_MS + SEE_CS ) ;
ee_data = 0 ;
for ( i = 1 ; i < = 16 ; i + + ) {
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_data < < = 1 ;
if ( RD_HARPOON ( p_port + hp_ee_ctrl ) & SEE_DI )
ee_data | = 1 ;
}
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 */
return ( ee_data ) ;
}
/*---------------------------------------------------------------------
*
* 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:26 +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:24 +03:00
unsigned char ee_value ;
unsigned char narrow_flg ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:25 +03:00
unsigned short i ;
2005-04-17 02:20:36 +04:00
2006-03-08 11:14:24 +03:00
narrow_flg = ( unsigned char ) ( RD_HARPOON ( p_port + hp_page_ctrl ) & NARROW_SCSI_CARD ) ;
2005-04-17 02:20:36 +04:00
ee_value = SEE_MS ;
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
ee_value | = SEE_CS ; /* Set CS to EEPROM */
WR_HARPOON ( p_port + hp_ee_ctrl , ee_value ) ;
for ( i = 0x04 ; i ! = 0 ; i > > = 1 ) {
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 ) ;
}
if ( narrow_flg )
i = 0x0080 ;
else
i = 0x0200 ;
while ( i ! = 0 ) {
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 ;
}
}
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:25 +03:00
unsigned short crc = 0 ;
2005-04-17 02:20:36 +04:00
int i , j ;
2006-03-08 11:14:25 +03:00
unsigned short ch ;
2005-04-17 02:20:36 +04:00
for ( i = 0 ; i < ID_STRING_LENGTH ; i + + )
{
2006-03-08 11:14:25 +03:00
ch = ( unsigned short ) buffer [ i ] ;
2005-04-17 02:20:36 +04:00
for ( j = 0 ; j < 8 ; j + + )
{
if ( ( crc ^ ch ) & 1 )
crc = ( crc > > 1 ) ^ CRCMASK ;
else
crc > > = 1 ;
ch > > = 1 ;
}
}
return ( crc ) ;
}
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 ;
for ( i = 0 ; i < ID_STRING_LENGTH ; i + + )
lrc ^ = buffer [ i ] ;
return ( lrc ) ;
}
/*
The following inline definitions avoid type conflicts .
*/
static inline unsigned char
FlashPoint__ProbeHostAdapter ( struct FlashPoint_Info * FlashPointInfo )
{
2006-03-08 11:14:30 +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:30 +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 )
{
FlashPoint_ReleaseHostAdapter ( CardHandle ) ;
}
static inline void
FlashPoint__StartCCB ( FlashPoint_CardHandle_T CardHandle , struct BusLogic_CCB * CCB )
{
2006-03-08 11:14:29 +03:00
FlashPoint_StartCCB ( CardHandle , ( struct sccb * ) CCB ) ;
2005-04-17 02:20:36 +04:00
}
static inline void
FlashPoint__AbortCCB ( FlashPoint_CardHandle_T CardHandle , struct BusLogic_CCB * CCB )
{
2006-03-08 11:14:29 +03:00
FlashPoint_AbortCCB ( CardHandle , ( struct sccb * ) CCB ) ;
2005-04-17 02:20:36 +04:00
}
static inline boolean
FlashPoint__InterruptPending ( FlashPoint_CardHandle_T CardHandle )
{
return FlashPoint_InterruptPending ( CardHandle ) ;
}
static inline int
FlashPoint__HandleInterrupt ( FlashPoint_CardHandle_T CardHandle )
{
return FlashPoint_HandleInterrupt ( CardHandle ) ;
}
# 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
# else /* CONFIG_SCSI_OMIT_FLASHPOINT */
/*
Define prototypes for the FlashPoint SCCB Manager Functions .
*/
extern unsigned char FlashPoint_ProbeHostAdapter ( struct FlashPoint_Info * ) ;
extern FlashPoint_CardHandle_T
FlashPoint_HardwareResetHostAdapter ( struct FlashPoint_Info * ) ;
extern void FlashPoint_StartCCB ( FlashPoint_CardHandle_T , struct BusLogic_CCB * ) ;
extern int FlashPoint_AbortCCB ( FlashPoint_CardHandle_T , struct BusLogic_CCB * ) ;
extern boolean FlashPoint_InterruptPending ( FlashPoint_CardHandle_T ) ;
extern int FlashPoint_HandleInterrupt ( FlashPoint_CardHandle_T ) ;
extern void FlashPoint_ReleaseHostAdapter ( FlashPoint_CardHandle_T ) ;
# endif /* CONFIG_SCSI_OMIT_FLASHPOINT */