diff options
Diffstat (limited to 'drivers/mtd/devices/phram.c')
-rw-r--r-- | drivers/mtd/devices/phram.c | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 23423bd00b06..67823de68db6 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -33,45 +33,33 @@ struct phram_mtd_list { | |||
33 | 33 | ||
34 | static LIST_HEAD(phram_list); | 34 | static LIST_HEAD(phram_list); |
35 | 35 | ||
36 | |||
37 | static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) | 36 | static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) |
38 | { | 37 | { |
39 | u_char *start = mtd->priv; | 38 | u_char *start = mtd->priv; |
40 | 39 | ||
41 | if (instr->addr + instr->len > mtd->size) | ||
42 | return -EINVAL; | ||
43 | |||
44 | memset(start + instr->addr, 0xff, instr->len); | 40 | memset(start + instr->addr, 0xff, instr->len); |
45 | 41 | ||
46 | /* This'll catch a few races. Free the thing before returning :) | 42 | /* |
43 | * This'll catch a few races. Free the thing before returning :) | ||
47 | * I don't feel at all ashamed. This kind of thing is possible anyway | 44 | * I don't feel at all ashamed. This kind of thing is possible anyway |
48 | * with flash, but unlikely. | 45 | * with flash, but unlikely. |
49 | */ | 46 | */ |
50 | |||
51 | instr->state = MTD_ERASE_DONE; | 47 | instr->state = MTD_ERASE_DONE; |
52 | |||
53 | mtd_erase_callback(instr); | 48 | mtd_erase_callback(instr); |
54 | |||
55 | return 0; | 49 | return 0; |
56 | } | 50 | } |
57 | 51 | ||
58 | static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, | 52 | static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, |
59 | size_t *retlen, void **virt, resource_size_t *phys) | 53 | size_t *retlen, void **virt, resource_size_t *phys) |
60 | { | 54 | { |
61 | if (from + len > mtd->size) | ||
62 | return -EINVAL; | ||
63 | |||
64 | /* can we return a physical address with this driver? */ | ||
65 | if (phys) | ||
66 | return -EINVAL; | ||
67 | |||
68 | *virt = mtd->priv + from; | 55 | *virt = mtd->priv + from; |
69 | *retlen = len; | 56 | *retlen = len; |
70 | return 0; | 57 | return 0; |
71 | } | 58 | } |
72 | 59 | ||
73 | static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) | 60 | static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
74 | { | 61 | { |
62 | return 0; | ||
75 | } | 63 | } |
76 | 64 | ||
77 | static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, | 65 | static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, |
@@ -79,14 +67,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
79 | { | 67 | { |
80 | u_char *start = mtd->priv; | 68 | u_char *start = mtd->priv; |
81 | 69 | ||
82 | if (from >= mtd->size) | ||
83 | return -EINVAL; | ||
84 | |||
85 | if (len > mtd->size - from) | ||
86 | len = mtd->size - from; | ||
87 | |||
88 | memcpy(buf, start + from, len); | 70 | memcpy(buf, start + from, len); |
89 | |||
90 | *retlen = len; | 71 | *retlen = len; |
91 | return 0; | 72 | return 0; |
92 | } | 73 | } |
@@ -96,20 +77,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
96 | { | 77 | { |
97 | u_char *start = mtd->priv; | 78 | u_char *start = mtd->priv; |
98 | 79 | ||
99 | if (to >= mtd->size) | ||
100 | return -EINVAL; | ||
101 | |||
102 | if (len > mtd->size - to) | ||
103 | len = mtd->size - to; | ||
104 | |||
105 | memcpy(start + to, buf, len); | 80 | memcpy(start + to, buf, len); |
106 | |||
107 | *retlen = len; | 81 | *retlen = len; |
108 | return 0; | 82 | return 0; |
109 | } | 83 | } |
110 | 84 | ||
111 | |||
112 | |||
113 | static void unregister_devices(void) | 85 | static void unregister_devices(void) |
114 | { | 86 | { |
115 | struct phram_mtd_list *this, *safe; | 87 | struct phram_mtd_list *this, *safe; |
@@ -142,11 +114,11 @@ static int register_device(char *name, unsigned long start, unsigned long len) | |||
142 | new->mtd.name = name; | 114 | new->mtd.name = name; |
143 | new->mtd.size = len; | 115 | new->mtd.size = len; |
144 | new->mtd.flags = MTD_CAP_RAM; | 116 | new->mtd.flags = MTD_CAP_RAM; |
145 | new->mtd.erase = phram_erase; | 117 | new->mtd._erase = phram_erase; |
146 | new->mtd.point = phram_point; | 118 | new->mtd._point = phram_point; |
147 | new->mtd.unpoint = phram_unpoint; | 119 | new->mtd._unpoint = phram_unpoint; |
148 | new->mtd.read = phram_read; | 120 | new->mtd._read = phram_read; |
149 | new->mtd.write = phram_write; | 121 | new->mtd._write = phram_write; |
150 | new->mtd.owner = THIS_MODULE; | 122 | new->mtd.owner = THIS_MODULE; |
151 | new->mtd.type = MTD_RAM; | 123 | new->mtd.type = MTD_RAM; |
152 | new->mtd.erasesize = PAGE_SIZE; | 124 | new->mtd.erasesize = PAGE_SIZE; |
@@ -233,7 +205,17 @@ static inline void kill_final_newline(char *str) | |||
233 | return 1; \ | 205 | return 1; \ |
234 | } while (0) | 206 | } while (0) |
235 | 207 | ||
236 | static int phram_setup(const char *val, struct kernel_param *kp) | 208 | /* |
209 | * This shall contain the module parameter if any. It is of the form: | ||
210 | * - phram=<device>,<address>,<size> for module case | ||
211 | * - phram.phram=<device>,<address>,<size> for built-in case | ||
212 | * We leave 64 bytes for the device name, 12 for the address and 12 for the | ||
213 | * size. | ||
214 | * Example: phram.phram=rootfs,0xa0000000,512Mi | ||
215 | */ | ||
216 | static __initdata char phram_paramline[64+12+12]; | ||
217 | |||
218 | static int __init phram_setup(const char *val) | ||
237 | { | 219 | { |
238 | char buf[64+12+12], *str = buf; | 220 | char buf[64+12+12], *str = buf; |
239 | char *token[3]; | 221 | char *token[3]; |
@@ -282,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp) | |||
282 | return ret; | 264 | return ret; |
283 | } | 265 | } |
284 | 266 | ||
285 | module_param_call(phram, phram_setup, NULL, NULL, 000); | 267 | static int __init phram_param_call(const char *val, struct kernel_param *kp) |
268 | { | ||
269 | /* | ||
270 | * This function is always called before 'init_phram()', whether | ||
271 | * built-in or module. | ||
272 | */ | ||
273 | if (strlen(val) >= sizeof(phram_paramline)) | ||
274 | return -ENOSPC; | ||
275 | strcpy(phram_paramline, val); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | module_param_call(phram, phram_param_call, NULL, NULL, 000); | ||
286 | MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); | 281 | MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); |
287 | 282 | ||
288 | 283 | ||
289 | static int __init init_phram(void) | 284 | static int __init init_phram(void) |
290 | { | 285 | { |
286 | if (phram_paramline[0]) | ||
287 | return phram_setup(phram_paramline); | ||
288 | |||
291 | return 0; | 289 | return 0; |
292 | } | 290 | } |
293 | 291 | ||