9
0
Fork 0

drivers/mtd: split mtd mtdoob devices

Split /dev/mtd and /dev/mtdoob devices.
Remove from mtd structure the mtdoob character device.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Robert Jarzmik 2011-12-21 22:30:43 +01:00 committed by Sascha Hauer
parent c6c880ecdb
commit 6473b28065
7 changed files with 105 additions and 73 deletions

View File

@ -8,8 +8,9 @@ config MTD_WRITE
default y
prompt "Support writing to MTD devices"
config MTD_READ_OOB
config MTD_OOB_DEVICE
bool
select NAND_READ_OOB
default y
prompt "Create a device for reading the OOB data"

View File

@ -1,4 +1,5 @@
obj-$(CONFIG_NAND) += nand/
obj-$(CONFIG_UBI) += ubi/
obj-$(CONFIG_PARTITION_NEED_MTD) += partition.o
obj-$(CONFIG_MTD) += core.o
obj-$(CONFIG_MTD) += core.o
obj-$(CONFIG_MTD_OOB_DEVICE) += mtdoob.o

View File

@ -114,7 +114,7 @@ out:
}
#endif
static int mtd_ioctl(struct cdev *cdev, int request, void *buf)
int mtd_ioctl(struct cdev *cdev, int request, void *buf)
{
struct mtd_info *mtd = cdev->priv;
struct mtd_info_user *user = buf;
@ -186,67 +186,6 @@ static struct file_operations mtd_ops = {
.lseek = dev_lseek_default,
};
#ifdef CONFIG_NAND_OOB_DEVICE
static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
ulong offset, ulong flags)
{
struct mtd_info *mtd = cdev->priv;
struct mtd_oob_ops ops;
int ret;
if (count < mtd->oobsize)
return -EINVAL;
ops.mode = MTD_OOB_RAW;
ops.ooboffs = 0;
ops.ooblen = mtd->oobsize;
ops.oobbuf = buf;
ops.datbuf = NULL;
ops.len = mtd->oobsize;
offset /= mtd->oobsize;
ret = mtd->read_oob(mtd, offset * mtd->writesize, &ops);
if (ret)
return ret;
return mtd->oobsize;
}
static struct file_operations mtd_ops_oob = {
.read = mtd_read_oob,
.ioctl = mtd_ioctl,
.lseek = dev_lseek_default,
};
static int mtd_init_oob_cdev(struct mtd_info *mtd, char *devname)
{
mtd->cdev_oob.ops = &mtd_ops_oob;
mtd->cdev_oob.size = (mtd->size / mtd->writesize) * mtd->oobsize;
mtd->cdev_oob.name = asprintf("%s_oob%d", devname, mtd->class_dev.id);
mtd->cdev_oob.priv = mtd;
mtd->cdev_oob.dev = &mtd->class_dev;
devfs_create(&mtd->cdev_oob);
return 0;
}
static void mtd_exit_oob_cdev(struct mtd_info *mtd)
{
free(mtd->cdev_oob.name);
}
#else
static int mtd_init_oob_cdev(struct mtd_info *mtd, char *devname)
{
return 0;
}
static void mtd_exit_oob_cdev(struct mtd_info *mtd)
{
return;
}
#endif
int add_mtd_device(struct mtd_info *mtd, char *devname)
{
char str[16];
@ -276,7 +215,6 @@ int add_mtd_device(struct mtd_info *mtd, char *devname)
devfs_create(&mtd->cdev);
mtd_init_oob_cdev(mtd, devname);
list_for_each_entry(hook, &mtd_register_hooks, hook)
if (hook->add_mtd_device)
hook->add_mtd_device(mtd, devname);
@ -292,7 +230,6 @@ int del_mtd_device (struct mtd_info *mtd)
if (hook->del_mtd_device)
hook->del_mtd_device(mtd);
unregister_device(&mtd->class_dev);
mtd_exit_oob_cdev(mtd);
free(mtd->param_size.value);
free(mtd->cdev.name);
return 0;

View File

@ -28,6 +28,7 @@ struct mtddev_hook {
int (*add_mtd_device)(struct mtd_info *mtd, char *devname);
int (*del_mtd_device)(struct mtd_info *mtd);
};
struct cdev;
/**
* mtdcore_add_hook - add a hook to MTD registration/unregistration
@ -37,3 +38,5 @@ struct mtddev_hook {
* mtdraw, ...)
*/
void mtdcore_add_hook(struct mtddev_hook *hook);
int mtd_ioctl(struct cdev *cdev, int request, void *buf);

97
drivers/mtd/mtdoob.c Normal file
View File

@ -0,0 +1,97 @@
/*
* MTD oob device
*
* Copyright (C) 2011 Sascha Hauer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Adds a character devices :
* - mtdoob<N>
*/
#include <common.h>
#include <init.h>
#include <malloc.h>
#include <ioctl.h>
#include <errno.h>
#include <linux/mtd/mtd.h>
#include "mtd.h"
struct mtdoob {
struct cdev cdev;
struct mtd_info *mtd;
};
static struct mtd_info *to_mtd(struct cdev *cdev)
{
struct mtdoob *mtdoob = cdev->priv;
return mtdoob->mtd;
}
static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
ulong offset, ulong flags)
{
struct mtd_info *mtd = to_mtd(cdev);
struct mtd_oob_ops ops;
int ret;
if (count < mtd->oobsize)
return -EINVAL;
ops.mode = MTD_OOB_RAW;
ops.ooboffs = 0;
ops.ooblen = mtd->oobsize;
ops.oobbuf = buf;
ops.datbuf = NULL;
ops.len = mtd->oobsize;
offset /= mtd->oobsize;
ret = mtd->read_oob(mtd, offset * mtd->writesize, &ops);
if (ret)
return ret;
return mtd->oobsize;
}
static struct file_operations mtd_ops_oob = {
.read = mtd_read_oob,
.ioctl = mtd_ioctl,
.lseek = dev_lseek_default,
};
static int add_mtdoob_device(struct mtd_info *mtd, char *devname)
{
struct mtdoob *mtdoob;
mtdoob = xzalloc(sizeof(*mtdoob));
mtdoob->cdev.ops = &mtd_ops_oob;
mtdoob->cdev.size = (mtd->size / mtd->writesize) * mtd->oobsize;
mtdoob->cdev.name = asprintf("%s_oob%d", devname, mtd->class_dev.id);
mtdoob->cdev.priv = mtdoob;
mtdoob->cdev.dev = &mtd->class_dev;
mtdoob->mtd = mtd;
devfs_create(&mtdoob->cdev);
return 0;
}
static struct mtddev_hook mtdoob_hook = {
.add_mtd_device = add_mtdoob_device,
};
static int __init register_mtdoob(void)
{
mtdcore_add_hook(&mtdoob_hook);
return 0;
}
coredevice_initcall(register_mtdoob);

View File

@ -48,12 +48,6 @@ config NAND_BBT
Say y here to include support for bad block tables. This speeds
up the process of checking for bad blocks
config NAND_OOB_DEVICE
bool
select NAND_READ_OOB
default y
prompt "create a device for reading the OOB data"
config NAND_IMX
bool
prompt "i.MX NAND driver"

View File

@ -202,7 +202,6 @@ struct mtd_info {
struct device_d class_dev;
struct device_d *dev;
struct cdev cdev;
struct cdev cdev_oob;
struct param_d param_size;
char *size_str;