* [U-Boot] [PATCH] Add MTD core & partition
@ 2008-08-29 8:13 Kyungmin Park
2008-09-06 22:13 ` Wolfgang Denk
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Kyungmin Park @ 2008-08-29 8:13 UTC (permalink / raw)
To: u-boot
It's preparation for UBI codes.
UBI uses partition and get & put mtd devices
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 6538f7a..d225a68 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libmtd.a
+COBJS-$(CONFIG_CMD_UBI) += mtdcore.o mtdpart.o
COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o
COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o
COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
new file mode 100644
index 0000000..2fb6099
--- /dev/null
+++ b/drivers/mtd/mtdcore.c
@@ -0,0 +1,142 @@
+/*
+ * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
+ *
+ * Core registration and callback routines for MTD
+ * drivers and users.
+ */
+
+#include <linux/mtd/mtd.h>
+#include <mtd_uboot.h>
+#include <ubi_uboot.h>
+
+struct mtd_info *mtd_table[MAX_MTD_DEVICES];
+
+int add_mtd_device(struct mtd_info *mtd)
+{
+ int i;
+
+ BUG_ON(mtd->writesize == 0);
+
+ for (i=0; i < MAX_MTD_DEVICES; i++)
+ if (!mtd_table[i]) {
+ mtd_table[i] = mtd;
+ mtd->index = i;
+ mtd->usecount = 0;
+
+ printf("mtd: Giving out device %d to %s\n",i, mtd->name);
+ /* No need to get a refcount on the module containing
+ the notifier, since we hold the mtd_table_mutex */
+
+ /* We _know_ we aren't being removed, because
+ our caller is still holding us here. So none
+ of this try_ nonsense, and no bitching about it
+ either. :) */
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * del_mtd_device - unregister an MTD device
+ * @mtd: pointer to MTD device info structure
+ *
+ * Remove a device from the list of MTD devices present in the system,
+ * and notify each currently active MTD 'user' of its departure.
+ * Returns zero on success or 1 on failure, which currently will happen
+ * if the requested device does not appear to be present in the list.
+ */
+int del_mtd_device (struct mtd_info *mtd)
+{
+ int ret;
+
+ if (mtd_table[mtd->index] != mtd) {
+ ret = -ENODEV;
+ } else if (mtd->usecount) {
+ printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
+ mtd->index, mtd->name, mtd->usecount);
+ ret = -EBUSY;
+ } else {
+ /* No need to get a refcount on the module containing
+ * the notifier, since we hold the mtd_table_mutex */
+ mtd_table[mtd->index] = NULL;
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/**
+ * get_mtd_device - obtain a validated handle for an MTD device
+ * @mtd: last known address of the required MTD device
+ * @num: internal device number of the required MTD device
+ *
+ * Given a number and NULL address, return the num'th entry in the device
+ * table, if any. Given an address and num == -1, search the device table
+ * for a device with that address and return if it's still present. Given
+ * both, return the num'th driver only if its address matches. Return
+ * error code if not.
+ */
+struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
+{
+ struct mtd_info *ret = NULL;
+ int i, err = -ENODEV;
+
+ if (num == -1) {
+ for (i=0; i< MAX_MTD_DEVICES; i++)
+ if (mtd_table[i] == mtd)
+ ret = mtd_table[i];
+ } else if (num < MAX_MTD_DEVICES) {
+ ret = mtd_table[num];
+ if (mtd && mtd != ret)
+ ret = NULL;
+ }
+
+ if (!ret)
+ goto out_unlock;
+
+ ret->usecount++;
+ return ret;
+
+out_unlock:
+ return ERR_PTR(err);
+}
+
+/**
+ * get_mtd_device_nm - obtain a validated handle for an MTD device by
+ * device name
+ * @name: MTD device name to open
+ *
+ * This function returns MTD device description structure in case of
+ * success and an error code in case of failure.
+ */
+struct mtd_info *get_mtd_device_nm(const char *name)
+{
+ int i, err = -ENODEV;
+ struct mtd_info *mtd = NULL;
+
+ for (i = 0; i < MAX_MTD_DEVICES; i++) {
+ if (mtd_table[i] && !strcmp(name, mtd_table[i]->name)) {
+ mtd = mtd_table[i];
+ break;
+ }
+ }
+
+ if (!mtd)
+ goto out_unlock;
+
+ mtd->usecount++;
+ return mtd;
+
+out_unlock:
+ return ERR_PTR(err);
+}
+
+void put_mtd_device(struct mtd_info *mtd)
+{
+ int c;
+
+ c = --mtd->usecount;
+ BUG_ON(c < 0);
+}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
new file mode 100644
index 0000000..113516a
--- /dev/null
+++ b/drivers/mtd/mtdpart.c
@@ -0,0 +1,531 @@
+/*
+ * Simple MTD partitioning layer
+ *
+ * (C) 2000 Nicolas Pitre <nico@cam.org>
+ *
+ * This code is GPL
+ *
+ * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $
+ *
+ * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
+ * added support for read_oob, write_oob
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/errno.h>
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/compat.h>
+
+/* Our partition linked list */
+static LIST_HEAD(mtd_partitions);
+
+/* Our partition node structure */
+struct mtd_part {
+ struct mtd_info mtd;
+ struct mtd_info *master;
+ u_int32_t offset;
+ int index;
+ struct list_head list;
+ int registered;
+};
+
+/*
+ * Given a pointer to the MTD object in the mtd_part structure, we can retrieve
+ * the pointer to that structure with this macro.
+ */
+#define PART(x) ((struct mtd_part *)(x))
+
+
+/*
+ * MTD methods which simply translate the effective address and pass through
+ * to the _real_ device.
+ */
+
+static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct mtd_part *part = PART(mtd);
+ int res;
+
+ if (from >= mtd->size)
+ len = 0;
+ else if (from + len > mtd->size)
+ len = mtd->size - from;
+ res = part->master->read (part->master, from + part->offset,
+ len, retlen, buf);
+#if 0
+ if (unlikely(res)) {
+ if (res == -EUCLEAN)
+ mtd->ecc_stats.corrected++;
+ if (res == -EBADMSG)
+ mtd->ecc_stats.failed++;
+ }
+#endif
+ return res;
+}
+
+#if 0
+static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, void **virt, resource_size_t *phys)
+{
+ struct mtd_part *part = PART(mtd);
+ if (from >= mtd->size)
+ len = 0;
+ else if (from + len > mtd->size)
+ len = mtd->size - from;
+ return part->master->point (part->master, from + part->offset,
+ len, retlen, virt, phys);
+}
+
+static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+
+ part->master->unpoint(part->master, from + part->offset, len);
+}
+
+static int part_read_oob(struct mtd_info *mtd, loff_t from,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_part *part = PART(mtd);
+ int res;
+
+ if (from >= mtd->size)
+ return -EINVAL;
+ if (ops->datbuf && from + ops->len > mtd->size)
+ return -EINVAL;
+ res = part->master->read_oob(part->master, from + part->offset, ops);
+
+ if (unlikely(res)) {
+ if (res == -EUCLEAN)
+ mtd->ecc_stats.corrected++;
+ if (res == -EBADMSG)
+ mtd->ecc_stats.failed++;
+ }
+ return res;
+}
+
+static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->read_user_prot_reg (part->master, from,
+ len, retlen, buf);
+}
+
+static int part_get_user_prot_info (struct mtd_info *mtd,
+ struct otp_info *buf, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->get_user_prot_info (part->master, buf, len);
+}
+
+static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->read_fact_prot_reg (part->master, from,
+ len, retlen, buf);
+}
+
+static int part_get_fact_prot_info (struct mtd_info *mtd,
+ struct otp_info *buf, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->get_fact_prot_info (part->master, buf, len);
+}
+#endif
+
+static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct mtd_part *part = PART(mtd);
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+ if (to >= mtd->size)
+ len = 0;
+ else if (to + len > mtd->size)
+ len = mtd->size - to;
+ return part->master->write (part->master, to + part->offset,
+ len, retlen, buf);
+}
+
+#if 0
+static int part_panic_write (struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct mtd_part *part = PART(mtd);
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+ if (to >= mtd->size)
+ len = 0;
+ else if (to + len > mtd->size)
+ len = mtd->size - to;
+ return part->master->panic_write (part->master, to + part->offset,
+ len, retlen, buf);
+}
+
+static int part_write_oob(struct mtd_info *mtd, loff_t to,
+ struct mtd_oob_ops *ops)
+{
+ struct mtd_part *part = PART(mtd);
+
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+
+ if (to >= mtd->size)
+ return -EINVAL;
+ if (ops->datbuf && to + ops->len > mtd->size)
+ return -EINVAL;
+ return part->master->write_oob(part->master, to + part->offset, ops);
+}
+
+static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->write_user_prot_reg (part->master, from,
+ len, retlen, buf);
+}
+
+static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->lock_user_prot_reg (part->master, from, len);
+}
+
+static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
+ unsigned long count, loff_t to, size_t *retlen)
+{
+ struct mtd_part *part = PART(mtd);
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+ return part->master->writev (part->master, vecs, count,
+ to + part->offset, retlen);
+}
+#endif
+
+static int part_erase (struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct mtd_part *part = PART(mtd);
+ int ret;
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+ if (instr->addr >= mtd->size)
+ return -EINVAL;
+ instr->addr += part->offset;
+ ret = part->master->erase(part->master, instr);
+ if (ret) {
+ if (instr->fail_addr != 0xffffffff)
+ instr->fail_addr -= part->offset;
+ instr->addr -= part->offset;
+ }
+ return ret;
+}
+
+void mtd_erase_callback(struct erase_info *instr)
+{
+ if (instr->mtd->erase == part_erase) {
+ struct mtd_part *part = PART(instr->mtd);
+
+ if (instr->fail_addr != 0xffffffff)
+ instr->fail_addr -= part->offset;
+ instr->addr -= part->offset;
+ }
+ if (instr->callback)
+ instr->callback(instr);
+}
+#if 0
+EXPORT_SYMBOL_GPL(mtd_erase_callback);
+#endif
+
+#if 0
+static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ if ((len + ofs) > mtd->size)
+ return -EINVAL;
+ return part->master->lock(part->master, ofs + part->offset, len);
+}
+
+static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
+{
+ struct mtd_part *part = PART(mtd);
+ if ((len + ofs) > mtd->size)
+ return -EINVAL;
+ return part->master->unlock(part->master, ofs + part->offset, len);
+}
+#endif
+
+static void part_sync(struct mtd_info *mtd)
+{
+ struct mtd_part *part = PART(mtd);
+ part->master->sync(part->master);
+}
+
+#if 0
+static int part_suspend(struct mtd_info *mtd)
+{
+ struct mtd_part *part = PART(mtd);
+ return part->master->suspend(part->master);
+}
+
+static void part_resume(struct mtd_info *mtd)
+{
+ struct mtd_part *part = PART(mtd);
+ part->master->resume(part->master);
+}
+#endif
+
+static int part_block_isbad (struct mtd_info *mtd, loff_t ofs)
+{
+ struct mtd_part *part = PART(mtd);
+ if (ofs >= mtd->size)
+ return -EINVAL;
+ ofs += part->offset;
+ return part->master->block_isbad(part->master, ofs);
+}
+
+static int part_block_markbad (struct mtd_info *mtd, loff_t ofs)
+{
+ struct mtd_part *part = PART(mtd);
+ int res;
+
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+ if (ofs >= mtd->size)
+ return -EINVAL;
+ ofs += part->offset;
+ res = part->master->block_markbad(part->master, ofs);
+#if 0
+ if (!res)
+ mtd->ecc_stats.badblocks++;
+#endif
+ return res;
+}
+
+/*
+ * This function unregisters and destroy all slave MTD objects which are
+ * attached to the given master MTD object.
+ */
+
+int del_mtd_partitions(struct mtd_info *master)
+{
+ struct list_head *node;
+ struct mtd_part *slave;
+
+ for (node = mtd_partitions.next;
+ node != &mtd_partitions;
+ node = node->next) {
+ slave = list_entry(node, struct mtd_part, list);
+ if (slave->master == master) {
+ struct list_head *prev = node->prev;
+ __list_del(prev, node->next);
+ if(slave->registered)
+ del_mtd_device(&slave->mtd);
+ kfree(slave);
+ node = prev;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function, given a master MTD object and a partition table, creates
+ * and registers slave MTD objects which are bound to the master according to
+ * the partition definitions.
+ * (Q: should we register the master MTD object as well?)
+ */
+
+int add_mtd_partitions(struct mtd_info *master,
+ const struct mtd_partition *parts,
+ int nbparts)
+{
+ struct mtd_part *slave;
+ u_int32_t cur_offset = 0;
+ int i;
+
+ printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
+
+ for (i = 0; i < nbparts; i++) {
+
+ /* allocate the partition structure */
+ slave = kzalloc (sizeof(*slave), GFP_KERNEL);
+ if (!slave) {
+ printk ("memory allocation error while creating partitions for \"%s\"\n",
+ master->name);
+ del_mtd_partitions(master);
+ return -ENOMEM;
+ }
+ list_add(&slave->list, &mtd_partitions);
+
+ /* set up the MTD object for this partition */
+ slave->mtd.type = master->type;
+ slave->mtd.flags = master->flags & ~parts[i].mask_flags;
+ slave->mtd.size = parts[i].size;
+ slave->mtd.writesize = master->writesize;
+ slave->mtd.oobsize = master->oobsize;
+ slave->mtd.oobavail = master->oobavail;
+ slave->mtd.subpage_sft = master->subpage_sft;
+
+ slave->mtd.name = parts[i].name;
+ slave->mtd.owner = master->owner;
+
+ slave->mtd.read = part_read;
+ slave->mtd.write = part_write;
+
+#if 0
+ if (master->panic_write)
+ slave->mtd.panic_write = part_panic_write;
+
+ if(master->point && master->unpoint){
+ slave->mtd.point = part_point;
+ slave->mtd.unpoint = part_unpoint;
+ }
+
+ if (master->read_oob)
+ slave->mtd.read_oob = part_read_oob;
+ if (master->write_oob)
+ slave->mtd.write_oob = part_write_oob;
+ if(master->read_user_prot_reg)
+ slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
+ if(master->read_fact_prot_reg)
+ slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
+ if(master->write_user_prot_reg)
+ slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
+ if(master->lock_user_prot_reg)
+ slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
+ if(master->get_user_prot_info)
+ slave->mtd.get_user_prot_info = part_get_user_prot_info;
+ if(master->get_fact_prot_info)
+ slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
+#endif
+ if (master->sync)
+ slave->mtd.sync = part_sync;
+#if 0
+ if (!i && master->suspend && master->resume) {
+ slave->mtd.suspend = part_suspend;
+ slave->mtd.resume = part_resume;
+ }
+ if (master->writev)
+ slave->mtd.writev = part_writev;
+ if (master->lock)
+ slave->mtd.lock = part_lock;
+ if (master->unlock)
+ slave->mtd.unlock = part_unlock;
+#endif
+ if (master->block_isbad)
+ slave->mtd.block_isbad = part_block_isbad;
+ if (master->block_markbad)
+ slave->mtd.block_markbad = part_block_markbad;
+ slave->mtd.erase = part_erase;
+ slave->master = master;
+ slave->offset = parts[i].offset;
+ slave->index = i;
+
+ if (slave->offset == MTDPART_OFS_APPEND)
+ slave->offset = cur_offset;
+ if (slave->offset == MTDPART_OFS_NXTBLK) {
+ slave->offset = cur_offset;
+ if ((cur_offset % master->erasesize) != 0) {
+ /* Round up to next erasesize */
+ slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
+ printk(KERN_NOTICE "Moving partition %d: "
+ "0x%08x -> 0x%08x\n", i,
+ cur_offset, slave->offset);
+ }
+ }
+ if (slave->mtd.size == MTDPART_SIZ_FULL)
+ slave->mtd.size = master->size - slave->offset;
+ cur_offset = slave->offset + slave->mtd.size;
+
+ printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
+ slave->offset + slave->mtd.size, slave->mtd.name);
+
+ /* let's do some sanity checks */
+ if (slave->offset >= master->size) {
+ /* let's register it anyway to preserve ordering */
+ slave->offset = 0;
+ slave->mtd.size = 0;
+ printk ("mtd: partition \"%s\" is out of reach -- disabled\n",
+ parts[i].name);
+ }
+ if (slave->offset + slave->mtd.size > master->size) {
+ slave->mtd.size = master->size - slave->offset;
+ printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
+ parts[i].name, master->name, slave->mtd.size);
+ }
+ if (master->numeraseregions>1) {
+ /* Deal with variable erase size stuff */
+ int i;
+ struct mtd_erase_region_info *regions = master->eraseregions;
+
+ /* Find the first erase regions which is part of this partition. */
+ for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
+ ;
+
+ for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
+ if (slave->mtd.erasesize < regions[i].erasesize) {
+ slave->mtd.erasesize = regions[i].erasesize;
+ }
+ }
+ } else {
+ /* Single erase size */
+ slave->mtd.erasesize = master->erasesize;
+ }
+
+ if ((slave->mtd.flags & MTD_WRITEABLE) &&
+ (slave->offset % slave->mtd.erasesize)) {
+ /* Doesn't start on a boundary of major erase size */
+ /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
+ slave->mtd.flags &= ~MTD_WRITEABLE;
+ printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
+ parts[i].name);
+ }
+ if ((slave->mtd.flags & MTD_WRITEABLE) &&
+ (slave->mtd.size % slave->mtd.erasesize)) {
+ slave->mtd.flags &= ~MTD_WRITEABLE;
+ printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
+ parts[i].name);
+ }
+
+#if 0
+ slave->mtd.ecclayout = master->ecclayout;
+ if (master->block_isbad) {
+ uint32_t offs = 0;
+
+ while(offs < slave->mtd.size) {
+ if (master->block_isbad(master,
+ offs + slave->offset))
+ slave->mtd.ecc_stats.badblocks++;
+ offs += slave->mtd.erasesize;
+ }
+ }
+
+ if(parts[i].mtdp)
+ { /* store the object pointer (caller may or may not register it */
+ *parts[i].mtdp = &slave->mtd;
+ slave->registered = 0;
+ }
+ else
+#endif
+ {
+ /* register our partition */
+ add_mtd_device(&slave->mtd);
+ slave->registered = 1;
+ }
+ }
+
+ return 0;
+}
+
+#if 0
+EXPORT_SYMBOL(add_mtd_partitions);
+EXPORT_SYMBOL(del_mtd_partitions);
+#endif
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-08-29 8:13 [U-Boot] [PATCH] Add MTD core & partition Kyungmin Park
@ 2008-09-06 22:13 ` Wolfgang Denk
2008-09-07 23:28 ` Kyungmin Park
2008-09-08 19:30 ` Scott Wood
2008-09-19 12:31 ` Michael Lawnick
2 siblings, 1 reply; 11+ messages in thread
From: Wolfgang Denk @ 2008-09-06 22:13 UTC (permalink / raw)
To: u-boot
Dear Kyungmin Park,
In message <20080829081323.GA4269@july> you wrote:
> It's preparation for UBI codes.
> UBI uses partition and get & put mtd devices
Please co-ordinate any UBI-related work with Stefan Roese.
I will not apply any UBI related patches unless I have his ACK.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Tactical? TACTICAL!?!? Hey, buddy, we went from kilotons to megatons
several minutes ago. We don't need no stinkin' tactical nukes. (By
the way, do you have change for 10 million people?) - lwall
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-06 22:13 ` Wolfgang Denk
@ 2008-09-07 23:28 ` Kyungmin Park
2008-09-08 7:35 ` Stefan Roese
0 siblings, 1 reply; 11+ messages in thread
From: Kyungmin Park @ 2008-09-07 23:28 UTC (permalink / raw)
To: u-boot
Dear Wolfgang,
> In message <20080829081323.GA4269@july> you wrote:
>> It's preparation for UBI codes.
>> UBI uses partition and get & put mtd devices
>
> Please co-ordinate any UBI-related work with Stefan Roese.
>
> I will not apply any UBI related patches unless I have his ACK.
>
Sure, I agreed your opinions.
Then how about to crate u-boot-ubi tree for others?
Now we are using UBI both NAND and OneNAND. To do this, we also change
OneNAND command to support UBI fully. but previous patch it doesn't
have.
I want to share our works at least UBI.
If you have more opinions please let me know.
Thank you,
Kyungmin Park
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-07 23:28 ` Kyungmin Park
@ 2008-09-08 7:35 ` Stefan Roese
0 siblings, 0 replies; 11+ messages in thread
From: Stefan Roese @ 2008-09-08 7:35 UTC (permalink / raw)
To: u-boot
Kyungmi,
On Monday 08 September 2008, Kyungmin Park wrote:
> >> It's preparation for UBI codes.
> >> UBI uses partition and get & put mtd devices
> >
> > Please co-ordinate any UBI-related work with Stefan Roese.
> >
> > I will not apply any UBI related patches unless I have his ACK.
I have no objections to this patch. So here my:
Acked-by: Stefan Roese <sr@denx.de>
But I think it would be a good idea if Scott Wood could also take a look at
this patch (and the whole UBI integration) since this UBI integration also
touches "his" NAND infrastructure.
Scott, any comments?
> Sure, I agreed your opinions.
> Then how about to crate u-boot-ubi tree for others?
Good idea. Please see below.
> Now we are using UBI both NAND and OneNAND. To do this, we also change
> OneNAND command to support UBI fully. but previous patch it doesn't
> have.
>
> I want to share our works at least UBI.
We really appreciate this. Thanks a lot.
> If you have more opinions please let me know.
We will add an new u-boot-ubi repository and would like you to become the
custodian. Would you accept this? Do you (or anybody else) have other
volunteers for this job?
If you accept this and nobody objects, please send your public SSH key to
Wolfgang in a private mail, so that he can create the new repository for you.
Thanks.
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-08-29 8:13 [U-Boot] [PATCH] Add MTD core & partition Kyungmin Park
2008-09-06 22:13 ` Wolfgang Denk
@ 2008-09-08 19:30 ` Scott Wood
2008-09-09 1:15 ` Kyungmin Park
2008-09-19 12:31 ` Michael Lawnick
2 siblings, 1 reply; 11+ messages in thread
From: Scott Wood @ 2008-09-08 19:30 UTC (permalink / raw)
To: u-boot
On Fri, Aug 29, 2008 at 05:13:23PM +0900, Kyungmin Park wrote:
> It's preparation for UBI codes.
> UBI uses partition and get & put mtd devices
Please import the latest MTD code; there have been several cleanups/fixes
in mtdpart.c recently (in particular, the patches from Atsushi Nemoto
dated Jul 19).
As for the #if 0 blocks, I'd rather leave them out entirely -- I think
the increased readability would be worth the occasional extra merge
conflict when importing new upstream code.
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---
> diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
> index 6538f7a..d225a68 100644
> --- a/drivers/mtd/Makefile
> +++ b/drivers/mtd/Makefile
> @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
>
> LIB := $(obj)libmtd.a
>
> +COBJS-$(CONFIG_CMD_UBI) += mtdcore.o mtdpart.o
Is UBI the only case where we want the generic MTD infrastructure? Maybe
we can remove some duplication and/or add partition support elsewhere.
> COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o
> COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o
> COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> new file mode 100644
> index 0000000..2fb6099
> --- /dev/null
> +++ b/drivers/mtd/mtdcore.c
> @@ -0,0 +1,142 @@
> +/*
> + * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
> + *
> + * Core registration and callback routines for MTD
> + * drivers and users.
> + */
> +
> +#include <linux/mtd/mtd.h>
> +#include <mtd_uboot.h>
> +#include <ubi_uboot.h>
I don't see mtd_uboot.h or ubi_uboot.h in the current tree, nor are they
added by this patch.
Is this patch supposed to depend on the giant UBI patch (I'd think not,
since the changelog says it's preparing for UBI)?
> +/**
> + * del_mtd_device - unregister an MTD device
> + * @mtd: pointer to MTD device info structure
> + *
> + * Remove a device from the list of MTD devices present in the system,
> + * and notify each currently active MTD 'user' of its departure.
> + * Returns zero on success or 1 on failure, which currently will happen
> + * if the requested device does not appear to be present in the list.
> + */
> +int del_mtd_device (struct mtd_info *mtd)
> +{
> + int ret;
> +
> + if (mtd_table[mtd->index] != mtd) {
> + ret = -ENODEV;
> + } else if (mtd->usecount) {
> + printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
> + mtd->index, mtd->name, mtd->usecount);
> + ret = -EBUSY;
> + } else {
> + /* No need to get a refcount on the module containing
> + * the notifier, since we hold the mtd_table_mutex */
> + mtd_table[mtd->index] = NULL;
> +
> + ret = 0;
> + }
> +
> + return ret;
> +}
We should remove all the refcounting/removal stuff -- it's just bloat in
u-boot.
-Scott
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-08 19:30 ` Scott Wood
@ 2008-09-09 1:15 ` Kyungmin Park
0 siblings, 0 replies; 11+ messages in thread
From: Kyungmin Park @ 2008-09-09 1:15 UTC (permalink / raw)
To: u-boot
On Tue, Sep 9, 2008 at 4:30 AM, Scott Wood <scottwood@freescale.com> wrote:
> On Fri, Aug 29, 2008 at 05:13:23PM +0900, Kyungmin Park wrote:
>> It's preparation for UBI codes.
>> UBI uses partition and get & put mtd devices
>
> Please import the latest MTD code; there have been several cleanups/fixes
> in mtdpart.c recently (in particular, the patches from Atsushi Nemoto
> dated Jul 19).
>
> As for the #if 0 blocks, I'd rather leave them out entirely -- I think
> the increased readability would be worth the occasional extra merge
> conflict when importing new upstream code.
>
That's the reason I want to create new tree to sync u-boot tree. At
that time there's no point, ecc_stats, and ... fields at mtd_info, So
I disable it. Now it's included and we can remove #if 0.
>> ---
>> diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
>> index 6538f7a..d225a68 100644
>> --- a/drivers/mtd/Makefile
>> +++ b/drivers/mtd/Makefile
>> @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
>>
>> LIB := $(obj)libmtd.a
>>
>> +COBJS-$(CONFIG_CMD_UBI) += mtdcore.o mtdpart.o
>
> Is UBI the only case where we want the generic MTD infrastructure? Maybe
> we can remove some duplication and/or add partition support elsewhere.
Yes I agree. As I know there's no users to use mtdpart. Instead it
used another mtdpart format at mtdpart command. Next time it changes
from previous one to MTD infrastructure.
>
>> COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o
>> COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o
>> COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o
>> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
>> new file mode 100644
>> index 0000000..2fb6099
>> --- /dev/null
>> +++ b/drivers/mtd/mtdcore.c
>> @@ -0,0 +1,142 @@
>> +/*
>> + * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
>> + *
>> + * Core registration and callback routines for MTD
>> + * drivers and users.
>> + */
>> +
>> +#include <linux/mtd/mtd.h>
>> +#include <mtd_uboot.h>
>> +#include <ubi_uboot.h>
>
> I don't see mtd_uboot.h or ubi_uboot.h in the current tree, nor are they
> added by this patch.
>
> Is this patch supposed to depend on the giant UBI patch (I'd think not,
> since the changelog says it's preparing for UBI)?
>
>> +/**
>> + * del_mtd_device - unregister an MTD device
>> + * @mtd: pointer to MTD device info structure
>> + *
>> + * Remove a device from the list of MTD devices present in the system,
>> + * and notify each currently active MTD 'user' of its departure.
>> + * Returns zero on success or 1 on failure, which currently will happen
>> + * if the requested device does not appear to be present in the list.
>> + */
>> +int del_mtd_device (struct mtd_info *mtd)
>> +{
>> + int ret;
>> +
>> + if (mtd_table[mtd->index] != mtd) {
>> + ret = -ENODEV;
>> + } else if (mtd->usecount) {
>> + printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
>> + mtd->index, mtd->name, mtd->usecount);
>> + ret = -EBUSY;
>> + } else {
>> + /* No need to get a refcount on the module containing
>> + * the notifier, since we hold the mtd_table_mutex */
>> + mtd_table[mtd->index] = NULL;
>> +
>> + ret = 0;
>> + }
>> +
>> + return ret;
>> +}
>
> We should remove all the refcounting/removal stuff -- it's just bloat in
> u-boot.
I don't want to remove or modify imported codes at least MTD & UBI codes.
Thank you,
Kyungmin Park
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-08-29 8:13 [U-Boot] [PATCH] Add MTD core & partition Kyungmin Park
2008-09-06 22:13 ` Wolfgang Denk
2008-09-08 19:30 ` Scott Wood
@ 2008-09-19 12:31 ` Michael Lawnick
2008-09-19 13:07 ` Stefan Roese
2 siblings, 1 reply; 11+ messages in thread
From: Michael Lawnick @ 2008-09-19 12:31 UTC (permalink / raw)
To: u-boot
Kyungmin Park <kmpark <at> infradead.org> writes:
>
> It's preparation for UBI codes.
> UBI uses partition and get & put mtd devices
>
...
Hi,
how far have you got?
We are planning to integrate UBI in u-boot too (NOR flashes), so if all is
already done - or will be in next time - we could spare some hours ...
Kind Regards,
Michael
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-19 12:31 ` Michael Lawnick
@ 2008-09-19 13:07 ` Stefan Roese
2008-09-19 13:24 ` Michael Lawnick
0 siblings, 1 reply; 11+ messages in thread
From: Stefan Roese @ 2008-09-19 13:07 UTC (permalink / raw)
To: u-boot
On Friday 19 September 2008, Michael Lawnick wrote:
> how far have you got?
> We are planning to integrate UBI in u-boot too (NOR flashes), so if all is
> already done - or will be in next time - we could spare some hours ...
We also have a project to integrate UBI support into U-Boot. The real UBI work
will start in 2-3 weeks. We really should coordinate our work on this.
BTW: Which NOR FLASH driver are you using? The common CFI driver? It has no
real connection to the MTD layer which is needed for the UBI port from
Kyungmin. Did you think about this?
Thanks.
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-19 13:07 ` Stefan Roese
@ 2008-09-19 13:24 ` Michael Lawnick
2008-09-19 13:38 ` Stefan Roese
0 siblings, 1 reply; 11+ messages in thread
From: Michael Lawnick @ 2008-09-19 13:24 UTC (permalink / raw)
To: u-boot
Stefan Roese <sr <at> denx.de> writes:
>
> On Friday 19 September 2008, Michael Lawnick wrote:
> > how far have you got?
> > We are planning to integrate UBI in u-boot too (NOR flashes), so if all is
> > already done - or will be in next time - we could spare some hours ...
>
> We also have a project to integrate UBI support into U-Boot. The real UBI work
> will start in 2-3 weeks. We really should coordinate our work on this.
>
> BTW: Which NOR FLASH driver are you using? The common CFI driver? It has no
> real connection to the MTD layer which is needed for the UBI port from
> Kyungmin. Did you think about this?
>
We are using CFI driver for AM29GL512.
As said we are _planning_ to integrate, i.e. I'm currently gathering
information. We need r/o access from u-boot to find our kernel and boot it.
Writing to flash could be done from Linux.
What are the problems to face?
Kind Regards,
Michael
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-19 13:24 ` Michael Lawnick
@ 2008-09-19 13:38 ` Stefan Roese
2008-09-22 12:13 ` Michael Lawnick
0 siblings, 1 reply; 11+ messages in thread
From: Stefan Roese @ 2008-09-19 13:38 UTC (permalink / raw)
To: u-boot
On Friday 19 September 2008, Michael Lawnick wrote:
> > BTW: Which NOR FLASH driver are you using? The common CFI driver? It has
> > no real connection to the MTD layer which is needed for the UBI port from
> > Kyungmin. Did you think about this?
>
> We are using CFI driver for AM29GL512.
> As said we are _planning_ to integrate, i.e. I'm currently gathering
> information. We need r/o access from u-boot to find our kernel and boot it.
> Writing to flash could be done from Linux.
Understood.
> What are the problems to face?
As I mentioned the CFI driver is missing the interface to the MTD layer. This
is available for NAND and OneNAND but missing for NOR in the U-Boot CFI
implementation. It really is not needed right now and such an extension has
to be made carefully since it adds new code which increases the image size of
all boards using this driver. The only option (I can think of) to not
increase the image size for those boards would be to add this MTD connection
via #ifdef's. But this will not help to make the code more readable. :-(
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
^ permalink raw reply [flat|nested] 11+ messages in thread
* [U-Boot] [PATCH] Add MTD core & partition
2008-09-19 13:38 ` Stefan Roese
@ 2008-09-22 12:13 ` Michael Lawnick
0 siblings, 0 replies; 11+ messages in thread
From: Michael Lawnick @ 2008-09-22 12:13 UTC (permalink / raw)
To: u-boot
Stefan Roese <sr <at> denx.de> writes:
>
> On Friday 19 September 2008, Michael Lawnick wrote:
> > > BTW: Which NOR FLASH driver are you using? The common CFI driver? It has
> > > no real connection to the MTD layer which is needed for the UBI port from
> > > Kyungmin. Did you think about this?
> >
> > We are using CFI driver for AM29GL512.
> > As said we are _planning_ to integrate, i.e. I'm currently gathering
> > information. We need r/o access from u-boot to find our kernel and boot it.
> > Writing to flash could be done from Linux.
>
> Understood.
>
> > What are the problems to face?
>
> As I mentioned the CFI driver is missing the interface to the MTD layer. This
> is available for NAND and OneNAND but missing for NOR in the U-Boot CFI
> implementation. It really is not needed right now and such an extension has
> to be made carefully since it adds new code which increases the image size of
> all boards using this driver. The only option (I can think of) to not
> increase the image size for those boards would be to add this MTD connection
> via #ifdef's. But this will not help to make the code more readable.
>
Hmm, seems I've got some problems to understand.
If there is a clearly defined API (which I haven't found yet) it should be
independent from H/W (NAND/NOR/SRAM/...) IMHO. If not, UBI will be NAND-only :-(
Could you give me a kick into the right direction, so I will find e.g. a .h file
where the functions are listed that have to be supported by H/W-layer driver?
#ifdef's could be avoided by using a different sort of driver for the same H/W,
e.g. cfi_flash and cfi_ubi_flash.
Kind regards,
Michael
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-09-22 12:13 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-29 8:13 [U-Boot] [PATCH] Add MTD core & partition Kyungmin Park
2008-09-06 22:13 ` Wolfgang Denk
2008-09-07 23:28 ` Kyungmin Park
2008-09-08 7:35 ` Stefan Roese
2008-09-08 19:30 ` Scott Wood
2008-09-09 1:15 ` Kyungmin Park
2008-09-19 12:31 ` Michael Lawnick
2008-09-19 13:07 ` Stefan Roese
2008-09-19 13:24 ` Michael Lawnick
2008-09-19 13:38 ` Stefan Roese
2008-09-22 12:13 ` Michael Lawnick
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox