Module Name: src Committed By: ahoka Date: Mon Apr 4 14:25:10 UTC 2011
Modified Files: src/sys/dev/flash: flash.c flash.h src/sys/dev/nand: nand.c nand.h nand_bbt.c nand_bbt.h nand_io.c Log Message: Fix badblock checking Replace flash_addr_t with flash_off_t and use it to address flash everywhere To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/flash/flash.c src/sys/dev/flash/flash.h cvs rdiff -u -r1.6 -r1.7 src/sys/dev/nand/nand.c cvs rdiff -u -r1.4 -r1.5 src/sys/dev/nand/nand.h cvs rdiff -u -r1.1 -r1.2 src/sys/dev/nand/nand_bbt.c \ src/sys/dev/nand/nand_bbt.h src/sys/dev/nand/nand_io.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/flash/flash.c diff -u src/sys/dev/flash/flash.c:1.2 src/sys/dev/flash/flash.c:1.3 --- src/sys/dev/flash/flash.c:1.2 Wed Mar 30 14:34:26 2011 +++ src/sys/dev/flash/flash.c Mon Apr 4 14:25:09 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: flash.c,v 1.2 2011/03/30 14:34:26 uebayasi Exp $ */ +/* $NetBSD: flash.c,v 1.3 2011/04/04 14:25:09 ahoka Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: flash.c,v 1.2 2011/03/30 14:34:26 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: flash.c,v 1.3 2011/04/04 14:25:09 ahoka Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -88,7 +88,7 @@ int flash_nsectors(struct buf *bp); int flash_sector(struct buf *bp); -static inline off_t flash_get_part_offset(struct flash_softc *fl, +static inline flash_off_t flash_get_part_offset(struct flash_softc *fl, size_t poffset); int flash_match(device_t parent, cfdata_t match, void *aux); @@ -405,7 +405,8 @@ struct flash_softc *sc; int unit, err; size_t retlen; - flash_addr_t offset; + flash_off_t offset; + bool bad; unit = minor(dev); if ((sc = device_lookup_private(&flash_cd, unit)) == NULL) @@ -441,15 +442,11 @@ */ bbp = data; - err = flash_block_isbad(sc->sc_dev, bbp->bbp_addr); - if (err == EIO) { - bbp->bbp_isbad = true; - err = 0; - } else if (err) { + err = flash_block_isbad(sc->sc_dev, bbp->bbp_addr, &bad); + if (err) { return err; - } else { - bbp->bbp_isbad = false; } + bbp->bbp_isbad = bad; break; case FLASH_BLOCK_MARKBAD: @@ -548,7 +545,7 @@ return sc->sc_dev; } -static inline off_t +static inline flash_off_t flash_get_part_offset(struct flash_softc *fl, size_t poffset) { return fl->flash_if->partition.part_offset + poffset; @@ -577,7 +574,7 @@ int flash_read(device_t self, - off_t offset, size_t len, size_t *retlen, uint8_t *buf) + flash_off_t offset, size_t len, size_t *retlen, uint8_t *buf) { struct flash_softc *sc = device_private(self); @@ -593,7 +590,7 @@ int flash_write(device_t self, - off_t offset, size_t len, size_t *retlen, const uint8_t *buf) + flash_off_t offset, size_t len, size_t *retlen, const uint8_t *buf) { struct flash_softc *sc = device_private(self); @@ -611,7 +608,7 @@ } int -flash_block_markbad(device_t self, uint64_t offset) +flash_block_markbad(device_t self, flash_off_t offset) { struct flash_softc *sc = device_private(self); @@ -629,7 +626,7 @@ } int -flash_block_isbad(device_t self, uint64_t offset) +flash_block_isbad(device_t self, flash_off_t offset, bool *bad) { struct flash_softc *sc = device_private(self); @@ -640,7 +637,7 @@ sc->flash_if->partition.part_offset) return EINVAL; - return sc->flash_if->block_isbad(device_parent(self), offset); + return sc->flash_if->block_isbad(device_parent(self), offset, bad); } int Index: src/sys/dev/flash/flash.h diff -u src/sys/dev/flash/flash.h:1.2 src/sys/dev/flash/flash.h:1.3 --- src/sys/dev/flash/flash.h:1.2 Wed Mar 30 14:34:26 2011 +++ src/sys/dev/flash/flash.h Mon Apr 4 14:25:09 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: flash.h,v 1.2 2011/03/30 14:34:26 uebayasi Exp $ */ +/* $NetBSD: flash.h,v 1.3 2011/04/04 14:25:09 ahoka Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -73,8 +73,8 @@ * @state: the erase operation's result */ struct flash_erase_instruction { - flash_addr_t ei_addr; - flash_addr_t ei_len; + flash_off_t ei_addr; + flash_off_t ei_len; void (*ei_callback)(struct flash_erase_instruction *); u_long ei_priv; u_char ei_state; @@ -86,8 +86,8 @@ }; struct flash_partition { - flash_addr_t part_offset; - flash_addr_t part_size; + flash_off_t part_offset; + flash_off_t part_size; int part_flags; }; @@ -107,10 +107,10 @@ */ struct flash_interface { int (*erase)(device_t, struct flash_erase_instruction *); - int (*read)(device_t, off_t, size_t, size_t *, uint8_t *); - int (*write)(device_t, off_t, size_t, size_t *, const uint8_t *); - int (*block_markbad)(device_t, uint64_t); - int (*block_isbad)(device_t, uint64_t); + int (*read)(device_t, flash_off_t, size_t, size_t *, uint8_t *); + int (*write)(device_t, flash_off_t, size_t, size_t *, const uint8_t *); + int (*block_markbad)(device_t, flash_off_t); + int (*block_isbad)(device_t, flash_off_t, bool *); int (*sync)(device_t); int (*submit)(device_t, struct buf *); @@ -119,7 +119,7 @@ struct flash_partition partition; /* total size of mtd */ - flash_addr_t size; + flash_size_t size; uint32_t page_size; uint32_t erasesize; uint32_t writesize; @@ -132,16 +132,16 @@ */ struct flash_cache { size_t fc_len; - flash_addr_t fc_block; + flash_off_t fc_block; uint8_t *fc_data; }; /* flash operations should be used through these */ int flash_erase(device_t, struct flash_erase_instruction *); -int flash_read(device_t, off_t, size_t, size_t *, uint8_t *); -int flash_write(device_t, off_t, size_t, size_t *, const uint8_t *); -int flash_block_markbad(device_t, uint64_t); -int flash_block_isbad(device_t, uint64_t); +int flash_read(device_t, flash_off_t, size_t, size_t *, uint8_t *); +int flash_write(device_t, flash_off_t, size_t, size_t *, const uint8_t *); +int flash_block_markbad(device_t, flash_off_t); +int flash_block_isbad(device_t, flash_off_t, bool *); int flash_sync(device_t); /* Index: src/sys/dev/nand/nand.c diff -u src/sys/dev/nand/nand.c:1.6 src/sys/dev/nand/nand.c:1.7 --- src/sys/dev/nand/nand.c:1.6 Sun Mar 27 13:33:04 2011 +++ src/sys/dev/nand/nand.c Mon Apr 4 14:25:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: nand.c,v 1.6 2011/03/27 13:33:04 ahoka Exp $ */ +/* $NetBSD: nand.c,v 1.7 2011/04/04 14:25:10 ahoka Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -34,7 +34,7 @@ /* Common driver for NAND chips implementing the ONFI 2.2 specification */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.6 2011/03/27 13:33:04 ahoka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nand.c,v 1.7 2011/04/04 14:25:10 ahoka Exp $"); #include "locators.h" @@ -615,7 +615,7 @@ { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - off_t i; + int i; /* XXX TODO */ row >>= chip->nc_page_shift; @@ -647,7 +647,7 @@ } static void -nand_prepare_read(device_t self, flash_addr_t row, flash_addr_t column) +nand_prepare_read(device_t self, flash_off_t row, flash_off_t column) { nand_command(self, ONFI_READ); nand_address_column(self, row, column); @@ -865,9 +865,9 @@ { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t blockoffset, marker; + flash_off_t blockoffset, marker; #ifdef NAND_BBT - flash_addr_t block; + flash_off_t block; block = offset / chip->nc_block_size; @@ -889,11 +889,11 @@ } bool -nand_isfactorybad(device_t self, flash_addr_t offset) +nand_isfactorybad(device_t self, flash_off_t offset) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t block, first_page, last_page, page; + flash_off_t block, first_page, last_page, page; int i; /* Check for factory bad blocks first @@ -926,11 +926,11 @@ } bool -nand_iswornoutbad(device_t self, flash_addr_t offset) +nand_iswornoutbad(device_t self, flash_off_t offset) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t block; + flash_off_t block; /* we inspect the first page of the block */ block = offset & chip->nc_block_mask; @@ -963,12 +963,12 @@ } bool -nand_isbad(device_t self, flash_addr_t offset) +nand_isbad(device_t self, flash_off_t offset) { #ifdef NAND_BBT struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t block; + flash_off_t block; block = offset / chip->nc_block_size; @@ -1041,14 +1041,14 @@ * handle (page) unaligned write to nand */ static int -nand_flash_write_unaligned(device_t self, off_t offset, size_t len, +nand_flash_write_unaligned(device_t self, flash_off_t offset, size_t len, size_t *retlen, const uint8_t *buf) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t first, last, firstoff; + flash_off_t first, last, firstoff; const uint8_t *bufp; - flash_addr_t addr; + flash_off_t addr; size_t left, count; int error, i; @@ -1155,7 +1155,7 @@ } int -nand_flash_write(device_t self, off_t offset, size_t len, size_t *retlen, +nand_flash_write(device_t self, flash_off_t offset, size_t len, size_t *retlen, const uint8_t *buf) { struct nand_softc *sc = device_private(self); @@ -1287,7 +1287,7 @@ } int -nand_flash_read(device_t self, off_t offset, size_t len, size_t *retlen, +nand_flash_read(device_t self, flash_off_t offset, size_t len, size_t *retlen, uint8_t *buf) { struct nand_softc *sc = device_private(self); @@ -1354,7 +1354,7 @@ } int -nand_flash_isbad(device_t self, uint64_t ofs) +nand_flash_isbad(device_t self, flash_off_t ofs, bool *isbad) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; @@ -1368,22 +1368,23 @@ } if (ofs % chip->nc_block_size != 0) { - panic("offset (0x%jx) is not the multiple of block size (%ju)", - (uintmax_t)ofs, (uintmax_t)chip->nc_block_size); + DPRINTF(("offset (0x%jx) is not the multiple of block size " + "(%ju)", + (uintmax_t)ofs, (uintmax_t)chip->nc_block_size)); + return EINVAL; } mutex_enter(&sc->sc_device_lock); result = nand_isbad(self, ofs); mutex_exit(&sc->sc_device_lock); - if (result) - return 1; - else - return 0; + *isbad = result; + + return 0; } int -nand_flash_markbad(device_t self, uint64_t ofs) +nand_flash_markbad(device_t self, flash_off_t ofs) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; @@ -1413,7 +1414,7 @@ { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t addr; + flash_off_t addr; int error; if (ei->ei_addr < 0 || ei->ei_len < chip->nc_block_size) Index: src/sys/dev/nand/nand.h diff -u src/sys/dev/nand/nand.h:1.4 src/sys/dev/nand/nand.h:1.5 --- src/sys/dev/nand/nand.h:1.4 Sun Mar 27 13:33:04 2011 +++ src/sys/dev/nand/nand.h Mon Apr 4 14:25:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: nand.h,v 1.4 2011/03/27 13:33:04 ahoka Exp $ */ +/* $NetBSD: nand.h,v 1.5 2011/04/04 14:25:10 ahoka Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -401,7 +401,7 @@ #if 0 static inline bool -nand_block_isbad(device_t self, off_t block) +nand_block_isbad(device_t self, flash_off_t block) { struct nand_softc *sc = device_private(self); @@ -455,10 +455,10 @@ } /* flash interface implementation */ -int nand_flash_isbad(device_t, uint64_t); -int nand_flash_markbad(device_t, uint64_t); -int nand_flash_write(device_t, off_t, size_t, size_t *, const u_char *); -int nand_flash_read(device_t, off_t, size_t, size_t *, uint8_t *); +int nand_flash_isbad(device_t, flash_off_t, bool *); +int nand_flash_markbad(device_t, flash_off_t); +int nand_flash_write(device_t, flash_off_t, size_t, size_t *, const u_char *); +int nand_flash_read(device_t, flash_off_t, size_t, size_t *, uint8_t *); int nand_flash_erase(device_t, struct flash_erase_instruction *); /* nand specific functions */ @@ -469,9 +469,9 @@ int nand_sync_thread_start(device_t); void nand_sync_thread_stop(device_t); -bool nand_isfactorybad(device_t, flash_addr_t); -bool nand_iswornoutbad(device_t, flash_addr_t); -bool nand_isbad(device_t, flash_addr_t); +bool nand_isfactorybad(device_t, flash_off_t); +bool nand_iswornoutbad(device_t, flash_off_t); +bool nand_isbad(device_t, flash_off_t); void nand_markbad(device_t, size_t); //int nand_read_page(device_t, size_t, uint8_t *); Index: src/sys/dev/nand/nand_bbt.c diff -u src/sys/dev/nand/nand_bbt.c:1.1 src/sys/dev/nand/nand_bbt.c:1.2 --- src/sys/dev/nand/nand_bbt.c:1.1 Sat Feb 26 18:07:31 2011 +++ src/sys/dev/nand/nand_bbt.c Mon Apr 4 14:25:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: nand_bbt.c,v 1.1 2011/02/26 18:07:31 ahoka Exp $ */ +/* $NetBSD: nand_bbt.c,v 1.2 2011/04/04 14:25:10 ahoka Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -68,7 +68,7 @@ { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t i, blocks, addr; + flash_off_t i, blocks, addr; blocks = chip->nc_size / chip->nc_block_size; @@ -93,7 +93,7 @@ } static bool -nand_bbt_page_has_bbt(device_t self, flash_addr_t addr) { +nand_bbt_page_has_bbt(device_t self, flash_off_t addr) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; uint8_t *oob = chip->nc_oob_cache; @@ -110,7 +110,7 @@ } static bool -nand_bbt_get_bbt_from_page(device_t self, flash_addr_t addr) +nand_bbt_get_bbt_from_page(device_t self, flash_off_t addr) { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; @@ -156,7 +156,7 @@ { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t blockaddr; + flash_off_t blockaddr; int n; blockaddr = chip->nc_size - chip->nc_block_size; @@ -173,7 +173,7 @@ } void -nand_bbt_block_markbad(device_t self, flash_addr_t block) +nand_bbt_block_markbad(device_t self, flash_off_t block) { if (nand_bbt_block_isbad(self, block)) { aprint_error_dev(self, @@ -184,7 +184,7 @@ } void -nand_bbt_block_markfactorybad(device_t self, flash_addr_t block) +nand_bbt_block_markfactorybad(device_t self, flash_off_t block) { if (nand_bbt_block_isbad(self, block)) { aprint_error_dev(self, @@ -195,7 +195,7 @@ } void -nand_bbt_block_mark(device_t self, flash_addr_t block, uint8_t marker) +nand_bbt_block_mark(device_t self, flash_off_t block, uint8_t marker) { struct nand_softc *sc = device_private(self); #ifdef DIAGNOSTIC @@ -215,7 +215,7 @@ } bool -nand_bbt_block_isbad(device_t self, flash_addr_t block) +nand_bbt_block_isbad(device_t self, flash_off_t block) { struct nand_softc *sc = device_private(self); #ifdef DIAGNOSTIC Index: src/sys/dev/nand/nand_bbt.h diff -u src/sys/dev/nand/nand_bbt.h:1.1 src/sys/dev/nand/nand_bbt.h:1.2 --- src/sys/dev/nand/nand_bbt.h:1.1 Sat Feb 26 18:07:31 2011 +++ src/sys/dev/nand/nand_bbt.h Mon Apr 4 14:25:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: nand_bbt.h,v 1.1 2011/02/26 18:07:31 ahoka Exp $ */ +/* $NetBSD: nand_bbt.h,v 1.2 2011/04/04 14:25:10 ahoka Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -50,9 +50,9 @@ void nand_bbt_scan(device_t); bool nand_bbt_update(device_t); bool nand_bbt_load(device_t); -void nand_bbt_block_mark(device_t, flash_addr_t, uint8_t); -void nand_bbt_block_markbad(device_t, flash_addr_t); -void nand_bbt_block_markfactorybad(device_t, flash_addr_t); -bool nand_bbt_block_isbad(device_t, flash_addr_t); +void nand_bbt_block_mark(device_t, flash_off_t, uint8_t); +void nand_bbt_block_markbad(device_t, flash_off_t); +void nand_bbt_block_markfactorybad(device_t, flash_off_t); +bool nand_bbt_block_isbad(device_t, flash_off_t); #endif Index: src/sys/dev/nand/nand_io.c diff -u src/sys/dev/nand/nand_io.c:1.1 src/sys/dev/nand/nand_io.c:1.2 --- src/sys/dev/nand/nand_io.c:1.1 Sat Feb 26 18:07:31 2011 +++ src/sys/dev/nand/nand_io.c Mon Apr 4 14:25:10 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: nand_io.c,v 1.1 2011/02/26 18:07:31 ahoka Exp $ */ +/* $NetBSD: nand_io.c,v 1.2 2011/04/04 14:25:10 ahoka Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -72,7 +72,7 @@ { struct nand_softc *sc = device_private(self); struct nand_chip *chip = &sc->sc_chip; - flash_addr_t block, last; + flash_off_t block, last; /* get block number of first byte */ block = bp->b_rawblkno * DEV_BSIZE / chip->nc_block_size;