From 832215e3ebc89b4558d3bb0075f938b9094a7923 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 20 May 2006 16:13:34 +0100 Subject: [PATCH] --- yaml --- r: 27809 b: refs/heads/master c: 9641b784ff82cf0a48a6c70ef9867f5fd728de67 h: refs/heads/master i: 27807: c61e7148ac7dba2715b060289b65d59938866edd v: v3 --- [refs] | 2 +- trunk/drivers/mtd/chips/gen_probe.c | 6 +- trunk/drivers/mtd/devices/docprobe.c | 47 +++++- trunk/drivers/mtd/nand/Kconfig | 6 - trunk/drivers/mtd/nand/Makefile | 1 - trunk/drivers/mtd/nand/ams-delta.c | 238 --------------------------- trunk/fs/jffs2/scan.c | 74 +++++++-- trunk/fs/jffs2/summary.c | 36 +--- trunk/fs/jffs2/summary.h | 3 +- 9 files changed, 110 insertions(+), 303 deletions(-) delete mode 100644 trunk/drivers/mtd/nand/ams-delta.c diff --git a/[refs] b/[refs] index f88e915f41d1..75ef76d9950f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 615191bb1dfc6980e7c7a85225444d860d74b343 +refs/heads/master: 9641b784ff82cf0a48a6c70ef9867f5fd728de67 diff --git a/trunk/drivers/mtd/chips/gen_probe.c b/trunk/drivers/mtd/chips/gen_probe.c index cdb0f590b40c..00ca6f591202 100644 --- a/trunk/drivers/mtd/chips/gen_probe.c +++ b/trunk/drivers/mtd/chips/gen_probe.c @@ -207,14 +207,14 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, struct cfi_private *cfi = map->fldrv_priv; __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; #ifdef CONFIG_MODULES - char probename[16+sizeof(MODULE_SYMBOL_PREFIX)]; + char probename[32]; cfi_cmdset_fn_t *probe_function; - sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type); + sprintf(probename, "cfi_cmdset_%4.4X", type); probe_function = __symbol_get(probename); if (!probe_function) { - request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1); + request_module(probename); probe_function = __symbol_get(probename); } diff --git a/trunk/drivers/mtd/devices/docprobe.c b/trunk/drivers/mtd/devices/docprobe.c index 593bb033a3fa..dce4c904b636 100644 --- a/trunk/drivers/mtd/devices/docprobe.c +++ b/trunk/drivers/mtd/devices/docprobe.c @@ -231,9 +231,26 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr static int docfound; +#ifdef CONFIG_MTD_DOC2000 extern void DoC2k_init(struct mtd_info *); +#define doc2k_initfunc (&DoC2k_init) +#else +#define doc2k_initfunc NULL +#endif + +#ifdef CONFIG_MTD_DOC2001 extern void DoCMil_init(struct mtd_info *); +#define docmil_initfunc (&DoCMil_init) +#else +#define docmil_initfunc NULL +#endif + +#ifdef CONFIG_MTD_DOC2001PLUS extern void DoCMilPlus_init(struct mtd_info *); +#define docmplus_initfunc (&DoCMilPlus_init) +#else +#define docmplus_initfunc NULL +#endif static void __init DoC_Probe(unsigned long physadr) { @@ -243,6 +260,8 @@ static void __init DoC_Probe(unsigned long physadr) int ChipID; char namebuf[15]; char *name = namebuf; + char *im_funcname = NULL; + char *im_modname = NULL; void (*initroutine)(struct mtd_info *) = NULL; docptr = ioremap(physadr, DOC_IOREMAP_LEN); @@ -280,30 +299,48 @@ static void __init DoC_Probe(unsigned long physadr) switch(ChipID) { case DOC_ChipID_Doc2kTSOP: name="2000 TSOP"; - initroutine = symbol_request(DoC2k_init); + im_funcname = "DoC2k_init"; + im_modname = "doc2000"; + initroutine = doc2k_initfunc; break; case DOC_ChipID_Doc2k: name="2000"; - initroutine = symbol_request(DoC2k_init); + im_funcname = "DoC2k_init"; + im_modname = "doc2000"; + initroutine = doc2k_initfunc; break; case DOC_ChipID_DocMil: name="Millennium"; #ifdef DOC_SINGLE_DRIVER - initroutine = symbol_request(DoC2k_init); + im_funcname = "DoC2k_init"; + im_modname = "doc2000"; + initroutine = doc2k_initfunc; #else - initroutine = symbol_request(DoCMil_init); + im_funcname = "DoCMil_init"; + im_modname = "doc2001"; + initroutine = docmil_initfunc; #endif /* DOC_SINGLE_DRIVER */ break; case DOC_ChipID_DocMilPlus16: case DOC_ChipID_DocMilPlus32: name="MillenniumPlus"; - initroutine = symbol_request(DoCMilPlus_init); + im_funcname = "DoCMilPlus_init"; + im_modname = "doc2001plus"; + initroutine = docmplus_initfunc; break; } +#ifdef CONFIG_MODULES + if (im_funcname && !initroutine) + initroutine = __symbol_get(im_funcname); + if (im_funcname && !initroutine) { + request_module(im_modname); + initroutine = __symbol_get(im_funcname); + } +#endif if (initroutine) { (*initroutine)(mtd); symbol_put_addr(initroutine); diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index 2d0ebad55a49..b1f807980b79 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -49,12 +49,6 @@ config MTD_NAND_SPIA help If you had to ask, you don't have one. Say 'N'. -config MTD_NAND_AMS_DELTA - tristate "NAND Flash device on Amstrad E3" - depends on MACH_AMS_DELTA && MTD_NAND - help - Support for NAND flash on Amstrad E3 (Delta). - config MTD_NAND_TOTO tristate "NAND Flash device on TOTO board" depends on ARCH_OMAP && MTD_NAND diff --git a/trunk/drivers/mtd/nand/Makefile b/trunk/drivers/mtd/nand/Makefile index 33475087dbff..0741d739cb87 100644 --- a/trunk/drivers/mtd/nand/Makefile +++ b/trunk/drivers/mtd/nand/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o obj-$(CONFIG_MTD_NAND_SPIA) += spia.o -obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o obj-$(CONFIG_MTD_NAND_TOTO) += toto.o obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o diff --git a/trunk/drivers/mtd/nand/ams-delta.c b/trunk/drivers/mtd/nand/ams-delta.c deleted file mode 100644 index 5a349eb316f5..000000000000 --- a/trunk/drivers/mtd/nand/ams-delta.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * drivers/mtd/nand/ams-delta.c - * - * Copyright (C) 2006 Jonathan McDowell - * - * Derived from drivers/mtd/toto.c - * - * 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. - * - * Overview: - * This is a device driver for the NAND flash device found on the - * Amstrad E3 (Delta). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * MTD structure for E3 (Delta) - */ -static struct mtd_info *ams_delta_mtd = NULL; - -#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP) - -#define T_NAND_CTL_CLRALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, 0) -#define T_NAND_CTL_SETALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, AMS_DELTA_LATCH2_NAND_ALE) -#define T_NAND_CTL_CLRCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, 0) -#define T_NAND_CTL_SETCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, AMS_DELTA_LATCH2_NAND_CLE) -#define T_NAND_CTL_SETNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, 0) -#define T_NAND_CTL_CLRNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, AMS_DELTA_LATCH2_NAND_NCE) - -/* - * Define partitions for flash devices - */ - -static struct mtd_partition partition_info[] = { - { .name = "Kernel", - .offset = 0, - .size = 3 * SZ_1M + SZ_512K }, - { .name = "u-boot", - .offset = 3 * SZ_1M + SZ_512K, - .size = SZ_256K }, - { .name = "u-boot params", - .offset = 3 * SZ_1M + SZ_512K + SZ_256K, - .size = SZ_256K }, - { .name = "Amstrad LDR", - .offset = 4 * SZ_1M, - .size = SZ_256K }, - { .name = "File system", - .offset = 4 * SZ_1M + 1 * SZ_256K, - .size = 27 * SZ_1M }, - { .name = "PBL reserved", - .offset = 32 * SZ_1M - 3 * SZ_256K, - .size = 3 * SZ_256K }, -}; - -/* - * hardware specific access to control-lines -*/ - -static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd) -{ - switch (cmd) { - - case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break; - case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break; - - case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break; - case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break; - - case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break; - case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break; - } -} - -static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) -{ - struct nand_chip *this = mtd->priv; - - omap_writew(0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL)); - omap_writew(byte, this->IO_ADDR_W); - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0); - ndelay(40); - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, - AMS_DELTA_LATCH2_NAND_NWE); -} - -static u_char ams_delta_read_byte(struct mtd_info *mtd) -{ - u_char res; - struct nand_chip *this = mtd->priv; - - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0); - ndelay(40); - omap_writew(~0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL)); - res = omap_readw(this->IO_ADDR_R); - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, - AMS_DELTA_LATCH2_NAND_NRE); - - return res; -} - -static void ams_delta_write_buf(struct mtd_info *mtd, const u_char *buf, - int len) -{ - int i; - - for (i=0; iowner = THIS_MODULE; - - /* Get pointer to private data */ - this = (struct nand_chip *) (&ams_delta_mtd[1]); - - /* Initialize structures */ - memset(ams_delta_mtd, 0, sizeof(struct mtd_info)); - memset(this, 0, sizeof(struct nand_chip)); - - /* Link the private data with the MTD structure */ - ams_delta_mtd->priv = this; - - /* Set address of NAND IO lines */ - this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH); - this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT); - this->read_byte = ams_delta_read_byte; - this->write_byte = ams_delta_write_byte; - this->write_buf = ams_delta_write_buf; - this->read_buf = ams_delta_read_buf; - this->verify_buf = ams_delta_verify_buf; - this->hwcontrol = ams_delta_hwcontrol; - if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) { - this->dev_ready = ams_delta_nand_ready; - } else { - this->dev_ready = NULL; - printk(KERN_NOTICE "Couldn't request gpio for Delta NAND ready.\n"); - } - /* 25 us command delay time */ - this->chip_delay = 30; - this->eccmode = NAND_ECC_SOFT; - - /* Set chip enabled, but */ - ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE | - AMS_DELTA_LATCH2_NAND_NWE | - AMS_DELTA_LATCH2_NAND_NCE | - AMS_DELTA_LATCH2_NAND_NWP); - - /* Scan to find existance of the device */ - if (nand_scan(ams_delta_mtd, 1)) { - err = -ENXIO; - goto out_mtd; - } - - /* Register the partitions */ - add_mtd_partitions(ams_delta_mtd, partition_info, - ARRAY_SIZE(partition_info)); - - goto out; - - out_mtd: - kfree(ams_delta_mtd); - out: - return err; -} - -module_init(ams_delta_init); - -/* - * Clean up routine - */ -static void __exit ams_delta_cleanup(void) -{ - /* Release resources, unregister device */ - nand_release(ams_delta_mtd); - - /* Free the MTD device structure */ - kfree(ams_delta_mtd); -} -module_exit(ams_delta_cleanup); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jonathan McDowell "); -MODULE_DESCRIPTION("Glue layer for NAND flash on Amstrad E3 (Delta)"); diff --git a/trunk/fs/jffs2/scan.c b/trunk/fs/jffs2/scan.c index 352ada892f3e..2a24b44662bb 100644 --- a/trunk/fs/jffs2/scan.c +++ b/trunk/fs/jffs2/scan.c @@ -306,11 +306,12 @@ int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *je return BLK_STATE_ALLDIRTY; } +/* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into + the flash, XIP-style */ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) { + unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) { struct jffs2_unknown_node *node; struct jffs2_unknown_node crcnode; - struct jffs2_sum_marker *sm; uint32_t ofs, prevofs; uint32_t hdr_crc, buf_ofs, buf_len; int err; @@ -344,32 +345,69 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo #endif if (jffs2_sum_active()) { - sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL); - if (!sm) { - return -ENOMEM; - } + struct jffs2_sum_marker *sm; + void *sumptr = NULL; + uint32_t sumlen; + + if (!buf_size) { + /* XIP case. Just look, point at the summary if it's there */ + sm = (void *)buf + jeb->offset - sizeof(*sm); + if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { + sumptr = buf + je32_to_cpu(sm->offset); + sumlen = c->sector_size - je32_to_cpu(sm->offset); + } + } else { + /* If NAND flash, read a whole page of it. Else just the end */ + if (c->wbuf_pagesize) + buf_len = c->wbuf_pagesize; + else + buf_len = sizeof(*sm); + + /* Read as much as we want into the _end_ of the preallocated buffer */ + err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, + jeb->offset + c->sector_size - buf_len, + buf_len); + if (err) + return err; + + sm = (void *)buf + buf_size - sizeof(*sm); + if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC) { + sumlen = c->sector_size - je32_to_cpu(sm->offset); + sumptr = buf + buf_size - sumlen; + + /* Now, make sure the summary itself is available */ + if (sumlen > buf_size) { + /* Need to kmalloc for this. */ + sumptr = kmalloc(sumlen, GFP_KERNEL); + if (!sumptr) + return -ENOMEM; + memcpy(sumptr + sumlen - buf_len, buf + buf_size - buf_len, buf_len); + } + if (buf_len < sumlen) { + /* Need to read more so that the entire summary node is present */ + err = jffs2_fill_scan_buf(c, sumptr, + jeb->offset + c->sector_size - sumlen, + sumlen - buf_len); + if (err) + return err; + } + } - err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size - - sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker)); - if (err) { - kfree(sm); - return err; } - if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) { - err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random); - if (err) { - kfree(sm); + if (sumptr) { + err = jffs2_sum_scan_sumnode(c, jeb, sumptr, sumlen, &pseudo_random); + if (err) return err; - } + if (buf_size && sumlen > buf_size) + kfree(sumptr); } - - kfree(sm); } buf_ofs = jeb->offset; if (!buf_size) { + /* This is the XIP case -- we're reading _directly_ from the flash chip */ buf_len = c->sector_size; } else { buf_len = EMPTY_SCAN_SIZE(c->sector_size); diff --git a/trunk/fs/jffs2/summary.c b/trunk/fs/jffs2/summary.c index 48293c197f13..82a3706c54d8 100644 --- a/trunk/fs/jffs2/summary.c +++ b/trunk/fs/jffs2/summary.c @@ -318,7 +318,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras raw = jffs2_alloc_raw_node_ref(); if (!raw) { JFFS2_NOTICE("allocation of node reference failed\n"); - kfree(summary); return -ENOMEM; } @@ -326,7 +325,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras if (!ic) { JFFS2_NOTICE("scan_make_ino_cache failed\n"); jffs2_free_raw_node_ref(raw); - kfree(summary); return -ENOMEM; } @@ -358,10 +356,8 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras jeb->offset + je32_to_cpu(spd->offset)); fd = jffs2_alloc_full_dirent(spd->nsize+1); - if (!fd) { - kfree(summary); + if (!fd) return -ENOMEM; - } memcpy(&fd->name, spd->name, spd->nsize); fd->name[spd->nsize] = 0; @@ -370,7 +366,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras if (!raw) { jffs2_free_full_dirent(fd); JFFS2_NOTICE("allocation of node reference failed\n"); - kfree(summary); return -ENOMEM; } @@ -378,7 +373,6 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras if (!ic) { jffs2_free_full_dirent(fd); jffs2_free_raw_node_ref(raw); - kfree(summary); return -ENOMEM; } @@ -411,45 +405,28 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras default : { JFFS2_WARNING("Unsupported node type found in summary! Exiting..."); - kfree(summary); return -EIO; } } } - kfree(summary); return 0; } /* Process the summary node - called from jffs2_scan_eraseblock() */ - int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - uint32_t ofs, uint32_t *pseudo_random) + struct jffs2_raw_summary *summary, uint32_t sumsize, + uint32_t *pseudo_random) { struct jffs2_unknown_node crcnode; struct jffs2_raw_node_ref *cache_ref; - struct jffs2_raw_summary *summary; - int ret, sumsize; + int ret, ofs; uint32_t crc; - sumsize = c->sector_size - ofs; - ofs += jeb->offset; + ofs = jeb->offset + c->sector_size - sumsize; dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", - jeb->offset, ofs, sumsize); - - summary = kmalloc(sumsize, GFP_KERNEL); - - if (!summary) { - return -ENOMEM; - } - - ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize); - - if (ret) { - kfree(summary); - return ret; - } + jeb->offset, ofs, sumsize); /* OK, now check for node validity and CRC */ crcnode.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -499,7 +476,6 @@ int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb if (!marker_ref) { JFFS2_NOTICE("Failed to allocate node ref for clean marker\n"); - kfree(summary); return -ENOMEM; } diff --git a/trunk/fs/jffs2/summary.h b/trunk/fs/jffs2/summary.h index b7a678be1709..afff4bd551a1 100644 --- a/trunk/fs/jffs2/summary.h +++ b/trunk/fs/jffs2/summary.h @@ -160,7 +160,8 @@ int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size); int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs); int jffs2_sum_add_dirent_mem(struct jffs2_summary *s, struct jffs2_raw_dirent *rd, uint32_t ofs); int jffs2_sum_scan_sumnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - uint32_t ofs, uint32_t *pseudo_random); + struct jffs2_raw_summary *summary, uint32_t sumlen, + uint32_t *pseudo_random); #else /* SUMMARY DISABLED */