⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doch_ata.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************** *                                                                            * * 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 + -