Module Name: src Committed By: jmcneill Date: Mon Nov 13 17:35:58 UTC 2017
Modified Files: src/sys/dev/flash: files.flash flash.c flash.h Added Files: src/sys/dev/flash: flash_mtdparts.c Log Message: Add support for defining partitions using a Linux-style "mtdparts" string. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/flash/files.flash cvs rdiff -u -r1.13 -r1.14 src/sys/dev/flash/flash.c cvs rdiff -u -r1.7 -r1.8 src/sys/dev/flash/flash.h cvs rdiff -u -r0 -r1.1 src/sys/dev/flash/flash_mtdparts.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/files.flash diff -u src/sys/dev/flash/files.flash:1.2 src/sys/dev/flash/files.flash:1.3 --- src/sys/dev/flash/files.flash:1.2 Tue Jun 28 18:14:11 2011 +++ src/sys/dev/flash/files.flash Mon Nov 13 17:35:58 2017 @@ -1,10 +1,11 @@ -# $NetBSD: files.flash,v 1.2 2011/06/28 18:14:11 ahoka Exp $ +# $NetBSD: files.flash,v 1.3 2017/11/13 17:35:58 jmcneill Exp $ -define flashbus { [offset = 0], [size = 0], [readonly = 0] } +define flashbus { [offset = 0], [size = 0], [readonly = 0], [dynamic = 0] } device flash attach flash at flashbus file dev/flash/flash.c flash file dev/flash/flash_io.c flash +file dev/flash/flash_mtdparts.c flash defflag opt_flash.h FLASH_STATIC_PARTITIONS Index: src/sys/dev/flash/flash.c diff -u src/sys/dev/flash/flash.c:1.13 src/sys/dev/flash/flash.c:1.14 --- src/sys/dev/flash/flash.c:1.13 Sat Oct 28 04:53:55 2017 +++ src/sys/dev/flash/flash.c Mon Nov 13 17:35:58 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: flash.c,v 1.13 2017/10/28 04:53:55 riastradh Exp $ */ +/* $NetBSD: flash.c,v 1.14 2017/11/13 17:35:58 jmcneill Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: flash.c,v 1.13 2017/10/28 04:53:55 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: flash.c,v 1.14 2017/11/13 17:35:58 jmcneill Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -147,20 +147,12 @@ flash_attach(device_t parent, device_t s aprint_naive("\n"); - switch (sc->flash_if->type) { - case FLASH_TYPE_NOR: - aprint_normal(": NOR flash partition size %s, offset %#jx", - pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset); - break; - - case FLASH_TYPE_NAND: - aprint_normal(": NAND flash partition size %s, offset %#jx", - pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset); - break; + aprint_normal(": partition"); + if (sc->sc_partinfo.part_name != NULL) + aprint_normal(" \"%s\"", sc->sc_partinfo.part_name); - default: - aprint_normal(": %s unknown flash", pbuf[0]); - } + aprint_normal(", size %s, offset %#jx", + pbuf[0], (uintmax_t)sc->sc_partinfo.part_offset); if (sc->sc_partinfo.part_flags & FLASH_PART_READONLY) { sc->sc_readonly = true; Index: src/sys/dev/flash/flash.h diff -u src/sys/dev/flash/flash.h:1.7 src/sys/dev/flash/flash.h:1.8 --- src/sys/dev/flash/flash.h:1.7 Fri Jul 29 20:48:33 2011 +++ src/sys/dev/flash/flash.h Mon Nov 13 17:35:58 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: flash.h,v 1.7 2011/07/29 20:48:33 ahoka Exp $ */ +/* $NetBSD: flash.h,v 1.8 2017/11/13 17:35:58 jmcneill Exp $ */ /*- * Copyright (c) 2011 Department of Software Engineering, @@ -53,6 +53,7 @@ struct flash_partition { flash_off_t part_offset; flash_size_t part_size; int part_flags; + const char *part_name; }; /** @@ -120,6 +121,7 @@ struct flash_cache { }; device_t flash_attach_mi(struct flash_interface *, device_t); +void flash_attach_mtdparts(struct flash_interface *, device_t, flash_size_t, const char *, const char *); const struct flash_interface *flash_get_interface(dev_t); const struct flash_softc *flash_get_softc(dev_t); device_t flash_get_device(dev_t); Added files: Index: src/sys/dev/flash/flash_mtdparts.c diff -u /dev/null src/sys/dev/flash/flash_mtdparts.c:1.1 --- /dev/null Mon Nov 13 17:35:58 2017 +++ src/sys/dev/flash/flash_mtdparts.c Mon Nov 13 17:35:58 2017 @@ -0,0 +1,196 @@ +/* $NetBSD: flash_mtdparts.c,v 1.1 2017/11/13 17:35:58 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: flash_mtdparts.c,v 1.1 2017/11/13 17:35:58 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/kmem.h> + +#include <dev/flash/flash.h> + +extern int flash_print(void *, const char *); + +static void +flash_attach_partition(struct flash_interface *flash_if, device_t parent, + struct flash_partition *part) +{ + struct flash_attach_args faa; + + faa.flash_if = flash_if; + faa.partinfo = *part; + + config_found_ia(parent, "flashbus", &faa, flash_print); +} + +static flash_size_t +flash_parse_size(char *partdef, char **ep) +{ + flash_size_t size; + + /* Parse the size parameter */ + size = strtoul(partdef, ep, 10); + if (partdef == *ep) + return 0; + + switch (**ep) { + case 'G': + case 'g': + size <<= 10; + /* FALLTHROUGH */ + case 'M': + case 'm': + size <<= 10; + /* FALLTHROUGH */ + case 'K': + case 'k': + size <<= 10; + (*ep)++; + break; + } + + return size; +} + +static int +flash_parse_partdef(flash_size_t flash_size, char *partdef, flash_off_t *offset, + struct flash_partition *ppart) +{ + struct flash_partition part; + + /* Get the partition size */ + if (*partdef == '-') { + /* Use the remaining space */ + part.part_size = 0; + partdef++; + } else { + part.part_size = flash_parse_size(partdef, &partdef); + if (part.part_size == 0) + return EINVAL; + } + + if (*partdef == '@') { + /* Explicit offset */ + partdef++; + part.part_offset = flash_parse_size(partdef, &partdef); + } else { + /* Offset is the end of the previous partition */ + part.part_offset = *offset; + } + + /* Calculate partition size for "all remaining space" parts */ + if (part.part_size == 0) + part.part_size = flash_size - part.part_offset; + + if (*partdef == '(') { + /* Partition name */ + partdef++; + part.part_name = partdef; + partdef = strchr(partdef, ')'); + if (partdef == NULL) + return EINVAL; + *partdef = '\0'; + partdef++; + } + + part.part_flags = 0; + if (strncmp(partdef, "ro", 2) == 0) { + part.part_flags |= FLASH_PART_READONLY; + partdef += 2; + } + + *ppart = part; + + *offset = part.part_offset + part.part_size; + + return 0; +} + +static void +flash_parse_mtddef(struct flash_interface *flash_if, device_t parent, + flash_size_t flash_size, char *mtddef) +{ + struct flash_partition part; + char *partdef = mtddef, *nextdef; + flash_off_t offset = 0; + int error; + + while (partdef && offset < flash_size) { + /* Find the end */ + nextdef = strchr(partdef, ','); + if (nextdef == NULL) + nextdef = strchr(partdef, ' '); + if (nextdef) + *nextdef++ = '\0'; + + error = flash_parse_partdef(flash_size, partdef, &offset, + &part); + if (error) { + aprint_error_dev(parent, "bad partition def '%s'\n", + partdef); + return; + } + + flash_attach_partition(flash_if, parent, &part); + + partdef = nextdef; + } +} + +/* + * Attach partitions to a given parent device node that match the supplied + * device id. The cmdline follows the following format: + * + * mtdparts=<mtddef>[;<mtddef] + * <mtddef> := <mtd-id>:<partdef>[,<partdef>] + * <partdef> := <size>[@offset][<name>][ro] + * <mtd-id> := unique id used in mapping driver/device (number of flash bank) + * <size> := memsize OR "-" to denote all remaining space + * <name> := '(' NAME ')' + */ +void +flash_attach_mtdparts(struct flash_interface *flash_if, device_t parent, + flash_size_t flash_size, const char *mtd_id, const char *cmdline) +{ + char *mtddef; + size_t mtddeflen; + + /* Find the definition for our mtd id */ + const char *s = strstr(cmdline, mtd_id); + if (s == NULL || s[strlen(mtd_id)] != ':') + return; + + mtddef = kmem_strdupsize(s + strlen(mtd_id) + 1, &mtddeflen, KM_SLEEP); + + flash_parse_mtddef(flash_if, parent, flash_size, mtddef); + + kmem_free(mtddef, mtddeflen); +}