* [PATCH V2 1/8] drivers/mtd: move nand.c into core.c
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 2/8] drivers/mtd: cosmetic changes Robert Jarzmik
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
Move nand core into the global MTD core.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/Makefile | 1 +
drivers/mtd/core.c | 290 +++++++++++++++++++++++++++++++++++++++++++++
drivers/mtd/nand/Makefile | 2 +-
drivers/mtd/nand/nand.c | 290 ---------------------------------------------
4 files changed, 292 insertions(+), 291 deletions(-)
create mode 100644 drivers/mtd/core.c
delete mode 100644 drivers/mtd/nand/nand.c
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 85bed11..80fe386 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_NAND) += nand/
obj-$(CONFIG_UBI) += ubi/
obj-$(CONFIG_PARTITION_NEED_MTD) += partition.o
+obj-$(CONFIG_MTD) += core.o
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
new file mode 100644
index 0000000..6db21d6
--- /dev/null
+++ b/drivers/mtd/core.c
@@ -0,0 +1,290 @@
+/*
+ * (C) Copyright 2005
+ * 2N Telekomunikace, a.s. <www.2n.cz>
+ * Ladislav Michl <michl@2n.cz>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/mtd.h>
+#include <init.h>
+#include <xfuncs.h>
+#include <driver.h>
+#include <malloc.h>
+#include <ioctl.h>
+#include <nand.h>
+#include <errno.h>
+
+static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count, ulong offset, ulong flags)
+{
+ struct mtd_info *info = cdev->priv;
+ size_t retlen;
+ int ret;
+
+ debug("nand_read: 0x%08lx 0x%08x\n", offset, count);
+
+ ret = info->read(info, offset, count, &retlen, buf);
+
+ if(ret) {
+ printf("err %d\n", ret);
+ return ret;
+ }
+ return retlen;
+}
+
+#define NOTALIGNED(x) (x & (info->writesize - 1)) != 0
+
+#ifdef CONFIG_NAND_WRITE
+static int all_ff(const void *buf, int len)
+{
+ int i;
+ const uint8_t *p = buf;
+
+ for (i = 0; i < len; i++)
+ if (p[i] != 0xFF)
+ return 0;
+ return 1;
+}
+
+static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulong offset, ulong flags)
+{
+ struct mtd_info *info = cdev->priv;
+ size_t retlen, now;
+ int ret = 0;
+ void *wrbuf = NULL;
+ size_t count = _count;
+
+ if (NOTALIGNED(offset)) {
+ printf("offset 0x%0lx not page aligned\n", offset);
+ return -EINVAL;
+ }
+
+ debug("write: 0x%08lx 0x%08x\n", offset, count);
+
+ while (count) {
+ now = count > info->writesize ? info->writesize : count;
+
+ if (NOTALIGNED(now)) {
+ debug("not aligned: %d %ld\n", info->writesize, (offset % info->writesize));
+ wrbuf = xmalloc(info->writesize);
+ memset(wrbuf, 0xff, info->writesize);
+ memcpy(wrbuf + (offset % info->writesize), buf, now);
+ if (!all_ff(wrbuf, info->writesize))
+ ret = info->write(info, offset & ~(info->writesize - 1),
+ info->writesize, &retlen, wrbuf);
+ free(wrbuf);
+ } else {
+ if (!all_ff(buf, info->writesize))
+ ret = info->write(info, offset, now, &retlen, buf);
+ debug("offset: 0x%08lx now: 0x%08x retlen: 0x%08x\n", offset, now, retlen);
+ }
+ if (ret)
+ goto out;
+
+ offset += now;
+ count -= now;
+ buf += now;
+ }
+
+out:
+ return ret ? ret : _count;
+}
+#endif
+
+static int nand_ioctl(struct cdev *cdev, int request, void *buf)
+{
+ struct mtd_info *info = cdev->priv;
+ struct mtd_info_user *user = buf;
+
+ switch (request) {
+ case MEMGETBADBLOCK:
+ debug("MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
+ return info->block_isbad(info, (off_t)buf);
+#ifdef CONFIG_NAND_WRITE
+ case MEMSETBADBLOCK:
+ debug("MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
+ return info->block_markbad(info, (off_t)buf);
+#endif
+ case MEMGETINFO:
+ user->type = info->type;
+ user->flags = info->flags;
+ user->size = info->size;
+ user->erasesize = info->erasesize;
+ user->oobsize = info->oobsize;
+ user->mtd = info;
+ /* The below fields are obsolete */
+ user->ecctype = -1;
+ user->eccsize = 0;
+ return 0;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_NAND_WRITE
+static ssize_t nand_erase(struct cdev *cdev, size_t count, unsigned long offset)
+{
+ struct mtd_info *info = cdev->priv;
+ struct erase_info erase;
+ int ret;
+
+ memset(&erase, 0, sizeof(erase));
+ erase.mtd = info;
+ erase.addr = offset;
+ erase.len = info->erasesize;
+
+ while (count > 0) {
+ debug("erase %d %d\n", erase.addr, erase.len);
+
+ ret = info->block_isbad(info, erase.addr);
+ if (ret > 0) {
+ printf("Skipping bad block at 0x%08x\n", erase.addr);
+ } else {
+ ret = info->erase(info, &erase);
+ if (ret)
+ return ret;
+ }
+
+ erase.addr += info->erasesize;
+ count -= count > info->erasesize ? info->erasesize : count;
+ }
+
+ return 0;
+}
+#endif
+
+#if 0
+static char* mtd_get_size(struct device_d *, struct param_d *param)
+{
+ static char
+}
+#endif
+
+static struct file_operations nand_ops = {
+ .read = nand_read,
+#ifdef CONFIG_NAND_WRITE
+ .write = nand_write,
+ .erase = nand_erase,
+#endif
+ .ioctl = nand_ioctl,
+ .lseek = dev_lseek_default,
+};
+
+#ifdef CONFIG_NAND_READ_OOB
+static ssize_t nand_read_oob(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
+{
+ struct mtd_info *info = cdev->priv;
+ struct nand_chip *chip = info->priv;
+ struct mtd_oob_ops ops;
+ int ret;
+
+ if (count < info->oobsize)
+ return -EINVAL;
+
+ ops.mode = MTD_OOB_RAW;
+ ops.ooboffs = 0;
+ ops.ooblen = info->oobsize;
+ ops.oobbuf = buf;
+ ops.datbuf = NULL;
+ ops.len = info->oobsize;
+
+ offset /= info->oobsize;
+ ret = info->read_oob(info, offset << chip->page_shift, &ops);
+ if (ret)
+ return ret;
+
+ return info->oobsize;
+}
+
+static struct file_operations nand_ops_oob = {
+ .read = nand_read_oob,
+ .ioctl = nand_ioctl,
+ .lseek = dev_lseek_default,
+};
+
+static int nand_init_oob_cdev(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ mtd->cdev_oob.ops = &nand_ops_oob;
+ mtd->cdev_oob.size = (mtd->size >> chip->page_shift) * mtd->oobsize;
+ mtd->cdev_oob.name = asprintf("nand_oob%d", 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 nand_exit_oob_cdev(struct mtd_info *mtd)
+{
+ free(mtd->cdev_oob.name);
+}
+#else
+
+static int nand_init_oob_cdev(struct mtd_info *mtd)
+{
+ return 0;
+}
+
+static void nand_exit_oob_cdev(struct mtd_info *mtd)
+{
+ return;
+}
+#endif
+
+int add_mtd_device(struct mtd_info *mtd)
+{
+ char str[16];
+
+ strcpy(mtd->class_dev.name, "nand");
+ register_device(&mtd->class_dev);
+
+ mtd->cdev.ops = &nand_ops;
+ mtd->cdev.size = mtd->size;
+ mtd->cdev.name = asprintf("nand%d", mtd->class_dev.id);
+ mtd->cdev.priv = mtd;
+ mtd->cdev.dev = &mtd->class_dev;
+ mtd->cdev.mtd = mtd;
+
+ sprintf(str, "%u", mtd->size);
+ dev_add_param_fixed(&mtd->class_dev, "size", str);
+ sprintf(str, "%u", mtd->erasesize);
+ dev_add_param_fixed(&mtd->class_dev, "erasesize", str);
+ sprintf(str, "%u", mtd->writesize);
+ dev_add_param_fixed(&mtd->class_dev, "writesize", str);
+ sprintf(str, "%u", mtd->oobsize);
+ dev_add_param_fixed(&mtd->class_dev, "oobsize", str);
+
+ devfs_create(&mtd->cdev);
+
+ nand_init_oob_cdev(mtd);
+
+ return 0;
+}
+
+int del_mtd_device (struct mtd_info *mtd)
+{
+ unregister_device(&mtd->class_dev);
+ nand_exit_oob_cdev(mtd);
+ free(mtd->param_size.value);
+ free(mtd->cdev.name);
+ return 0;
+}
+
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 149cbbf..26b65a7 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -1,6 +1,6 @@
# Generic NAND options
-obj-$(CONFIG_NAND) += nand.o nand_ecc.o
+obj-$(CONFIG_NAND) += nand_ecc.o
obj-$(CONFIG_NAND_WRITE) += nand_write.o
obj-$(CONFIG_NAND_ECC_SOFT) += nand_ecc.o nand_swecc.o
obj-$(CONFIG_NAND_ECC_HW) += nand_hwecc.o
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
deleted file mode 100644
index 6db21d6..0000000
--- a/drivers/mtd/nand/nand.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * (C) Copyright 2005
- * 2N Telekomunikace, a.s. <www.2n.cz>
- * Ladislav Michl <michl@2n.cz>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-#include <common.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/mtd.h>
-#include <init.h>
-#include <xfuncs.h>
-#include <driver.h>
-#include <malloc.h>
-#include <ioctl.h>
-#include <nand.h>
-#include <errno.h>
-
-static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count, ulong offset, ulong flags)
-{
- struct mtd_info *info = cdev->priv;
- size_t retlen;
- int ret;
-
- debug("nand_read: 0x%08lx 0x%08x\n", offset, count);
-
- ret = info->read(info, offset, count, &retlen, buf);
-
- if(ret) {
- printf("err %d\n", ret);
- return ret;
- }
- return retlen;
-}
-
-#define NOTALIGNED(x) (x & (info->writesize - 1)) != 0
-
-#ifdef CONFIG_NAND_WRITE
-static int all_ff(const void *buf, int len)
-{
- int i;
- const uint8_t *p = buf;
-
- for (i = 0; i < len; i++)
- if (p[i] != 0xFF)
- return 0;
- return 1;
-}
-
-static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulong offset, ulong flags)
-{
- struct mtd_info *info = cdev->priv;
- size_t retlen, now;
- int ret = 0;
- void *wrbuf = NULL;
- size_t count = _count;
-
- if (NOTALIGNED(offset)) {
- printf("offset 0x%0lx not page aligned\n", offset);
- return -EINVAL;
- }
-
- debug("write: 0x%08lx 0x%08x\n", offset, count);
-
- while (count) {
- now = count > info->writesize ? info->writesize : count;
-
- if (NOTALIGNED(now)) {
- debug("not aligned: %d %ld\n", info->writesize, (offset % info->writesize));
- wrbuf = xmalloc(info->writesize);
- memset(wrbuf, 0xff, info->writesize);
- memcpy(wrbuf + (offset % info->writesize), buf, now);
- if (!all_ff(wrbuf, info->writesize))
- ret = info->write(info, offset & ~(info->writesize - 1),
- info->writesize, &retlen, wrbuf);
- free(wrbuf);
- } else {
- if (!all_ff(buf, info->writesize))
- ret = info->write(info, offset, now, &retlen, buf);
- debug("offset: 0x%08lx now: 0x%08x retlen: 0x%08x\n", offset, now, retlen);
- }
- if (ret)
- goto out;
-
- offset += now;
- count -= now;
- buf += now;
- }
-
-out:
- return ret ? ret : _count;
-}
-#endif
-
-static int nand_ioctl(struct cdev *cdev, int request, void *buf)
-{
- struct mtd_info *info = cdev->priv;
- struct mtd_info_user *user = buf;
-
- switch (request) {
- case MEMGETBADBLOCK:
- debug("MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
- return info->block_isbad(info, (off_t)buf);
-#ifdef CONFIG_NAND_WRITE
- case MEMSETBADBLOCK:
- debug("MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
- return info->block_markbad(info, (off_t)buf);
-#endif
- case MEMGETINFO:
- user->type = info->type;
- user->flags = info->flags;
- user->size = info->size;
- user->erasesize = info->erasesize;
- user->oobsize = info->oobsize;
- user->mtd = info;
- /* The below fields are obsolete */
- user->ecctype = -1;
- user->eccsize = 0;
- return 0;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_NAND_WRITE
-static ssize_t nand_erase(struct cdev *cdev, size_t count, unsigned long offset)
-{
- struct mtd_info *info = cdev->priv;
- struct erase_info erase;
- int ret;
-
- memset(&erase, 0, sizeof(erase));
- erase.mtd = info;
- erase.addr = offset;
- erase.len = info->erasesize;
-
- while (count > 0) {
- debug("erase %d %d\n", erase.addr, erase.len);
-
- ret = info->block_isbad(info, erase.addr);
- if (ret > 0) {
- printf("Skipping bad block at 0x%08x\n", erase.addr);
- } else {
- ret = info->erase(info, &erase);
- if (ret)
- return ret;
- }
-
- erase.addr += info->erasesize;
- count -= count > info->erasesize ? info->erasesize : count;
- }
-
- return 0;
-}
-#endif
-
-#if 0
-static char* mtd_get_size(struct device_d *, struct param_d *param)
-{
- static char
-}
-#endif
-
-static struct file_operations nand_ops = {
- .read = nand_read,
-#ifdef CONFIG_NAND_WRITE
- .write = nand_write,
- .erase = nand_erase,
-#endif
- .ioctl = nand_ioctl,
- .lseek = dev_lseek_default,
-};
-
-#ifdef CONFIG_NAND_READ_OOB
-static ssize_t nand_read_oob(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
-{
- struct mtd_info *info = cdev->priv;
- struct nand_chip *chip = info->priv;
- struct mtd_oob_ops ops;
- int ret;
-
- if (count < info->oobsize)
- return -EINVAL;
-
- ops.mode = MTD_OOB_RAW;
- ops.ooboffs = 0;
- ops.ooblen = info->oobsize;
- ops.oobbuf = buf;
- ops.datbuf = NULL;
- ops.len = info->oobsize;
-
- offset /= info->oobsize;
- ret = info->read_oob(info, offset << chip->page_shift, &ops);
- if (ret)
- return ret;
-
- return info->oobsize;
-}
-
-static struct file_operations nand_ops_oob = {
- .read = nand_read_oob,
- .ioctl = nand_ioctl,
- .lseek = dev_lseek_default,
-};
-
-static int nand_init_oob_cdev(struct mtd_info *mtd)
-{
- struct nand_chip *chip = mtd->priv;
-
- mtd->cdev_oob.ops = &nand_ops_oob;
- mtd->cdev_oob.size = (mtd->size >> chip->page_shift) * mtd->oobsize;
- mtd->cdev_oob.name = asprintf("nand_oob%d", 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 nand_exit_oob_cdev(struct mtd_info *mtd)
-{
- free(mtd->cdev_oob.name);
-}
-#else
-
-static int nand_init_oob_cdev(struct mtd_info *mtd)
-{
- return 0;
-}
-
-static void nand_exit_oob_cdev(struct mtd_info *mtd)
-{
- return;
-}
-#endif
-
-int add_mtd_device(struct mtd_info *mtd)
-{
- char str[16];
-
- strcpy(mtd->class_dev.name, "nand");
- register_device(&mtd->class_dev);
-
- mtd->cdev.ops = &nand_ops;
- mtd->cdev.size = mtd->size;
- mtd->cdev.name = asprintf("nand%d", mtd->class_dev.id);
- mtd->cdev.priv = mtd;
- mtd->cdev.dev = &mtd->class_dev;
- mtd->cdev.mtd = mtd;
-
- sprintf(str, "%u", mtd->size);
- dev_add_param_fixed(&mtd->class_dev, "size", str);
- sprintf(str, "%u", mtd->erasesize);
- dev_add_param_fixed(&mtd->class_dev, "erasesize", str);
- sprintf(str, "%u", mtd->writesize);
- dev_add_param_fixed(&mtd->class_dev, "writesize", str);
- sprintf(str, "%u", mtd->oobsize);
- dev_add_param_fixed(&mtd->class_dev, "oobsize", str);
-
- devfs_create(&mtd->cdev);
-
- nand_init_oob_cdev(mtd);
-
- return 0;
-}
-
-int del_mtd_device (struct mtd_info *mtd)
-{
- unregister_device(&mtd->class_dev);
- nand_exit_oob_cdev(mtd);
- free(mtd->param_size.value);
- free(mtd->cdev.name);
- return 0;
-}
-
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 2/8] drivers/mtd: cosmetic changes
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 1/8] drivers/mtd: move nand.c into core.c Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core Robert Jarzmik
` (5 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
Fix whitespace, replace all debug() by dev_dbg(), and fix
line length to 80 characters.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/core.c | 47 ++++++++++++++++++++++-------------------------
1 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 6db21d6..3bfcaf4 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -14,11 +14,6 @@
* 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
*/
#include <common.h>
#include <linux/mtd/nand.h>
@@ -31,7 +26,8 @@
#include <nand.h>
#include <errno.h>
-static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count, ulong offset, ulong flags)
+static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count,
+ ulong offset, ulong flags)
{
struct mtd_info *info = cdev->priv;
size_t retlen;
@@ -49,6 +45,7 @@ static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count, ulong offs
}
#define NOTALIGNED(x) (x & (info->writesize - 1)) != 0
+#define MTDPGALG(x) ((x) & (info->writesize - 1))
#ifdef CONFIG_NAND_WRITE
static int all_ff(const void *buf, int len)
@@ -62,7 +59,8 @@ static int all_ff(const void *buf, int len)
return 1;
}
-static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulong offset, ulong flags)
+static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count,
+ ulong offset, ulong flags)
{
struct mtd_info *info = cdev->priv;
size_t retlen, now;
@@ -75,24 +73,29 @@ static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count, ulo
return -EINVAL;
}
- debug("write: 0x%08lx 0x%08x\n", offset, count);
-
+ dev_dbg(cdev->dev, "write: 0x%08lx 0x%08x\n", offset, count);
while (count) {
now = count > info->writesize ? info->writesize : count;
if (NOTALIGNED(now)) {
- debug("not aligned: %d %ld\n", info->writesize, (offset % info->writesize));
+ dev_dbg(cdev->dev, "not aligned: %d %ld\n",
+ info->writesize,
+ (offset % info->writesize));
wrbuf = xmalloc(info->writesize);
memset(wrbuf, 0xff, info->writesize);
memcpy(wrbuf + (offset % info->writesize), buf, now);
if (!all_ff(wrbuf, info->writesize))
- ret = info->write(info, offset & ~(info->writesize - 1),
- info->writesize, &retlen, wrbuf);
+ ret = info->write(info, MTDPGALG(offset),
+ info->writesize, &retlen,
+ wrbuf);
free(wrbuf);
} else {
if (!all_ff(buf, info->writesize))
- ret = info->write(info, offset, now, &retlen, buf);
- debug("offset: 0x%08lx now: 0x%08x retlen: 0x%08x\n", offset, now, retlen);
+ ret = info->write(info, offset, now, &retlen,
+ buf);
+ dev_dbg(cdev->dev,
+ "offset: 0x%08lx now: 0x%08x retlen: 0x%08x\n",
+ offset, now, retlen);
}
if (ret)
goto out;
@@ -114,11 +117,11 @@ static int nand_ioctl(struct cdev *cdev, int request, void *buf)
switch (request) {
case MEMGETBADBLOCK:
- debug("MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
+ dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
return info->block_isbad(info, (off_t)buf);
#ifdef CONFIG_NAND_WRITE
case MEMSETBADBLOCK:
- debug("MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
+ dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
return info->block_markbad(info, (off_t)buf);
#endif
case MEMGETINFO:
@@ -150,7 +153,7 @@ static ssize_t nand_erase(struct cdev *cdev, size_t count, unsigned long offset)
erase.len = info->erasesize;
while (count > 0) {
- debug("erase %d %d\n", erase.addr, erase.len);
+ dev_dbg(cdev->dev, "erase %d %d\n", erase.addr, erase.len);
ret = info->block_isbad(info, erase.addr);
if (ret > 0) {
@@ -169,13 +172,6 @@ static ssize_t nand_erase(struct cdev *cdev, size_t count, unsigned long offset)
}
#endif
-#if 0
-static char* mtd_get_size(struct device_d *, struct param_d *param)
-{
- static char
-}
-#endif
-
static struct file_operations nand_ops = {
.read = nand_read,
#ifdef CONFIG_NAND_WRITE
@@ -187,7 +183,8 @@ static struct file_operations nand_ops = {
};
#ifdef CONFIG_NAND_READ_OOB
-static ssize_t nand_read_oob(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
+static ssize_t nand_read_oob(struct cdev *cdev, void *buf, size_t count,
+ ulong offset, ulong flags)
{
struct mtd_info *info = cdev->priv;
struct nand_chip *chip = info->priv;
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 1/8] drivers/mtd: move nand.c into core.c Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 2/8] drivers/mtd: cosmetic changes Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-19 9:49 ` Sascha Hauer
2011-12-16 21:50 ` [PATCH V2 4/8] drivers/mtd: recover NAND default device name "nand" Robert Jarzmik
` (4 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
Change NAND_WRITE into MTD_WRITE.
Change "page_shift" references in the core, which are purely
NAND, into mtd->writesize which is MTD generic.
Rename all "info" (struct mtd_info) into "mtd".
Beware, bisection is broken here as driver name changes from
/dev/nand<N> into /dev/mtd<N>.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/Kconfig | 10 ++
drivers/mtd/core.c | 149 ++++++++++++++++----------------
drivers/mtd/nand/Kconfig | 10 --
drivers/mtd/nand/Makefile | 2 +-
drivers/mtd/nand/nand-bb.c | 6 +-
drivers/mtd/nand/nand_base.c | 14 ++--
drivers/mtd/nand/nand_bbt.c | 2 +-
drivers/mtd/nand/nand_hwecc.c | 4 +-
drivers/mtd/nand/nand_hwecc_syndrome.c | 6 +-
drivers/mtd/nand/nand_swecc.c | 4 +-
10 files changed, 104 insertions(+), 103 deletions(-)
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 562f0cd..81282ab 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -3,6 +3,16 @@ menuconfig MTD
if MTD
+config MTD_WRITE
+ bool
+ default y
+ prompt "Support writing to MTD devices"
+
+config MTD_READ_OOB
+ bool
+ default y
+ prompt "Create a device for reading the OOB data"
+
source "drivers/mtd/nand/Kconfig"
source "drivers/mtd/ubi/Kconfig"
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 3bfcaf4..cea5231 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -26,16 +26,16 @@
#include <nand.h>
#include <errno.h>
-static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count,
+static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count,
ulong offset, ulong flags)
{
- struct mtd_info *info = cdev->priv;
+ struct mtd_info *mtd = cdev->priv;
size_t retlen;
int ret;
- debug("nand_read: 0x%08lx 0x%08x\n", offset, count);
+ debug("mtd_read: 0x%08lx 0x%08x\n", offset, count);
- ret = info->read(info, offset, count, &retlen, buf);
+ ret = mtd->read(mtd, offset, count, &retlen, buf);
if(ret) {
printf("err %d\n", ret);
@@ -44,10 +44,10 @@ static ssize_t nand_read(struct cdev *cdev, void* buf, size_t count,
return retlen;
}
-#define NOTALIGNED(x) (x & (info->writesize - 1)) != 0
-#define MTDPGALG(x) ((x) & (info->writesize - 1))
+#define NOTALIGNED(x) (x & (mtd->writesize - 1)) != 0
+#define MTDPGALG(x) ((x) & (mtd->writesize - 1))
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static int all_ff(const void *buf, int len)
{
int i;
@@ -59,10 +59,10 @@ static int all_ff(const void *buf, int len)
return 1;
}
-static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count,
+static ssize_t mtd_write(struct cdev* cdev, const void *buf, size_t _count,
ulong offset, ulong flags)
{
- struct mtd_info *info = cdev->priv;
+ struct mtd_info *mtd = cdev->priv;
size_t retlen, now;
int ret = 0;
void *wrbuf = NULL;
@@ -75,23 +75,23 @@ static ssize_t nand_write(struct cdev* cdev, const void *buf, size_t _count,
dev_dbg(cdev->dev, "write: 0x%08lx 0x%08x\n", offset, count);
while (count) {
- now = count > info->writesize ? info->writesize : count;
+ now = count > mtd->writesize ? mtd->writesize : count;
if (NOTALIGNED(now)) {
dev_dbg(cdev->dev, "not aligned: %d %ld\n",
- info->writesize,
- (offset % info->writesize));
- wrbuf = xmalloc(info->writesize);
- memset(wrbuf, 0xff, info->writesize);
- memcpy(wrbuf + (offset % info->writesize), buf, now);
- if (!all_ff(wrbuf, info->writesize))
- ret = info->write(info, MTDPGALG(offset),
- info->writesize, &retlen,
+ mtd->writesize,
+ (offset % mtd->writesize));
+ wrbuf = xmalloc(mtd->writesize);
+ memset(wrbuf, 0xff, mtd->writesize);
+ memcpy(wrbuf + (offset % mtd->writesize), buf, now);
+ if (!all_ff(wrbuf, mtd->writesize))
+ ret = mtd->write(mtd, MTDPGALG(offset),
+ mtd->writesize, &retlen,
wrbuf);
free(wrbuf);
} else {
- if (!all_ff(buf, info->writesize))
- ret = info->write(info, offset, now, &retlen,
+ if (!all_ff(buf, mtd->writesize))
+ ret = mtd->write(mtd, offset, now, &retlen,
buf);
dev_dbg(cdev->dev,
"offset: 0x%08lx now: 0x%08x retlen: 0x%08x\n",
@@ -110,27 +110,27 @@ out:
}
#endif
-static int nand_ioctl(struct cdev *cdev, int request, void *buf)
+static int mtd_ioctl(struct cdev *cdev, int request, void *buf)
{
- struct mtd_info *info = cdev->priv;
+ struct mtd_info *mtd = cdev->priv;
struct mtd_info_user *user = buf;
switch (request) {
case MEMGETBADBLOCK:
dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
- return info->block_isbad(info, (off_t)buf);
-#ifdef CONFIG_NAND_WRITE
+ return mtd->block_isbad(mtd, (off_t)buf);
+#ifdef CONFIG_MTD_WRITE
case MEMSETBADBLOCK:
dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
- return info->block_markbad(info, (off_t)buf);
+ return mtd->block_markbad(mtd, (off_t)buf);
#endif
case MEMGETINFO:
- user->type = info->type;
- user->flags = info->flags;
- user->size = info->size;
- user->erasesize = info->erasesize;
- user->oobsize = info->oobsize;
- user->mtd = info;
+ user->type = mtd->type;
+ user->flags = mtd->flags;
+ user->size = mtd->size;
+ user->erasesize = mtd->erasesize;
+ user->oobsize = mtd->oobsize;
+ user->mtd = mtd;
/* The below fields are obsolete */
user->ecctype = -1;
user->eccsize = 0;
@@ -140,88 +140,89 @@ static int nand_ioctl(struct cdev *cdev, int request, void *buf)
return 0;
}
-#ifdef CONFIG_NAND_WRITE
-static ssize_t nand_erase(struct cdev *cdev, size_t count, unsigned long offset)
+#ifdef CONFIG_MTD_WRITE
+static ssize_t mtd_erase(struct cdev *cdev, size_t count, unsigned long offset)
{
- struct mtd_info *info = cdev->priv;
+ struct mtd_info *mtd = cdev->priv;
struct erase_info erase;
int ret;
memset(&erase, 0, sizeof(erase));
- erase.mtd = info;
+ erase.mtd = mtd;
erase.addr = offset;
- erase.len = info->erasesize;
+ erase.len = mtd->erasesize;
while (count > 0) {
dev_dbg(cdev->dev, "erase %d %d\n", erase.addr, erase.len);
- ret = info->block_isbad(info, erase.addr);
+ ret = mtd->block_isbad(mtd, erase.addr);
if (ret > 0) {
printf("Skipping bad block at 0x%08x\n", erase.addr);
} else {
- ret = info->erase(info, &erase);
+ ret = mtd->erase(mtd, &erase);
if (ret)
return ret;
}
- erase.addr += info->erasesize;
- count -= count > info->erasesize ? info->erasesize : count;
+ erase.addr += mtd->erasesize;
+ count -= count > mtd->erasesize ? mtd->erasesize : count;
}
return 0;
}
#endif
-static struct file_operations nand_ops = {
- .read = nand_read,
-#ifdef CONFIG_NAND_WRITE
- .write = nand_write,
- .erase = nand_erase,
+static struct file_operations mtd_ops = {
+ .read = mtd_read,
+#ifdef CONFIG_MTD_WRITE
+ .write = mtd_write,
+ .erase = mtd_erase,
#endif
- .ioctl = nand_ioctl,
+ .ioctl = mtd_ioctl,
.lseek = dev_lseek_default,
};
-#ifdef CONFIG_NAND_READ_OOB
-static ssize_t nand_read_oob(struct cdev *cdev, void *buf, size_t count,
+#ifdef CONFIG_MTD_READ_OOB
+static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
ulong offset, ulong flags)
{
- struct mtd_info *info = cdev->priv;
- struct nand_chip *chip = info->priv;
+ struct mtd_info *mtd = cdev->priv;
struct mtd_oob_ops ops;
int ret;
- if (count < info->oobsize)
+ if (count < mtd->oobsize)
return -EINVAL;
ops.mode = MTD_OOB_RAW;
ops.ooboffs = 0;
- ops.ooblen = info->oobsize;
+ ops.ooblen = mtd->oobsize;
ops.oobbuf = buf;
ops.datbuf = NULL;
- ops.len = info->oobsize;
-
- offset /= info->oobsize;
- ret = info->read_oob(info, offset << chip->page_shift, &ops);
+ ops.len = mtd->oobsize;
+
+ offset /= mtd->oobsize;
+ /*
+ * This seems suspicious, shouldn't it be :
+ * offset / mtd->oobsize * mtd->writesize
+ */
+ ret = mtd->read_oob(mtd, offset * mtd->writesize, &ops);
if (ret)
return ret;
- return info->oobsize;
+ return mtd->oobsize;
}
-static struct file_operations nand_ops_oob = {
- .read = nand_read_oob,
- .ioctl = nand_ioctl,
+static struct file_operations mtd_ops_oob = {
+ .read = mtd_read_oob,
+ .ioctl = mtd_ioctl,
.lseek = dev_lseek_default,
};
-static int nand_init_oob_cdev(struct mtd_info *mtd)
+static int mtd_init_oob_cdev(struct mtd_info *mtd)
{
- struct nand_chip *chip = mtd->priv;
-
- mtd->cdev_oob.ops = &nand_ops_oob;
- mtd->cdev_oob.size = (mtd->size >> chip->page_shift) * mtd->oobsize;
- mtd->cdev_oob.name = asprintf("nand_oob%d", mtd->class_dev.id);
+ mtd->cdev_oob.ops = &mtd_ops_oob;
+ mtd->cdev_oob.size = (mtd->size / mtd->writesize) * mtd->oobsize;
+ mtd->cdev_oob.name = asprintf("mtd_oob%d", mtd->class_dev.id);
mtd->cdev_oob.priv = mtd;
mtd->cdev_oob.dev = &mtd->class_dev;
devfs_create(&mtd->cdev_oob);
@@ -229,18 +230,18 @@ static int nand_init_oob_cdev(struct mtd_info *mtd)
return 0;
}
-static void nand_exit_oob_cdev(struct mtd_info *mtd)
+static void mtd_exit_oob_cdev(struct mtd_info *mtd)
{
free(mtd->cdev_oob.name);
}
#else
-static int nand_init_oob_cdev(struct mtd_info *mtd)
+static int mtd_init_oob_cdev(struct mtd_info *mtd)
{
return 0;
}
-static void nand_exit_oob_cdev(struct mtd_info *mtd)
+static void mtd_exit_oob_cdev(struct mtd_info *mtd)
{
return;
}
@@ -250,12 +251,12 @@ int add_mtd_device(struct mtd_info *mtd)
{
char str[16];
- strcpy(mtd->class_dev.name, "nand");
+ strcpy(mtd->class_dev.name, "mtd");
register_device(&mtd->class_dev);
- mtd->cdev.ops = &nand_ops;
+ mtd->cdev.ops = &mtd_ops;
mtd->cdev.size = mtd->size;
- mtd->cdev.name = asprintf("nand%d", mtd->class_dev.id);
+ mtd->cdev.name = asprintf("mtd%d", mtd->class_dev.id);
mtd->cdev.priv = mtd;
mtd->cdev.dev = &mtd->class_dev;
mtd->cdev.mtd = mtd;
@@ -271,7 +272,7 @@ int add_mtd_device(struct mtd_info *mtd)
devfs_create(&mtd->cdev);
- nand_init_oob_cdev(mtd);
+ mtd_init_oob_cdev(mtd);
return 0;
}
@@ -279,7 +280,7 @@ int add_mtd_device(struct mtd_info *mtd)
int del_mtd_device (struct mtd_info *mtd)
{
unregister_device(&mtd->class_dev);
- nand_exit_oob_cdev(mtd);
+ mtd_exit_oob_cdev(mtd);
free(mtd->param_size.value);
free(mtd->cdev.name);
return 0;
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 20f9f33..43fa620 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -8,11 +8,6 @@ menuconfig NAND
if NAND
-config NAND_WRITE
- bool
- default y
- prompt "Support writing to Nand"
-
config NAND_ECC_SOFT
bool
default y
@@ -49,11 +44,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_READ_OOB
- bool
- default y
- prompt "create a device for reading the OOB data"
-
config NAND_IMX
bool
prompt "i.MX NAND driver"
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 26b65a7..00b7b27 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -1,7 +1,7 @@
# Generic NAND options
obj-$(CONFIG_NAND) += nand_ecc.o
-obj-$(CONFIG_NAND_WRITE) += nand_write.o
+obj-$(CONFIG_MTD_WRITE) += nand_write.o
obj-$(CONFIG_NAND_ECC_SOFT) += nand_ecc.o nand_swecc.o
obj-$(CONFIG_NAND_ECC_HW) += nand_hwecc.o
obj-$(CONFIG_NAND_ECC_HW_SYNDROME) += nand_hwecc_syndrome.o
diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
index dbfb8e3..dab0f38 100644
--- a/drivers/mtd/nand/nand-bb.c
+++ b/drivers/mtd/nand/nand-bb.c
@@ -89,7 +89,7 @@ static ssize_t nand_bb_read(struct cdev *cdev, void *buf, size_t count,
/* Must be a multiple of the largest NAND page size */
#define BB_WRITEBUF_SIZE 4096
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static int nand_bb_write_buf(struct nand_bb *bb, size_t count)
{
int ret, now;
@@ -183,7 +183,7 @@ static int nand_bb_close(struct cdev *cdev)
{
struct nand_bb *bb = cdev->priv;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
if (bb->needs_write)
nand_bb_write_buf(bb, bb->offset % BB_WRITEBUF_SIZE);
#endif
@@ -215,7 +215,7 @@ static struct file_operations nand_bb_ops = {
.open = nand_bb_open,
.close = nand_bb_close,
.read = nand_bb_read,
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
.write = nand_bb_write,
.erase = nand_bb_erase,
#endif
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ec0f4a3..c4eca0d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1006,7 +1006,7 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
chip->read_word = nand_read_word;
if (!chip->block_bad)
chip->block_bad = nand_block_bad;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
if (!chip->block_markbad)
chip->block_markbad = nand_default_block_markbad;
if (!chip->write_buf)
@@ -1168,7 +1168,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
/* Check for AND chips with 4 page planes */
if (chip->options & NAND_4PAGE_ARRAY)
chip->erase_cmd = multi_erase_cmd;
@@ -1297,7 +1297,7 @@ int nand_scan_tail(struct mtd_info *mtd)
}
}
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
if (!chip->write_page)
chip->write_page = nand_write_page;
#endif
@@ -1308,7 +1308,7 @@ int nand_scan_tail(struct mtd_info *mtd)
*/
if (!chip->ecc.read_page_raw)
chip->ecc.read_page_raw = nand_read_page_raw;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
if (!chip->ecc.write_page_raw)
chip->ecc.write_page_raw = nand_write_page_raw;
#endif
@@ -1335,7 +1335,7 @@ int nand_scan_tail(struct mtd_info *mtd)
printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
"This is not recommended !!\n");
chip->ecc.read_page = nand_read_page_raw;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
chip->ecc.write_page = nand_write_page_raw;
chip->ecc.write_oob = nand_write_oob_std;
#endif
@@ -1401,7 +1401,7 @@ int nand_scan_tail(struct mtd_info *mtd)
/* Fill in remaining MTD driver data */
mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
mtd->erase = nand_erase;
mtd->write = nand_write;
mtd->write_oob = nand_write_oob;
@@ -1413,7 +1413,7 @@ int nand_scan_tail(struct mtd_info *mtd)
mtd->lock = NULL;
mtd->unlock = NULL;
mtd->block_isbad = nand_block_isbad;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
mtd->block_markbad = nand_block_markbad;
#endif
/* propagate ecc.layout to mtd_info */
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index bf3a7db..c1696ee 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -557,7 +557,7 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt
* (Re)write the bad block table
*
*/
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md,
int chipsel)
diff --git a/drivers/mtd/nand/nand_hwecc.c b/drivers/mtd/nand/nand_hwecc.c
index 5ead49c..a48efa1 100644
--- a/drivers/mtd/nand/nand_hwecc.c
+++ b/drivers/mtd/nand/nand_hwecc.c
@@ -61,7 +61,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
* @chip: nand chip info structure
* @buf: data buffer
*/
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
{
@@ -94,7 +94,7 @@ void nand_init_ecc_hw(struct nand_chip *chip)
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_std;
#endif
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
if (!chip->ecc.write_oob)
chip->ecc.write_oob = nand_write_oob_std;
if (!chip->ecc.write_page)
diff --git a/drivers/mtd/nand/nand_hwecc_syndrome.c b/drivers/mtd/nand/nand_hwecc_syndrome.c
index dd067c9..1493b88 100644
--- a/drivers/mtd/nand/nand_hwecc_syndrome.c
+++ b/drivers/mtd/nand/nand_hwecc_syndrome.c
@@ -72,7 +72,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
* The hw generator calculates the error syndrome automatically. Therefor
* we need a special oob layout and handling.
*/
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static void nand_write_page_syndrome(struct mtd_info *mtd,
struct nand_chip *chip, const uint8_t *buf)
{
@@ -155,7 +155,7 @@ static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
* @chip: nand chip info structure
* @page: page number to write
*/
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static int nand_write_oob_syndrome(struct mtd_info *mtd,
struct nand_chip *chip, int page)
{
@@ -216,7 +216,7 @@ void nand_init_ecc_hw_syndrome(struct nand_chip *chip)
chip->ecc.read_page = nand_read_page_syndrome;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_syndrome;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_syndrome;
if (!chip->ecc.write_oob)
diff --git a/drivers/mtd/nand/nand_swecc.c b/drivers/mtd/nand/nand_swecc.c
index a5edffa..95dfbd8 100644
--- a/drivers/mtd/nand/nand_swecc.c
+++ b/drivers/mtd/nand/nand_swecc.c
@@ -57,7 +57,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
* @chip: nand chip info structure
* @buf: data buffer
*/
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
{
@@ -85,7 +85,7 @@ void nand_init_ecc_soft(struct nand_chip *chip)
chip->ecc.correct = nand_correct_data;
chip->ecc.read_page = nand_read_page_swecc;
chip->ecc.read_oob = nand_read_oob_std;
-#ifdef CONFIG_NAND_WRITE
+#ifdef CONFIG_MTD_WRITE
chip->ecc.write_page = nand_write_page_swecc;
chip->ecc.write_oob = nand_write_oob_std;
#endif
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core
2011-12-16 21:50 ` [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core Robert Jarzmik
@ 2011-12-19 9:49 ` Sascha Hauer
2011-12-19 10:48 ` Robert Jarzmik
0 siblings, 1 reply; 14+ messages in thread
From: Sascha Hauer @ 2011-12-19 9:49 UTC (permalink / raw)
To: Robert Jarzmik; +Cc: barebox
On Fri, Dec 16, 2011 at 10:50:29PM +0100, Robert Jarzmik wrote:
>
> if MTD
>
> +config MTD_WRITE
> + bool
> + default y
> + prompt "Support writing to MTD devices"
> +
> +config MTD_READ_OOB
> + bool
> + default y
> + prompt "Create a device for reading the OOB data"
> +
This one is a rename...
>
> -config NAND_READ_OOB
> - bool
> - default y
> - prompt "create a device for reading the OOB data"
> -
from this one, but not all references to it were renamed.
This revealed a bug which was present before this patch. The following
fixes this, see the commit log for more details. Can you rebase your
series on this patch?
Otherwise your series seems to work properly.
Sascha
8<--------------------------------------------------
mtd nand: fix oob compile time option
The NAND_READ_OOB Kconfig option is used to
a) creating a cdev for reading OOB data
b) compiling in mtd->read_oob support
The former was intended and that's also what the Kconfig help
says. The latter though was implicit and wrong. mtd->read_oob
is also used by the bbt code which resulted in a NULL pointer
deref when compiled with BBT but without NAND_READ_OOB.
To fix this, split the option into two. The now invisible
option NAND_OOB_DEVICE is only responsible for b) and gets
selected when necessary.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/Kconfig | 7 ++++++-
drivers/mtd/nand/nand.c | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 20f9f33..1cc29a8 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -41,16 +41,21 @@ config NAND_INFO
Show informational strings about the vendor and nand flash type
during startup
+config NAND_READ_OOB
+ bool
+
config NAND_BBT
bool
+ select NAND_READ_OOB
default y
prompt "support bad block tables"
help
Say y here to include support for bad block tables. This speeds
up the process of checking for bad blocks
-config NAND_READ_OOB
+config NAND_OOB_DEVICE
bool
+ select NAND_READ_OOB
default y
prompt "create a device for reading the OOB data"
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index 6db21d6..130e2af 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -186,7 +186,7 @@ static struct file_operations nand_ops = {
.lseek = dev_lseek_default,
};
-#ifdef CONFIG_NAND_READ_OOB
+#ifdef CONFIG_NAND_OOB_DEVICE
static ssize_t nand_read_oob(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
{
struct mtd_info *info = cdev->priv;
--
1.7.7.3
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core
2011-12-19 9:49 ` Sascha Hauer
@ 2011-12-19 10:48 ` Robert Jarzmik
2011-12-19 11:08 ` Sascha Hauer
0 siblings, 1 reply; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-19 10:48 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Sascha Hauer <s.hauer@pengutronix.de> writes:
> On Fri, Dec 16, 2011 at 10:50:29PM +0100, Robert Jarzmik wrote:
>
>>
>> if MTD
>>
>> +config MTD_WRITE
>> + bool
>> + default y
>> + prompt "Support writing to MTD devices"
>> +
>> +config MTD_READ_OOB
>> + bool
>> + default y
>> + prompt "Create a device for reading the OOB data"
>> +
>
> This one is a rename...
>
>>
>> -config NAND_READ_OOB
>> - bool
>> - default y
>> - prompt "create a device for reading the OOB data"
>> -
>
> from this one, but not all references to it were renamed.
Arg. I see it now. I'll amend this patch.
> This revealed a bug which was present before this patch. The following
> fixes this, see the commit log for more details. Can you rebase your
> series on this patch?
Of course.
> Otherwise your series seems to work properly.
Ok, great. Do you want me to resend the whole serie, or provide you a pull
request with this patchset rebased on barebox.git/next, and your patch, and then
this serie ?
FWIW, I checked erase/read/write on mtdraw and mtd, and with the docg3
everything works fine. If I understand correctly, you tested with a NAND you've
got, which is great as a non-regression test :)
Cheers.
--
Robert
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core
2011-12-19 10:48 ` Robert Jarzmik
@ 2011-12-19 11:08 ` Sascha Hauer
0 siblings, 0 replies; 14+ messages in thread
From: Sascha Hauer @ 2011-12-19 11:08 UTC (permalink / raw)
To: Robert Jarzmik; +Cc: barebox
On Mon, Dec 19, 2011 at 11:48:49AM +0100, Robert Jarzmik wrote:
> Sascha Hauer <s.hauer@pengutronix.de> writes:
>
> > On Fri, Dec 16, 2011 at 10:50:29PM +0100, Robert Jarzmik wrote:
> >
> >>
> >> if MTD
> >>
> >> +config MTD_WRITE
> >> + bool
> >> + default y
> >> + prompt "Support writing to MTD devices"
> >> +
> >> +config MTD_READ_OOB
> >> + bool
> >> + default y
> >> + prompt "Create a device for reading the OOB data"
> >> +
> >
> > This one is a rename...
> >
> >>
> >> -config NAND_READ_OOB
> >> - bool
> >> - default y
> >> - prompt "create a device for reading the OOB data"
> >> -
> >
> > from this one, but not all references to it were renamed.
> Arg. I see it now. I'll amend this patch.
>
> > This revealed a bug which was present before this patch. The following
> > fixes this, see the commit log for more details. Can you rebase your
> > series on this patch?
> Of course.
>
> > Otherwise your series seems to work properly.
> Ok, great. Do you want me to resend the whole serie, or provide you a pull
> request with this patchset rebased on barebox.git/next, and your patch, and then
> this serie ?
I just applied the fix to -master and merged master into -next. Please
just rebase your series on top of this and resend.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 4/8] drivers/mtd: recover NAND default device name "nand"
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
` (2 preceding siblings ...)
2011-12-16 21:50 ` [PATCH V2 3/8] drivers/mtd: transfer NAND notions to MTD core Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 5/8] drivers/mtd: fix core multiple MTD registrations Robert Jarzmik
` (3 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
As the previous commit changed the generic MTD device name
created from nand<N> into mtd<N>, provide a parameter to
add_mtd_device() so that legacy nand devices still appear as
nand<N>, and repair existing environements.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/core.c | 16 +++++++++-------
drivers/mtd/nand/atmel_nand.c | 2 +-
drivers/mtd/nand/diskonchip.c | 2 +-
drivers/mtd/nand/nand_imx.c | 2 +-
drivers/mtd/nand/nand_omap_gpmc.c | 2 +-
drivers/mtd/nand/nand_s3c2410.c | 2 +-
drivers/mtd/nand/nomadik_nand.c | 2 +-
include/linux/mtd/mtd.h | 2 +-
8 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index cea5231..9029474 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -218,11 +218,11 @@ static struct file_operations mtd_ops_oob = {
.lseek = dev_lseek_default,
};
-static int mtd_init_oob_cdev(struct mtd_info *mtd)
+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("mtd_oob%d", mtd->class_dev.id);
+ 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);
@@ -236,7 +236,7 @@ static void mtd_exit_oob_cdev(struct mtd_info *mtd)
}
#else
-static int mtd_init_oob_cdev(struct mtd_info *mtd)
+static int mtd_init_oob_cdev(struct mtd_info *mtd, char *devname)
{
return 0;
}
@@ -247,16 +247,18 @@ static void mtd_exit_oob_cdev(struct mtd_info *mtd)
}
#endif
-int add_mtd_device(struct mtd_info *mtd)
+int add_mtd_device(struct mtd_info *mtd, char *devname)
{
char str[16];
- strcpy(mtd->class_dev.name, "mtd");
+ if (!devname)
+ devname = "mtd";
+ strcpy(mtd->class_dev.name, devname);
register_device(&mtd->class_dev);
mtd->cdev.ops = &mtd_ops;
mtd->cdev.size = mtd->size;
- mtd->cdev.name = asprintf("mtd%d", mtd->class_dev.id);
+ mtd->cdev.name = asprintf("%s%d", devname, mtd->class_dev.id);
mtd->cdev.priv = mtd;
mtd->cdev.dev = &mtd->class_dev;
mtd->cdev.mtd = mtd;
@@ -272,7 +274,7 @@ int add_mtd_device(struct mtd_info *mtd)
devfs_create(&mtd->cdev);
- mtd_init_oob_cdev(mtd);
+ mtd_init_oob_cdev(mtd, devname);
return 0;
}
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 8cc1b51..534a065 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -485,7 +485,7 @@ static int __init atmel_nand_probe(struct device_d *dev)
goto err_scan_tail;
}
- add_mtd_device(mtd);
+ add_mtd_device(mtd, "nand");
if (!res)
return res;
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 2433945..8323575 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1358,7 +1358,7 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd)
At least as nand_bbt.c is currently written. */
if ((ret = nand_scan_bbt(mtd, NULL)))
return ret;
- add_mtd_device(mtd);
+ add_mtd_device(mtd, "nand");
#ifdef CONFIG_MTD_PARTITIONS
if (!no_autopart)
add_mtd_partitions(mtd, parts, numparts);
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index c8c69d6..85cfbed 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -1176,7 +1176,7 @@ static int __init imxnd_probe(struct device_d *dev)
goto escan;
}
- add_mtd_device(mtd);
+ add_mtd_device(mtd, "nand");
dev->priv = host;
diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index d5e642a..9fb1132 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -956,7 +956,7 @@ static int gpmc_nand_probe(struct device_d *pdev)
dev_set_param(pdev, "eccmode", ecc_mode_strings[pdata->ecc_mode]);
/* We are all set to register with the system now! */
- err = add_mtd_device(minfo);
+ err = add_mtd_device(minfo, "nand");
if (err) {
dev_dbg(pdev, "device registration failed\n");
goto out_release_mem;
diff --git a/drivers/mtd/nand/nand_s3c2410.c b/drivers/mtd/nand/nand_s3c2410.c
index c5f5d97..ed45788 100644
--- a/drivers/mtd/nand/nand_s3c2410.c
+++ b/drivers/mtd/nand/nand_s3c2410.c
@@ -485,7 +485,7 @@ static int s3c24x0_nand_probe(struct device_d *dev)
goto on_error;
}
- return add_mtd_device(mtd);
+ return add_mtd_device(mtd, "nand");
on_error:
free(host);
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c
index c1e93ad..05d61c2 100644
--- a/drivers/mtd/nand/nomadik_nand.c
+++ b/drivers/mtd/nand/nomadik_nand.c
@@ -220,7 +220,7 @@ static int nomadik_nand_probe(struct device_d *dev)
}
pr_info("Registering %s as whole device\n", mtd->name);
- add_mtd_device(mtd);
+ add_mtd_device(mtd, "nand");
return 0;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 29591e2..a985c30 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -220,7 +220,7 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
}
/* Kernel-side ioctl definitions */
-extern int add_mtd_device(struct mtd_info *mtd);
+extern int add_mtd_device(struct mtd_info *mtd, char *devname);
extern int del_mtd_device (struct mtd_info *mtd);
extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 5/8] drivers/mtd: fix core multiple MTD registrations
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
` (3 preceding siblings ...)
2011-12-16 21:50 ` [PATCH V2 4/8] drivers/mtd: recover NAND default device name "nand" Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 6/8] drivers/mtd: add mtd core hooks Robert Jarzmik
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
If multiple MTD devices were registered, an exception
occured, as they all wanted id 0. Let the driver code choose
the device number dynamically.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/core.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 9029474..49a2dfa 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -254,6 +254,7 @@ int add_mtd_device(struct mtd_info *mtd, char *devname)
if (!devname)
devname = "mtd";
strcpy(mtd->class_dev.name, devname);
+ mtd->class_dev.id = -1;
register_device(&mtd->class_dev);
mtd->cdev.ops = &mtd_ops;
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 6/8] drivers/mtd: add mtd core hooks
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
` (4 preceding siblings ...)
2011-12-16 21:50 ` [PATCH V2 5/8] drivers/mtd: fix core multiple MTD registrations Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 7/8] mtd/drivers: split mtd mtdoob devices Robert Jarzmik
2011-12-16 21:50 ` [PATCH V2 8/8] drivers/mtd: add the mtdraw device (data+oob) Robert Jarzmik
7 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
Add hooks for spinoff MTD drivers (mtdoob, mtdraw, ...).
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/core.c | 17 +++++++++++++++++
drivers/mtd/mtd.h | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)
create mode 100644 drivers/mtd/mtd.h
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 49a2dfa..55fe575 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -26,6 +26,10 @@
#include <nand.h>
#include <errno.h>
+#include "mtd.h"
+
+static LIST_HEAD(mtd_register_hooks);
+
static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count,
ulong offset, ulong flags)
{
@@ -250,6 +254,7 @@ static void mtd_exit_oob_cdev(struct mtd_info *mtd)
int add_mtd_device(struct mtd_info *mtd, char *devname)
{
char str[16];
+ struct mtddev_hook *hook;
if (!devname)
devname = "mtd";
@@ -276,12 +281,20 @@ 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);
return 0;
}
int del_mtd_device (struct mtd_info *mtd)
{
+ struct mtddev_hook *hook;
+
+ list_for_each_entry(hook, &mtd_register_hooks, hook)
+ 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);
@@ -289,3 +302,7 @@ int del_mtd_device (struct mtd_info *mtd)
return 0;
}
+void mtdcore_add_hook(struct mtddev_hook *hook)
+{
+ list_add(&hook->hook, &mtd_register_hooks);
+}
diff --git a/drivers/mtd/mtd.h b/drivers/mtd/mtd.h
new file mode 100644
index 0000000..261cd2b
--- /dev/null
+++ b/drivers/mtd/mtd.h
@@ -0,0 +1,39 @@
+/*
+ * MTD devices registration
+ *
+ * Copyright (C) 2011 Robert Jarzmik
+ *
+ * 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.
+ *
+ */
+
+/**
+ * mtddev_hook - hook to register additional mtd devices
+ * @add_mtd_device: called when a MTD driver calls add_mtd_device()
+ * @del_mtd_device: called when a MTD driver calls del_mtd_device()
+ *
+ * Provide a hook to be called whenether a add_mtd_device() is called.
+ * Additionnal devices like mtdoob and mtdraw subscribe to the service.
+ */
+struct mtddev_hook {
+ struct list_head hook;
+ int (*add_mtd_device)(struct mtd_info *mtd, char *devname);
+ int (*del_mtd_device)(struct mtd_info *mtd);
+};
+
+/**
+ * mtdcore_add_hook - add a hook to MTD registration/unregistration
+ * @hook: the hook
+ *
+ * Normally called in a coredevice_initcall() to add another MTD layout (such as
+ * mtdraw, ...)
+ */
+void mtdcore_add_hook(struct mtddev_hook *hook);
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 7/8] mtd/drivers: split mtd mtdoob devices
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
` (5 preceding siblings ...)
2011-12-16 21:50 ` [PATCH V2 6/8] drivers/mtd: add mtd core hooks Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
2011-12-19 9:50 ` Sascha Hauer
2011-12-16 21:50 ` [PATCH V2 8/8] drivers/mtd: add the mtdraw device (data+oob) Robert Jarzmik
7 siblings, 1 reply; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
Split /dev/mtd and /dev/mtdoob devices.
Remove from mtd structure the mtdoob character device.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/Makefile | 1 +
drivers/mtd/core.c | 69 +--------------------------------
drivers/mtd/mtd.h | 3 +
drivers/mtd/mtdoob.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/mtd.h | 1 -
5 files changed, 105 insertions(+), 69 deletions(-)
create mode 100644 drivers/mtd/mtdoob.c
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 80fe386..ae52a68 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_NAND) += nand/
obj-$(CONFIG_UBI) += ubi/
obj-$(CONFIG_PARTITION_NEED_MTD) += partition.o
obj-$(CONFIG_MTD) += core.o
+obj-$(CONFIG_MTD_READ_OOB) += mtdoob.o
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 55fe575..55d845d 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -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,71 +186,6 @@ static struct file_operations mtd_ops = {
.lseek = dev_lseek_default,
};
-#ifdef CONFIG_MTD_READ_OOB
-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;
- /*
- * This seems suspicious, shouldn't it be :
- * offset / mtd->oobsize * mtd->writesize
- */
- 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];
@@ -280,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);
@@ -296,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;
diff --git a/drivers/mtd/mtd.h b/drivers/mtd/mtd.h
index 261cd2b..c8af6e3 100644
--- a/drivers/mtd/mtd.h
+++ b/drivers/mtd/mtd.h
@@ -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);
diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
new file mode 100644
index 0000000..ba30c5b
--- /dev/null
+++ b/drivers/mtd/mtdoob.c
@@ -0,0 +1,100 @@
+/*
+ * MTD oob device
+ *
+ * Copyright (C) 2011 Sasha 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;
+ /*
+ * This seems suspicious, shouldn't it be :
+ * offset / mtd->oobsize * mtd->writesize
+ */
+ 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;
+ 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);
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index a985c30..71d3c6f 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -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;
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH V2 7/8] mtd/drivers: split mtd mtdoob devices
2011-12-16 21:50 ` [PATCH V2 7/8] mtd/drivers: split mtd mtdoob devices Robert Jarzmik
@ 2011-12-19 9:50 ` Sascha Hauer
2011-12-19 10:50 ` Robert Jarzmik
0 siblings, 1 reply; 14+ messages in thread
From: Sascha Hauer @ 2011-12-19 9:50 UTC (permalink / raw)
To: Robert Jarzmik; +Cc: barebox
On Fri, Dec 16, 2011 at 10:50:33PM +0100, Robert Jarzmik wrote:
> Split /dev/mtd and /dev/mtdoob devices.
> Remove from mtd structure the mtdoob character device.
>
> diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
> new file mode 100644
> index 0000000..ba30c5b
> --- /dev/null
> +++ b/drivers/mtd/mtdoob.c
> @@ -0,0 +1,100 @@
> +/*
> + * MTD oob device
> + *
> + * Copyright (C) 2011 Sasha Hauer
s/Sasha/Sascha/
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH V2 7/8] mtd/drivers: split mtd mtdoob devices
2011-12-19 9:50 ` Sascha Hauer
@ 2011-12-19 10:50 ` Robert Jarzmik
0 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-19 10:50 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Sascha Hauer <s.hauer@pengutronix.de> writes:
> On Fri, Dec 16, 2011 at 10:50:33PM +0100, Robert Jarzmik wrote:
>> Split /dev/mtd and /dev/mtdoob devices.
>> Remove from mtd structure the mtdoob character device.
>>
>> diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
>> new file mode 100644
>> index 0000000..ba30c5b
>> --- /dev/null
>> +++ b/drivers/mtd/mtdoob.c
>> @@ -0,0 +1,100 @@
>> +/*
>> + * MTD oob device
>> + *
>> + * Copyright (C) 2011 Sasha Hauer
>
> s/Sasha/Sascha/
Really sorry for that.
I'll amend that one, and change the author to be you, as this is your code, not
mine. I haven't seen that until I read back from the mailing list.
Cheers.
--
Robert
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH V2 8/8] drivers/mtd: add the mtdraw device (data+oob)
2011-12-16 21:50 [PATCH V2 0/8] mtd framework rework Robert Jarzmik
` (6 preceding siblings ...)
2011-12-16 21:50 ` [PATCH V2 7/8] mtd/drivers: split mtd mtdoob devices Robert Jarzmik
@ 2011-12-16 21:50 ` Robert Jarzmik
7 siblings, 0 replies; 14+ messages in thread
From: Robert Jarzmik @ 2011-12-16 21:50 UTC (permalink / raw)
To: barebox
Add a device to read and write to MTD data and oob
(/dev/mtdraw<N>).
The device is constrained in a separate source file, so that
further improvement of commands (such as nandwrite) could
make it useless, and easy to remove.
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
drivers/mtd/Kconfig | 5 +
drivers/mtd/Makefile | 8 +-
drivers/mtd/mtdraw.c | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 313 insertions(+), 3 deletions(-)
create mode 100644 drivers/mtd/mtdraw.c
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 81282ab..7bf8fdb 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -13,6 +13,11 @@ config MTD_READ_OOB
default y
prompt "Create a device for reading the OOB data"
+config MTD_RAW_DEVICE
+ bool
+ default n
+ prompt "mtdraw device to read/write both data+oob"
+
source "drivers/mtd/nand/Kconfig"
source "drivers/mtd/ubi/Kconfig"
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index ae52a68..59fef7b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,5 +1,7 @@
-obj-$(CONFIG_NAND) += nand/
-obj-$(CONFIG_UBI) += ubi/
+obj-$(CONFIG_NAND) += nand/
+obj-$(CONFIG_UBI) += ubi/
+obj-y += devices/
obj-$(CONFIG_PARTITION_NEED_MTD) += partition.o
-obj-$(CONFIG_MTD) += core.o
+obj-$(CONFIG_MTD) += core.o
obj-$(CONFIG_MTD_READ_OOB) += mtdoob.o
+obj-$(CONFIG_MTD_RAW_DEVICE) += mtdraw.o
diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c
new file mode 100644
index 0000000..b1cce3d
--- /dev/null
+++ b/drivers/mtd/mtdraw.c
@@ -0,0 +1,303 @@
+/*
+ * MTD raw device
+ *
+ * Copyright (C) 2011 Robert Jarzmik
+ *
+ * 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 :
+ * - mtdraw<N>
+ *
+ * Device mtd_raw<N> provides acces to the MTD "pages+OOB". For example if a MTD
+ * has pages of 512 bytes and OOB of 16 bytes, mtd_oob<N> will be made of blocks
+ * of 528 bytes, with page data being followed by OOB.
+ * The layout will be: <page0> <oob0> <page1> <oob1> ... <pageN> <oobN>.
+ * This means that a read at offset 516 of 20 bytes will give the 12 last bytes
+ * of the OOB of page0, and the 8 first bytes of page1.
+ * Same thing applies for writes, which have to be page+oob aligned (ie. offset
+ * and size should be multiples of (mtd->writesize + mtd->oobsize)).
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <ioctl.h>
+#include <errno.h>
+#include <linux/mtd/mtd.h>
+
+#include "mtd.h"
+
+/* Must be a multiple of the largest NAND page size */
+#define RAW_WRITEBUF_SIZE 4096
+
+/**
+ * mtdraw - mtdraw device private data
+ * @cdev: character device "mtdraw<N>"
+ * @mtd: MTD device to handle read/writes/erases
+ *
+ * @writebuf: buffer to handle unaligned writes (ie. writes of sizes which are
+ * not multiples of MTD (writesize+oobsize)
+ * @write_fill: number of bytes in writebuf
+ * @write_ofs: offset in character device (mtdraw) where last write(s) stored
+ * bytes because of unaligned writes (ie. remain of writesize+oobsize write)
+ *
+ * The mtdraw device must allow unaligned writes. This is enabled by a write buffer which gathers data to issue mtd->write_oob() with full page+oob data.
+ * Suppose writesize=512, oobsize=16.
+ * A first write of 512 bytes triggers:
+ * - write_ofs = offset of write()
+ * - write_fill = 512
+ * - copy of the 512 provided bytes into writebuf
+ * - no actual mtd->write if done
+ * A second write of 512 bytes triggers:
+ * - copy of the 16 first bytes into writebuf
+ * - a mtd->write_oob() from writebuf
+ * - empty writebuf
+ * - copy the remaining 496 bytes into writebuf
+ * => write_fill = 496, write_ofs = offset + 528
+ * Etc ...
+ */
+struct mtdraw {
+ struct cdev cdev;
+ struct mtd_info *mtd;
+ void *writebuf;
+ int write_fill;
+ int write_ofs;
+};
+
+static struct mtdraw *to_mtdraw(struct cdev *cdev)
+{
+ return cdev->priv;
+}
+
+static struct mtd_info *to_mtd(struct cdev *cdev)
+{
+ struct mtdraw *mtdraw = to_mtdraw(cdev);
+ return mtdraw->mtd;
+}
+
+static ssize_t mtdraw_read_unaligned(struct mtd_info *mtd, void *dst,
+ size_t count, int skip, ulong offset)
+{
+ struct mtd_oob_ops ops;
+ ssize_t ret;
+ int partial = 0;
+ void *tmp = dst;
+
+ if (skip || count < mtd->writesize + mtd->oobsize)
+ partial = 1;
+ if (partial)
+ tmp = malloc(mtd->writesize + mtd->oobsize);
+ if (!tmp)
+ return -ENOMEM;
+ ops.mode = MTD_OOB_RAW;
+ ops.datbuf = tmp;
+ ops.len = mtd->writesize;
+ ops.oobbuf = tmp + mtd->writesize;
+ ops.ooblen = mtd->oobsize;
+ ret = mtd->read_oob(mtd, offset, &ops);
+ if (ret)
+ goto err;
+ if (partial)
+ memcpy(dst, tmp + skip, count);
+ ret = count;
+err:
+ if (partial)
+ free(tmp);
+
+ return ret;
+}
+
+static ssize_t mtdraw_read(struct cdev *cdev, void *buf, size_t count,
+ ulong offset, ulong flags)
+{
+ struct mtd_info *mtd = to_mtd(cdev);
+ ssize_t retlen = 0, ret = 1, toread;
+ ulong numpage;
+ int skip;
+
+ numpage = offset / (mtd->writesize + mtd->oobsize);
+ skip = offset % (mtd->writesize + mtd->oobsize);
+
+ while (ret > 0 && count > 0) {
+ toread = min_t(int, count, mtd->writesize + mtd->oobsize);
+ ret = mtdraw_read_unaligned(mtd, buf, toread,
+ skip, numpage++ * mtd->writesize);
+ buf += ret;
+ skip = 0;
+ count -= ret;
+ retlen += ret;
+ }
+ if (ret < 0)
+ printf("err %d\n", ret);
+ else
+ ret = retlen;
+ return ret;
+}
+
+#ifdef CONFIG_MTD_WRITE
+static ssize_t mtdraw_blkwrite(struct mtd_info *mtd, const void *buf,
+ ulong offset)
+{
+ struct mtd_oob_ops ops;
+ int ret;
+
+ ops.mode = MTD_OOB_RAW;
+ ops.datbuf = (void *)buf;
+ ops.len = mtd->writesize;
+ ops.oobbuf = (void *)buf + mtd->writesize;
+ ops.ooblen = mtd->oobsize;
+ ret = mtd->write_oob(mtd, offset, &ops);
+ if (!ret)
+ ret = ops.retlen + ops.oobretlen;
+ return ret;
+}
+
+static void mtdraw_fillbuf(struct mtdraw *mtdraw, const void *src, int nbbytes)
+{
+ memcpy(mtdraw->writebuf + mtdraw->write_fill, src, nbbytes);
+ mtdraw->write_fill += nbbytes;
+}
+
+static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
+ ulong offset, ulong flags)
+{
+ struct mtdraw *mtdraw = to_mtdraw(cdev);
+ struct mtd_info *mtd = to_mtd(cdev);
+ int bsz = mtd->writesize + mtd->oobsize;
+ ulong numpage;
+ size_t retlen = 0, tofill;
+ int ret = 0;
+
+ if (mtdraw->write_fill &&
+ mtdraw->write_ofs + mtdraw->write_fill != offset)
+ return -EINVAL;
+ if (mtdraw->write_fill == 0 && offset % bsz)
+ return -EINVAL;
+
+ if (mtdraw->write_fill) {
+ tofill = min_t(size_t, count, bsz - mtdraw->write_fill);
+ mtdraw_fillbuf(mtdraw, buf, tofill);
+ offset += tofill;
+ count -= tofill;
+ retlen += tofill;
+ }
+
+ if (mtdraw->write_fill == bsz) {
+ ret = mtdraw_blkwrite(mtd, mtdraw->writebuf, mtdraw->write_ofs);
+ retlen += ret;
+ mtdraw->write_fill = 0;
+ }
+
+ numpage = offset / (mtd->writesize + mtd->oobsize);
+ while (ret >= 0 && count >= bsz) {
+ ret = mtdraw_blkwrite(mtd, buf + retlen,
+ mtd->writesize * numpage++);
+ count -= ret;
+ retlen += ret;
+ offset += ret;
+ }
+
+ if (ret >= 0 && count) {
+ mtdraw->write_ofs = offset - mtdraw->write_fill;
+ mtdraw_fillbuf(mtdraw, buf + retlen, count);
+ }
+
+ if (ret < 0) {
+ printf("err %d\n", ret);
+ return ret;
+ } else {
+ return retlen;
+ }
+}
+
+static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, ulong offset)
+{
+ struct mtd_info *mtd = to_mtd(cdev);
+ struct erase_info erase;
+ int ret;
+
+ offset = offset / (mtd->writesize + mtd->oobsize) * mtd->writesize;
+ count = count / (mtd->writesize + mtd->oobsize) * mtd->writesize;
+
+ memset(&erase, 0, sizeof(erase));
+ erase.mtd = mtd;
+ erase.addr = offset;
+ erase.len = mtd->erasesize;
+
+ while (count > 0) {
+ debug("erase %d %d\n", erase.addr, erase.len);
+
+ ret = mtd->block_isbad(mtd, erase.addr);
+ if (ret > 0) {
+ printf("Skipping bad block at 0x%08x\n", erase.addr);
+ } else {
+ ret = mtd->erase(mtd, &erase);
+ if (ret)
+ return ret;
+ }
+
+ erase.addr += mtd->erasesize;
+ count -= count > mtd->erasesize ? mtd->erasesize : count;
+ }
+
+ return 0;
+}
+#else
+static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
+ ulong offset, ulong flags)
+{
+ return 0;
+}
+static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, ulong offset)
+{
+ return 0;
+}
+#endif
+
+static const struct file_operations mtd_raw_fops = {
+ .read = mtdraw_read,
+ .write = mtdraw_write,
+ .erase = mtdraw_erase,
+ .ioctl = mtd_ioctl,
+ .lseek = dev_lseek_default,
+};
+
+static int add_mtdraw_device(struct mtd_info *mtd, char *devname)
+{
+ struct mtdraw *mtdraw;
+
+ mtdraw = xzalloc(sizeof(*mtdraw));
+ mtdraw->writebuf = xmalloc(RAW_WRITEBUF_SIZE);
+ mtdraw->mtd = mtd;
+
+ mtdraw->cdev.ops = (struct file_operations *)&mtd_raw_fops;
+ mtdraw->cdev.size = mtd->size / mtd->writesize *
+ (mtd->writesize + mtd->oobsize);
+ mtdraw->cdev.name = asprintf("%sraw%d", devname, mtd->class_dev.id);
+ mtdraw->cdev.priv = mtdraw;
+ mtdraw->cdev.dev = &mtd->class_dev;
+ mtdraw->cdev.mtd = mtd;
+ devfs_create(&mtdraw->cdev);
+
+ return 0;
+}
+
+static struct mtddev_hook mtdraw_hook = {
+ .add_mtd_device = add_mtdraw_device,
+};
+
+static int __init register_mtdraw(void)
+{
+ mtdcore_add_hook(&mtdraw_hook);
+ return 0;
+}
+
+coredevice_initcall(register_mtdraw);
--
1.7.5.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 14+ messages in thread