Date: Fri, 15 Nov 2013 23:41:32 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258200 - head/sys/dev/nand Message-ID: <201311152341.rAFNfWJN034483@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Fri Nov 15 23:41:32 2013 New Revision: 258200 URL: http://svnweb.freebsd.org/changeset/base/258200 Log: ONFI parameters are little-endian, hence we must take care to convert them to native endianness. We must also pay attention to unaligned accesses. Copy the interesting parameters to a new struct so the rest of the code can forget about these problems. Submitted by: Kristof Provost <kristof@sigsegv.be> (cleanup) and me (orig). Modified: head/sys/dev/nand/nand.c head/sys/dev/nand/nand.h head/sys/dev/nand/nand_generic.c Modified: head/sys/dev/nand/nand.c ============================================================================== --- head/sys/dev/nand/nand.c Fri Nov 15 23:37:33 2013 (r258199) +++ head/sys/dev/nand/nand.c Fri Nov 15 23:41:32 2013 (r258200) @@ -115,7 +115,7 @@ nand_init(struct nand_softc *nand, devic } void -nand_onfi_set_params(struct nand_chip *chip, struct onfi_params *params) +nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params) { struct chip_geom *cg; Modified: head/sys/dev/nand/nand.h ============================================================================== --- head/sys/dev/nand/nand.h Fri Nov 15 23:37:33 2013 (r258199) +++ head/sys/dev/nand/nand.h Fri Nov 15 23:41:32 2013 (r258200) @@ -235,6 +235,20 @@ struct onfi_params { }__attribute__((packed)); CTASSERT(sizeof(struct onfi_params) == 256); +struct onfi_chip_params { + uint8_t luns; + uint32_t blocks_per_lun; + uint32_t pages_per_block; + uint32_t bytes_per_page; + uint32_t spare_bytes_per_page; + uint16_t t_bers; + uint16_t t_prog; + uint16_t t_r; + uint16_t t_ccs; + uint16_t features; + uint8_t address_cycles; +}; + struct nand_ecc_data { int eccsize; /* Number of data bytes per ECC step */ int eccmode; @@ -367,7 +381,7 @@ void nand_init(struct nand_softc *nand, void nand_detach(struct nand_softc *nand); struct nand_params *nand_get_params(struct nand_id *id); -void nand_onfi_set_params(struct nand_chip *chip, struct onfi_params *params); +void nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params); void nand_set_params(struct nand_chip *chip, struct nand_params *params); int nand_init_stat(struct nand_chip *chip); void nand_destroy_stat(struct nand_chip *chip); Modified: head/sys/dev/nand/nand_generic.c ============================================================================== --- head/sys/dev/nand/nand_generic.c Fri Nov 15 23:37:33 2013 (r258199) +++ head/sys/dev/nand/nand_generic.c Fri Nov 15 23:41:32 2013 (r258200) @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/bus.h> #include <sys/conf.h> +#include <sys/endian.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/rman.h> @@ -73,7 +74,7 @@ static int small_program_page(device_t, static int small_program_oob(device_t, uint32_t, void *, uint32_t, uint32_t); static int onfi_is_blk_bad(device_t, uint32_t, uint8_t *); -static int onfi_read_parameter(struct nand_chip *, struct onfi_params *); +static int onfi_read_parameter(struct nand_chip *, struct onfi_chip_params *); static int nand_send_address(device_t, int32_t, int32_t, int8_t); @@ -206,7 +207,7 @@ generic_nand_attach(device_t dev) { struct nand_chip *chip; struct nandbus_ivar *ivar; - struct onfi_params *onfi_params; + struct onfi_chip_params *onfi_chip_params; device_t nandbus, nfc; int err; @@ -225,25 +226,24 @@ generic_nand_attach(device_t dev) chip->nand = device_get_softc(nfc); if (ivar->is_onfi) { - onfi_params = malloc(sizeof(struct onfi_params), + onfi_chip_params = malloc(sizeof(struct onfi_chip_params), M_NAND, M_WAITOK | M_ZERO); - if (onfi_params == NULL) - return (ENXIO); + if (onfi_chip_params == NULL) + return (ENOMEM); - if (onfi_read_parameter(chip, onfi_params)) { + if (onfi_read_parameter(chip, onfi_chip_params)) { nand_debug(NDBG_GEN,"Could not read parameter page!\n"); - free(onfi_params, M_NAND); + free(onfi_chip_params, M_NAND); return (ENXIO); } - nand_onfi_set_params(chip, onfi_params); + nand_onfi_set_params(chip, onfi_chip_params); /* Set proper column and row cycles */ - ivar->cols = (onfi_params->address_cycles >> 4) & 0xf; - ivar->rows = onfi_params->address_cycles & 0xf; - free(onfi_params, M_NAND); + ivar->cols = (onfi_chip_params->address_cycles >> 4) & 0xf; + ivar->rows = onfi_chip_params->address_cycles & 0xf; + free(onfi_chip_params, M_NAND); } else { - nand_set_params(chip, ivar->params); } @@ -340,9 +340,10 @@ onfi_crc(const void *buf, size_t buflen) } static int -onfi_read_parameter(struct nand_chip *chip, struct onfi_params *params) +onfi_read_parameter(struct nand_chip *chip, struct onfi_chip_params *chip_params) { device_t nandbus; + struct onfi_params params; int found, sigcount, trycopy; nand_debug(NDBG_GEN,"read parameter"); @@ -373,20 +374,32 @@ onfi_read_parameter(struct nand_chip *ch * rule that the signature is valid if any 2 of the 4 bytes are correct. */ for (found= 0, trycopy = 0; !found && trycopy < 3; trycopy++) { - NANDBUS_READ_BUFFER(nandbus, params, sizeof(struct onfi_params)); - sigcount = params->signature[0] == 'O'; - sigcount += params->signature[1] == 'N'; - sigcount += params->signature[2] == 'F'; - sigcount += params->signature[3] == 'I'; + NANDBUS_READ_BUFFER(nandbus, ¶ms, sizeof(struct onfi_params)); + sigcount = params.signature[0] == 'O'; + sigcount += params.signature[1] == 'N'; + sigcount += params.signature[2] == 'F'; + sigcount += params.signature[3] == 'I'; if (sigcount < 2) continue; - if (onfi_crc(params, 254) != params->crc) + if (onfi_crc(¶ms, 254) != params.crc) continue; found = 1; } if (!found) return (ENXIO); + chip_params->luns = params.luns; + chip_params->blocks_per_lun = le32dec(¶ms.blocks_per_lun); + chip_params->pages_per_block = le32dec(¶ms.pages_per_block); + chip_params->bytes_per_page = le32dec(¶ms.bytes_per_page); + chip_params->spare_bytes_per_page = le32dec(¶ms.spare_bytes_per_page); + chip_params->t_bers = le16dec(¶ms.t_bers); + chip_params->t_prog = le16dec(¶ms.t_prog); + chip_params->t_r = le16dec(¶ms.t_r); + chip_params->t_ccs = le16dec(¶ms.t_ccs); + chip_params->features = le16dec(¶ms.features); + chip_params->address_cycles = params.address_cycles; + return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311152341.rAFNfWJN034483>