mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-28 22:02:25 +02:00
the forgotten one :)
This commit is contained in:
parent
2d3cd80303
commit
6e1aa6e45c
@ -1,531 +0,0 @@
|
|||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/vmalloc.h>
|
|
||||||
#include <linux/hdreg.h>
|
|
||||||
#include <linux/mtd/mtd.h>
|
|
||||||
#include <linux/mtd/nand.h>
|
|
||||||
#include <linux/mtd/blktrans.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <asm/jzsoc.h>
|
|
||||||
|
|
||||||
#define CACHE_MAX_NUM 256
|
|
||||||
#define SECTOR_SIZE 512
|
|
||||||
|
|
||||||
//#define UDC_CACHE_DEBUG
|
|
||||||
|
|
||||||
#ifdef UDC_CACHE_DEBUG
|
|
||||||
#define dprintk(a...) printk(a)
|
|
||||||
#else
|
|
||||||
#define dprintk(a...) while(0){}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned short CacheState;
|
|
||||||
unsigned short UseCount;
|
|
||||||
unsigned short CacheChange;
|
|
||||||
unsigned short CacheReserve;
|
|
||||||
unsigned int BlockId;
|
|
||||||
unsigned char *aBlockData;
|
|
||||||
} SSFDC__LB_CACHE;
|
|
||||||
|
|
||||||
#define FREE_CACHE 0
|
|
||||||
#define PREWRITE_CACHE 2
|
|
||||||
#define OFTEN_USE_CACHE 3
|
|
||||||
#define SECTOR_SHIFT 9
|
|
||||||
|
|
||||||
#define CACHE_TO_UNCATCH(x) ((unsigned int)x | 0xa0000000)
|
|
||||||
static unsigned int __aBlockData[SECTOR_SIZE * CACHE_MAX_NUM / 4] __attribute__ ((aligned (32)));
|
|
||||||
static SSFDC__LB_CACHE ssfdc_cache[CACHE_MAX_NUM];
|
|
||||||
static unsigned short Cur_CacheCount = 0;
|
|
||||||
int FlushDataState = 0;
|
|
||||||
static struct mtdblk_dev *g_udc_mtdblk;
|
|
||||||
static struct mtd_info *g_udc_mtd;
|
|
||||||
|
|
||||||
extern int udc_mtdblock_readsect(struct mtdblk_dev *, unsigned long, char *, int);
|
|
||||||
extern int udc_mtdblock_writesect(struct mtdblk_dev *, unsigned long, char *);
|
|
||||||
extern struct mtdblk_dev *udc_get_mtdblk(void);
|
|
||||||
extern struct mtd_info *udc_get_mtd(void);
|
|
||||||
extern void udc_flush_cache(struct mtdblk_dev *mtdblk);
|
|
||||||
|
|
||||||
#define _NAND_LB_Write(pCache) udc_mtdblock_writesect(g_udc_mtdblk, pCache->BlockId,pCache->aBlockData)
|
|
||||||
#define _NAND_LB_Read(Sector,pBuffer) udc_mtdblock_readsect(g_udc_mtdblk, Sector, pBuffer, SECTOR_SIZE);
|
|
||||||
|
|
||||||
#define DMA_ENABLE 0
|
|
||||||
|
|
||||||
#if DMA_ENABLE
|
|
||||||
#define DMA_CHANNEL 5
|
|
||||||
#define PHYSADDR(x) virt_to_phys((void *)x)
|
|
||||||
#else
|
|
||||||
#define lb_memcpy memcpy
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DMA_ENABLE
|
|
||||||
static void lb_memcpy(void *target,void* source,unsigned int len)
|
|
||||||
{
|
|
||||||
int ch = DMA_CHANNEL;
|
|
||||||
if(((unsigned int)source < 0xa0000000) && len)
|
|
||||||
dma_cache_wback_inv((unsigned long)source, len);
|
|
||||||
if(((unsigned int)target < 0xa0000000) && len)
|
|
||||||
dma_cache_wback_inv((unsigned long)target, len);
|
|
||||||
|
|
||||||
REG_DMAC_DSAR(ch) = PHYSADDR((unsigned long)source);
|
|
||||||
REG_DMAC_DTAR(ch) = PHYSADDR((unsigned long)target);
|
|
||||||
REG_DMAC_DTCR(ch) = len / 32;
|
|
||||||
REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AUTO;
|
|
||||||
REG_DMAC_DCMD(ch) = DMAC_DCMD_SAI| DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32|DMAC_DCMD_DS_32BYTE;
|
|
||||||
REG_DMAC_DCCSR(ch) = DMAC_DCCSR_EN | DMAC_DCCSR_NDES;
|
|
||||||
while ( REG_DMAC_DTCR(ch) );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void _NAND_LB_InitCache(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
SSFDC__LB_CACHE *pCache = ssfdc_cache;
|
|
||||||
#if DMA_ENABLE
|
|
||||||
unsigned char * ptr = (unsigned char *)CACHE_TO_UNCATCH(__aBlockData);
|
|
||||||
#else
|
|
||||||
unsigned char * ptr = (unsigned char *)(__aBlockData);
|
|
||||||
#endif
|
|
||||||
for(i = 0;i < CACHE_MAX_NUM;i++)
|
|
||||||
{
|
|
||||||
pCache->CacheState = FREE_CACHE;
|
|
||||||
pCache->UseCount = 0;
|
|
||||||
pCache->CacheChange = 0;
|
|
||||||
pCache->aBlockData = ptr;
|
|
||||||
ptr+=SECTOR_SIZE;
|
|
||||||
pCache++;
|
|
||||||
}
|
|
||||||
Cur_CacheCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SSFDC__LB_CACHE * _NAND_LB_GetFreeCache(void)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
SSFDC__LB_CACHE *pCacheInfo = &ssfdc_cache[Cur_CacheCount];
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(ret >= CACHE_MAX_NUM)
|
|
||||||
return 0;
|
|
||||||
if(pCacheInfo >= &ssfdc_cache[CACHE_MAX_NUM])
|
|
||||||
{
|
|
||||||
pCacheInfo = ssfdc_cache;
|
|
||||||
Cur_CacheCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pCacheInfo->CacheState == FREE_CACHE)
|
|
||||||
{
|
|
||||||
return pCacheInfo;
|
|
||||||
}
|
|
||||||
pCacheInfo++;
|
|
||||||
Cur_CacheCount++;
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _NAND_LB_CloseCACHES(unsigned int sectorstart,unsigned int sectorend)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
SSFDC__LB_CACHE *pCache = ssfdc_cache;
|
|
||||||
for( i = 0;i < CACHE_MAX_NUM;i++){
|
|
||||||
if((pCache->CacheState != FREE_CACHE) && (pCache->BlockId >= sectorstart) && (pCache->BlockId < sectorend)){
|
|
||||||
pCache->CacheChange = 0;
|
|
||||||
pCache->CacheState = FREE_CACHE;
|
|
||||||
pCache->UseCount = 0;
|
|
||||||
}
|
|
||||||
pCache++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _NAND_LB_FLUSHCACHES(unsigned int sectorstart,unsigned int sectorend)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
SSFDC__LB_CACHE *pCache = ssfdc_cache;
|
|
||||||
for( i = 0;i < CACHE_MAX_NUM;i++){
|
|
||||||
if((pCache->CacheState != FREE_CACHE) && (pCache->BlockId >= sectorstart) && (pCache->BlockId < sectorend)){
|
|
||||||
if(pCache->CacheChange)
|
|
||||||
_NAND_LB_Write(pCache);
|
|
||||||
pCache->CacheChange = 0;
|
|
||||||
pCache->CacheState = FREE_CACHE;
|
|
||||||
pCache->UseCount = 0;
|
|
||||||
}
|
|
||||||
pCache++;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int Get_NAND_CacheFreeCount(void)
|
|
||||||
{
|
|
||||||
SSFDC__LB_CACHE *pCache = ssfdc_cache;
|
|
||||||
SSFDC__LB_CACHE *pEndCache = &ssfdc_cache[CACHE_MAX_NUM];
|
|
||||||
unsigned int count = 0;
|
|
||||||
while(pCache < pEndCache)
|
|
||||||
{
|
|
||||||
if(pCache->CacheState == FREE_CACHE)
|
|
||||||
count++;
|
|
||||||
pCache++;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int _NAND_LB_PreWiteToNand(SSFDC__LB_CACHE *pCache,unsigned short *count,unsigned int update)
|
|
||||||
{
|
|
||||||
SSFDC__LB_CACHE *pWriteCache;
|
|
||||||
SSFDC__LB_CACHE *pEndCache = &ssfdc_cache[CACHE_MAX_NUM];
|
|
||||||
unsigned int sector = -1;
|
|
||||||
unsigned int flag;
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
sector = -1;
|
|
||||||
flag = 0;
|
|
||||||
pWriteCache = ssfdc_cache;
|
|
||||||
while(pWriteCache < pEndCache)
|
|
||||||
{
|
|
||||||
if(pWriteCache->CacheState == update) //PREWRITE_CACHE
|
|
||||||
{
|
|
||||||
if(pWriteCache->BlockId < sector)
|
|
||||||
{
|
|
||||||
sector = pWriteCache->BlockId;
|
|
||||||
pCache = pWriteCache;
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
flag++;
|
|
||||||
pWriteCache++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(flag < CACHE_MAX_NUM)
|
|
||||||
{
|
|
||||||
if(pCache->CacheChange)
|
|
||||||
{
|
|
||||||
_NAND_LB_Write(pCache);
|
|
||||||
pCache->CacheChange = 0;
|
|
||||||
}
|
|
||||||
pCache->CacheState = FREE_CACHE;
|
|
||||||
pCache->UseCount = 0;
|
|
||||||
(*count)++;
|
|
||||||
}else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _NAND_LB_OftenToNand(SSFDC__LB_CACHE *pCache,unsigned short *count,unsigned int update)
|
|
||||||
{
|
|
||||||
SSFDC__LB_CACHE *pWriteCache = pCache;
|
|
||||||
SSFDC__LB_CACHE *pOldCache = pCache;
|
|
||||||
SSFDC__LB_CACHE *pEndCache = &ssfdc_cache[CACHE_MAX_NUM];
|
|
||||||
|
|
||||||
dprintk("%s!\n",__FUNCTION__);
|
|
||||||
while(pCache)
|
|
||||||
{
|
|
||||||
if(pCache->CacheState == OFTEN_USE_CACHE)
|
|
||||||
{
|
|
||||||
if(pWriteCache->CacheState != OFTEN_USE_CACHE)
|
|
||||||
pWriteCache = pCache;
|
|
||||||
else if(pWriteCache->UseCount > pCache->UseCount)
|
|
||||||
{
|
|
||||||
pWriteCache = pCache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pCache++;
|
|
||||||
if(pCache >= pEndCache)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(pWriteCache->CacheState == OFTEN_USE_CACHE)
|
|
||||||
{
|
|
||||||
(*count)++;
|
|
||||||
if(pWriteCache->CacheChange)
|
|
||||||
_NAND_LB_Write(pWriteCache);
|
|
||||||
pWriteCache->CacheState = FREE_CACHE;
|
|
||||||
|
|
||||||
pWriteCache->UseCount = 0;
|
|
||||||
pWriteCache->CacheChange = 0;
|
|
||||||
if(update != -1)
|
|
||||||
update--;
|
|
||||||
if(update != 0)
|
|
||||||
_NAND_LB_OftenToNand(pOldCache,count,update);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _NAND_LB_FreeCache(unsigned int update)
|
|
||||||
{
|
|
||||||
unsigned short freecount = 0,totalfree = 0;
|
|
||||||
|
|
||||||
freecount = 0;
|
|
||||||
_NAND_LB_PreWiteToNand(ssfdc_cache,&freecount,PREWRITE_CACHE);
|
|
||||||
|
|
||||||
totalfree += freecount;
|
|
||||||
dprintk("free count = %d\n",freecount);
|
|
||||||
if(freecount == 0)
|
|
||||||
{
|
|
||||||
freecount = 0;
|
|
||||||
_NAND_LB_PreWiteToNand(ssfdc_cache,&freecount,OFTEN_USE_CACHE);
|
|
||||||
totalfree += freecount;
|
|
||||||
update = 0;
|
|
||||||
}
|
|
||||||
if(update)
|
|
||||||
{
|
|
||||||
if(Get_NAND_CacheFreeCount() < CACHE_MAX_NUM * 1 / 4) // because fat is 4 sector
|
|
||||||
{
|
|
||||||
freecount = 0;
|
|
||||||
_NAND_LB_PreWiteToNand(ssfdc_cache,&freecount,OFTEN_USE_CACHE);
|
|
||||||
totalfree += freecount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintk("Free = %d\r\n",totalfree);
|
|
||||||
return totalfree;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _NAND_LB_GetFromCache(unsigned int Sector, void *pBuffer) {
|
|
||||||
|
|
||||||
SSFDC__LB_CACHE *pCache = &ssfdc_cache[Cur_CacheCount];
|
|
||||||
SSFDC__LB_CACHE *pUseCache = 0;
|
|
||||||
unsigned short i;
|
|
||||||
dprintk("sector = %x pBuffer = %x\n",Sector,pBuffer);
|
|
||||||
if(pCache >= &ssfdc_cache[CACHE_MAX_NUM])
|
|
||||||
pCache = ssfdc_cache;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (1) {
|
|
||||||
if(pCache->CacheState != FREE_CACHE)
|
|
||||||
{
|
|
||||||
if (Sector == pCache->BlockId) {
|
|
||||||
dprintk("Cache is use = %d\r\n",pCache->BlockId);
|
|
||||||
pUseCache = pCache;
|
|
||||||
pCache->UseCount++;
|
|
||||||
if(pCache->UseCount == 0)
|
|
||||||
pCache->UseCount = -1;
|
|
||||||
pCache->CacheState = OFTEN_USE_CACHE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pCache--;
|
|
||||||
if(pCache < ssfdc_cache)
|
|
||||||
pCache = &ssfdc_cache[CACHE_MAX_NUM - 1];
|
|
||||||
|
|
||||||
i++;
|
|
||||||
if (i >= CACHE_MAX_NUM) {
|
|
||||||
break; /* Sector not in cache */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pUseCache) {
|
|
||||||
dprintk("From Cache %d\r\n",Sector);
|
|
||||||
lb_memcpy(pBuffer, pUseCache->aBlockData, SECTOR_SIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _NAND_LB_ClearCache(void) {
|
|
||||||
|
|
||||||
unsigned short freecount = 0;
|
|
||||||
dprintk("Clear Cache\r\n");
|
|
||||||
|
|
||||||
_NAND_LB_PreWiteToNand(ssfdc_cache,&freecount,PREWRITE_CACHE);
|
|
||||||
_NAND_LB_PreWiteToNand(ssfdc_cache,&freecount,OFTEN_USE_CACHE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _NAND_LB_CopyToCache(unsigned int Sector, void *pBuffer,unsigned short rw)
|
|
||||||
{
|
|
||||||
SSFDC__LB_CACHE *pCache = _NAND_LB_GetFreeCache();
|
|
||||||
dprintk("Copy to Cache = 0x%08x 0x%08x\r\n",pCache,ssfdc_cache);
|
|
||||||
|
|
||||||
if(!pCache)
|
|
||||||
{
|
|
||||||
_NAND_LB_FreeCache(rw);
|
|
||||||
|
|
||||||
pCache = _NAND_LB_GetFreeCache();
|
|
||||||
}
|
|
||||||
pCache->BlockId = Sector;
|
|
||||||
pCache->CacheState = PREWRITE_CACHE;
|
|
||||||
pCache->UseCount = 0;
|
|
||||||
pCache->CacheChange = rw;
|
|
||||||
|
|
||||||
lb_memcpy(pCache->aBlockData,pBuffer,SECTOR_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int _NAND_LB_UpdateInCache(unsigned int Sector, void *pBuffer) {
|
|
||||||
short i,ret = 0;
|
|
||||||
i = Cur_CacheCount;
|
|
||||||
if(Cur_CacheCount > CACHE_MAX_NUM)
|
|
||||||
i = 0;
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
if(ret >= CACHE_MAX_NUM)
|
|
||||||
return -1;
|
|
||||||
if(ssfdc_cache[i].CacheState != FREE_CACHE)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(ssfdc_cache[i].BlockId == Sector)
|
|
||||||
{
|
|
||||||
dprintk("UpdateInCache = %d\r\n",Sector);
|
|
||||||
ssfdc_cache[i].CacheState = OFTEN_USE_CACHE;
|
|
||||||
ssfdc_cache[i].UseCount++;
|
|
||||||
ssfdc_cache[i].CacheChange = 1;
|
|
||||||
lb_memcpy(ssfdc_cache[i].aBlockData,pBuffer,SECTOR_SIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
if(i < 0)
|
|
||||||
i = CACHE_MAX_NUM - 1;
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int NAND_LB_MultiRead(unsigned int Sector, void *pBuffer,unsigned int SectorCount)
|
|
||||||
{
|
|
||||||
int i,ret,end;
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
dprintk("NAND_LB_MultiRead = %d %d \n",Sector,SectorCount);
|
|
||||||
end = Sector + SectorCount;
|
|
||||||
_NAND_LB_FLUSHCACHES(Sector,end);
|
|
||||||
|
|
||||||
p = pBuffer;
|
|
||||||
for (i = Sector; i < end; i ++)
|
|
||||||
{
|
|
||||||
ret = udc_mtdblock_readsect(g_udc_mtdblk, i, p, SECTOR_SIZE);
|
|
||||||
p += SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int NAND_LB_Read(unsigned int Sector, void *pBuffer)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
#if DMA_ENABLE
|
|
||||||
unsigned char *ptr = (unsigned char *)CACHE_TO_UNCATCH(pBuffer);
|
|
||||||
dma_cache_wback_inv(pBuffer,SECTOR_SIZE);
|
|
||||||
#else
|
|
||||||
unsigned char *ptr = (unsigned char *)pBuffer;
|
|
||||||
#endif
|
|
||||||
dprintk("LB_Read = %d \n",Sector);
|
|
||||||
if(_NAND_LB_GetFromCache(Sector,ptr))
|
|
||||||
{
|
|
||||||
x = _NAND_LB_Read(Sector,ptr);
|
|
||||||
_NAND_LB_CopyToCache(Sector,ptr,0);
|
|
||||||
}
|
|
||||||
return 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int NAND_LB_MultiWrite(unsigned int Sector, void *pBuffer,unsigned int SectorCount)
|
|
||||||
{
|
|
||||||
int i,ret;
|
|
||||||
unsigned char *p;
|
|
||||||
|
|
||||||
_NAND_LB_CloseCACHES(Sector,Sector + SectorCount);
|
|
||||||
p = (unsigned char *)pBuffer;
|
|
||||||
for (i = Sector; i < Sector + SectorCount; i ++)
|
|
||||||
{
|
|
||||||
ret = udc_mtdblock_writesect(g_udc_mtdblk, i, p);
|
|
||||||
p += 512;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int NAND_LB_Write(unsigned int Sector, void *pBuffer)
|
|
||||||
{
|
|
||||||
#if DMA_ENABLE
|
|
||||||
unsigned char *ptr = (unsigned char *)CACHE_TO_UNCATCH(pBuffer);
|
|
||||||
dma_cache_wback_inv(pBuffer,SECTOR_SIZE);
|
|
||||||
#else
|
|
||||||
unsigned char *ptr = (unsigned char *)pBuffer;
|
|
||||||
#endif
|
|
||||||
dprintk("LB_Write = %x %x\r\n",Sector,pBuffer);
|
|
||||||
if(_NAND_LB_UpdateInCache(Sector,ptr))
|
|
||||||
{
|
|
||||||
_NAND_LB_CopyToCache(Sector,ptr,1);
|
|
||||||
}
|
|
||||||
return 512;
|
|
||||||
}
|
|
||||||
/*********************************************************************
|
|
||||||
*
|
|
||||||
* Global functions
|
|
||||||
*
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
int NAND_LB_Init(void)
|
|
||||||
{
|
|
||||||
dprintk("UDC CACHE Init \n");
|
|
||||||
_NAND_LB_InitCache();
|
|
||||||
g_udc_mtdblk = udc_get_mtdblk();
|
|
||||||
g_udc_mtd = udc_get_mtd();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NAND_LB_FLASHCACHE(void)
|
|
||||||
{
|
|
||||||
dprintk("Flush lb cache !\n");
|
|
||||||
_NAND_LB_ClearCache();
|
|
||||||
// dprintk("Flush mtd cache !\n");
|
|
||||||
// udc_flush_cache(g_udc_mtdblk);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NAND_MTD_FLASHCACHE(void)
|
|
||||||
{
|
|
||||||
dprintk("Flush mtd cache !\n");
|
|
||||||
udc_flush_cache(g_udc_mtdblk);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int udc_read(unsigned int offset, unsigned int len, unsigned char *buf)
|
|
||||||
{
|
|
||||||
unsigned long block,sector,i;
|
|
||||||
|
|
||||||
block = offset >> SECTOR_SHIFT;
|
|
||||||
sector = len >> SECTOR_SHIFT;
|
|
||||||
dprintk("read dev = ia:%x, s:%d c:%d\r\n",buf,block,sector);
|
|
||||||
|
|
||||||
if (sector <= 8)
|
|
||||||
{
|
|
||||||
for(i = 0;i < sector; i++)
|
|
||||||
{
|
|
||||||
NAND_LB_Read(block + i,(void *)(buf));
|
|
||||||
buf += 512;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
NAND_LB_MultiRead(block, buf, sector);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int udc_write(unsigned int offset, unsigned int len, unsigned char *buf)
|
|
||||||
{
|
|
||||||
unsigned long block,sector,i;
|
|
||||||
|
|
||||||
block = offset >> SECTOR_SHIFT;
|
|
||||||
sector = len >> SECTOR_SHIFT;
|
|
||||||
dprintk("write dev s:%d c:%d\r\n",block,sector);
|
|
||||||
|
|
||||||
if(sector <= 8)
|
|
||||||
{
|
|
||||||
for(i = 0;i < sector; i++)
|
|
||||||
{
|
|
||||||
NAND_LB_Write(block + i,(void *)(buf));
|
|
||||||
buf += 512;
|
|
||||||
FlushDataState = 1;
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
NAND_LB_MultiWrite(block,(void *)(buf),sector);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(udc_write);
|
|
||||||
EXPORT_SYMBOL_GPL(udc_read);
|
|
||||||
EXPORT_SYMBOL_GPL(NAND_LB_Init);
|
|
||||||
EXPORT_SYMBOL_GPL(NAND_LB_FLASHCACHE);
|
|
||||||
EXPORT_SYMBOL_GPL(FlushDataState);
|
|
||||||
EXPORT_SYMBOL_GPL(NAND_MTD_FLASHCACHE);
|
|
Loading…
Reference in New Issue
Block a user