2005-04-17 02:20:36 +04:00
/*
* mtdram - a test mtd device
2005-04-21 07:42:15 +04:00
* $ Id : mtdram . c , v 1.37 2005 / 04 / 21 03 : 42 : 11 joern Exp $
2005-04-17 02:20:36 +04:00
* Author : Alexander Larsson < alex @ cendio . se >
*
* Copyright ( c ) 1999 Alexander Larsson < alex @ cendio . se >
2005-04-21 07:42:15 +04:00
* Copyright ( c ) 2005 Joern Engel < joern @ wh . fh - wedel . de >
2005-04-17 02:20:36 +04:00
*
* This code is GPL
*
*/
# include <linux/config.h>
# include <linux/module.h>
# include <linux/slab.h>
# include <linux/ioport.h>
# include <linux/vmalloc.h>
# include <linux/init.h>
# include <linux/mtd/compatmac.h>
# include <linux/mtd/mtd.h>
static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE ;
static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE ;
# define MTDRAM_TOTAL_SIZE (total_size * 1024)
# define MTDRAM_ERASE_SIZE (erase_size * 1024)
2005-04-21 07:42:15 +04:00
# ifdef MODULE
module_param ( total_size , ulong , 0 ) ;
MODULE_PARM_DESC ( total_size , " Total device size in KiB " ) ;
module_param ( erase_size , ulong , 0 ) ;
MODULE_PARM_DESC ( erase_size , " Device erase block size in KiB " ) ;
# endif
2005-04-17 02:20:36 +04:00
// We could store these in the mtd structure, but we only support 1 device..
static struct mtd_info * mtd_info ;
2005-04-21 07:42:15 +04:00
static int ram_erase ( struct mtd_info * mtd , struct erase_info * instr )
2005-04-17 02:20:36 +04:00
{
2005-04-21 07:42:15 +04:00
if ( instr - > addr + instr - > len > mtd - > size )
return - EINVAL ;
memset ( ( char * ) mtd - > priv + instr - > addr , 0xff , instr - > len ) ;
instr - > state = MTD_ERASE_DONE ;
mtd_erase_callback ( instr ) ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-04-21 07:42:15 +04:00
static int ram_point ( struct mtd_info * mtd , loff_t from , size_t len ,
size_t * retlen , u_char * * mtdbuf )
2005-04-17 02:20:36 +04:00
{
2005-04-21 07:42:15 +04:00
if ( from + len > mtd - > size )
return - EINVAL ;
* mtdbuf = mtd - > priv + from ;
* retlen = len ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
2005-04-21 07:42:15 +04:00
static void ram_unpoint ( struct mtd_info * mtd , u_char * addr , loff_t from ,
size_t len )
2005-04-17 02:20:36 +04:00
{
}
static int ram_read ( struct mtd_info * mtd , loff_t from , size_t len ,
2005-04-21 07:42:15 +04:00
size_t * retlen , u_char * buf )
2005-04-17 02:20:36 +04:00
{
2005-04-21 07:42:15 +04:00
if ( from + len > mtd - > size )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
2005-04-21 07:42:15 +04:00
memcpy ( buf , mtd - > priv + from , len ) ;
2005-04-17 02:20:36 +04:00
2005-04-21 07:42:15 +04:00
* retlen = len ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
static int ram_write ( struct mtd_info * mtd , loff_t to , size_t len ,
2005-04-21 07:42:15 +04:00
size_t * retlen , const u_char * buf )
2005-04-17 02:20:36 +04:00
{
2005-04-21 07:42:15 +04:00
if ( to + len > mtd - > size )
return - EINVAL ;
2005-04-17 02:20:36 +04:00
2005-04-21 07:42:15 +04:00
memcpy ( ( char * ) mtd - > priv + to , buf , len ) ;
2005-04-17 02:20:36 +04:00
2005-04-21 07:42:15 +04:00
* retlen = len ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
static void __exit cleanup_mtdram ( void )
{
2005-04-21 07:42:15 +04:00
if ( mtd_info ) {
del_mtd_device ( mtd_info ) ;
if ( mtd_info - > priv )
vfree ( mtd_info - > priv ) ;
kfree ( mtd_info ) ;
}
2005-04-17 02:20:36 +04:00
}
2005-04-21 07:42:15 +04:00
int mtdram_init_device ( struct mtd_info * mtd , void * mapped_address ,
unsigned long size , char * name )
2005-04-17 02:20:36 +04:00
{
2005-04-21 07:42:15 +04:00
memset ( mtd , 0 , sizeof ( * mtd ) ) ;
/* Setup the MTD structure */
mtd - > name = name ;
mtd - > type = MTD_RAM ;
mtd - > flags = MTD_CAP_RAM ;
mtd - > size = size ;
mtd - > erasesize = MTDRAM_ERASE_SIZE ;
mtd - > priv = mapped_address ;
mtd - > owner = THIS_MODULE ;
mtd - > erase = ram_erase ;
mtd - > point = ram_point ;
mtd - > unpoint = ram_unpoint ;
mtd - > read = ram_read ;
mtd - > write = ram_write ;
if ( add_mtd_device ( mtd ) ) {
return - EIO ;
}
return 0 ;
2005-04-17 02:20:36 +04:00
}
static int __init init_mtdram ( void )
{
2005-04-21 07:42:15 +04:00
void * addr ;
int err ;
if ( ! total_size )
return - EINVAL ;
/* Allocate some memory */
mtd_info = kmalloc ( sizeof ( struct mtd_info ) , GFP_KERNEL ) ;
if ( ! mtd_info )
return - ENOMEM ;
addr = vmalloc ( MTDRAM_TOTAL_SIZE ) ;
if ( ! addr ) {
kfree ( mtd_info ) ;
mtd_info = NULL ;
return - ENOMEM ;
}
err = mtdram_init_device ( mtd_info , addr , MTDRAM_TOTAL_SIZE , " mtdram test device " ) ;
if ( err ) {
vfree ( addr ) ;
kfree ( mtd_info ) ;
mtd_info = NULL ;
return err ;
}
memset ( mtd_info - > priv , 0xff , MTDRAM_TOTAL_SIZE ) ;
return err ;
2005-04-17 02:20:36 +04:00
}
module_init ( init_mtdram ) ;
module_exit ( cleanup_mtdram ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Alexander Larsson <alexl@redhat.com> " ) ;
MODULE_DESCRIPTION ( " Simulated MTD driver for testing " ) ;