📄 lnx2tffs.c
字号:
#include "flcustom.h"#include "tffsdrv.h"#include <linux/ioport.h> /* check_mem_region */#include <asm/io.h> /* ioremap_nocache */#include <linux/delay.h> /* mdelay */#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/vmalloc.h>#include <asm/uaccess.h> /* ok_access */#include <linux/init.h> /* __initdata */#ifndef __init# ifdef __initfunc# define __init __initfunc# else# define __init# endif#endif#ifndef __initdata# define __initdata#endif#include "flsystem.h"#ifdef TFFS_MESSAGES_ENABLEDshort fl_debug=FL_DEBUG_DEF;# ifdef MODULEMODULE_PARM(fl_debug,"h");MODULE_PARM_DESC(fl_debug,"Print TrueFFS debug messages [0-7].");# endif#endif /* TFFS_MESSAGES_ENABLED */unsigned long __initdata fl_winl=TFFS_PHYS_ADDR_LOW;#ifdef MODULEMODULE_PARM(fl_winl,"l");MODULE_PARM_DESC(fl_winl,"Upper memory range in which driver will search for DiskOnChip.");#endifunsigned long __initdata fl_winh=TFFS_PHYS_ADDR_HIGH;#ifdef MODULEMODULE_PARM(fl_winh,"l");MODULE_PARM_DESC(fl_winh,"Top memory range in which driver will search for DiskOnChip.");#endif#ifdef ENVIRONMENT_VARSshort __initdata fl_nftl_cache=FL_TL_CACHE_ENABLED_DEF;# ifdef MODULEMODULE_PARM(fl_nftl_cache,"h");MODULE_PARM_DESC(fl_nftl_cache,"Set flUseTLCache [0,1].");# endif# if TFFS_SVER<60000short __initdata fl_is_ram_check=FL_IS_RAM_CHECK_DEF;# ifdef MODULEMODULE_PARM(fl_is_ram_check,"h");MODULE_PARM_DESC(fl_is_ram_check,"Set flUseisRAM [0,1].");# endif# endif /* TFFS_SVER<60000 */short __initdata fl_8bit_access=FL_DOC_8BIT_ACCESS_DEF;# ifdef MODULEMODULE_PARM(fl_8bit_access,"h");MODULE_PARM_DESC(fl_8bit_access,"Set flUse8Bit [0,1].");# endifunsigned long __initdata fl_mtd_bus_access_type=FL_MTD_BUS_ACCESS_TYPE_DEF;# ifdef MODULEMODULE_PARM(fl_mtd_bus_access_type,"l");MODULE_PARM_DESC(fl_mtd_bus_access_type,"Set flBusConfig [0...0x24].");# endifunsigned long __initdata fl_sectors_verified_per_folding=FL_SECTORS_VERIFIED_PER_FOLDING_DEF;# ifdef MODULEMODULE_PARM(fl_sectors_verified_per_folding,"l");MODULE_PARM_DESC(fl_sectors_verified_per_folding,"Set flSectorsVerifiedPerFolding [0...0xffffffff].");# endif#endif /* ENVIRONMENT_VARS */#ifdef TFFS_KEY_FROM_PARAMS#ifdef HW_PROTECTIONstatic short __initdata fl_part_prot=SOCKETS*VOLUMES;# ifdef MODULEMODULE_PARM(fl_part_prot,"h");MODULE_PARM_DESC(fl_part_prot,"Number of protected device.");# endifstatic char * __initdata fl_key_prot=NULL;# ifdef MODULEMODULE_PARM(fl_key_prot,"s");MODULE_PARM_DESC(fl_key_prot,"Key of protected device.");# endif#endif /* HW_PROTECTION */#endif#ifdef ACCESS_ROUTINES_DEBUG/* save mapped addresses */static unsigned long dwVirLDebug,dwVirHDebug;#endif#ifdef TFFS_KEY_FROM_PARAMS#ifdef HW_PROTECTIONvoid LnxGetKeyFromParam(unsigned char*wDevice,char**pKey){ *wDevice=(unsigned char)fl_part_prot; *pKey=fl_key_prot;}#endif /* HW_PROTECTION */#endif/*****************************************************************************The following are the Linux versions of various things required by theTrueFFS that must be compiled here in the Linux kernel environment.*****************************************************************************/typedef struct{ unsigned long dwPhyAddress,dwVirAddress,dwLen; unsigned char fRequested,fMapped;}MappedIoMem;#ifdef TFFS_USE_AMD_ISA# define TFFS_MAPPED_IO 2#else# define TFFS_MAPPED_IO 1#endifstatic MappedIoMem mappedIoMem[TFFS_MAPPED_IO];void MapMem(MappedIoMem*mappedIoMem){ if(check_mem_region(mappedIoMem->dwPhyAddress,mappedIoMem->dwLen)<0) { PrintkWarning("MapMem: check_mem_region(%lx,%lx) failed",mappedIoMem->dwPhyAddress,mappedIoMem->dwLen); } else { request_mem_region(mappedIoMem->dwPhyAddress,mappedIoMem->dwLen,"TrueFFS Device"); mappedIoMem->fRequested=1; PrintkDebug("MapMem: request_mem_region(%lx,%lx) OK",mappedIoMem->dwPhyAddress,mappedIoMem->dwLen); } mappedIoMem->dwVirAddress=(unsigned long)ioremap_nocache(mappedIoMem->dwPhyAddress,mappedIoMem->dwLen); if(mappedIoMem->dwVirAddress==0) { PrintkError("MapMem: ioremap_nocache returns zero"); } else { mappedIoMem->fMapped=1; PrintkDebug("MapMem: ioremap_nocache(%lx,%lx) mapped to %lx",mappedIoMem->dwPhyAddress,mappedIoMem->dwLen,mappedIoMem->dwVirAddress); }}void LnxUnmapMem(MappedIoMem*mappedIoMem){ if(mappedIoMem->fMapped) { iounmap((void*)mappedIoMem->dwVirAddress); mappedIoMem->fMapped=0; } if(mappedIoMem->fRequested) { release_mem_region(mappedIoMem->dwPhyAddress,mappedIoMem->dwLen); mappedIoMem->fRequested=0; }}void LnxGetMappedRange(unsigned long*dwL,unsigned long*dwH#ifdef TFFS_USE_AMD_ISA ,unsigned long*dwIsaReg#endif ){ *dwL=mappedIoMem[0].dwVirAddress; *dwH=mappedIoMem[0].dwVirAddress+(fl_winh-fl_winl);#ifdef TFFS_USE_AMD_ISA *dwIsaReg=mappedIoMem[1].dwVirAddress;#endif}int LnxPrintk(const char *fmt, ...){ va_list args; char buf[1024]; /* hopefully enough, kernel/printk.c thinks so */ int i; va_start(args, fmt); i = vsprintf(buf, fmt, args); va_end(args); buf[i] = '\0'; LOG_DELAY;printk(KERN_DEBUG TFFS_DEVICE_NAME": %s\n",buf); return i;}int LnxTffsPrint(const char *fmt, ...){ va_list args; char buf[1024]; /* hopefully enough, kernel/printk.c thinks so */ int i; va_start(args, fmt); i = vsprintf(buf, fmt, args); va_end(args); buf[i] = '\0'; while(i>0) { if(buf[i-1]==0xd || buf[i-1]==0xa) { buf[--i]=0; } else break; } LOG_DELAY;printk(KERN_DEBUG TFFS_DEVICE_NAME": %s\n",buf); return i;}#if (TFFS_SVER < 60000)# ifdef ENVIRONMENT_VARSvoid*flmemcpy(void*dest,const void*src,unsigned long count){ unsigned long i; unsigned char*ldest=(unsigned char*)dest; const unsigned char*lsrc=(unsigned char*)src; for(i=0;( i < count );i++,ldest++,lsrc++) *(ldest) = *(lsrc); return dest;}void*flmemset(void*dest,int c,unsigned long count){ unsigned long i; unsigned char *ldest = (unsigned char *)dest; for(i=0;( i < count );i++,ldest++) *(ldest) = (unsigned char)c; return dest;}int flmemcmp(const void*dest,const void*src,unsigned long count){ unsigned long i; const unsigned char *ldest = (unsigned char *)dest; const unsigned char *lsrc = (unsigned char *)src; for(i=0;( i < count );i++,ldest++,lsrc++) if( *(ldest) != *(lsrc) ) return (*(ldest)-*(lsrc)); return 0;}# endif /* ENVIRONMENT_VARS */#endif /* (TFFS_SVER < 60000) */#if (TFFS_SVER<60000) || !defined(TFFS_ACCESS_MACROS)void*LnxMemcpy(void*dest,const void*src,size_t count){ return memcpy(dest,src,count);}void*LnxMemset(void*dest,int value,size_t count){ return memset(dest,value,count);}int LnxMemcmp(const void*dest,const void*src,size_t count){ return memcmp(dest,src,count);}#endif#ifndef TFFS_ACCESS_MACROSvoid*LnxMalloc(unsigned long size){ return vmalloc(size);}void LnxFree(void*addr){ vfree(addr);}void LnxMemcpy_fromio(void *dest, const void * src, unsigned int length){#ifdef ACCESS_ROUTINES_DEBUG if((long)src<dwVirLDebug || (long)src>dwVirHDebug-length) { PrintkError("Achtung, partisanen: LnxMemcpy_fromio(%lx)",(long)src); return; }#endif memcpy_fromio(dest, src, length);}void LnxMemcpy_toio(void *dest, const void * src, unsigned int length){#ifdef ACCESS_ROUTINES_DEBUG if((long)dest<dwVirLDebug || (long)dest>dwVirHDebug-length) { PrintkError("Achtung, partisanen: LnxMemcpy_toio(%lx)",(long)dest); return; }#endif memcpy_toio(dest, src, length);}void LnxMemset_io(void *dest, int value, unsigned int length){#ifdef ACCESS_ROUTINES_DEBUG if((long)dest<dwVirLDebug || (long)dest>dwVirHDebug-length) { PrintkError("Achtung, partisanen: LnxMemset_io(%lx)",(long)dest); return; }#endif memset_io(dest, value, length);}unsigned char LnxReadb(volatile void*addr){#ifdef ACCESS_ROUTINES_DEBUG unsigned char a; if((long)addr<dwVirLDebug || (long)addr>dwVirHDebug) { PrintkError("Achtung, partisanen: LnxReadb(%lx)",(long)addr); return 0; } a=readb(addr); PrintkDebug(" %8lx -> %2x",(unsigned long)addr,a); return a;#else return readb(addr);#endif}unsigned short LnxReadw(volatile void *addr){#ifdef ACCESS_ROUTINES_DEBUG unsigned short a; if((long)addr<dwVirLDebug || (long)addr>dwVirHDebug) { PrintkError("Achtung, partisanen: LnxReadw(%lx)",(long)addr); return 0; } a=readw(addr); PrintkDebug(" %8lx -> %4x",(unsigned long)addr,a); return a;#else return readw(addr);#endif}unsigned long LnxReadl(volatile void *addr){#ifdef ACCESS_ROUTINES_DEBUG unsigned long a; if((long)addr<dwVirLDebug || (long)addr>dwVirHDebug) { PrintkError("Achtung, partisanen: LnxReadl(%lx)",(long)addr); return 0; } a=readl(addr); PrintkDebug(" %8lx -> %8x",(unsigned long)addr,a); return a;#else return readl(addr);#endif}void LnxWriteb(unsigned char value, volatile void *addr){#ifdef ACCESS_ROUTINES_DEBUG if((long)addr<dwVirLDebug || (long)addr>dwVirHDebug) { PrintkError("Achtung, partisanen: LnxWriteb(%lx)",(long)addr); return; }#endif writeb(value, addr);#ifdef ACCESS_ROUTINES_DEBUG PrintkDebug(" %8lx <- %2x",(unsigned long)addr,value);#endif}void LnxWritew(unsigned short value, volatile void*addr){#ifdef ACCESS_ROUTINES_DEBUG if((long)addr<dwVirLDebug || (long)addr>dwVirHDebug) { PrintkError("Achtung, partisanen: LnxWritew(%lx)",(long)addr); return; }#endif writew(value, addr);#ifdef ACCESS_ROUTINES_DEBUG PrintkDebug(" %8lx <- %4x",(unsigned long)addr,value);#endif}void LnxWritel(unsigned long value, volatile void *addr){#ifdef ACCESS_ROUTINES_DEBUG if((long)addr<dwVirLDebug || (long)addr>dwVirHDebug) { PrintkError("Achtung, partisanen: LnxWritel(%lx)",(long)addr); return; }#endif writel(value, addr);#ifdef ACCESS_ROUTINES_DEBUG PrintkDebug(" %8lx <- %8x",(unsigned long)addr,value);#endif}#endif /* TFFS_ACCESS_MACROS *//*****************************************************************************H/W init for custom platforms*****************************************************************************/#ifdef TFFS_COTULLA#define MSC2_CNTR_REG_ADDR 0x48000000#define MSC2_OFFSET 0x10#define MCS5_INIT_VAL 0xFFF80000#endif /* TFFS_COTULLA */unsigned char TffsHWInit(void){#ifdef TFFS_COTULLA volatile void *myMSC2ptr; unsigned long msc2Val; myMSC2ptr = (volatile void *)ioremap_nocache(MSC2_CNTR_REG_ADDR, 0x1000); /* MSC2 Static Memory Control Register - 16-bit mode for CS5 */ msc2Val = readl( myMSC2ptr + MSC2_OFFSET ); writel( ((msc2Val & 0x0000FFFF) | MCS5_INIT_VAL), myMSC2ptr + MSC2_OFFSET ); /* *(myMCS5 + 4) = MCS5_INIT_VAL; */ iounmap( (void *)myMSC2ptr);#endif /* TFFS_COTULLA */ return 1;}/*****************************************************************************Functions exported directly to TrueFFS (replacement for flsystem.c an flcustom.c).*****************************************************************************//* Add unsigned long offset to the far pointer */void *flAddLongToFarPointer(void*ptr, unsigned long offset){ return (void*)(((unsigned long)(ptr)) + offset);}/* Return a random number from 0 to 255 */unsigned int flRandByte(void){ struct timeval time; do_gettimeofday(&time); return (time.tv_usec >> 1) & 0xff;}static struct semaphore tffsSemaphore[SOCKETS];static int nextFreeSemaphore;void flSysfunInit(void){ PrintkDebug("flSysfunInit"); memset(mappedIoMem,0,sizeof(MappedIoMem)*TFFS_MAPPED_IO); mappedIoMem[0].dwPhyAddress=fl_winl; mappedIoMem[0].dwLen=fl_winh-fl_winl+TFFS_IOMEM_WINDOW_SIZE; MapMem(&mappedIoMem[0]);#ifdef TFFS_USE_AMD_ISA mappedIoMem[1].dwPhyAddress=FL_AMD_ISA_SOCKET; mappedIoMem[1].dwLen=4;#endif#ifdef ACCESS_ROUTINES_DEBUG dwVirLDebug=mappedIoMem[0].dwVirAddress; dwVirHDebug=mappedIoMem[0].dwVirAddress+mappedIoMem[0].dwLen;#endif /* ACCESS_ROUTINES_DEBUG */ nextFreeSemaphore=0;}void LnxSysfunRelease(void){ PrintkDebug("LnxSysfunRelease"); LnxUnmapMem(&mappedIoMem[0]);#ifdef TFFS_USE_AMD_ISA LnxUnmapMem(&mappedIoMem[1]);#endif memset(mappedIoMem,0,sizeof(MappedIoMem)*TFFS_MAPPED_IO); nextFreeSemaphore=0;}int flCreateMutex(FLMutex*mutex){/* PrintkDebug("flCreateMutex: %d",*mutex); */ *mutex=nextFreeSemaphore; sema_init(tffsSemaphore+*mutex,1); ++nextFreeSemaphore; return 0;}void flDeleteMutex(FLMutex*mutex){/* PrintkDebug("flDeleteMutex: %d",*mutex); */ up(tffsSemaphore+*mutex);}int flTakeMutex(FLMutex*mutex){/* PrintkDebug("flTakeMutex: %d",*mutex); */ down_interruptible(tffsSemaphore+*mutex); return 1;}void flFreeMutex(FLMutex*mutex){/* PrintkDebug("flFreeMutex: %d",*mutex); */ up(tffsSemaphore+*mutex);}#if (TFFS_SVER<60000)void flDelayMsecs(unsigned int milliseconds){ mdelay(milliseconds);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -