diff options
Diffstat (limited to 'drivers/mtd/mtdchar.c')
-rw-r--r-- | drivers/mtd/mtdchar.c | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index d1ffd246ad55..6f044584bdc6 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: mtdchar.c,v 1.75 2005/11/06 10:04:37 gleixner Exp $ | 2 | * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $ |
3 | * | 3 | * |
4 | * Character-device access to raw MTD devices. | 4 | * Character-device access to raw MTD devices. |
5 | * | 5 | * |
@@ -28,7 +28,7 @@ static void mtd_notify_add(struct mtd_info* mtd) | |||
28 | 28 | ||
29 | class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), | 29 | class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), |
30 | NULL, "mtd%d", mtd->index); | 30 | NULL, "mtd%d", mtd->index); |
31 | 31 | ||
32 | class_device_create(mtd_class, NULL, | 32 | class_device_create(mtd_class, NULL, |
33 | MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), | 33 | MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), |
34 | NULL, "mtd%dro", mtd->index); | 34 | NULL, "mtd%dro", mtd->index); |
@@ -108,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file) | |||
108 | return -EACCES; | 108 | return -EACCES; |
109 | 109 | ||
110 | mtd = get_mtd_device(NULL, devnum); | 110 | mtd = get_mtd_device(NULL, devnum); |
111 | 111 | ||
112 | if (!mtd) | 112 | if (!mtd) |
113 | return -ENODEV; | 113 | return -ENODEV; |
114 | 114 | ||
115 | if (MTD_ABSENT == mtd->type) { | 115 | if (MTD_ABSENT == mtd->type) { |
116 | put_mtd_device(mtd); | 116 | put_mtd_device(mtd); |
117 | return -ENODEV; | 117 | return -ENODEV; |
118 | } | 118 | } |
119 | 119 | ||
120 | file->private_data = mtd; | 120 | file->private_data = mtd; |
121 | 121 | ||
122 | /* You can't open it RW if it's not a writeable device */ | 122 | /* You can't open it RW if it's not a writeable device */ |
123 | if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { | 123 | if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { |
124 | put_mtd_device(mtd); | 124 | put_mtd_device(mtd); |
125 | return -EACCES; | 125 | return -EACCES; |
126 | } | 126 | } |
127 | 127 | ||
128 | return 0; | 128 | return 0; |
129 | } /* mtd_open */ | 129 | } /* mtd_open */ |
130 | 130 | ||
@@ -137,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file) | |||
137 | DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); | 137 | DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); |
138 | 138 | ||
139 | mtd = TO_MTD(file); | 139 | mtd = TO_MTD(file); |
140 | 140 | ||
141 | if (mtd->sync) | 141 | if (mtd->sync) |
142 | mtd->sync(mtd); | 142 | mtd->sync(mtd); |
143 | 143 | ||
144 | put_mtd_device(mtd); | 144 | put_mtd_device(mtd); |
145 | 145 | ||
146 | return 0; | 146 | return 0; |
@@ -159,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
159 | int ret=0; | 159 | int ret=0; |
160 | int len; | 160 | int len; |
161 | char *kbuf; | 161 | char *kbuf; |
162 | 162 | ||
163 | DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); | 163 | DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); |
164 | 164 | ||
165 | if (*ppos + count > mtd->size) | 165 | if (*ppos + count > mtd->size) |
@@ -167,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
167 | 167 | ||
168 | if (!count) | 168 | if (!count) |
169 | return 0; | 169 | return 0; |
170 | 170 | ||
171 | /* FIXME: Use kiovec in 2.5 to lock down the user's buffers | 171 | /* FIXME: Use kiovec in 2.5 to lock down the user's buffers |
172 | and pass them directly to the MTD functions */ | 172 | and pass them directly to the MTD functions */ |
173 | while (count) { | 173 | while (count) { |
174 | if (count > MAX_KMALLOC_SIZE) | 174 | if (count > MAX_KMALLOC_SIZE) |
175 | len = MAX_KMALLOC_SIZE; | 175 | len = MAX_KMALLOC_SIZE; |
176 | else | 176 | else |
177 | len = count; | 177 | len = count; |
@@ -179,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
179 | kbuf=kmalloc(len,GFP_KERNEL); | 179 | kbuf=kmalloc(len,GFP_KERNEL); |
180 | if (!kbuf) | 180 | if (!kbuf) |
181 | return -ENOMEM; | 181 | return -ENOMEM; |
182 | 182 | ||
183 | switch (MTD_MODE(file)) { | 183 | switch (MTD_MODE(file)) { |
184 | case MTD_MODE_OTP_FACT: | 184 | case MTD_MODE_OTP_FACT: |
185 | ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); | 185 | ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); |
@@ -192,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
192 | } | 192 | } |
193 | /* Nand returns -EBADMSG on ecc errors, but it returns | 193 | /* Nand returns -EBADMSG on ecc errors, but it returns |
194 | * the data. For our userspace tools it is important | 194 | * the data. For our userspace tools it is important |
195 | * to dump areas with ecc errors ! | 195 | * to dump areas with ecc errors ! |
196 | * Userspace software which accesses NAND this way | 196 | * Userspace software which accesses NAND this way |
197 | * must be aware of the fact that it deals with NAND | 197 | * must be aware of the fact that it deals with NAND |
198 | */ | 198 | */ |
@@ -214,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t | |||
214 | kfree(kbuf); | 214 | kfree(kbuf); |
215 | return ret; | 215 | return ret; |
216 | } | 216 | } |
217 | 217 | ||
218 | kfree(kbuf); | 218 | kfree(kbuf); |
219 | } | 219 | } |
220 | 220 | ||
@@ -231,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count | |||
231 | int len; | 231 | int len; |
232 | 232 | ||
233 | DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); | 233 | DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); |
234 | 234 | ||
235 | if (*ppos == mtd->size) | 235 | if (*ppos == mtd->size) |
236 | return -ENOSPC; | 236 | return -ENOSPC; |
237 | 237 | ||
238 | if (*ppos + count > mtd->size) | 238 | if (*ppos + count > mtd->size) |
239 | count = mtd->size - *ppos; | 239 | count = mtd->size - *ppos; |
240 | 240 | ||
@@ -242,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count | |||
242 | return 0; | 242 | return 0; |
243 | 243 | ||
244 | while (count) { | 244 | while (count) { |
245 | if (count > MAX_KMALLOC_SIZE) | 245 | if (count > MAX_KMALLOC_SIZE) |
246 | len = MAX_KMALLOC_SIZE; | 246 | len = MAX_KMALLOC_SIZE; |
247 | else | 247 | else |
248 | len = count; | 248 | len = count; |
@@ -257,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count | |||
257 | kfree(kbuf); | 257 | kfree(kbuf); |
258 | return -EFAULT; | 258 | return -EFAULT; |
259 | } | 259 | } |
260 | 260 | ||
261 | switch (MTD_MODE(file)) { | 261 | switch (MTD_MODE(file)) { |
262 | case MTD_MODE_OTP_FACT: | 262 | case MTD_MODE_OTP_FACT: |
263 | ret = -EROFS; | 263 | ret = -EROFS; |
@@ -282,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count | |||
282 | kfree(kbuf); | 282 | kfree(kbuf); |
283 | return ret; | 283 | return ret; |
284 | } | 284 | } |
285 | 285 | ||
286 | kfree(kbuf); | 286 | kfree(kbuf); |
287 | } | 287 | } |
288 | 288 | ||
@@ -306,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
306 | void __user *argp = (void __user *)arg; | 306 | void __user *argp = (void __user *)arg; |
307 | int ret = 0; | 307 | int ret = 0; |
308 | u_long size; | 308 | u_long size; |
309 | 309 | ||
310 | DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); | 310 | DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); |
311 | 311 | ||
312 | size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; | 312 | size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; |
@@ -318,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
318 | if (!access_ok(VERIFY_WRITE, argp, size)) | 318 | if (!access_ok(VERIFY_WRITE, argp, size)) |
319 | return -EFAULT; | 319 | return -EFAULT; |
320 | } | 320 | } |
321 | 321 | ||
322 | switch (cmd) { | 322 | switch (cmd) { |
323 | case MEMGETREGIONCOUNT: | 323 | case MEMGETREGIONCOUNT: |
324 | if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) | 324 | if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) |
@@ -370,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
370 | erase->mtd = mtd; | 370 | erase->mtd = mtd; |
371 | erase->callback = mtdchar_erase_callback; | 371 | erase->callback = mtdchar_erase_callback; |
372 | erase->priv = (unsigned long)&waitq; | 372 | erase->priv = (unsigned long)&waitq; |
373 | 373 | ||
374 | /* | 374 | /* |
375 | FIXME: Allow INTERRUPTIBLE. Which means | 375 | FIXME: Allow INTERRUPTIBLE. Which means |
376 | not having the wait_queue head on the stack. | 376 | not having the wait_queue head on the stack. |
377 | 377 | ||
378 | If the wq_head is on the stack, and we | 378 | If the wq_head is on the stack, and we |
379 | leave because we got interrupted, then the | 379 | leave because we got interrupted, then the |
380 | wq_head is no longer there when the | 380 | wq_head is no longer there when the |
@@ -402,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
402 | struct mtd_oob_buf buf; | 402 | struct mtd_oob_buf buf; |
403 | void *databuf; | 403 | void *databuf; |
404 | ssize_t retlen; | 404 | ssize_t retlen; |
405 | 405 | ||
406 | if(!(file->f_mode & 2)) | 406 | if(!(file->f_mode & 2)) |
407 | return -EPERM; | 407 | return -EPERM; |
408 | 408 | ||
409 | if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) | 409 | if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) |
410 | return -EFAULT; | 410 | return -EFAULT; |
411 | 411 | ||
412 | if (buf.length > 0x4096) | 412 | if (buf.length > 0x4096) |
413 | return -EINVAL; | 413 | return -EINVAL; |
414 | 414 | ||
@@ -424,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
424 | databuf = kmalloc(buf.length, GFP_KERNEL); | 424 | databuf = kmalloc(buf.length, GFP_KERNEL); |
425 | if (!databuf) | 425 | if (!databuf) |
426 | return -ENOMEM; | 426 | return -ENOMEM; |
427 | 427 | ||
428 | if (copy_from_user(databuf, buf.ptr, buf.length)) { | 428 | if (copy_from_user(databuf, buf.ptr, buf.length)) { |
429 | kfree(databuf); | 429 | kfree(databuf); |
430 | return -EFAULT; | 430 | return -EFAULT; |
@@ -448,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
448 | 448 | ||
449 | if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) | 449 | if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) |
450 | return -EFAULT; | 450 | return -EFAULT; |
451 | 451 | ||
452 | if (buf.length > 0x4096) | 452 | if (buf.length > 0x4096) |
453 | return -EINVAL; | 453 | return -EINVAL; |
454 | 454 | ||
@@ -464,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
464 | databuf = kmalloc(buf.length, GFP_KERNEL); | 464 | databuf = kmalloc(buf.length, GFP_KERNEL); |
465 | if (!databuf) | 465 | if (!databuf) |
466 | return -ENOMEM; | 466 | return -ENOMEM; |
467 | 467 | ||
468 | ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); | 468 | ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); |
469 | 469 | ||
470 | if (put_user(retlen, (uint32_t __user *)argp)) | 470 | if (put_user(retlen, (uint32_t __user *)argp)) |
471 | ret = -EFAULT; | 471 | ret = -EFAULT; |
472 | else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) | 472 | else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) |
473 | ret = -EFAULT; | 473 | ret = -EFAULT; |
474 | 474 | ||
475 | kfree(databuf); | 475 | kfree(databuf); |
476 | break; | 476 | break; |
477 | } | 477 | } |
@@ -521,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
521 | case MEMGETBADBLOCK: | 521 | case MEMGETBADBLOCK: |
522 | { | 522 | { |
523 | loff_t offs; | 523 | loff_t offs; |
524 | 524 | ||
525 | if (copy_from_user(&offs, argp, sizeof(loff_t))) | 525 | if (copy_from_user(&offs, argp, sizeof(loff_t))) |
526 | return -EFAULT; | 526 | return -EFAULT; |
527 | if (!mtd->block_isbad) | 527 | if (!mtd->block_isbad) |