diff options
| author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-28 10:49:35 +0000 |
|---|---|---|
| committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-28 11:05:22 +0000 |
| commit | 1b5c6d6327840e5b96577c720bde6776656f47cd (patch) | |
| tree | ceb1faded0eaebf5f4363e12423900e802de995d /debian/patches | |
| parent | f966eb26edd102d2cc16ad1625d9bf6cdadb8430 (diff) | |
* patches/80_missing_files.patch: Add missing files from git.
Diffstat (limited to 'debian/patches')
| -rw-r--r-- | debian/patches/80_missing_files.patch | 13925 | ||||
| -rw-r--r-- | debian/patches/series | 1 |
2 files changed, 13926 insertions, 0 deletions
diff --git a/debian/patches/80_missing_files.patch b/debian/patches/80_missing_files.patch new file mode 100644 index 0000000..f95435a --- /dev/null +++ b/debian/patches/80_missing_files.patch @@ -0,0 +1,13925 @@ +diff --git a/linux/src/drivers/scsi/FlashPoint.c b/linux/src/drivers/scsi/FlashPoint.c +new file mode 100644 +index 0000000..aae35c0 +--- /dev/null ++++ b/linux/src/drivers/scsi/FlashPoint.c +@@ -0,0 +1,12156 @@ ++/* ++ ++ 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 UNIX ++#define FW_TYPE _SCCB_MGR_ ++#define MAX_CARDS 8 ++#undef BUSTYPE_PCI ++ ++ ++#define OS_InPortByte(port) inb(port) ++#define OS_InPortWord(port) inw(port) ++#define OS_InPortLong(port) inl(port) ++#define OS_OutPortByte(port, value) outb(value, port) ++#define OS_OutPortWord(port, value) outw(value, port) ++#define OS_OutPortLong(port, value) outl(value, port) ++#define OS_Lock(x) ++#define OS_UnLock(x) ++ ++ ++/* ++ Define name replacements for compatibility with the Linux BusLogic Driver. ++*/ ++ ++#define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter ++#define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter ++#define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter ++#define SccbMgr_start_sccb FlashPoint_StartCCB ++#define SccbMgr_abort_sccb FlashPoint_AbortCCB ++#define SccbMgr_my_int FlashPoint_InterruptPending ++#define SccbMgr_isr FlashPoint_HandleInterrupt ++ ++ ++/* ++ Define name replacements to avoid kernel namespace pollution. ++*/ ++ ++#define BL_Card FPT_BL_Card ++#define BusMasterInit FPT_BusMasterInit ++#define CalcCrc16 FPT_CalcCrc16 ++#define CalcLrc FPT_CalcLrc ++#define ChkIfChipInitialized FPT_ChkIfChipInitialized ++#define DiagBusMaster FPT_DiagBusMaster ++#define DiagEEPROM FPT_DiagEEPROM ++#define DiagXbow FPT_DiagXbow ++#define GetTarLun FPT_GetTarLun ++#define RNVRamData FPT_RNVRamData ++#define RdStack FPT_RdStack ++#define SccbMgrTableInitAll FPT_SccbMgrTableInitAll ++#define SccbMgrTableInitCard FPT_SccbMgrTableInitCard ++#define SccbMgrTableInitTarget FPT_SccbMgrTableInitTarget ++#define SccbMgr_bad_isr FPT_SccbMgr_bad_isr ++#define SccbMgr_scsi_reset FPT_SccbMgr_scsi_reset ++#define SccbMgr_timer_expired FPT_SccbMgr_timer_expired ++#define SendMsg FPT_SendMsg ++#define Wait FPT_Wait ++#define Wait1Second FPT_Wait1Second ++#define WrStack FPT_WrStack ++#define XbowInit FPT_XbowInit ++#define autoCmdCmplt FPT_autoCmdCmplt ++#define autoLoadDefaultMap FPT_autoLoadDefaultMap ++#define busMstrDataXferStart FPT_busMstrDataXferStart ++#define busMstrSGDataXferStart FPT_busMstrSGDataXferStart ++#define busMstrTimeOut FPT_busMstrTimeOut ++#define dataXferProcessor FPT_dataXferProcessor ++#define default_intena FPT_default_intena ++#define hostDataXferAbort FPT_hostDataXferAbort ++#define hostDataXferRestart FPT_hostDataXferRestart ++#define inisci FPT_inisci ++#define mbCards FPT_mbCards ++#define nvRamInfo FPT_nvRamInfo ++#define phaseBusFree FPT_phaseBusFree ++#define phaseChkFifo FPT_phaseChkFifo ++#define phaseCommand FPT_phaseCommand ++#define phaseDataIn FPT_phaseDataIn ++#define phaseDataOut FPT_phaseDataOut ++#define phaseDecode FPT_phaseDecode ++#define phaseIllegal FPT_phaseIllegal ++#define phaseMsgIn FPT_phaseMsgIn ++#define phaseMsgOut FPT_phaseMsgOut ++#define phaseStatus FPT_phaseStatus ++#define queueAddSccb FPT_queueAddSccb ++#define queueCmdComplete FPT_queueCmdComplete ++#define queueDisconnect FPT_queueDisconnect ++#define queueFindSccb FPT_queueFindSccb ++#define queueFlushSccb FPT_queueFlushSccb ++#define queueFlushTargSccb FPT_queueFlushTargSccb ++#define queueSearchSelect FPT_queueSearchSelect ++#define queueSelectFail FPT_queueSelectFail ++#define s_PhaseTbl FPT_s_PhaseTbl ++#define scamHAString FPT_scamHAString ++#define scamInfo FPT_scamInfo ++#define scarb FPT_scarb ++#define scasid FPT_scasid ++#define scbusf FPT_scbusf ++#define sccbMgrTbl FPT_sccbMgrTbl ++#define schkdd FPT_schkdd ++#define scini FPT_scini ++#define sciso FPT_sciso ++#define scmachid FPT_scmachid ++#define scsavdi FPT_scsavdi ++#define scsel FPT_scsel ++#define scsell FPT_scsell ++#define scsendi FPT_scsendi ++#define scvalq FPT_scvalq ++#define scwirod FPT_scwirod ++#define scwiros FPT_scwiros ++#define scwtsel FPT_scwtsel ++#define scxferc FPT_scxferc ++#define sdecm FPT_sdecm ++#define sfm FPT_sfm ++#define shandem FPT_shandem ++#define sinits FPT_sinits ++#define sisyncn FPT_sisyncn ++#define sisyncr FPT_sisyncr ++#define siwidn FPT_siwidn ++#define siwidr FPT_siwidr ++#define sres FPT_sres ++#define sresb FPT_sresb ++#define ssel FPT_ssel ++#define ssenss FPT_ssenss ++#define sssyncv FPT_sssyncv ++#define stsyncn FPT_stsyncn ++#define stwidn FPT_stwidn ++#define sxfrp FPT_sxfrp ++#define utilEERead FPT_utilEERead ++#define utilEEReadOrg FPT_utilEEReadOrg ++#define utilEESendCmdAddr FPT_utilEESendCmdAddr ++#define utilEEWrite FPT_utilEEWrite ++#define utilEEWriteOnOff FPT_utilEEWriteOnOff ++#define utilUpdateResidual FPT_utilUpdateResidual ++ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: globals.h $ ++ * ++ * Description: Common shared global defines. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++#ifndef __GLOBALS_H__ ++#define __GLOBALS_H__ ++ ++#define _UCB_MGR_ 1 ++#define _SCCB_MGR_ 2 ++ ++/*#include <osflags.h>*/ ++ ++#define MAX_CDBLEN 12 ++ ++#define SCAM_LEV_2 1 ++ ++#define CRCMASK 0xA001 ++ ++/* In your osflags.h file, please ENSURE that only ONE OS FLAG ++ is on at a time !!! Also, please make sure you turn set the ++ variable FW_TYPE to either _UCB_MGR_ or _SCCB_MGR_ !!! */ ++ ++#if defined(DOS) || defined(WIN95_16) || defined(OS2) || defined(OTHER_16) ++ #define COMPILER_16_BIT 1 ++#elif defined(NETWARE) || defined(NT) || defined(WIN95_32) || defined(UNIX) || defined(OTHER_32) || defined(SOLARIS_REAL_MODE) ++ #define COMPILER_32_BIT 1 ++#endif ++ ++ ++#define BL_VENDOR_ID 0x104B ++#define FP_DEVICE_ID 0x8130 ++#define MM_DEVICE_ID 0x1040 ++ ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++#ifndef TRUE ++#define TRUE (!(FALSE)) ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#define FAILURE 0xFFFFFFFFL ++ ++ ++typedef unsigned char UCHAR; ++typedef unsigned short USHORT; ++typedef unsigned int UINT; ++typedef unsigned long ULONG; ++typedef unsigned char * PUCHAR; ++typedef unsigned short* PUSHORT; ++typedef unsigned long * PULONG; ++typedef void * PVOID; ++ ++ ++#if defined(COMPILER_16_BIT) ++typedef unsigned char far * uchar_ptr; ++typedef unsigned short far * ushort_ptr; ++typedef unsigned long far * ulong_ptr; ++#endif /* 16_BIT_COMPILER */ ++ ++#if defined(COMPILER_32_BIT) ++typedef unsigned char * uchar_ptr; ++typedef unsigned short * ushort_ptr; ++typedef unsigned long * ulong_ptr; ++#endif /* 32_BIT_COMPILER */ ++ ++ ++/* NEW TYPE DEFINITIONS (shared with Mylex North) ++ ++** Use following type defines to avoid confusion in 16 and 32-bit ++** environments. Avoid using 'int' as it denotes 16 bits in 16-bit ++** environment and 32 in 32-bit environments. ++ ++*/ ++ ++#define s08bits char ++#define s16bits short ++#define s32bits long ++ ++#define u08bits unsigned s08bits ++#define u16bits unsigned s16bits ++#define u32bits unsigned s32bits ++ ++#if defined(COMPILER_16_BIT) ++ ++typedef u08bits far * pu08bits; ++typedef u16bits far * pu16bits; ++typedef u32bits far * pu32bits; ++ ++#endif /* COMPILER_16_BIT */ ++ ++#if defined(COMPILER_32_BIT) ++ ++typedef u08bits * pu08bits; ++typedef u16bits * pu16bits; ++typedef u32bits * pu32bits; ++ ++#endif /* COMPILER_32_BIT */ ++ ++ ++#define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */ ++#define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */ ++ ++ ++ ++#if defined(DOS) ++/*#include <dos.h>*/ ++ #undef inportb /* undefine for Borland Lib */ ++ #undef inport /* they may have define I/O function in LIB */ ++ #undef outportb ++ #undef outport ++ ++ #define OS_InPortByte(ioport) inportb(ioport) ++ #define OS_InPortWord(ioport) inport(ioport) ++ #define OS_InPortLong(ioport) inportq(ioport, val) ++ #define OS_OutPortByte(ioport, val) outportb(ioport, val) ++ #define OS_OutPortWord(ioport, val) outport(ioport, val) ++ #define OS_OutPortLong(ioport) outportq(ioport, val) ++#endif /* DOS */ ++ ++#if defined(NETWARE) || defined(OTHER_32) || defined(OTHER_16) ++ extern u08bits OS_InPortByte(u32bits ioport); ++ extern u16bits OS_InPortWord(u32bits ioport); ++ extern u32bits OS_InPortLong(u32bits ioport); ++ ++ extern OS_InPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count); ++ extern OS_InPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count); ++ extern OS_OutPortByte(u32bits ioport, u08bits val); ++ extern OS_OutPortWord(u32bits ioport, u16bits val); ++ extern OS_OutPortLong(u32bits ioport, u32bits val); ++ extern OS_OutPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count); ++ extern OS_OutPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count); ++#endif /* NETWARE || OTHER_32 || OTHER_16 */ ++ ++#if defined (NT) || defined(WIN95_32) || defined(WIN95_16) ++ #if defined(NT) ++ ++ extern __declspec(dllimport) u08bits ScsiPortReadPortUchar(pu08bits ioport); ++ extern __declspec(dllimport) u16bits ScsiPortReadPortUshort(pu16bits ioport); ++ extern __declspec(dllimport) u32bits ScsiPortReadPortUlong(pu32bits ioport); ++ extern __declspec(dllimport) void ScsiPortWritePortUchar(pu08bits ioport, u08bits val); ++ extern __declspec(dllimport) void ScsiPortWritePortUshort(pu16bits port, u16bits val); ++ extern __declspec(dllimport) void ScsiPortWritePortUlong(pu32bits port, u32bits val); ++ ++ #else ++ ++ extern u08bits ScsiPortReadPortUchar(pu08bits ioport); ++ extern u16bits ScsiPortReadPortUshort(pu16bits ioport); ++ extern u32bits ScsiPortReadPortUlong(pu32bits ioport); ++ extern void ScsiPortWritePortUchar(pu08bits ioport, u08bits val); ++ extern void ScsiPortWritePortUshort(pu16bits port, u16bits val); ++ extern void ScsiPortWritePortUlong(pu32bits port, u32bits val); ++ #endif ++ ++ ++ #define OS_InPortByte(ioport) ScsiPortReadPortUchar((pu08bits) ioport) ++ #define OS_InPortWord(ioport) ScsiPortReadPortUshort((pu16bits) ioport) ++ #define OS_InPortLong(ioport) ScsiPortReadPortUlong((pu32bits) ioport) ++ ++ #define OS_OutPortByte(ioport, val) ScsiPortWritePortUchar((pu08bits) ioport, (u08bits) val) ++ #define OS_OutPortWord(ioport, val) ScsiPortWritePortUshort((pu16bits) ioport, (u16bits) val) ++ #define OS_OutPortLong(ioport, val) ScsiPortWritePortUlong((pu32bits) ioport, (u32bits) val) ++ #define OS_OutPortByteBuffer(ioport, buffer, count) \ ++ ScsiPortWritePortBufferUchar((pu08bits)&port, (pu08bits) buffer, (u32bits) count) ++ #define OS_OutPortWordBuffer(ioport, buffer, count) \ ++ ScsiPortWritePortBufferUshort((pu16bits)&port, (pu16bits) buffer, (u32bits) count) ++ ++ #define OS_Lock(x) ++ #define OS_UnLock(x) ++#endif /* NT || WIN95_32 || WIN95_16 */ ++ ++#if defined (UNIX) && !defined(OS_InPortByte) ++ #define OS_InPortByte(ioport) inb((u16bits)ioport) ++ #define OS_InPortWord(ioport) inw((u16bits)ioport) ++ #define OS_InPortLong(ioport) inl((u16bits)ioport) ++ #define OS_OutPortByte(ioport,val) outb((u16bits)ioport, (u08bits)val) ++ #define OS_OutPortWord(ioport,val) outw((u16bits)ioport, (u16bits)val) ++ #define OS_OutPortLong(ioport,val) outl((u16bits)ioport, (u32bits)val) ++ ++ #define OS_Lock(x) ++ #define OS_UnLock(x) ++#endif /* UNIX */ ++ ++ ++#if defined(OS2) ++ extern u08bits inb(u32bits ioport); ++ extern u16bits inw(u32bits ioport); ++ extern void outb(u32bits ioport, u08bits val); ++ extern void outw(u32bits ioport, u16bits val); ++ ++ #define OS_InPortByte(ioport) inb(ioport) ++ #define OS_InPortWord(ioport) inw(ioport) ++ #define OS_OutPortByte(ioport, val) outb(ioport, val) ++ #define OS_OutPortWord(ioport, val) outw(ioport, val) ++ extern u32bits OS_InPortLong(u32bits ioport); ++ extern void OS_OutPortLong(u32bits ioport, u32bits val); ++ ++ #define OS_Lock(x) ++ #define OS_UnLock(x) ++#endif /* OS2 */ ++ ++#if defined(SOLARIS_REAL_MODE) ++ ++extern unsigned char inb(unsigned long ioport); ++extern unsigned short inw(unsigned long ioport); ++ ++#define OS_InPortByte(ioport) inb(ioport) ++#define OS_InPortWord(ioport) inw(ioport) ++ ++extern void OS_OutPortByte(unsigned long ioport, unsigned char val); ++extern void OS_OutPortWord(unsigned long ioport, unsigned short val); ++extern unsigned long OS_InPortLong(unsigned long ioport); ++extern void OS_OutPortLong(unsigned long ioport, unsigned long val); ++ ++#define OS_Lock(x) ++#define OS_UnLock(x) ++ ++#endif /* SOLARIS_REAL_MODE */ ++ ++#endif /* __GLOBALS_H__ */ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: sccbmgr.h $ ++ * ++ * Description: Common shared SCCB Interface defines and SCCB ++ * Manager specifics defines. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++#ifndef __SCCB_H__ ++#define __SCCB_H__ ++ ++/*#include <osflags.h>*/ ++/*#include <globals.h>*/ ++ ++#if defined(BUGBUG) ++#define debug_size 32 ++#endif ++ ++#if defined(DOS) ++ ++ typedef struct _SCCB near *PSCCB; ++ #if (FW_TYPE == _SCCB_MGR_) ++ typedef void (*CALL_BK_FN)(PSCCB); ++ #endif ++ ++#elif defined(OS2) ++ ++ typedef struct _SCCB far *PSCCB; ++ #if (FW_TYPE == _SCCB_MGR_) ++ typedef void (far *CALL_BK_FN)(PSCCB); ++ #endif ++ ++#else ++ ++ typedef struct _SCCB *PSCCB; ++ #if (FW_TYPE == _SCCB_MGR_) ++ typedef void (*CALL_BK_FN)(PSCCB); ++ #endif ++ ++#endif ++ ++ ++typedef struct SCCBMgr_info { ++ ULONG si_baseaddr; ++ UCHAR si_present; ++ UCHAR si_intvect; ++ UCHAR si_id; ++ UCHAR si_lun; ++ USHORT si_fw_revision; ++ USHORT si_per_targ_init_sync; ++ USHORT si_per_targ_fast_nego; ++ USHORT si_per_targ_ultra_nego; ++ USHORT si_per_targ_no_disc; ++ USHORT si_per_targ_wide_nego; ++ USHORT si_flags; ++ UCHAR si_card_family; ++ UCHAR si_bustype; ++ UCHAR si_card_model[3]; ++ UCHAR si_relative_cardnum; ++ UCHAR si_reserved[4]; ++ ULONG si_OS_reserved; ++ UCHAR si_XlatInfo[4]; ++ ULONG si_reserved2[5]; ++ ULONG si_secondary_range; ++} SCCBMGR_INFO; ++ ++#if defined(DOS) ++ typedef SCCBMGR_INFO * PSCCBMGR_INFO; ++#else ++ #if defined (COMPILER_16_BIT) ++ typedef SCCBMGR_INFO far * PSCCBMGR_INFO; ++ #else ++ typedef SCCBMGR_INFO * PSCCBMGR_INFO; ++ #endif ++#endif // defined(DOS) ++ ++ ++ ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ #define SCSI_PARITY_ENA 0x0001 ++ #define LOW_BYTE_TERM 0x0010 ++ #define HIGH_BYTE_TERM 0x0020 ++ #define BUSTYPE_PCI 0x3 ++#endif ++ ++#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 ++ ++ ++#define ISA_BUS_CARD 0x01 ++#define EISA_BUS_CARD 0x02 ++#define PCI_BUS_CARD 0x03 ++#define VESA_BUS_CARD 0x04 ++ ++/* SCCB struc used for both SCCB and UCB manager compiles! ++ * The UCB Manager treats the SCCB as it's 'native hardware structure' ++ */ ++ ++ ++#pragma pack(1) ++typedef struct _SCCB { ++ UCHAR OperationCode; ++ UCHAR ControlByte; ++ UCHAR CdbLength; ++ UCHAR RequestSenseLength; ++ ULONG DataLength; ++ ULONG DataPointer; ++ UCHAR CcbRes[2]; ++ UCHAR HostStatus; ++ UCHAR TargetStatus; ++ UCHAR TargID; ++ UCHAR Lun; ++ UCHAR Cdb[12]; ++ UCHAR CcbRes1; ++ UCHAR Reserved1; ++ ULONG Reserved2; ++ ULONG SensePointer; ++ ++ ++ CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */ ++ ULONG SccbIOPort; /* Identifies board base port */ ++ UCHAR SccbStatus; ++ UCHAR SCCBRes2; ++ USHORT SccbOSFlags; ++ ++ ++ ULONG Sccb_XferCnt; /* actual transfer count */ ++ ULONG Sccb_ATC; ++ ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */ ++ ULONG Sccb_res1; ++ USHORT Sccb_MGRFlags; ++ USHORT Sccb_sgseg; ++ UCHAR Sccb_scsimsg; /* identify msg for selection */ ++ UCHAR Sccb_tag; ++ UCHAR Sccb_scsistat; ++ UCHAR Sccb_idmsg; /* image of last msg in */ ++ PSCCB Sccb_forwardlink; ++ PSCCB Sccb_backlink; ++ ULONG Sccb_savedATC; ++ UCHAR Save_Cdb[6]; ++ UCHAR Save_CdbLen; ++ UCHAR Sccb_XferState; ++ ULONG Sccb_SGoffset; ++#if (FW_TYPE == _UCB_MGR_) ++ PUCB Sccb_ucb_ptr; ++#endif ++ } SCCB; ++ ++#define SCCB_SIZE sizeof(SCCB) ++ ++#pragma pack() ++ ++ ++ ++#define SCSI_INITIATOR_COMMAND 0x00 ++#define TARGET_MODE_COMMAND 0x01 ++#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 TAG_Q_MASK 0xE0 ++#define SCCB_DATA_XFER_OUT 0x10 /* Write */ ++#define SCCB_DATA_XFER_IN 0x08 /* Read */ ++ ++ ++#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ ++#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 STATUS_ST 10 ++#define ABORT_ST 11 ++#define MESSAGE_ST 12 ++ ++ ++#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_MSGLOADED 0x02 ++#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_UNEXPECTED_BUS_FREE 0x13 /* Target dropped SCSI BSY */ ++#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */ ++ ++#define SCCB_INVALID_OP_CODE 0x16 /* SCCB invalid operation code */ ++#define SCCB_INVALID_SCCB 0x1A /* Invalid SCCB - bad parameter */ ++#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */ ++#define SCCB_BM_ERR 0x30 /* BusMaster error. */ ++#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */ ++ ++ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ #define HBA_AUTO_SENSE_FAIL 0x1B ++ #define HBA_TQ_REJECTED 0x1C ++ #define HBA_UNSUPORTED_MSG 0x1D ++ #define HBA_HW_ERROR 0x20 ++ #define HBA_ATN_NOT_RESPONDED 0x21 ++ #define HBA_SCSI_RESET_BY_ADAPTER 0x22 ++ #define HBA_SCSI_RESET_BY_TARGET 0x23 ++ #define HBA_WRONG_CONNECTION 0x24 ++ #define HBA_BUS_DEVICE_RESET 0x25 ++ #define HBA_ABORT_QUEUE 0x26 ++ ++#else // these are not defined in BUDI/UCB ++ ++ #define SCCB_INVALID_DIRECTION 0x18 /* Invalid target direction */ ++ #define SCCB_DUPLICATE_SCCB 0x19 /* Duplicate SCCB */ ++ #define SCCB_SCSI_RST 0x35 /* SCSI RESET detected. */ ++ ++#endif // (FW_TYPE==_UCB_MGR_) ++ ++ ++#define SCCB_IN_PROCESS 0x00 ++#define SCCB_SUCCESS 0x01 ++#define SCCB_ABORT 0x02 ++#define SCCB_NOT_FOUND 0x03 ++#define SCCB_ERROR 0x04 ++#define SCCB_INVALID 0x05 ++ ++#define SCCB_SIZE sizeof(SCCB) ++ ++ ++ ++ ++#if (FW_TYPE == _UCB_MGR_) ++ void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb); ++ s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb); ++ u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard); ++ s32bits SccbMgr_isr(CARD_HANDLE pCurrCard); ++ void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard); ++ void SccbMgr_timer_expired(CARD_HANDLE pCurrCard); ++ void SccbMgr_unload_card(CARD_HANDLE pCurrCard); ++ void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard); ++ void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard); ++ void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo); ++ ++#endif ++ ++ ++#if (FW_TYPE == _SCCB_MGR_) ++ ++ #if defined (DOS) ++ int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo); ++ USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo); ++ void SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_SCCB); ++ int SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_SCCB); ++ UCHAR SccbMgr_my_int(USHORT pCurrCard); ++ int SccbMgr_isr(USHORT pCurrCard); ++ void SccbMgr_scsi_reset(USHORT pCurrCard); ++ void SccbMgr_timer_expired(USHORT pCurrCard); ++ USHORT SccbMgr_status(USHORT pCurrCard); ++ void SccbMgr_unload_card(USHORT pCurrCard); ++ ++ #else //non-DOS ++ ++ int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo); ++ ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo); ++ void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_SCCB); ++ int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_SCCB); ++ UCHAR SccbMgr_my_int(ULONG pCurrCard); ++ int SccbMgr_isr(ULONG pCurrCard); ++ void SccbMgr_scsi_reset(ULONG pCurrCard); ++ void SccbMgr_enable_int(ULONG pCurrCard); ++ void SccbMgr_disable_int(ULONG pCurrCard); ++ void SccbMgr_timer_expired(ULONG pCurrCard); ++ void SccbMgr_unload_card(ULONG pCurrCard); ++ ++ #endif ++#endif // (FW_TYPE == _SCCB_MGR_) ++ ++#endif /* __SCCB_H__ */ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: blx30.h $ ++ * ++ * Description: This module contains SCCB/UCB Manager implementation ++ * specific stuff. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++ ++#ifndef __blx30_H__ ++#define __blx30_H__ ++ ++/*#include <globals.h>*/ ++ ++#define ORION_FW_REV 3110 ++ ++ ++ ++ ++#define HARP_REVD 1 ++ ++ ++#if defined(DOS) ++#define QUEUE_DEPTH 8+1 /*1 for Normal disconnect 0 for Q'ing. */ ++#else ++#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */ ++#endif // defined(DOS) ++ ++#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */ ++ ++#define WIDE_SCSI 1 ++ ++#if defined(WIDE_SCSI) ++ #if defined(DOS) ++ #define MAX_SCSI_TAR 16 ++ #define MAX_LUN 8 ++ #define LUN_MASK 0x07 ++ #else ++ #define MAX_SCSI_TAR 16 ++ #define MAX_LUN 32 ++ #define LUN_MASK 0x1f ++ ++ #endif ++#else ++ #define MAX_SCSI_TAR 8 ++ #define MAX_LUN 8 ++ #define LUN_MASK 0x07 ++#endif ++ ++#if defined(HARP_REVA) ++#define SG_BUF_CNT 15 /*Number of prefetched elements. */ ++#else ++#define SG_BUF_CNT 16 /*Number of prefetched elements. */ ++#endif ++ ++#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */ ++#define SG_LOCAL_MASK 0x00000000L ++#define SG_ELEMENT_MASK 0xFFFFFFFFL ++ ++ ++#if (FW_TYPE == _UCB_MGR_) ++ #define OPC_DECODE_NORMAL 0x0f7f ++#endif // _UCB_MGR_ ++ ++ ++ ++#if defined(DOS) ++ ++/*#include <dos.h>*/ ++ #define RD_HARPOON(ioport) (OS_InPortByte(ioport)) ++ #define RDW_HARPOON(ioport) (OS_InPortWord(ioport)) ++ #define WR_HARPOON(ioport,val) (OS_OutPortByte(ioport,val)) ++ #define WRW_HARPOON(ioport,val) (OS_OutPortWord(ioport,val)) ++ ++ #define RD_HARP32(port,offset,data) asm{db 66h; \ ++ push ax; \ ++ mov dx,port; \ ++ add dx, offset; \ ++ db 66h; \ ++ in ax,dx; \ ++ db 66h; \ ++ mov word ptr data,ax;\ ++ db 66h; \ ++ pop ax} ++ ++ #define WR_HARP32(port,offset,data) asm{db 66h; \ ++ push ax; \ ++ mov dx,port; \ ++ add dx, offset; \ ++ db 66h; \ ++ mov ax,word ptr data;\ ++ db 66h; \ ++ out dx,ax; \ ++ db 66h; \ ++ pop ax} ++#endif /* DOS */ ++ ++#if defined(NETWARE) || defined(OTHER_32) || defined(OTHER_16) ++ #define RD_HARPOON(ioport) OS_InPortByte((unsigned long)ioport) ++ #define RDW_HARPOON(ioport) OS_InPortWord((unsigned long)ioport) ++ #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong(ioport + offset)) ++ #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val) ++ #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val) ++ #define WR_HARP32(ioport,offset,data) OS_OutPortLong((ioport + offset), data) ++#endif /* NETWARE || OTHER_32 || OTHER_16 */ ++ ++#if defined(NT) || defined(WIN95_32) || defined(WIN95_16) ++ #define RD_HARPOON(ioport) OS_InPortByte((ULONG)ioport) ++ #define RDW_HARPOON(ioport) OS_InPortWord((ULONG)ioport) ++ #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset))) ++ #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val) ++ #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val) ++ #define WR_HARP32(ioport,offset,data) OS_OutPortLong((ULONG)(ioport + offset), data) ++#endif /* NT || WIN95_32 || WIN95_16 */ ++ ++#if defined (UNIX) ++ #define RD_HARPOON(ioport) OS_InPortByte((u32bits)ioport) ++ #define RDW_HARPOON(ioport) OS_InPortWord((u32bits)ioport) ++ #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset))) ++ #define WR_HARPOON(ioport,val) OS_OutPortByte((u32bits)ioport,(u08bits) val) ++ #define WRW_HARPOON(ioport,val) OS_OutPortWord((u32bits)ioport,(u16bits)val) ++ #define WR_HARP32(ioport,offset,data) OS_OutPortLong((u32bits)(ioport + offset), data) ++#endif /* UNIX */ ++ ++#if defined(OS2) ++ #define RD_HARPOON(ioport) OS_InPortByte((unsigned long)ioport) ++ #define RDW_HARPOON(ioport) OS_InPortWord((unsigned long)ioport) ++ #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset))) ++ #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val) ++ #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val) ++ #define WR_HARP32(ioport,offset,data) OS_OutPortLong(((ULONG)(ioport + offset)), data) ++#endif /* OS2 */ ++ ++#if defined(SOLARIS_REAL_MODE) ++ ++ #define RD_HARPOON(ioport) OS_InPortByte((unsigned long)ioport) ++ #define RDW_HARPOON(ioport) OS_InPortWord((unsigned long)ioport) ++ #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset))) ++ #define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val) ++ #define WRW_HARPOON(ioport,val) OS_OutPortWord((ULONG)ioport,(USHORT)val) ++ #define WR_HARP32(ioport,offset,data) OS_OutPortLong((ULONG)(ioport + offset), (ULONG)data) ++ ++#endif /* SOLARIS_REAL_MODE */ ++ ++#endif /* __BLX30_H__ */ ++ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: target.h $ ++ * ++ * Description: Definitions for Target related structures ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++#ifndef __TARGET__ ++#define __TARGET__ ++ ++/*#include <globals.h>*/ ++/*#include <blx30.h>*/ ++ ++ ++#define TAR_SYNC_MASK (BIT(7)+BIT(6)) ++#define SYNC_UNKNOWN 0x00 ++#define SYNC_TRYING BIT(6) ++#define SYNC_SUPPORTED (BIT(7)+BIT(6)) ++ ++#define TAR_WIDE_MASK (BIT(5)+BIT(4)) ++#define WIDE_DISABLED 0x00 ++#define WIDE_ENABLED BIT(4) ++#define WIDE_NEGOCIATED BIT(5) ++ ++#define TAR_TAG_Q_MASK (BIT(3)+BIT(2)) ++#define TAG_Q_UNKNOWN 0x00 ++#define TAG_Q_TRYING BIT(2) ++#define TAG_Q_REJECT BIT(3) ++#define TAG_Q_SUPPORTED (BIT(3)+BIT(2)) ++ ++#define TAR_ALLOW_DISC BIT(0) ++ ++ ++#define EE_SYNC_MASK (BIT(0)+BIT(1)) ++#define EE_SYNC_ASYNC 0x00 ++#define EE_SYNC_5MB BIT(0) ++#define EE_SYNC_10MB BIT(1) ++#define EE_SYNC_20MB (BIT(0)+BIT(1)) ++ ++#define EE_ALLOW_DISC BIT(6) ++#define EE_WIDE_SCSI BIT(7) ++ ++ ++#if defined(DOS) ++ typedef struct SCCBMgr_tar_info near *PSCCBMgr_tar_info; ++ ++#elif defined(OS2) ++ typedef struct SCCBMgr_tar_info far *PSCCBMgr_tar_info; ++ ++#else ++ typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info; ++ ++#endif ++ ++ ++typedef struct SCCBMgr_tar_info { ++ ++ PSCCB TarSelQ_Head; ++ PSCCB TarSelQ_Tail; ++ UCHAR TarLUN_CA; /*Contingent Allgiance */ ++ UCHAR TarTagQ_Cnt; ++ UCHAR TarSelQ_Cnt; ++ UCHAR TarStatus; ++ UCHAR TarEEValue; ++ UCHAR TarSyncCtrl; ++ UCHAR TarReserved[2]; /* for alignment */ ++ UCHAR LunDiscQ_Idx[MAX_LUN]; ++ UCHAR TarLUNBusy[MAX_LUN]; ++} SCCBMGR_TAR_INFO; ++ ++typedef struct NVRAMInfo { ++ UCHAR niModel; /* Model No. of card */ ++ UCHAR niCardNo; /* Card no. */ ++#if defined(DOS) ++ USHORT niBaseAddr; /* Port Address of card */ ++#else ++ ULONG niBaseAddr; /* Port Address of card */ ++#endif ++ UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */ ++ UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */ ++ UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */ ++ UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */ ++ UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */ ++ UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */ ++}NVRAMINFO; ++ ++#if defined(DOS) ++typedef NVRAMINFO near *PNVRamInfo; ++#elif defined (OS2) ++typedef NVRAMINFO far *PNVRamInfo; ++#else ++typedef NVRAMINFO *PNVRamInfo; ++#endif ++ ++#define MODEL_LT 1 ++#define MODEL_DL 2 ++#define MODEL_LW 3 ++#define MODEL_DW 4 ++ ++ ++typedef struct SCCBcard { ++ PSCCB currentSCCB; ++#if (FW_TYPE==_SCCB_MGR_) ++ PSCCBMGR_INFO cardInfo; ++#else ++ PADAPTER_INFO cardInfo; ++#endif ++ ++#if defined(DOS) ++ USHORT ioPort; ++#else ++ ULONG ioPort; ++#endif ++ ++ USHORT cmdCounter; ++ UCHAR discQCount; ++ UCHAR tagQ_Lst; ++ UCHAR cardIndex; ++ UCHAR scanIndex; ++ UCHAR globalFlags; ++ UCHAR ourId; ++ PNVRamInfo pNvRamInfo; ++ PSCCB discQ_Tbl[QUEUE_DEPTH]; ++ ++}SCCBCARD; ++ ++#if defined(DOS) ++typedef struct SCCBcard near *PSCCBcard; ++#elif defined (OS2) ++typedef struct SCCBcard far *PSCCBcard; ++#else ++typedef struct SCCBcard *PSCCBcard; ++#endif ++ ++ ++#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 TYPE_CODE1 00 /*No ID yet */ ++ ++#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 ID_10_17 0x12 ++#define ID_18_1F 0x0B ++#define MISC_CODE 0x14 ++#define CLR_P_FLAG 0x18 ++#define LOCATE_ON 0x12 ++#define LOCATE_OFF 0x0B ++ ++#define LVL_1_MST 0x00 ++#define LVL_2_MST 0x40 ++#define DOM_LVL_2 0xC0 ++ ++ ++#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 { ++ ++ UCHAR id_string[ID_STRING_LENGTH]; ++ enum scam_id_st state; ++ ++} SCCBSCAM_INFO, *PSCCBSCAM_INFO; ++ ++#endif ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: scsi2.h $ ++ * ++ * Description: Register definitions for HARPOON ASIC. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++#ifndef __SCSI_H__ ++#define __SCSI_H__ ++ ++ ++ ++#define SCSI_TEST_UNIT_READY 0x00 ++#define SCSI_REZERO_UNIT 0x01 ++#define SCSI_REQUEST_SENSE 0x03 ++#define SCSI_FORMAT_UNIT 0x04 ++#define SCSI_REASSIGN 0x07 ++#define SCSI_READ 0x08 ++#define SCSI_WRITE 0x0A ++#define SCSI_SEEK 0x0B ++#define SCSI_INQUIRY 0x12 ++#define SCSI_MODE_SELECT 0x15 ++#define SCSI_RESERVE_UNIT 0x16 ++#define SCSI_RELEASE_UNIT 0x17 ++#define SCSI_MODE_SENSE 0x1A ++#define SCSI_START_STOP_UNIT 0x1B ++#define SCSI_SEND_DIAGNOSTIC 0x1D ++#define SCSI_READ_CAPACITY 0x25 ++#define SCSI_READ_EXTENDED 0x28 ++#define SCSI_WRITE_EXTENDED 0x2A ++#define SCSI_SEEK_EXTENDED 0x2B ++#define SCSI_WRITE_AND_VERIFY 0x2E ++#define SCSI_VERIFY 0x2F ++#define SCSI_READ_DEFECT_DATA 0x37 ++#define SCSI_WRITE_BUFFER 0x3B ++#define SCSI_READ_BUFFER 0x3C ++#define SCSI_RECV_DIAGNOSTIC 0x1C ++#define SCSI_READ_LONG 0x3E ++#define SCSI_WRITE_LONG 0x3F ++#define SCSI_LAST_SCSI_CMND SCSI_WRITE_LONG ++#define SCSI_INVALID_CMND 0xFF ++ ++ ++ ++#define SSGOOD 0x00 ++#define SSCHECK 0x02 ++#define SSCOND_MET 0x04 ++#define SSBUSY 0x08 ++#define SSRESERVATION_CONFLICT 0x18 ++#define SSCMD_TERM 0x22 ++#define SSQ_FULL 0x28 ++ ++ ++#define SKNO_SEN 0x00 ++#define SKRECOV_ERR 0x01 ++#define SKNOT_RDY 0x02 ++#define SKMED_ERR 0x03 ++#define SKHW_ERR 0x04 ++#define SKILL_REQ 0x05 ++#define SKUNIT_ATTN 0x06 ++#define SKDATA_PROTECT 0x07 ++#define SKBLNK_CHK 0x08 ++#define SKCPY_ABORT 0x0A ++#define SKABORT_CMD 0x0B ++#define SKEQUAL 0x0C ++#define SKVOL_OVF 0x0D ++#define SKMIS_CMP 0x0E ++ ++ ++#define SMCMD_COMP 0x00 ++#define SMEXT 0x01 ++#define SMSAVE_DATA_PTR 0x02 ++#define SMREST_DATA_PTR 0x03 ++#define SMDISC 0x04 ++#define SMINIT_DETEC_ERR 0x05 ++#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 SM10MBS 0x19 /* 100ns */ ++#define SM5MBS 0x32 /* 200ns */ ++#define SMOFFSET 0x0F /* Maxoffset value */ ++#define SMWDTR 0x03 ++#define SM8BIT 0x00 ++#define SM16BIT 0x01 ++#define SM32BIT 0x02 ++#define SMIGNORWR 0x23 /* Ignore Wide Residue */ ++ ++ ++#define ARBITRATION_DELAY 0x01 /* 2.4us using a 40Mhz clock */ ++#define BUS_SETTLE_DELAY 0x01 /* 400ns */ ++#define BUS_CLEAR_DELAY 0x01 /* 800ns */ ++ ++ ++ ++#define SPHASE_TO 0x0A /* 10 second timeout waiting for */ ++#define SCMD_TO 0x0F /* Overall command timeout */ ++ ++ ++ ++#define SIX_BYTE_CMD 0x06 ++#define TEN_BYTE_CMD 0x0A ++#define TWELVE_BYTE_CMD 0x0C ++ ++#define ASYNC 0x00 ++#define PERI25NS 0x06 /* 25/4ns to next clock for xbow. */ ++#define SYNC10MBS 0x19 ++#define SYNC5MBS 0x32 ++#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */ ++ ++#endif ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: eeprom.h $ ++ * ++ * Description: Definitions for EEPROM related structures ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++#ifndef __EEPROM__ ++#define __EEPROM__ ++ ++/*#include <globals.h>*/ ++ ++#define EEPROM_WD_CNT 256 ++ ++#define EEPROM_CHECK_SUM 0 ++#define FW_SIGNATURE 2 ++#define MODEL_NUMB_0 4 ++#define MODEL_NUMB_1 5 ++#define MODEL_NUMB_2 6 ++#define MODEL_NUMB_3 7 ++#define MODEL_NUMB_4 8 ++#define MODEL_NUMB_5 9 ++#define IO_BASE_ADDR 10 ++#define IRQ_NUMBER 12 ++#define PCI_INT_PIN 13 ++#define BUS_DELAY 14 /*On time in byte 14 off delay in 15 */ ++#define SYSTEM_CONFIG 16 ++#define SCSI_CONFIG 17 ++#define BIOS_CONFIG 18 ++#define SPIN_UP_DELAY 19 ++#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 DOM_MASTER (BIT(0) + BIT(1)) ++ #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) ++ ++ ++#endif ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: harpoon.h $ ++ * ++ * Description: Register definitions for HARPOON ASIC. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++ ++/*#include <globals.h>*/ ++ ++#ifndef __HARPOON__ ++#define __HARPOON__ ++ ++ ++ #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_vendor_id_0 0x04 /* LSB */ ++ #define hp_sub_vendor_id_1 0x05 /* MSB */ ++ #define hp_sub_device_id_0 0x06 /* LSB */ ++ #define hp_sub_device_id_1 0x07 /* MSB */ ++ ++ ++ #define hp_dual_addr_lo 0x08 ++ #define hp_dual_addr_lmi 0x09 ++ #define hp_dual_addr_hmi 0x0A ++ #define hp_dual_addr_hi 0x0B ++ ++ #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_user_defined_D 0x0D ++ ++ #define hp_reserved_E 0x0E ++ ++ #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 DIAG_MODE BIT(5) /*Diagnostic Mode */ ++ ++ #define BM_ABORT_TMOUT 0x50 /*Halt State machine time out */ ++ ++ #define hp_sys_cfg 0x10 ++ ++ #define DONT_RST_FIFO BIT(7) /*Don't reset FIFO */ ++ ++ ++ #define hp_host_ctrl0 0x11 ++ ++ #define DUAL_ADDR_MODE BIT(0) /*Enable 64-bit addresses */ ++ #define IO_MEM_SPACE BIT(1) /*I/O Memory Space */ ++ #define RESOURCE_LOCK BIT(2) /*Enable Resource Lock */ ++ #define IGNOR_ACCESS_ERR BIT(3) /*Ignore Access Error */ ++ #define HOST_INT_EDGE BIT(4) /*Host interrupt level/edge mode sel */ ++ #define SIX_CLOCKS BIT(5) /*6 Clocks between Strobe */ ++ #define DMA_EVEN_PARITY BIT(6) /*Enable DMA Enen Parity */ ++ ++/* ++ #define BURST_MODE BIT(0) ++*/ ++ ++ #define hp_reserved_12 0x12 ++ ++ #define hp_host_blk_cnt 0x13 ++ ++ #define XFER_BLK1 0x00 /* 0 0 0 1 byte per block*/ ++ #define XFER_BLK2 0x01 /* 0 0 1 2 byte per block*/ ++ #define XFER_BLK4 0x02 /* 0 1 0 4 byte per block*/ ++ #define XFER_BLK8 0x03 /* 0 1 1 8 byte per block*/ ++ #define XFER_BLK16 0x04 /* 1 0 0 16 byte per block*/ ++ #define XFER_BLK32 0x05 /* 1 0 1 32 byte per block*/ ++ #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/ ++ ++ #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/ ++ ++ ++ #define hp_reserved_14 0x14 ++ #define hp_reserved_15 0x15 ++ #define hp_reserved_16 0x16 ++ ++ #define hp_int_mask 0x17 ++ ++ #define INT_CMD_COMPL BIT(0) /* DMA command complete */ ++ #define INT_EXT_STATUS BIT(1) /* Extended Status Set */ ++ #define INT_SCSI BIT(2) /* Scsi block interrupt */ ++ #define INT_FIFO_RDY BIT(4) /* FIFO data ready */ ++ ++ ++ #define hp_xfer_cnt_lo 0x18 ++ #define hp_xfer_cnt_mi 0x19 ++ #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_MPU 0x02 /* 0 1 0 Transfer Host -> MPU */ ++ #define XFER_MPU_HOST 0x03 /* 0 1 1 Transfer MPU -> Host */ ++ #define XFER_DMA_MPU 0x04 /* 1 0 0 Transfer DMA -> MPU */ ++ #define XFER_MPU_DMA 0x05 /* 1 0 1 Transfer MPU -> DMA */ ++ #define SET_SEMAPHORE 0x06 /* 1 1 0 Set Semaphore */ ++ #define XFER_NOP 0x07 /* 1 1 1 Transfer NOP */ ++ #define XFER_MB_MPU 0x06 /* 1 1 0 Transfer MB -> MPU */ ++ #define XFER_MB_DMA 0x07 /* 1 1 1 Transfer MB -> DMA */ ++ ++ ++ #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */ ++ #define XFER_HOST_8BIT 0x08 /* 0 1 8 BIT Transfer Size */ ++ #define XFER_HOST_16BIT 0x10 /* 1 0 16 BIT Transfer Size */ ++ #define XFER_HOST_32BIT 0x18 /* 1 1 32 BIT Transfer Size */ ++ ++ #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */ ++ #define XFER_DMA_16BIT 0x40 /* 1 0 16 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 WIDE_HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_16BIT)) ++ #define WIDE_HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_16BIT)) ++ ++ #define hp_host_addr_lo 0x1C ++ #define hp_host_addr_lmi 0x1D ++ #define hp_host_addr_hmi 0x1E ++ #define hp_host_addr_hi 0x1F ++ ++ #define hp_pio_data 0x20 ++ #define hp_reserved_21 0x21 ++ #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_brdctl 0x23 ++ ++ #define DAT_7 BIT(7) ++ #define DAT_6 BIT(6) ++ #define DAT_5 BIT(5) ++ #define BRD_STB BIT(4) ++ #define BRD_CS BIT(3) ++ #define BRD_WR BIT(2) ++ ++ #define hp_reserved_24 0x24 ++ #define hp_reserved_25 0x25 ++ ++ ++ ++ ++ #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 BM_XFER_MIN_8 BIT(2) /*Enable bus master transfer of 9 */ ++ #define BIOS_ENA BIT(3) /*Enable BIOS/FLASH Enable */ ++ #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_reserved_27 0x27 ++ ++ #define hp_sg_addr 0x28 ++ #define hp_page_ctrl 0x29 ++ ++ #define SCATTER_EN BIT(0) ++ #define SGRAM_ARAM BIT(1) ++ #define BIOS_SHADOW BIT(2) ++ #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */ ++ #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */ ++ ++ #define hp_reserved_2A 0x2A ++ #define hp_pci_cmd_cfg 0x2B ++ ++ #define IO_SPACE_ENA BIT(0) /*enable I/O space */ ++ #define MEM_SPACE_ENA BIT(1) /*enable memory space */ ++ #define BUS_MSTR_ENA BIT(2) /*enable bus master operation */ ++ #define MEM_WI_ENA BIT(4) /*enable Write and Invalidate */ ++ #define PAR_ERR_RESP BIT(6) /*enable parity error responce. */ ++ ++ #define hp_reserved_2C 0x2C ++ ++ #define hp_pci_stat_cfg 0x2D ++ ++ #define DATA_PARITY_ERR BIT(0) ++ #define REC_TARGET_ABORT BIT(4) /*received Target abort */ ++ #define REC_MASTER_ABORT BIT(5) /*received Master abort */ ++ #define SIG_SYSTEM_ERR BIT(6) ++ #define DETECTED_PAR_ERR BIT(7) ++ ++ #define hp_reserved_2E 0x2E ++ ++ #define hp_sys_status 0x2F ++ ++ #define SLV_DATA_RDY BIT(0) /*Slave data ready */ ++ #define XFER_CNT_ZERO BIT(1) /*Transfer counter = 0 */ ++ #define BM_FIFO_EMPTY BIT(2) /*FIFO empty */ ++ #define BM_FIFO_FULL BIT(3) /*FIFO full */ ++ #define HOST_OP_DONE BIT(4) /*host operation done */ ++ #define DMA_OP_DONE BIT(5) /*DMA operation done */ ++ #define SLV_OP_DONE BIT(6) /*Slave operation done */ ++ #define PWR_ON_FLAG BIT(7) /*Power on flag */ ++ ++ #define hp_reserved_30 0x30 ++ ++ #define hp_host_status0 0x31 ++ ++ #define HOST_TERM BIT(5) /*Host Terminal Count */ ++ #define HOST_TRSHLD BIT(6) /*Host Threshold */ ++ #define CONNECTED_2_HOST BIT(7) /*Connected to Host */ ++ ++ #define hp_reserved_32 0x32 ++ ++ #define hp_rev_num 0x33 ++ ++ #define REV_A_CONST 0x0E ++ #define REV_B_CONST 0x0E ++ ++ #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 FIFO_TC_NOT_ZERO BIT(2) /*FIFO or transfer counter not zero */ ++ #define CHIP_RST_OCCUR BIT(3) /*Chip reset occurs */ ++ #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 BM_CMD_CMPL BIT(0) /*Bus Master command complete */ ++ #define EXT_STATUS_ON BIT(1) /*Extended status is valid */ ++ #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */ ++ #define BM_FIFO_RDY BIT(4) ++ #define INT_ASSERTED BIT(5) /* */ ++ #define SRAM_BUSY BIT(6) /*Scatter/Gather RAM busy */ ++ #define CMD_REG_BUSY BIT(7) ++ ++ ++ #define hp_fifo_cnt 0x38 ++ #define hp_curr_host_cnt 0x39 ++ #define hp_reserved_3A 0x3A ++ #define hp_fifo_in_addr 0x3B ++ ++ #define hp_fifo_out_addr 0x3C ++ #define hp_reserved_3D 0x3D ++ #define hp_reserved_3E 0x3E ++ #define hp_reserved_3F 0x3F ++ ++ ++ ++ extern USHORT default_intena; ++ ++ #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_CMD_PH (BIT(2) ) ++ #define S_MSGO_PH (BIT(2)+BIT(1) ) ++ #define S_STAT_PH (BIT(2) +BIT(0)) ++ #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 NO_ARB BIT(7) ++ #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_TAR BIT(7) ++ #define SCSI_INI BIT(6) ++ #define SCAM_EN BIT(5) ++ #define ACK_HOLD BIT(4) ++ #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_1 0x49 ++ #define hp_xfercnt_2 0x4A ++ #define hp_xfercnt_3 0x4B ++ ++ #define hp_fifodata_0 0x4C ++ #define hp_fifodata_1 0x4D ++ #define hp_addstat 0x4E ++ ++ #define SCAM_TIMER BIT(7) ++ #define AUTO_RUNNING BIT(6) ++ #define FAST_SYNC BIT(5) ++ #define SCSI_MODE8 BIT(3) ++ #define SCSI_PAR_ERR BIT(0) ++ ++ #define hp_prgmcnt_0 0x4F ++ ++ #define AUTO_PC_MASK 0x3F ++ ++ #define hp_selfid_0 0x50 ++ #define hp_selfid_1 0x51 ++ #define hp_arb_id 0x52 ++ ++ #define ARB_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0)) ++ ++ #define hp_select_id 0x53 ++ ++ #define RESEL_ID (BIT(7) + BIT(6) + BIT(5) + BIT(4)) ++ #define SELECT_ID (BIT(3) + BIT(2) + BIT(1) + BIT(0)) ++ ++ #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 RATE_20MB 0x00 ++ #define RATE_10MB ( BIT(5)) ++ #define RATE_6_6MB ( BIT(6) ) ++ #define RATE_5MB ( BIT(6)+BIT(5)) ++ #define RATE_4MB (BIT(7) ) ++ #define RATE_3_33MB (BIT(7) +BIT(5)) ++ #define RATE_2_85MB (BIT(7)+BIT(6) ) ++ #define RATE_2_5MB (BIT(7)+BIT(5)+BIT(6)) ++ #define NEXT_CLK BIT(5) ++ #define SLOWEST_SYNC (BIT(7)+BIT(6)+BIT(5)) ++ #define NARROW_SCSI BIT(4) ++ #define SYNC_OFFSET (BIT(3) + BIT(2) + BIT(1) + BIT(0)) ++ #define DEFAULT_ASYNC 0x00 ++ #define DEFAULT_OFFSET 0x0F ++ ++ #define hp_autostart_0 0x64 ++ #define hp_autostart_1 0x65 ++ #define hp_autostart_2 0x66 ++ #define hp_autostart_3 0x67 ++ ++ ++ ++ #define DISABLE 0x00 ++ #define AUTO_IMMED BIT(5) ++ #define SELECT BIT(6) ++ #define RESELECT (BIT(6)+BIT(5)) ++ #define BUSFREE BIT(7) ++ #define XFER_0 (BIT(7)+BIT(5)) ++ #define END_DATA (BIT(7)+BIT(6)) ++ #define MSG_PHZ (BIT(7)+BIT(6)+BIT(5)) ++ ++ #define hp_gp_reg_0 0x68 ++ #define hp_gp_reg_1 0x69 ++ #define hp_gp_reg_2 0x6A ++ #define hp_gp_reg_3 0x6B ++ ++ #define hp_seltimeout 0x6C ++ ++ ++ #define TO_2ms 0x54 /* 2.0503ms */ ++ #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 TO_350ms 0xD6 /* 350.62ms */ ++ #define TO_417ms 0xFF /* 417.79ms */ ++ ++ #define hp_clkctrl_0 0x6D ++ ++ #define PWR_DWN BIT(6) ++ #define ACTdeassert BIT(4) ++ #define ATNonErr BIT(3) ++ #define CLK_30MHZ BIT(1) ++ #define CLK_40MHZ (BIT(1) + BIT(0)) ++ #define CLK_50MHZ BIT(2) ++ ++ #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ) ++ ++ #define hp_fiforead 0x6E ++ #define hp_fifowrite 0x6F ++ ++ #define hp_offsetctr 0x70 ++ #define hp_xferstat 0x71 ++ ++ #define FIFO_FULL BIT(7) ++ #define FIFO_EMPTY BIT(6) ++ #define FIFO_MASK 0x3F /* Mask for the FIFO count value. */ ++ #define FIFO_LEN 0x20 ++ ++ #define hp_portctrl_1 0x72 ++ ++ #define EVEN_HOST_P BIT(5) ++ #define INVT_SCSI BIT(4) ++ #define CHK_SCSI_P BIT(3) ++ #define HOST_MODE8 BIT(0) ++ #define HOST_MODE16 0x00 ++ ++ #define hp_xfer_pad 0x73 ++ ++ #define ID_UNLOCK BIT(3) ++ #define XFER_PAD BIT(2) ++ ++ #define hp_scsidata_0 0x74 ++ #define hp_scsidata_1 0x75 ++ #define hp_timer_0 0x76 ++ #define hp_timer_1 0x77 ++ ++ #define hp_reserved_78 0x78 ++ #define hp_reserved_79 0x79 ++ #define hp_reserved_7A 0x7A ++ #define hp_reserved_7B 0x7B ++ ++ #define hp_reserved_7C 0x7C ++ #define hp_reserved_7D 0x7D ++ #define hp_reserved_7E 0x7E ++ #define hp_reserved_7F 0x7F ++ ++ #define hp_aramBase 0x80 ++ #define BIOS_DATA_OFFSET 0x60 ++ #define BIOS_RELATIVE_CARD 0x64 ++ ++ ++ ++ ++ #define AUTO_LEN 0x80 ++ #define AR0 0x00 ++ #define AR1 BITW(8) ++ #define AR2 BITW(9) ++ #define AR3 (BITW(9) + BITW(8)) ++ #define SDATA BITW(10) ++ ++ #define NOP_OP 0x00 /* Nop command */ ++ ++ #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */ ++ ++ #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */ ++ ++ #define CBE_OP (BITW(14)+BITW(12)+BITW(11)) /* Cmp SCSI cmd class & Branch EQ */ ++ ++ #define CBN_OP (BITW(14)+BITW(13)) /* Cmp SCSI cmd class & Branch NOT EQ */ ++ ++ #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 AILLEGAL (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 ATN_SET BITW(8) ++ #define ATN_RESET BITW(9) ++ #define XFER_CNT (BITW(9)+BITW(8)) ++ #define FIFO_0 BITW(10) ++ #define FIFO_NOT0 (BITW(10)+BITW(8)) ++ #define T_USE_SYNC0 (BITW(10)+BITW(9)) ++ ++ ++ #define MPM_OP BITW(15) /* Match phase and move data */ ++ ++ #define MDR_OP (BITW(12)+BITW(11)) /* Move data to Reg. */ ++ ++ #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_AR2 BIT(1) ++ #define D_AR3 (BIT(1) + BIT(0)) ++ #define D_SDATA BIT(2) ++ #define D_BUCKET (BIT(2) + BIT(1) + BIT(0)) ++ ++ ++ #define ADR_OP (BITW(13)+BITW(12)) /* Logical AND Reg. w. Data */ ++ ++ #define ADS_OP (BITW(14)+BITW(13)+BITW(12)) ++ ++ #define ODR_OP (BITW(13)+BITW(12)+BITW(11)) ++ ++ #define ODS_OP (BITW(14)+BITW(13)+BITW(12)+BITW(11)) ++ ++ #define STR_OP (BITW(15)+BITW(14)) /* Store to A_Reg. */ ++ ++ #define AINT_ENA1 0x00 ++ #define AINT_STAT1 BITW(8) ++ #define ASCSI_SIG BITW(9) ++ #define ASCSI_CNTL (BITW(9)+BITW(8)) ++ #define APORT_CNTL BITW(10) ++ #define ARST_CNTL (BITW(10)+BITW(8)) ++ #define AXFERCNT0 (BITW(10)+BITW(9)) ++ #define AXFERCNT1 (BITW(10)+BITW(9)+BITW(8)) ++ #define AXFERCNT2 BITW(11) ++ #define AFIFO_DATA (BITW(11)+BITW(8)) ++ #define ASCSISELID (BITW(11)+BITW(9)) ++ #define ASCSISYNC0 (BITW(11)+BITW(9)+BITW(8)) ++ ++ ++ #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_IDI_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 MI 0x14 /*Message In */ ++ #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 RFAIL 0x27 /*Reselection failed */ ++ #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 SELECTION_START 0x00 ++ #define DISCONNECT_START 0x10/2 ++ #define END_DATA_START 0x14/2 ++ #define NONTAG_STRT 0x02/2 ++ #define CMD_ONLY_STRT CMDPZ/2 ++ #define TICKLE_STRT TICK/2 ++ #define SELCHK_STRT SELCHK/2 ++ ++ ++ ++ ++#define mEEPROM_CLK_DELAY(port) (RD_HARPOON(port+hp_intstat_1)) ++ ++#define mWAIT_10MS(port) (RD_HARPOON(port+hp_intstat_1)) ++ ++ ++#define CLR_XFER_CNT(port) (WR_HARPOON(port+hp_xfercnt_0, 0x00)) ++ ++#define SET_XFER_CNT(port, data) (WR_HARP32(port,hp_xfercnt_0,data)) ++ ++#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,\ ++ xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0))) ++ */ ++#if defined(DOS) ++#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((USHORT)(port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\ ++ addr >>= 16,\ ++ WRW_HARPOON((USHORT)(port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\ ++ WR_HARP32(port,hp_xfercnt_0,count),\ ++ WRW_HARPOON((USHORT)(port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\ ++ count >>= 16,\ ++ WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF))) ++#else ++#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\ ++ addr >>= 16,\ ++ WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\ ++ WR_HARP32(port,hp_xfercnt_0,count),\ ++ WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\ ++ count >>= 16,\ ++ WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF))) ++#endif ++ ++#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 ACCEPT_STAT(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\ ++ WR_HARPOON(port+hp_scsisig, S_ILL_PH);} ++ ++#define ACCEPT_STAT_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))) ++ ++ ++ ++#endif ++ ++ ++#if (FW_TYPE==_UCB_MGR_) ++void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb); ++void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb); ++void UpdateCheckSum(u32bits baseport); ++#endif // (FW_TYPE==_UCB_MGR_) ++ ++#if defined(DOS) ++UCHAR sfm(USHORT port, PSCCB pcurrSCCB); ++void scsiStartAuto(USHORT port); ++UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag); ++void ssel(USHORT port, UCHAR p_card); ++void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard); ++void sdecm(UCHAR message, USHORT port, UCHAR p_card); ++void shandem(USHORT port, UCHAR p_card,PSCCB pCurrSCCB); ++void stsyncn(USHORT port, UCHAR p_card); ++void sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset); ++void sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info); ++void sresb(USHORT port, UCHAR p_card); ++void sxfrp(USHORT p_port, UCHAR p_card); ++void schkdd(USHORT port, UCHAR p_card); ++UCHAR RdStack(USHORT port, UCHAR index); ++void WrStack(USHORT portBase, UCHAR index, UCHAR data); ++UCHAR ChkIfChipInitialized(USHORT ioPort); ++ ++#if defined(V302) ++UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun); ++#endif ++ ++void SendMsg(USHORT port, UCHAR message); ++void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code); ++UCHAR scsellDOS(USHORT p_port, UCHAR targ_id); ++#else ++UCHAR sfm(ULONG port, PSCCB pcurrSCCB); ++void scsiStartAuto(ULONG port); ++UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag); ++void ssel(ULONG port, UCHAR p_card); ++void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard); ++void sdecm(UCHAR message, ULONG port, UCHAR p_card); ++void shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB); ++void stsyncn(ULONG port, UCHAR p_card); ++void sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset); ++void sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info); ++void sresb(ULONG port, UCHAR p_card); ++void sxfrp(ULONG p_port, UCHAR p_card); ++void schkdd(ULONG port, UCHAR p_card); ++UCHAR RdStack(ULONG port, UCHAR index); ++void WrStack(ULONG portBase, UCHAR index, UCHAR data); ++UCHAR ChkIfChipInitialized(ULONG ioPort); ++ ++#if defined(V302) ++UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tar, PUCHAR lun); ++#endif ++ ++void SendMsg(ULONG port, UCHAR message); ++void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code); ++#endif ++ ++void ssenss(PSCCBcard pCurrCard); ++void sinits(PSCCB p_sccb, UCHAR p_card); ++void RNVRamData(PNVRamInfo pNvRamInfo); ++ ++#if defined(WIDE_SCSI) ++ #if defined(DOS) ++ UCHAR siwidn(USHORT port, UCHAR p_card); ++ void stwidn(USHORT port, UCHAR p_card); ++ void siwidr(USHORT port, UCHAR width); ++ #else ++ UCHAR siwidn(ULONG port, UCHAR p_card); ++ void stwidn(ULONG port, UCHAR p_card); ++ void siwidr(ULONG port, UCHAR width); ++ #endif ++#endif ++ ++ ++void queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card); ++void queueDisconnect(PSCCB p_SCCB, UCHAR p_card); ++void queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB, UCHAR p_card); ++void queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card); ++void queueFlushSccb(UCHAR p_card, UCHAR error_code); ++void queueAddSccb(PSCCB p_SCCB, UCHAR card); ++UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card); ++void utilUpdateResidual(PSCCB p_SCCB); ++USHORT CalcCrc16(UCHAR buffer[]); ++UCHAR CalcLrc(UCHAR buffer[]); ++ ++ ++#if defined(DOS) ++void Wait1Second(USHORT p_port); ++void Wait(USHORT p_port, UCHAR p_delay); ++void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode); ++void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr); ++USHORT utilEERead(USHORT p_port, USHORT ee_addr); ++USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr); ++void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr); ++#else ++void Wait1Second(ULONG p_port); ++void Wait(ULONG p_port, UCHAR p_delay); ++void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode); ++void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr); ++USHORT utilEERead(ULONG p_port, USHORT ee_addr); ++USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr); ++void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr); ++#endif ++ ++ ++ ++#if defined(OS2) ++ void far phaseDataOut(ULONG port, UCHAR p_card); ++ void far phaseDataIn(ULONG port, UCHAR p_card); ++ void far phaseCommand(ULONG port, UCHAR p_card); ++ void far phaseStatus(ULONG port, UCHAR p_card); ++ void far phaseMsgOut(ULONG port, UCHAR p_card); ++ void far phaseMsgIn(ULONG port, UCHAR p_card); ++ void far phaseIllegal(ULONG port, UCHAR p_card); ++#else ++ #if defined(DOS) ++ void phaseDataOut(USHORT port, UCHAR p_card); ++ void phaseDataIn(USHORT port, UCHAR p_card); ++ void phaseCommand(USHORT port, UCHAR p_card); ++ void phaseStatus(USHORT port, UCHAR p_card); ++ void phaseMsgOut(USHORT port, UCHAR p_card); ++ void phaseMsgIn(USHORT port, UCHAR p_card); ++ void phaseIllegal(USHORT port, UCHAR p_card); ++ #else ++ void phaseDataOut(ULONG port, UCHAR p_card); ++ void phaseDataIn(ULONG port, UCHAR p_card); ++ void phaseCommand(ULONG port, UCHAR p_card); ++ void phaseStatus(ULONG port, UCHAR p_card); ++ void phaseMsgOut(ULONG port, UCHAR p_card); ++ void phaseMsgIn(ULONG port, UCHAR p_card); ++ void phaseIllegal(ULONG port, UCHAR p_card); ++ #endif ++#endif ++ ++#if defined(DOS) ++void phaseDecode(USHORT port, UCHAR p_card); ++void phaseChkFifo(USHORT port, UCHAR p_card); ++void phaseBusFree(USHORT p_port, UCHAR p_card); ++#else ++void phaseDecode(ULONG port, UCHAR p_card); ++void phaseChkFifo(ULONG port, UCHAR p_card); ++void phaseBusFree(ULONG p_port, UCHAR p_card); ++#endif ++ ++ ++ ++ ++#if defined(DOS) ++void XbowInit(USHORT port, UCHAR scamFlg); ++void BusMasterInit(USHORT p_port); ++int DiagXbow(USHORT port); ++int DiagBusMaster(USHORT port); ++void DiagEEPROM(USHORT p_port); ++#else ++void XbowInit(ULONG port, UCHAR scamFlg); ++void BusMasterInit(ULONG p_port); ++int DiagXbow(ULONG port); ++int DiagBusMaster(ULONG port); ++void DiagEEPROM(ULONG p_port); ++#endif ++ ++ ++ ++ ++#if defined(DOS) ++void busMstrAbort(USHORT port); ++UCHAR busMstrTimeOut(USHORT port); ++void dataXferProcessor(USHORT port, PSCCBcard pCurrCard); ++void busMstrSGDataXferStart(USHORT port, PSCCB pCurrSCCB); ++void busMstrDataXferStart(USHORT port, PSCCB pCurrSCCB); ++void hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB); ++#else ++void busMstrAbort(ULONG port); ++UCHAR busMstrTimeOut(ULONG port); ++void dataXferProcessor(ULONG port, PSCCBcard pCurrCard); ++void busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB); ++void busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB); ++void hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB); ++#endif ++void hostDataXferRestart(PSCCB currSCCB); ++ ++ ++#if defined (DOS) ++UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int); ++#else ++UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int); ++ ++#endif ++ ++void SccbMgrTableInitAll(void); ++void SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card); ++void SccbMgrTableInitTarget(UCHAR p_card, UCHAR target); ++ ++ ++ ++void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up); ++ ++#if defined(DOS) ++int scarb(USHORT p_port, UCHAR p_sel_type); ++void scbusf(USHORT p_port); ++void scsel(USHORT p_port); ++void scasid(UCHAR p_card, USHORT p_port); ++UCHAR scxferc(USHORT p_port, UCHAR p_data); ++UCHAR scsendi(USHORT p_port, UCHAR p_id_string[]); ++UCHAR sciso(USHORT p_port, UCHAR p_id_string[]); ++void scwirod(USHORT p_port, UCHAR p_data_bit); ++void scwiros(USHORT p_port, UCHAR p_data_bit); ++UCHAR scvalq(UCHAR p_quintet); ++UCHAR scsell(USHORT p_port, UCHAR targ_id); ++void scwtsel(USHORT p_port); ++void inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id); ++void scsavdi(UCHAR p_card, USHORT p_port); ++#else ++int scarb(ULONG p_port, UCHAR p_sel_type); ++void scbusf(ULONG p_port); ++void scsel(ULONG p_port); ++void scasid(UCHAR p_card, ULONG p_port); ++UCHAR scxferc(ULONG p_port, UCHAR p_data); ++UCHAR scsendi(ULONG p_port, UCHAR p_id_string[]); ++UCHAR sciso(ULONG p_port, UCHAR p_id_string[]); ++void scwirod(ULONG p_port, UCHAR p_data_bit); ++void scwiros(ULONG p_port, UCHAR p_data_bit); ++UCHAR scvalq(UCHAR p_quintet); ++UCHAR scsell(ULONG p_port, UCHAR targ_id); ++void scwtsel(ULONG p_port); ++void inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id); ++void scsavdi(UCHAR p_card, ULONG p_port); ++#endif ++UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]); ++ ++ ++#if defined(DOS) ++void autoCmdCmplt(USHORT p_port, UCHAR p_card); ++void autoLoadDefaultMap(USHORT p_port); ++#else ++void autoCmdCmplt(ULONG p_port, UCHAR p_card); ++void autoLoadDefaultMap(ULONG p_port); ++#endif ++ ++ ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ void OS_start_timer(unsigned long ioport, unsigned long timeout); ++ void OS_stop_timer(unsigned long ioport, unsigned long timeout); ++ void OS_disable_int(unsigned char intvec); ++ void OS_enable_int(unsigned char intvec); ++ void OS_delay(unsigned long count); ++ int OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr); ++ #if !(defined(UNIX) || defined(OS2) || defined(SOLARIS_REAL_MODE)) ++ void OS_Lock(PSCCBMGR_INFO pCardInfo); ++ void OS_UnLock(PSCCBMGR_INFO pCardInfo); ++#endif // if FW_TYPE == ... ++ ++#endif ++ ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++ ++ ++#if defined(OS2) ++ extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR); ++#else ++ #if defined(DOS) ++ extern void (*s_PhaseTbl[8]) (USHORT, UCHAR); ++ #else ++ extern void (*s_PhaseTbl[8]) (ULONG, UCHAR); ++ #endif ++#endif ++ ++extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR]; ++extern NVRAMINFO nvRamInfo[MAX_MB_CARDS]; ++#if defined(DOS) || defined(OS2) ++extern UCHAR temp_id_string[ID_STRING_LENGTH]; ++#endif ++extern UCHAR scamHAString[]; ++ ++ ++extern UCHAR mbCards; ++#if defined(BUGBUG) ++extern UCHAR debug_int[MAX_CARDS][debug_size]; ++extern UCHAR debug_index[MAX_CARDS]; ++void Debug_Load(UCHAR p_card, UCHAR p_bug_data); ++#endif ++ ++#if (FW_TYPE==_SCCB_MGR_) ++#if defined(DOS) ++ extern UCHAR first_time; ++#endif ++#endif /* (FW_TYPE==_SCCB_MGR_) */ ++ ++#if (FW_TYPE==_UCB_MGR_) ++#if defined(DOS) ++ extern u08bits first_time; ++#endif ++#endif /* (FW_TYPE==_UCB_MGR_) */ ++ ++#if defined(BUGBUG) ++void Debug_Load(UCHAR p_card, UCHAR p_bug_data); ++#endif ++ ++extern unsigned int SccbGlobalFlags; ++ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: sccb.c $ ++ * ++ * Description: Functions relating to handling of the SCCB interface ++ * between the device driver and the HARPOON. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++ /*#include <budioctl.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <eeprom.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <harpoon.h>*/ ++ ++ ++ ++#if (FW_TYPE==_SCCB_MGR_) ++#define mOS_Lock(card) OS_Lock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo)) ++#define mOS_UnLock(card) OS_UnLock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo)) ++#else /* FW_TYPE==_UCB_MGR_ */ ++#define mOS_Lock(card) OS_Lock((u32bits)(((PSCCBcard)card)->ioPort)) ++#define mOS_UnLock(card) OS_UnLock((u32bits)(((PSCCBcard)card)->ioPort)) ++#endif ++ ++ ++/* ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++extern SCCBCARD BL_Card[MAX_CARDS]; ++ ++extern NVRAMINFO nvRamInfo[MAX_MB_CARDS]; ++extern UCHAR mbCards; ++ ++#if defined (OS2) ++ extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR); ++#else ++ #if defined(DOS) ++ extern void (*s_PhaseTbl[8]) (USHORT, UCHAR); ++ #else ++ extern void (*s_PhaseTbl[8]) (ULONG, UCHAR); ++ #endif ++#endif ++ ++ ++#if defined(BUGBUG) ++extern UCHAR debug_int[MAX_CARDS][debug_size]; ++extern UCHAR debug_index[MAX_CARDS]; ++void Debug_Load(UCHAR p_card, UCHAR p_bug_data); ++#endif ++*/ ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_sense_adapter ++ * ++ * Description: Setup and/or Search for cards and return info to caller. ++ * ++ *---------------------------------------------------------------------*/ ++ ++int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo) ++{ ++#if defined(DOS) ++#else ++ static UCHAR first_time = 1; ++#endif ++ ++ UCHAR i,j,id,ScamFlg; ++ USHORT temp,temp2,temp3,temp4,temp5,temp6; ++#if defined(DOS) ++ USHORT ioport; ++#else ++ ULONG ioport; ++#endif ++ PNVRamInfo pCurrNvRam; ++ ++#if defined(DOS) ++ ioport = (USHORT)pCardInfo->si_baseaddr; ++#else ++ ioport = pCardInfo->si_baseaddr; ++#endif ++ ++ ++ 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) ++ { ++ SccbMgrTableInitAll(); ++ first_time = 0; ++ mbCards = 0; ++ } ++ ++ if(RdStack(ioport, 0) != 0x00) { ++ if(ChkIfChipInitialized(ioport) == FALSE) ++ { ++ pCurrNvRam = NULL; ++ WR_HARPOON(ioport+hp_semaphore, 0x00); ++ XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ ++ DiagEEPROM(ioport); ++ } ++ else ++ { ++ if(mbCards < MAX_MB_CARDS) { ++ pCurrNvRam = &nvRamInfo[mbCards]; ++ mbCards++; ++ pCurrNvRam->niBaseAddr = ioport; ++ RNVRamData(pCurrNvRam); ++ }else ++ return((int) FAILURE); ++ } ++ }else ++ pCurrNvRam = NULL; ++#if defined (NO_BIOS_OPTION) ++ pCurrNvRam = NULL; ++ XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ ++ DiagEEPROM(ioport); ++#endif /* No BIOS Option */ ++ ++ WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT); ++ WR_HARPOON(ioport+hp_sys_ctrl, 0x00); ++ ++ if(pCurrNvRam) ++ pCardInfo->si_id = pCurrNvRam->niAdapId; ++ else ++ pCardInfo->si_id = (UCHAR)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) & ++ (UCHAR)0x0FF); ++ ++ pCardInfo->si_lun = 0x00; ++ pCardInfo->si_fw_revision = ORION_FW_REV; ++ temp2 = 0x0000; ++ temp3 = 0x0000; ++ temp4 = 0x0000; ++ temp5 = 0x0000; ++ temp6 = 0x0000; ++ ++ for (id = 0; id < (16/2); id++) { ++ ++ if(pCurrNvRam){ ++ temp = (USHORT) pCurrNvRam->niSyncTbl[id]; ++ temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + ++ (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); ++ }else ++ temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id)); ++ ++ for (i = 0; i < 2; temp >>=8,i++) { ++ ++ temp2 >>= 1; ++ temp3 >>= 1; ++ temp4 >>= 1; ++ temp5 >>= 1; ++ temp6 >>= 1; ++ switch (temp & 0x3) ++ { ++ case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */ ++ temp6 |= 0x8000; /* Fall through */ ++ case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */ ++ temp5 |= 0x8000; /* Fall through */ ++ case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */ ++ temp2 |= 0x8000; /* Fall through */ ++ case AUTO_RATE_00: /* Asynchronous */ ++ break; ++ } ++ ++ 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 ++ i = (UCHAR)(utilEERead(ioport, (SYSTEM_CONFIG/2))); ++ ++ if(pCurrNvRam) ++ ScamFlg = pCurrNvRam->niScamConf; ++ else ++ ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2); ++ ++ 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{ ++ temp = utilEERead(ioport, (MODEL_NUMB_0/2)); ++ pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8); ++ temp = utilEERead(ioport, (MODEL_NUMB_2/2)); ++ ++ pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF); ++ pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8); ++ } ++ ++ 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 = ++ (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1); ++ ++ SGRAM_ACCESS(ioport); ++ ++ s_PhaseTbl[0] = phaseDataOut; ++ s_PhaseTbl[1] = phaseDataIn; ++ s_PhaseTbl[2] = phaseIllegal; ++ s_PhaseTbl[3] = phaseIllegal; ++ s_PhaseTbl[4] = phaseCommand; ++ s_PhaseTbl[5] = phaseStatus; ++ s_PhaseTbl[6] = phaseMsgOut; ++ s_PhaseTbl[7] = phaseMsgIn; ++ ++ pCardInfo->si_present = 0x01; ++ ++#if defined(BUGBUG) ++ ++ ++ for (i = 0; i < MAX_CARDS; i++) { ++ ++ for (id=0; id<debug_size; id++) ++ debug_int[i][id] = (UCHAR)0x00; ++ debug_index[i] = 0; ++ } ++ ++#endif ++ ++ return(0); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_config_adapter ++ * ++ * Description: Setup adapter for normal operation (hard reset). ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo) ++#else ++ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo) ++#endif ++{ ++ PSCCBcard CurrCard = NULL; ++ PNVRamInfo pCurrNvRam; ++ UCHAR i,j,thisCard, ScamFlg; ++ USHORT temp,sync_bit_map,id; ++#if defined(DOS) ++ USHORT ioport; ++#else ++ ULONG ioport; ++#endif ++ ++#if defined(DOS) ++ ioport = (USHORT)pCardInfo->si_baseaddr; ++#else ++ ioport = pCardInfo->si_baseaddr; ++#endif ++ ++ for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) { ++ ++ if (thisCard == MAX_CARDS) { ++ ++ return(FAILURE); ++ } ++ ++ if (BL_Card[thisCard].ioPort == ioport) { ++ ++ CurrCard = &BL_Card[thisCard]; ++ SccbMgrTableInitCard(CurrCard,thisCard); ++ break; ++ } ++ ++ else if (BL_Card[thisCard].ioPort == 0x00) { ++ ++ BL_Card[thisCard].ioPort = ioport; ++ CurrCard = &BL_Card[thisCard]; ++ ++ if(mbCards) ++ for(i = 0; i < mbCards; i++){ ++ if(CurrCard->ioPort == nvRamInfo[i].niBaseAddr) ++ CurrCard->pNvRamInfo = &nvRamInfo[i]; ++ } ++ SccbMgrTableInitCard(CurrCard,thisCard); ++ CurrCard->cardIndex = thisCard; ++ CurrCard->cardInfo = pCardInfo; ++ ++ break; ++ } ++ } ++ ++ pCurrNvRam = CurrCard->pNvRamInfo; ++ ++ if(pCurrNvRam){ ++ ScamFlg = pCurrNvRam->niScamConf; ++ } ++ else{ ++ ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2); ++ } ++ ++ ++ BusMasterInit(ioport); ++ XbowInit(ioport, ScamFlg); ++ ++#if defined (NO_BIOS_OPTION) ++ ++ ++ if (DiagXbow(ioport)) return(FAILURE); ++ if (DiagBusMaster(ioport)) return(FAILURE); ++ ++#endif /* No BIOS Option */ ++ ++ autoLoadDefaultMap(ioport); ++ ++ ++ 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; ++ ++ i = (UCHAR) pCardInfo->si_flags; ++ 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)) { ++ ++ sresb(ioport,thisCard); ++ ++ scini(thisCard, pCardInfo->si_id, 0); ++ } ++ ++ ++ ++ if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) ++ CurrCard->globalFlags |= F_NO_FILTER; ++ ++ if(pCurrNvRam){ ++ if(pCurrNvRam->niSysConf & 0x10) ++ CurrCard->globalFlags |= F_GREEN_PC; ++ } ++ else{ ++ if (utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA) ++ CurrCard->globalFlags |= F_GREEN_PC; ++ } ++ ++ /* 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 (utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA) ++ CurrCard->globalFlags |= F_DO_RENEGO; ++ } ++ ++ if(pCurrNvRam){ ++ if(pCurrNvRam->niScsiConf & 0x08) ++ CurrCard->globalFlags |= F_CONLUN_IO; ++ } ++ else{ ++ if (utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA) ++ CurrCard->globalFlags |= F_CONLUN_IO; ++ } ++ ++ ++ temp = pCardInfo->si_per_targ_no_disc; ++ ++ for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) { ++ ++ if (temp & id) ++ sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC; ++ } ++ ++ sync_bit_map = 0x0001; ++ ++ for (id = 0; id < (MAX_SCSI_TAR/2); id++) { ++ ++ if(pCurrNvRam){ ++ temp = (USHORT) pCurrNvRam->niSyncTbl[id]; ++ temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + ++ (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); ++ }else ++ temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id)); ++ ++ for (i = 0; i < 2; temp >>=8,i++) { ++ ++ if (pCardInfo->si_per_targ_init_sync & sync_bit_map) { ++ ++ sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp; ++ } ++ ++ else { ++ sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED; ++ sccbMgrTbl[thisCard][id*2+i].TarEEValue = ++ (UCHAR)(temp & ~EE_SYNC_MASK); ++ } ++ ++#if defined(WIDE_SCSI) ++/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) || ++ (id*2+i >= 8)){ ++*/ ++ if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){ ++ ++ sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI; ++ ++ } ++ ++ else { /* NARROW SCSI */ ++ sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED; ++ } ++ ++#else ++ sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED; ++#endif ++ ++ ++ sync_bit_map <<= 1; ++ ++ ++ ++ } ++ } ++ ++ WR_HARPOON((ioport+hp_semaphore), ++ (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT)); ++ ++#if defined(DOS) ++ return((USHORT)CurrCard); ++#else ++ return((ULONG)CurrCard); ++#endif ++} ++ ++#else /* end (FW_TYPE==_SCCB_MGR_) */ ++ ++ ++ ++STATIC s16bits FP_PresenceCheck(PMGR_INFO pMgrInfo) ++{ ++ PMGR_ENTRYPNTS pMgr_EntryPnts = &pMgrInfo->mi_Functions; ++ ++ pMgr_EntryPnts->UCBMgr_probe_adapter = probe_adapter; ++ pMgr_EntryPnts->UCBMgr_init_adapter = init_adapter; ++ pMgr_EntryPnts->UCBMgr_start_UCB = SccbMgr_start_sccb; ++ pMgr_EntryPnts->UCBMgr_build_UCB = build_UCB; ++ pMgr_EntryPnts->UCBMgr_abort_UCB = SccbMgr_abort_sccb; ++ pMgr_EntryPnts->UCBMgr_my_int = SccbMgr_my_int; ++ pMgr_EntryPnts->UCBMgr_isr = SccbMgr_isr; ++ pMgr_EntryPnts->UCBMgr_scsi_reset = SccbMgr_scsi_reset; ++ pMgr_EntryPnts->UCBMgr_timer_expired = SccbMgr_timer_expired; ++#ifndef NO_IOCTLS ++ pMgr_EntryPnts->UCBMgr_unload_card = SccbMgr_unload_card; ++ pMgr_EntryPnts->UCBMgr_save_foreign_state = ++ SccbMgr_save_foreign_state; ++ pMgr_EntryPnts->UCBMgr_restore_foreign_state = ++ SccbMgr_restore_foreign_state; ++ pMgr_EntryPnts->UCBMgr_restore_native_state = ++ SccbMgr_restore_native_state; ++#endif /*NO_IOCTLS*/ ++ ++ pMgrInfo->mi_SGListFormat=0x01; ++ pMgrInfo->mi_DataPtrFormat=0x01; ++ pMgrInfo->mi_MaxSGElements= (u16bits) 0xffffffff; ++ pMgrInfo->mi_MgrPrivateLen=sizeof(SCCB); ++ pMgrInfo->mi_PCIVendorID=BL_VENDOR_ID; ++ pMgrInfo->mi_PCIDeviceID=FP_DEVICE_ID; ++ pMgrInfo->mi_MgrAttributes= ATTR_IO_MAPPED + ++ ATTR_PHYSICAL_ADDRESS + ++ ATTR_VIRTUAL_ADDRESS + ++ ATTR_OVERLAPPED_IO_IOCTLS_OK; ++ pMgrInfo->mi_IoRangeLen = 256; ++ return(0); ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: probe_adapter ++ * ++ * Description: Setup and/or Search for cards and return info to caller. ++ * ++ *---------------------------------------------------------------------*/ ++STATIC s32bits probe_adapter(PADAPTER_INFO pAdapterInfo) ++{ ++ u16bits temp,temp2,temp3,temp4; ++ u08bits i,j,id; ++ ++#if defined(DOS) ++#else ++ static u08bits first_time = 1; ++#endif ++ BASE_PORT ioport; ++ PNVRamInfo pCurrNvRam; ++ ++ ioport = (BASE_PORT)pAdapterInfo->ai_baseaddr; ++ ++ ++ ++ if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0) ++ return(1); ++ ++ if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1)) ++ return(2); ++ ++ if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0)) ++ return(3); ++ ++ if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1)) ++ return(4); ++ ++ ++ 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(5); ++ } ++ ++ if (first_time) { ++ ++ SccbMgrTableInitAll(); ++ first_time = 0; ++ mbCards = 0; ++ } ++ ++ if(RdStack(ioport, 0) != 0x00) { ++ if(ChkIfChipInitialized(ioport) == FALSE) ++ { ++ pCurrNvRam = NULL; ++ WR_HARPOON(ioport+hp_semaphore, 0x00); ++ XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ ++ DiagEEPROM(ioport); ++ } ++ else ++ { ++ if(mbCards < MAX_MB_CARDS) { ++ pCurrNvRam = &nvRamInfo[mbCards]; ++ mbCards++; ++ pCurrNvRam->niBaseAddr = ioport; ++ RNVRamData(pCurrNvRam); ++ }else ++ return((int) FAILURE); ++ } ++ }else ++ pCurrNvRam = NULL; ++ ++#if defined (NO_BIOS_OPTION) ++ pCurrNvRam = NULL; ++ XbowInit(ioport, 0); /*Must Init the SCSI before attempting */ ++ DiagEEPROM(ioport); ++#endif /* No BIOS Option */ ++ ++ WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT); ++ WR_HARPOON(ioport+hp_sys_ctrl, 0x00); ++ ++ if(pCurrNvRam) ++ pAdapterInfo->ai_id = pCurrNvRam->niAdapId; ++ else ++ pAdapterInfo->ai_id = (u08bits)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) & ++ (u08bits)0x0FF); ++ ++ pAdapterInfo->ai_lun = 0x00; ++ pAdapterInfo->ai_fw_revision[0] = '3'; ++ pAdapterInfo->ai_fw_revision[1] = '1'; ++ pAdapterInfo->ai_fw_revision[2] = '1'; ++ pAdapterInfo->ai_fw_revision[3] = ' '; ++ pAdapterInfo->ai_NumChannels = 1; ++ ++ temp2 = 0x0000; ++ temp3 = 0x0000; ++ temp4 = 0x0000; ++ ++ for (id = 0; id < (16/2); id++) { ++ ++ if(pCurrNvRam){ ++ temp = (USHORT) pCurrNvRam->niSyncTbl[id]; ++ temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + ++ (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); ++ }else ++ temp = utilEERead(ioport, (u16bits)((SYNC_RATE_TBL/2)+id)); ++ ++ for (i = 0; i < 2; temp >>=8,i++) { ++ ++ if ((temp & 0x03) != AUTO_RATE_00) { ++ ++ temp2 >>= 0x01; ++ temp2 |= 0x8000; ++ } ++ ++ else { ++ temp2 >>= 0x01; ++ } ++ ++ if (temp & DISC_ENABLE_BIT) { ++ ++ temp3 >>= 0x01; ++ temp3 |= 0x8000; ++ } ++ ++ else { ++ temp3 >>= 0x01; ++ } ++ ++ if (temp & WIDE_NEGO_BIT) { ++ ++ temp4 >>= 0x01; ++ temp4 |= 0x8000; ++ } ++ ++ else { ++ temp4 >>= 0x01; ++ } ++ ++ } ++ } ++ ++ pAdapterInfo->ai_per_targ_init_sync = temp2; ++ pAdapterInfo->ai_per_targ_no_disc = temp3; ++ pAdapterInfo->ai_per_targ_wide_nego = temp4; ++ if(pCurrNvRam) ++ i = pCurrNvRam->niSysConf; ++ else ++ i = (u08bits)(utilEERead(ioport, (SYSTEM_CONFIG/2))); ++ ++ /* ++ ** interrupts always level-triggered for FlashPoint ++ */ ++ pAdapterInfo->ai_stateinfo |= LEVEL_TRIG; ++ ++ if (i & 0x01) ++ pAdapterInfo->ai_stateinfo |= SCSI_PARITY_ENA; ++ ++ if (i & 0x02) /* SCSI Bus reset in AutoSCSI Set ? */ ++ { ++ if(pCurrNvRam) ++ { ++ j = pCurrNvRam->niScamConf; ++ } ++ else ++ { ++ j = (u08bits) utilEERead(ioport, SCAM_CONFIG/2); ++ } ++ if(j & SCAM_ENABLED) ++ { ++ if(j & SCAM_LEVEL2) ++ { ++ pAdapterInfo->ai_stateinfo |= SCAM2_ENA; ++ } ++ else ++ { ++ pAdapterInfo->ai_stateinfo |= SCAM1_ENA; ++ } ++ } ++ } ++ j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L); ++ if (i & 0x04) { ++ j |= SCSI_TERM_ENA_L; ++ pAdapterInfo->ai_stateinfo |= LOW_BYTE_TERM_ENA; ++ } ++ 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; ++ pAdapterInfo->ai_stateinfo |= HIGH_BYTE_TERM_ENA; ++ } ++ WR_HARPOON(ioport+hp_ee_ctrl, j ); ++ ++ if(RD_HARPOON(ioport + hp_page_ctrl) & BIOS_SHADOW) ++ { ++ pAdapterInfo->ai_FlashRomSize = 64 * 1024; /* 64k ROM */ ++ } ++ else ++ { ++ pAdapterInfo->ai_FlashRomSize = 32 * 1024; /* 32k ROM */ ++ } ++ ++ pAdapterInfo->ai_stateinfo |= (FAST20_ENA | TAG_QUEUE_ENA); ++ if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD)) ++ { ++ pAdapterInfo->ai_attributes |= (WIDE_CAPABLE | FAST20_CAPABLE ++ | SCAM2_CAPABLE ++ | TAG_QUEUE_CAPABLE ++ | SUPRESS_UNDERRRUNS_CAPABLE ++ | SCSI_PARITY_CAPABLE); ++ pAdapterInfo->ai_MaxTarg = 16; ++ pAdapterInfo->ai_MaxLun = 32; ++ } ++ else ++ { ++ pAdapterInfo->ai_attributes |= (FAST20_CAPABLE | SCAM2_CAPABLE ++ | TAG_QUEUE_CAPABLE ++ | SUPRESS_UNDERRRUNS_CAPABLE ++ | SCSI_PARITY_CAPABLE); ++ pAdapterInfo->ai_MaxTarg = 8; ++ pAdapterInfo->ai_MaxLun = 8; ++ } ++ ++ pAdapterInfo->ai_product_family = HARPOON_FAMILY; ++ pAdapterInfo->ai_HBAbustype = BUSTYPE_PCI; ++ ++ for (i=0;i<CARD_MODEL_NAMELEN;i++) ++ { ++ pAdapterInfo->ai_card_model[i]=' '; /* initialize the ai_card_model */ ++ } ++ ++ if(pCurrNvRam){ ++ pAdapterInfo->ai_card_model[0] = '9'; ++ switch(pCurrNvRam->niModel & 0x0f){ ++ case MODEL_LT: ++ pAdapterInfo->ai_card_model[1] = '3'; ++ pAdapterInfo->ai_card_model[2] = '0'; ++ break; ++ case MODEL_LW: ++ pAdapterInfo->ai_card_model[1] = '5'; ++ pAdapterInfo->ai_card_model[2] = '0'; ++ break; ++ case MODEL_DL: ++ pAdapterInfo->ai_card_model[1] = '3'; ++ pAdapterInfo->ai_card_model[2] = '2'; ++ break; ++ case MODEL_DW: ++ pAdapterInfo->ai_card_model[1] = '5'; ++ pAdapterInfo->ai_card_model[2] = '2'; ++ break; ++ } ++ }else{ ++ temp = utilEERead(ioport, (MODEL_NUMB_0/2)); ++ pAdapterInfo->ai_card_model[0] = (u08bits)(temp >> 8); ++ temp = utilEERead(ioport, (MODEL_NUMB_2/2)); ++ ++ pAdapterInfo->ai_card_model[1] = (u08bits)(temp & 0x00FF); ++ pAdapterInfo->ai_card_model[2] = (u08bits)(temp >> 8); ++ } ++ ++ ++ ++ pAdapterInfo->ai_FiberProductType = 0; ++ ++ pAdapterInfo->ai_secondary_range = 0; ++ ++ for (i=0;i<WORLD_WIDE_NAMELEN;i++) ++ { ++ pAdapterInfo->ai_worldwidename[i]='\0'; ++ } ++ ++ for (i=0;i<VENDOR_NAMELEN;i++) ++ { ++ pAdapterInfo->ai_vendorstring[i]='\0'; ++ } ++ pAdapterInfo->ai_vendorstring[0]='B'; ++ pAdapterInfo->ai_vendorstring[1]='U'; ++ pAdapterInfo->ai_vendorstring[2]='S'; ++ pAdapterInfo->ai_vendorstring[3]='L'; ++ pAdapterInfo->ai_vendorstring[4]='O'; ++ pAdapterInfo->ai_vendorstring[5]='G'; ++ pAdapterInfo->ai_vendorstring[6]='I'; ++ pAdapterInfo->ai_vendorstring[7]='C'; ++ ++ for (i=0;i<FAMILY_NAMELEN;i++) ++ { ++ pAdapterInfo->ai_AdapterFamilyString[i]='\0'; ++ } ++ pAdapterInfo->ai_AdapterFamilyString[0]='F'; ++ pAdapterInfo->ai_AdapterFamilyString[1]='L'; ++ pAdapterInfo->ai_AdapterFamilyString[2]='A'; ++ pAdapterInfo->ai_AdapterFamilyString[3]='S'; ++ pAdapterInfo->ai_AdapterFamilyString[4]='H'; ++ pAdapterInfo->ai_AdapterFamilyString[5]='P'; ++ pAdapterInfo->ai_AdapterFamilyString[6]='O'; ++ pAdapterInfo->ai_AdapterFamilyString[7]='I'; ++ pAdapterInfo->ai_AdapterFamilyString[8]='N'; ++ pAdapterInfo->ai_AdapterFamilyString[9]='T'; ++ ++ ARAM_ACCESS(ioport); ++ ++ for ( i = 0; i < 4; i++ ) { ++ ++ pAdapterInfo->ai_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) */ ++ ++ ++ pAdapterInfo->ai_relative_cardnum = ++ (u08bits)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1); ++ ++ SGRAM_ACCESS(ioport); ++ ++ s_PhaseTbl[0] = phaseDataOut; ++ s_PhaseTbl[1] = phaseDataIn; ++ s_PhaseTbl[2] = phaseIllegal; ++ s_PhaseTbl[3] = phaseIllegal; ++ s_PhaseTbl[4] = phaseCommand; ++ s_PhaseTbl[5] = phaseStatus; ++ s_PhaseTbl[6] = phaseMsgOut; ++ s_PhaseTbl[7] = phaseMsgIn; ++ ++ pAdapterInfo->ai_present = 0x01; ++ ++#if defined(BUGBUG) ++ ++ ++ for (i = 0; i < MAX_CARDS; i++) { ++ ++ for (id=0; id<debug_size; id++) ++ debug_int[i][id] = (u08bits)0x00; ++ debug_index[i] = 0; ++ } ++ ++#endif ++ ++ return(0); ++} ++ ++ ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: init_adapter, exported to BUDI via UCBMgr_init_adapter entry ++ * ++ * ++ * Description: Setup adapter for normal operation (hard reset). ++ * ++ *---------------------------------------------------------------------*/ ++STATIC CARD_HANDLE init_adapter(PADAPTER_INFO pCardInfo) ++{ ++ PSCCBcard CurrCard; ++ PNVRamInfo pCurrNvRam; ++ u08bits i,j,thisCard, ScamFlg; ++ u16bits temp,sync_bit_map,id; ++ BASE_PORT ioport; ++ ++ ioport = (BASE_PORT)pCardInfo->ai_baseaddr; ++ ++ for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) { ++ ++ if (thisCard == MAX_CARDS) { ++ ++ return(FAILURE); ++ } ++ ++ if (BL_Card[thisCard].ioPort == ioport) { ++ ++ CurrCard = &BL_Card[thisCard]; ++ SccbMgrTableInitCard(CurrCard,thisCard); ++ break; ++ } ++ ++ else if (BL_Card[thisCard].ioPort == 0x00) { ++ ++ BL_Card[thisCard].ioPort = ioport; ++ CurrCard = &BL_Card[thisCard]; ++ ++ if(mbCards) ++ for(i = 0; i < mbCards; i++){ ++ if(CurrCard->ioPort == nvRamInfo[i].niBaseAddr) ++ CurrCard->pNvRamInfo = &nvRamInfo[i]; ++ } ++ SccbMgrTableInitCard(CurrCard,thisCard); ++ CurrCard->cardIndex = thisCard; ++ CurrCard->cardInfo = pCardInfo; ++ ++ break; ++ } ++ } ++ ++ pCurrNvRam = CurrCard->pNvRamInfo; ++ ++ ++ if(pCurrNvRam){ ++ ScamFlg = pCurrNvRam->niScamConf; ++ } ++ else{ ++ ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2); ++ } ++ ++ ++ BusMasterInit(ioport); ++ XbowInit(ioport, ScamFlg); ++ ++#if defined (NO_BIOS_OPTION) ++ ++ ++ if (DiagXbow(ioport)) return(FAILURE); ++ if (DiagBusMaster(ioport)) return(FAILURE); ++ ++#endif /* No BIOS Option */ ++ ++ autoLoadDefaultMap(ioport); ++ ++ ++ for (i = 0,id = 0x01; i != pCardInfo->ai_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->ai_id); ++ CurrCard->ourId = (unsigned char) pCardInfo->ai_id; ++ ++ i = (u08bits) pCardInfo->ai_stateinfo; ++ 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_ENA) ++ 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_ENA) ++ j |= SCSI_TERM_ENA_H; ++ WR_HARPOON(ioport+hp_ee_ctrl, j ); ++ ++ ++ if (!(pCardInfo->ai_stateinfo & NO_RESET_IN_INIT)) { ++ ++ sresb(ioport,thisCard); ++ ++ scini(thisCard, (u08bits) pCardInfo->ai_id, 0); ++ } ++ ++ ++ ++ if (pCardInfo->ai_stateinfo & SUPRESS_UNDERRRUNS_ENA) ++ CurrCard->globalFlags |= F_NO_FILTER; ++ ++ if(pCurrNvRam){ ++ if(pCurrNvRam->niSysConf & 0x10) ++ CurrCard->globalFlags |= F_GREEN_PC; ++ } ++ else{ ++ if (utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA) ++ CurrCard->globalFlags |= F_GREEN_PC; ++ } ++ ++ /* 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 (utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA) ++ CurrCard->globalFlags |= F_DO_RENEGO; ++ } ++ ++ if(pCurrNvRam){ ++ if(pCurrNvRam->niScsiConf & 0x08) ++ CurrCard->globalFlags |= F_CONLUN_IO; ++ } ++ else{ ++ if (utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA) ++ CurrCard->globalFlags |= F_CONLUN_IO; ++ } ++ ++ temp = pCardInfo->ai_per_targ_no_disc; ++ ++ for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) { ++ ++ if (temp & id) ++ sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC; ++ } ++ ++ sync_bit_map = 0x0001; ++ ++ for (id = 0; id < (MAX_SCSI_TAR/2); id++){ ++ ++ if(pCurrNvRam){ ++ temp = (USHORT) pCurrNvRam->niSyncTbl[id]; ++ temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) + ++ (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000)); ++ }else ++ temp = utilEERead(ioport, (u16bits)((SYNC_RATE_TBL/2)+id)); ++ ++ for (i = 0; i < 2; temp >>=8,i++){ ++ ++ if (pCardInfo->ai_per_targ_init_sync & sync_bit_map){ ++ ++ sccbMgrTbl[thisCard][id*2+i].TarEEValue = (u08bits)temp; ++ } ++ ++ else { ++ sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED; ++ sccbMgrTbl[thisCard][id*2+i].TarEEValue = ++ (u08bits)(temp & ~EE_SYNC_MASK); ++ } ++ ++#if defined(WIDE_SCSI) ++/* if ((pCardInfo->ai_per_targ_wide_nego & sync_bit_map) || ++ (id*2+i >= 8)){ ++*/ ++ if (pCardInfo->ai_per_targ_wide_nego & sync_bit_map){ ++ ++ sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI; ++ ++ } ++ ++ else { /* NARROW SCSI */ ++ sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED; ++ } ++ ++#else ++ sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED; ++#endif ++ ++ ++ sync_bit_map <<= 1; ++ } ++ } ++ ++ ++ pCardInfo->ai_SGListFormat=0x01; ++ pCardInfo->ai_DataPtrFormat=0x01; ++ pCardInfo->ai_AEN_mask &= SCSI_RESET_COMPLETE; ++ ++ WR_HARPOON((ioport+hp_semaphore), ++ (u08bits)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT)); ++ ++ return((u32bits)CurrCard); ++ ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: build_ucb, exported to BUDI via UCBMgr_build_ucb entry ++ * ++ * Description: prepare fw portion of ucb. do not start, resource not guaranteed ++ * so don't manipulate anything that's derived from states which ++ * may change ++ * ++ *---------------------------------------------------------------------*/ ++void build_UCB(CARD_HANDLE pCurrCard, PUCB p_ucb) ++{ ++ ++ u08bits thisCard; ++ u08bits i,j; ++ ++ PSCCB p_sccb; ++ ++ ++ thisCard = ((PSCCBcard) pCurrCard)->cardIndex; ++ ++ ++ p_sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr; ++ ++ ++ p_sccb->Sccb_ucb_ptr=p_ucb; ++ ++ switch (p_ucb->UCB_opcode & (OPC_DEVICE_RESET+OPC_XFER_SG+OPC_CHK_RESIDUAL)) ++ { ++ case OPC_DEVICE_RESET: ++ p_sccb->OperationCode=RESET_COMMAND; ++ break; ++ case OPC_XFER_SG: ++ p_sccb->OperationCode=SCATTER_GATHER_COMMAND; ++ break; ++ case OPC_XFER_SG+OPC_CHK_RESIDUAL: ++ p_sccb->OperationCode=RESIDUAL_SG_COMMAND; ++ break; ++ case OPC_CHK_RESIDUAL: ++ ++ p_sccb->OperationCode=RESIDUAL_COMMAND; ++ break; ++ default: ++ p_sccb->OperationCode=SCSI_INITIATOR_COMMAND; ++ break; ++ } ++ ++ if (p_ucb->UCB_opcode & OPC_TQ_ENABLE) ++ { ++ p_sccb->ControlByte = (u08bits)((p_ucb->UCB_opcode & OPC_TQ_MASK)>>2) | F_USE_CMD_Q; ++ } ++ else ++ { ++ p_sccb->ControlByte = 0; ++ } ++ ++ ++ p_sccb->CdbLength = (u08bits)p_ucb->UCB_cdblen; ++ ++ if (p_ucb->UCB_opcode & OPC_NO_AUTO_SENSE) ++ { ++ p_sccb->RequestSenseLength = 0; ++ } ++ else ++ { ++ p_sccb->RequestSenseLength = (unsigned char) p_ucb->UCB_senselen; ++ } ++ ++ ++ if (p_ucb->UCB_opcode & OPC_XFER_SG) ++ { ++ p_sccb->DataPointer=p_ucb->UCB_virt_dataptr; ++ p_sccb->DataLength = (((u32bits)p_ucb->UCB_NumSgElements)<<3); ++ } ++ else ++ { ++ p_sccb->DataPointer=p_ucb->UCB_phys_dataptr; ++ p_sccb->DataLength=p_ucb->UCB_datalen; ++ }; ++ ++ p_sccb->HostStatus=0; ++ p_sccb->TargetStatus=0; ++ p_sccb->TargID=(unsigned char)p_ucb->UCB_targid; ++ p_sccb->Lun=(unsigned char) p_ucb->UCB_lun; ++ p_sccb->SccbIOPort=((PSCCBcard)pCurrCard)->ioPort; ++ ++ j=p_ucb->UCB_cdblen; ++ for (i=0;i<j;i++) ++ { ++ p_sccb->Cdb[i] = p_ucb->UCB_cdb[i]; ++ } ++ ++ p_sccb->SensePointer=p_ucb->UCB_phys_senseptr; ++ ++ sinits(p_sccb,thisCard); ++ ++} ++#ifndef NO_IOCTLS ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: GetDevSyncRate ++ * ++ *---------------------------------------------------------------------*/ ++STATIC int GetDevSyncRate(PSCCBcard pCurrCard,PUCB p_ucb) ++{ ++ struct _SYNC_RATE_INFO * pSyncStr; ++ PSCCBMgr_tar_info currTar_Info; ++ BASE_PORT ioport; ++ u08bits scsiID, j; ++ ++#if (FW_TYPE != _SCCB_MGR_) ++ if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg ) ++ { ++ return(1); ++ } ++#endif ++ ++ ioport = pCurrCard->ioPort; ++ pSyncStr = (struct _SYNC_RATE_INFO *) p_ucb->UCB_virt_dataptr; ++ scsiID = (u08bits) p_ucb->UCB_targid; ++ currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID]; ++ j = currTar_Info->TarSyncCtrl; ++ ++ switch (currTar_Info->TarEEValue & EE_SYNC_MASK) ++ { ++ case EE_SYNC_ASYNC: ++ pSyncStr->RequestMegaXferRate = 0x00; ++ break; ++ case EE_SYNC_5MB: ++ pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 50 : 100; ++ break; ++ case EE_SYNC_10MB: ++ pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 100 : 200; ++ break; ++ case EE_SYNC_20MB: ++ pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 200 : 400; ++ break; ++ } ++ ++ switch ((j >> 5) & 0x07) ++ { ++ case 0x00: ++ if((j & 0x07) == 0x00) ++ { ++ pSyncStr->ActualMegaXferRate = 0x00; /* Async Mode */ ++ } ++ else ++ { ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 200 : 400; ++ } ++ break; ++ case 0x01: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 100 : 200; ++ break; ++ case 0x02: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 66 : 122; ++ break; ++ case 0x03: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 50 : 100; ++ break; ++ case 0x04: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 40 : 80; ++ break; ++ case 0x05: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 33 : 66; ++ break; ++ case 0x06: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 28 : 56; ++ break; ++ case 0x07: ++ pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 25 : 50; ++ break; ++ } ++ pSyncStr->NegotiatedOffset = j & 0x0f; ++ ++ return(0); ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SetDevSyncRate ++ * ++ *---------------------------------------------------------------------*/ ++STATIC int SetDevSyncRate(PSCCBcard pCurrCard, PUCB p_ucb) ++{ ++ struct _SYNC_RATE_INFO * pSyncStr; ++ PSCCBMgr_tar_info currTar_Info; ++ BASE_PORT ioPort; ++ u08bits scsiID, i, j, syncVal; ++ u16bits syncOffset, actualXferRate; ++ union { ++ u08bits tempb[2]; ++ u16bits tempw; ++ }temp2; ++ ++#if (FW_TYPE != _SCCB_MGR_) ++ if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg ) ++ { ++ return(1); ++ } ++#endif ++ ++ ioPort = pCurrCard->ioPort; ++ pSyncStr = (struct _SYNC_RATE_INFO *) p_ucb->UCB_virt_dataptr; ++ scsiID = (u08bits) p_ucb->UCB_targid; ++ currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID]; ++ i = RD_HARPOON(ioPort+hp_xfer_pad); /* Save current value */ ++ WR_HARPOON(ioPort+hp_xfer_pad, (i | ID_UNLOCK)); ++ WR_HARPOON(ioPort+hp_select_id, ((scsiID << 4) | scsiID)); ++ j = RD_HARPOON(ioPort+hp_synctarg_0); ++ WR_HARPOON(ioPort+hp_xfer_pad, i); /* restore value */ ++ ++ actualXferRate = pSyncStr->ActualMegaXferRate; ++ if(!(j & NARROW_SCSI)) ++ { ++ actualXferRate <<= 1; ++ } ++ if(actualXferRate == 0x00) ++ { ++ syncVal = EE_SYNC_ASYNC; /* Async Mode */ ++ } ++ if(actualXferRate == 0x0200) ++ { ++ syncVal = EE_SYNC_20MB; /* 20/40 MB Mode */ ++ } ++ if(actualXferRate > 0x0050 && actualXferRate < 0x0200 ) ++ { ++ syncVal = EE_SYNC_10MB; /* 10/20 MB Mode */ ++ } ++ else ++ { ++ syncVal = EE_SYNC_5MB; /* 5/10 MB Mode */ ++ } ++ if(currTar_Info->TarEEValue && EE_SYNC_MASK == syncVal) ++ return(0); ++ currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_SYNC_MASK) ++ | syncVal; ++ syncOffset = (SYNC_RATE_TBL + scsiID) / 2; ++ temp2.tempw = utilEERead(ioPort, syncOffset); ++ if(scsiID & 0x01) ++ { ++ temp2.tempb[0] = (temp2.tempb[0] & !EE_SYNC_MASK) | syncVal; ++ } ++ else ++ { ++ temp2.tempb[1] = (temp2.tempb[1] & !EE_SYNC_MASK) | syncVal; ++ } ++ utilEEWriteOnOff(ioPort, 1); ++ utilEEWrite(ioPort, temp2.tempw, syncOffset); ++ utilEEWriteOnOff(ioPort, 0); ++ UpdateCheckSum(ioPort); ++ ++ return(0); ++} ++/*--------------------------------------------------------------------- ++ * ++ * Function: GetDevWideMode ++ * ++ *---------------------------------------------------------------------*/ ++int GetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb) ++{ ++ u08bits *pData; ++ ++ pData = (u08bits *)p_ucb->UCB_virt_dataptr; ++ if(sccbMgrTbl[pCurrCard->cardIndex][p_ucb->UCB_targid].TarEEValue ++ & EE_WIDE_SCSI) ++ { ++ *pData = 1; ++ } ++ else ++ { ++ *pData = 0; ++ } ++ ++ return(0); ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SetDevWideMode ++ * ++ *---------------------------------------------------------------------*/ ++int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb) ++{ ++ u08bits *pData; ++ PSCCBMgr_tar_info currTar_Info; ++ BASE_PORT ioPort; ++ u08bits scsiID, scsiWideMode; ++ u16bits syncOffset; ++ union { ++ u08bits tempb[2]; ++ u16bits tempw; ++ }temp2; ++ ++#if (FW_TYPE != _SCCB_MGR_) ++ if( !(pCurrCard->cardInfo->ai_attributes & WIDE_CAPABLE) ) ++ { ++ return(1); ++ } ++ ++ if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg ) ++ { ++ return(1); ++ } ++#endif ++ ++ ioPort = pCurrCard->ioPort; ++ pData = (u08bits *)p_ucb->UCB_virt_dataptr; ++ scsiID = (u08bits) p_ucb->UCB_targid; ++ currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID]; ++ ++ if(*pData) ++ { ++ if(currTar_Info->TarEEValue & EE_WIDE_SCSI) ++ { ++ return(0); ++ } ++ else ++ { ++ scsiWideMode = EE_WIDE_SCSI; ++ } ++ } ++ else ++ { ++ if(!currTar_Info->TarEEValue & EE_WIDE_SCSI) ++ { ++ return(0); ++ } ++ else ++ { ++ scsiWideMode = 0; ++ } ++ } ++ currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_WIDE_SCSI) ++ | scsiWideMode; ++ ++ syncOffset = (SYNC_RATE_TBL + scsiID) / 2; ++ temp2.tempw = utilEERead(ioPort, syncOffset); ++ if(scsiID & 0x01) ++ { ++ temp2.tempb[0] = (temp2.tempb[0] & !EE_WIDE_SCSI) | scsiWideMode; ++ } ++ else ++ { ++ temp2.tempb[1] = (temp2.tempb[1] & !EE_WIDE_SCSI) | scsiWideMode; ++ } ++ utilEEWriteOnOff(ioPort, 1); ++ utilEEWrite(ioPort, temp2.tempw, syncOffset); ++ utilEEWriteOnOff(ioPort, 0); ++ UpdateCheckSum(ioPort); ++ ++ return(0); ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: ReadNVRam ++ * ++ *---------------------------------------------------------------------*/ ++void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb) ++{ ++ u08bits *pdata; ++ u16bits i,numwrds,numbytes,offset,temp; ++ u08bits OneMore = FALSE; ++#if defined(DOS) ++ u16bits ioport; ++#else ++ u32bits ioport; ++#endif ++ ++ numbytes = (u16bits) p_ucb->UCB_datalen; ++ ioport = pCurrCard->ioPort; ++ pdata = (u08bits *) p_ucb->UCB_virt_dataptr; ++ offset = (u16bits) (p_ucb->UCB_IOCTLParams[0]); ++ ++ ++ ++ if (offset & 0x1) ++ { ++ *((u16bits*) pdata) = utilEERead(ioport,(u16bits)((offset - 1) / 2)); /* 16 bit read */ ++ *pdata = *(pdata + 1); ++ ++offset; ++ ++pdata; ++ --numbytes; ++ } ++ ++ numwrds = numbytes / 2; ++ if (numbytes & 1) ++ OneMore = TRUE; ++ ++ for (i = 0; i < numwrds; i++) ++ { ++ *((u16bits*) pdata) = utilEERead(ioport,(u16bits)(offset / 2)); ++ pdata += 2; ++ offset += 2; ++ } ++ if (OneMore) ++ { ++ --pdata; ++ -- offset; ++ temp = utilEERead(ioport,(u16bits)(offset / 2)); ++ *pdata = (u08bits) (temp); ++ } ++ ++} /* end proc ReadNVRam */ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: WriteNVRam ++ * ++ *---------------------------------------------------------------------*/ ++void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb) ++{ ++ u08bits *pdata; ++ u16bits i,numwrds,numbytes,offset, eeprom_end; ++ u08bits OneMore = FALSE; ++ union { ++ u08bits tempb[2]; ++ u16bits tempw; ++ } temp2; ++ ++#if defined(DOS) ++ u16bits ioport; ++#else ++ u32bits ioport; ++#endif ++ ++ numbytes = (u16bits) p_ucb->UCB_datalen; ++ ioport = pCurrCard->ioPort; ++ pdata = (u08bits *) p_ucb->UCB_virt_dataptr; ++ offset = (u16bits) (p_ucb->UCB_IOCTLParams[0]); ++ ++ if (RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD) ++ eeprom_end = 512; ++ else ++ eeprom_end = 768; ++ ++ if(offset > eeprom_end) ++ return; ++ ++ if((offset + numbytes) > eeprom_end) ++ numbytes = eeprom_end - offset; ++ ++ utilEEWriteOnOff(ioport,1); /* Enable write access to the EEPROM */ ++ ++ ++ ++ if (offset & 0x1) ++ { ++ temp2.tempw = utilEERead(ioport,(u16bits)((offset - 1) / 2)); /* 16 bit read */ ++ temp2.tempb[1] = *pdata; ++ utilEEWrite(ioport, temp2.tempw, (u16bits)((offset -1) / 2)); ++ *pdata = *(pdata + 1); ++ ++offset; ++ ++pdata; ++ --numbytes; ++ } ++ ++ numwrds = numbytes / 2; ++ if (numbytes & 1) ++ OneMore = TRUE; ++ ++ for (i = 0; i < numwrds; i++) ++ { ++ utilEEWrite(ioport, *((pu16bits)pdata),(u16bits)(offset / 2)); ++ pdata += 2; ++ offset += 2; ++ } ++ if (OneMore) ++ { ++ ++ temp2.tempw = utilEERead(ioport,(u16bits)(offset / 2)); ++ temp2.tempb[0] = *pdata; ++ utilEEWrite(ioport, temp2.tempw, (u16bits)(offset / 2)); ++ } ++ utilEEWriteOnOff(ioport,0); /* Turn off write access */ ++ UpdateCheckSum((u32bits)ioport); ++ ++} /* end proc WriteNVRam */ ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: UpdateCheckSum ++ * ++ * Description: Update Check Sum in EEPROM ++ * ++ *---------------------------------------------------------------------*/ ++ ++ ++void UpdateCheckSum(u32bits baseport) ++{ ++ USHORT i,sum_data, eeprom_end; ++ ++ sum_data = 0x0000; ++ ++ ++ if (RD_HARPOON(baseport+hp_page_ctrl) & NARROW_SCSI_CARD) ++ eeprom_end = 512; ++ else ++ eeprom_end = 768; ++ ++ for (i = 1; i < eeprom_end/2; i++) ++ { ++ sum_data += utilEERead(baseport, i); ++ } ++ ++ utilEEWriteOnOff(baseport,1); /* Enable write access to the EEPROM */ ++ ++ utilEEWrite(baseport, sum_data, EEPROM_CHECK_SUM/2); ++ utilEEWriteOnOff(baseport,0); /* Turn off write access */ ++} ++ ++void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo) ++{ ++} ++ ++ ++void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard) ++{ ++} ++ ++void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard) ++{ ++} ++ ++#endif /* NO_IOCTLS */ ++ ++#endif /* (FW_TYPE==_UCB_MGR_) */ ++ ++#ifndef NO_IOCTLS ++#if (FW_TYPE==_UCB_MGR_) ++void SccbMgr_unload_card(CARD_HANDLE pCurrCard) ++#else ++#if defined(DOS) ++void SccbMgr_unload_card(USHORT pCurrCard) ++#else ++void SccbMgr_unload_card(ULONG pCurrCard) ++#endif ++#endif ++{ ++ UCHAR i; ++#if defined(DOS) ++ USHORT portBase; ++ USHORT regOffset; ++#else ++ ULONG portBase; ++ ULONG regOffset; ++#endif ++ ULONG scamData; ++#if defined(OS2) ++ ULONG far *pScamTbl; ++#else ++ ULONG *pScamTbl; ++#endif ++ PNVRamInfo pCurrNvRam; ++ ++ pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo; ++ ++ if(pCurrNvRam){ ++ WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel); ++ WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf); ++ WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf); ++ WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf); ++ WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId); ++ ++ for(i = 0; i < MAX_SCSI_TAR / 2; i++) ++ WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]); ++ ++ portBase = pCurrNvRam->niBaseAddr; ++ ++ for(i = 0; i < MAX_SCSI_TAR; i++){ ++ regOffset = hp_aramBase + 64 + i*4; ++#if defined(OS2) ++ pScamTbl = (ULONG far *) &pCurrNvRam->niScamTbl[i]; ++#else ++ pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i]; ++#endif ++ scamData = *pScamTbl; ++ WR_HARP32(portBase, regOffset, scamData); ++ } ++ ++ }else{ ++ WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0); ++ } ++} ++#endif /* NO_IOCTLS */ ++ ++ ++void RNVRamData(PNVRamInfo pNvRamInfo) ++{ ++ UCHAR i; ++#if defined(DOS) ++ USHORT portBase; ++ USHORT regOffset; ++#else ++ ULONG portBase; ++ ULONG regOffset; ++#endif ++ ULONG scamData; ++#if defined (OS2) ++ ULONG far *pScamTbl; ++#else ++ ULONG *pScamTbl; ++#endif ++ ++ pNvRamInfo->niModel = RdStack(pNvRamInfo->niBaseAddr, 0); ++ pNvRamInfo->niSysConf = RdStack(pNvRamInfo->niBaseAddr, 1); ++ pNvRamInfo->niScsiConf = RdStack(pNvRamInfo->niBaseAddr, 2); ++ pNvRamInfo->niScamConf = RdStack(pNvRamInfo->niBaseAddr, 3); ++ pNvRamInfo->niAdapId = RdStack(pNvRamInfo->niBaseAddr, 4); ++ ++ for(i = 0; i < MAX_SCSI_TAR / 2; i++) ++ pNvRamInfo->niSyncTbl[i] = RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5)); ++ ++ portBase = pNvRamInfo->niBaseAddr; ++ ++ for(i = 0; i < MAX_SCSI_TAR; i++){ ++ regOffset = hp_aramBase + 64 + i*4; ++ RD_HARP32(portBase, regOffset, scamData); ++#if defined(OS2) ++ pScamTbl = (ULONG far *) &pNvRamInfo->niScamTbl[i]; ++#else ++ pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i]; ++#endif ++ *pScamTbl = scamData; ++ } ++ ++} ++ ++#if defined(DOS) ++UCHAR RdStack(USHORT portBase, UCHAR index) ++#else ++UCHAR RdStack(ULONG portBase, UCHAR index) ++#endif ++{ ++ WR_HARPOON(portBase + hp_stack_addr, index); ++ return(RD_HARPOON(portBase + hp_stack_data)); ++} ++ ++#if defined(DOS) ++void WrStack(USHORT portBase, UCHAR index, UCHAR data) ++#else ++void WrStack(ULONG portBase, UCHAR index, UCHAR data) ++#endif ++{ ++ WR_HARPOON(portBase + hp_stack_addr, index); ++ WR_HARPOON(portBase + hp_stack_data, data); ++} ++ ++ ++#if (FW_TYPE==_UCB_MGR_) ++u08bits ChkIfChipInitialized(BASE_PORT ioPort) ++#else ++#if defined(DOS) ++UCHAR ChkIfChipInitialized(USHORT ioPort) ++#else ++UCHAR ChkIfChipInitialized(ULONG ioPort) ++#endif ++#endif ++{ ++ if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != RdStack(ioPort, 4)) ++ return(FALSE); ++ if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT) ++ != CLKCTRL_DEFAULT) ++ return(FALSE); ++ if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) || ++ (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms)) ++ return(TRUE); ++ return(FALSE); ++ ++} ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_start_sccb ++ * ++ * Description: Start a command pointed to by p_Sccb. When the ++ * command is completed it will be returned via the ++ * callback function. ++ * ++ *---------------------------------------------------------------------*/ ++#if (FW_TYPE==_UCB_MGR_) ++void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb) ++#else ++#if defined(DOS) ++void SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_Sccb) ++#else ++void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb) ++#endif ++#endif ++{ ++#if defined(DOS) ++ USHORT ioport; ++#else ++ ULONG ioport; ++#endif ++ UCHAR thisCard, lun; ++ PSCCB pSaveSccb; ++ CALL_BK_FN callback; ++ ++#if (FW_TYPE==_UCB_MGR_) ++ PSCCB p_Sccb; ++#endif ++ ++ mOS_Lock((PSCCBcard)pCurrCard); ++ thisCard = ((PSCCBcard) pCurrCard)->cardIndex; ++ ioport = ((PSCCBcard) pCurrCard)->ioPort; ++ ++#if (FW_TYPE==_UCB_MGR_) ++ p_Sccb = (PSCCB)p_ucb->UCB_MgrPrivatePtr; ++#endif ++ ++ if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN)) ++ { ++ ++#if (FW_TYPE==_UCB_MGR_) ++ p_ucb->UCB_hbastat = SCCB_COMPLETE; ++ p_ucb->UCB_status=SCCB_ERROR; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++#endif ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ p_Sccb->HostStatus = SCCB_COMPLETE; ++ p_Sccb->SccbStatus = SCCB_ERROR; ++ callback = (CALL_BK_FN)p_Sccb->SccbCallback; ++ if (callback) ++ callback(p_Sccb); ++#endif ++ ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ } ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ sinits(p_Sccb,thisCard); ++#endif ++ ++ ++#if (FW_TYPE==_UCB_MGR_) ++#ifndef NO_IOCTLS ++ ++ if (p_ucb->UCB_opcode & OPC_IOCTL) ++ { ++ ++ switch (p_ucb->UCB_IOCTLCommand) ++ { ++ case READ_NVRAM: ++ ReadNVRam((PSCCBcard)pCurrCard,p_ucb); ++ p_ucb->UCB_status=UCB_SUCCESS; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ ++ case WRITE_NVRAM: ++ WriteNVRam((PSCCBcard)pCurrCard,p_ucb); ++ p_ucb->UCB_status=UCB_SUCCESS; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ ++ case SEND_SCSI_PASSTHRU: ++#if (FW_TYPE != _SCCB_MGR_) ++ if( p_ucb->UCB_targid >= ++ ((PSCCBcard)pCurrCard)->cardInfo->ai_MaxTarg ) ++ { ++ p_ucb->UCB_status = UCB_ERROR; ++ p_ucb->UCB_hbastat = HASTAT_HW_ERROR; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ } ++#endif ++ break; ++ ++ case HARD_RESET: ++ p_ucb->UCB_status = UCB_INVALID; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ case GET_DEVICE_SYNCRATE: ++ if( !GetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) ) ++ { ++ p_ucb->UCB_status = UCB_SUCCESS; ++ } ++ else ++ { ++ p_ucb->UCB_status = UCB_ERROR; ++ p_ucb->UCB_hbastat = HASTAT_HW_ERROR; ++ } ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ case SET_DEVICE_SYNCRATE: ++ if( !SetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) ) ++ { ++ p_ucb->UCB_status = UCB_SUCCESS; ++ } ++ else ++ { ++ p_ucb->UCB_status = UCB_ERROR; ++ p_ucb->UCB_hbastat = HASTAT_HW_ERROR; ++ } ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ case GET_WIDE_MODE: ++ if( !GetDevWideMode((PSCCBcard)pCurrCard,p_ucb) ) ++ { ++ p_ucb->UCB_status = UCB_SUCCESS; ++ } ++ else ++ { ++ p_ucb->UCB_status = UCB_ERROR; ++ p_ucb->UCB_hbastat = HASTAT_HW_ERROR; ++ } ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ case SET_WIDE_MODE: ++ if( !SetDevWideMode((PSCCBcard)pCurrCard,p_ucb) ) ++ { ++ p_ucb->UCB_status = UCB_SUCCESS; ++ } ++ else ++ { ++ p_ucb->UCB_status = UCB_ERROR; ++ p_ucb->UCB_hbastat = HASTAT_HW_ERROR; ++ } ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ default: ++ p_ucb->UCB_status=UCB_INVALID; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ if (callback) ++ callback(p_ucb); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ return; ++ } ++ } ++#endif /* NO_IOCTLS */ ++#endif /* (FW_TYPE==_UCB_MGR_) */ ++ ++ ++ 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; ++ queueSelectFail(&BL_Card[thisCard], thisCard); ++ ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb; ++ } ++ else ++ { ++ queueAddSccb(p_Sccb,thisCard); ++ } ++ } ++ ++ 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; ++ queueSelectFail(&BL_Card[thisCard], thisCard); ++ ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb; ++ } ++ else ++ { ++ queueAddSccb(p_Sccb,thisCard); ++ } ++ } ++ ++ else { ++ ++ MDISABLE_INT(ioport); ++ ++ if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) ++ lun = p_Sccb->Lun; ++ else ++ lun = 0; ++ if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) && ++ (sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) && ++ (sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun] ++ == FALSE)) { ++ ++ ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; ++ mOS_UnLock((PSCCBcard)pCurrCard); ++#if defined(DOS) ++ ssel((USHORT)p_Sccb->SccbIOPort,thisCard); ++#else ++ ssel(p_Sccb->SccbIOPort,thisCard); ++#endif ++ mOS_Lock((PSCCBcard)pCurrCard); ++ } ++ ++ else { ++ ++ if(p_Sccb->OperationCode == RESET_COMMAND) ++ { ++ pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB; ++ ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; ++ queueSelectFail(&BL_Card[thisCard], thisCard); ++ ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb; ++ } ++ else ++ { ++ queueAddSccb(p_Sccb,thisCard); ++ } ++ } ++ ++ ++ MENABLE_INT(ioport); ++ } ++ ++ mOS_UnLock((PSCCBcard)pCurrCard); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_abort_sccb ++ * ++ * Description: Abort the command pointed to by p_Sccb. When the ++ * command is completed it will be returned via the ++ * callback function. ++ * ++ *---------------------------------------------------------------------*/ ++#if (FW_TYPE==_UCB_MGR_) ++s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb) ++#else ++#if defined(DOS) ++int SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_Sccb) ++#else ++int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb) ++#endif ++#endif ++ ++{ ++#if defined(DOS) ++ USHORT ioport; ++#else ++ ULONG ioport; ++#endif ++ ++ UCHAR thisCard; ++ CALL_BK_FN callback; ++ UCHAR TID; ++ PSCCB pSaveSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ PSCCB p_Sccb; ++ p_Sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr; ++#endif ++ ++ ioport = ((PSCCBcard) pCurrCard)->ioPort; ++ ++ thisCard = ((PSCCBcard)pCurrCard)->cardIndex; ++ ++ mOS_Lock((PSCCBcard)pCurrCard); ++ ++ if (RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE) ++ { ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ } ++ ++ else ++ { ++ ++ if (queueFindSccb(p_Sccb,thisCard)) ++ { ++ ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ ++ ((PSCCBcard)pCurrCard)->cmdCounter--; ++ ++ if (!((PSCCBcard)pCurrCard)->cmdCounter) ++ WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore) ++ & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) )); ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ p_Sccb->SccbStatus = SCCB_ABORT; ++ callback = p_Sccb->SccbCallback; ++ callback(p_Sccb); ++#else ++ p_ucb->UCB_status=SCCB_ABORT; ++ callback = (CALL_BK_FN)p_ucb->UCB_callback; ++ callback(p_ucb); ++#endif ++ ++ return(0); ++ } ++ ++ else ++ { ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ ++ 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; ++#if (FW_TYPE==_UCB_MGR_) ++ p_ucb->UCB_status=SCCB_ABORT; ++#endif ++ p_Sccb->Sccb_scsimsg = SMABORT_TAG; ++ ++ if(((PSCCBcard) pCurrCard)->currentSCCB == NULL) ++ { ++ ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; ++ ssel(ioport, thisCard); ++ } ++ else ++ { ++ pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB; ++ ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb; ++ queueSelectFail((PSCCBcard) pCurrCard, thisCard); ++ ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB; ++ } ++ } ++ MENABLE_INT(ioport); ++ return(0); ++ } ++ else ++ { ++ currTar_Info = &sccbMgrTbl[thisCard][p_Sccb->TargID]; ++ ++ if(BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]] ++ == p_Sccb) ++ { ++ p_Sccb->SccbStatus = SCCB_ABORT; ++ return(0); ++ } ++ } ++ } ++ } ++ } ++ return(-1); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_my_int ++ * ++ * Description: Do a quick check to determine if there is a pending ++ * interrupt for this card and disable the IRQ Pin if so. ++ * ++ *---------------------------------------------------------------------*/ ++#if (FW_TYPE==_UCB_MGR_) ++u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard) ++#else ++#if defined(DOS) ++UCHAR SccbMgr_my_int(USHORT pCurrCard) ++#else ++UCHAR SccbMgr_my_int(ULONG pCurrCard) ++#endif ++#endif ++{ ++#if defined(DOS) ++ USHORT ioport; ++#else ++ ULONG ioport; ++#endif ++ ++ ioport = ((PSCCBcard)pCurrCard)->ioPort; ++ ++ if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED) ++ { ++ ++#if defined(DOS) ++ MDISABLE_INT(ioport); ++#endif ++ ++ return(TRUE); ++ } ++ ++ else ++ ++ return(FALSE); ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_isr ++ * ++ * Description: This is our entry point when an interrupt is generated ++ * by the card and the upper level driver passes it on to ++ * us. ++ * ++ *---------------------------------------------------------------------*/ ++#if (FW_TYPE==_UCB_MGR_) ++s32bits SccbMgr_isr(CARD_HANDLE pCurrCard) ++#else ++#if defined(DOS) ++int SccbMgr_isr(USHORT pCurrCard) ++#else ++int SccbMgr_isr(ULONG pCurrCard) ++#endif ++#endif ++{ ++ PSCCB currSCCB; ++ UCHAR thisCard,result,bm_status, bm_int_st; ++ USHORT hp_int; ++ UCHAR i, target; ++#if defined(DOS) ++ USHORT ioport; ++#else ++ ULONG ioport; ++#endif ++ ++ mOS_Lock((PSCCBcard)pCurrCard); ++ ++ thisCard = ((PSCCBcard)pCurrCard)->cardIndex; ++ ioport = ((PSCCBcard)pCurrCard)->ioPort; ++ ++ MDISABLE_INT(ioport); ++ ++#if defined(BUGBUG) ++ WR_HARPOON(ioport+hp_user_defined_D, RD_HARPOON(ioport+hp_int_status)); ++#endif ++ ++ if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON) ++ bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS; ++ else ++ bm_status = 0; ++ ++ WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT)); ++ ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ ++ while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & default_intena) | ++ bm_status) ++ { ++ ++ currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB; ++ ++#if defined(BUGBUG) ++ Debug_Load(thisCard,(UCHAR) 0XFF); ++ Debug_Load(thisCard,bm_int_st); ++ ++ Debug_Load(thisCard,hp_int_0); ++ Debug_Load(thisCard,hp_int_1); ++#endif ++ ++ ++ if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) { ++ result = SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int); ++ WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL)); ++ bm_status = 0; ++ ++ if (result) { ++ ++ mOS_Lock((PSCCBcard)pCurrCard); ++ MENABLE_INT(ioport); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ 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.5us or ++ less. SRR Wednesday, 3/8/1995. ++ */ ++ while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ; ++ } ++ ++ if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) ++ ++ phaseChkFifo(ioport, thisCard); ++ ++/* WRW_HARPOON((ioport+hp_intstat), ++ (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0)); ++ */ ++ ++ WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1); ++ ++ autoCmdCmplt(ioport,thisCard); ++ ++ } ++ ++ ++ else if (hp_int & ITAR_DISC) ++ { ++ ++ if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) { ++ ++ phaseChkFifo(ioport, thisCard); ++ ++ } ++ ++ 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; ++ queueDisconnect(currSCCB,thisCard); ++ ++ /* Wait for the BusFree before starting a new command. We ++ must also check for being reselected since the BusFree ++ may not show up if another device reselects us in 1.5us 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))) ++ { ++ mOS_Lock((PSCCBcard)pCurrCard); ++ MENABLE_INT(ioport); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ 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) ++ { ++ phaseChkFifo(ioport, thisCard); ++ } ++ ++ 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; ++ queueDisconnect(currSCCB,thisCard); ++ } ++ ++ sres(ioport,thisCard,((PSCCBcard)pCurrCard)); ++ phaseDecode(ioport,thisCard); ++ ++ } ++ ++ ++ else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) ++ { ++ ++ WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0)); ++ phaseDecode(ioport,thisCard); ++ ++ } ++ ++ ++ else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) ) ++ { ++ WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT)); ++ if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK) ++ { ++ phaseDecode(ioport,thisCard); ++ } ++ else ++ { ++ /* Harpoon problem some SCSI target device respond to selection ++ with short BUSY pulse (<400ns) this will make the Harpoon is not able ++ to latch the correct Target ID into reg. x53. ++ The work around require to correct this reg. But when write to this ++ reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we ++ need to read this reg first then restore it later. After update to 0x53 */ ++ ++ i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite)); ++ target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3)); ++ WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK); ++ WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4)); ++ WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00); ++ 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); ++ ++ schkdd(ioport,thisCard); ++ ++ } ++ ++ ++ else if (hp_int & BUS_FREE) { ++ ++ WRW_HARPOON((ioport+hp_intstat), BUS_FREE); ++ ++ if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) { ++ ++ hostDataXferAbort(ioport,thisCard,currSCCB); ++ } ++ ++ phaseBusFree(ioport,thisCard); ++ } ++ ++ ++ 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) { ++ ++ queueSearchSelect(((PSCCBcard)pCurrCard),thisCard); ++ } ++ ++ if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) { ++ ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD; ++ ssel(ioport,thisCard); ++ } ++ ++ break; ++ ++ } ++ ++ } /*end while */ ++ ++ mOS_Lock((PSCCBcard)pCurrCard); ++ MENABLE_INT(ioport); ++ mOS_UnLock((PSCCBcard)pCurrCard); ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int) ++#else ++UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int) ++#endif ++{ ++#if defined(HARP_REVX) ++ ULONG timer; ++#endif ++UCHAR temp, ScamFlg; ++PSCCBMgr_tar_info currTar_Info; ++PNVRamInfo pCurrNvRam; ++ ++ ++ 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) ++ { ++ ++ hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB); ++ } ++ ++ 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; ++ ++ sxfrp(p_port,p_card); ++ ++ temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & ++ (EXT_ARB_ACK | SCSI_TERM_ENA_H)); ++ WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS)); ++ WR_HARPOON(p_port+hp_ee_ctrl, temp); ++ ++ if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET))) ++ { ++ phaseDecode(p_port,p_card); ++ } ++ } ++ } ++ ++ ++ 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) ++ ++ hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB); ++ } ++ ++ ++ DISABLE_AUTO(p_port); ++ ++ sresb(p_port,p_card); ++ ++ while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {} ++ ++ pCurrNvRam = pCurrCard->pNvRamInfo; ++ if(pCurrNvRam){ ++ ScamFlg = pCurrNvRam->niScamConf; ++ } ++ else{ ++ ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2); ++ } ++ ++ XbowInit(p_port, ScamFlg); ++ ++ scini(p_card, pCurrCard->ourId, 0); ++ ++ return(0xFF); ++ } ++ ++ ++ else if (p_int & FIFO) { ++ ++ WRW_HARPOON((p_port+hp_intstat), FIFO); ++ ++#if defined(HARP_REVX) ++ ++ for (timer=0x00FFFFFFL; timer != 0x00000000L; timer--) { ++ ++ if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY) ++ break; ++ ++ if (RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE) ++ break; ++ } ++ ++ ++ if ( (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY) && ++ (RD_HARPOON(p_port+hp_fiforead) != ++ RD_HARPOON(p_port+hp_fifowrite)) && ++ (RD_HARPOON(p_port+hp_xfercnt_0)) ++ ) ++ ++ WR_HARPOON((p_port+hp_xferstat), 0x01); ++ ++/* else ++ */ ++/* sxfrp(p_port,p_card); ++ */ ++#else ++ if (pCurrCard->currentSCCB != NULL) ++ sxfrp(p_port,p_card); ++#endif ++ } ++ ++ 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; ++ ++ ++ currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; ++ if((pCurrCard->globalFlags & F_CONLUN_IO) && ++ ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) ++ currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = FALSE; ++ else ++ currTar_Info->TarLUNBusy[0] = FALSE; ++ ++ ++ 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; ++ } ++ ++ sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info); ++ ++ queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card); ++ ++ } ++ ++#if defined(SCAM_LEV_2) ++ ++ else if (p_int & SCAM_SEL) ++ { ++ ++ scarb(p_port,LEVEL2_TAR); ++ scsel(p_port); ++ scasid(p_card, p_port); ++ ++ scbusf(p_port); ++ ++ WRW_HARPOON((p_port+hp_intstat), SCAM_SEL); ++ } ++#endif ++ ++ return(0x00); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_scsi_reset ++ * ++ * Description: A SCSI bus reset will be generated and all outstanding ++ * Sccbs will be returned via the callback. ++ * ++ *---------------------------------------------------------------------*/ ++#if (FW_TYPE==_UCB_MGR_) ++void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard) ++#else ++#if defined(DOS) ++void SccbMgr_scsi_reset(USHORT pCurrCard) ++#else ++void SccbMgr_scsi_reset(ULONG pCurrCard) ++#endif ++#endif ++{ ++ UCHAR thisCard; ++ ++ thisCard = ((PSCCBcard)pCurrCard)->cardIndex; ++ ++ mOS_Lock((PSCCBcard)pCurrCard); ++ ++ if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC) ++ { ++ WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_clkctrl_0, CLKCTRL_DEFAULT); ++ WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sys_ctrl, 0x00); ++ } ++ ++ sresb(((PSCCBcard)pCurrCard)->ioPort,thisCard); ++ ++ if (RD_HARPOON(((PSCCBcard)pCurrCard)->ioPort+hp_ext_status) & BM_CMD_BUSY) ++ { ++ WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl, ++ (RD_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl) ++ & ~SCATTER_EN)); ++ ++ WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sg_addr,0x00); ++ ++ ((PSCCBcard) pCurrCard)->globalFlags &= ~F_HOST_XFER_ACT; ++ busMstrTimeOut(((PSCCBcard) pCurrCard)->ioPort); ++ ++ WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_int_mask, ++ (INT_CMD_COMPL | SCSI_INTERRUPT)); ++ } ++ ++/* ++ if (utilEERead(((PSCCBcard)pCurrCard)->ioPort, (SCAM_CONFIG/2)) ++ & SCAM_ENABLED) ++*/ ++ scini(thisCard, ((PSCCBcard)pCurrCard)->ourId, 0); ++ ++#if (FW_TYPE==_UCB_MGR_) ++ ((PSCCBcard)pCurrCard)->cardInfo->ai_AEN_routine(0x01,pCurrCard,0,0,0,0); ++#endif ++ ++ mOS_UnLock((PSCCBcard)pCurrCard); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_timer_expired ++ * ++ * Description: This function allow me to kill my own job that has not ++ * yet completed, and has cause a timeout to occur. This ++ * timeout has caused the upper level driver to call this ++ * function. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++void SccbMgr_timer_expired(CARD_HANDLE pCurrCard) ++#else ++#if defined(DOS) ++void SccbMgr_timer_expired(USHORT pCurrCard) ++#else ++void SccbMgr_timer_expired(ULONG pCurrCard) ++#endif ++#endif ++{ ++} ++ ++#if defined(DOS) ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgr_status ++ * ++ * Description: This function returns the number of outstanding SCCB's. ++ * This is specific to the DOS enviroment, which needs this ++ * to help them keep protected and real mode commands staight. ++ * ++ *---------------------------------------------------------------------*/ ++ ++USHORT SccbMgr_status(USHORT pCurrCard) ++{ ++ return(BL_Card[pCurrCard].cmdCounter); ++} ++#endif ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgrTableInit ++ * ++ * Description: Initialize all Sccb manager data structures. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void SccbMgrTableInitAll() ++{ ++ UCHAR thisCard; ++ ++ for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) ++ { ++ SccbMgrTableInitCard(&BL_Card[thisCard],thisCard); ++ ++ BL_Card[thisCard].ioPort = 0x00; ++ BL_Card[thisCard].cardInfo = NULL; ++ BL_Card[thisCard].cardIndex = 0xFF; ++ BL_Card[thisCard].ourId = 0x00; ++ BL_Card[thisCard].pNvRamInfo = NULL; ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: SccbMgrTableInit ++ * ++ * Description: Initialize all Sccb manager data structures. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card) ++{ ++ UCHAR scsiID, qtag; ++ ++ for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) ++ { ++ BL_Card[p_card].discQ_Tbl[qtag] = NULL; ++ } ++ ++ for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) ++ { ++ sccbMgrTbl[p_card][scsiID].TarStatus = 0; ++ sccbMgrTbl[p_card][scsiID].TarEEValue = 0; ++ SccbMgrTableInitTarget(p_card, scsiID); ++ } ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void SccbMgrTableInitTarget(UCHAR p_card, UCHAR target) ++{ ++ ++ UCHAR lun, qtag; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currTar_Info = &sccbMgrTbl[p_card][target]; ++ ++ currTar_Info->TarSelQ_Cnt = 0; ++ currTar_Info->TarSyncCtrl = 0; ++ ++ currTar_Info->TarSelQ_Head = NULL; ++ currTar_Info->TarSelQ_Tail = NULL; ++ currTar_Info->TarTagQ_Cnt = 0; ++ currTar_Info->TarLUN_CA = FALSE; ++ ++ ++ for (lun = 0; lun < MAX_LUN; lun++) ++ { ++ currTar_Info->TarLUNBusy[lun] = FALSE; ++ currTar_Info->LunDiscQ_Idx[lun] = 0; ++ } ++ ++ for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) ++ { ++ if(BL_Card[p_card].discQ_Tbl[qtag] != NULL) ++ { ++ if(BL_Card[p_card].discQ_Tbl[qtag]->TargID == target) ++ { ++ BL_Card[p_card].discQ_Tbl[qtag] = NULL; ++ BL_Card[p_card].discQCount--; ++ } ++ } ++ } ++} ++ ++#if defined(BUGBUG) ++ ++/***************************************************************** ++ * Save the current byte in the debug array ++ *****************************************************************/ ++ ++ ++void Debug_Load(UCHAR p_card, UCHAR p_bug_data) ++{ ++ debug_int[p_card][debug_index[p_card]] = p_bug_data; ++ debug_index[p_card]++; ++ ++ if (debug_index[p_card] == debug_size) ++ ++ debug_index[p_card] = 0; ++} ++ ++#endif ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: sccb_dat.c $ ++ * ++ * Description: Functions relating to handling of the SCCB interface ++ * between the device driver and the HARPOON. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <harpoon.h>*/ ++ ++/* ++** IMPORTANT NOTE!!! ++** ++** You MUST preassign all data to a valid value or zero. This is ++** required due to the MS compiler bug under OS/2 and Solaris Real-Mode ++** driver environment. ++*/ ++ ++ ++SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } }; ++SCCBCARD BL_Card[MAX_CARDS] = { { 0 } }; ++SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR] = { { { 0 } } }; ++NVRAMINFO nvRamInfo[MAX_MB_CARDS] = { { 0 } }; ++ ++ ++#if defined(OS2) ++void (far *s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 }; ++UCHAR temp_id_string[ID_STRING_LENGTH] = { 0 }; ++#elif defined(SOLARIS_REAL_MODE) || defined(__STDC__) ++void (*s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 }; ++#else ++void (*s_PhaseTbl[8]) (); ++#endif ++ ++#if defined(DOS) ++UCHAR first_time = 0; ++#endif ++ ++UCHAR mbCards = 0; ++UCHAR scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \ ++ ' ', 'B', 'T', '-', '9', '3', '0', \ ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \ ++ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; ++ ++USHORT default_intena = 0; ++ ++#if defined(BUGBUG) ++UCHAR debug_int[MAX_CARDS][debug_size] = { 0 }; ++UCHAR debug_index[MAX_CARDS] = { 0 }; ++UCHAR reserved_1[3] = { 0 }; ++#endif ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: scsi.c $ ++ * ++ * Description: Functions for handling SCSI bus functions such as ++ * selection/reselection, sync negotiation, message-in ++ * decoding. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <eeprom.h>*/ ++/*#include <harpoon.h>*/ ++ ++ ++/* ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++#if defined(BUGBUG) ++void Debug_Load(UCHAR p_card, UCHAR p_bug_data); ++#endif ++*/ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sfetm ++ * ++ * Description: Read in a message byte from the SCSI bus, and check ++ * for a parity error. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR sfm(USHORT port, PSCCB pCurrSCCB) ++#else ++UCHAR sfm(ULONG port, PSCCB pCurrSCCB) ++#endif ++{ ++ UCHAR message; ++ USHORT TimeOutLoop; ++ ++ 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); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: ssel ++ * ++ * Description: Load up automation and select target device. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void ssel(USHORT port, UCHAR p_card) ++#else ++void ssel(ULONG port, UCHAR p_card) ++#endif ++{ ++ ++#if defined(DOS) ++ UCHAR auto_loaded, i, target, *theCCB; ++#elif defined(OS2) ++ UCHAR auto_loaded, i, target; ++ UCHAR far *theCCB; ++#else ++ UCHAR auto_loaded, i, target, *theCCB; ++#endif ++ ++#if defined(DOS) ++ USHORT cdb_reg; ++#else ++ ULONG cdb_reg; ++#endif ++ PSCCBcard CurrCard; ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ UCHAR lastTag, lun; ++ ++ CurrCard = &BL_Card[p_card]; ++ currSCCB = CurrCard->currentSCCB; ++ target = currSCCB->TargID; ++ currTar_Info = &sccbMgrTbl[p_card][target]; ++ 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 defined(DOS) ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ ++#else ++ ++ if (CurrCard->globalFlags & F_TAG_STARTED) ++ { ++ if (!(currSCCB->ControlByte & F_USE_CMD_Q)) ++ { ++ if ((currTar_Info->TarLUN_CA == FALSE) ++ && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ++ == TAG_Q_TRYING)) ++ { ++ ++ if (currTar_Info->TarTagQ_Cnt !=0) ++ { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ queueSelectFail(CurrCard,p_card); ++ SGRAM_ACCESS(port); ++ return; ++ } ++ ++ else { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ } ++ ++ } /*End non-tagged */ ++ ++ else { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ } ++ ++ } /*!Use cmd Q Tagged */ ++ ++ else { ++ if (currTar_Info->TarLUN_CA == TRUE) ++ { ++ queueSelectFail(CurrCard,p_card); ++ SGRAM_ACCESS(port); ++ return; ++ } ++ ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ ++ } /*else use cmd Q tagged */ ++ ++ } /*if glob tagged started */ ++ ++ else { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ } ++ ++#endif /* DOS */ ++ ++ ++ ++ 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) ++ { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ queueSelectFail(CurrCard,p_card); ++ 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) ++ { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ queueSelectFail(CurrCard,p_card); ++ SGRAM_ACCESS(port); ++ return; ++ } ++ } ++ ++ ++ ++ auto_loaded = FALSE; ++ ++ 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)); ++ auto_loaded = TRUE; ++ currSCCB->Sccb_scsistat = SELECT_BDR_ST; ++ ++ if (currTar_Info->TarEEValue & EE_SYNC_MASK) ++ { ++ currTar_Info->TarSyncCtrl = 0; ++ currTar_Info->TarStatus &= ~TAR_SYNC_MASK; ++ } ++ ++#if defined(WIDE_SCSI) ++ ++ if (currTar_Info->TarEEValue & EE_WIDE_SCSI) ++ { ++ currTar_Info->TarStatus &= ~TAR_WIDE_MASK; ++ } ++#endif ++ ++ sssyncv(port, target, NARROW_SCSI,currTar_Info); ++ SccbMgrTableInitTarget(p_card, target); ++ ++ } ++ ++ 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+ ++ (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK) ++ >> 6) | (UCHAR)0x20))); ++ 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)); ++ auto_loaded = TRUE; ++ ++ } ++ ++#if defined(WIDE_SCSI) ++ ++ ++ else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) { ++ auto_loaded = siwidn(port,p_card); ++ currSCCB->Sccb_scsistat = SELECT_WN_ST; ++ } ++ ++#endif ++ ++ ++ else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) ++ == SYNC_SUPPORTED)) { ++ auto_loaded = sisyncn(port,p_card, FALSE); ++ currSCCB->Sccb_scsistat = SELECT_SN_ST; ++ } ++ ++ ++ if (!auto_loaded) ++ { ++ ++#if !defined(DOS) ++ 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; ++ ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ } ++ ++ 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+ ++ (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK) ++ >> 6) | (UCHAR)0x20))); ++ ++ for (i = 1; i < QUEUE_DEPTH; i++) ++ { ++ if (++lastTag >= QUEUE_DEPTH) lastTag = 1; ++ if (CurrCard->discQ_Tbl[lastTag] == NULL) ++ { ++ WRW_HARPOON((port+ID_MSG_STRT+6), ++ (MPM_OP+AMSG_OUT+lastTag)); ++ CurrCard->tagQ_Lst = lastTag; ++ currSCCB->Sccb_tag = lastTag; ++ CurrCard->discQ_Tbl[lastTag] = currSCCB; ++ CurrCard->discQCount++; ++ break; ++ } ++ } ++ ++ ++ if ( i == QUEUE_DEPTH ) ++ { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ queueSelectFail(CurrCard,p_card); ++ SGRAM_ACCESS(port); ++ return; ++ } ++ ++ currSCCB->Sccb_scsistat = SELECT_Q_ST; ++ ++ WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); ++ } ++ } ++ ++ else ++ { ++#endif /* !DOS */ ++ ++ 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)); ++#if !defined(DOS) ++ } ++#endif ++ ++ ++#if defined(OS2) ++ theCCB = (UCHAR far *)&currSCCB->Cdb[0]; ++#else ++ theCCB = (UCHAR *)&currSCCB->Cdb[0]; ++#endif ++ ++ 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 */ ++ ++#if defined(WIDE_SCSI) ++ WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00); ++ WR_HARPOON(port+hp_xferstat, 0x00); ++#endif ++ ++ 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 ++ { ++ ++/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F); ++ auto_loaded |= AUTO_IMMED; */ ++ auto_loaded = AUTO_IMMED; ++ ++ DISABLE_AUTO(port); ++ ++ WR_HARPOON(port+hp_autostart_3, auto_loaded); ++ } ++ ++ SGRAM_ACCESS(port); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sres ++ * ++ * Description: Hookup the correct CCB and handle the incoming messages. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard) ++#else ++void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard) ++#endif ++{ ++ ++#if defined(V302) ++#ifdef DOS ++ UCHAR our_target,message, msgRetryCount; ++ extern UCHAR lun, tag; ++#else ++ UCHAR our_target,message,lun,tag, msgRetryCount; ++#endif ++ ++#else /* V302 */ ++ UCHAR our_target, message, lun = 0, tag, msgRetryCount; ++#endif /* V302 */ ++ ++ ++ PSCCBMgr_tar_info currTar_Info; ++ PSCCB currSCCB; ++ ++ ++ ++ ++ if(pCurrCard->currentSCCB != NULL) ++ { ++ currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID]; ++ 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))) ++ { ++ currTar_Info->TarLUNBusy[currSCCB->Lun] = FALSE; ++ if(currSCCB->Sccb_scsistat != ABORT_ST) ++ { ++ pCurrCard->discQCount--; ++ pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]] ++ = NULL; ++ } ++ } ++ else ++ { ++ currTar_Info->TarLUNBusy[0] = FALSE; ++ 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; ++ } ++ } ++ } ++ ++ queueSelectFail(&BL_Card[p_card],p_card); ++ } ++ ++#if defined(WIDE_SCSI) ++ WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00); ++#endif ++ ++ ++ our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4); ++ currTar_Info = &sccbMgrTbl[p_card][our_target]; ++ ++ ++ msgRetryCount = 0; ++ do ++ { ++ ++#if defined(V302) ++ ++ message = GetTarLun(port, p_card, our_target, pCurrCard, &tag, &lun); ++ ++#else /* V302 */ ++ ++ currTar_Info = &sccbMgrTbl[p_card][our_target]; ++ 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) ++ { ++ ++ message = sfm(port,pCurrCard->currentSCCB); ++ if (message) ++ { ++ ++ if (message <= (0x80 | LUN_MASK)) ++ { ++ lun = message & (UCHAR)LUN_MASK; ++ ++#if !defined(DOS) ++ if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING) ++ { ++ if (currTar_Info->TarTagQ_Cnt != 0) ++ { ++ ++ if (!(currTar_Info->TarLUN_CA)) ++ { ++ ACCEPT_MSG(port); /*Release the ACK for ID msg. */ ++ ++ ++ message = sfm(port,pCurrCard->currentSCCB); ++ if (message) ++ { ++ ACCEPT_MSG(port); ++ } ++ ++ else ++ message = FALSE; ++ ++ if(message != FALSE) ++ { ++ tag = sfm(port,pCurrCard->currentSCCB); ++ ++ if (!(tag)) ++ message = FALSE; ++ } ++ ++ } /*C.A. exists! */ ++ ++ } /*End Q cnt != 0 */ ++ ++ } /*End Tag cmds supported! */ ++#endif /* !DOS */ ++ ++ } /*End valid ID message. */ ++ ++ else ++ { ++ ++ ACCEPT_MSG_ATN(port); ++ } ++ ++ } /* End good id message. */ ++ ++ else ++ { ++ ++ message = FALSE; ++ } ++ } ++ 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; ++ } ++ ++#endif /* V302 */ ++ ++ if(message == FALSE) ++ { ++ msgRetryCount++; ++ if(msgRetryCount == 1) ++ { ++ SendMsg(port, SMPARITY); ++ } ++ else ++ { ++ SendMsg(port, SMDEV_RESET); ++ ++ sssyncv(port, our_target, NARROW_SCSI,currTar_Info); ++ ++ if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK) ++ { ++ ++ sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK; ++ ++ } ++ ++ if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI) ++ { ++ ++ sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK; ++ } ++ ++ ++ queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE); ++ SccbMgrTableInitTarget(p_card,our_target); ++ return; ++ } ++ } ++ }while(message == FALSE); ++ ++ ++ ++ if(((pCurrCard->globalFlags & F_CONLUN_IO) && ++ ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ currTar_Info->TarLUNBusy[lun] = TRUE; ++ pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]]; ++ if(pCurrCard->currentSCCB != NULL) ++ { ++ ACCEPT_MSG(port); ++ } ++ else ++ { ++ ACCEPT_MSG_ATN(port); ++ } ++ } ++ else ++ { ++ currTar_Info->TarLUNBusy[0] = TRUE; ++ ++ ++ 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 */ ++ queueFindSccb(pCurrCard->currentSCCB, p_card); ++ } ++ } ++ ++ ++ while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) && ++ !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) && ++ (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ; ++} ++ ++#if defined(V302) ++ ++#if defined(DOS) ++UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun) ++#else ++UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun) ++#endif ++{ ++ UCHAR message; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ ++ currTar_Info = &sccbMgrTbl[p_card][our_target]; ++ *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(TRUE); ++ } ++ } ++ ++ WRW_HARPOON((port+hp_intstat), PHASE); ++ if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) ++ { ++ ++ message = sfm(port,pCurrCard->currentSCCB); ++ if (message) ++ { ++ ++ if (message <= (0x80 | LUN_MASK)) ++ { ++ *lun = message & (UCHAR)LUN_MASK; ++ ++#if !defined(DOS) ++ if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING) ++ { ++ if (currTar_Info->TarTagQ_Cnt != 0) ++ { ++ ++ if (!(currTar_Info->TarLUN_CA)) ++ { ++ ACCEPT_MSG(port); /*Release the ACK for ID msg. */ ++ ++ ++ message = sfm(port,pCurrCard->currentSCCB); ++ if (message) ++ { ++ ACCEPT_MSG(port); ++ } ++ ++ else ++ return(FALSE); ++ ++ *tag = sfm(port,pCurrCard->currentSCCB); ++ ++ if (!(*tag)) return(FALSE); ++ ++ } /*C.A. exists! */ ++ ++ } /*End Q cnt != 0 */ ++ ++ } /*End Tag cmds supported! */ ++#endif /* !DOS */ ++ ++ } /*End valid ID message. */ ++ ++ else ++ { ++ ++ ACCEPT_MSG_ATN(port); ++ } ++ ++ } /* End good id message. */ ++ ++ else ++ { ++ ++ return(FALSE); ++ } ++ } ++ else ++ { ++ ACCEPT_MSG_ATN(port); ++ return(TRUE); ++ } ++ return(TRUE); ++} ++ ++#endif /* V302 */ ++ ++#if defined(DOS) ++void SendMsg(USHORT port, UCHAR message) ++#else ++void SendMsg(ULONG port, UCHAR message) ++#endif ++{ ++ 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); ++ } ++ } ++ } ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sdecm ++ * ++ * Description: Determine the proper responce to the message from the ++ * target device. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void sdecm(UCHAR message, USHORT port, UCHAR p_card) ++#else ++void sdecm(UCHAR message, ULONG port, UCHAR p_card) ++#endif ++{ ++ PSCCB currSCCB; ++ PSCCBcard CurrCard; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ CurrCard = &BL_Card[p_card]; ++ currSCCB = CurrCard->currentSCCB; ++ ++ currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID]; ++ ++ if (message == SMREST_DATA_PTR) ++ { ++ if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) ++ { ++ currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC; ++ ++ hostDataXferRestart(currSCCB); ++ } ++ ++ 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) ++ { ++ currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK; ++ currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT; ++ } ++ ++ 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)) ++ { ++ ++ currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED; ++ ++ currTar_Info->TarEEValue &= ~EE_SYNC_MASK; ++ } ++ ++#if defined(WIDE_SCSI) ++ else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST)) ++ { ++ ++ ++ currTar_Info->TarStatus = (currTar_Info->TarStatus & ++ ~WIDE_ENABLED) | WIDE_NEGOCIATED; ++ ++ currTar_Info->TarEEValue &= ~EE_WIDE_SCSI; ++ ++ } ++#endif ++ ++ else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) ++ { ++ currTar_Info->TarStatus = (currTar_Info->TarStatus & ++ ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT; ++ ++ ++ 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)) ++ currTar_Info->TarLUNBusy[currSCCB->Lun] = TRUE; ++ else ++ currTar_Info->TarLUNBusy[0] = TRUE; ++ ++ ++ currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q; ++ ++ 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); ++ shandem(port,p_card,currSCCB); ++ } ++ ++ else if (message == SMIGNORWR) ++ { ++ ++ ACCEPT_MSG(port); /* ACK the RESIDUE MSG */ ++ ++ message = sfm(port,currSCCB); ++ ++ 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)); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: shandem ++ * ++ * Description: Decide what to do with the extended message. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void shandem(USHORT port, UCHAR p_card, PSCCB pCurrSCCB) ++#else ++void shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB) ++#endif ++{ ++ UCHAR length,message; ++ ++ length = sfm(port,pCurrSCCB); ++ if (length) ++ { ++ ++ ACCEPT_MSG(port); ++ message = sfm(port,pCurrSCCB); ++ if (message) ++ { ++ ++ if (message == SMSYNC) ++ { ++ ++ if (length == 0x03) ++ { ++ ++ ACCEPT_MSG(port); ++ stsyncn(port,p_card); ++ } ++ else ++ { ++ ++ pCurrSCCB->Sccb_scsimsg = SMREJECT; ++ ACCEPT_MSG_ATN(port); ++ } ++ } ++#if defined(WIDE_SCSI) ++ else if (message == SMWDTR) ++ { ++ ++ if (length == 0x02) ++ { ++ ++ ACCEPT_MSG(port); ++ stwidn(port,p_card); ++ } ++ else ++ { ++ ++ pCurrSCCB->Sccb_scsimsg = SMREJECT; ++ ACCEPT_MSG_ATN(port); ++ ++ WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); ++ } ++ } ++#endif ++ 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)); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sisyncn ++ * ++ * Description: Read in a message byte from the SCSI bus, and check ++ * for a parity error. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag) ++#else ++UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag) ++#endif ++{ ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID]; ++ ++ if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) { ++ ++ ++ WRW_HARPOON((port+ID_MSG_STRT), ++ (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV))); ++ ++ 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 )); ++ ++ ++ if(syncFlag == FALSE) ++ { ++ WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT)); ++ currTar_Info->TarStatus = ((currTar_Info->TarStatus & ++ ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING); ++ } ++ else ++ { ++ WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT)); ++ } ++ ++ ++ return(TRUE); ++ } ++ ++ else { ++ ++ currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED; ++ currTar_Info->TarEEValue &= ~EE_SYNC_MASK; ++ return(FALSE); ++ } ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: stsyncn ++ * ++ * Description: The has sent us a Sync Nego message so handle it as ++ * necessary. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void stsyncn(USHORT port, UCHAR p_card) ++#else ++void stsyncn(ULONG port, UCHAR p_card) ++#endif ++{ ++ UCHAR sync_msg,offset,sync_reg,our_sync_msg; ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID]; ++ ++ sync_msg = sfm(port,currSCCB); ++ ++ if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) ++ { ++ WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); ++ return; ++ } ++ ++ ACCEPT_MSG(port); ++ ++ ++ offset = sfm(port,currSCCB); ++ ++ 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 defined(WIDE_SCSI) ++ if (currTar_Info->TarStatus & WIDE_ENABLED) ++ ++ sync_reg |= offset; ++ ++ else ++ ++ sync_reg |= (offset | NARROW_SCSI); ++ ++#else ++ sync_reg |= (offset | NARROW_SCSI); ++#endif ++ ++ sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info); ++ ++ ++ if (currSCCB->Sccb_scsistat == SELECT_SN_ST) { ++ ++ ++ ACCEPT_MSG(port); ++ ++ currTar_Info->TarStatus = ((currTar_Info->TarStatus & ++ ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED); ++ ++ WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); ++ } ++ ++ else { ++ ++ ++ ACCEPT_MSG_ATN(port); ++ ++ sisyncr(port,sync_msg,offset); ++ ++ currTar_Info->TarStatus = ((currTar_Info->TarStatus & ++ ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sisyncr ++ * ++ * Description: Answer the targets sync message. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset) ++#else ++void sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset) ++#endif ++{ ++ 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))) {} ++} ++ ++ ++ ++#if defined(WIDE_SCSI) ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: siwidn ++ * ++ * Description: Read in a message byte from the SCSI bus, and check ++ * for a parity error. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR siwidn(USHORT port, UCHAR p_card) ++#else ++UCHAR siwidn(ULONG port, UCHAR p_card) ++#endif ++{ ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID]; ++ ++ if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) { ++ ++ ++ WRW_HARPOON((port+ID_MSG_STRT), ++ (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV))); ++ ++ 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 & ++ ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED); ++ ++ return(TRUE); ++ } ++ ++ else { ++ ++ currTar_Info->TarStatus = ((currTar_Info->TarStatus & ++ ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED); ++ ++ currTar_Info->TarEEValue &= ~EE_WIDE_SCSI; ++ return(FALSE); ++ } ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: stwidn ++ * ++ * Description: The has sent us a Wide Nego message so handle it as ++ * necessary. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void stwidn(USHORT port, UCHAR p_card) ++#else ++void stwidn(ULONG port, UCHAR p_card) ++#endif ++{ ++ UCHAR width; ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID]; ++ ++ width = sfm(port,currSCCB); ++ ++ 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; ++ } ++ ++ ++ sssyncv(port,currSCCB->TargID,width,currTar_Info); ++ ++ ++ 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); ++ sisyncn(port,p_card, TRUE); ++ 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; ++ ++ siwidr(port,width); ++ ++ currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: siwidr ++ * ++ * Description: Answer the targets Wide nego message. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void siwidr(USHORT port, UCHAR width) ++#else ++void siwidr(ULONG port, UCHAR width) ++#endif ++{ ++ 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))) {} ++} ++ ++#endif ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sssyncv ++ * ++ * Description: Write the desired value to the Sync Register for the ++ * ID specified. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info) ++#else ++void sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info) ++#endif ++{ ++ UCHAR index; ++ ++ index = p_id; ++ ++ switch (index) { ++ ++ case 0: ++ index = 12; /* hp_synctarg_0 */ ++ break; ++ case 1: ++ index = 13; /* hp_synctarg_1 */ ++ break; ++ case 2: ++ index = 14; /* hp_synctarg_2 */ ++ break; ++ case 3: ++ index = 15; /* hp_synctarg_3 */ ++ break; ++ case 4: ++ index = 8; /* hp_synctarg_4 */ ++ break; ++ case 5: ++ index = 9; /* hp_synctarg_5 */ ++ break; ++ case 6: ++ index = 10; /* hp_synctarg_6 */ ++ break; ++ case 7: ++ index = 11; /* hp_synctarg_7 */ ++ break; ++ case 8: ++ index = 4; /* hp_synctarg_8 */ ++ break; ++ case 9: ++ index = 5; /* hp_synctarg_9 */ ++ break; ++ case 10: ++ index = 6; /* hp_synctarg_10 */ ++ break; ++ case 11: ++ index = 7; /* hp_synctarg_11 */ ++ break; ++ case 12: ++ index = 0; /* hp_synctarg_12 */ ++ break; ++ case 13: ++ index = 1; /* hp_synctarg_13 */ ++ break; ++ case 14: ++ index = 2; /* hp_synctarg_14 */ ++ break; ++ case 15: ++ index = 3; /* hp_synctarg_15 */ ++ ++ } ++ ++ WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value); ++ ++ currTar_Info->TarSyncCtrl = p_sync_value; ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sresb ++ * ++ * Description: Reset the desired card's SCSI bus. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void sresb(USHORT port, UCHAR p_card) ++#else ++void sresb(ULONG port, UCHAR p_card) ++#endif ++{ ++ UCHAR scsiID, i; ++ ++ 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); ++ ++ Wait(port, TO_5ms); ++ ++ 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++) ++ { ++ currTar_Info = &sccbMgrTbl[p_card][scsiID]; ++ ++ 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; ++ } ++ ++ sssyncv(port, scsiID, NARROW_SCSI,currTar_Info); ++ ++ SccbMgrTableInitTarget(p_card, scsiID); ++ } ++ ++ BL_Card[p_card].scanIndex = 0x00; ++ BL_Card[p_card].currentSCCB = NULL; ++ BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT ++ | F_NEW_SCCB_CMD); ++ BL_Card[p_card].cmdCounter = 0x00; ++ BL_Card[p_card].discQCount = 0x00; ++ BL_Card[p_card].tagQ_Lst = 0x01; ++ ++ for(i = 0; i < QUEUE_DEPTH; i++) ++ BL_Card[p_card].discQ_Tbl[i] = NULL; ++ ++ WR_HARPOON(port+hp_page_ctrl, ++ (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE)); ++ ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: ssenss ++ * ++ * Description: Setup for the Auto Sense command. ++ * ++ *---------------------------------------------------------------------*/ ++void ssenss(PSCCBcard pCurrCard) ++{ ++ UCHAR i; ++ PSCCB currSCCB; ++ ++ 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; ++ currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */ ++ 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; ++ ++ currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV; ++ ++ currSCCB->ControlByte = 0x00; ++ ++ currSCCB->Sccb_MGRFlags &= F_STATUSLOADED; ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sxfrp ++ * ++ * Description: Transfer data into the bit bucket until the device ++ * decides to switch phase. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void sxfrp(USHORT p_port, UCHAR p_card) ++#else ++void sxfrp(ULONG p_port, UCHAR p_card) ++#endif ++{ ++ UCHAR curr_phz; ++ ++ ++ DISABLE_AUTO(p_port); ++ ++ if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) { ++ ++ hostDataXferAbort(p_port,p_card,BL_Card[p_card].currentSCCB); ++ ++ } ++ ++ /* If the Automation handled the end of the transfer then do not ++ match the phase or we will get out of sync with the ISR. */ ++ ++ if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT)) ++ return; ++ ++ WR_HARPOON(p_port+hp_xfercnt_0, 0x00); ++ ++ curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ; ++ ++ 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)) && ++ (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) ) ++ { ++ if (curr_phz & (UCHAR)SCSI_IOBIT) ++ { ++ 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))) ; ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: schkdd ++ * ++ * Description: Make sure data has been flushed from both FIFOs and abort ++ * the operations if necessary. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void schkdd(USHORT port, UCHAR p_card) ++#else ++void schkdd(ULONG port, UCHAR p_card) ++#endif ++{ ++ USHORT TimeOutLoop; ++ UCHAR sPhase; ++ ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ ++ 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; ++ WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00); ++ 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); ++ } ++ ++ ++ hostDataXferAbort(port,p_card,currSCCB); ++ ++ ++ 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; ++ } ++ if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) { ++ 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)) || ++ (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) || ++ (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) { ++ phaseDataIn(port,p_card); ++ } ++ ++ else { ++ phaseDataOut(port,p_card); ++ } ++ } ++ else ++ { ++ sxfrp(port,p_card); ++ if (!(RDW_HARPOON((port+hp_intstat)) & ++ (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) ++ { ++ WRW_HARPOON((port+hp_intstat), AUTO_INT); ++ phaseDecode(port,p_card); ++ } ++ } ++ ++ } ++ ++ else { ++ WR_HARPOON(port+hp_portctrl_0, 0x00); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sinits ++ * ++ * Description: Setup SCCB manager fields in this SCCB. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void sinits(PSCCB p_sccb, UCHAR p_card) ++{ ++ PSCCBMgr_tar_info currTar_Info; ++ ++ if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN)) ++ { ++ return; ++ } ++ currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID]; ++ ++ 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 */ ++ ++/* ++ if (((!(BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) && ++ (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)) { ++ p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun; ++ } ++ ++ else { ++ ++ p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun; ++ } ++ ++ 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; ++ ++} ++ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: phase.c $ ++ * ++ * Description: Functions to intially handle the SCSI bus phase when ++ * the target asserts request (and the automation is not ++ * enabled to handle the situation). ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <harpoon.h>*/ ++ ++ ++/* ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++ ++#if defined(OS2) ++ extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR); ++#else ++ #if defined(DOS) ++ extern void (*s_PhaseTbl[8]) (USHORT, UCHAR); ++ #else ++ extern void (*s_PhaseTbl[8]) (ULONG, UCHAR); ++ #endif ++#endif ++*/ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Phase Decode ++ * ++ * Description: Determine the phase and call the appropriate function. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void phaseDecode(USHORT p_port, UCHAR p_card) ++#else ++void phaseDecode(ULONG p_port, UCHAR p_card) ++#endif ++{ ++ unsigned char phase_ref; ++#if defined(OS2) ++ void (far *phase) (ULONG, UCHAR); ++#else ++ #if defined(DOS) ++ void (*phase) (USHORT, UCHAR); ++ #else ++ void (*phase) (ULONG, UCHAR); ++ #endif ++#endif ++ ++ ++ DISABLE_AUTO(p_port); ++ ++ phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ); ++ ++ phase = s_PhaseTbl[phase_ref]; ++ ++ (*phase)(p_port, p_card); /* Call the correct phase func */ ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Data Out Phase ++ * ++ * Description: Start up both the BusMaster and Xbow. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseDataOut(ULONG port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseDataOut(USHORT port, UCHAR p_card) ++#else ++void phaseDataOut(ULONG port, UCHAR p_card) ++#endif ++#endif ++{ ++ ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ 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)); ++ ++ dataXferProcessor(port, &BL_Card[p_card]); ++ ++#if defined(NOBUGBUG) ++ if (RDW_HARPOON((port+hp_intstat)) & XFER_CNT_0) ++ WRW_HARPOON((port+hp_intstat), XFER_CNT_0); ++ ++#endif ++ ++ ++ if (currSCCB->Sccb_XferCnt == 0) { ++ ++ ++ if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) && ++ (currSCCB->HostStatus == SCCB_COMPLETE)) ++ currSCCB->HostStatus = SCCB_DATA_OVER_RUN; ++ ++ sxfrp(port,p_card); ++ if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET))) ++ phaseDecode(port,p_card); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Data In Phase ++ * ++ * Description: Startup the BusMaster and the XBOW. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseDataIn(ULONG port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseDataIn(USHORT port, UCHAR p_card) ++#else ++void phaseDataIn(ULONG port, UCHAR p_card) ++#endif ++#endif ++{ ++ ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ 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)); ++ ++ dataXferProcessor(port, &BL_Card[p_card]); ++ ++ if (currSCCB->Sccb_XferCnt == 0) { ++ ++ ++ if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) && ++ (currSCCB->HostStatus == SCCB_COMPLETE)) ++ currSCCB->HostStatus = SCCB_DATA_OVER_RUN; ++ ++ sxfrp(port,p_card); ++ if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET))) ++ phaseDecode(port,p_card); ++ ++ } ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Command Phase ++ * ++ * Description: Load the CDB into the automation and start it up. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseCommand(ULONG p_port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseCommand(USHORT p_port, UCHAR p_card) ++#else ++void phaseCommand(ULONG p_port, UCHAR p_card) ++#endif ++#endif ++{ ++ PSCCB currSCCB; ++#if defined(DOS) ++ USHORT cdb_reg; ++#else ++ ULONG cdb_reg; ++#endif ++ UCHAR i; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ 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 ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseStatus(ULONG port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseStatus(USHORT port, UCHAR p_card) ++#else ++void phaseStatus(ULONG port, UCHAR p_card) ++#endif ++#endif ++{ ++ /* 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseMsgOut(ULONG port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseMsgOut(USHORT port, UCHAR p_card) ++#else ++void phaseMsgOut(ULONG port, UCHAR p_card) ++#endif ++#endif ++{ ++ UCHAR message,scsiID; ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ if (currSCCB != NULL) { ++ ++ message = currSCCB->Sccb_scsimsg; ++ scsiID = currSCCB->TargID; ++ ++ if (message == SMDEV_RESET) ++ { ++ ++ ++ currTar_Info = &sccbMgrTbl[p_card][scsiID]; ++ currTar_Info->TarSyncCtrl = 0; ++ sssyncv(port, scsiID, NARROW_SCSI,currTar_Info); ++ ++ if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK) ++ { ++ ++ sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK; ++ ++ } ++ ++ if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI) ++ { ++ ++ sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK; ++ } ++ ++ ++ queueFlushSccb(p_card,SCCB_COMPLETE); ++ SccbMgrTableInitTarget(p_card,scsiID); ++ } ++ else if (currSCCB->Sccb_scsistat == ABORT_ST) ++ { ++ currSCCB->HostStatus = SCCB_COMPLETE; ++ if(BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL) ++ { ++ BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; ++ sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--; ++ } ++ ++ } ++ ++ else if (currSCCB->Sccb_scsistat < COMMAND_ST) ++ { ++ ++ ++ if(message == SMNO_OP) ++ { ++ currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED; ++ ++ ssel(port,p_card); ++ return; ++ } ++ } ++ else ++ { ++ ++ ++ if (message == SMABORT) ++ ++ queueFlushSccb(p_card,SCCB_COMPLETE); ++ } ++ ++ } ++ 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) ++ { ++ ++ if((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE; ++ else ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE; ++ ++ queueCmdComplete(&BL_Card[p_card],currSCCB, p_card); ++ } ++ ++ else ++ { ++ BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; ++ } ++ } ++ ++ else ++ { ++ ++ sxfrp(port,p_card); ++ } ++ } ++ ++ else ++ { ++ ++ if(message == SMPARITY) ++ { ++ currSCCB->Sccb_scsimsg = SMNO_OP; ++ WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START)); ++ } ++ else ++ { ++ sxfrp(port,p_card); ++ } ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Message In phase ++ * ++ * Description: Bring in the message and determine what to do with it. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseMsgIn(ULONG port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseMsgIn(USHORT port, UCHAR p_card) ++#else ++void phaseMsgIn(ULONG port, UCHAR p_card) ++#endif ++#endif ++{ ++ UCHAR message; ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) ++ { ++ ++ phaseChkFifo(port, p_card); ++ } ++ ++ 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 ++ { ++ ++ message = sfm(port,currSCCB); ++ if (message) ++ { ++ ++ ++ sdecm(message,port,p_card); ++ ++ } ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(OS2) ++void far phaseIllegal(ULONG port, UCHAR p_card) ++#else ++#if defined(DOS) ++void phaseIllegal(USHORT port, UCHAR p_card) ++#else ++void phaseIllegal(ULONG port, UCHAR p_card) ++#endif ++#endif ++{ ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void phaseChkFifo(USHORT port, UCHAR p_card) ++#else ++void phaseChkFifo(ULONG port, UCHAR p_card) ++#endif ++{ ++ ULONG xfercnt; ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ 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); ++ } ++ ++ hostDataXferAbort(port,p_card,currSCCB); ++ ++ dataXferProcessor(port, &BL_Card[p_card]); ++ ++ while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) && ++ (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {} ++ ++ } ++ } /*End Data In specific code. */ ++ ++ ++ ++#if defined(DOS) ++ asm { mov dx,port; ++ add dx,hp_xfercnt_2; ++ in al,dx; ++ dec dx; ++ xor ah,ah; ++ mov word ptr xfercnt+2,ax; ++ in al,dx; ++ dec dx; ++ mov ah,al; ++ in al,dx; ++ mov word ptr xfercnt,ax; ++ } ++#else ++ GET_XFER_CNT(port,xfercnt); ++#endif ++ ++ ++ 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); ++ } ++ ++ ++ hostDataXferAbort(port,p_card,currSCCB); ++ ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void phaseBusFree(USHORT port, UCHAR p_card) ++#else ++void phaseBusFree(ULONG port, UCHAR p_card) ++#endif ++{ ++ PSCCB currSCCB; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ if (currSCCB != NULL) ++ { ++ ++ DISABLE_AUTO(port); ++ ++ ++ if (currSCCB->OperationCode == RESET_COMMAND) ++ { ++ ++ if((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE; ++ else ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE; ++ ++ queueCmdComplete(&BL_Card[p_card], currSCCB, p_card); ++ ++ queueSearchSelect(&BL_Card[p_card],p_card); ++ ++ } ++ ++ else if(currSCCB->Sccb_scsistat == SELECT_SN_ST) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= ++ (UCHAR)SYNC_SUPPORTED; ++ sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK; ++ } ++ ++ else if(currSCCB->Sccb_scsistat == SELECT_WN_ST) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = ++ (sccbMgrTbl[p_card][currSCCB->TargID]. ++ TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; ++ ++ sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI; ++ } ++ ++#if !defined(DOS) ++ 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)) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK; ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT; ++ } ++ ++ else ++ { ++ return; ++ } ++ } ++#endif ++ ++ else ++ { ++ ++ currSCCB->Sccb_scsistat = BUS_FREE_ST; ++ ++ if (!currSCCB->HostStatus) ++ { ++ currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; ++ } ++ ++ if((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE; ++ else ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE; ++ ++ queueCmdComplete(&BL_Card[p_card], currSCCB, p_card); ++ return; ++ } ++ ++ ++ BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; ++ ++ } /*end if !=null */ ++} ++ ++ ++ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: automate.c $ ++ * ++ * Description: Functions relating to programming the automation of ++ * the HARPOON. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <harpoon.h>*/ ++ ++/* ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++extern SCCBCARD BL_Card[MAX_CARDS]; ++*/ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Auto Load Default Map ++ * ++ * Description: Load the Automation RAM with the defualt map values. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void autoLoadDefaultMap(USHORT p_port) ++#else ++void autoLoadDefaultMap(ULONG p_port) ++#endif ++{ ++#if defined(DOS) ++ USHORT map_addr; ++#else ++ ULONG map_addr; ++#endif ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void autoCmdCmplt(USHORT p_port, UCHAR p_card) ++#else ++void autoCmdCmplt(ULONG p_port, UCHAR p_card) ++#endif ++{ ++ PSCCB currSCCB; ++ UCHAR status_byte; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ ++ status_byte = RD_HARPOON(p_port+hp_gp_reg_0); ++ ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = FALSE; ++ ++ if (status_byte != SSGOOD) { ++ ++ if (status_byte == SSQ_FULL) { ++ ++ ++ if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE; ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; ++ } ++ else ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE; ++ if(currSCCB->Sccb_tag) ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; ++ }else ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; ++ } ++ } ++ ++ currSCCB->Sccb_MGRFlags |= F_STATUSLOADED; ++ ++ queueSelectFail(&BL_Card[p_card],p_card); ++ ++ return; ++ } ++ ++ if(currSCCB->Sccb_scsistat == SELECT_SN_ST) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= ++ (UCHAR)SYNC_SUPPORTED; ++ ++ sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK; ++ BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; ++ ++ if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE; ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; ++ } ++ else ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE; ++ if(currSCCB->Sccb_tag) ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; ++ }else ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; ++ } ++ } ++ return; ++ ++ } ++ ++ if(currSCCB->Sccb_scsistat == SELECT_WN_ST) ++ { ++ ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus = ++ (sccbMgrTbl[p_card][currSCCB->TargID]. ++ TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED; ++ ++ sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI; ++ BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; ++ ++ if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE; ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; ++ } ++ else ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE; ++ if(currSCCB->Sccb_tag) ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; ++ }else ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; ++ } ++ } ++ return; ++ ++ } ++ ++ if (status_byte == SSCHECK) ++ { ++ if(BL_Card[p_card].globalFlags & F_DO_RENEGO) ++ { ++ if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK; ++ } ++ if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK; ++ } ++ } ++ } ++ ++ if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) { ++ ++ currSCCB->SccbStatus = SCCB_ERROR; ++ currSCCB->TargetStatus = status_byte; ++ ++ if (status_byte == SSCHECK) { ++ ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA ++ = TRUE; ++ ++ ++#if (FW_TYPE==_SCCB_MGR_) ++ if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) { ++ ++ if (currSCCB->RequestSenseLength == 0) ++ currSCCB->RequestSenseLength = 14; ++ ++ ssenss(&BL_Card[p_card]); ++ BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; ++ ++ if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE; ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; ++ } ++ else ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE; ++ if(currSCCB->Sccb_tag) ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; ++ }else ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; ++ } ++ } ++ return; ++ } ++#else ++ if ((!(currSCCB->Sccb_ucb_ptr->UCB_opcode & OPC_NO_AUTO_SENSE)) && ++ (currSCCB->RequestSenseLength)) ++ { ++ ssenss(&BL_Card[p_card]); ++ BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD; ++ ++ if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE; ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL; ++ } ++ else ++ { ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE; ++ if(currSCCB->Sccb_tag) ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL; ++ }else ++ { ++ if(BL_Card[p_card].discQCount != 0) ++ BL_Card[p_card].discQCount--; ++ BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL; ++ } ++ } ++ return; ++ } ++ ++#endif ++ } ++ } ++ } ++ ++ ++ if((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)) ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE; ++ else ++ sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE; ++ ++ ++ queueCmdComplete(&BL_Card[p_card], currSCCB, p_card); ++} ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: busmstr.c $ ++ * ++ * Description: Functions to start, stop, and abort BusMaster operations. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <harpoon.h>*/ ++ ++ ++/* ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++*/ ++ ++#define SHORT_WAIT 0x0000000F ++#define LONG_WAIT 0x0000FFFFL ++ ++#if defined(BUGBUG) ++void Debug_Load(UCHAR p_card, UCHAR p_bug_data); ++#endif ++ ++/*--------------------------------------------------------------------- ++ * ++ * 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void dataXferProcessor(USHORT port, PSCCBcard pCurrCard) ++#else ++void dataXferProcessor(ULONG port, PSCCBcard pCurrCard) ++#endif ++{ ++ PSCCB currSCCB; ++ ++ currSCCB = pCurrCard->currentSCCB; ++ ++ if (currSCCB->Sccb_XferState & F_SG_XFER) ++ { ++ if (pCurrCard->globalFlags & F_HOST_XFER_ACT) ++ ++ { ++ currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT; ++ currSCCB->Sccb_SGoffset = 0x00; ++ } ++ pCurrCard->globalFlags |= F_HOST_XFER_ACT; ++ ++ busMstrSGDataXferStart(port, currSCCB); ++ } ++ ++ else ++ { ++ if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) ++ { ++ pCurrCard->globalFlags |= F_HOST_XFER_ACT; ++ ++ busMstrDataXferStart(port, currSCCB); ++ } ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: BusMaster Scatter Gather Data Transfer Start ++ * ++ * Description: ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void busMstrSGDataXferStart(USHORT p_port, PSCCB pcurrSCCB) ++#else ++void busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB) ++#endif ++{ ++ ULONG count,addr,tmpSGCnt; ++ UINT sg_index; ++ UCHAR sg_count, i; ++#if defined(DOS) ++ USHORT reg_offset; ++#else ++ ULONG reg_offset; ++#endif ++ ++ ++ if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) { ++ ++ count = ((ULONG) HOST_RD_CMD)<<24; ++ } ++ ++ else { ++ count = ((ULONG) HOST_WRT_CMD)<<24; ++ } ++ ++ sg_count = 0; ++ tmpSGCnt = 0; ++ sg_index = pcurrSCCB->Sccb_sgseg; ++ reg_offset = hp_aramBase; ++ ++ ++ i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN)); ++ ++ ++ WR_HARPOON(p_port+hp_page_ctrl, i); ++ ++ while ((sg_count < (UCHAR)SG_BUF_CNT) && ++ ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) { ++ ++#if defined(COMPILER_16_BIT) && !defined(DOS) ++ tmpSGCnt += *(((ULONG far *)pcurrSCCB->DataPointer)+ ++ (sg_index * 2)); ++ ++ count |= *(((ULONG far *)pcurrSCCB->DataPointer)+ ++ (sg_index * 2)); ++ ++ addr = *(((ULONG far *)pcurrSCCB->DataPointer)+ ++ ((sg_index * 2) + 1)); ++ ++#else ++ tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+ ++ (sg_index * 2)); ++ ++ count |= *(((ULONG *)pcurrSCCB->DataPointer)+ ++ (sg_index * 2)); ++ ++ addr = *(((ULONG *)pcurrSCCB->DataPointer)+ ++ ((sg_index * 2) + 1)); ++#endif ++ ++ ++ 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); ++ } ++ ++ ++ WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN)); ++ ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: BusMaster Data Transfer Start ++ * ++ * Description: ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void busMstrDataXferStart(USHORT p_port, PSCCB pcurrSCCB) ++#else ++void busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB) ++#endif ++{ ++ ULONG addr,count; ++ ++ if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) { ++ ++ count = pcurrSCCB->Sccb_XferCnt; ++ ++ addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC; ++ } ++ ++ else { ++ addr = pcurrSCCB->SensePointer; ++ count = pcurrSCCB->RequestSenseLength; ++ ++ } ++ ++#if defined(DOS) ++ asm { mov dx,p_port; ++ mov ax,word ptr count; ++ add dx,hp_xfer_cnt_lo; ++ out dx,al; ++ inc dx; ++ xchg ah,al ++ out dx,al; ++ inc dx; ++ mov ax,word ptr count+2; ++ out dx,al; ++ inc dx; ++ inc dx; ++ mov ax,word ptr addr; ++ out dx,al; ++ inc dx; ++ xchg ah,al ++ out dx,al; ++ inc dx; ++ mov ax,word ptr addr+2; ++ out dx,al; ++ inc dx; ++ xchg ah,al ++ out dx,al; ++ } ++ ++ WR_HARP32(p_port,hp_xfercnt_0,count); ++ ++#else ++ HP_SETUP_ADDR_CNT(p_port,addr,count); ++#endif ++ ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++UCHAR busMstrTimeOut(USHORT p_port) ++#else ++UCHAR busMstrTimeOut(ULONG p_port) ++#endif ++{ ++ ULONG timeout; ++ ++ 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) { ++ return(TRUE); ++ } ++ ++ else { ++ return(FALSE); ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Host Data Transfer Abort ++ * ++ * Description: Abort any in progress transfer. ++ * ++ *---------------------------------------------------------------------*/ ++#if defined(DOS) ++void hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB) ++#else ++void hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB) ++#endif ++{ ++ ++ ULONG timeout; ++ ULONG remain_cnt; ++ UINT sg_ptr; ++ ++ BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT; ++ ++ 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) { ++ ++ if (busMstrTimeOut(port)) { ++ ++ 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; ++#if defined(BUGBUG) ++ WR_HARPOON(port+hp_dual_addr_lo, ++ RD_HARPOON(port+hp_ext_status)); ++#endif ++ } ++ } ++ } ++ } ++ ++ 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; ++ ++ if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) { ++ ++ sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE); ++ } ++ ++ remain_cnt = pCurrSCCB->Sccb_XferCnt; ++ ++ while (remain_cnt < 0x01000000L) { ++ ++ sg_ptr--; ++ ++#if defined(COMPILER_16_BIT) && !defined(DOS) ++ if (remain_cnt > (ULONG)(*(((ULONG far *)pCurrSCCB-> ++ DataPointer) + (sg_ptr * 2)))) { ++ ++ remain_cnt -= (ULONG)(*(((ULONG far *)pCurrSCCB-> ++ DataPointer) + (sg_ptr * 2))); ++ } ++ ++#else ++ if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB-> ++ DataPointer) + (sg_ptr * 2)))) { ++ ++ remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB-> ++ DataPointer) + (sg_ptr * 2))); ++ } ++#endif ++ ++ else { ++ ++ break; ++ } ++ } ++ ++ ++ ++ if (remain_cnt < 0x01000000L) { ++ ++ ++ pCurrSCCB->Sccb_SGoffset = remain_cnt; ++ ++ pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr; ++ ++ ++ if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength ++ && (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) { ++ ++ busMstrTimeOut(port); ++ } ++ ++ 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; ++#if defined(BUGBUG) ++ WR_HARPOON(port+hp_dual_addr_lo, ++ RD_HARPOON(port+hp_ext_status)); ++#endif ++ } ++ } ++ } ++ ++ } ++ } ++ ++ 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; ++ } ++ ++ busMstrTimeOut(port); ++ } ++ } ++ ++ 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 defined(BUGBUG) ++ WR_HARPOON(port+hp_dual_addr_lo, ++ RD_HARPOON(port+hp_ext_status)); ++#endif ++ } ++ } ++ } ++ } ++ ++ } ++ ++ 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; ++ } ++ ++ busMstrTimeOut(port); ++ } ++ } ++ ++ ++ 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 defined(BUGBUG) ++ WR_HARPOON(port+hp_dual_addr_lo, ++ RD_HARPOON(port+hp_ext_status)); ++#endif ++ } ++ } ++ ++ } ++ ++ 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; ++ ++ ++ if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >= ++ pCurrSCCB->DataLength) { ++ ++ pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED; ++ ++ pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE); ++ ++ } ++ } ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++void hostDataXferRestart(PSCCB currSCCB) ++{ ++ ULONG data_count; ++ UINT sg_index; ++#if defined(COMPILER_16_BIT) && !defined(DOS) ++ ULONG far *sg_ptr; ++#else ++ ULONG *sg_ptr; ++#endif ++ ++ 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. */ ++ ++#if defined(COMPILER_16_BIT) && !defined(DOS) ++ sg_ptr = (ULONG far *)currSCCB->DataPointer; ++#else ++ sg_ptr = (ULONG *)currSCCB->DataPointer; ++#endif ++ ++ 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; ++ } ++ ++ currSCCB->Sccb_sgseg = (USHORT)sg_index; ++ } ++ ++ else { ++ currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC; ++ } ++} ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: scam.c $ ++ * ++ * Description: Functions relating to handling of the SCAM selection ++ * and the determination of the SCSI IDs to be assigned ++ * to all perspective SCSI targets. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <eeprom.h>*/ ++/*#include <harpoon.h>*/ ++ ++ ++ ++/* ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR]; ++extern NVRAMINFO nvRamInfo[MAX_MB_CARDS]; ++#if defined(DOS) || defined(OS2) ++extern UCHAR temp_id_string[ID_STRING_LENGTH]; ++#endif ++extern UCHAR scamHAString[]; ++*/ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scini ++ * ++ * Description: Setup all data structures necessary for SCAM selection. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up) ++{ ++ ++#if defined(SCAM_LEV_2) ++ UCHAR loser,assigned_id; ++#endif ++#if defined(DOS) ++ ++ USHORT p_port; ++#else ++ ULONG p_port; ++#endif ++ ++ UCHAR i,k,ScamFlg ; ++ PSCCBcard currCard; ++ PNVRamInfo pCurrNvRam; ++ ++ currCard = &BL_Card[p_card]; ++ p_port = currCard->ioPort; ++ pCurrNvRam = currCard->pNvRamInfo; ++ ++ ++ if(pCurrNvRam){ ++ ScamFlg = pCurrNvRam->niScamConf; ++ i = pCurrNvRam->niSysConf; ++ } ++ else{ ++ ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2); ++ i = (UCHAR)(utilEERead(p_port, (SYSTEM_CONFIG/2))); ++ } ++ if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */ ++ return; ++ ++ inisci(p_card,p_port, p_our_id); ++ ++ /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW ++ too slow to return to SCAM selection */ ++ ++ /* if (p_power_up) ++ Wait1Second(p_port); ++ else ++ Wait(p_port, TO_250ms); */ ++ ++ Wait1Second(p_port); ++ ++#if defined(SCAM_LEV_2) ++ ++ if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) ++ { ++ while (!(scarb(p_port,INIT_SELTD))) {} ++ ++ scsel(p_port); ++ ++ do { ++ scxferc(p_port,SYNC_PTRN); ++ scxferc(p_port,DOM_MSTR); ++ loser = scsendi(p_port,&scamInfo[p_our_id].id_string[0]); ++ } while ( loser == 0xFF ); ++ ++ scbusf(p_port); ++ ++ if ((p_power_up) && (!loser)) ++ { ++ sresb(p_port,p_card); ++ Wait(p_port, TO_250ms); ++ ++ while (!(scarb(p_port,INIT_SELTD))) {} ++ ++ scsel(p_port); ++ ++ do { ++ scxferc(p_port, SYNC_PTRN); ++ scxferc(p_port, DOM_MSTR); ++ loser = scsendi(p_port,&scamInfo[p_our_id]. ++ id_string[0]); ++ } while ( loser == 0xFF ); ++ ++ scbusf(p_port); ++ } ++ } ++ ++ else ++ { ++ loser = FALSE; ++ } ++ ++ ++ if (!loser) ++ { ++ ++#endif /* SCAM_LEV_2 */ ++ ++ scamInfo[p_our_id].state = ID_ASSIGNED; ++ ++ ++ if (ScamFlg & SCAM_ENABLED) ++ { ++ ++ for (i=0; i < MAX_SCSI_TAR; i++) ++ { ++ if ((scamInfo[i].state == ID_UNASSIGNED) || ++ (scamInfo[i].state == ID_UNUSED)) ++ { ++ if (scsell(p_port,i)) ++ { ++ scamInfo[i].state = LEGACY; ++ if ((scamInfo[i].id_string[0] != 0xFF) || ++ (scamInfo[i].id_string[1] != 0xFA)) ++ { ++ ++ scamInfo[i].id_string[0] = 0xFF; ++ scamInfo[i].id_string[1] = 0xFA; ++ if(pCurrNvRam == NULL) ++ currCard->globalFlags |= F_UPDATE_EEPROM; ++ } ++ } ++ } ++ } ++ ++ sresb(p_port,p_card); ++ Wait1Second(p_port); ++ while (!(scarb(p_port,INIT_SELTD))) {} ++ scsel(p_port); ++ scasid(p_card, p_port); ++ } ++ ++#if defined(SCAM_LEV_2) ++ ++ } ++ ++ else if ((loser) && (ScamFlg & SCAM_ENABLED)) ++ { ++ scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0; ++ assigned_id = FALSE; ++ scwtsel(p_port); ++ ++ do { ++ while (scxferc(p_port,0x00) != SYNC_PTRN) {} ++ ++ i = scxferc(p_port,0x00); ++ if (i == ASSIGN_ID) ++ { ++ if (!(scsendi(p_port,&scamInfo[p_our_id].id_string[0]))) ++ { ++ i = scxferc(p_port,0x00); ++ if (scvalq(i)) ++ { ++ k = scxferc(p_port,0x00); ++ ++ if (scvalq(k)) ++ { ++ currCard->ourId = ++ ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F; ++ inisci(p_card, p_port, p_our_id); ++ scamInfo[currCard->ourId].state = ID_ASSIGNED; ++ scamInfo[currCard->ourId].id_string[0] ++ = SLV_TYPE_CODE0; ++ assigned_id = TRUE; ++ } ++ } ++ } ++ } ++ ++ else if (i == SET_P_FLAG) ++ { ++ if (!(scsendi(p_port, ++ &scamInfo[p_our_id].id_string[0]))) ++ scamInfo[p_our_id].id_string[0] |= 0x80; ++ } ++ }while (!assigned_id); ++ ++ while (scxferc(p_port,0x00) != CFG_CMPLT) {} ++ } ++ ++#endif /* SCAM_LEV_2 */ ++ if (ScamFlg & SCAM_ENABLED) ++ { ++ scbusf(p_port); ++ if (currCard->globalFlags & F_UPDATE_EEPROM) ++ { ++ scsavdi(p_card, p_port); ++ currCard->globalFlags &= ~F_UPDATE_EEPROM; ++ } ++ } ++ ++ ++#if defined(DOS) ++ for (i=0; i < MAX_SCSI_TAR; i++) ++ { ++ if (((ScamFlg & SCAM_ENABLED) && (scamInfo[i].state == LEGACY)) ++ || (i != p_our_id)) ++ { ++ scsellDOS(p_port,i); ++ } ++ } ++#endif ++ ++/* ++ for (i=0,k=0; i < MAX_SCSI_TAR; i++) ++ { ++ if ((scamInfo[i].state == ID_ASSIGNED) || ++ (scamInfo[i].state == LEGACY)) ++ k++; ++ } ++ ++ if (k==2) ++ currCard->globalFlags |= F_SINGLE_DEVICE; ++ else ++ currCard->globalFlags &= ~F_SINGLE_DEVICE; ++*/ ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scarb ++ * ++ * Description: Gain control of the bus and wait SCAM select time (250ms) ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++int scarb(USHORT p_port, UCHAR p_sel_type) ++#else ++int scarb(ULONG p_port, UCHAR p_sel_type) ++#endif ++{ ++ 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) ++ return(FALSE); ++ ++ if (RD_HARPOON(p_port+hp_scsidata_0) != 00) ++ return(FALSE); ++ ++ 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)); ++ return(FALSE); ++ } ++ ++ ++ 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))); ++ return(FALSE); ++ } ++ } ++ ++ ++ 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); ++#if defined(WIDE_SCSI) ++ WR_HARPOON(p_port+hp_scsidata_1, 0x00); ++#endif ++ 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)); ++ ++ Wait(p_port,TO_250ms); ++ ++ return(TRUE); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scbusf ++ * ++ * Description: Release the SCSI bus and disable SCAM selection. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scbusf(USHORT p_port) ++#else ++void scbusf(ULONG p_port) ++#endif ++{ ++ 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)); ++ ++#if defined(SCAM_LEV_2) ++ WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL)); ++#else ++ WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT)); ++#endif ++ ++ WR_HARPOON(p_port+hp_page_ctrl, ++ (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)); ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scasid ++ * ++ * Description: Assign an ID to all the SCAM devices. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scasid(UCHAR p_card, USHORT p_port) ++#else ++void scasid(UCHAR p_card, ULONG p_port) ++#endif ++{ ++#if defined(DOS) || defined(OS2) ++ /* Use external defined in global space area, instead of Stack ++ space. WIN/95 DOS doesnot work TINY mode. The OS doesnot intialize ++ SS equal to DS. Thus the array allocated on stack doesnot get ++ access correctly */ ++#else ++ UCHAR temp_id_string[ID_STRING_LENGTH]; ++#endif ++ ++ UCHAR i,k,scam_id; ++ UCHAR crcBytes[3]; ++ PNVRamInfo pCurrNvRam; ++ ushort_ptr pCrcBytes; ++ ++ pCurrNvRam = BL_Card[p_card].pNvRamInfo; ++ ++ i=FALSE; ++ ++ while (!i) ++ { ++ ++ for (k=0; k < ID_STRING_LENGTH; k++) ++ { ++ temp_id_string[k] = (UCHAR) 0x00; ++ } ++ ++ scxferc(p_port,SYNC_PTRN); ++ scxferc(p_port,ASSIGN_ID); ++ ++ if (!(sciso(p_port,&temp_id_string[0]))) ++ { ++ if(pCurrNvRam){ ++ pCrcBytes = (ushort_ptr)&crcBytes[0]; ++ *pCrcBytes = CalcCrc16(&temp_id_string[0]); ++ crcBytes[2] = CalcLrc(&temp_id_string[0]); ++ 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++) ++ temp_id_string[k] = (UCHAR) 0x00; ++ } ++ i = scmachid(p_card,temp_id_string); ++ ++ if (i == CLR_PRIORITY) ++ { ++ scxferc(p_port,MISC_CODE); ++ scxferc(p_port,CLR_P_FLAG); ++ i = FALSE; /*Not the last ID yet. */ ++ } ++ ++ else if (i != NO_ID_AVAIL) ++ { ++ if (i < 8 ) ++ scxferc(p_port,ID_0_7); ++ else ++ scxferc(p_port,ID_8_F); ++ ++ scam_id = (i & (UCHAR) 0x07); ++ ++ ++ for (k=1; k < 0x08; k <<= 1) ++ if (!( k & i )) ++ scam_id += 0x08; /*Count number of zeros in DB0-3. */ ++ ++ scxferc(p_port,scam_id); ++ ++ i = FALSE; /*Not the last ID yet. */ ++ } ++ } ++ ++ else ++ { ++ i = TRUE; ++ } ++ ++ } /*End while */ ++ ++ scxferc(p_port,SYNC_PTRN); ++ scxferc(p_port,CFG_CMPLT); ++} ++ ++ ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scsel ++ * ++ * Description: Select all the SCAM devices. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scsel(USHORT p_port) ++#else ++void scsel(ULONG p_port) ++#endif ++{ ++ ++ WR_HARPOON(p_port+hp_scsisig, SCSI_SEL); ++ scwiros(p_port, SCSI_MSG); ++ ++ WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY)); ++ ++ ++ WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); ++ WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) | ++ (UCHAR)(BIT(7)+BIT(6)))); ++ ++ ++ WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD)); ++ scwiros(p_port, SCSI_SEL); ++ ++ WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) & ++ ~(UCHAR)BIT(6))); ++ scwirod(p_port, BIT(6)); ++ ++ WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD)); ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scxferc ++ * ++ * Description: Handshake the p_data (DB4-0) across the bus. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR scxferc(USHORT p_port, UCHAR p_data) ++#else ++UCHAR scxferc(ULONG p_port, UCHAR p_data) ++#endif ++{ ++ UCHAR curr_data, ret_data; ++ ++ 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); ++ ++ scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */ ++ while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5))); ++ ++ ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F); ++ ++ 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); ++ ++ scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */ ++ ++ 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); ++ ++ scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */ ++ ++ return(ret_data); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scsendi ++ * ++ * Description: Transfer our Identification string to determine if we ++ * will be the dominant master. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR scsendi(USHORT p_port, UCHAR p_id_string[]) ++#else ++UCHAR scsendi(ULONG p_port, UCHAR p_id_string[]) ++#endif ++{ ++ UCHAR ret_data,byte_cnt,bit_cnt,defer; ++ ++ defer = FALSE; ++ ++ for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { ++ ++ for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) { ++ ++ if (defer) ++ ret_data = scxferc(p_port,00); ++ ++ else if (p_id_string[byte_cnt] & bit_cnt) ++ ++ ret_data = scxferc(p_port,02); ++ ++ else { ++ ++ ret_data = scxferc(p_port,01); ++ if (ret_data & 02) ++ defer = TRUE; ++ } ++ ++ 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! */ ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: sciso ++ * ++ * Description: Transfer the Identification string. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR sciso(USHORT p_port, UCHAR p_id_string[]) ++#else ++UCHAR sciso(ULONG p_port, UCHAR p_id_string[]) ++#endif ++{ ++ UCHAR ret_data,the_data,byte_cnt,bit_cnt; ++ ++ the_data = 0; ++ ++ for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) { ++ ++ for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) { ++ ++ ret_data = scxferc(p_port,0); ++ ++ 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; ++ scxferc(p_port, SYNC_PTRN); ++ scxferc(p_port, ASSIGN_ID); ++ continue; ++ } ++*/ ++ if (byte_cnt) ++ return(0x00); ++ else ++ return(0xFF); ++ } ++ ++ } /*bit loop */ ++ ++ p_id_string[byte_cnt] = the_data; ++ ++ } /*byte loop */ ++ ++ return(0); ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scwirod ++ * ++ * Description: Sample the SCSI data bus making sure the signal has been ++ * deasserted for the correct number of consecutive samples. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scwirod(USHORT p_port, UCHAR p_data_bit) ++#else ++void scwirod(ULONG p_port, UCHAR p_data_bit) ++#endif ++{ ++ UCHAR i; ++ ++ i = 0; ++ while ( i < MAX_SCSI_TAR ) { ++ ++ if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit) ++ ++ i = 0; ++ ++ else ++ ++ i++; ++ ++ } ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scwiros ++ * ++ * Description: Sample the SCSI Signal lines making sure the signal has been ++ * deasserted for the correct number of consecutive samples. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scwiros(USHORT p_port, UCHAR p_data_bit) ++#else ++void scwiros(ULONG p_port, UCHAR p_data_bit) ++#endif ++{ ++ UCHAR i; ++ ++ i = 0; ++ while ( i < MAX_SCSI_TAR ) { ++ ++ if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit) ++ ++ i = 0; ++ ++ else ++ ++ i++; ++ ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scvalq ++ * ++ * Description: Make sure we received a valid data byte. ++ * ++ *---------------------------------------------------------------------*/ ++ ++UCHAR scvalq(UCHAR p_quintet) ++{ ++ UCHAR count; ++ ++ for (count=1; count < 0x08; count<<=1) { ++ if (!(p_quintet & count)) ++ p_quintet -= 0x80; ++ } ++ ++ if (p_quintet & 0x18) ++ return(FALSE); ++ ++ else ++ return(TRUE); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scsell ++ * ++ * Description: Select the specified device ID using a selection timeout ++ * less than 4ms. If somebody responds then it is a legacy ++ * drive and this ID must be marked as such. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++UCHAR scsell(USHORT p_port, UCHAR targ_id) ++#else ++UCHAR scsell(ULONG p_port, UCHAR targ_id) ++#endif ++{ ++#if defined(DOS) ++ USHORT i; ++#else ++ ULONG i; ++#endif ++ ++ 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)); ++ WR_HARPOON(p_port+hp_seltimeout,TO_4ms); ++ ++ ++ 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) ++ Wait(p_port, TO_250ms); ++ ++ 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)); ++ ++ return(FALSE); /*No legacy device */ ++ } ++ ++ 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)); ++ ++ return(TRUE); /*Found one of them oldies! */ ++ } ++} ++ ++#if defined(DOS) ++/*--------------------------------------------------------------------- ++ * ++ * Function: scsell for DOS ++ * ++ * Description: Select the specified device ID using a selection timeout ++ * less than 2ms. This was specially required to solve ++ * the problem with Plextor 12X CD-ROM drive. This drive ++ * was responding the Selection at the end of 4ms and ++ * hanging the system. ++ * ++ *---------------------------------------------------------------------*/ ++ ++UCHAR scsellDOS(USHORT p_port, UCHAR targ_id) ++{ ++ USHORT i; ++ ++ 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)); ++ WR_HARPOON(p_port+hp_seltimeout,TO_2ms); ++ ++ ++ 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) ++ Wait(p_port, TO_250ms); ++ ++ 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)); ++ ++ return(FALSE); /*No legacy device */ ++ } ++ ++ 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)); ++ ++ return(TRUE); /*Found one of them oldies! */ ++ } ++} ++#endif /* DOS */ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scwtsel ++ * ++ * Description: Wait to be selected by another SCAM initiator. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scwtsel(USHORT p_port) ++#else ++void scwtsel(ULONG p_port) ++#endif ++{ ++ while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {} ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: inisci ++ * ++ * Description: Setup the data Structure with the info from the EEPROM. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id) ++#else ++void inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id) ++#endif ++{ ++ UCHAR i,k,max_id; ++ USHORT ee_data; ++ PNVRamInfo pCurrNvRam; ++ ++ pCurrNvRam = BL_Card[p_card].pNvRamInfo; ++ ++ 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++) ++ scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k]; ++ for(k = 4; k < ID_STRING_LENGTH; k++) ++ scamInfo[i].id_string[k] = (UCHAR) 0x00; ++ ++ if(scamInfo[i].id_string[0] == 0x00) ++ scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ ++ else ++ scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ ++ ++ } ++ }else { ++ for (i=0; i < max_id; i++) ++ { ++ for (k=0; k < ID_STRING_LENGTH; k+=2) ++ { ++ ee_data = utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) + ++ (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2))); ++ scamInfo[i].id_string[k] = (UCHAR) ee_data; ++ ee_data >>= 8; ++ scamInfo[i].id_string[k+1] = (UCHAR) ee_data; ++ } ++ ++ if ((scamInfo[i].id_string[0] == 0x00) || ++ (scamInfo[i].id_string[0] == 0xFF)) ++ ++ scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */ ++ ++ else ++ scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */ ++ ++ } ++ } ++ for(k = 0; k < ID_STRING_LENGTH; k++) ++ scamInfo[p_our_id].id_string[k] = scamHAString[k]; ++ ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scmachid ++ * ++ * Description: Match the Device ID string with our values stored in ++ * the EEPROM. ++ * ++ *---------------------------------------------------------------------*/ ++ ++UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]) ++{ ++ ++ UCHAR i,k,match; ++ ++ ++ for (i=0; i < MAX_SCSI_TAR; i++) { ++ ++#if !defined(SCAM_LEV_2) ++ if (scamInfo[i].state == ID_UNASSIGNED) ++ { ++#endif ++ match = TRUE; ++ ++ for (k=0; k < ID_STRING_LENGTH; k++) ++ { ++ if (p_id_string[k] != scamInfo[i].id_string[k]) ++ match = FALSE; ++ } ++ ++ if (match) ++ { ++ scamInfo[i].state = ID_ASSIGNED; ++ return(i); ++ } ++ ++#if !defined(SCAM_LEV_2) ++ } ++#endif ++ ++ } ++ ++ ++ ++ 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)) ++ match = p_id_string[1] & (UCHAR) 0x1F; ++ else ++ match = 7; ++ ++ while (i > 0) ++ { ++ i--; ++ ++ if (scamInfo[match].state == ID_UNUSED) ++ { ++ for (k=0; k < ID_STRING_LENGTH; k++) ++ { ++ scamInfo[match].id_string[k] = p_id_string[k]; ++ } ++ ++ scamInfo[match].state = ID_ASSIGNED; ++ ++ if(BL_Card[p_card].pNvRamInfo == NULL) ++ BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM; ++ 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)) ++ match = p_id_string[1] & (UCHAR) 0x1F; ++ else ++ match = 7; ++ ++ while (i > 0) ++ { ++ ++ i--; ++ ++ if (scamInfo[match].state == ID_UNASSIGNED) ++ { ++ for (k=0; k < ID_STRING_LENGTH; k++) ++ { ++ scamInfo[match].id_string[k] = p_id_string[k]; ++ } ++ ++ scamInfo[match].id_string[0] |= BIT(7); ++ scamInfo[match].state = ID_ASSIGNED; ++ if(BL_Card[p_card].pNvRamInfo == NULL) ++ BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM; ++ 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); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: scsavdi ++ * ++ * Description: Save off the device SCAM ID strings. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void scsavdi(UCHAR p_card, USHORT p_port) ++#else ++void scsavdi(UCHAR p_card, ULONG p_port) ++#endif ++{ ++ UCHAR i,k,max_id; ++ USHORT ee_data,sum_data; ++ ++ ++ sum_data = 0x0000; ++ ++ for (i = 1; i < EE_SCAMBASE/2; i++) ++ { ++ sum_data += utilEERead(p_port, i); ++ } ++ ++ ++ utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */ ++ ++ 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) ++ { ++ ee_data = scamInfo[i].id_string[k+1]; ++ ee_data <<= 8; ++ ee_data |= scamInfo[i].id_string[k]; ++ sum_data += ee_data; ++ utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) + ++ (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2))); ++ } ++ } ++ ++ ++ utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2); ++ utilEEWriteOnOff(p_port,0); /* Turn off write access */ ++} ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: diagnose.c $ ++ * ++ * Description: Diagnostic funtions for testing the integrity of ++ * the HARPOON. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <eeprom.h>*/ ++/*#include <harpoon.h>*/ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: XbowInit ++ * ++ * Description: Setup the Xbow for normal operation. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void XbowInit(USHORT port, UCHAR ScamFlg) ++#else ++void XbowInit(ULONG port, UCHAR ScamFlg) ++#endif ++{ ++UCHAR i; ++ ++ i = RD_HARPOON(port+hp_page_ctrl); ++ WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE)); ++ ++ 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); ++ ++#if defined(SCAM_LEV_2) ++ default_intena = RESET | RSEL | PROG_HLT | TIMEOUT | ++ BUS_FREE | XFER_CNT_0 | AUTO_INT; ++ ++ if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) ++ default_intena |= SCAM_SEL; ++ ++#else ++ default_intena = RESET | RSEL | PROG_HLT | TIMEOUT | ++ BUS_FREE | XFER_CNT_0 | AUTO_INT; ++#endif ++ WRW_HARPOON((port+hp_intena), default_intena); ++ ++ 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); ++ ++#if defined(NO_BIOS_OPTION) ++ ++ WR_HARPOON(port+hp_synctarg_0,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_1,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_2,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_3,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_4,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_5,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_6,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_7,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_8,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_9,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_10,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_11,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_12,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_13,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_14,NARROW_SCSI); ++ WR_HARPOON(port+hp_synctarg_15,NARROW_SCSI); ++ ++#endif ++ WR_HARPOON(port+hp_page_ctrl, i); ++ ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: BusMasterInit ++ * ++ * Description: Initialize the BusMaster for normal operations. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void BusMasterInit(USHORT p_port) ++#else ++void BusMasterInit(ULONG p_port) ++#endif ++{ ++ ++ ++ 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)); ++ ++ ++#if defined(NT) ++ ++ WR_HARPOON(p_port+hp_pci_cmd_cfg, (RD_HARPOON(p_port+hp_pci_cmd_cfg) ++ & ~MEM_SPACE_ENA)); ++ ++#endif ++ ++ 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)); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: DiagXbow ++ * ++ * Description: Test Xbow integrity. Non-zero return indicates an error. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++int DiagXbow(USHORT port) ++#else ++int DiagXbow(ULONG port) ++#endif ++{ ++ unsigned char fifo_cnt,loop_cnt; ++ ++ unsigned char fifodata[5]; ++ fifodata[0] = 0x00; ++ fifodata[1] = 0xFF; ++ fifodata[2] = 0x55; ++ fifodata[3] = 0xAA; ++ fifodata[4] = 0x00; ++ ++ ++ WRW_HARPOON((port+hp_intstat), CLR_ALL_INT); ++ WRW_HARPOON((port+hp_intena), 0x0000); ++ ++ WR_HARPOON(port+hp_seltimeout,TO_5ms); ++ ++ WR_HARPOON(port+hp_portctrl_0,START_TO); ++ ++ ++ for(fifodata[4] = 0x01; fifodata[4] != (UCHAR) 0; fifodata[4] = fifodata[4] << 1) { ++ ++ WR_HARPOON(port+hp_selfid_0,fifodata[4]); ++ WR_HARPOON(port+hp_selfid_1,fifodata[4]); ++ ++ if ((RD_HARPOON(port+hp_selfid_0) != fifodata[4]) || ++ (RD_HARPOON(port+hp_selfid_1) != fifodata[4])) ++ return(1); ++ } ++ ++ ++ for(loop_cnt = 0; loop_cnt < 4; loop_cnt++) { ++ ++ WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | HOST_WRT | START_TO)); ++ ++ ++ for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) { ++ ++ WR_HARPOON(port+hp_fifodata_0, fifodata[loop_cnt]); ++ } ++ ++ ++ if (!(RD_HARPOON(port+hp_xferstat) & FIFO_FULL)) ++ return(1); ++ ++ ++ WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | START_TO)); ++ ++ for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) { ++ ++ if (RD_HARPOON(port+hp_fifodata_0) != fifodata[loop_cnt]) ++ return(1); ++ } ++ ++ ++ if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ++ return(1); ++ } ++ ++ ++ while(!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {} ++ ++ ++ WR_HARPOON(port+hp_seltimeout,TO_290ms); ++ ++ WRW_HARPOON((port+hp_intstat), CLR_ALL_INT); ++ ++ WRW_HARPOON((port+hp_intena), default_intena); ++ ++ return(0); ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: DiagBusMaster ++ * ++ * Description: Test BusMaster integrity. Non-zero return indicates an ++ * error. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++int DiagBusMaster(USHORT port) ++#else ++int DiagBusMaster(ULONG port) ++#endif ++{ ++ UCHAR testdata; ++ ++ for(testdata = (UCHAR) 1; testdata != (UCHAR)0; testdata = testdata << 1) { ++ ++ WR_HARPOON(port+hp_xfer_cnt_lo,testdata); ++ WR_HARPOON(port+hp_xfer_cnt_mi,testdata); ++ WR_HARPOON(port+hp_xfer_cnt_hi,testdata); ++ WR_HARPOON(port+hp_host_addr_lo,testdata); ++ WR_HARPOON(port+hp_host_addr_lmi,testdata); ++ WR_HARPOON(port+hp_host_addr_hmi,testdata); ++ WR_HARPOON(port+hp_host_addr_hi,testdata); ++ ++ if ((RD_HARPOON(port+hp_xfer_cnt_lo) != testdata) || ++ (RD_HARPOON(port+hp_xfer_cnt_mi) != testdata) || ++ (RD_HARPOON(port+hp_xfer_cnt_hi) != testdata) || ++ (RD_HARPOON(port+hp_host_addr_lo) != testdata) || ++ (RD_HARPOON(port+hp_host_addr_lmi) != testdata) || ++ (RD_HARPOON(port+hp_host_addr_hmi) != testdata) || ++ (RD_HARPOON(port+hp_host_addr_hi) != testdata)) ++ ++ return(1); ++ } ++ RD_HARPOON(port+hp_int_status); /*Clear interrupts. */ ++ return(0); ++} ++ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: DiagEEPROM ++ * ++ * Description: Verfiy checksum and 'Key' and initialize the EEPROM if ++ * neccessary. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void DiagEEPROM(USHORT p_port) ++#else ++void DiagEEPROM(ULONG p_port) ++#endif ++ ++{ ++ USHORT index,temp,max_wd_cnt; ++ ++ 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; ++ ++ temp = utilEERead(p_port, FW_SIGNATURE/2); ++ ++ if (temp == 0x4641) { ++ ++ for (index = 2; index < max_wd_cnt; index++) { ++ ++ temp += utilEERead(p_port, index); ++ ++ } ++ ++ if (temp == utilEERead(p_port, EEPROM_CHECK_SUM/2)) { ++ ++ return; /*EEPROM is Okay so return now! */ ++ } ++ } ++ ++ ++ utilEEWriteOnOff(p_port,(UCHAR)1); ++ ++ for (index = 0; index < max_wd_cnt; index++) { ++ ++ utilEEWrite(p_port, 0x0000, index); ++ } ++ ++ temp = 0; ++ ++ utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2); ++ temp += 0x4641; ++ utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2); ++ temp += 0x3920; ++ utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2); ++ temp += 0x3033; ++ utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2); ++ temp += 0x2020; ++ utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2); ++ temp += 0x70D3; ++ utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2); ++ temp += 0x0010; ++ utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2); ++ temp += 0x0003; ++ utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2); ++ temp += 0x0007; ++ ++ utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2); ++ temp += 0x0000; ++ utilEEWrite(p_port, 0x0000, SEND_START_ENA/2); ++ temp += 0x0000; ++ utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2); ++ temp += 0x0000; ++ ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2); ++ temp += 0x4242; ++ utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2); ++ temp += 0x4242; ++ ++ ++ utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */ ++ temp += 0x6C46; ++ utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */ ++ temp += 0x7361; ++ utilEEWrite(p_port, 0x5068, 68/2); ++ temp += 0x5068; ++ utilEEWrite(p_port, 0x696F, 70/2); ++ temp += 0x696F; ++ utilEEWrite(p_port, 0x746E, 72/2); ++ temp += 0x746E; ++ utilEEWrite(p_port, 0x4C20, 74/2); ++ temp += 0x4C20; ++ utilEEWrite(p_port, 0x2054, 76/2); ++ temp += 0x2054; ++ utilEEWrite(p_port, 0x2020, 78/2); ++ temp += 0x2020; ++ ++ index = ((EE_SCAMBASE/2)+(7*16)); ++ utilEEWrite(p_port, (0x0700+TYPE_CODE0), index); ++ temp += (0x0700+TYPE_CODE0); ++ index++; ++ utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */ ++ temp += 0x5542; /* BUSLOGIC */ ++ index++; ++ utilEEWrite(p_port, 0x4C53, index); ++ temp += 0x4C53; ++ index++; ++ utilEEWrite(p_port, 0x474F, index); ++ temp += 0x474F; ++ index++; ++ utilEEWrite(p_port, 0x4349, index); ++ temp += 0x4349; ++ index++; ++ utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */ ++ temp += 0x5442; /* BT- 930 */ ++ index++; ++ utilEEWrite(p_port, 0x202D, index); ++ temp += 0x202D; ++ index++; ++ utilEEWrite(p_port, 0x3339, index); ++ temp += 0x3339; ++ index++; /*Serial # */ ++ utilEEWrite(p_port, 0x2030, index); /* 01234567 */ ++ temp += 0x2030; ++ index++; ++ utilEEWrite(p_port, 0x5453, index); ++ temp += 0x5453; ++ index++; ++ utilEEWrite(p_port, 0x5645, index); ++ temp += 0x5645; ++ index++; ++ utilEEWrite(p_port, 0x2045, index); ++ temp += 0x2045; ++ index++; ++ utilEEWrite(p_port, 0x202F, index); ++ temp += 0x202F; ++ index++; ++ utilEEWrite(p_port, 0x4F4A, index); ++ temp += 0x4F4A; ++ index++; ++ utilEEWrite(p_port, 0x204E, index); ++ temp += 0x204E; ++ index++; ++ utilEEWrite(p_port, 0x3539, index); ++ temp += 0x3539; ++ ++ ++ ++ utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2); ++ ++ utilEEWriteOnOff(p_port,(UCHAR)0); ++ ++} ++ ++ ++/*---------------------------------------------------------------------- ++ * ++ * ++ * 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. ++ * ++ * $Workfile: utility.c $ ++ * ++ * Description: Utility functions relating to queueing and EEPROM ++ * manipulation and any other garbage functions. ++ * ++ * $Date: 1999/04/26 05:53:56 $ ++ * ++ * $Revision: 1.1 $ ++ * ++ *----------------------------------------------------------------------*/ ++/*#include <globals.h>*/ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ /*#include <budi.h>*/ ++#endif ++ ++/*#include <sccbmgr.h>*/ ++/*#include <blx30.h>*/ ++/*#include <target.h>*/ ++/*#include <scsi2.h>*/ ++/*#include <harpoon.h>*/ ++ ++ ++/* ++extern SCCBCARD BL_Card[MAX_CARDS]; ++extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR]; ++extern unsigned int SccbGlobalFlags; ++*/ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Queue Search Select ++ * ++ * Description: Try to find a new command to execute. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card) ++{ ++ UCHAR scan_ptr, lun; ++ PSCCBMgr_tar_info currTar_Info; ++ PSCCB pOldSccb; ++ ++ scan_ptr = pCurrCard->scanIndex; ++ do ++ { ++ currTar_Info = &sccbMgrTbl[p_card][scan_ptr]; ++ 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++) ++ { ++ if(currTar_Info->TarLUNBusy[lun] == FALSE) ++ { ++ ++ pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head; ++ pOldSccb = NULL; ++ ++ while((pCurrCard->currentSCCB != NULL) && ++ (lun != pCurrCard->currentSCCB->Lun)) ++ { ++ pOldSccb = pCurrCard->currentSCCB; ++ pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)-> ++ Sccb_forwardlink; ++ } ++ if(pCurrCard->currentSCCB == NULL) ++ continue; ++ if(pOldSccb != NULL) ++ { ++ pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)-> ++ Sccb_forwardlink; ++ pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)-> ++ Sccb_backlink; ++ currTar_Info->TarSelQ_Cnt--; ++ } ++ else ++ { ++ currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink; ++ ++ if (currTar_Info->TarSelQ_Head == NULL) ++ { ++ currTar_Info->TarSelQ_Tail = NULL; ++ currTar_Info->TarSelQ_Cnt = 0; ++ } ++ else ++ { ++ currTar_Info->TarSelQ_Cnt--; ++ currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL; ++ } ++ } ++ 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) && ++ (currTar_Info->TarLUNBusy[0] == FALSE)) ++ { ++ ++ pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head; ++ ++ currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink; ++ ++ if (currTar_Info->TarSelQ_Head == NULL) ++ { ++ currTar_Info->TarSelQ_Tail = NULL; ++ currTar_Info->TarSelQ_Cnt = 0; ++ } ++ else ++ { ++ currTar_Info->TarSelQ_Cnt--; ++ currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL; ++ } ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card) ++{ ++ UCHAR thisTarg; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ if (pCurrCard->currentSCCB != NULL) ++ { ++ thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID); ++ currTar_Info = &sccbMgrTbl[p_card][thisTarg]; ++ ++ pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL; ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb, UCHAR p_card) ++{ ++ ++#if (FW_TYPE==_UCB_MGR_) ++ ++ u08bits SCSIcmd; ++ CALL_BK_FN callback; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ PUCB p_ucb; ++ p_ucb=p_sccb->Sccb_ucb_ptr; ++ ++ SCSIcmd = p_sccb->Cdb[0]; ++ ++ ++ if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) ++ { ++ ++ if ((p_ucb->UCB_opcode & OPC_CHK_UNDER_OVER_RUN) && ++ (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; ++ } ++ ++ p_ucb->UCB_status=SCCB_SUCCESS; ++ ++ if ((p_ucb->UCB_hbastat=p_sccb->HostStatus) || (p_ucb->UCB_scsistat=p_sccb->TargetStatus)) ++ { ++ p_ucb->UCB_status=SCCB_ERROR; ++ } ++ ++ if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) || ++ (p_sccb->OperationCode == RESIDUAL_COMMAND)) ++ { ++ ++ utilUpdateResidual(p_sccb); ++ ++ p_ucb->UCB_datalen=p_sccb->DataLength; ++ } ++ ++ 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) ++ { ++ currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID]; ++ 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_ucb->UCB_callback; ++ callback(p_ucb); ++ pCurrCard->globalFlags |= F_NEW_SCCB_CMD; ++ pCurrCard->currentSCCB = NULL; ++} ++ ++ ++ ++ ++#else ++ ++ UCHAR i, SCSIcmd; ++ 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)) { ++ ++ utilUpdateResidual(p_sccb); ++ } ++ ++ 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) ++ { ++ currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID]; ++ 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; ++} ++#endif /* ( if FW_TYPE==...) */ ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Queue Disconnect ++ * ++ * Description: Add SCCB to our disconnect array. ++ * ++ *---------------------------------------------------------------------*/ ++void queueDisconnect(PSCCB p_sccb, UCHAR p_card) ++{ ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID]; ++ ++ if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) && ++ ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) ++ { ++ BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb; ++ } ++ else ++ { ++ if (p_sccb->Sccb_tag) ++ { ++ BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb; ++ sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = FALSE; ++ sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++; ++ }else ++ { ++ BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb; ++ } ++ } ++ BL_Card[p_card].currentSCCB = NULL; ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Queue Flush SCCB ++ * ++ * Description: Flush all SCCB's back to the host driver for this target. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void queueFlushSccb(UCHAR p_card, UCHAR error_code) ++{ ++ UCHAR qtag,thisTarg; ++ PSCCB currSCCB; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currSCCB = BL_Card[p_card].currentSCCB; ++ if(currSCCB != NULL) ++ { ++ thisTarg = (UCHAR)currSCCB->TargID; ++ currTar_Info = &sccbMgrTbl[p_card][thisTarg]; ++ ++ for (qtag=0; qtag<QUEUE_DEPTH; qtag++) { ++ ++ if (BL_Card[p_card].discQ_Tbl[qtag] && ++ (BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) ++ { ++ ++ BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code; ++ ++ queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card); ++ ++ BL_Card[p_card].discQ_Tbl[qtag] = NULL; ++ currTar_Info->TarTagQ_Cnt--; ++ ++ } ++ } ++ } ++ ++} ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Queue Flush Target SCCB ++ * ++ * Description: Flush all SCCB's back to the host driver for this target. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code) ++{ ++ UCHAR qtag; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currTar_Info = &sccbMgrTbl[p_card][thisTarg]; ++ ++ for (qtag=0; qtag<QUEUE_DEPTH; qtag++) { ++ ++ if (BL_Card[p_card].discQ_Tbl[qtag] && ++ (BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) ++ { ++ ++ BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code; ++ ++ queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card); ++ ++ BL_Card[p_card].discQ_Tbl[qtag] = NULL; ++ currTar_Info->TarTagQ_Cnt--; ++ ++ } ++ } ++ ++} ++ ++ ++ ++ ++ ++void queueAddSccb(PSCCB p_SCCB, UCHAR p_card) ++{ ++ PSCCBMgr_tar_info currTar_Info; ++ currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID]; ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card) ++{ ++ PSCCB q_ptr; ++ PSCCBMgr_tar_info currTar_Info; ++ ++ currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID]; ++ ++ 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--; ++ ++ return(TRUE); ++ } ++ ++ else { ++ q_ptr = q_ptr->Sccb_forwardlink; ++ } ++ } ++ ++ ++ return(FALSE); ++ ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++void utilUpdateResidual(PSCCB p_SCCB) ++{ ++ ULONG partial_cnt; ++ UINT sg_index; ++#if defined(COMPILER_16_BIT) && !defined(DOS) ++ ULONG far *sg_ptr; ++#else ++ ULONG *sg_ptr; ++#endif ++ ++ 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; ++ ++#if defined(COMPILER_16_BIT) && !defined(DOS) ++ sg_ptr = (ULONG far *)p_SCCB->DataPointer; ++#else ++ sg_ptr = (ULONG *)p_SCCB->DataPointer; ++#endif ++ ++ if (p_SCCB->Sccb_SGoffset) { ++ ++ partial_cnt = p_SCCB->Sccb_SGoffset; ++ sg_index++; ++ } ++ ++ while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) < ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void Wait1Second(USHORT p_port) ++#else ++void Wait1Second(ULONG p_port) ++#endif ++{ ++ UCHAR i; ++ ++ for(i=0; i < 4; i++) { ++ ++ Wait(p_port, TO_250ms); ++ ++ if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST)) ++ break; ++ ++ if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) ++ break; ++ } ++} ++ ++ ++/*--------------------------------------------------------------------- ++ * ++ * Function: Wait ++ * ++ * Description: Wait the desired delay. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void Wait(USHORT p_port, UCHAR p_delay) ++#else ++void Wait(ULONG p_port, UCHAR p_delay) ++#endif ++{ ++ UCHAR old_timer; ++ UCHAR green_flag; ++ ++ 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); ++ WRW_HARPOON((p_port+hp_intena), (default_intena & ~TIMEOUT)); ++ ++ ++ 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); ++ WRW_HARPOON((p_port+hp_intena), default_intena); ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode) ++#else ++void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode) ++#endif ++{ ++ UCHAR ee_value; ++ ++ ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H)); ++ ++ if (p_mode) ++ ++ utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR); ++ ++ else ++ ++ ++ utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR); ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr) ++#else ++void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr) ++#endif ++{ ++ ++ UCHAR ee_value; ++ USHORT i; ++ ++ ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))| ++ (SEE_MS | SEE_CS)); ++ ++ ++ ++ utilEESendCmdAddr(p_port, EE_WRITE, ee_addr); ++ ++ ++ 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)); ++ ++ Wait(p_port, TO_10ms); ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++USHORT utilEERead(USHORT p_port, USHORT ee_addr) ++#else ++USHORT utilEERead(ULONG p_port, USHORT ee_addr) ++#endif ++{ ++ USHORT i, ee_data1, ee_data2; ++ ++ i = 0; ++ ee_data1 = utilEEReadOrg(p_port, ee_addr); ++ do ++ { ++ ee_data2 = utilEEReadOrg(p_port, ee_addr); ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr) ++#else ++USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr) ++#endif ++{ ++ ++ UCHAR ee_value; ++ USHORT i, ee_data; ++ ++ ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))| ++ (SEE_MS | SEE_CS)); ++ ++ ++ utilEESendCmdAddr(p_port, EE_READ, ee_addr); ++ ++ ++ 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. ++ * ++ *---------------------------------------------------------------------*/ ++ ++#if defined(DOS) ++void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr) ++#else ++void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr) ++#endif ++{ ++ UCHAR ee_value; ++ UCHAR narrow_flg; ++ ++ USHORT i; ++ ++ ++ narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD); ++ ++ ++ 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; ++ } ++} ++ ++USHORT CalcCrc16(UCHAR buffer[]) ++{ ++ USHORT crc=0; ++ int i,j; ++ USHORT ch; ++ for (i=0; i < ID_STRING_LENGTH; i++) ++ { ++ ch = (USHORT) buffer[i]; ++ for(j=0; j < 8; j++) ++ { ++ if ((crc ^ ch) & 1) ++ crc = (crc >> 1) ^ CRCMASK; ++ else ++ crc >>= 1; ++ ch >>= 1; ++ } ++ } ++ return(crc); ++} ++ ++UCHAR CalcLrc(UCHAR buffer[]) ++{ ++ int i; ++ UCHAR lrc; ++ 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(FlashPoint_Info_T *FlashPointInfo) ++{ ++ return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo); ++} ++ ++ ++static inline FlashPoint_CardHandle_T ++FlashPoint__HardwareResetHostAdapter(FlashPoint_Info_T *FlashPointInfo) ++{ ++ return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo); ++} ++ ++static inline void ++FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle) ++{ ++ FlashPoint_ReleaseHostAdapter(CardHandle); ++} ++ ++ ++static inline void ++FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB) ++{ ++ FlashPoint_StartCCB(CardHandle, (PSCCB) CCB); ++} ++ ++ ++static inline void ++FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, BusLogic_CCB_T *CCB) ++{ ++ FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB); ++} ++ ++ ++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 ++ ++ ++/* ++ FlashPoint_InquireTargetInfo returns the Synchronous Period, Synchronous ++ Offset, and Wide Transfers Active information for TargetID on CardHandle. ++*/ ++ ++void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T CardHandle, ++ int TargetID, ++ unsigned char *SynchronousPeriod, ++ unsigned char *SynchronousOffset, ++ unsigned char *WideTransfersActive) ++{ ++ SCCBMGR_TAR_INFO *TargetInfo = ++ &sccbMgrTbl[((SCCBCARD *)CardHandle)->cardIndex][TargetID]; ++ if ((TargetInfo->TarSyncCtrl & SYNC_OFFSET) > 0) ++ { ++ *SynchronousPeriod = 5 * ((TargetInfo->TarSyncCtrl >> 5) + 1); ++ *SynchronousOffset = TargetInfo->TarSyncCtrl & SYNC_OFFSET; ++ } ++ else ++ { ++ *SynchronousPeriod = 0; ++ *SynchronousOffset = 0; ++ } ++ *WideTransfersActive = (TargetInfo->TarSyncCtrl & NARROW_SCSI ? 0 : 1); ++} ++ ++ ++#else /* CONFIG_SCSI_OMIT_FLASHPOINT */ ++ ++ ++/* ++ Define prototypes for the FlashPoint SCCB Manager Functions. ++*/ ++ ++extern unsigned char FlashPoint_ProbeHostAdapter(FlashPoint_Info_T *); ++extern FlashPoint_CardHandle_T ++ FlashPoint_HardwareResetHostAdapter(FlashPoint_Info_T *); ++extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *); ++extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, BusLogic_CCB_T *); ++extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T); ++extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); ++extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); ++extern void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T, ++ int, unsigned char *, ++ unsigned char *, unsigned char *); ++ ++ ++#endif /* CONFIG_SCSI_OMIT_FLASHPOINT */ +diff --git a/linux/src/drivers/scsi/eata_pio_proc.c b/linux/src/drivers/scsi/eata_pio_proc.c +new file mode 100644 +index 0000000..54783f2 +--- /dev/null ++++ b/linux/src/drivers/scsi/eata_pio_proc.c +@@ -0,0 +1,135 @@ ++ ++/* ++ * eata_set_info ++ * buffer : pointer to the data that has been written to the hostfile ++ * length : number of bytes written to the hostfile ++ * HBA_ptr: pointer to the Scsi_Host struct ++ */ ++int eata_pio_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr) ++{ ++ DBG(DBG_PROC_WRITE, printk("%s\n", buffer)); ++ return(-ENOSYS); /* Currently this is a no-op */ ++} ++ ++/* ++ * eata_proc_info ++ * inout : decides on the direction of the dataflow and the meaning of the ++ * variables ++ * buffer: If inout==FALSE data is being written to it else read from it ++ * *start: If inout==FALSE start of the valid data in the buffer ++ * offset: If inout==FALSE offset from the beginning of the imaginary file ++ * from which we start writing into the buffer ++ * length: If inout==FALSE max number of bytes to be written into the buffer ++ * else number of bytes in the buffer ++ */ ++int eata_pio_proc_info(char *buffer, char **start, off_t offset, int length, ++ int hostno, int inout) ++{ ++ ++ Scsi_Device *scd; ++ struct Scsi_Host *HBA_ptr; ++ static u8 buff[512]; ++ int i; ++ int size, len = 0; ++ off_t begin = 0; ++ off_t pos = 0; ++ ++ HBA_ptr = first_HBA; ++ for (i = 1; i <= registered_HBAs; i++) { ++ if (HBA_ptr->host_no == hostno) ++ break; ++ HBA_ptr = SD(HBA_ptr)->next; ++ } ++ ++ if(inout == TRUE) /* Has data been written to the file ? */ ++ return(eata_pio_set_info(buffer, length, HBA_ptr)); ++ ++ if (offset == 0) ++ memset(buff, 0, sizeof(buff)); ++ ++ size = sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " ++ "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); ++ len += size; pos = begin + len; ++ size = sprintf(buffer + len, "queued commands: %10ld\n" ++ "processed interrupts:%10ld\n", queue_counter, int_counter); ++ len += size; pos = begin + len; ++ ++ size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", ++ HBA_ptr->host_no, SD(HBA_ptr)->name); ++ len += size; ++ pos = begin + len; ++ size = sprintf(buffer + len, "Firmware revision: v%s\n", ++ SD(HBA_ptr)->revision); ++ len += size; ++ pos = begin + len; ++ size = sprintf(buffer + len, "IO: PIO\n"); ++ len += size; ++ pos = begin + len; ++ size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base); ++ len += size; ++ pos = begin + len; ++ size = sprintf(buffer + len, "Host Bus: %s\n", ++ (SD(HBA_ptr)->bustype == 'P')?"PCI ": ++ (SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA "); ++ ++ len += size; ++ pos = begin + len; ++ ++ if (pos < offset) { ++ len = 0; ++ begin = pos; ++ } ++ if (pos > offset + length) ++ goto stop_output; ++ ++ scd = scsi_devices; ++ ++ size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none"); ++ len += size; ++ pos = begin + len; ++ ++ while (scd) { ++ if (scd->host == HBA_ptr) { ++ proc_print_scsidevice(scd, buffer, &size, len); ++ len += size; ++ pos = begin + len; ++ ++ if (pos < offset) { ++ len = 0; ++ begin = pos; ++ } ++ if (pos > offset + length) ++ goto stop_output; ++ } ++ scd = scd->next; ++ } ++ ++ stop_output: ++ DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); ++ *start=buffer+(offset-begin); /* Start of wanted data */ ++ len-=(offset-begin); /* Start slop */ ++ if(len>length) ++ len = length; /* Ending slop */ ++ DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); ++ ++ return (len); ++} ++ ++/* ++ * Overrides for Emacs so that we follow Linus's tabbing style. ++ * Emacs will notice this stuff at the end of the file and automatically ++ * adjust the settings for this buffer only. This must remain at the end ++ * of the file. ++ * --------------------------------------------------------------------------- ++ * Local variables: ++ * c-indent-level: 4 ++ * c-brace-imaginary-offset: 0 ++ * c-brace-offset: -4 ++ * c-argdecl-indent: 4 ++ * c-label-offset: -4 ++ * c-continued-statement-offset: 4 ++ * c-continued-brace-offset: 0 ++ * tab-width: 8 ++ * End: ++ */ ++ +diff --git a/linux/src/drivers/scsi/scsiiom.c b/linux/src/drivers/scsi/scsiiom.c +new file mode 100644 +index 0000000..97801d7 +--- /dev/null ++++ b/linux/src/drivers/scsi/scsiiom.c +@@ -0,0 +1,1540 @@ ++/*********************************************************************** ++ * FILE NAME : SCSIIOM.C * ++ * BY : C.L. Huang, ching@tekram.com.tw * ++ * Description: Device Driver for Tekram DC-390 (T) PCI SCSI * ++ * Bus Master Host Adapter * ++ ***********************************************************************/ ++ ++ ++static USHORT ++DC390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ) ++{ ++ USHORT ioport, rc; ++ UCHAR bval, bval1, i, cnt; ++ PUCHAR ptr; ++ ULONG wlval; ++ ++ pSRB->TagNumber = 31; ++ ioport = pACB->IOPortBase; ++ bval = pDCB->UnitSCSIID; ++ outb(bval,ioport+Scsi_Dest_ID); ++ bval = pDCB->SyncPeriod; ++ outb(bval,ioport+Sync_Period); ++ bval = pDCB->SyncOffset; ++ outb(bval,ioport+Sync_Offset); ++ bval = pDCB->CtrlR1; ++ outb(bval,ioport+CtrlReg1); ++ bval = pDCB->CtrlR3; ++ outb(bval,ioport+CtrlReg3); ++ bval = pDCB->CtrlR4; ++ outb(bval,ioport+CtrlReg4); ++ bval = CLEAR_FIFO_CMD; /* Flush FIFO */ ++ outb(bval,ioport+ScsiCmd); ++ ++ pSRB->ScsiPhase = SCSI_NOP0; ++ bval = pDCB->IdentifyMsg; ++ if( !(pDCB->SyncMode & EN_ATN_STOP) ) ++ { ++ if( (pSRB->CmdBlock[0] == INQUIRY) || ++ (pSRB->CmdBlock[0] == REQUEST_SENSE) || ++ (pSRB->SRBFlag & AUTO_REQSENSE) ) ++ { ++ bval &= 0xBF; /* NO disconnection */ ++ outb(bval,ioport+ScsiFifo); ++ bval1 = SELECT_W_ATN; ++ pSRB->SRBState = SRB_START_; ++ if( pDCB->SyncMode & SYNC_ENABLE ) ++ { ++ if( !(pDCB->IdentifyMsg & 7) || ++ (pSRB->CmdBlock[0] != INQUIRY) ) ++ { ++ bval1 = SEL_W_ATN_STOP; ++ pSRB->SRBState = SRB_MSGOUT; ++ } ++ } ++ } ++ else ++ { ++ if(pDCB->SyncMode & EN_TAG_QUEUING) ++ { ++ outb(bval,ioport+ScsiFifo); ++ bval = MSG_SIMPLE_QTAG; ++ outb(bval,ioport+ScsiFifo); ++ wlval = 1; ++ bval = 0; ++ while( wlval & pDCB->TagMask ) ++ { ++ wlval = wlval << 1; ++ bval++; ++ } ++ outb(bval,ioport+ScsiFifo); ++ pDCB->TagMask |= wlval; ++ pSRB->TagNumber = bval; ++ bval1 = SEL_W_ATN2; ++ pSRB->SRBState = SRB_START_; ++ } ++ else ++ { ++ outb(bval,ioport+ScsiFifo); ++ bval1 = SELECT_W_ATN; ++ pSRB->SRBState = SRB_START_; ++ } ++ } ++ ++ if( pSRB->SRBFlag & AUTO_REQSENSE ) ++ { ++ bval = REQUEST_SENSE; ++ outb(bval,ioport+ScsiFifo); ++ bval = pDCB->IdentifyMsg << 5; ++ outb(bval,ioport+ScsiFifo); ++ bval = 0; ++ outb(bval,ioport+ScsiFifo); ++ outb(bval,ioport+ScsiFifo); ++ bval = sizeof(pSRB->pcmd->sense_buffer); ++ outb(bval,ioport+ScsiFifo); ++ bval = 0; ++ outb(bval,ioport+ScsiFifo); ++ } ++ else ++ { ++ cnt = pSRB->ScsiCmdLen; ++ ptr = (PUCHAR) pSRB->CmdBlock; ++ for(i=0; i<cnt; i++) ++ { ++ bval = *ptr++; ++ outb(bval,ioport+ScsiFifo); ++ } ++ } ++ } ++ else /* ATN_STOP */ ++ { ++ if( (pSRB->CmdBlock[0] == INQUIRY) || ++ (pSRB->CmdBlock[0] == REQUEST_SENSE) || ++ (pSRB->SRBFlag & AUTO_REQSENSE) ) ++ { ++ bval &= 0xBF; ++ outb(bval,ioport+ScsiFifo); ++ bval1 = SELECT_W_ATN; ++ pSRB->SRBState = SRB_START_; ++ if( pDCB->SyncMode & SYNC_ENABLE ) ++ { ++ if( !(pDCB->IdentifyMsg & 7) || ++ (pSRB->CmdBlock[0] != INQUIRY) ) ++ { ++ bval1 = SEL_W_ATN_STOP; ++ pSRB->SRBState = SRB_MSGOUT; ++ } ++ } ++ } ++ else ++ { ++ if(pDCB->SyncMode & EN_TAG_QUEUING) ++ { ++ outb(bval,ioport+ScsiFifo); ++ pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG; ++ wlval = 1; ++ bval = 0; ++ while( wlval & pDCB->TagMask ) ++ { ++ wlval = wlval << 1; ++ bval++; ++ } ++ pDCB->TagMask |= wlval; ++ pSRB->TagNumber = bval; ++ pSRB->MsgOutBuf[1] = bval; ++ pSRB->MsgCnt = 2; ++ bval1 = SEL_W_ATN_STOP; ++ pSRB->SRBState = SRB_START_; ++ } ++ else ++ { ++ outb(bval,ioport+ScsiFifo); ++ pSRB->MsgOutBuf[0] = MSG_NOP; ++ pSRB->MsgCnt = 1; ++ pSRB->SRBState = SRB_START_; ++ bval1 = SEL_W_ATN_STOP; ++ } ++ } ++ } ++ bval = inb( ioport+Scsi_Status ); ++ if( bval & INTERRUPT ) ++ { ++ pSRB->SRBState = SRB_READY; ++ pDCB->TagMask &= ~( 1 << pSRB->TagNumber ); ++ rc = 1; ++ } ++ else ++ { ++ pSRB->ScsiPhase = SCSI_NOP1; ++ pACB->pActiveDCB = pDCB; ++ pDCB->pActiveSRB = pSRB; ++ rc = 0; ++ outb(bval1,ioport+ScsiCmd); ++ } ++ return( rc ); ++} ++ ++ ++#ifndef VERSION_ELF_1_2_13 ++static void ++DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs) ++#else ++static void ++DC390_Interrupt( int irq, struct pt_regs *regs) ++#endif ++{ ++ PACB pACB; ++ PDCB pDCB; ++ PSRB pSRB; ++ USHORT ioport = 0; ++ USHORT phase, i; ++ void (*stateV)( PACB, PSRB, PUCHAR ); ++ UCHAR istate = 0; ++ UCHAR sstatus=0, istatus; ++ ++ pACB = pACB_start; ++ if( pACB == NULL ) ++ return; ++ for( i=0; i < adapterCnt; i++ ) ++ { ++ if( pACB->IRQLevel == (UCHAR) irq ) ++ { ++ ioport = pACB->IOPortBase; ++ sstatus = inb( ioport+Scsi_Status ); ++ if( sstatus & INTERRUPT ) ++ break; ++ else ++ pACB = pACB->pNextACB; ++ } ++ else ++ { ++ pACB = pACB->pNextACB; ++ } ++ } ++ ++#ifdef DC390_DEBUG1 ++ printk("sstatus=%2x,",sstatus); ++#endif ++ ++ if( pACB == (PACB )-1 ) ++ { ++ printk("DC390: Spurious interrupt detected!\n"); ++ return; ++ } ++ ++ istate = inb( ioport+Intern_State ); ++ istatus = inb( ioport+INT_Status ); ++ ++#ifdef DC390_DEBUG1 ++ printk("Istatus=%2x,",istatus); ++#endif ++ ++ if(istatus & DISCONNECTED) ++ { ++ DC390_Disconnect( pACB ); ++ return; ++ } ++ ++ if(istatus & RESELECTED) ++ { ++ DC390_Reselect( pACB ); ++ return; ++ } ++ ++ if(istatus & INVALID_CMD) ++ { ++ DC390_InvalidCmd( pACB ); ++ return; ++ } ++ ++ if(istatus & SCSI_RESET) ++ { ++ DC390_ScsiRstDetect( pACB ); ++ return; ++ } ++ ++ if( istatus & (SUCCESSFUL_OP+SERVICE_REQUEST) ) ++ { ++ pDCB = pACB->pActiveDCB; ++ pSRB = pDCB->pActiveSRB; ++ if( pDCB ) ++ { ++ if( pDCB->DCBFlag & ABORT_DEV_ ) ++ EnableMsgOut( pACB, pSRB ); ++ } ++ ++ phase = (USHORT) pSRB->ScsiPhase; ++ stateV = (void *) DC390_phase0[phase]; ++ stateV( pACB, pSRB, &sstatus ); ++ ++ pSRB->ScsiPhase = sstatus & 7; ++ phase = (USHORT) sstatus & 7; ++ stateV = (void *) DC390_phase1[phase]; ++ stateV( pACB, pSRB, &sstatus ); ++ } ++} ++ ++ ++static void ++DC390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR sstatus, bval; ++ USHORT ioport; ++ PSGL psgl; ++ ULONG ResidCnt, xferCnt; ++ ++ ioport = pACB->IOPortBase; ++ sstatus = *psstatus; ++ ++ if( !(pSRB->SRBState & SRB_XFERPAD) ) ++ { ++ if( sstatus & PARITY_ERR ) ++ pSRB->SRBStatus |= PARITY_ERROR; ++ ++ if( sstatus & COUNT_2_ZERO ) ++ { ++ bval = inb(ioport+DMA_Status); ++ while( !(bval & DMA_XFER_DONE) ) ++ bval = inb(ioport+DMA_Status); ++ pSRB->TotalXferredLen += pSRB->SGToBeXferLen; ++ pSRB->SGIndex++; ++ if( pSRB->SGIndex < pSRB->SGcount ) ++ { ++ pSRB->pSegmentList++; ++ psgl = pSRB->pSegmentList; ++ ++#ifndef VERSION_ELF_1_2_13 ++ pSRB->SGPhysAddr = virt_to_phys( psgl->address ); ++#else ++ pSRB->SGPhysAddr = (ULONG) psgl->address; ++#endif ++ pSRB->SGToBeXferLen = (ULONG) psgl->length; ++ } ++ else ++ pSRB->SGToBeXferLen = 0; ++ } ++ else ++ { ++ bval = inb( ioport+Current_Fifo ); ++ bval &= 0x1f; ++ ResidCnt = (ULONG) inb(ioport+CtcReg_High); ++ ResidCnt = ResidCnt << 8; ++ ResidCnt |= (ULONG) inb(ioport+CtcReg_Mid); ++ ResidCnt = ResidCnt << 8; ++ ResidCnt |= (ULONG) inb(ioport+CtcReg_Low); ++ ResidCnt += (ULONG) bval; ++ ++ xferCnt = pSRB->SGToBeXferLen - ResidCnt; ++ pSRB->SGPhysAddr += xferCnt; ++ pSRB->TotalXferredLen += xferCnt; ++ pSRB->SGToBeXferLen = ResidCnt; ++ } ++ } ++ bval = WRITE_DIRECTION+DMA_IDLE_CMD; ++ outb( bval, ioport+DMA_Cmd); ++} ++ ++static void ++DC390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR sstatus, bval; ++ USHORT i, ioport, residual; ++ PSGL psgl; ++ ULONG ResidCnt, xferCnt; ++ PUCHAR ptr; ++ ++ ++ ioport = pACB->IOPortBase; ++ sstatus = *psstatus; ++ ++ if( !(pSRB->SRBState & SRB_XFERPAD) ) ++ { ++ if( sstatus & PARITY_ERR ) ++ pSRB->SRBStatus |= PARITY_ERROR; ++ ++ if( sstatus & COUNT_2_ZERO ) ++ { ++ bval = inb(ioport+DMA_Status); ++ while( !(bval & DMA_XFER_DONE) ) ++ bval = inb(ioport+DMA_Status); ++ ++ bval = READ_DIRECTION+DMA_IDLE_CMD; ++ outb( bval, ioport+DMA_Cmd); ++ ++ pSRB->TotalXferredLen += pSRB->SGToBeXferLen; ++ pSRB->SGIndex++; ++ if( pSRB->SGIndex < pSRB->SGcount ) ++ { ++ pSRB->pSegmentList++; ++ psgl = pSRB->pSegmentList; ++ ++#ifndef VERSION_ELF_1_2_13 ++ pSRB->SGPhysAddr = virt_to_phys( psgl->address ); ++#else ++ pSRB->SGPhysAddr = (ULONG) psgl->address; ++#endif ++ pSRB->SGToBeXferLen = (ULONG) psgl->length; ++ } ++ else ++ pSRB->SGToBeXferLen = 0; ++ } ++ else /* phase changed */ ++ { ++ residual = 0; ++ bval = inb(ioport+Current_Fifo); ++ while( bval & 0x1f ) ++ { ++ if( (bval & 0x1f) == 1 ) ++ { ++ for(i=0; i< 0x100; i++) ++ { ++ bval = inb(ioport+Current_Fifo); ++ if( !(bval & 0x1f) ) ++ goto din_1; ++ else if( i == 0x0ff ) ++ { ++ residual = 1; /* ;1 residual byte */ ++ goto din_1; ++ } ++ } ++ } ++ else ++ bval = inb(ioport+Current_Fifo); ++ } ++din_1: ++ bval = READ_DIRECTION+DMA_BLAST_CMD; ++ outb(bval, ioport+DMA_Cmd); ++ for(i=0; i<0x8000; i++) ++ { ++ bval = inb(ioport+DMA_Status); ++ if(bval & BLAST_COMPLETE) ++ break; ++ } ++ bval = READ_DIRECTION+DMA_IDLE_CMD; ++ outb(bval, ioport+DMA_Cmd); ++ ++ ResidCnt = (ULONG) inb(ioport+CtcReg_High); ++ ResidCnt = ResidCnt << 8; ++ ResidCnt |= (ULONG) inb(ioport+CtcReg_Mid); ++ ResidCnt = ResidCnt << 8; ++ ResidCnt |= (ULONG) inb(ioport+CtcReg_Low); ++ ++ xferCnt = pSRB->SGToBeXferLen - ResidCnt; ++ pSRB->SGPhysAddr += xferCnt; ++ pSRB->TotalXferredLen += xferCnt; ++ pSRB->SGToBeXferLen = ResidCnt; ++ ++ if( residual ) ++ { ++ bval = inb(ioport+ScsiFifo); /* get residual byte */ ++#ifndef VERSION_ELF_1_2_13 ++ ptr = (PUCHAR) phys_to_virt( pSRB->SGPhysAddr ); ++#else ++ ptr = (PUCHAR) pSRB->SGPhysAddr; ++#endif ++ *ptr = bval; ++ pSRB->SGPhysAddr++; ++ pSRB->TotalXferredLen++; ++ pSRB->SGToBeXferLen--; ++ } ++ } ++ } ++} ++ ++static void ++DC390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++} ++ ++static void ++DC390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR bval; ++ USHORT ioport; ++ ++ ioport = pACB->IOPortBase; ++ bval = inb(ioport+ScsiFifo); ++ pSRB->TargetStatus = bval; ++ bval++; ++ bval = inb(ioport+ScsiFifo); /* get message */ ++ pSRB->EndMessage = bval; ++ ++ *psstatus = SCSI_NOP0; ++ pSRB->SRBState = SRB_COMPLETED; ++ bval = MSG_ACCEPTED_CMD; ++ outb(bval, ioport+ScsiCmd); ++} ++ ++static void ++DC390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) ) ++ *psstatus = SCSI_NOP0; ++} ++ ++static void ++DC390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR bval; ++ USHORT ioport, wval, wval1; ++ PDCB pDCB; ++ PSRB psrb; ++ ++ ioport = pACB->IOPortBase; ++ pDCB = pACB->pActiveDCB; ++ ++ bval = inb( ioport+ScsiFifo ); ++ if( !(pSRB->SRBState & SRB_MSGIN_MULTI) ) ++ { ++ if(bval == MSG_DISCONNECT) ++ { ++ pSRB->SRBState = SRB_DISCONNECT; ++ } ++ else if( bval == MSG_SAVE_PTR ) ++ goto min6; ++ else if( (bval == MSG_EXTENDED) || ((bval >= MSG_SIMPLE_QTAG) && ++ (bval <= MSG_ORDER_QTAG)) ) ++ { ++ pSRB->SRBState |= SRB_MSGIN_MULTI; ++ pSRB->MsgInBuf[0] = bval; ++ pSRB->MsgCnt = 1; ++ pSRB->pMsgPtr = &pSRB->MsgInBuf[1]; ++ } ++ else if(bval == MSG_REJECT_) ++ { ++ bval = RESET_ATN_CMD; ++ outb(bval, ioport+ScsiCmd); ++ if( pSRB->SRBState & DO_SYNC_NEGO) ++ goto set_async; ++ } ++ else if( bval == MSG_RESTORE_PTR) ++ goto min6; ++ else ++ goto min6; ++ } ++ else ++ { /* minx: */ ++ ++ *pSRB->pMsgPtr = bval; ++ pSRB->MsgCnt++; ++ pSRB->pMsgPtr++; ++ if( (pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) && ++ (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG) ) ++ { ++ if( pSRB->MsgCnt == 2) ++ { ++ pSRB->SRBState = 0; ++ bval = pSRB->MsgInBuf[1]; ++ pSRB = pDCB->pGoingSRB; ++ psrb = pDCB->pGoingLast; ++ if( pSRB ) ++ { ++ for( ;; ) ++ { ++ if(pSRB->TagNumber != bval) ++ { ++ if( pSRB == psrb ) ++ goto mingx0; ++ pSRB = pSRB->pNextSRB; ++ } ++ else ++ break; ++ } ++ if( pDCB->DCBFlag & ABORT_DEV_ ) ++ { ++ pSRB->SRBState = SRB_ABORT_SENT; ++ EnableMsgOut( pACB, pSRB ); ++ } ++ if( !(pSRB->SRBState & SRB_DISCONNECT) ) ++ goto mingx0; ++ pDCB->pActiveSRB = pSRB; ++ pSRB->SRBState = SRB_DATA_XFER; ++ } ++ else ++ { ++mingx0: ++ pSRB = pACB->pTmpSRB; ++ pSRB->SRBState = SRB_UNEXPECT_RESEL; ++ pDCB->pActiveSRB = pSRB; ++ pSRB->MsgOutBuf[0] = MSG_ABORT_TAG; ++ EnableMsgOut2( pACB, pSRB ); ++ } ++ } ++ } ++ else if( (pSRB->MsgInBuf[0] == MSG_EXTENDED) && (pSRB->MsgCnt == 5) ) ++ { ++ pSRB->SRBState &= ~(SRB_MSGIN_MULTI+DO_SYNC_NEGO); ++ if( (pSRB->MsgInBuf[1] != 3) || (pSRB->MsgInBuf[2] != 1) ) ++ { /* reject_msg: */ ++ pSRB->MsgCnt = 1; ++ pSRB->MsgInBuf[0] = MSG_REJECT_; ++ bval = SET_ATN_CMD; ++ outb(bval, ioport+ScsiCmd); ++ } ++ else if( !(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4]) ) ++ { ++set_async: ++ pDCB = pSRB->pSRBDCB; ++ pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE); ++ pDCB->SyncPeriod = 0; ++ pDCB->SyncOffset = 0; ++ pDCB->CtrlR3 = FAST_CLK; /* ;non_fast */ ++ pDCB->CtrlR4 &= 0x3f; ++ pDCB->CtrlR4 |= EATER_25NS; /* ; 25ns glitch eater */ ++ goto re_prog; ++ } ++ else ++ { /* set_sync: */ ++ ++ pDCB = pSRB->pSRBDCB; ++ pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE; ++ pDCB->SyncOffset &= 0x0f0; ++ pDCB->SyncOffset |= pSRB->MsgInBuf[4]; ++ pDCB->NegoPeriod = pSRB->MsgInBuf[3]; ++ wval = (USHORT) pSRB->MsgInBuf[3]; ++ wval = wval << 2; ++ wval--; ++ wval1 = wval / 25; ++ if( (wval1 * 25) != wval) ++ wval1++; ++ bval = FAST_CLK+FAST_SCSI; ++ pDCB->CtrlR4 &= 0x3f; ++ if(wval1 >= 8) ++ { ++ wval1--; ++ bval = FAST_CLK; /* ;fast clock/normal scsi */ ++ pDCB->CtrlR4 |= EATER_25NS; /* ;25 ns glitch eater */ ++ } ++ pDCB->CtrlR3 = bval; ++ pDCB->SyncPeriod = (UCHAR)wval1; ++re_prog: ++ bval = pDCB->SyncPeriod; ++ outb(bval, ioport+Sync_Period); ++ bval = pDCB->SyncOffset; ++ outb(bval, ioport+Sync_Offset); ++ bval = pDCB->CtrlR3; ++ outb(bval, ioport+CtrlReg3); ++ bval = pDCB->CtrlR4; ++ outb(bval, ioport+CtrlReg4); ++ SetXferRate( pACB, pDCB); ++ } ++ } ++ } ++min6: ++ *psstatus = SCSI_NOP0; ++ bval = MSG_ACCEPTED_CMD; ++ outb(bval, ioport+ScsiCmd); ++} ++ ++static void ++DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir) ++{ ++ PSGL psgl; ++ UCHAR bval; ++ USHORT ioport; ++ ULONG lval; ++ ++ ++ ioport = pACB->IOPortBase; ++ if( pSRB->SGIndex < pSRB->SGcount ) ++ { ++ bval = DMA_IDLE_CMD | ioDir; /* ;+EN_DMA_INT */ ++ outb( bval, ioport+DMA_Cmd); ++ if( !pSRB->SGToBeXferLen ) ++ { ++ psgl = pSRB->pSegmentList; ++#ifndef VERSION_ELF_1_2_13 ++ pSRB->SGPhysAddr = virt_to_phys( psgl->address ); ++#else ++ pSRB->SGPhysAddr = (ULONG) psgl->address; ++#endif ++ pSRB->SGToBeXferLen = (ULONG) psgl->length; ++ } ++ lval = pSRB->SGToBeXferLen; ++ bval = (UCHAR) lval; ++ outb(bval,ioport+CtcReg_Low); ++ lval = lval >> 8; ++ bval = (UCHAR) lval; ++ outb(bval,ioport+CtcReg_Mid); ++ lval = lval >> 8; ++ bval = (UCHAR) lval; ++ outb(bval,ioport+CtcReg_High); ++ ++ lval = pSRB->SGToBeXferLen; ++ outl(lval, ioport+DMA_XferCnt); ++ ++ lval = pSRB->SGPhysAddr; ++ outl( lval, ioport+DMA_XferAddr); ++ ++ bval = DMA_COMMAND+INFO_XFER_CMD; ++ outb(bval, ioport+ScsiCmd); ++ ++ pSRB->SRBState = SRB_DATA_XFER; ++ ++ bval = DMA_IDLE_CMD | ioDir; /* ;+EN_DMA_INT */ ++ outb(bval, ioport+DMA_Cmd); ++ ++ bval = DMA_START_CMD | ioDir; /* ;+EN_DMA_INT */ ++ outb(bval, ioport+DMA_Cmd); ++ } ++ else /* xfer pad */ ++ { ++ if( pSRB->SGcount ) ++ { ++ pSRB->AdaptStatus = H_OVER_UNDER_RUN; ++ pSRB->SRBStatus |= OVER_RUN; ++ } ++ bval = 0; ++ outb(bval,ioport+CtcReg_Low); ++ outb(bval,ioport+CtcReg_Mid); ++ outb(bval,ioport+CtcReg_High); ++ ++ pSRB->SRBState |= SRB_XFERPAD; ++ bval = DMA_COMMAND+XFER_PAD_BYTE; ++ outb(bval, ioport+ScsiCmd); ++/* ++ bval = DMA_IDLE_CMD | ioDir; ;+EN_DMA_INT ++ outb(bval, ioport+DMA_Cmd); ++ bval = DMA_START_CMD | ioDir; ;+EN_DMA_INT ++ outb(bval, ioport+DMA_Cmd); ++*/ ++ } ++} ++ ++ ++static void ++DC390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR ioDir; ++ ++ ioDir = WRITE_DIRECTION; ++ DataIO_Comm( pACB, pSRB, ioDir); ++} ++ ++static void ++DC390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR ioDir; ++ ++ ioDir = READ_DIRECTION; ++ DataIO_Comm( pACB, pSRB, ioDir); ++} ++ ++static void ++DC390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ PDCB pDCB; ++ UCHAR bval; ++ PUCHAR ptr; ++ USHORT ioport, i, cnt; ++ ++ ++ ioport = pACB->IOPortBase; ++ bval = RESET_ATN_CMD; ++ outb(bval, ioport+ScsiCmd); ++ bval = CLEAR_FIFO_CMD; ++ outb(bval, ioport+ScsiCmd); ++ if( !(pSRB->SRBFlag & AUTO_REQSENSE) ) ++ { ++ cnt = (USHORT) pSRB->ScsiCmdLen; ++ ptr = (PUCHAR) pSRB->CmdBlock; ++ for(i=0; i < cnt; i++) ++ { ++ outb(*ptr, ioport+ScsiFifo); ++ ptr++; ++ } ++ } ++ else ++ { ++ bval = REQUEST_SENSE; ++ outb(bval, ioport+ScsiFifo); ++ pDCB = pACB->pActiveDCB; ++ bval = pDCB->IdentifyMsg << 5; ++ outb(bval, ioport+ScsiFifo); ++ bval = 0; ++ outb(bval, ioport+ScsiFifo); ++ outb(bval, ioport+ScsiFifo); ++ bval = sizeof(pSRB->pcmd->sense_buffer); ++ outb(bval, ioport+ScsiFifo); ++ bval = 0; ++ outb(bval, ioport+ScsiFifo); ++ } ++ pSRB->SRBState = SRB_COMMAND; ++ bval = INFO_XFER_CMD; ++ outb(bval, ioport+ScsiCmd); ++} ++ ++static void ++DC390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR bval; ++ USHORT ioport; ++ ++ ioport = pACB->IOPortBase; ++ bval = CLEAR_FIFO_CMD; ++ outb(bval, ioport+ScsiCmd); ++ pSRB->SRBState = SRB_STATUS; ++ bval = INITIATOR_CMD_CMPLTE; ++ outb(bval, ioport+ScsiCmd); ++} ++ ++static void ++DC390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR bval; ++ USHORT ioport, i, cnt; ++ PUCHAR ptr; ++ PDCB pDCB; ++ ++ ioport = pACB->IOPortBase; ++ bval = CLEAR_FIFO_CMD; ++ outb(bval, ioport+ScsiCmd); ++ pDCB = pACB->pActiveDCB; ++ if( !(pSRB->SRBState & SRB_MSGOUT) ) ++ { ++ cnt = pSRB->MsgCnt; ++ if( cnt ) ++ { ++ ptr = (PUCHAR) pSRB->MsgOutBuf; ++ for(i=0; i < cnt; i++) ++ { ++ outb(*ptr, ioport+ScsiFifo); ++ ptr++; ++ } ++ pSRB->MsgCnt = 0; ++ if( (pDCB->DCBFlag & ABORT_DEV_) && ++ (pSRB->MsgOutBuf[0] == MSG_ABORT) ) ++ pSRB->SRBState = SRB_ABORT_SENT; ++ } ++ else ++ { ++ bval = MSG_ABORT; /* ??? MSG_NOP */ ++ if( (pSRB->CmdBlock[0] == INQUIRY ) || ++ (pSRB->CmdBlock[0] == REQUEST_SENSE) || ++ (pSRB->SRBFlag & AUTO_REQSENSE) ) ++ { ++ if( pDCB->SyncMode & SYNC_ENABLE ) ++ goto mop1; ++ } ++ outb(bval, ioport+ScsiFifo); ++ } ++ bval = INFO_XFER_CMD; ++ outb( bval, ioport+ScsiCmd); ++ } ++ else ++ { ++mop1: ++ bval = MSG_EXTENDED; ++ outb(bval, ioport+ScsiFifo); ++ bval = 3; /* ;length of extended msg */ ++ outb(bval, ioport+ScsiFifo); ++ bval = 1; /* ; sync nego */ ++ outb(bval, ioport+ScsiFifo); ++ bval = pDCB->NegoPeriod; ++ outb(bval, ioport+ScsiFifo); ++ bval = SYNC_NEGO_OFFSET; ++ outb(bval, ioport+ScsiFifo); ++ pSRB->SRBState |= DO_SYNC_NEGO; ++ bval = INFO_XFER_CMD; ++ outb(bval, ioport+ScsiCmd); ++ } ++} ++ ++static void ++DC390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++ UCHAR bval; ++ USHORT ioport; ++ ++ ioport = pACB->IOPortBase; ++ bval = CLEAR_FIFO_CMD; ++ outb(bval, ioport+ScsiCmd); ++ if( !(pSRB->SRBState & SRB_MSGIN) ) ++ { ++ pSRB->SRBState &= SRB_DISCONNECT; ++ pSRB->SRBState |= SRB_MSGIN; ++ } ++ bval = INFO_XFER_CMD; ++ outb(bval, ioport+ScsiCmd); ++} ++ ++static void ++DC390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++} ++ ++static void ++DC390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus) ++{ ++} ++ ++ ++static void ++SetXferRate( PACB pACB, PDCB pDCB ) ++{ ++ UCHAR bval; ++ USHORT cnt, i; ++ PDCB ptr; ++ ++ if( !(pDCB->IdentifyMsg & 0x07) ) ++ { ++ if( pACB->scan_devices ) ++ { ++ CurrSyncOffset = pDCB->SyncOffset; ++ } ++ else ++ { ++ ptr = pACB->pLinkDCB; ++ cnt = pACB->DeviceCnt; ++ bval = pDCB->UnitSCSIID; ++ for(i=0; i<cnt; i++) ++ { ++ if( ptr->UnitSCSIID == bval ) ++ { ++ ptr->SyncPeriod = pDCB->SyncPeriod; ++ ptr->SyncOffset = pDCB->SyncOffset; ++ ptr->CtrlR3 = pDCB->CtrlR3; ++ ptr->CtrlR4 = pDCB->CtrlR4; ++ ptr->SyncMode = pDCB->SyncMode; ++ } ++ ptr = ptr->pNextDCB; ++ } ++ } ++ } ++ return; ++} ++ ++ ++static void ++DC390_Disconnect( PACB pACB ) ++{ ++ PDCB pDCB; ++ PSRB pSRB, psrb; ++ ULONG flags; ++ USHORT ioport, i, cnt; ++ UCHAR bval; ++ ++#ifdef DC390_DEBUG0 ++ printk("DISC,"); ++#endif ++ ++ save_flags(flags); ++ cli(); ++ ioport = pACB->IOPortBase; ++ pDCB = pACB->pActiveDCB; ++ if (!pDCB) ++ { ++#ifdef DC390_DEBUG0 ++ printk("ACB:%08lx->ActiveDCB:%08lx !,",(ULONG)pACB,(ULONG)pDCB); ++#endif ++ restore_flags(flags); return; ++ } ++ pSRB = pDCB->pActiveSRB; ++ pACB->pActiveDCB = 0; ++ pSRB->ScsiPhase = SCSI_NOP0; ++ bval = EN_SEL_RESEL; ++ outb(bval, ioport+ScsiCmd); ++ if( pSRB->SRBState & SRB_UNEXPECT_RESEL ) ++ { ++ pSRB->SRBState = 0; ++ DoWaitingSRB( pACB ); ++ } ++ else if( pSRB->SRBState & SRB_ABORT_SENT ) ++ { ++ pDCB->TagMask = 0; ++ pDCB->DCBFlag = 0; ++ cnt = pDCB->GoingSRBCnt; ++ pDCB->GoingSRBCnt = 0; ++ pSRB = pDCB->pGoingSRB; ++ for( i=0; i < cnt; i++) ++ { ++ psrb = pSRB->pNextSRB; ++ pSRB->pNextSRB = pACB->pFreeSRB; ++ pACB->pFreeSRB = pSRB; ++ pSRB = psrb; ++ } ++ pDCB->pGoingSRB = 0; ++ DoWaitingSRB( pACB ); ++ } ++ else ++ { ++ if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || ++ !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) ) ++ { /* Selection time out */ ++ if( !(pACB->scan_devices) ) ++ { ++ pSRB->SRBState = SRB_READY; ++ RewaitSRB( pDCB, pSRB); ++ } ++ else ++ { ++ pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT; ++ goto disc1; ++ } ++ } ++ else if( pSRB->SRBState & SRB_DISCONNECT ) ++ { ++ DoWaitingSRB( pACB ); ++ } ++ else if( pSRB->SRBState & SRB_COMPLETED ) ++ { ++disc1: ++ if(pDCB->MaxCommand > 1) ++ { ++ bval = pSRB->TagNumber; ++ pDCB->TagMask &= (~(1 << bval)); /* free tag mask */ ++ } ++ pDCB->pActiveSRB = 0; ++ pSRB->SRBState = SRB_FREE; ++ SRBdone( pACB, pDCB, pSRB); ++ } ++ } ++ restore_flags(flags); ++ return; ++} ++ ++ ++static void ++DC390_Reselect( PACB pACB ) ++{ ++ PDCB pDCB, pdcb; ++ PSRB pSRB; ++ USHORT ioport, wval; ++ UCHAR bval, bval1; ++ ++ ++#ifdef DC390_DEBUG0 ++ printk("RSEL,"); ++#endif ++ ioport = pACB->IOPortBase; ++ pDCB = pACB->pActiveDCB; ++ if( pDCB ) ++ { /* Arbitration lost but Reselection win */ ++ pSRB = pDCB->pActiveSRB; ++ if( !( pACB->scan_devices ) ) ++ { ++ pSRB->SRBState = SRB_READY; ++ RewaitSRB( pDCB, pSRB); ++ } ++ } ++ bval = inb(ioport+ScsiFifo); /* get ID */ ++ bval = bval ^ pACB->HostID_Bit; ++ wval = 0; ++ bval1 = 1; ++ for(;;) ++ { ++ if( !(bval & bval1) ) ++ { ++ bval1 = bval1 << 1; ++ wval++; ++ } ++ else ++ break; ++ } ++ wval |= ( (USHORT) inb(ioport+ScsiFifo) & 7) << 8; /* get LUN */ ++ pDCB = pACB->pLinkDCB; ++ pdcb = pDCB; ++ while( wval != *((PUSHORT) &pDCB->UnitSCSIID) ) ++ { ++ pDCB = pDCB->pNextDCB; ++ if( pDCB == pdcb ) ++ return; ++ } ++ pACB->pActiveDCB = pDCB; ++ if( pDCB->SyncMode & EN_TAG_QUEUING ) ++ { ++ pSRB = pACB->pTmpSRB; ++ pDCB->pActiveSRB = pSRB; ++ } ++ else ++ { ++ pSRB = pDCB->pActiveSRB; ++ if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) ) ++ { ++ pSRB= pACB->pTmpSRB; ++ pSRB->SRBState = SRB_UNEXPECT_RESEL; ++ pDCB->pActiveSRB = pSRB; ++ EnableMsgOut( pACB, pSRB ); ++ } ++ else ++ { ++ if( pDCB->DCBFlag & ABORT_DEV_ ) ++ { ++ pSRB->SRBState = SRB_ABORT_SENT; ++ EnableMsgOut( pACB, pSRB ); ++ } ++ else ++ pSRB->SRBState = SRB_DATA_XFER; ++ } ++ } ++ pSRB->ScsiPhase = SCSI_NOP0; ++ bval = pDCB->UnitSCSIID; ++ outb( bval, ioport+Scsi_Dest_ID); ++ bval = pDCB->SyncPeriod; ++ outb(bval, ioport+Sync_Period); ++ bval = pDCB->SyncOffset; ++ outb( bval, ioport+Sync_Offset); ++ bval = pDCB->CtrlR1; ++ outb(bval, ioport+CtrlReg1); ++ bval = pDCB->CtrlR3; ++ outb(bval, ioport+CtrlReg3); ++ bval = pDCB->CtrlR4; /* ; Glitch eater */ ++ outb(bval, ioport+CtrlReg4); ++ bval = MSG_ACCEPTED_CMD; /* ;to rls the /ACK signal */ ++ outb(bval, ioport+ScsiCmd); ++} ++ ++ ++static void ++SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB ) ++{ ++ PSRB psrb; ++ UCHAR bval, bval1, i, j, status; ++ PSCSICMD pcmd; ++ PSCSI_INQDATA ptr; ++ USHORT disable_tag; ++ ULONG flags; ++ PSGL ptr2; ++ ULONG swlval; ++ ++ pcmd = pSRB->pcmd; ++ status = pSRB->TargetStatus; ++ if(pSRB->SRBFlag & AUTO_REQSENSE) ++ { ++ pSRB->SRBFlag &= ~AUTO_REQSENSE; ++ pSRB->AdaptStatus = 0; ++ pSRB->TargetStatus = SCSI_STAT_CHECKCOND; ++ if(status == SCSI_STAT_CHECKCOND) ++ { ++ pcmd->result = DID_BAD_TARGET << 16; ++ goto ckc_e; ++ } ++ if(pSRB->RetryCnt == 0) ++ { ++ *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; ++ pSRB->TotalXferredLen = pSRB->Segment1[1]; ++ if( (pSRB->TotalXferredLen) && ++ (pSRB->TotalXferredLen >= pcmd->underflow) ) ++ pcmd->result |= (DID_OK << 16); ++ else ++ pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | ++ SCSI_STAT_CHECKCOND; ++#ifdef DC390_DEBUG0 ++ printk("Cmd=%2x,Result=%8x,XferL=%8x,",pSRB->CmdBlock[0], ++ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen); ++#endif ++ goto ckc_e; ++ } ++ else ++ { ++ pSRB->RetryCnt--; ++ pSRB->AdaptStatus = 0; ++ pSRB->TargetStatus = 0; ++ *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0]; ++ *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1]; ++ if( pSRB->CmdBlock[0] == TEST_UNIT_READY ) ++ { ++ pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) | ++ SCSI_STAT_CHECKCOND; ++ goto ckc_e; ++ } ++ pcmd->result |= (DRIVER_SENSE << 24); ++ pSRB->SGcount = (UCHAR) pSRB->Segment1[0]; ++ pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8); ++ pSRB->SGIndex = 0; ++ pSRB->TotalXferredLen = 0; ++ pSRB->SGToBeXferLen = 0; ++ if( pcmd->use_sg ) ++ pSRB->pSegmentList = (PSGL) pcmd->request_buffer; ++ else if( pcmd->request_buffer ) ++ { ++ pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; ++ pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer; ++ pSRB->Segmentx.length = pcmd->request_bufflen; ++ } ++ if( DC390_StartSCSI( pACB, pDCB, pSRB ) ) ++ RewaitSRB( pDCB, pSRB ); ++ return; ++ } ++ } ++ if( status ) ++ { ++ if( status == SCSI_STAT_CHECKCOND) ++ { ++ if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) ) ++ { ++ bval = pSRB->SGcount; ++ swlval = 0; ++ ptr2 = pSRB->pSegmentList; ++ for( i=pSRB->SGIndex; i < bval; i++) ++ { ++ swlval += ptr2->length; ++ ptr2++; ++ } ++#ifdef DC390_DEBUG0 ++ printk("XferredLen=%8x,NotXferLen=%8x,", ++ (UINT) pSRB->TotalXferredLen, (UINT) swlval); ++#endif ++ } ++ RequestSense( pACB, pDCB, pSRB ); ++ return; ++ } ++ else if( status == SCSI_STAT_QUEUEFULL ) ++ { ++ bval = (UCHAR) pDCB->GoingSRBCnt; ++ bval--; ++ pDCB->MaxCommand = bval; ++ RewaitSRB( pDCB, pSRB ); ++ pSRB->AdaptStatus = 0; ++ pSRB->TargetStatus = 0; ++ return; ++ } ++ else if(status == SCSI_STAT_SEL_TIMEOUT) ++ { ++ pSRB->AdaptStatus = H_SEL_TIMEOUT; ++ pSRB->TargetStatus = 0; ++ pcmd->result = DID_BAD_TARGET << 16; ++ } ++ else ++ { ++ pSRB->AdaptStatus = 0; ++ if( pSRB->RetryCnt ) ++ { ++ pSRB->RetryCnt--; ++ pSRB->TargetStatus = 0; ++ pSRB->SGIndex = 0; ++ pSRB->TotalXferredLen = 0; ++ pSRB->SGToBeXferLen = 0; ++ if( pcmd->use_sg ) ++ pSRB->pSegmentList = (PSGL) pcmd->request_buffer; ++ else if( pcmd->request_buffer ) ++ { ++ pSRB->pSegmentList = (PSGL) &pSRB->Segmentx; ++ pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer; ++ pSRB->Segmentx.length = pcmd->request_bufflen; ++ } ++ if( DC390_StartSCSI( pACB, pDCB, pSRB ) ) ++ RewaitSRB( pDCB, pSRB ); ++ return; ++ } ++ else ++ { ++ pcmd->result |= (DID_ERROR << 16) | (ULONG) (pSRB->EndMessage << 8) | ++ (ULONG) status; ++ } ++ } ++ } ++ else ++ { ++ status = pSRB->AdaptStatus; ++ if(status & H_OVER_UNDER_RUN) ++ { ++ pSRB->TargetStatus = 0; ++ pcmd->result |= (DID_OK << 16) | (pSRB->EndMessage << 8); ++ } ++ else if( pSRB->SRBStatus & PARITY_ERROR) ++ { ++ pcmd->result |= (DID_PARITY << 16) | (pSRB->EndMessage << 8); ++ } ++ else /* No error */ ++ { ++ pSRB->AdaptStatus = 0; ++ pSRB->TargetStatus = 0; ++ pcmd->result |= (DID_OK << 16); ++ } ++ } ++ ++ckc_e: ++ if( pACB->scan_devices ) ++ { ++ if( pSRB->CmdBlock[0] == TEST_UNIT_READY ) ++ { ++ if(pcmd->result != (DID_OK << 16)) ++ { ++ if( pcmd->result & SCSI_STAT_CHECKCOND ) ++ { ++ goto RTN_OK; ++ } ++ else ++ { ++ pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun); ++ pPrevDCB->pNextDCB = pACB->pLinkDCB; ++ if( (pcmd->target == pACB->max_id) && ++ ((pcmd->lun == 0) || (pcmd->lun == pACB->max_lun)) ) ++ { ++ pACB->scan_devices = 0; ++ } ++ } ++ } ++ else ++ { ++RTN_OK: ++ pPrevDCB->pNextDCB = pDCB; ++ pDCB->pNextDCB = pACB->pLinkDCB; ++ if( (pcmd->target == pACB->max_id) && (pcmd->lun == pACB->max_lun) ) ++ pACB->scan_devices = END_SCAN; ++ } ++ } ++ else if( pSRB->CmdBlock[0] == INQUIRY ) ++ { ++ if( (pcmd->target == pACB->max_id) && ++ (pcmd->lun == pACB->max_lun) ) ++ { ++ pACB->scan_devices = 0; ++ } ++ ptr = (PSCSI_INQDATA) (pcmd->request_buffer); ++ if( pcmd->use_sg ) ++ ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address); ++ bval1 = ptr->DevType & SCSI_DEVTYPE; ++ if(bval1 == SCSI_NODEV) ++ { ++ pACB->DCBmap[pcmd->target] &= ~(1 << pcmd->lun); ++ pPrevDCB->pNextDCB = pACB->pLinkDCB; ++ } ++ else ++ { ++ pACB->DeviceCnt++; ++ pPrevDCB = pDCB; ++ pACB->pDCB_free = (PDCB) ((ULONG) (pACB->pDCB_free) + sizeof( DC390_DCB )); ++ pDCB->DevType = bval1; ++ if(bval1 == TYPE_DISK || bval1 == TYPE_MOD) ++ { ++ if( (((ptr->Vers & 0x07) >= 2) || ((ptr->RDF & 0x0F) == 2)) && ++ (ptr->Flags & SCSI_INQ_CMDQUEUE) && ++ (pDCB->DevMode & TAG_QUEUING_) && ++ (pDCB->DevMode & EN_DISCONNECT_) ) ++ { ++ disable_tag = 0; ++ for(i=0; i<BADDEVCNT; i++) ++ { ++ for(j=0; j<28; j++) ++ { ++ if( ((PUCHAR)ptr)[8+j] != baddevname1[i][j]) ++ break; ++ } ++ if(j == 28) ++ { ++ disable_tag = 1; ++ break; ++ } ++ } ++ ++ if( !disable_tag ) ++ { ++ pDCB->MaxCommand = pACB->TagMaxNum; ++ pDCB->SyncMode |= EN_TAG_QUEUING; ++ pDCB->TagMask = 0; ++ } ++ else ++ { ++ pDCB->SyncMode |= EN_ATN_STOP; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ save_flags( flags ); ++ cli(); ++/* ReleaseSRB( pDCB, pSRB ); */ ++ ++ if(pSRB == pDCB->pGoingSRB ) ++ { ++ pDCB->pGoingSRB = pSRB->pNextSRB; ++ } ++ else ++ { ++ psrb = pDCB->pGoingSRB; ++ while( psrb->pNextSRB != pSRB ) ++ psrb = psrb->pNextSRB; ++ psrb->pNextSRB = pSRB->pNextSRB; ++ if( pSRB == pDCB->pGoingLast ) ++ pDCB->pGoingLast = psrb; ++ } ++ pSRB->pNextSRB = pACB->pFreeSRB; ++ pACB->pFreeSRB = pSRB; ++ pDCB->GoingSRBCnt--; ++ ++ DoWaitingSRB( pACB ); ++ restore_flags(flags); ++ ++/* Notify cmd done */ ++ pcmd->scsi_done( pcmd ); ++ ++ if( pDCB->QIORBCnt ) ++ DoNextCmd( pACB, pDCB ); ++ return; ++} ++ ++ ++static void ++DoingSRB_Done( PACB pACB ) ++{ ++ PDCB pDCB, pdcb; ++ PSRB psrb, psrb2; ++ USHORT cnt, i; ++ PSCSICMD pcmd; ++ ++ pDCB = pACB->pLinkDCB; ++ pdcb = pDCB; ++ do ++ { ++ cnt = pdcb->GoingSRBCnt; ++ psrb = pdcb->pGoingSRB; ++ for( i=0; i<cnt; i++) ++ { ++ psrb2 = psrb->pNextSRB; ++ pcmd = psrb->pcmd; ++ pcmd->result = DID_RESET << 16; ++ ++/* ReleaseSRB( pDCB, pSRB ); */ ++ ++ psrb->pNextSRB = pACB->pFreeSRB; ++ pACB->pFreeSRB = psrb; ++ ++ pcmd->scsi_done( pcmd ); ++ psrb = psrb2; ++ } ++ pdcb->GoingSRBCnt = 0;; ++ pdcb->pGoingSRB = NULL; ++ pdcb->TagMask = 0; ++ pdcb = pdcb->pNextDCB; ++ } ++ while( pdcb != pDCB ); ++} ++ ++ ++static void ++DC390_ResetSCSIBus( PACB pACB ) ++{ ++ USHORT ioport; ++ UCHAR bval; ++ ULONG flags; ++ ++ save_flags(flags); ++ cli(); ++ pACB->ACBFlag |= RESET_DEV; ++ ioport = pACB->IOPortBase; ++ ++ bval = DMA_IDLE_CMD; ++ outb(bval,ioport+DMA_Cmd); ++ ++ bval = RST_SCSI_BUS_CMD; ++ outb(bval,ioport+ScsiCmd); ++ ++ restore_flags(flags); ++ return; ++} ++ ++ ++static void ++DC390_ScsiRstDetect( PACB pACB ) ++{ ++ ULONG wlval, flags; ++ USHORT ioport; ++ UCHAR bval; ++ ++#ifdef DC390_DEBUG0 ++ printk("RST_DETEC"); ++#endif ++ save_flags(flags); ++ sti(); ++ wlval = jiffies + HZ; ++ while( jiffies < wlval ); /* delay 1 sec */ ++ ++ cli(); ++ ioport = pACB->IOPortBase; ++ bval = DMA_IDLE_CMD; ++ outb(bval,ioport+DMA_Cmd); ++ bval = CLEAR_FIFO_CMD; ++ outb(bval,ioport+ScsiCmd); ++ ++ if( pACB->ACBFlag & RESET_DEV ) ++ pACB->ACBFlag |= RESET_DONE; ++ else ++ { ++ pACB->ACBFlag |= RESET_DETECT; ++ ++ ResetDevParam( pACB ); ++/* DoingSRB_Done( pACB ); ???? */ ++ RecoverSRB( pACB ); ++ pACB->pActiveDCB = NULL; ++ pACB->ACBFlag = 0; ++ DoWaitingSRB( pACB ); ++ } ++ restore_flags(flags); ++ return; ++} ++ ++ ++static void ++RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB ) ++{ ++ PSCSICMD pcmd; ++ ++ pSRB->SRBFlag |= AUTO_REQSENSE; ++ pSRB->Segment0[0] = *((PULONG) &(pSRB->CmdBlock[0])); ++ pSRB->Segment0[1] = *((PULONG) &(pSRB->CmdBlock[4])); ++ pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount); ++ pSRB->Segment1[1] = pSRB->TotalXferredLen; ++ pSRB->AdaptStatus = 0; ++ pSRB->TargetStatus = 0; ++ ++ pcmd = pSRB->pcmd; ++ ++ pSRB->Segmentx.address = (PUCHAR) &(pcmd->sense_buffer); ++ pSRB->Segmentx.length = sizeof(pcmd->sense_buffer); ++ pSRB->pSegmentList = &pSRB->Segmentx; ++ pSRB->SGcount = 1; ++ pSRB->SGIndex = 0; ++ ++ *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003; ++ pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5; ++ *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(pcmd->sense_buffer); ++ pSRB->ScsiCmdLen = 6; ++ ++ pSRB->TotalXferredLen = 0; ++ pSRB->SGToBeXferLen = 0; ++ if( DC390_StartSCSI( pACB, pDCB, pSRB ) ) ++ RewaitSRB( pDCB, pSRB ); ++} ++ ++ ++static void ++EnableMsgOut2( PACB pACB, PSRB pSRB ) ++{ ++ USHORT ioport; ++ UCHAR bval; ++ ++ ioport = pACB->IOPortBase; ++ pSRB->MsgCnt = 1; ++ bval = SET_ATN_CMD; ++ outb(bval, ioport+ScsiCmd); ++} ++ ++ ++static void ++EnableMsgOut( PACB pACB, PSRB pSRB ) ++{ ++ pSRB->MsgOutBuf[0] = MSG_ABORT; ++ EnableMsgOut2( pACB, pSRB ); ++} ++ ++ ++static void ++DC390_InvalidCmd( PACB pACB ) ++{ ++ UCHAR bval; ++ USHORT ioport; ++ PSRB pSRB; ++ ++ pSRB = pACB->pActiveDCB->pActiveSRB; ++ if( pSRB->SRBState & (SRB_START_+SRB_MSGOUT) ) ++ { ++ ioport = pACB->IOPortBase; ++ bval = CLEAR_FIFO_CMD; ++ outb(bval,(ioport+ScsiCmd)); ++ } ++} ++ +diff --git a/ddb/db_write_cmd.h b/ddb/db_write_cmd.h +new file mode 100644 +index 0000000..74bac54 +--- /dev/null ++++ b/ddb/db_write_cmd.h +@@ -0,0 +1,16 @@ ++#ifndef _DDB_DB_WRITE_CMD_H_ ++#define _DDB_DB_WRITE_CMD_H_ ++ ++#include <mach/boolean.h> ++#include <machine/db_machdep.h> ++ ++/* Prototypes for functions exported by this module. ++ */ ++ ++void db_write_cmd( ++ db_expr_t address, ++ boolean_t have_addr, ++ db_expr_t count, ++ char * modif); ++ ++#endif /* !_DDB_DB_WRITE_CMD_H_ */ +diff --git a/vm/vm_print.h b/vm/vm_print.h +new file mode 100644 +index 0000000..69a20ba +--- /dev/null ++++ b/vm/vm_print.h +@@ -0,0 +1,22 @@ ++#ifndef VM_PRINT_H ++#define VM_PRINT_H ++ ++#include <vm/vm_map.h> ++#include <machine/db_machdep.h> ++ ++/* Debugging: print a map */ ++extern void vm_map_print(vm_map_t); ++ ++/* Pretty-print a copy object for ddb. */ ++extern void vm_map_copy_print(vm_map_copy_t); ++ ++#include <vm/vm_object.h> ++ ++extern void vm_object_print(vm_object_t); ++ ++#include <vm/vm_page.h> ++ ++extern void vm_page_print(vm_page_t); ++ ++#endif /* VM_PRINT_H */ ++ +diff --git a/ipc/ipc_print.h b/ipc/ipc_print.h +new file mode 100644 +index 0000000..ef676a7 +--- /dev/null ++++ b/ipc/ipc_print.h +@@ -0,0 +1,20 @@ ++#ifndef _IPC_PRINT_H_ ++#define _IPC_PRINT_H_ ++ ++#if MACH_KDB ++ ++#include <mach/mach_types.h> ++#include <mach/message.h> ++#include <ipc/ipc_types.h> ++ ++extern void ipc_port_print(ipc_port_t); ++ ++extern void ipc_pset_print(ipc_pset_t); ++ ++extern void ipc_kmsg_print(ipc_kmsg_t); ++ ++extern void ipc_msg_print(mach_msg_header_t*); ++ ++#endif /* MACH_KDB */ ++ ++#endif /* IPC_PRINT_H */ diff --git a/debian/patches/series b/debian/patches/series index a95f927..7ac3565 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -3,3 +3,4 @@ 50_initrd.patch 60_bigmem.patch 70_dde.patch +80_missing_files.patch |
