diff options
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r-- | drivers/mtd/devices/block2mtd.c | 20 | ||||
-rw-r--r-- | drivers/mtd/devices/ms02-nv.c | 8 | ||||
-rw-r--r-- | drivers/mtd/devices/mtdram.c | 265 | ||||
-rw-r--r-- | drivers/mtd/devices/phram.c | 34 | ||||
-rw-r--r-- | drivers/mtd/devices/slram.c | 23 |
5 files changed, 151 insertions, 199 deletions
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index cfe6ccf07972..4a7a805e7564 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -1,10 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: block2mtd.c,v 1.23 2005/01/05 17:05:46 dwmw2 Exp $ | 2 | * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $ |
3 | * | 3 | * |
4 | * block2mtd.c - create an mtd from a block device | 4 | * block2mtd.c - create an mtd from a block device |
5 | * | 5 | * |
6 | * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> | 6 | * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> |
7 | * Copyright (C) 2004 Gareth Bult <Gareth@Encryptec.net> | ||
8 | * Copyright (C) 2004,2005 Jörn Engel <joern@wh.fh-wedel.de> | 7 | * Copyright (C) 2004,2005 Jörn Engel <joern@wh.fh-wedel.de> |
9 | * | 8 | * |
10 | * Licence: GPL | 9 | * Licence: GPL |
@@ -20,7 +19,7 @@ | |||
20 | #include <linux/mtd/mtd.h> | 19 | #include <linux/mtd/mtd.h> |
21 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
22 | 21 | ||
23 | #define VERSION "$Revision: 1.23 $" | 22 | #define VERSION "$Revision: 1.28 $" |
24 | 23 | ||
25 | 24 | ||
26 | #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) | 25 | #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) |
@@ -89,7 +88,6 @@ void cache_readahead(struct address_space *mapping, int index) | |||
89 | static struct page* page_readahead(struct address_space *mapping, int index) | 88 | static struct page* page_readahead(struct address_space *mapping, int index) |
90 | { | 89 | { |
91 | filler_t *filler = (filler_t*)mapping->a_ops->readpage; | 90 | filler_t *filler = (filler_t*)mapping->a_ops->readpage; |
92 | //do_page_cache_readahead(mapping, index, XXX, 64); | ||
93 | cache_readahead(mapping, index); | 91 | cache_readahead(mapping, index); |
94 | return read_cache_page(mapping, index, filler, NULL); | 92 | return read_cache_page(mapping, index, filler, NULL); |
95 | } | 93 | } |
@@ -157,7 +155,7 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
157 | struct block2mtd_dev *dev = mtd->priv; | 155 | struct block2mtd_dev *dev = mtd->priv; |
158 | struct page *page; | 156 | struct page *page; |
159 | int index = from >> PAGE_SHIFT; | 157 | int index = from >> PAGE_SHIFT; |
160 | int offset = from & (PAGE_SHIFT-1); | 158 | int offset = from & (PAGE_SIZE-1); |
161 | int cpylen; | 159 | int cpylen; |
162 | 160 | ||
163 | if (from > mtd->size) | 161 | if (from > mtd->size) |
@@ -370,16 +368,16 @@ static int ustrtoul(const char *cp, char **endp, unsigned int base) | |||
370 | } | 368 | } |
371 | 369 | ||
372 | 370 | ||
373 | static int parse_num32(u32 *num32, const char *token) | 371 | static int parse_num(size_t *num, const char *token) |
374 | { | 372 | { |
375 | char *endp; | 373 | char *endp; |
376 | unsigned long n; | 374 | size_t n; |
377 | 375 | ||
378 | n = ustrtoul(token, &endp, 0); | 376 | n = (size_t) ustrtoul(token, &endp, 0); |
379 | if (*endp) | 377 | if (*endp) |
380 | return -EINVAL; | 378 | return -EINVAL; |
381 | 379 | ||
382 | *num32 = n; | 380 | *num = n; |
383 | return 0; | 381 | return 0; |
384 | } | 382 | } |
385 | 383 | ||
@@ -422,7 +420,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) | |||
422 | char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */ | 420 | char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */ |
423 | char *token[2]; | 421 | char *token[2]; |
424 | char *name; | 422 | char *name; |
425 | u32 erase_size = PAGE_SIZE; | 423 | size_t erase_size = PAGE_SIZE; |
426 | int i, ret; | 424 | int i, ret; |
427 | 425 | ||
428 | if (strnlen(val, sizeof(buf)) >= sizeof(buf)) | 426 | if (strnlen(val, sizeof(buf)) >= sizeof(buf)) |
@@ -449,7 +447,7 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) | |||
449 | return 0; | 447 | return 0; |
450 | 448 | ||
451 | if (token[1]) { | 449 | if (token[1]) { |
452 | ret = parse_num32(&erase_size, token[1]); | 450 | ret = parse_num(&erase_size, token[1]); |
453 | if (ret) | 451 | if (ret) |
454 | parse_err("illegal erase size"); | 452 | parse_err("illegal erase size"); |
455 | } | 453 | } |
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 380ff08d29e4..f5026cee087f 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
7 | * 2 of the License, or (at your option) any later version. | 7 | * 2 of the License, or (at your option) any later version. |
8 | * | 8 | * |
9 | * $Id: ms02-nv.c,v 1.8 2005/01/05 18:05:12 dwmw2 Exp $ | 9 | * $Id: ms02-nv.c,v 1.10 2005/06/20 12:24:41 macro Exp $ |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -99,8 +99,8 @@ static inline uint ms02nv_probe_one(ulong addr) | |||
99 | * The firmware writes MS02NV_ID at MS02NV_MAGIC and also | 99 | * The firmware writes MS02NV_ID at MS02NV_MAGIC and also |
100 | * a diagnostic status at MS02NV_DIAG. | 100 | * a diagnostic status at MS02NV_DIAG. |
101 | */ | 101 | */ |
102 | ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG)); | 102 | ms02nv_diagp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_DIAG)); |
103 | ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC)); | 103 | ms02nv_magicp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_MAGIC)); |
104 | err = get_dbe(ms02nv_magic, ms02nv_magicp); | 104 | err = get_dbe(ms02nv_magic, ms02nv_magicp); |
105 | if (err) | 105 | if (err) |
106 | return 0; | 106 | return 0; |
@@ -233,7 +233,7 @@ static int __init ms02nv_init_one(ulong addr) | |||
233 | goto err_out_csr_res; | 233 | goto err_out_csr_res; |
234 | } | 234 | } |
235 | 235 | ||
236 | printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n", | 236 | printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %zuMiB.\n", |
237 | mtd->index, ms02nv_name, addr, size >> 20); | 237 | mtd->index, ms02nv_name, addr, size >> 20); |
238 | 238 | ||
239 | mp->next = root_ms02nv_mtd; | 239 | mp->next = root_ms02nv_mtd; |
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index edac4156d69c..bb713fed2f37 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * mtdram - a test mtd device | 2 | * mtdram - a test mtd device |
3 | * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $ | 3 | * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $ |
4 | * Author: Alexander Larsson <alex@cendio.se> | 4 | * Author: Alexander Larsson <alex@cendio.se> |
5 | * | 5 | * |
6 | * Copyright (c) 1999 Alexander Larsson <alex@cendio.se> | 6 | * Copyright (c) 1999 Alexander Larsson <alex@cendio.se> |
7 | * Copyright (c) 2005 Joern Engel <joern@wh.fh-wedel.de> | ||
7 | * | 8 | * |
8 | * This code is GPL | 9 | * This code is GPL |
9 | * | 10 | * |
@@ -18,213 +19,140 @@ | |||
18 | #include <linux/mtd/compatmac.h> | 19 | #include <linux/mtd/compatmac.h> |
19 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
20 | 21 | ||
21 | #ifndef CONFIG_MTDRAM_ABS_POS | ||
22 | #define CONFIG_MTDRAM_ABS_POS 0 | ||
23 | #endif | ||
24 | |||
25 | #if CONFIG_MTDRAM_ABS_POS > 0 | ||
26 | #include <asm/io.h> | ||
27 | #endif | ||
28 | |||
29 | #ifdef MODULE | ||
30 | static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE; | 22 | static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE; |
31 | static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE; | 23 | 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) | 24 | #define MTDRAM_TOTAL_SIZE (total_size * 1024) |
37 | #define MTDRAM_ERASE_SIZE (erase_size * 1024) | 25 | #define MTDRAM_ERASE_SIZE (erase_size * 1024) |
38 | #else | ||
39 | #define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024) | ||
40 | #define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024) | ||
41 | #endif | ||
42 | 26 | ||
27 | #ifdef MODULE | ||
28 | module_param(total_size, ulong, 0); | ||
29 | MODULE_PARM_DESC(total_size, "Total device size in KiB"); | ||
30 | module_param(erase_size, ulong, 0); | ||
31 | MODULE_PARM_DESC(erase_size, "Device erase block size in KiB"); | ||
32 | #endif | ||
43 | 33 | ||
44 | // We could store these in the mtd structure, but we only support 1 device.. | 34 | // We could store these in the mtd structure, but we only support 1 device.. |
45 | static struct mtd_info *mtd_info; | 35 | static struct mtd_info *mtd_info; |
46 | 36 | ||
47 | 37 | static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) | |
48 | static int | ||
49 | ram_erase(struct mtd_info *mtd, struct erase_info *instr) | ||
50 | { | 38 | { |
51 | DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len); | 39 | if (instr->addr + instr->len > mtd->size) |
52 | if (instr->addr + instr->len > mtd->size) { | 40 | return -EINVAL; |
53 | DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size); | 41 | |
54 | return -EINVAL; | 42 | memset((char *)mtd->priv + instr->addr, 0xff, instr->len); |
55 | } | 43 | |
56 | 44 | instr->state = MTD_ERASE_DONE; | |
57 | memset((char *)mtd->priv + instr->addr, 0xff, instr->len); | 45 | mtd_erase_callback(instr); |
58 | 46 | ||
59 | instr->state = MTD_ERASE_DONE; | 47 | return 0; |
60 | mtd_erase_callback(instr); | ||
61 | |||
62 | return 0; | ||
63 | } | 48 | } |
64 | 49 | ||
65 | static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) | 50 | static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, |
51 | size_t *retlen, u_char **mtdbuf) | ||
66 | { | 52 | { |
67 | if (from + len > mtd->size) | 53 | if (from + len > mtd->size) |
68 | return -EINVAL; | 54 | return -EINVAL; |
69 | 55 | ||
70 | *mtdbuf = mtd->priv + from; | 56 | *mtdbuf = mtd->priv + from; |
71 | *retlen = len; | 57 | *retlen = len; |
72 | return 0; | 58 | return 0; |
73 | } | 59 | } |
74 | 60 | ||
75 | static void ram_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, | 61 | static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from, |
76 | size_t len) | 62 | size_t len) |
77 | { | 63 | { |
78 | DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n"); | ||
79 | } | 64 | } |
80 | 65 | ||
81 | static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, | 66 | static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, |
82 | size_t *retlen, u_char *buf) | 67 | size_t *retlen, u_char *buf) |
83 | { | 68 | { |
84 | DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len); | 69 | if (from + len > mtd->size) |
85 | if (from + len > mtd->size) { | 70 | return -EINVAL; |
86 | DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | 71 | ||
90 | memcpy(buf, mtd->priv + from, len); | 72 | memcpy(buf, mtd->priv + from, len); |
91 | 73 | ||
92 | *retlen=len; | 74 | *retlen = len; |
93 | return 0; | 75 | return 0; |
94 | } | 76 | } |
95 | 77 | ||
96 | static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, | 78 | static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, |
97 | size_t *retlen, const u_char *buf) | 79 | size_t *retlen, const u_char *buf) |
98 | { | 80 | { |
99 | DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len); | 81 | if (to + len > mtd->size) |
100 | if (to + len > mtd->size) { | 82 | return -EINVAL; |
101 | DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | 83 | ||
105 | memcpy ((char *)mtd->priv + to, buf, len); | 84 | memcpy((char *)mtd->priv + to, buf, len); |
106 | 85 | ||
107 | *retlen=len; | 86 | *retlen = len; |
108 | return 0; | 87 | return 0; |
109 | } | 88 | } |
110 | 89 | ||
111 | static void __exit cleanup_mtdram(void) | 90 | static void __exit cleanup_mtdram(void) |
112 | { | 91 | { |
113 | if (mtd_info) { | 92 | if (mtd_info) { |
114 | del_mtd_device(mtd_info); | 93 | del_mtd_device(mtd_info); |
115 | #if CONFIG_MTDRAM_TOTAL_SIZE > 0 | 94 | if (mtd_info->priv) |
116 | if (mtd_info->priv) | 95 | vfree(mtd_info->priv); |
117 | #if CONFIG_MTDRAM_ABS_POS > 0 | 96 | kfree(mtd_info); |
118 | iounmap(mtd_info->priv); | 97 | } |
119 | #else | ||
120 | vfree(mtd_info->priv); | ||
121 | #endif | ||
122 | #endif | ||
123 | kfree(mtd_info); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, | ||
128 | unsigned long size, char *name) | ||
129 | { | ||
130 | memset(mtd, 0, sizeof(*mtd)); | ||
131 | |||
132 | /* Setup the MTD structure */ | ||
133 | mtd->name = name; | ||
134 | mtd->type = MTD_RAM; | ||
135 | mtd->flags = MTD_CAP_RAM; | ||
136 | mtd->size = size; | ||
137 | mtd->erasesize = MTDRAM_ERASE_SIZE; | ||
138 | mtd->priv = mapped_address; | ||
139 | |||
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; | ||
146 | |||
147 | if (add_mtd_device(mtd)) { | ||
148 | return -EIO; | ||
149 | } | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | #if CONFIG_MTDRAM_TOTAL_SIZE > 0 | ||
155 | #if CONFIG_MTDRAM_ABS_POS > 0 | ||
156 | static int __init init_mtdram(void) | ||
157 | { | ||
158 | void *addr; | ||
159 | int err; | ||
160 | /* Allocate some memory */ | ||
161 | mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); | ||
162 | if (!mtd_info) | ||
163 | return -ENOMEM; | ||
164 | |||
165 | addr = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE); | ||
166 | if (!addr) { | ||
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); | ||
170 | kfree(mtd_info); | ||
171 | mtd_info = NULL; | ||
172 | return -ENOMEM; | ||
173 | } | ||
174 | err = mtdram_init_device(mtd_info, addr, | ||
175 | MTDRAM_TOTAL_SIZE, "mtdram test device"); | ||
176 | if (err) | ||
177 | { | ||
178 | iounmap(addr); | ||
179 | kfree(mtd_info); | ||
180 | mtd_info = NULL; | ||
181 | return err; | ||
182 | } | ||
183 | memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE); | ||
184 | return err; | ||
185 | } | 98 | } |
186 | 99 | ||
187 | #else /* CONFIG_MTDRAM_ABS_POS > 0 */ | 100 | int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, |
188 | 101 | unsigned long size, char *name) | |
189 | static int __init init_mtdram(void) | ||
190 | { | 102 | { |
191 | void *addr; | 103 | memset(mtd, 0, sizeof(*mtd)); |
192 | int err; | 104 | |
193 | /* Allocate some memory */ | 105 | /* Setup the MTD structure */ |
194 | mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); | 106 | mtd->name = name; |
195 | if (!mtd_info) | 107 | mtd->type = MTD_RAM; |
196 | return -ENOMEM; | 108 | mtd->flags = MTD_CAP_RAM; |
197 | 109 | mtd->size = size; | |
198 | addr = vmalloc(MTDRAM_TOTAL_SIZE); | 110 | mtd->erasesize = MTDRAM_ERASE_SIZE; |
199 | if (!addr) { | 111 | mtd->priv = mapped_address; |
200 | DEBUG(MTD_DEBUG_LEVEL1, | 112 | |
201 | "Failed to vmalloc memory region of size %ld\n", | 113 | mtd->owner = THIS_MODULE; |
202 | (long)MTDRAM_TOTAL_SIZE); | 114 | mtd->erase = ram_erase; |
203 | kfree(mtd_info); | 115 | mtd->point = ram_point; |
204 | mtd_info = NULL; | 116 | mtd->unpoint = ram_unpoint; |
205 | return -ENOMEM; | 117 | mtd->read = ram_read; |
206 | } | 118 | mtd->write = ram_write; |
207 | err = mtdram_init_device(mtd_info, addr, | 119 | |
208 | MTDRAM_TOTAL_SIZE, "mtdram test device"); | 120 | if (add_mtd_device(mtd)) { |
209 | if (err) | 121 | return -EIO; |
210 | { | 122 | } |
211 | vfree(addr); | 123 | |
212 | kfree(mtd_info); | 124 | return 0; |
213 | mtd_info = NULL; | ||
214 | return err; | ||
215 | } | ||
216 | memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE); | ||
217 | return err; | ||
218 | } | 125 | } |
219 | #endif /* !(CONFIG_MTDRAM_ABS_POS > 0) */ | ||
220 | |||
221 | #else /* CONFIG_MTDRAM_TOTAL_SIZE > 0 */ | ||
222 | 126 | ||
223 | static int __init init_mtdram(void) | 127 | static int __init init_mtdram(void) |
224 | { | 128 | { |
225 | return 0; | 129 | void *addr; |
130 | int err; | ||
131 | |||
132 | if (!total_size) | ||
133 | return -EINVAL; | ||
134 | |||
135 | /* Allocate some memory */ | ||
136 | mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); | ||
137 | if (!mtd_info) | ||
138 | return -ENOMEM; | ||
139 | |||
140 | addr = vmalloc(MTDRAM_TOTAL_SIZE); | ||
141 | if (!addr) { | ||
142 | kfree(mtd_info); | ||
143 | mtd_info = NULL; | ||
144 | return -ENOMEM; | ||
145 | } | ||
146 | err = mtdram_init_device(mtd_info, addr, MTDRAM_TOTAL_SIZE, "mtdram test device"); | ||
147 | if (err) { | ||
148 | vfree(addr); | ||
149 | kfree(mtd_info); | ||
150 | mtd_info = NULL; | ||
151 | return err; | ||
152 | } | ||
153 | memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE); | ||
154 | return err; | ||
226 | } | 155 | } |
227 | #endif /* !(CONFIG_MTDRAM_TOTAL_SIZE > 0) */ | ||
228 | 156 | ||
229 | module_init(init_mtdram); | 157 | module_init(init_mtdram); |
230 | module_exit(cleanup_mtdram); | 158 | module_exit(cleanup_mtdram); |
@@ -232,4 +160,3 @@ module_exit(cleanup_mtdram); | |||
232 | MODULE_LICENSE("GPL"); | 160 | MODULE_LICENSE("GPL"); |
233 | MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>"); | 161 | MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>"); |
234 | MODULE_DESCRIPTION("Simulated MTD driver for testing"); | 162 | MODULE_DESCRIPTION("Simulated MTD driver for testing"); |
235 | |||
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 5f8e164ddb71..a423a382095a 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * $Id: phram.c,v 1.11 2005/01/05 18:05:13 dwmw2 Exp $ | 2 | * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> | 4 | * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> |
5 | * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> | 5 | * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> |
@@ -15,9 +15,7 @@ | |||
15 | * | 15 | * |
16 | * Example: | 16 | * Example: |
17 | * phram=swap,64Mi,128Mi phram=test,900Mi,1Mi | 17 | * phram=swap,64Mi,128Mi phram=test,900Mi,1Mi |
18 | * | ||
19 | */ | 18 | */ |
20 | |||
21 | #include <asm/io.h> | 19 | #include <asm/io.h> |
22 | #include <linux/init.h> | 20 | #include <linux/init.h> |
23 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -36,7 +34,6 @@ struct phram_mtd_list { | |||
36 | static LIST_HEAD(phram_list); | 34 | static LIST_HEAD(phram_list); |
37 | 35 | ||
38 | 36 | ||
39 | |||
40 | static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) | 37 | static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) |
41 | { | 38 | { |
42 | u_char *start = mtd->priv; | 39 | u_char *start = mtd->priv; |
@@ -71,7 +68,8 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, | |||
71 | return 0; | 68 | return 0; |
72 | } | 69 | } |
73 | 70 | ||
74 | static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) | 71 | static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, |
72 | size_t len) | ||
75 | { | 73 | { |
76 | } | 74 | } |
77 | 75 | ||
@@ -80,8 +78,11 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
80 | { | 78 | { |
81 | u_char *start = mtd->priv; | 79 | u_char *start = mtd->priv; |
82 | 80 | ||
83 | if (from + len > mtd->size) | 81 | if (from >= mtd->size) |
84 | return -EINVAL; | 82 | return -EINVAL; |
83 | |||
84 | if (len > mtd->size - from) | ||
85 | len = mtd->size - from; | ||
85 | 86 | ||
86 | memcpy(buf, start + from, len); | 87 | memcpy(buf, start + from, len); |
87 | 88 | ||
@@ -94,8 +95,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
94 | { | 95 | { |
95 | u_char *start = mtd->priv; | 96 | u_char *start = mtd->priv; |
96 | 97 | ||
97 | if (to + len > mtd->size) | 98 | if (to >= mtd->size) |
98 | return -EINVAL; | 99 | return -EINVAL; |
100 | |||
101 | if (len > mtd->size - to) | ||
102 | len = mtd->size - to; | ||
99 | 103 | ||
100 | memcpy(start + to, buf, len); | 104 | memcpy(start + to, buf, len); |
101 | 105 | ||
@@ -107,9 +111,9 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
107 | 111 | ||
108 | static void unregister_devices(void) | 112 | static void unregister_devices(void) |
109 | { | 113 | { |
110 | struct phram_mtd_list *this; | 114 | struct phram_mtd_list *this, *safe; |
111 | 115 | ||
112 | list_for_each_entry(this, &phram_list, list) { | 116 | list_for_each_entry_safe(this, safe, &phram_list, list) { |
113 | del_mtd_device(&this->mtd); | 117 | del_mtd_device(&this->mtd); |
114 | iounmap(this->mtd.priv); | 118 | iounmap(this->mtd.priv); |
115 | kfree(this); | 119 | kfree(this); |
@@ -145,7 +149,7 @@ static int register_device(char *name, unsigned long start, unsigned long len) | |||
145 | new->mtd.write = phram_write; | 149 | new->mtd.write = phram_write; |
146 | new->mtd.owner = THIS_MODULE; | 150 | new->mtd.owner = THIS_MODULE; |
147 | new->mtd.type = MTD_RAM; | 151 | new->mtd.type = MTD_RAM; |
148 | new->mtd.erasesize = 0; | 152 | new->mtd.erasesize = PAGE_SIZE; |
149 | 153 | ||
150 | ret = -EAGAIN; | 154 | ret = -EAGAIN; |
151 | if (add_mtd_device(&new->mtd)) { | 155 | if (add_mtd_device(&new->mtd)) { |
@@ -214,6 +218,15 @@ static int parse_name(char **pname, const char *token) | |||
214 | return 0; | 218 | return 0; |
215 | } | 219 | } |
216 | 220 | ||
221 | |||
222 | static inline void kill_final_newline(char *str) | ||
223 | { | ||
224 | char *newline = strrchr(str, '\n'); | ||
225 | if (newline && !newline[1]) | ||
226 | *newline = 0; | ||
227 | } | ||
228 | |||
229 | |||
217 | #define parse_err(fmt, args...) do { \ | 230 | #define parse_err(fmt, args...) do { \ |
218 | ERROR(fmt , ## args); \ | 231 | ERROR(fmt , ## args); \ |
219 | return 0; \ | 232 | return 0; \ |
@@ -232,6 +245,7 @@ static int phram_setup(const char *val, struct kernel_param *kp) | |||
232 | parse_err("parameter too long\n"); | 245 | parse_err("parameter too long\n"); |
233 | 246 | ||
234 | strcpy(str, val); | 247 | strcpy(str, val); |
248 | kill_final_newline(str); | ||
235 | 249 | ||
236 | for (i=0; i<3; i++) | 250 | for (i=0; i<3; i++) |
237 | token[i] = strsep(&str, ","); | 251 | token[i] = strsep(&str, ","); |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 5ab15e643be7..84fa91392a8c 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /*====================================================================== | 1 | /*====================================================================== |
2 | 2 | ||
3 | $Id: slram.c,v 1.33 2005/01/05 18:05:13 dwmw2 Exp $ | 3 | $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $ |
4 | 4 | ||
5 | This driver provides a method to access memory not used by the kernel | 5 | This driver provides a method to access memory not used by the kernel |
6 | itself (i.e. if the kernel commandline mem=xxx is used). To actually | 6 | itself (i.e. if the kernel commandline mem=xxx is used). To actually |
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/mtd/mtd.h> | 50 | #include <linux/mtd/mtd.h> |
51 | 51 | ||
52 | #define SLRAM_MAX_DEVICES_PARAMS 6 /* 3 parameters / device */ | 52 | #define SLRAM_MAX_DEVICES_PARAMS 6 /* 3 parameters / device */ |
53 | #define SLRAM_BLK_SZ 0x4000 | ||
53 | 54 | ||
54 | #define T(fmt, args...) printk(KERN_DEBUG fmt, ## args) | 55 | #define T(fmt, args...) printk(KERN_DEBUG fmt, ## args) |
55 | #define E(fmt, args...) printk(KERN_NOTICE fmt, ## args) | 56 | #define E(fmt, args...) printk(KERN_NOTICE fmt, ## args) |
@@ -108,6 +109,9 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, | |||
108 | { | 109 | { |
109 | slram_priv_t *priv = mtd->priv; | 110 | slram_priv_t *priv = mtd->priv; |
110 | 111 | ||
112 | if (from + len > mtd->size) | ||
113 | return -EINVAL; | ||
114 | |||
111 | *mtdbuf = priv->start + from; | 115 | *mtdbuf = priv->start + from; |
112 | *retlen = len; | 116 | *retlen = len; |
113 | return(0); | 117 | return(0); |
@@ -121,7 +125,13 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
121 | size_t *retlen, u_char *buf) | 125 | size_t *retlen, u_char *buf) |
122 | { | 126 | { |
123 | slram_priv_t *priv = mtd->priv; | 127 | slram_priv_t *priv = mtd->priv; |
124 | 128 | ||
129 | if (from > mtd->size) | ||
130 | return -EINVAL; | ||
131 | |||
132 | if (from + len > mtd->size) | ||
133 | len = mtd->size - from; | ||
134 | |||
125 | memcpy(buf, priv->start + from, len); | 135 | memcpy(buf, priv->start + from, len); |
126 | 136 | ||
127 | *retlen = len; | 137 | *retlen = len; |
@@ -133,6 +143,9 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
133 | { | 143 | { |
134 | slram_priv_t *priv = mtd->priv; | 144 | slram_priv_t *priv = mtd->priv; |
135 | 145 | ||
146 | if (to + len > mtd->size) | ||
147 | return -EINVAL; | ||
148 | |||
136 | memcpy(priv->start + to, buf, len); | 149 | memcpy(priv->start + to, buf, len); |
137 | 150 | ||
138 | *retlen = len; | 151 | *retlen = len; |
@@ -188,7 +201,7 @@ static int register_device(char *name, unsigned long start, unsigned long length | |||
188 | (*curmtd)->mtdinfo->name = name; | 201 | (*curmtd)->mtdinfo->name = name; |
189 | (*curmtd)->mtdinfo->size = length; | 202 | (*curmtd)->mtdinfo->size = length; |
190 | (*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS | | 203 | (*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS | |
191 | MTD_WRITEB_WRITEABLE | MTD_VOLATILE; | 204 | MTD_WRITEB_WRITEABLE | MTD_VOLATILE | MTD_CAP_RAM; |
192 | (*curmtd)->mtdinfo->erase = slram_erase; | 205 | (*curmtd)->mtdinfo->erase = slram_erase; |
193 | (*curmtd)->mtdinfo->point = slram_point; | 206 | (*curmtd)->mtdinfo->point = slram_point; |
194 | (*curmtd)->mtdinfo->unpoint = slram_unpoint; | 207 | (*curmtd)->mtdinfo->unpoint = slram_unpoint; |
@@ -196,7 +209,7 @@ static int register_device(char *name, unsigned long start, unsigned long length | |||
196 | (*curmtd)->mtdinfo->write = slram_write; | 209 | (*curmtd)->mtdinfo->write = slram_write; |
197 | (*curmtd)->mtdinfo->owner = THIS_MODULE; | 210 | (*curmtd)->mtdinfo->owner = THIS_MODULE; |
198 | (*curmtd)->mtdinfo->type = MTD_RAM; | 211 | (*curmtd)->mtdinfo->type = MTD_RAM; |
199 | (*curmtd)->mtdinfo->erasesize = 0x0; | 212 | (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; |
200 | 213 | ||
201 | if (add_mtd_device((*curmtd)->mtdinfo)) { | 214 | if (add_mtd_device((*curmtd)->mtdinfo)) { |
202 | E("slram: Failed to register new device\n"); | 215 | E("slram: Failed to register new device\n"); |
@@ -261,7 +274,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) | |||
261 | } | 274 | } |
262 | T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", | 275 | T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", |
263 | devname, devstart, devlength); | 276 | devname, devstart, devlength); |
264 | if ((devstart < 0) || (devlength < 0)) { | 277 | if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { |
265 | E("slram: Illegal start / length parameter.\n"); | 278 | E("slram: Illegal start / length parameter.\n"); |
266 | return(-EINVAL); | 279 | return(-EINVAL); |
267 | } | 280 | } |