Changeset View
Changeset View
Standalone View
Standalone View
head/sys/geom/geom_flashmap.c
Show All 33 Lines | |||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/slicer.h> | #include <sys/slicer.h> | ||||
#include <geom/geom.h> | #include <geom/geom.h> | ||||
#include <geom/geom_slice.h> | |||||
#include <geom/geom_disk.h> | #include <geom/geom_disk.h> | ||||
#include <geom/geom_flashmap.h> | |||||
#include <geom/geom_slice.h> | |||||
#include <dev/nand/nand_dev.h> | #include <dev/nand/nand_dev.h> | ||||
#define FLASHMAP_CLASS_NAME "Flashmap" | |||||
struct g_flashmap_slice { | struct g_flashmap_slice { | ||||
off_t sl_start; | off_t sl_start; | ||||
off_t sl_end; | off_t sl_end; | ||||
const char *sl_name; | const char *sl_name; | ||||
STAILQ_ENTRY(g_flashmap_slice) sl_link; | STAILQ_ENTRY(g_flashmap_slice) sl_link; | ||||
}; | }; | ||||
Show All 9 Lines | static struct { | ||||
{ "MMC::device", NULL } | { "MMC::device", NULL } | ||||
}; | }; | ||||
static g_ioctl_t g_flashmap_ioctl; | static g_ioctl_t g_flashmap_ioctl; | ||||
static g_taste_t g_flashmap_taste; | static g_taste_t g_flashmap_taste; | ||||
static int g_flashmap_load(device_t dev, struct g_provider *pp, | static int g_flashmap_load(device_t dev, struct g_provider *pp, | ||||
flash_slicer_t slicer, struct g_flashmap_head *head); | flash_slicer_t slicer, struct g_flashmap_head *head); | ||||
static int g_flashmap_modify(struct g_geom *gp, const char *devname, | static int g_flashmap_modify(struct g_flashmap *gfp, struct g_geom *gp, | ||||
int secsize, struct g_flashmap_head *slices); | const char *devname, int secsize, struct g_flashmap_head *slices); | ||||
static void g_flashmap_print(struct g_flashmap_slice *slice); | static void g_flashmap_print(struct g_flashmap_slice *slice); | ||||
MALLOC_DECLARE(M_FLASHMAP); | MALLOC_DECLARE(M_FLASHMAP); | ||||
MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class"); | MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class"); | ||||
static void | static void | ||||
g_flashmap_print(struct g_flashmap_slice *slice) | g_flashmap_print(struct g_flashmap_slice *slice) | ||||
{ | { | ||||
printf("%08jx-%08jx: %s (%juKB)\n", (uintmax_t)slice->sl_start, | printf("%08jx-%08jx: %s (%juKB)\n", (uintmax_t)slice->sl_start, | ||||
(uintmax_t)slice->sl_end, slice->sl_name, | (uintmax_t)slice->sl_end, slice->sl_name, | ||||
(uintmax_t)(slice->sl_end - slice->sl_start) / 1024); | (uintmax_t)(slice->sl_end - slice->sl_start) / 1024); | ||||
} | } | ||||
static int | static int | ||||
g_flashmap_modify(struct g_geom *gp, const char *devname, int secsize, | g_flashmap_modify(struct g_flashmap *gfp, struct g_geom *gp, | ||||
struct g_flashmap_head *slices) | const char *devname, int secsize, struct g_flashmap_head *slices) | ||||
{ | { | ||||
struct g_flashmap_slice *slice; | struct g_flashmap_slice *slice; | ||||
int i, error; | int i, error; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
i = 0; | i = 0; | ||||
STAILQ_FOREACH(slice, slices, sl_link) { | STAILQ_FOREACH(slice, slices, sl_link) { | ||||
if (bootverbose) { | if (bootverbose) { | ||||
printf("%s: slice ", devname); | printf("%s: slice ", devname); | ||||
g_flashmap_print(slice); | g_flashmap_print(slice); | ||||
} | } | ||||
error = g_slice_config(gp, i++, G_SLICE_CONFIG_CHECK, | error = g_slice_config(gp, i++, G_SLICE_CONFIG_CHECK, | ||||
slice->sl_start, | slice->sl_start, | ||||
slice->sl_end - slice->sl_start + 1, | slice->sl_end - slice->sl_start + 1, | ||||
secsize, FLASH_SLICES_FMT, gp->name, slice->sl_name); | secsize, FLASH_SLICES_FMT, gp->name, slice->sl_name); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
i = 0; | i = 0; | ||||
STAILQ_FOREACH(slice, slices, sl_link) { | STAILQ_FOREACH(slice, slices, sl_link) { | ||||
free(__DECONST(void *, gfp->labels[i]), M_FLASHMAP); | |||||
gfp->labels[i] = strdup(slice->sl_name, M_FLASHMAP); | |||||
error = g_slice_config(gp, i++, G_SLICE_CONFIG_SET, | error = g_slice_config(gp, i++, G_SLICE_CONFIG_SET, | ||||
slice->sl_start, | slice->sl_start, | ||||
slice->sl_end - slice->sl_start + 1, | slice->sl_end - slice->sl_start + 1, | ||||
secsize, "%ss.%s", gp->name, slice->sl_name); | secsize, "%ss.%s", gp->name, slice->sl_name); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
Show All 23 Lines | |||||
static struct g_geom * | static struct g_geom * | ||||
g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) | g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
struct g_flashmap_head head; | struct g_flashmap_head head; | ||||
struct g_flashmap_slice *slice, *slice_temp; | struct g_flashmap_slice *slice, *slice_temp; | ||||
struct g_flashmap *gfp; | |||||
flash_slicer_t slicer; | flash_slicer_t slicer; | ||||
device_t dev; | device_t dev; | ||||
int i, size; | int i, size; | ||||
g_trace(G_T_TOPOLOGY, "flashmap_taste(%s,%s)", mp->name, pp->name); | g_trace(G_T_TOPOLOGY, "flashmap_taste(%s,%s)", mp->name, pp->name); | ||||
g_topology_assert(); | g_topology_assert(); | ||||
if (flags == G_TF_NORMAL && | if (flags == G_TF_NORMAL && | ||||
strcmp(pp->geom->class->name, G_DISK_CLASS_NAME) != 0) | strcmp(pp->geom->class->name, G_DISK_CLASS_NAME) != 0) | ||||
return (NULL); | return (NULL); | ||||
gp = g_slice_new(mp, FLASH_SLICES_MAX_NUM, pp, &cp, NULL, 0, NULL); | gp = g_slice_new(mp, FLASH_SLICES_MAX_NUM, pp, &cp, (void**)&gfp, | ||||
sizeof(struct g_flashmap), NULL); | |||||
if (gp == NULL) | if (gp == NULL) | ||||
return (NULL); | return (NULL); | ||||
STAILQ_INIT(&head); | STAILQ_INIT(&head); | ||||
do { | do { | ||||
slicer = NULL; | slicer = NULL; | ||||
for (i = 0; i < nitems(g_flashmap_slicers); i++) { | for (i = 0; i < nitems(g_flashmap_slicers); i++) { | ||||
size = sizeof(device_t); | size = sizeof(device_t); | ||||
if (g_io_getattr(g_flashmap_slicers[i].type, cp, | if (g_io_getattr(g_flashmap_slicers[i].type, cp, | ||||
&size, &dev) == 0) { | &size, &dev) == 0) { | ||||
slicer = g_flashmap_slicers[i].slicer; | slicer = g_flashmap_slicers[i].slicer; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (slicer == NULL) | if (slicer == NULL) | ||||
break; | break; | ||||
if (g_flashmap_load(dev, pp, slicer, &head) == 0) | if (g_flashmap_load(dev, pp, slicer, &head) == 0) | ||||
break; | break; | ||||
g_flashmap_modify(gp, cp->provider->name, | g_flashmap_modify(gfp, gp, cp->provider->name, | ||||
cp->provider->sectorsize, &head); | cp->provider->sectorsize, &head); | ||||
} while (0); | } while (0); | ||||
g_access(cp, -1, 0, 0); | 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); | free(slice, M_FLASHMAP); | ||||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |