diff options
-rw-r--r-- | sys/dev/bhnd/cores/chipc/chipc_slicer.c | 12 | ||||
-rw-r--r-- | sys/dev/bhnd/cores/chipc/chipc_slicer.h | 8 | ||||
-rw-r--r-- | sys/dev/fdt/fdt_slicer.c | 36 | ||||
-rw-r--r-- | sys/dev/nand/nfc_rb.c | 39 | ||||
-rw-r--r-- | sys/geom/geom_flashmap.c | 119 | ||||
-rw-r--r-- | sys/modules/geom/Makefile | 1 | ||||
-rw-r--r-- | sys/modules/geom/geom_flashmap/Makefile | 8 | ||||
-rw-r--r-- | sys/powerpc/mikrotik/platform_rb.c | 38 | ||||
-rw-r--r-- | sys/sys/slicer.h | 24 |
9 files changed, 156 insertions, 129 deletions
diff --git a/sys/dev/bhnd/cores/chipc/chipc_slicer.c b/sys/dev/bhnd/cores/chipc/chipc_slicer.c index 45cac4d..4c6969d 100644 --- a/sys/dev/bhnd/cores/chipc/chipc_slicer.c +++ b/sys/dev/bhnd/cores/chipc/chipc_slicer.c @@ -63,10 +63,12 @@ chipc_register_slicer(chipc_flash flash_type) switch (flash_type) { case CHIPC_SFLASH_AT: case CHIPC_SFLASH_ST: - flash_register_slicer(chipc_slicer_spi); + flash_register_slicer(chipc_slicer_spi, FLASH_SLICES_TYPE_SPI, + TRUE); break; case CHIPC_PFLASH_CFI: - flash_register_slicer(chipc_slicer_cfi); + flash_register_slicer(chipc_slicer_cfi, FLASH_SLICES_TYPE_CFI, + TRUE); break; default: /* Unsupported */ @@ -75,7 +77,8 @@ chipc_register_slicer(chipc_flash flash_type) } int -chipc_slicer_cfi(device_t dev, struct flash_slice *slices, int *nslices) +chipc_slicer_cfi(device_t dev, const char *provider __unused, + struct flash_slice *slices, int *nslices) { struct cfi_softc *sc; device_t parent; @@ -100,7 +103,8 @@ chipc_slicer_cfi(device_t dev, struct flash_slice *slices, int *nslices) } int -chipc_slicer_spi(device_t dev, struct flash_slice *slices, int *nslices) +chipc_slicer_spi(device_t dev, const char *provider __unused, + struct flash_slice *slices, int *nslices) { struct chipc_spi_softc *sc; device_t chipc, spi, spibus; diff --git a/sys/dev/bhnd/cores/chipc/chipc_slicer.h b/sys/dev/bhnd/cores/chipc/chipc_slicer.h index 4c35caa..6f29626 100644 --- a/sys/dev/bhnd/cores/chipc/chipc_slicer.h +++ b/sys/dev/bhnd/cores/chipc/chipc_slicer.h @@ -41,9 +41,9 @@ #define NVRAM_MAGIC 0x48534C46 void chipc_register_slicer(chipc_flash flash_type); -int chipc_slicer_spi(device_t dev, struct flash_slice *slices, - int *nslices); -int chipc_slicer_cfi(device_t dev, struct flash_slice *slices, - int *nslices); +int chipc_slicer_spi(device_t dev, const char *provider, + struct flash_slice *slices, int *nslices); +int chipc_slicer_cfi(device_t dev, const char *provider, + struct flash_slice *slices, int *nslices); #endif /* _BHND_CORES_CHIPC_CHIPC_SLICER_H_ */ diff --git a/sys/dev/fdt/fdt_slicer.c b/sys/dev/fdt/fdt_slicer.c index 7e385c1..2765f53 100644 --- a/sys/dev/fdt/fdt_slicer.c +++ b/sys/dev/fdt/fdt_slicer.c @@ -30,10 +30,11 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> #include <sys/slicer.h> #include <dev/fdt/fdt_common.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/openfirm.h> #ifdef DEBUG #define debugf(fmt, args...) do { printf("%s(): ", __func__); \ @@ -42,8 +43,13 @@ __FBSDID("$FreeBSD$"); #define debugf(fmt, args...) #endif -int -fdt_flash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num) +static int fdt_flash_fill_slices(device_t dev, const char *provider, + struct flash_slice *slices, int *slices_num); +static void fdt_slicer_init(void); + +static int +fdt_flash_fill_slices(device_t dev, const char *provider __unused, + struct flash_slice *slices, int *slices_num) { char *slice_name; phandle_t dt_node, dt_child; @@ -90,8 +96,8 @@ fdt_flash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num) (void **)&slice_name); if (name_len <= 0) { /* Use node name if no label defined */ - name_len = OF_getprop_alloc(dt_child, "name", sizeof(char), - (void **)&slice_name); + name_len = OF_getprop_alloc(dt_child, "name", + sizeof(char), (void **)&slice_name); if (name_len <= 0) { debugf("slice i=%d with no name\n", i); slice_name = NULL; @@ -110,3 +116,23 @@ fdt_flash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num) *slices_num = i; return (0); } + +static void +fdt_slicer_init(void) +{ + + flash_register_slicer(fdt_flash_fill_slices, FLASH_SLICES_TYPE_NAND, + FALSE); + flash_register_slicer(fdt_flash_fill_slices, FLASH_SLICES_TYPE_CFI, + FALSE); + flash_register_slicer(fdt_flash_fill_slices, FLASH_SLICES_TYPE_SPI, + FALSE); +} + +/* + * Must be initialized after GEOM classes (SI_SUB_DRIVERS/SI_ORDER_FIRST), + * i. e. after g_init() is called, due to the use of the GEOM topology_lock + * in flash_register_slicer(). However, must be before SI_SUB_CONFIGURE. + */ +SYSINIT(fdt_slicer_rootconf, SI_SUB_DRIVERS, SI_ORDER_SECOND, fdt_slicer_init, + NULL); diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c index 38b2844..1102b3a 100644 --- a/sys/dev/nand/nfc_rb.c +++ b/sys/dev/nand/nfc_rb.c @@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/malloc.h> #include <sys/rman.h> +#include <sys/slicer.h> + +#include <geom/geom_disk.h> #include <machine/bus.h> @@ -106,6 +109,40 @@ static const struct nand_ecc_data rb_ecc = { }; #endif +/* Slicer operates on the NAND controller, so we have to find the chip. */ +static int +rb_nand_slicer(device_t dev, const char *provider __unused, + struct flash_slice *slices, int *nslices) +{ + struct nand_chip *chip; + device_t *children; + int n; + + if (device_get_children(dev, &children, &n) != 0) { + panic("Slicer called on controller with no child!"); + } + dev = children[0]; + free(children, M_TEMP); + + if (device_get_children(dev, &children, &n) != 0) { + panic("Slicer called on controller with nandbus but no child!"); + } + dev = children[0]; + free(children, M_TEMP); + + chip = device_get_softc(dev); + *nslices = 2; + slices[0].base = 0; + slices[0].size = 4 * 1024 * 1024; + slices[0].label = "boot"; + + slices[1].base = 4 * 1024 * 1024; + slices[1].size = chip->ndisk->d_mediasize - slices[0].size; + slices[1].label = "rootfs"; + + return (0); +} + static int rb_nand_probe(device_t dev) { @@ -175,6 +212,8 @@ rb_nand_attach(device_t dev) return (ENXIO); } + flash_register_slicer(rb_nand_slicer, FLASH_SLICES_TYPE_NAND, TRUE); + nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); err = nandbus_create(dev); diff --git a/sys/geom/geom_flashmap.c b/sys/geom/geom_flashmap.c index 76dd1fa..b7737b5 100644 --- a/sys/geom/geom_flashmap.c +++ b/sys/geom/geom_flashmap.c @@ -29,13 +29,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/endian.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/fcntl.h> #include <sys/malloc.h> -#include <sys/bio.h> -#include <sys/bus.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/slicer.h> @@ -43,9 +39,10 @@ __FBSDID("$FreeBSD$"); #include <geom/geom.h> #include <geom/geom_slice.h> #include <geom/geom_disk.h> + #include <dev/nand/nand_dev.h> -#define FLASHMAP_CLASS_NAME "Flashmap" +#define FLASHMAP_CLASS_NAME "Flashmap" struct g_flashmap_slice { off_t sl_start; @@ -57,21 +54,24 @@ struct g_flashmap_slice { STAILQ_HEAD(g_flashmap_head, g_flashmap_slice); -static void g_flashmap_print(struct g_flashmap_slice *); -static int g_flashmap_modify(struct g_geom *, const char *, - int, struct g_flashmap_head *); -static int g_flashmap_start(struct bio *); -static int g_flashmap_ioctl(struct g_provider *, u_long, void *, - int, struct thread *); -static void g_flashmap_dumpconf(struct sbuf *, const char *, - struct g_geom *, struct g_consumer *, struct g_provider *); -static struct g_geom *g_flashmap_taste(struct g_class *, - struct g_provider *, int); -static void g_flashmap_config(struct gctl_req *, struct g_class *, - const char *); -static int g_flashmap_load(device_t, struct g_flashmap_head *); -static int (*flash_fill_slices)(device_t, struct flash_slice *, int *) = - fdt_flash_fill_slices; +static struct { + const char *type; + flash_slicer_t slicer; +} g_flashmap_slicers[] = { + { "NAND::device", NULL }, + { "CFI::device", NULL }, + { "SPI::device", NULL }, + { "MMC::device", NULL } +}; + +static g_ioctl_t g_flashmap_ioctl; +static g_taste_t g_flashmap_taste; + +static int g_flashmap_load(device_t dev, struct g_provider *pp, + flash_slicer_t slicer, struct g_flashmap_head *head); +static int g_flashmap_modify(struct g_geom *gp, const char *devname, + int secsize, struct g_flashmap_head *slices); +static void g_flashmap_print(struct g_flashmap_slice *slice); MALLOC_DECLARE(M_FLASHMAP); MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class"); @@ -104,7 +104,7 @@ g_flashmap_modify(struct g_geom *gp, const char *devname, int secsize, error = g_slice_config(gp, i++, G_SLICE_CONFIG_CHECK, slice->sl_start, slice->sl_end - slice->sl_start + 1, - secsize, "%ss.%s", gp->name, slice->sl_name); + secsize, FLASH_SLICES_FMT, gp->name, slice->sl_name); if (error) return (error); @@ -125,23 +125,6 @@ g_flashmap_modify(struct g_geom *gp, const char *devname, int secsize, } static int -g_flashmap_start(struct bio *bp) -{ - - return (0); -} - -static void -g_flashmap_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, - struct g_consumer *cp __unused, struct g_provider *pp) -{ - struct g_slicer *gsp; - - gsp = gp->softc; - g_slice_dumpconf(sb, indent, gp, cp, pp); -} - -static int g_flashmap_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) { @@ -161,16 +144,16 @@ g_flashmap_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, return (gp->ioctl(cp->provider, cmd, data, fflag, td)); } - static struct g_geom * g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) { - struct g_geom *gp = NULL; + struct g_geom *gp; struct g_consumer *cp; struct g_flashmap_head head; struct g_flashmap_slice *slice, *slice_temp; + flash_slicer_t slicer; device_t dev; - int nslices, size; + int i, size; g_trace(G_T_TOPOLOGY, "flashmap_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); @@ -179,27 +162,26 @@ g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) strcmp(pp->geom->class->name, G_DISK_CLASS_NAME) != 0) return (NULL); - gp = g_slice_new(mp, FLASH_SLICES_MAX_NUM, pp, &cp, NULL, 0, - g_flashmap_start); + gp = g_slice_new(mp, FLASH_SLICES_MAX_NUM, pp, &cp, NULL, 0, NULL); if (gp == NULL) return (NULL); STAILQ_INIT(&head); do { - size = sizeof(device_t); - if (g_io_getattr("NAND::device", cp, &size, &dev)) { + slicer = NULL; + for (i = 0; i < nitems(g_flashmap_slicers); i++) { size = sizeof(device_t); - if (g_io_getattr("CFI::device", cp, &size, &dev)) { - size = sizeof(device_t); - if (g_io_getattr("SPI::device", cp, &size, - &dev)) - break; + if (g_io_getattr(g_flashmap_slicers[i].type, cp, + &size, &dev) == 0) { + slicer = g_flashmap_slicers[i].slicer; + break; } } + if (slicer == NULL) + break; - nslices = g_flashmap_load(dev, &head); - if (nslices == 0) + if (g_flashmap_load(dev, pp, slicer, &head) == 0) break; g_flashmap_modify(gp, cp->provider->name, @@ -208,9 +190,8 @@ g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) g_access(cp, -1, 0, 0); - STAILQ_FOREACH_SAFE(slice, &head, sl_link, slice_temp) { + STAILQ_FOREACH_SAFE(slice, &head, sl_link, slice_temp) free(slice, M_FLASHMAP); - } if (LIST_EMPTY(&gp->provider)) { g_slice_spoiled(cp); @@ -219,25 +200,17 @@ g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) return (gp); } -static void -g_flashmap_config(struct gctl_req *req, struct g_class *mp, const char *verb) -{ - - gctl_error(req, "unknown config verb"); -} - static int -g_flashmap_load(device_t dev, struct g_flashmap_head *head) +g_flashmap_load(device_t dev, struct g_provider *pp, flash_slicer_t slicer, + struct g_flashmap_head *head) { struct flash_slice *slices; struct g_flashmap_slice *slice; - uint32_t i, buf_size; - int nslices = 0; + int i, nslices = 0; - buf_size = sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM; - slices = malloc(buf_size, M_FLASHMAP, M_WAITOK | M_ZERO); - if (flash_fill_slices && - flash_fill_slices(dev, slices, &nslices) == 0) { + slices = malloc(sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM, + M_FLASHMAP, M_WAITOK | M_ZERO); + if (slicer(dev, pp->name, slices, &nslices) == 0) { for (i = 0; i < nslices; i++) { slice = malloc(sizeof(struct g_flashmap_slice), M_FLASHMAP, M_WAITOK); @@ -254,19 +227,21 @@ g_flashmap_load(device_t dev, struct g_flashmap_head *head) return (nslices); } -void flash_register_slicer(int (*slicer)(device_t, struct flash_slice *, int *)) +void flash_register_slicer(flash_slicer_t slicer, u_int type, bool force) { - flash_fill_slices = slicer; + g_topology_lock(); + if (g_flashmap_slicers[type].slicer == NULL || force == TRUE) + g_flashmap_slicers[type].slicer = slicer; + g_topology_unlock(); } static struct g_class g_flashmap_class = { .name = FLASHMAP_CLASS_NAME, .version = G_VERSION, .taste = g_flashmap_taste, - .dumpconf = g_flashmap_dumpconf, .ioctl = g_flashmap_ioctl, - .ctlreq = g_flashmap_config, }; DECLARE_GEOM_CLASS(g_flashmap_class, g_flashmap); +MODULE_VERSION(g_flashmap, 0); diff --git a/sys/modules/geom/Makefile b/sys/modules/geom/Makefile index 8d7e3c6..7b79f53 100644 --- a/sys/modules/geom/Makefile +++ b/sys/modules/geom/Makefile @@ -7,6 +7,7 @@ SUBDIR= geom_bde \ geom_cache \ geom_concat \ geom_eli \ + geom_flashmap \ geom_gate \ geom_journal \ geom_label \ diff --git a/sys/modules/geom/geom_flashmap/Makefile b/sys/modules/geom/geom_flashmap/Makefile new file mode 100644 index 0000000..d475860 --- /dev/null +++ b/sys/modules/geom/geom_flashmap/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../geom + +KMOD= geom_flashmap +SRCS= geom_flashmap.c + +.include <bsd.kmod.mk> diff --git a/sys/powerpc/mikrotik/platform_rb.c b/sys/powerpc/mikrotik/platform_rb.c index 39de29e..e05c59b 100644 --- a/sys/powerpc/mikrotik/platform_rb.c +++ b/sys/powerpc/mikrotik/platform_rb.c @@ -32,15 +32,12 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/bus.h> #include <sys/malloc.h> -#include <sys/slicer.h> #include <sys/smp.h> #include <machine/platform.h> #include <machine/platformvar.h> -#include <dev/nand/nand.h> #include <dev/ofw/openfirm.h> -#include <geom/geom_disk.h> #include <powerpc/mpc85xx/mpc85xx.h> @@ -59,39 +56,6 @@ DEFINE_CLASS_1(rb, rb_platform, rb_methods, 0, mpc85xx_platform); PLATFORM_DEF(rb_platform); -/* Slicer operates on the NAND controller, so we have to find the chip. */ -static int -rb_nand_slicer(device_t dev, struct flash_slice *slices, int *nslices) -{ - struct nand_chip *chip; - device_t *children; - int n; - - if (device_get_children(dev, &children, &n) != 0) { - panic("Slicer called on controller with no child!"); - } - dev = children[0]; - free(children, M_TEMP); - - if (device_get_children(dev, &children, &n) != 0) { - panic("Slicer called on controller with nandbus but no child!"); - } - dev = children[0]; - free(children, M_TEMP); - - chip = device_get_softc(dev); - *nslices = 2; - slices[0].base = 0; - slices[0].size = 4 * 1024 * 1024; - slices[0].label = "boot"; - - slices[1].base = 4 * 1024 * 1024; - slices[1].size = chip->ndisk->d_mediasize - slices[0].size; - slices[1].label = "rootfs"; - - return (0); -} - static int rb_probe(platform_t plat) { @@ -117,7 +81,5 @@ rb_attach(platform_t plat) if (error) return (error); - flash_register_slicer(rb_nand_slicer); - return (0); } diff --git a/sys/sys/slicer.h b/sys/sys/slicer.h index 9bf8748..53f680d 100644 --- a/sys/sys/slicer.h +++ b/sys/sys/slicer.h @@ -27,26 +27,38 @@ */ #ifndef _FLASH_SLICER_H_ -#define _FLASH_SLICER_H_ +#define _FLASH_SLICER_H_ #include <sys/types.h> -#define FLASH_SLICES_MAX_NUM 8 -#define FLASH_SLICES_MAX_NAME_LEN (32 + 1) +#define FLASH_SLICES_MAX_NUM 8 +#define FLASH_SLICES_MAX_NAME_LEN (32 + 1) #define FLASH_SLICES_FLAG_NONE 0 #define FLASH_SLICES_FLAG_RO 1 /* Read only */ +#define FLASH_SLICES_FMT "%ss.%s" + struct flash_slice { off_t base; off_t size; - char *label; + const char *label; unsigned int flags; }; #ifdef _KERNEL -int fdt_flash_fill_slices(device_t, struct flash_slice *, int *) __weak_symbol; -void flash_register_slicer(int (*)(device_t, struct flash_slice *, int *)); + +typedef int (*flash_slicer_t)(device_t dev, const char *provider, + struct flash_slice *slices, int *slices_num); + +#define FLASH_SLICES_TYPE_NAND 0 +#define FLASH_SLICES_TYPE_CFI 1 +#define FLASH_SLICES_TYPE_SPI 2 +#define FLASH_SLICES_TYPE_MMC 3 + +/* Use NULL for deregistering a slicer */ +void flash_register_slicer(flash_slicer_t slicer, u_int type, bool force); + #endif /* _KERNEL */ #endif /* _FLASH_SLICER_H_ */ |