2 * mtdram - a test mtd device
3 * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $
4 * Author: Alexander Larsson <alex@cendio.se>
6 * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
12 #include <linux/config.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/ioport.h>
16 #include <linux/vmalloc.h>
17 #include <linux/init.h>
18 #include <linux/mtd/compatmac.h>
19 #include <linux/mtd/mtd.h>
21 #ifndef CONFIG_MTDRAM_ABS_POS
22 #define CONFIG_MTDRAM_ABS_POS 0
25 #if CONFIG_MTDRAM_ABS_POS > 0
30 static unsigned long total_size
= CONFIG_MTDRAM_TOTAL_SIZE
;
31 static unsigned long erase_size
= CONFIG_MTDRAM_ERASE_SIZE
;
32 module_param(total_size
,ulong
,0);
33 MODULE_PARM_DESC(total_size
, "Total device size in KiB");
34 module_param(erase_size
,ulong
,0);
35 MODULE_PARM_DESC(erase_size
, "Device erase block size in KiB");
36 #define MTDRAM_TOTAL_SIZE (total_size * 1024)
37 #define MTDRAM_ERASE_SIZE (erase_size * 1024)
39 #define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
40 #define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
44 // We could store these in the mtd structure, but we only support 1 device..
45 static struct mtd_info
*mtd_info
;
49 ram_erase(struct mtd_info
*mtd
, struct erase_info
*instr
)
51 DEBUG(MTD_DEBUG_LEVEL2
, "ram_erase(pos:%ld, len:%ld)\n", (long)instr
->addr
, (long)instr
->len
);
52 if (instr
->addr
+ instr
->len
> mtd
->size
) {
53 DEBUG(MTD_DEBUG_LEVEL1
, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr
->addr
+ instr
->len
), (long)mtd
->size
);
57 memset((char *)mtd
->priv
+ instr
->addr
, 0xff, instr
->len
);
59 instr
->state
= MTD_ERASE_DONE
;
60 mtd_erase_callback(instr
);
65 static int ram_point (struct mtd_info
*mtd
, loff_t from
, size_t len
, size_t *retlen
, u_char
**mtdbuf
)
67 if (from
+ len
> mtd
->size
)
70 *mtdbuf
= mtd
->priv
+ from
;
75 static void ram_unpoint (struct mtd_info
*mtd
, u_char
*addr
, loff_t from
,
78 DEBUG(MTD_DEBUG_LEVEL2
, "ram_unpoint\n");
81 static int ram_read(struct mtd_info
*mtd
, loff_t from
, size_t len
,
82 size_t *retlen
, u_char
*buf
)
84 DEBUG(MTD_DEBUG_LEVEL2
, "ram_read(pos:%ld, len:%ld)\n", (long)from
, (long)len
);
85 if (from
+ len
> mtd
->size
) {
86 DEBUG(MTD_DEBUG_LEVEL1
, "ram_read() out of bounds (%ld > %ld)\n", (long)(from
+ len
), (long)mtd
->size
);
90 memcpy(buf
, mtd
->priv
+ from
, len
);
96 static int ram_write(struct mtd_info
*mtd
, loff_t to
, size_t len
,
97 size_t *retlen
, const u_char
*buf
)
99 DEBUG(MTD_DEBUG_LEVEL2
, "ram_write(pos:%ld, len:%ld)\n", (long)to
, (long)len
);
100 if (to
+ len
> mtd
->size
) {
101 DEBUG(MTD_DEBUG_LEVEL1
, "ram_write() out of bounds (%ld > %ld)\n", (long)(to
+ len
), (long)mtd
->size
);
105 memcpy ((char *)mtd
->priv
+ to
, buf
, len
);
111 static void __exit
cleanup_mtdram(void)
114 del_mtd_device(mtd_info
);
115 #if CONFIG_MTDRAM_TOTAL_SIZE > 0
117 #if CONFIG_MTDRAM_ABS_POS > 0
118 iounmap(mtd_info
->priv
);
120 vfree(mtd_info
->priv
);
127 int mtdram_init_device(struct mtd_info
*mtd
, void *mapped_address
,
128 unsigned long size
, char *name
)
130 memset(mtd
, 0, sizeof(*mtd
));
132 /* Setup the MTD structure */
135 mtd
->flags
= MTD_CAP_RAM
;
137 mtd
->erasesize
= MTDRAM_ERASE_SIZE
;
138 mtd
->priv
= mapped_address
;
140 mtd
->owner
= THIS_MODULE
;
141 mtd
->erase
= ram_erase
;
142 mtd
->point
= ram_point
;
143 mtd
->unpoint
= ram_unpoint
;
144 mtd
->read
= ram_read
;
145 mtd
->write
= ram_write
;
147 if (add_mtd_device(mtd
)) {
154 #if CONFIG_MTDRAM_TOTAL_SIZE > 0
155 #if CONFIG_MTDRAM_ABS_POS > 0
156 static int __init
init_mtdram(void)
160 /* Allocate some memory */
161 mtd_info
= kmalloc(sizeof(struct mtd_info
), GFP_KERNEL
);
165 addr
= ioremap(CONFIG_MTDRAM_ABS_POS
, MTDRAM_TOTAL_SIZE
);
167 DEBUG(MTD_DEBUG_LEVEL1
,
168 "Failed to ioremap) memory region of size %ld at ABS_POS:%ld\n",
169 (long)MTDRAM_TOTAL_SIZE
, (long)CONFIG_MTDRAM_ABS_POS
);
174 err
= mtdram_init_device(mtd_info
, addr
,
175 MTDRAM_TOTAL_SIZE
, "mtdram test device");
183 memset(mtd_info
->priv
, 0xff, MTDRAM_TOTAL_SIZE
);
187 #else /* CONFIG_MTDRAM_ABS_POS > 0 */
189 static int __init
init_mtdram(void)
193 /* Allocate some memory */
194 mtd_info
= kmalloc(sizeof(struct mtd_info
), GFP_KERNEL
);
198 addr
= vmalloc(MTDRAM_TOTAL_SIZE
);
200 DEBUG(MTD_DEBUG_LEVEL1
,
201 "Failed to vmalloc memory region of size %ld\n",
202 (long)MTDRAM_TOTAL_SIZE
);
207 err
= mtdram_init_device(mtd_info
, addr
,
208 MTDRAM_TOTAL_SIZE
, "mtdram test device");
216 memset(mtd_info
->priv
, 0xff, MTDRAM_TOTAL_SIZE
);
219 #endif /* !(CONFIG_MTDRAM_ABS_POS > 0) */
221 #else /* CONFIG_MTDRAM_TOTAL_SIZE > 0 */
223 static int __init
init_mtdram(void)
227 #endif /* !(CONFIG_MTDRAM_TOTAL_SIZE > 0) */
229 module_init(init_mtdram
);
230 module_exit(cleanup_mtdram
);
232 MODULE_LICENSE("GPL");
233 MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
234 MODULE_DESCRIPTION("Simulated MTD driver for testing");