/*
- * $Id: mtdchar.c,v 1.64 2004/08/09 13:59:46 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.54 2003/05/21 10:50:43 dwmw2 Exp $
*
* Character-device access to raw MTD devices.
*
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
-#include <linux/mtd/compatmac.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
#ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h>
-
-static void mtd_notify_add(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
- S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index);
-
- devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
- S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index);
-}
-
-static void mtd_notify_remove(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
- devfs_remove("mtd/%d", mtd->index);
- devfs_remove("mtd/%dro", mtd->index);
-}
+static void mtd_notify_add(struct mtd_info* mtd);
+static void mtd_notify_remove(struct mtd_info* mtd);
static struct mtd_notifier notifier = {
.add = mtd_notify_add,
.remove = mtd_notify_remove,
};
-static inline void mtdchar_devfs_init(void)
-{
- devfs_mk_dir("mtd");
- register_mtd_user(¬ifier);
-}
-
-static inline void mtdchar_devfs_exit(void)
-{
- unregister_mtd_user(¬ifier);
- devfs_remove("mtd");
-}
-#else /* !DEVFS */
-#define mtdchar_devfs_init() do { } while(0)
-#define mtdchar_devfs_exit() do { } while(0)
#endif
static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
IOCTL calls for getting device parameters.
======================================================================*/
-static void mtdchar_erase_callback (struct erase_info *instr)
+static void mtd_erase_callback (struct erase_info *instr)
{
wake_up((wait_queue_head_t *)instr->priv);
}
memset (erase,0,sizeof(struct erase_info));
if (copy_from_user(&erase->addr, argp,
- sizeof(struct erase_info_user))) {
+ 2 * sizeof(u_long))) {
kfree(erase);
return -EFAULT;
}
erase->mtd = mtd;
- erase->callback = mtdchar_erase_callback;
+ erase->callback = mtd_erase_callback;
erase->priv = (unsigned long)&waitq;
/*
ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf);
- if (copy_to_user(argp + sizeof(uint32_t), &retlen, sizeof(uint32_t)))
+ if (copy_to_user(argp + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
ret = -EFAULT;
kfree(databuf);
ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
- if (put_user(retlen, (uint32_t __user *)argp))
+ if (copy_to_user(argp + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
ret = -EFAULT;
else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
ret = -EFAULT;
case MEMLOCK:
{
- struct erase_info_user info;
+ unsigned long adrs[2];
- if (copy_from_user(&info, argp, sizeof(info)))
+ if (copy_from_user(adrs, argp, 2* sizeof(unsigned long)))
return -EFAULT;
if (!mtd->lock)
ret = -EOPNOTSUPP;
else
- ret = mtd->lock(mtd, info.start, info.length);
+ ret = mtd->lock(mtd, adrs[0], adrs[1]);
break;
}
case MEMUNLOCK:
{
- struct erase_info_user info;
+ unsigned long adrs[2];
- if (copy_from_user(&info, argp, sizeof(info)))
+ if (copy_from_user(adrs, argp, 2* sizeof(unsigned long)))
return -EFAULT;
if (!mtd->unlock)
ret = -EOPNOTSUPP;
else
- ret = mtd->unlock(mtd, info.start, info.length);
+ ret = mtd->unlock(mtd, adrs[0], adrs[1]);
break;
}
return -EFAULT;
break;
}
-
- case MEMGETOOBSEL:
- {
- if (copy_to_user(argp, &(mtd->oobinfo), sizeof(struct nand_oobinfo)))
- return -EFAULT;
- break;
- }
-
- case MEMGETBADBLOCK:
- {
- loff_t offs;
- if (copy_from_user(&offs, argp, sizeof(loff_t)))
- return -EFAULT;
- if (!mtd->block_isbad)
- ret = -EOPNOTSUPP;
- else
- return mtd->block_isbad(mtd, offs);
- break;
- }
-
- case MEMSETBADBLOCK:
- {
- loff_t offs;
-
- if (copy_from_user(&offs, argp, sizeof(loff_t)))
- return -EFAULT;
- if (!mtd->block_markbad)
- ret = -EOPNOTSUPP;
- else
- return mtd->block_markbad(mtd, offs);
- break;
- }
-
default:
+ DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
ret = -ENOTTY;
}
.release = mtd_close,
};
+
+#ifdef CONFIG_DEVFS_FS
+/* Notification that a new device has been added. Create the devfs entry for
+ * it. */
+
+static void mtd_notify_add(struct mtd_info* mtd)
+{
+ if (!mtd)
+ return;
+ devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+ S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index);
+ devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+ S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%dro", mtd->index);
+}
+
+static void mtd_notify_remove(struct mtd_info* mtd)
+{
+ if (!mtd)
+ return;
+ devfs_remove("mtd/%d", mtd->index);
+ devfs_remove("mtd/%dro", mtd->index);
+}
+#endif
+
static int __init init_mtdchar(void)
{
if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) {
return -EAGAIN;
}
- mtdchar_devfs_init();
+#ifdef CONFIG_DEVFS_FS
+ devfs_mk_dir("mtd");
+
+ register_mtd_user(¬ifier);
+#endif
return 0;
}
static void __exit cleanup_mtdchar(void)
{
- mtdchar_devfs_exit();
+#ifdef CONFIG_DEVFS_FS
+ unregister_mtd_user(¬ifier);
+ devfs_remove("mtd");
+#endif
unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
}