diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/mtdcore.c | 44 | ||||
-rw-r--r-- | drivers/mtd/mtdpart.c | 16 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 245 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 19 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_ecc.c | 17 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_util.c | 159 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 1 |
7 files changed, 126 insertions, 375 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 6eb52ed..a195dda 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -142,3 +142,47 @@ void put_mtd_device(struct mtd_info *mtd) c = --mtd->usecount; BUG_ON(c < 0); } + +#if defined(CONFIG_CMD_MTDPARTS_SPREAD) +/** + * mtd_get_len_incl_bad + * + * Check if length including bad blocks fits into device. + * + * @param mtd an MTD device + * @param offset offset in flash + * @param length image length + * @return image length including bad blocks in *len_incl_bad and whether or not + * the length returned was truncated in *truncated + */ +void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset, + const uint64_t length, uint64_t *len_incl_bad, + int *truncated) +{ + *truncated = 0; + *len_incl_bad = 0; + + if (!mtd->block_isbad) { + *len_incl_bad = length; + return; + } + + uint64_t len_excl_bad = 0; + uint64_t block_len; + + while (len_excl_bad < length) { + if (offset >= mtd->size) { + *truncated = 1; + return; + } + + block_len = mtd->erasesize - (offset & (mtd->erasesize - 1)); + + if (!mtd->block_isbad(mtd, offset & ~(mtd->erasesize - 1))) + len_excl_bad += block_len; + + *len_incl_bad += block_len; + offset += block_len; + } +} +#endif /* defined(CONFIG_CMD_MTDPARTS_SPREAD) */ diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index e2e43ea..f647e43 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -230,18 +230,6 @@ static void part_sync(struct mtd_info *mtd) part->master->sync(part->master); } -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); -} - static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) { struct mtd_part *part = PART(mtd); @@ -339,10 +327,6 @@ static struct mtd_part *add_one_partition(struct mtd_info *master, slave->mtd.get_fact_prot_info = part_get_fact_prot_info; if (master->sync) slave->mtd.sync = part_sync; - if (!partno && master->suspend && master->resume) { - slave->mtd.suspend = part_suspend; - slave->mtd.resume = part_resume; - } if (master->lock) slave->mtd.lock = part_lock; if (master->unlock) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7d17846..21cc5a3 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -32,30 +32,6 @@ * */ -/* XXX U-BOOT XXX */ -#if 0 -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/nand.h> -#include <linux/mtd/nand_ecc.h> -#include <linux/mtd/compatmac.h> -#include <linux/interrupt.h> -#include <linux/bitops.h> -#include <linux/leds.h> -#include <asm/io.h> - -#ifdef CONFIG_MTD_PARTITIONS -#include <linux/mtd/partitions.h> -#endif - -#endif - #include <common.h> #define ENOTSUPP 524 /* Operation is not supported */ @@ -75,10 +51,6 @@ #include <asm/io.h> #include <asm/errno.h> -#ifdef CONFIG_JFFS2_NAND -#include <jffs2/jffs2.h> -#endif - /* * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting * a flash. NAND flash is initialized prior to interrupts so standard timers @@ -143,44 +115,17 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, static int nand_wait(struct mtd_info *mtd, struct nand_chip *this); -/* - * For devices which display every fart in the system on a separate LED. Is - * compiled away when LED support is disabled. - */ -/* XXX U-BOOT XXX */ -#if 0 -DEFINE_LED_TRIGGER(nand_led_trigger); -#endif - /** * nand_release_device - [GENERIC] release chip * @mtd: MTD device structure * * Deselect, release chip lock and wake up anyone waiting on the device */ -/* XXX U-BOOT XXX */ -#if 0 -static void nand_release_device(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - /* De-select the NAND device */ - chip->select_chip(mtd, -1); - - /* Release the controller and the chip */ - spin_lock(&chip->controller->lock); - chip->controller->active = NULL; - chip->state = FL_READY; - wake_up(&chip->controller->wq); - spin_unlock(&chip->controller->lock); -} -#else static void nand_release_device (struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; this->select_chip(mtd, -1); /* De-select the NAND device */ } -#endif /** * nand_read_byte - [DEFAULT] read one byte from the chip @@ -490,24 +435,6 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, * Wait for the ready pin, after a command * The timeout is catched later. */ -/* XXX U-BOOT XXX */ -#if 0 -void nand_wait_ready(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - unsigned long timeo = jiffies + 2; - - led_trigger_event(nand_led_trigger, LED_FULL); - /* wait until command is processed or timeout occures */ - do { - if (chip->dev_ready(mtd)) - break; - touch_softlockup_watchdog(); - } while (time_before(jiffies, timeo)); - led_trigger_event(nand_led_trigger, LED_OFF); -} -EXPORT_SYMBOL_GPL(nand_wait_ready); -#else void nand_wait_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; @@ -522,7 +449,6 @@ void nand_wait_ready(struct mtd_info *mtd) break; } } -#endif /** * nand_command - [DEFAULT] Send command to NAND device @@ -759,45 +685,11 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, * * Get the device and lock it for exclusive access */ -/* XXX U-BOOT XXX */ -#if 0 -static int -nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) -{ - spinlock_t *lock = &chip->controller->lock; - wait_queue_head_t *wq = &chip->controller->wq; - DECLARE_WAITQUEUE(wait, current); - retry: - spin_lock(lock); - - /* Hardware controller shared among independend devices */ - /* Hardware controller shared among independend devices */ - if (!chip->controller->active) - chip->controller->active = chip; - - if (chip->controller->active == chip && chip->state == FL_READY) { - chip->state = new_state; - spin_unlock(lock); - return 0; - } - if (new_state == FL_PM_SUSPENDED) { - spin_unlock(lock); - return (chip->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; - } - set_current_state(TASK_UNINTERRUPTIBLE); - add_wait_queue(wq, &wait); - spin_unlock(lock); - schedule(); - remove_wait_queue(wq, &wait); - goto retry; -} -#else static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) { this->state = new_state; return 0; } -#endif /** * nand_wait - [DEFAULT] wait until the command is done @@ -808,46 +700,6 @@ static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int ne * Erase can take up to 400ms and program up to 20ms according to * general NAND and SmartMedia specs */ -/* XXX U-BOOT XXX */ -#if 0 -static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) -{ - - unsigned long timeo = jiffies; - int status, state = chip->state; - - if (state == FL_ERASING) - timeo += (HZ * 400) / 1000; - else - timeo += (HZ * 20) / 1000; - - led_trigger_event(nand_led_trigger, LED_FULL); - - /* Apply this short delay always to ensure that we do wait tWB in - * any case on any machine. */ - ndelay(100); - - if ((state == FL_ERASING) && (chip->options & NAND_IS_AND)) - chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); - else - chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); - - while (time_before(jiffies, timeo)) { - if (chip->dev_ready) { - if (chip->dev_ready(mtd)) - break; - } else { - if (chip->read_byte(mtd) & NAND_STATUS_READY) - break; - } - cond_resched(); - } - led_trigger_event(nand_led_trigger, LED_OFF); - - status = (int)chip->read_byte(mtd); - return status; -} -#else static int nand_wait(struct mtd_info *mtd, struct nand_chip *this) { unsigned long timeo; @@ -886,7 +738,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this) return this->read_byte(mtd); } -#endif /** * nand_read_page_raw - [Intern] read raw page data without ecc @@ -2001,13 +1852,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, if (!writelen) return 0; - /* reject writes, which are not page aligned */ - if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { - printk(KERN_NOTICE "nand_write: " - "Attempt to write not page aligned data\n"); - return -EINVAL; - } - column = to & (mtd->writesize - 1); subpage = column || (writelen & (mtd->writesize - 1)); @@ -2523,32 +2367,6 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) return chip->block_markbad(mtd, ofs); } -/** - * nand_suspend - [MTD Interface] Suspend the NAND flash - * @mtd: MTD device structure - */ -static int nand_suspend(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - return nand_get_device(chip, mtd, FL_PM_SUSPENDED); -} - -/** - * nand_resume - [MTD Interface] Resume the NAND flash - * @mtd: MTD device structure - */ -static void nand_resume(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - if (chip->state == FL_PM_SUSPENDED) - nand_release_device(mtd); - else - printk(KERN_ERR "nand_resume() called for a chip which is not " - "in suspended state\n"); -} - /* * Set default functions */ @@ -2584,17 +2402,8 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; if (!chip->scan_bbt) chip->scan_bbt = nand_default_bbt; - - if (!chip->controller) { + if (!chip->controller) chip->controller = &chip->hwcontrol; - - /* XXX U-BOOT XXX */ -#if 0 - spin_lock_init(&chip->controller->lock); - init_waitqueue_head(&chip->controller->wq); -#endif - } - } /* @@ -3028,8 +2837,6 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->sync = nand_sync; mtd->lock = NULL; mtd->unlock = NULL; - mtd->suspend = nand_suspend; - mtd->resume = nand_resume; mtd->block_isbad = nand_block_isbad; mtd->block_markbad = nand_block_markbad; @@ -3043,16 +2850,6 @@ int nand_scan_tail(struct mtd_info *mtd) return 0; } -/* module_text_address() isn't exported, and it's mostly a pointless - test if this is a module _anyway_ -- they'd have to try _really_ hard - to call us from in-kernel code if the core NAND support is modular. */ -#ifdef MODULE -#define caller_is_module() (1) -#else -#define caller_is_module() \ - module_text_address((unsigned long)__builtin_return_address(0)) -#endif - /** * nand_scan - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure @@ -3069,15 +2866,6 @@ int nand_scan(struct mtd_info *mtd, int maxchips) { int ret; - /* Many callers got this wrong, so check for it for a while... */ - /* XXX U-BOOT XXX */ -#if 0 - if (!mtd->owner && caller_is_module()) { - printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); - BUG(); - } -#endif - ret = nand_scan_ident(mtd, maxchips); if (!ret) ret = nand_scan_tail(mtd); @@ -3096,40 +2884,9 @@ void nand_release(struct mtd_info *mtd) /* Deregister partitions */ del_mtd_partitions(mtd); #endif - /* Deregister the device */ - /* XXX U-BOOT XXX */ -#if 0 - del_mtd_device(mtd); -#endif /* Free bad block table memory */ kfree(chip->bbt); if (!(chip->options & NAND_OWN_BUFFERS)) kfree(chip->buffers); } - -/* XXX U-BOOT XXX */ -#if 0 -EXPORT_SYMBOL_GPL(nand_scan); -EXPORT_SYMBOL_GPL(nand_scan_ident); -EXPORT_SYMBOL_GPL(nand_scan_tail); -EXPORT_SYMBOL_GPL(nand_release); - -static int __init nand_base_init(void) -{ - led_trigger_register_simple("nand-disk", &nand_led_trigger); - return 0; -} - -static void __exit nand_base_exit(void) -{ - led_trigger_unregister_simple(nand_led_trigger); -} - -module_init(nand_base_init); -module_exit(nand_base_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); -MODULE_DESCRIPTION("Generic NAND flash driver code"); -#endif diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 2fe68ab..521ddde 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -58,19 +58,6 @@ #include <asm/errno.h> -/* XXX U-BOOT XXX */ -#if 0 -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/nand.h> -#include <linux/mtd/nand_ecc.h> -#include <linux/mtd/compatmac.h> -#include <linux/bitops.h> -#include <linux/delay.h> -#include <linux/vmalloc.h> -#endif - /** * check_pattern - [GENERIC] check if a pattern is in the buffer * @buf: the buffer to search @@ -1231,9 +1218,3 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) } return 1; } - -/* XXX U-BOOT XXX */ -#if 0 -EXPORT_SYMBOL(nand_scan_bbt); -EXPORT_SYMBOL(nand_default_bbt); -#endif diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 463f9cb..52bc916 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -37,14 +37,6 @@ #include <common.h> -/* XXX U-BOOT XXX */ -#if 0 -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mtd/nand_ecc.h> -#endif - #include <asm/errno.h> #include <linux/mtd/mtd.h> @@ -140,10 +132,6 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, return 0; } -/* XXX U-BOOT XXX */ -#if 0 -EXPORT_SYMBOL(nand_calculate_ecc); -#endif #endif /* CONFIG_NAND_SPL */ static inline int countbits(uint32_t byte) @@ -212,8 +200,3 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, return -EBADMSG; } - -/* XXX U-BOOT XXX */ -#if 0 -EXPORT_SYMBOL(nand_correct_data); -#endif diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 29c42f7..22c7411 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -28,6 +28,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * + * Copyright 2010 Freescale Semiconductor + * The portions of this file whose copyright is held by Freescale and which + * are not considered a derived work of GPL v2-only code may be distributed + * and/or modified 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. */ #include <common.h> @@ -69,7 +75,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) { struct jffs2_unknown_node cleanmarker; erase_info_t erase; - ulong erase_length; + unsigned long erase_length, erased_length; /* in blocks */ int bbtest = 1; int result; int percent_complete = -1; @@ -78,13 +84,19 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) struct mtd_oob_ops oob_opts; struct nand_chip *chip = meminfo->priv; + if ((opts->offset & (meminfo->writesize - 1)) != 0) { + printf("Attempt to erase non page aligned data\n"); + return -1; + } + memset(&erase, 0, sizeof(erase)); memset(&oob_opts, 0, sizeof(oob_opts)); erase.mtd = meminfo; erase.len = meminfo->erasesize; erase.addr = opts->offset; - erase_length = opts->length; + erase_length = lldiv(opts->length + meminfo->erasesize - 1, + meminfo->erasesize); cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); @@ -108,15 +120,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) priv_nand->bbt = NULL; } - if (erase_length < meminfo->erasesize) { - printf("Warning: Erase size 0x%08lx smaller than one " \ - "erase block 0x%08x\n",erase_length, meminfo->erasesize); - printf(" Erasing 0x%08x instead\n", meminfo->erasesize); - erase_length = meminfo->erasesize; - } - - for (; - erase.addr < opts->offset + erase_length; + for (erased_length = 0; + erased_length < erase_length; erase.addr += meminfo->erasesize) { WATCHDOG_RESET (); @@ -129,6 +134,10 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) "0x%08llx " " \n", erase.addr); + + if (!opts->spread) + erased_length++; + continue; } else if (ret < 0) { @@ -139,6 +148,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) } } + erased_length++; + result = meminfo->erase(meminfo, &erase); if (result != 0) { printf("\n%s: MTD Erase failure: %d\n", @@ -165,9 +176,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) } if (!opts->quiet) { - unsigned long long n =(unsigned long long) - (erase.addr + meminfo->erasesize - opts->offset) - * 100; + unsigned long long n = erased_length * 100ULL; int percent; do_div(n, erase_length); @@ -202,41 +211,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) return 0; } -/* XXX U-BOOT XXX */ -#if 0 - -#define MAX_PAGE_SIZE 2048 -#define MAX_OOB_SIZE 64 - -/* - * buffer array used for writing data - */ -static unsigned char data_buf[MAX_PAGE_SIZE]; -static unsigned char oob_buf[MAX_OOB_SIZE]; - -/* OOB layouts to pass into the kernel as default */ -static struct nand_ecclayout none_ecclayout = { - .useecc = MTD_NANDECC_OFF, -}; - -static struct nand_ecclayout jffs2_ecclayout = { - .useecc = MTD_NANDECC_PLACE, - .eccbytes = 6, - .eccpos = { 0, 1, 2, 3, 6, 7 } -}; - -static struct nand_ecclayout yaffs_ecclayout = { - .useecc = MTD_NANDECC_PLACE, - .eccbytes = 6, - .eccpos = { 8, 9, 10, 13, 14, 15} -}; - -static struct nand_ecclayout autoplace_ecclayout = { - .useecc = MTD_NANDECC_AUTOPLACE -}; -#endif - -/* XXX U-BOOT XXX */ #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK /****************************************************************************** @@ -423,36 +397,43 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) #endif /** - * get_len_incl_bad + * check_skip_len * - * Check if length including bad blocks fits into device. + * Check if there are any bad blocks, and whether length including bad + * blocks fits into device * * @param nand NAND device * @param offset offset in flash * @param length image length - * @return image length including bad blocks + * @return 0 if the image fits and there are no bad blocks + * 1 if the image fits, but there are bad blocks + * -1 if the image does not fit */ -static size_t get_len_incl_bad (nand_info_t *nand, loff_t offset, - const size_t length) +static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length) { - size_t len_incl_bad = 0; size_t len_excl_bad = 0; - size_t block_len; + int ret = 0; while (len_excl_bad < length) { - block_len = nand->erasesize - (offset & (nand->erasesize - 1)); + size_t block_len, block_off; + loff_t block_start; - if (!nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) - len_excl_bad += block_len; + if (offset >= nand->size) + return -1; - len_incl_bad += block_len; - offset += block_len; + block_start = offset & ~(loff_t)(nand->erasesize - 1); + block_off = offset & (nand->erasesize - 1); + block_len = nand->erasesize - block_off; - if (offset >= nand->size) - break; + if (!nand_block_isbad(nand, block_start)) + len_excl_bad += block_len; + else + ret = 1; + + offset += block_len; } - return len_incl_bad; + return ret; } /** @@ -474,29 +455,41 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, { int rval; size_t left_to_write = *length; - size_t len_incl_bad; u_char *p_buffer = buffer; + int need_skip; - /* Reject writes, which are not page aligned */ - if ((offset & (nand->writesize - 1)) != 0 || - (*length & (nand->writesize - 1)) != 0) { + /* + * nand_write() handles unaligned, partial page writes. + * + * We allow length to be unaligned, for convenience in + * using the $filesize variable. + * + * However, starting at an unaligned offset makes the + * semantics of bad block skipping ambiguous (really, + * you should only start a block skipping access at a + * partition boundary). So don't try to handle that. + */ + if ((offset & (nand->writesize - 1)) != 0) { printf ("Attempt to write non page aligned data\n"); + *length = 0; return -EINVAL; } - len_incl_bad = get_len_incl_bad (nand, offset, *length); - - if ((offset + len_incl_bad) > nand->size) { + need_skip = check_skip_len(nand, offset, *length); + if (need_skip < 0) { printf ("Attempt to write outside the flash area\n"); + *length = 0; return -EINVAL; } - if (len_incl_bad == *length) { + if (!need_skip) { rval = nand_write (nand, offset, length, buffer); - if (rval != 0) - printf ("NAND write to offset %llx failed %d\n", - offset, rval); + if (rval == 0) + return 0; + *length = 0; + printf ("NAND write to offset %llx failed %d\n", + offset, rval); return rval; } @@ -553,20 +546,28 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, { int rval; size_t left_to_read = *length; - size_t len_incl_bad; u_char *p_buffer = buffer; + int need_skip; - len_incl_bad = get_len_incl_bad (nand, offset, *length); + if ((offset & (nand->writesize - 1)) != 0) { + printf ("Attempt to read non page aligned data\n"); + *length = 0; + return -EINVAL; + } - if ((offset + len_incl_bad) > nand->size) { + need_skip = check_skip_len(nand, offset, *length); + if (need_skip < 0) { printf ("Attempt to read outside the flash area\n"); + *length = 0; return -EINVAL; } - if (len_incl_bad == *length) { + if (!need_skip) { rval = nand_read (nand, offset, length, buffer); if (!rval || rval == -EUCLEAN) return 0; + + *length = 0; printf ("NAND read from offset %llx failed %d\n", offset, rval); return rval; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index f9273ab..24e02c2 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -2213,6 +2213,7 @@ char *onenand_print_device_info(int device, int version) } static const struct onenand_manufacturers onenand_manuf_ids[] = { + {ONENAND_MFR_NUMONYX, "Numonyx"}, {ONENAND_MFR_SAMSUNG, "Samsung"}, }; |