aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdchar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/mtdchar.c')
-rw-r--r--drivers/mtd/mtdchar.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 6ea2d8058a4a..548b89204aa2 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdchar.c,v 1.67 2005/02/08 17:45:51 nico Exp $ 2 * $Id: mtdchar.c,v 1.68 2005/02/08 19:12:50 nico Exp $
3 * 3 *
4 * Character-device access to raw MTD devices. 4 * Character-device access to raw MTD devices.
5 * 5 *
@@ -59,15 +59,25 @@ static inline void mtdchar_devfs_exit(void)
59#define mtdchar_devfs_exit() do { } while(0) 59#define mtdchar_devfs_exit() do { } while(0)
60#endif 60#endif
61 61
62/*
63 * We use file->private_data to store a pointer to the MTDdevice.
64 * Since alighment is at least 32 bits, we have 2 bits free for OTP
65 * modes as well.
66 */
67
68#define TO_MTD(file) (struct mtd_info *)((long)((file)->private_data) & ~3L)
62 69
63/* Well... let's abuse the unused bits in file->f_mode for those */ 70#define MTD_MODE_OTP_FACT 1
64#define MTD_MODE_OTP_FACT 0x1000 71#define MTD_MODE_OTP_USER 2
65#define MTD_MODE_OTP_USER 0x2000 72#define MTD_MODE(file) ((long)((file)->private_data) & 3)
66#define MTD_MODE_MASK 0xf000 73
74#define SET_MTD_MODE(file, mode) \
75 do { long __p = (long)((file)->private_data); \
76 (file)->private_data = (void *)((__p & ~3L) | mode); } while (0)
67 77
68static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) 78static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
69{ 79{
70 struct mtd_info *mtd = file->private_data; 80 struct mtd_info *mtd = TO_MTD(file);
71 81
72 switch (orig) { 82 switch (orig) {
73 case 0: 83 case 0:
@@ -111,10 +121,6 @@ static int mtd_open(struct inode *inode, struct file *file)
111 if ((file->f_mode & 2) && (minor & 1)) 121 if ((file->f_mode & 2) && (minor & 1))
112 return -EACCES; 122 return -EACCES;
113 123
114 /* make sure the locally abused bits are initialy clear */
115 if (file->f_mode & MTD_MODE_MASK)
116 return -EWOULDBLOCK;
117
118 mtd = get_mtd_device(NULL, devnum); 124 mtd = get_mtd_device(NULL, devnum);
119 125
120 if (!mtd) 126 if (!mtd)
@@ -144,7 +150,7 @@ static int mtd_close(struct inode *inode, struct file *file)
144 150
145 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 151 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
146 152
147 mtd = file->private_data; 153 mtd = TO_MTD(file);
148 154
149 if (mtd->sync) 155 if (mtd->sync)
150 mtd->sync(mtd); 156 mtd->sync(mtd);
@@ -161,7 +167,7 @@ static int mtd_close(struct inode *inode, struct file *file)
161 167
162static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos) 168static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
163{ 169{
164 struct mtd_info *mtd = file->private_data; 170 struct mtd_info *mtd = TO_MTD(file);
165 size_t retlen=0; 171 size_t retlen=0;
166 size_t total_retlen=0; 172 size_t total_retlen=0;
167 int ret=0; 173 int ret=0;
@@ -188,7 +194,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
188 if (!kbuf) 194 if (!kbuf)
189 return -ENOMEM; 195 return -ENOMEM;
190 196
191 switch (file->f_mode & MTD_MODE_MASK) { 197 switch (MTD_MODE(file)) {
192 case MTD_MODE_OTP_FACT: 198 case MTD_MODE_OTP_FACT:
193 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 199 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
194 break; 200 break;
@@ -231,7 +237,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
231 237
232static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos) 238static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
233{ 239{
234 struct mtd_info *mtd = file->private_data; 240 struct mtd_info *mtd = TO_MTD(file);
235 char *kbuf; 241 char *kbuf;
236 size_t retlen; 242 size_t retlen;
237 size_t total_retlen=0; 243 size_t total_retlen=0;
@@ -266,7 +272,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
266 return -EFAULT; 272 return -EFAULT;
267 } 273 }
268 274
269 switch (file->f_mode & MTD_MODE_MASK) { 275 switch (MTD_MODE(file)) {
270 case MTD_MODE_OTP_FACT: 276 case MTD_MODE_OTP_FACT:
271 ret = -EROFS; 277 ret = -EROFS;
272 break; 278 break;
@@ -310,7 +316,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
310static int mtd_ioctl(struct inode *inode, struct file *file, 316static int mtd_ioctl(struct inode *inode, struct file *file,
311 u_int cmd, u_long arg) 317 u_int cmd, u_long arg)
312{ 318{
313 struct mtd_info *mtd = file->private_data; 319 struct mtd_info *mtd = TO_MTD(file);
314 void __user *argp = (void __user *)arg; 320 void __user *argp = (void __user *)arg;
315 int ret = 0; 321 int ret = 0;
316 u_long size; 322 u_long size;
@@ -558,19 +564,19 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
558 int mode; 564 int mode;
559 if (copy_from_user(&mode, argp, sizeof(int))) 565 if (copy_from_user(&mode, argp, sizeof(int)))
560 return -EFAULT; 566 return -EFAULT;
561 file->f_mode &= ~MTD_MODE_MASK; 567 SET_MTD_MODE(file, 0);
562 switch (mode) { 568 switch (mode) {
563 case MTD_OTP_FACTORY: 569 case MTD_OTP_FACTORY:
564 if (!mtd->read_fact_prot_reg) 570 if (!mtd->read_fact_prot_reg)
565 ret = -EOPNOTSUPP; 571 ret = -EOPNOTSUPP;
566 else 572 else
567 file->f_mode |= MTD_MODE_OTP_FACT; 573 SET_MTD_MODE(file, MTD_MODE_OTP_FACT);
568 break; 574 break;
569 case MTD_OTP_USER: 575 case MTD_OTP_USER:
570 if (!mtd->read_fact_prot_reg) 576 if (!mtd->read_fact_prot_reg)
571 ret = -EOPNOTSUPP; 577 ret = -EOPNOTSUPP;
572 else 578 else
573 file->f_mode |= MTD_MODE_OTP_USER; 579 SET_MTD_MODE(file, MTD_MODE_OTP_USER);
574 break; 580 break;
575 default: 581 default:
576 ret = -EINVAL; 582 ret = -EINVAL;
@@ -587,7 +593,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
587 if (!buf) 593 if (!buf)
588 return -ENOMEM; 594 return -ENOMEM;
589 ret = -EOPNOTSUPP; 595 ret = -EOPNOTSUPP;
590 switch (file->f_mode & MTD_MODE_MASK) { 596 switch (MTD_MODE(file)) {
591 case MTD_MODE_OTP_FACT: 597 case MTD_MODE_OTP_FACT:
592 if (mtd->get_fact_prot_info) 598 if (mtd->get_fact_prot_info)
593 ret = mtd->get_fact_prot_info(mtd, buf, 4096); 599 ret = mtd->get_fact_prot_info(mtd, buf, 4096);
@@ -614,7 +620,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
614 { 620 {
615 struct otp_info info; 621 struct otp_info info;
616 622
617 if ((file->f_mode & MTD_MODE_MASK) != MTD_MODE_OTP_USER) 623 if (MTD_MODE(file) != MTD_MODE_OTP_USER)
618 return -EINVAL; 624 return -EINVAL;
619 if (copy_from_user(&info, argp, sizeof(info))) 625 if (copy_from_user(&info, argp, sizeof(info)))
620 return -EFAULT; 626 return -EFAULT;