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

📄 extfiltr.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** *                                                                            * * 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$ */#include "tffsdrv.h"#ifndef TFFS_DEBUG_EXTFILTER# undef TFFS_DEBUG_DRIVER#endif/* min:  0x40000  == sect>>9  == 256 blocks/group * 1024 bytes/blocktypical: 0x800000 == sect>>15 == 8192 blocks/group * 1024 bytes/blockdefault: 0x100000 == sect>>12 == 1M */# define TFFS_EXTF_CACHE_STEP 12#define EXTF_CACHE_MASK	((1<<TFFS_EXTF_CACHE_STEP)-1)/* blocks per group must be multiple of 8, >= 256, <= 8*blocksize *//* all offsets of SB/GD are including first empty block, block bitmap doesn't */#ifdef TFFS_USE_RAM# include "tffsram.h"#else# include "blockdev.h"#endifstatic unsigned char pTmp[512];#ifdef TFFS_DEBUG_DRIVERstatic unsigned long dwSearches=0,dwSteps=0;#endifunsigned char ExtReadSector(DeviceInfo*pDevice,unsigned long dwSector,unsigned char*p);unsigned char ExtDelSector(DeviceInfo*pDevice,unsigned long dwSector,unsigned char bSectors);void AddSect(DeviceInfo*pDevice,SectInfo*pSect);SectInfo*DelSect(DeviceInfo*pDevice,SectInfo*pSect);void CacheSect(DeviceInfo*pDevice,SectInfo*pSect);void UncacheSect(DeviceInfo*pDevice,SectInfo*pSect);#define PTChanged(pSect,pData) 1void AddPT(DeviceInfo*pDevice,SectInfo*pSect,unsigned char*pBuff);void DelPT(DeviceInfo*pDevice,SectInfo*pPT);#ifdef TFFS_DEBUG_DRIVERunsigned char SBChanged(SectInfo*pSect,struct ext2_super_block*pSB){	if(le32_to_cpu(pSB->s_log_block_size) != pSect->bSect2BlockShift-1)	{		PrintkDebug("SBChanged: s_log_block_size different: %d -> %d",(int)pSect->bSect2BlockShift-1,(int)pSB->s_log_block_size);		return 1;	}	if(le32_to_cpu(pSB->s_blocks_per_group) != pSect->dwBlocksPerBitmap)	{		PrintkDebug("SBChanged: s_blocks_per_group different: %d -> %d",(int)pSect->dwBlocksPerBitmap,(int)pSB->s_blocks_per_group);		return 1;	}	if(pSB->s_feature_compat != pSect->dwExt3Flags)	{		PrintkDebug("SBChanged: s_feature_compat different: %d -> %d",(int)pSect->dwExt3Flags,(int)pSB->s_feature_compat);		return 1;	}	PrintkDebug("SBChanged: not changed");	return 0;}#else# define SBChanged(pSect,pSB) ( ( le32_to_cpu((pSB)->s_log_block_size) != (pSect)->bSect2BlockShift-1 ) || ( le32_to_cpu((pSB)->s_blocks_per_group) != (pSect)->dwBlocksPerBitmap ) || ((pSB)->s_feature_compat!=(pSect)->dwExt3Flags))#endifvoid AddSB(DeviceInfo*pDevice,SectInfo*pSect,struct ext2_super_block*pSB);void DelSB(DeviceInfo*pDevice,SectInfo*pPart);void AddGD(DeviceInfo*pDevice,SectInfo*pSect,struct ext2_group_desc*pGD,unsigned char bOffset);void ProcessBB(DeviceInfo*pDevice,SectInfo*pSect,unsigned char*pOld,unsigned char*pNew,unsigned char bOffset);#ifdef TFFS_DEBUG_DRIVERvoid PrintSect(SectInfo*pSect,char*p){	char*str;	switch(pSect->bFlag)	{	case EXTF_PT:		str="PT empty";		break;	case EXTF_HAS_PT:		str="PT";		break;	case EXTF_SB:		str="SB empty";		break;	case EXTF_HAS_SB:		str="SB";		break;	case EXTF_HAS_GD:		str="SB&GD";		break;	case EXTF_BB:		str="BB not adjusted";		break;	case EXTF_HAS_BB:		str="BB";		break;	case 0:		str="last sect";		break;	default:		str="BAD FLAG";	}	PrintkDebug("%s: %s part %d sect %lu len %u flag %d",p,str,pSect->no,pSect->dwSector,pSect->bSectors,pSect->bFlag);}void PrintAllSect(DeviceInfo*pDevice){	SectInfo*pSect=&pDevice->sect[0];	do{		PrintSect(pSect,"LIST");		pSect=pSect->pNext;	}while(pSect!=&pDevice->sect[0]);}void Printp(unsigned char*p){	int i,k;	for(i=0;i<32;i++)	{		for(k=0;k<16;k++)			printk("%2x ",*(p+((i<<4)+k)));		printk("\n");	}}#else# define PrintAllSect(pDevice)# define PrintSect(pSect,p)# define Printp(p)#endifvoid ExtFilter(DeviceInfo*pDevice,unsigned char*pBuff,unsigned long dwSector,unsigned long dwSectors){	SectInfo*pSect=pDevice->pCache[dwSector>>TFFS_EXTF_CACHE_STEP];	unsigned long dwSect=dwSector;	PrintkDebug("ExtFilter: dev %d sec 0x%lx + 0x%lx",pDevice->diskNo,dwSector,dwSectors);	while(dwSect<dwSectors+dwSector)	{		unsigned char*pData;		while(dwSect>=pSect->dwSector+pSect->bSectors)			pSect=pSect->pNext;		if(dwSect>=pSect->dwSector+pSect->bSectors || dwSect+dwSectors<=pSect->dwSector)			return;		if(dwSect<pSect->dwSector)			dwSect=pSect->dwSector;		PrintkDebug("ExtFilter: sec 0x%lx",dwSect);/*		PrintkDebug("ExtFilter sec %lu + %lu: found %lu of %lu + %d",dwSector,dwSectors,dwSect,pSect->dwSector,pSect->bSectors); *//*		PrintSect(pSect,"ExtFilter: found"); */		pData=pBuff+((dwSect-dwSector)<<9);		switch(pSect->bFlag)		{		case EXTF_PT:			PrintkDebug("ExtFilter: EXTF_PT");			AddPT(pDevice,pSect,pData);			dwSect=pSect->pNext->dwSector;			break;		case EXTF_HAS_PT:			PrintkDebug("ExtFilter: EXTF_HAS_PT");			if(PTChanged(pSect,pData))			{				DelPT(pDevice,pSect);				AddPT(pDevice,pSect,pData);			}			dwSect=pSect->pNext->dwSector;			break;		case EXTF_SB:			PrintkDebug("ExtFilter: EXTF_SB");			AddSB(pDevice,pSect,(struct ext2_super_block*)pData);			dwSect++;			break;		case EXTF_HAS_SB:			PrintkDebug("ExtFilter: EXTF_HAS_SB");			if(dwSect==pSect->dwSector)		/* SB changed */			{				if(SBChanged(pSect,(struct ext2_super_block*)pData))					AddSB(pDevice,pSect,(struct ext2_super_block*)pData);				dwSect+=2;			}			else			{				if(dwSect>=pSect->dwSector+(pSect->bSect2BlockShift==3?6:2))	/* GD added */				{					AddGD(pDevice,pSect,(struct ext2_group_desc*)pData,dwSect-(pSect->dwSector+(pSect->bSect2BlockShift==3?6:2)));				}				dwSect++;			}			break;		case EXTF_HAS_GD:					/* ignore GD changes */			PrintkDebug("ExtFilter: EXTF_HAS_GD");			if(SBChanged(pSect,(struct ext2_super_block*)pData))			{				DelSB(pDevice,pSect);				AddSB(pDevice,pSect,(struct ext2_super_block*)pData);			}			dwSect=pSect->pNext->dwSector;			break;		case EXTF_BB:			PrintkDebug("ExtFilter: EXTF_BB");			/* do nothing */			dwSect=pSect->pNext->dwSector;			break;			return;		case EXTF_HAS_BB:			PrintkDebug("ExtFilter: EXTF_HAS_BB");			if(ExtReadSector(pDevice,dwSect,pTmp))				ProcessBB(pDevice,pSect,pTmp,pData,dwSect-pSect->dwSector);			dwSect++;			break;#ifdef TFFS_DEBUG_DRIVER		default:			PrintkDebug("ExtFilter: wrong case %d",pSect->bFlag);			dwSect++;#endif		}	}	PrintkDebug("ExtFilter:exit");}void ExtFilterInit(DeviceInfo*pDevice){	unsigned short wCache,wCacheSize;	PrintkDebug("ExtFilterInit");	/* init first and last sectors */	pDevice->sect[0].dwSector=0;	pDevice->sect[0].bSectors=1;	pDevice->sect[0].pParent=NULL;	pDevice->sect[0].pPrev=pDevice->sect[0].pNext=&pDevice->sect[1];	pDevice->sect[0].bFlag=EXTF_PT;	pDevice->sect[0].dwOffset=0;	pDevice->sect[1].dwSector=0xffffffff;	pDevice->sect[1].bSectors=0;	pDevice->sect[1].pParent=NULL;	pDevice->sect[1].pPrev=pDevice->sect[1].pNext=&pDevice->sect[0];	pDevice->sect[1].bFlag=0;	pDevice->sect[1].dwOffset=0;#ifdef TFFS_DEBUG_DRIVER	pDevice->sect[0].no=0;	pDevice->sect[1].no=0;#endif	/* init hash */	wCacheSize=(pDevice->dwSize >> TFFS_EXTF_CACHE_STEP) + 1;	PrintkDebug("ExtFilterInit: cache len %u",wCacheSize);	pDevice->pCache=KMalloc(sizeof(SectInfo*)*wCacheSize);	if(pDevice->pCache==NULL)		return;	pDevice->pCache[0]=&pDevice->sect[0];	for(wCache=1;wCache<wCacheSize;wCache++)		pDevice->pCache[wCache]=&pDevice->sect[1];	ExtReadSector(pDevice,0,pTmp);	AddPT(pDevice,&pDevice->sect[0],pTmp);	PrintAllSect(pDevice);}void ExtFilterRelease(DeviceInfo*pDevice){	PrintkDebug("ExtFilterRelease: %lu times, %lu steps, average %lu",dwSearches,dwSteps,(dwSearches!=0)?dwSteps/dwSearches:0);	PrintAllSect(pDevice);	DelPT(pDevice,&pDevice->sect[0]);	if(pDevice->pCache!=NULL)	{		kfree(pDevice->pCache);		pDevice->pCache=NULL;	}}void AddPT(DeviceInfo*pDevice,SectInfo*pSect,unsigned char*pBuff){	SectInfo*pPT=pSect;	unsigned char*pPTData,*pPartData;	pPTData=KMalloc(1024);	if(pPTData==NULL)		return;	memcpy(pPTData,pBuff,512);	pPartData=pPTData+512;	while(pPT!=NULL)	{		unsigned char bPart;		SectInfo*pNextPT=NULL;		PrintkDebug("AddPT %d",pPT->no);		if(pPTData[510]!=0x55 || pPTData[511]!=0xaa)		{			PrintkDebug("AddPT %d: no signature",pPT->no);			pPT->bFlag=EXTF_PT;			return;		}		PrintkDebug("AddPT %d: signature found",pPT->no);		pPT->bFlag=EXTF_HAS_PT;		for(bPart=0;bPart<4;bPart++)		{			SectInfo*pPart;			unsigned char*pData=pPTData+(446+bPart*16);			if(*(pData+4)==0)			{				PrintkDebug("AddPT %d: empty partition %d",pPT->no,bPart);				continue;			}			pPart=KMalloc(sizeof(SectInfo));			if(pPart==NULL)

⌨️ 快捷键说明

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