📄 doch_ata.c
字号:
/******************************************************************************/
/* */
/* Copyright (C), 1995-2006, msystems Ltd. All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* 1. Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* 3. Neither the name of msystems nor the names of its contributors may be */
/* used to endorse or promote products derived from this software without */
/* specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/******************************************************************************/
/*
* $Log: V:/PVCSDB/DiskOnChip/archives/Test for 7.x/src/H3/doch_ata.c-arc $
*
* Rev 1.56 Sep 14 2006 09:56:38 yaniv.iarovici
* Fix compilation warnings
*
* Rev 1.55 Sep 11 2006 13:45:14 yaniv.iarovici
* Legal header added
*
* Rev 1.54 Sep 10 2006 10:03:28 Yaniv.Iarovici
* Bug Fix: DMA handling in io_input() and io_output() (Device Head Register).
*
* Rev 1.53 Sep 03 2006 14:44:34 Yaniv.Iarovici
* Fixed DMA handling handling when DRQ>1.
*
* Rev 1.52 Aug 16 2006 08:45:46 Yaniv.Iarovici
* 1) Remove comment regarding #define DOCH_CHECK_CHIP_ID
* 2) Add global var: 'gIgnoreErrorBit' - used by ready() to ignore error bit when checking status (used when identifying device using ATA standard IDENTIFY DEVICE command)
* 3) Remove commented function - doch_pause()
* 4) Add 2nd argument 'FLSNative devNum' to doch_check_chipID()
* 5) Update clear_socket() to support 'ETFFS_Identified' field
* 6) Move the call to retrieveAndPrintAtaDebug() to after command is completed in doch_ata_passthru()
* 7) Add support to check CHIP ID on specific device (not only Dev0) in doch_check_chipID()
* 8) Add dunction 'doch_ATAstd_IDENTIFY_DEVICE(FLSNative socketNo, FLSNative devNum)' to identify a device using ATA standard IDENTIFY DEIVCE command when ETFFS was not detected on the device
* 9) Modify doch_init_socket() to:
* - Identify a device using ATA standard IDENTIFY DEVICE command when no ETFFS detected.
* - Check CHIP ID on specific device to reduce the time needed to identify NON-existing device.
* - Set Power Mode only if ETFFS was detected on the device.
*
* Rev 1.51 Aug 10 2006 10:23:02 Polina.Marimont
* bug fix - identifying in 128K window failure
*
* Rev 1.50 Aug 09 2006 17:26:52 Polina.Marimont
* initial for DOC Driver 1.0
*
*/
/*
* includes
*/
#include "flcustom.h"
#include "flsystem.h"
#include "flchkdef.h"
#include "flsystyp.h"
#include "flcommon.h"
#include "flsysfun.h"
#include "doch_func.h"
#include "doch_ata.h"
#include "hib.h"
#ifdef FL_MIGRATION_VERSION
#include "docsys.h"
#endif /*FL_MIGRATION_VERSION*/
FLWord gMemWindowType = 0;
FLDword gDochMemWinSize = 0;
FLWord gHibCoreAddress = 0;
FLWord gHibContRegAreaOffset = 0;
FLWord gHibDataPortAreaOffset = 0;
FLWord gHibConfigRegAreaOffset = 0;
#ifdef CHECK_POWER_ON_EVERY_COMMAND
FLBoolean gDeviceTurnedOff = FALSE;
#endif /*CHECK_POWER_ON_EVERY_COMMAND*/
/*
* types
*/
/*
* Global Variables
*/
#ifdef __cplusplus
extern "C" {
#endif
FLDword gAccessLayerType = 0;
FLDword gATANoTimeout = 0;
FLDword gUseShortWaitOnBusy = 0;
FLDword gIgnoreErrorBit = 0;
FLDword gDochAccessNanosec = 0;
#ifdef DOCH_DMA_CONFIG
FLDword gDMAChannelOpen = 0;
#endif /*DOCH_DMA_CONFIG*/
DOCH_DpdSettings gDpdSettings;
/* all DOCH sockets */
DOCH_Socket sockets [DOCH_MAX_SOCKETS];
#ifdef __cplusplus
}
#endif
/*
* static vars
*/
static DOCH_DeviceUserAttr devUserAttr;
static DOCH_ConfigRegsValue configRegValue;
static DOCH_ConfigRegsSet configRegValueSet;
static FLByte ataDBG[DOCH_SECTOR_SIZE];
static DOCH_DeviceInfo gDiskOnChipDeviceInfo;
#ifdef __cplusplus
extern "C" {
#endif
/*
* static routines
*/
static void clear_socket(DOCH_Socket * pdev);
static DOCH_Error ready(DOCH_Socket *pdev, FLSNative devNum, DOCH_Reg reg, FLByte mask, FLByte on_bits, FLDword millisec);
static DOCH_Error doch_find_base_address(FLSNative socketNo, FLDword Address);
#ifdef DOCH_CHECK_CHIP_ID
static DOCH_Error doch_check_chipID(FLSNative socketNo, FLSNative devNum);
#endif /*DOCH_CHECK_CHIP_ID*/
/*
* Internal routines
*/
DOCH_Error io_input(DOCH_Socket *pdev, FLSNative devNum, DOCH_Registers* regs, void *buf, FLNative secNum);
DOCH_Error io_output(DOCH_Socket *pdev, FLSNative devNum, DOCH_Registers* regs, void *buf, FLNative secNum);
DOCH_Error io_ctrl(DOCH_Socket *pdev, FLSNative devNum, DOCH_Registers* regs);
/*
* externals
*/
DOCH_Error get_out_registers(DOCH_Socket* pdev, FLSNative devNum, DOCH_Registers* out_regs);
extern DOCH_Error flUnRegisterDochParams(FLSNative socketNo);
extern FLDword gSdkDOCAddressObtained;
extern FLDword gConfigHWDefaults[DOCH_NUM_OF_DCONFIGHW_ITEMS];
extern FLDword gDochAtaDebug;
extern FLDword gSdkInitDone;
#ifdef DOCH_FORCE_USING_8KB
/******************************************************************************
* *
* s e t M e m W i n d o w S i z e 8 K B *
* *
* Set device memory window size to 8KB *
* *
* Parameters : *
* pdev : device to act on *
* *
******************************************************************************/
static
DOCH_Error dochSetMemWindowSize8KB(DOCH_Socket * pdev)
{
register int i = 0;
/*Step 0 - In case of PCI/PortaDoc EVB, set window offset to "0"*/
/*==============================================================*/
if(gAccessLayerType == DOCH_AL_NOR)
{
DOCH_SET_WINDOW_OFFSET(TRUE, pdev->bRegBase);
}
/* Exit virtual RAM mode */
DOCHWRITE_CTRL_REG (pdev->bRegBase, HIB_CHIPID2_REG, 0);
/*Step 1 - Enable paged registers
(Write 0x71 into Paged RAM Command register)*/
/*==================================================*/
DOCHWRITE_CTRL_REG (pdev->bRegBase, DOCH_PAGED_RAM_CMD_REG, 0x71);
/*Step 2 - Set window to 8KB mode with pull downs.
(Write 0x8 into Paged RAM COTP Select register)*/
/*======================================================*/
DOCHWRITE_CTRL_REG (pdev->bRegBase, DOCH_PAGED_RAM_COTP_SELECT_REG, 0x8);
/*Step 3 - Poll Paged RAM busy*/
/*============================*/
/* Perform a fixed delay before starting polling */
for (i=0; i<DOCH_READ_PAGED_RAM_DELAY; i++)
DOCHREAD_CTRL_REG(pdev->bRegBase, 0x400);
/* Loop until 2 consecutive reads produce the same value or until timeout */
for (i=0; i<DOCH_PAGED_RAM_TIMEOUT; i++)
{
FLByte bReadX,bReadY ;
bReadX = (FLByte)DOCHREAD_CTRL_REG(pdev->bRegBase, 0x400);
bReadY = (FLByte)DOCHREAD_CTRL_REG(pdev->bRegBase, 0x400);
if ((bReadX & 1)==(bReadY & 1))
break ;
}
if (i == DOCH_PAGED_RAM_TIMEOUT)
{
DBG_PRINT_ERR(FLZONE_ATA, "\r\nSetting Memory Window size timed out! \r\n");
return DOCH_TimedOut ;
}
DBG_PRINT_ERR(FLZONE_ATA, "\r\nMemory window set to 8KB \r\n");
return DOCH_OK;
}
#endif /*DOCH_FORCE_USING_8KB*/
/******************************************************************************
* *
* c l e a r _ s o c k e t *
* *
* Clears socket structure *
* *
* Parameters : *
* pdev : device to act on *
* *
******************************************************************************/
static
void clear_socket ( DOCH_Socket * pdev )
{
register FLSNative i = 0;
pdev->wSocketNo = 0;
pdev->wNumOfDevices = 0;
pdev->nTotalCapacity = 0;
pdev->wTotalNumOfPartitions = 0;
pdev->wLastPartitionSpanned = 0;
pdev->bUseDMA = 0;
pdev->bUseInterrupt = 0;
pdev->bUseBurst = 0;
pdev->bAtaDevNum = 0;
pdev->bRegBase = NULL;
for(i = 0; i<ATA_MAX_NUM_OF_DEVICES; i++)
{
pdev->device[i].wNumOfPartitions = 0;
pdev->device[i].ETFFS_Identified = FALSE;
/* we assume that multiple sector read/writes aren't supported */
pdev->device[i].dwMulti_read = DOCH_MULTI_DISABLED;
pdev->device[i].dwMulti_write = DOCH_MULTI_DISABLED;
pdev->device[i].dataTransferMode = DOCH_DATA_MODE_SINGLE;
}
}
#ifdef CHECK_POWER_ON_EVERY_COMMAND
/******************************************************************************
* *
* d o c h C h e c k P F S y m p t o m *
* *
* Wait until particular bit pattern appears in specified DOCH register *
* *
* Parameters : *
* pdev : device to act on *
* reg : DOCH register offset from base address *
* mask : bits we are interested in *
* on_bits : bits we are waiting to become '1' *
* millisec : timeout value in milliseconds *
* *
* Returns : *
* DOCH_OK in success, otherwise respective error code. *
* *
******************************************************************************/
DOCH_Error dochCheckPFSymptom(FLSNative socketNo, FLByte devNum, FLBoolean beforeCommand /* Used for debug prints */)
{
DOCH_Error rc;
DOCH_Socket* pdev = NULL;
DOCH_Registers in_regs;
FLByte resetOccured = 0;
if(!gSdkInitDone)
return DOCH_OK;
/* Sanity Check*/
/*=============*/
if(socketNo > DOCH_MAX_SOCKETS - 1)
return DOCH_BadParameter;
pdev = &sockets[socketNo];
/*Set Device Head register to appropriate device*/
DOCHWRITE_ATA_REG (pdev->bRegBase, DOCH_DRIVE_HEAD_REG, pdev->bAtaDevNum);
#ifdef DOCH_CHECK_CHIP_ID
/*Check ChipID to detect power failure ("Device Off") */
if(doch_check_chipID(socketNo, devNum) == DOCH_OK)
{
return DOCH_OK;
}
#endif /*DOCH_CHECK_CHIP_ID*/
/* Check reset status
Note: We DO NOT call DOCHGetResetStatus() to avoid recursion */
/*Update ATA register values*/
/*--------------------------*/
in_regs.bFeaturesError = DOCH_GET_RESET_STATUS;
in_regs.bSectorCount = 0;
in_regs.bSectorNumber = 0;
in_regs.bCylLow = 0;
in_regs.bCylHigh = 0;
in_regs.bDriveHead = (pdev->bAtaDevNum * DOCH_DEVICE);
in_regs.bCommandStatus = DOCH_VSCMD_EXT_DEVICE_CTRL;
gUseShortWaitOnBusy = DOCH_LONG_IDENTIFY_TIMEOUT;
rc = io_ctrl (pdev, devNum, &in_regs);
gUseShortWaitOnBusy = 0;
resetOccured = DOCHREAD_ATA_REG(pdev->bRegBase, DOCH_SECTOR_CNT_REG);
if(rc != DOCH_OK)
{
if(beforeCommand)
DBG_PRINT_ERR(FLZONE_ATA, "\r\ndoch_command(): DOCHGetResetStatus FAILED (Before Command)\r\n");
else
DBG_PRINT_ERR(FLZONE_ATA, "\r\ndoch_command(): DOCHGetResetStatus FAILED (After Command)\r\n");
gDeviceTurnedOff = TRUE;
return DOCH_DeviceTurnedOff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -