aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-07-11 13:18:18 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-11 13:18:18 -0400
commit200d481f28be4522464bb849dd0eb5f8cb6be781 (patch)
tree8cd00ead1b202dfd377cf34000a5193959aa2e8b /drivers/mtd/devices
parentf43a64c5e1a65d12b9b53a35ed2d5db441fcb64c (diff)
parent97f927a4d7dbccde0a854a62c3ea54d90bae8679 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/tglx/mtd-2.6
Diffstat (limited to 'drivers/mtd/devices')
-rw-r--r--drivers/mtd/devices/block2mtd.c20
-rw-r--r--drivers/mtd/devices/ms02-nv.c8
-rw-r--r--drivers/mtd/devices/mtdram.c265
-rw-r--r--drivers/mtd/devices/phram.c34
-rw-r--r--drivers/mtd/devices/slram.c23
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)
89static struct page* page_readahead(struct address_space *mapping, int index) 88static 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
373static int parse_num32(u32 *num32, const char *token) 371static 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
30static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE; 22static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
31static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE; 23static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
32module_param(total_size,ulong,0);
33MODULE_PARM_DESC(total_size, "Total device size in KiB");
34module_param(erase_size,ulong,0);
35MODULE_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
28module_param(total_size, ulong, 0);
29MODULE_PARM_DESC(total_size, "Total device size in KiB");
30module_param(erase_size, ulong, 0);
31MODULE_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..
45static struct mtd_info *mtd_info; 35static struct mtd_info *mtd_info;
46 36
47 37static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
48static int
49ram_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
65static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) 50static 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
75static void ram_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, 61static 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
81static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, 66static 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
96static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, 78static 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
111static void __exit cleanup_mtdram(void) 90static 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
127int 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
156static 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 */ 100int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
188 101 unsigned long size, char *name)
189static 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
223static int __init init_mtdram(void) 127static 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
229module_init(init_mtdram); 157module_init(init_mtdram);
230module_exit(cleanup_mtdram); 158module_exit(cleanup_mtdram);
@@ -232,4 +160,3 @@ module_exit(cleanup_mtdram);
232MODULE_LICENSE("GPL"); 160MODULE_LICENSE("GPL");
233MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>"); 161MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
234MODULE_DESCRIPTION("Simulated MTD driver for testing"); 162MODULE_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 {
36static LIST_HEAD(phram_list); 34static LIST_HEAD(phram_list);
37 35
38 36
39
40static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) 37static 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
74static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 71static 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
108static void unregister_devices(void) 112static 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
222static 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 }