📄 doch_ata.c
字号:
/****************************************************************************** * * * Project: DOC Driver for Linux 2.4 Block device driver for mDOC H3 family * * of devices under Linux kernel 2.4. * * * * Version: 1.0 * * Email questions to: oemsupport@sandisk.com * * Copyright (C) SanDisk IL Ltd. 1995 - 2007 * * SanDisk IL Ltd., 7 Atir Yeda Street, Kfar Saba 44425, Israel * * * ****************************************************************************** * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation; either version 2 of the License, or any later version.* * This program is distributed in the hope that it will be useful, but WITHOUT* * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details, which is set forth in the readme.txt file. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., 51 * * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * * * This License does not grant you any right to use the trademarks, service * * marks or logos of SanDisk IL Ltd. or SanDisk Corporation. * * Subject to the foregoing, SanDisk IL Ltd., for itself and on behalf of its * * licensors, hereby reserves all intellectual property rights in the program,* * except for the rights expressly granted in this License. * * * ******************************************************************************//*
* $Log: V:/PVCSDB/DiskOnChip/archives/Test for 7.x/src/H3/doch_ata.c-arc $
*
* Rev 1.57.2.5 Dec 04 2006 12:44:40 Yaniv.Iarovici
* Add ; to MACRO
*
* Rev 1.57.2.4 Nov 30 2006 10:23:46 Yaniv.Iarovici
* Added DOCH_WAIT_B4_DEV1_ID (anchor for setting a delay between Dev0 and Dev1 ID process).
*
* Rev 1.57.2.3 Nov 21 2006 14:26:22 Yaniv.Iarovici
* 1. Typo in comments
* 2. Check ChipID before applying ATA reset.
*
* Rev 1.57.2.2 Nov 12 2006 09:46:52 Yaniv.Iarovici
* 1. Fixed compilation warnings.
* 2. doch_reset():
* - Added parameter 'FLBoolean waitOnBusy'.
* - Wait for BUSY signal in ATA status register de-assertion before sending SRST, if waitOnBusy is TRUE.
*
* Rev 1.57.2.1 Oct 31 2006 12:23:32 yaniv.iarovici
* Added doch_init_window().
*
* Rev 1.57.2.0 Oct 29 2006 11:28:54 Yaniv.Iarovici
* Fixed compilation warning.
*
* Rev 1.57 Oct 05 2006 11:00:36 yaniv.iarovici
* 1. Removed dwMulti_Read, dwMulti_Write.
* 2. Added dwMulti_MAX.
*
* 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_MAX = 0;
pdev->device[i].dataTransferMode = DOCH_DATA_MODE_SINGLE;
pdev->device[i].dwSpare1 = 0;
}
}
#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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -