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

📄 docdrv.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 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/DocDriver/TrueFFS BD/src/docdrv.c-arc  $
 * 
 *    Rev 1.7   Nov 13 2006 15:13:48   Yaniv.Iarovici
 * Added environment variable - 'FL_DISABLE_MEMCPY'.
 * 
 *    Rev 1.6   Oct 30 2006 15:50:16   yaniv.iarovici
 * Add call to flDOCHIdentifyDiskOnChipDevice() after flInit() is completed
 * for updating actual number of partitions.
 * 
 *    Rev 1.5   Sep 11 2006 13:45:14   yaniv.iarovici
 * Legal header added
 * 
 *    Rev 1.4   Aug 22 2006 13:22:54   Yaniv.Iarovici
 * Bug fix: 'FL_DMA_HW_ENABLED' was NOT treated as bit but as a value in flInit().
 * 
 *    Rev 1.3   Aug 16 2006 08:43:26   Yaniv.Iarovici
 * Add support for Environment Variable: 'FL_SET_TRANSFER_MODE' - Controls DRQ size
 * 
 *    Rev 1.2   Aug 10 2006 10:39:48   Polina.Marimont
 * reinit fix
 * 
 *    Rev 1.1   Aug 10 2006 10:37:14   Polina.Marimont
 * bug fix - avoid initializing twice
 * 
 *    Rev 1.0   Aug 08 2006 15:47:22   Polina.Marimont
 * Initial revision.
 */
#include "flchkdef.h"
#include "flcommon.h"
#include "flstdcmp.h"
#include "blockdev.h"
#include "tffs_api.h"
#include "doch_api.h"
#include "doch_ata.h"
#include "bddefs.h"


#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

FLStatus bdSetBusy(Volume * pVol, FLBoolean state, FLByte  partition);

extern FLBoolean dochBdCallWasCalled;
#ifndef DOCH_USE_FUNC
FLFlash * DOCHFlash;
#endif /* DOCH_USE_FUNC */


bdCallType bdCall = bdCallTFFSToDOCH;
static FLBoolean fDocDriverInitDone = FALSE;


extern FLBoolean flPreventMemcpy;


/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flInit */
/* Description	    : */
/* Return type		: TFFS_DLL_API FLStatus */
/***********************************************************************************/
TFFS_DLL_API FLStatus NAMING_CONVENTION flInit()
{
#if (!defined(DOCH_USE_FUNC)) && (!defined (FL_NO_USE_FUNC))
    FLStatus flStatus;
	FLDword dwBusConfig = flBusConfig[0];
#endif /*!DOCH_USE_FUNC && !FL_NO_USE_FUNC*/
	DOCH_Error status_HDOC = DOCH_OK;
	DOCH_DeviceInfo tempDOCDI;
	IOreq ioreq;
	DOCH_Socket* pdev;
	DOCH_get_socket(pdev, 0);

	if( fDocDriverInitDone == TRUE )
		return flOK;

	_flInit();

	flSysfunInit();

    DBG_PRINT_FLOW(FLZONE_ABS, "Searching for H3 device... \r\n");

#ifndef DOCH_USE_FUNC
	/* Initialize DOCHFlash and redirect to regular MTD access layer */
	DOCHFlash = flFlashOf(0);
#ifndef FL_NO_USE_FUNC
	dwBusConfig |= FL_16BIT_DOC_ACCESS ;
	dwBusConfig |= FL_16BIT_FLASH_ACCESS ;
	dwBusConfig |= FL_BUS_HAS_16BIT_ACCESS;
    flStatus = setBusTypeOfFlash(DOCHFlash,dwBusConfig);
	if(flStatus != flOK)
		return flStatus;
#endif /* FL_NO_USE_FUNC */
#endif /* DOCH_USE_FUNC */

	status_HDOC = DochSDKInit();
	if(status_HDOC == DOCH_OK) /*DOCH Device*/
	{
		DBG_PRINT_FLOW(FLZONE_ABS, "H3 Device found !!! \r\n\n");
		bdCall = bdCallTFFSToDOCH;
#ifdef FL_DMA_INIT
		{
			IOreq myIoreq;
			FLByte bDmaInit = FL_DMA_INIT(0);
			if( (bDmaInit & FL_DMA_HW_ENABLED) == FL_DMA_HW_ENABLED ) /*if DMA enabled by default -> set this to SA SDK*/
			{
				tffsset(&myIoreq, 0, sizeof(myIoreq));
				myIoreq.irFlags = DOCH_DMA_ENABLE;
				myIoreq.irLength = TRUE;
				status_HDOC = flDOCHConfigHW(&myIoreq);
				if( status_HDOC!=DOCH_OK )
				{
					DBG_PRINT_FLOW_PRM(FLZONE_ABS, (FLTXT("Fail to enable DMA with status %d \r\n"),status_HDOC));
				}
			}
		}
#endif /*FL_DMA_INIT*/

		/* Update number of partitions*/
		tffsset(&ioreq, 0, sizeof(ioreq));
		ioreq.irData = &tempDOCDI;
		status_HDOC = flDOCHIdentifyDiskOnChipDevice(&ioreq);
		pdev->wTotalNumOfPartitions = tempDOCDI.wTotalNumOfPartitions;

		if( status_HDOC==DOCH_OK )
			fDocDriverInitDone = TRUE;

		return (status_HDOC==DOCH_OK)?flOK:((status_HDOC==DOCH_DiskNotFound)?flAdapterNotFound:flGeneralFailure); 
    }


	DBG_PRINT_FLOW(FLZONE_ABS, "\r\n*** Exiting flInit() ***\r\n\n\n");

	return flAdapterNotFound;
}/* flInit() */

#ifdef FL_EXIT

/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flExit*/
/* Description	    : */
/* Return type		: TFFS_DLL_API void */
/***********************************************************************************/
TFFS_DLL_API void NAMING_CONVENTION flExit()
{
	tffsApiExit();
	dochBdCallWasCalled = FALSE;
	fDocDriverInitDone = FALSE;
}/*flExit()*/
#endif /*FL_EXIT*/

#ifdef FL_ENVIRONMENT_VARS

/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flSetEnvVolume */
/* Description	    :  */
/* Return type		: TFFS_DLL_API FLStatus  */
/* Argument         : FLEnvVars variableType */
/* Argument         : FLByte  socket */
/* Argument         : FLByte  volume */
/* Argument         : FLDword value */
/* Argument         : FLDword FAR2 *prevValue */
/***********************************************************************************/
TFFS_DLL_API FLStatus NAMING_CONVENTION flSetEnvVolume(FLEnvVars variableType, FLByte  socket, FLByte  volume,
													    FLDword value, FLDword FAR2 *prevValue)
{
    IOreq ioreq;

    ioreq.irHandle = socket + (volume << 4);
    /*For utilities which uses env vars on legacy devices and not needed for H3*/
    if ((variableType == FL_DEBUG_MODES) ||
        (variableType == FL_SUSPEND_MODE) ||
        (variableType == FL_DIMAGE_CFG))
        return flOK;

	if(variableType == FL_SET_TRANSFER_MODE)
	{
		tffsset(&ioreq, 0, sizeof(ioreq));
		/*Fill ioreq structure according to flDOCHSetDataTransferMode API*/
		/*Single sector transfer mode*/
		if(value == 1)
		{
			ioreq.irCount = DOCH_DATA_XFER_MODE_SINGLE;
		}
		/*Multi-sector transfer mode*/
		else
		{
			ioreq.irCount = DOCH_DATA_XFER_MODE_MULT;
			ioreq.irLength = value;
		}

		/*Set requested Transfer Mode and Length*/
		if (flDOCHSetDataTransferMode(&ioreq) == DOCH_OK)
			return flOK;
		
		/*If the operation failed*/
		return flFeatureNotSupported;
	}
    else if (variableType == FL_ENV_ATA_DEBUG)
        ioreq.irFlags = DOCH_ENV_ATA_DEBUG;
	else if(variableType == FL_DISABLE_MEMCPY)
			flPreventMemcpy = value;
    else
	{
		switch(variableType)
		{
		case FL_VERIFY_WRITE_BDTL:
		case FL_VERIFY_WRITE_BINARY:
		case FL_VERIFY_WRITE_OTHER:
			ioreq.irFlags = DOCH_ENV_VERIFY_WRITE;
			break;
#if (defined(FL_VERIFY_WRITE) || !defined(FL_NO_USE_FUNC) | defined(FL_BD_AUTO_DPD_MODE))
		case FL_SET_AUTO_DPD_MODE:
#ifndef DOCH_AUTO_DPD_BY_HOST
		case FL_SET_ACTIVE_DPD_MODE:
		case FL_SET_INACTIVE_DPD_MODE:
		case FL_SET_TIMEOUT_DPD:
#endif /*DOCH_AUTO_DPD_BY_HOST*/
			return tffsApiSetAutoDpd(variableType, (FLSDword)socket, value, prevValue);
#endif /*(defined(FL_VERIFY_WRITE) || !defined(FL_NO_USE_FUNC) | defined (FL_BD_AUTO_DPD_MODE))*/
		default:
			ioreq.irFlags = 0;
		}/*switch*/
	}
    ioreq.irLength = value;
	if (flDOCHSetEnvVar(&ioreq) == DOCH_OK)
        return flOK;
    return flFeatureNotSupported;
}/*flSetEnvVolume()*/


/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flSetEnvSocket*/
/* Description	    : */
/* Return type		: TFFS_DLL_API FLStatus */
/* Argument         : FLEnvVars variableType*/
/* Argument         : FLByte  socket*/
/* Argument         : LDword value*/
/* Argument         : FLDword FAR2 *prevValue*/
/***********************************************************************************/
TFFS_DLL_API FLStatus NAMING_CONVENTION flSetEnvSocket(FLEnvVars variableType, FLByte  socket, 
													   FLDword value, FLDword FAR2 *prevValue)
{
	return flSetEnvVolume(variableType, socket, 0, value, prevValue);
}/*flSetEnvSocket()*/


/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flSetEnvAll */
/* Description	    : */
/* Return type		: TFFS_DLL_API FLStatus */
/* Argument         : FLEnvVars variableType */
/* Argument         : FLDword value */
/* Argument         : FLDword FAR2 *prevValue */
/***********************************************************************************/
TFFS_DLL_API FLStatus NAMING_CONVENTION flSetEnvAll( FLEnvVars variableType,FLDword value, 
													 FLDword FAR2 *prevValue)
{
    return flSetEnvVolume(variableType, 0, 0, value, prevValue);
}/*flSetEnvAll*/
#endif /*FL_ENVIRONMENT_VARS*/

#ifndef FL_NO_USE_FUNC


/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flGetDocBusRoutine*/
/* Description	    : */
/* Return type		: TFFS_DLL_API FLStatus */
/* Argument         : FLByte  socket */
/* Argument         : FLAccessStruct FAR1 * structPtr */
/***********************************************************************************/
TFFS_DLL_API FLStatus NAMING_CONVENTION flGetDocBusRoutine(FLByte  socket, FLAccessStruct FAR1 * structPtr)
{
	FLFlash* flash;

	/* Arg sanity check */
#ifndef FL_SKIP_ARGS_CHECK
	if (socket >= FL_SOCKETS)
	{
		DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - Change FL_SOCKETS definition in flcustom.h to support that many sockets.\r\n");
		return flFeatureNotSupported;
	}
	if(structPtr == NULL)
	{
		DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - structPtr argument is NULL.\r\n");
		return flBadParameter;
	}
#endif /* FL_SKIP_ARGS_CHECK */

	/* Make sure global variables are initialized to their default values */
	flInitGlobalVars();

	flash = flFlashOf(socket);

	structPtr->memWindowSize = flash->memWindowSize;
	structPtr->memRead       = flash->memRead;
	structPtr->memWrite      = flash->memWrite;
	structPtr->memSet        = flash->memSet;
	structPtr->memRead8bit   = flash->memRead8bit;
	structPtr->memRead16bit  = flash->memRead16bit;
	structPtr->memWrite8bit  = flash->memWrite8bit;
	structPtr->memWrite16bit = flash->memWrite16bit;
	structPtr->memSetGetMode = flash->memSetGetMode;
	structPtr->access        = flBusConfig[socket];

	return flOK;
}/*flGetDocBusRoutine()*/


/***********************************************************************************/
/* Function name	: NAMING_CONVENTION flSetDocBusRoutine*/
/* Description	    : */
/* Return type		: TFFS_DLL_API FLStatus */
/* Argument         : FLByte  socket*/
/* Argument         : FLAccessStruct FAR1 * structPtr*/
/***********************************************************************************/
TFFS_DLL_API FLStatus NAMING_CONVENTION flSetDocBusRoutine(FLByte  socket,FLAccessStruct FAR1 * structPtr)
{
   FLFlash* flash;

   /* Arg sanity check */
#ifndef FL_SKIP_ARGS_CHECK
   if (socket >= FL_SOCKETS)
   {
      DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - Change FL_SOCKETS definition in flcustom.h to support that many sockets.\r\n");
      return flFeatureNotSupported;
   }
   if(structPtr == NULL)
   {
      DBG_PRINT_ERR(FLZONE_BLKDEV,"ERROR - structPtr argument is NULL.\r\n");
      return flBadParameter;
   }
#endif /* FL_SKIP_ARGS_CHECK */

   /* Make sure global variables are initialized to their default values */
   flInitGlobalVars();

   flash = flFlashOf(socket);

   flash->memWindowSize = structPtr->memWindowSize;
   flash->memRead       = structPtr->memRead;
   flash->memWrite      = structPtr->memWrite;
   flash->memSet        = structPtr->memSet;
   flash->memRead8bit   = structPtr->memRead8bit;
   flash->memRead16bit  = structPtr->memRead16bit;
   flash->memWrite8bit  = structPtr->memWrite8bit;
   flash->memWrite16bit = structPtr->memWrite16bit;
   flash->memSetGetMode = structPtr->memSetGetMode;
   flBusConfig[socket]  = FL_ACCESS_USER_DEFINED;
   return flOK;
}/*flSetDocBusRoutine*/

#endif /*FL_NO_USE_FUNC*/

#ifdef __cplusplus
}
#endif /* __cplusplus */

/* ----------------------------------------------------------------------------------- */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -