Hi all!

I need Your help with testing and adding code to FreeBSD sources.

Not tested:
- redboot/FIS
- map search by key


Build options:
options GEOM_MAP                        # 
options GEOM_MAP_NO_REDBOOT     # turn off redboot/fis support



Static mappings in hints:
===========================================================
# Area 0: 30000000 to 3002FFFF (0 - 196607, size: 196607) : "Bootloader":
u-boot
# Area 1: 30030000 to 3003FFFF (196608 - 262143, size: 65535) : "Factory":
u-boot env
# Area 2: 30040000 to 3023FFFF (262144 - 2359295, size: 2097151) : "Kernel"
# Area 3: 30240000 to 307FFFFF (2359296 - 8388607, size: 6029311) : "RootFS"

hint.map.0.at = "flash/spi0"
hint.map.0.start =      0x00000000
hint.map.0.end =        0x00030000
hint.map.0.name =       "bootldr"
hint.map.0.readonly =1

hint.map.1.at = "flash/spi0"
hint.map.1.start =      0x00030000
hint.map.1.end =        0x00040000
hint.map.1.name =       "bootldr_env"
hint.map.1.readonly =1

hint.map.2.at = "flash/spi0"
hint.map.2.start =      0x00040000
hint.map.2.end =        0x00240000
hint.map.2.name =       "kernel"
hint.map.2.readonly =0

hint.map.3.at = "flash/spi0"
hint.map.3.start =      0x00240000
hint.map.3.end =        0x00800000
hint.map.3.name =       "rootfs"
hint.map.3.readonly =0
===========================================================



Boot log:
===========================================================
...
GEOM_MAP: /dev/flash/spi0: 0x00000000-0x00030000, offset=0x0, R/O,
size=196608 bytes at: "/dev/map/spi0bootldr"
GEOM_MAP: /dev/flash/spi0: 0x00030000-0x00040000, offset=0x0, R/O,
size=65536 bytes at: "/dev/map/spi0bootldr_env"
GEOM_MAP: /dev/flash/spi0: 0x00040000-0x00240000, offset=0x0, R/W,
size=2097152 bytes at: "/dev/map/spi0kernel"
GEOM_MAP: /dev/flash/spi0: 0x00240000-0x00800000, offset=0x0, R/W,
size=6029312 bytes at: "/dev/map/spi0rootfs"
GEOM_MAP: /dev/flash/spi0: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/flash/spi0: mediasize=8388608, secsize=65536, blksize=0
...
GEOM_MAP: /dev/da0: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/da0p1: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/gpt/Documental: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/gptid/ca70d533-5759-11e0-b900-001a4d559a42: FIS/RedBoot not
exist, incompatible blksize=0
Mounting local file systems:GEOM_MAP: /dev/md0: FIS/RedBoot not exist,
incompatible blksize=0
GEOM_MAP: /dev/ufsid/4d98a59e587419bf: FIS/RedBoot not exist, incompatible
blksize=0
GEOM_MAP: /dev/md0: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/ufsid/4d98a967c292e50d: FIS/RedBoot not exist, incompatible
blksize=0
GEOM_MAP: /dev/md1: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/md1: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/ufsid/4d98a968674909d4: FIS/RedBoot not exist, incompatible
blksize=0
...
===========================================================



Files:
 - geom_map.c - source of geom node
 - options_add_geom_map.txt - patch to add build options
 - subr_hints.txt - kernel api to read 64bit values from hints
http://www.freebsd.org/cgi/query-pr.cgi?pr=156130



 
--
Rozhuk Ivan
  


> -----Original Message-----
> From: Aleksandr Rybalko [mailto:[email protected]]
> Sent: Thursday, March 31, 2011 5:28 AM
> To: [email protected]
> Cc: [email protected]; 'Warner Losh'; [email protected];
> [email protected]
> Subject: Re: merge geom redboot and map
> 
> Hi all,
> 
> On Thu, 31 Mar 2011 04:19:11 +0900
> [email protected] wrote:
> 
> >
> > > > I need your opinions, suggestions and help with testing and
> > > > including
> > > code
> > > > to main stream source tree.
> > >
> > > I think this likely is a good refactoring.
> > >
> > > > PS: I can test only "map" part on my Agestar LB2.
> > >
> > > But please make sure FIS still works.
> >
> > I hope peoples with redboot hardware help with testing.
> >
> >
> > Another question is path to mapped block (partition)?
> >
> > Now
> > - redboot: /dev/redboot/%name
> > - map: /dev/map/%name
> >
> > Variants:
> > 1. stay as is
> > 2. /dev/flash/%name
> > 3. ?
> 
> 3. /dev/flash/spi0kernel, /dev/flash/spi0rootfs, ...
> 
> IMO, /dev/map/ more generic :)
> 
> >
> > _______________________________________________
> > [email protected] mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-arm
> > To unsubscribe, send any mail to "freebsd-arm-
> [email protected]"
> 
> P.S.
> 
> I think GEOM_FLASH_NO_MAP not needed,
> because this modules differ only on configuration source,
> REDBOOT partition map and hints, so maybe only GEOM_FLASH_NO_REDBOOT to
> avoid unwanted read.
> 
> WBW
> --
> Aleksandr Rybalko <[email protected]>
--- /usr/src/sys/kern/subr_hints_orig.c 2009-08-03 17:13:06.000000000 +0900
+++ /usr/src/sys/kern/subr_hints.c      2011-04-03 18:10:57.000000000 +0900
@@ -273,6 +273,30 @@
        return 0;
 }
 
+
+int
+resource_quad_t_value(const char *name, int unit, const char *resname, quad_t 
*result)
+{
+       int error;
+       const char *str;
+       char *op;
+       quad_t val;
+       int line;
+
+       line = 0;
+       error = resource_find(&line, NULL, name, &unit, resname, NULL,
+           NULL, NULL, NULL, NULL, NULL, &str);
+       if (error)
+               return error;
+       if (*str == '\0') 
+               return EFTYPE;
+       val = strtoq(str, &op, 0);
+       if (*op != '\0') 
+               return EFTYPE;
+       *result = val;
+       return 0;
+}
+
 int
 resource_string_value(const char *name, int unit, const char *resname,
     const char **result)


--- /usr/src/sys/sys/bus.h_orig 2011-02-09 06:08:00.000000000 +0800
+++ /usr/src/sys/sys/bus.h      2011-04-03 18:13:07.000000000 +0900
@@ -470,6 +470,8 @@
                           int *result);
 int    resource_long_value(const char *name, int unit, const char *resname,
                            long *result);
+int    resource_quad_t_value(const char *name, int unit, const char *resname,
+                               quad_t *result);
 int    resource_string_value(const char *name, int unit, const char *resname,
                              const char **result);
 int    resource_disabled(const char *name, int unit);

/*-
 * Copyright (c) 2009 Aleksandr Rybalko AKA Alex RAY, DDTeam.net
 * based on geom_redboot.c
 * Copyright (c) 2009 Sam Leffler, Errno Consulting
 * 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,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
 *    redistribution must be conditioned upon including a substantially
 *    similar Disclaimer requirement for further binary redistribution.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
 */


#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/param.h>
#include <sys/bus.h>
#include <sys/errno.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/lock.h>
#include <sys/mutex.h>

#include <sys/sbuf.h>
#include <geom/geom.h>
#include <geom/geom_slice.h>
#include "opt_geom.h"


#define MAP_CLASS_NAME          "MAP"
#define MAP_MAXSLICE                    64
#define MAP_SEARCH_KEY_LEN_MAX  255
#define MAP_SEARCH_STEP_DEF             0x10000U


struct g_map_softc {
        g_access_t      *parent_access;
        off_t           entry[MAP_MAXSLICE];            /* offset in image for 
entry point */
        off_t           dsize[MAP_MAXSLICE];            /* data size in bytes */
        u_int           readonly[MAP_MAXSLICE];
};



#if !defined(GEOM_MAP_NO_REDBOOT)

struct fis_image_desc {
        uint8_t name   [16];    /* null-terminated name */
        uint32_t        offset; /* offset in flash */
        uint32_t        addr;           /* address in memory */
        uint32_t        size;           /* image size in bytes */
        uint32_t        entry;          /* offset in image for entry point */
        uint32_t        dsize;          /* data size in bytes */
        uint8_t pad[256-(16+7*sizeof(uint32_t)+sizeof(void*))];
        struct fis_image_desc *next;    /* linked list (in memory) */
        uint32_t        dsum;           /* descriptor checksum */
        uint32_t        fsum;           /* checksum over image data */
};

#define FISDIR_NAME                     "FIS directory"
#define REDBCFG_NAME                    "RedBoot config"
#define REDBOOT_NAME                    "RedBoot"

#endif /* !defined(GEOM_MAP_NO_REDBOOT) */




static int
g_map_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct 
thread *td)
{
        return (ENOIOCTL);
}

static int
g_map_access(struct g_provider *pp, int dread, int dwrite, int dexcl)
{
        struct g_geom *gp = pp->geom;
        struct g_slicer *gsp = gp->softc;
        struct g_map_softc *sc = gsp->softc;

        if (dwrite > 0 && sc->readonly[pp->index])
                return (EPERM);
        return (sc->parent_access(pp, dread, dwrite, dexcl)); 
}

static int
g_map_start(struct bio *bp)
{
        struct g_provider *pp;
        struct g_geom *gp;
        struct g_map_softc *sc;
        struct g_slicer *gsp;
        int idx;

        pp = bp->bio_to;
        idx = pp->index;
        gp = pp->geom;
        gsp = gp->softc;
        sc = gsp->softc;
        if (bp->bio_cmd == BIO_GETATTR) {
                if (g_handleattr_off_t(bp, MAP_CLASS_NAME "::entry", 
sc->entry[idx]))
                        return (1);
                if (g_handleattr_off_t(bp, MAP_CLASS_NAME "::dsize", 
sc->dsize[idx]))
                        return (1);
        }
        return (0);
}

static void
g_map_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
               struct g_consumer *cp __unused, struct g_provider *pp)
{
        struct g_map_softc *sc;
        struct g_slicer *gsp;

        gsp = gp->softc;
        sc = gsp->softc;
        g_slice_dumpconf(sb, indent, gp, cp, pp);
        if (pp != NULL) {
                if (indent == NULL) {
                        sbuf_printf(sb, " entry %jd", sc->entry[pp->index]);
                        sbuf_printf(sb, " dsize %jd", sc->dsize[pp->index]);
                        sbuf_printf(sb, " readonly %u", 
sc->readonly[pp->index]);
                } else {
                        sbuf_printf(sb, "%s<entry>%jd</entry>\n", indent, 
sc->entry[pp->index]);
                        sbuf_printf(sb, "%s<dsize>%jd</dsize>\n", indent, 
sc->dsize[pp->index]);
                        sbuf_printf(sb, "%s<readonly>%u</readonly>\n", indent, 
sc->readonly[pp->index]);
                }
        }
}



#include <sys/ctype.h>



#if !defined(GEOM_MAP_NO_REDBOOT)

static void
g_map_print_redboot(int i, struct fis_image_desc *fd)
{
        printf("[%2d] \"%-15.15s\" %08x:%08x", i, fd->name, fd->offset, 
fd->size);
        printf(" addr %08x entry %08x\n", fd->addr, fd->entry);
        printf("     dsize 0x%x dsum 0x%x fsum 0x%x\n", fd->dsize, fd->dsum, 
fd->fsum);
}


static int
nameok(const char name[16])
{
        int i;

        /* descriptor names are null-terminated printable ascii */
        for (i = 0; i < 15; i++)
                if (!isprint(name[i]))
                        break;
        return (name[i] == '\0');
}


static struct fis_image_desc *
parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t offmask)
{
#define match(a,b)      (bcmp(a, b, sizeof(b)-1) == 0)
        struct fis_image_desc *fd, *efd;
        struct fis_image_desc *fisdir, *redbcfg;
        struct fis_image_desc *head, **tail;
        int i;

        fd = (struct fis_image_desc *)buf;
        efd = fd + (bufsize / sizeof(struct fis_image_desc));
#if 0
        /*
         * Find the start of the FIS table.
         */
        while (fd < efd && fd->name[0] != 0xff)
                fd++;
        if (fd == efd)
                return (NULL);
        if (bootverbose)
                printf("RedBoot FIS table starts at 0x%jx\n",
                    offset + fd - (struct fis_image_desc *) buf);
#endif
        /*
         * Scan forward collecting entries in a list.
         */
        fisdir = redbcfg = NULL;
        *(tail = &head) = NULL;
        for (i = 0; fd < efd; i++, fd++) {
                if (fd->name[0] == 0xff)
                        continue;
                if (match(fd->name, FISDIR_NAME))
                        fisdir = fd;
                else if (match(fd->name, REDBCFG_NAME))
                        redbcfg = fd;
                if (nameok(fd->name)) {
                        /*
                         * NB: flash address includes platform mapping;
                         *     strip it so we have only a flash offset.
                         */
                        fd->offset &= offmask;
                        if (bootverbose)
                                g_map_print_redboot(i, fd);
                        *tail = fd;
                        *(tail = &fd->next) = NULL;
                }
        }
        if (fisdir == NULL) {
                if (bootverbose)
                        printf("No RedBoot FIS table located at %ju\n", offset);
                return (NULL);
        }
        if (redbcfg != NULL &&
            fisdir->offset + fisdir->size == redbcfg->offset) {
                /*
                 * Merged FIS/RedBoot config directory.
                 */
                if (bootverbose)
                        printf("FIS/RedBoot merged at 0x%jx (not yet)\n",
                            offset + fisdir->offset);
                /* XXX */
        }
        return head;
#undef match
}


/* load maps from hints */
static u_int
g_map_load_fis(struct g_consumer *cp, u_int idx)
{
        struct g_geom *gp;
        struct g_provider *pp;
        struct g_slicer *gsp;
        struct g_map_softc *sc;
        struct fis_image_desc *fd, *head;
        u_char *buf;
        int error;
        u_int sectorsize, blksize;      /* NB: flash block size stored as 
stripesize */
        uint32_t offmask;
        off_t offset;


        gp = cp->geom;
        pp = cp->provider;
        gsp = gp->softc;
        sc = gsp->softc;

        sectorsize = cp->provider->sectorsize;
        if (sectorsize < sizeof(struct fis_image_desc) ||
            (sectorsize % sizeof(struct fis_image_desc))) {
                if (bootverbose)
                        printf("GEOM_MAP: /dev/%s: FIS/RedBoot not exist, 
incompatible sectorsize=%u\n", pp->name, sectorsize);
                return (0);
        }

        blksize = cp->provider->stripesize;
        if (blksize == 0) {
                if (bootverbose)
                        printf("GEOM_MAP: /dev/%s: FIS/RedBoot not exist, 
incompatible blksize=%u\n", pp->name, blksize);
                return (0);
        }

        if (powerof2(cp->provider->mediasize))
                offmask = cp->provider->mediasize-1;
        else
                offmask = 0xffffffff;   /* XXX */
        offset = (cp->provider->mediasize - blksize);
        g_topology_unlock();
again:
        head = NULL;
        buf = g_read_data(cp, offset, blksize, NULL);
        if (buf != NULL)
                head = parse_fis_directory(buf, blksize, offset, offmask);
        if (head == NULL && offset != 0) {
                if (bootverbose)
                        printf("GEOM_MAP: /dev/%s: FIS/RedBoot table not found 
in last block, try firast block\n", pp->name);
                if (buf != NULL)
                        g_free(buf);
                offset = 0; /* check the front */
                goto again;
        }
        g_topology_lock();
        if (head == NULL) {
                if (bootverbose)
                        printf("GEOM_MAP: /dev/%s: FIS/RedBoot not found on 
device\n", pp->name);
                if (buf != NULL)
                        g_free(buf);
                return (0);
        }

        /* Craft a slice for each entry. */
        for (fd = head; fd != NULL; fd = fd->next) {
                if (fd->name[0] == '\0')
                        continue;
                error = g_slice_config(gp, idx, G_SLICE_CONFIG_SET, fd->offset, 
fd->size, sectorsize, "redboot/%s", fd->name);
                if (error) {
                        printf("GEOM_MAP: /dev/%s: g_slice_config returns %d 
for \"%s\"\n", pp->name, error, fd->name);
                }else{
                        sc->entry[idx] = fd->entry;
                        sc->dsize[idx] = fd->dsize;
                        /* disallow writing hard-to-recover entries */
                        sc->readonly[idx] = (strcmp(fd->name, FISDIR_NAME) == 
0) || (strcmp(fd->name, REDBOOT_NAME) == 0);
                        idx ++;

                        printf("GEOM_MAP: /dev/%s: 0x%08x-0x%08x, offset=0x%x, 
%s, size=%ul bytes at: \"/dev/redboot/%s\"\n",
                                pp->name, fd->addr, (fd->addr + fd->size), 
fd->entry, (sc->readonly[idx]? "R/O":"R/W"), fd->size, fd->name);
                }
        }
        g_free(buf);

        return(idx);
}

#endif /* !defined(GEOM_MAP_NO_REDBOOT) */



/* search given key on some geom */
static off_t
g_map_search_key(struct g_consumer *cp, u_int sectorsize, off_t from, off_t 
step, const char *key, u_int key_len)
{
        struct g_provider *pp;
        off_t ret = 0, i, mediasize, read_len;
        u_int c;
        char key_mask[MAP_SEARCH_KEY_LEN_MAX];
        u_char *buf;


        pp = cp->provider;
        key_len = min(MAP_SEARCH_KEY_LEN_MAX, key_len);
        read_len = roundup(key_len, sectorsize);
        mediasize = cp->provider->mediasize;

        if (bootverbose)
                printf("GEOM_MAP: /dev/%s: searchkey=\"%s\", from=0x%jx, 
step=0x%jx...", pp->name, key, from, step);

        g_topology_unlock();
        for (i = from; i < mediasize && ret == 0; i += step) {
                buf = g_read_data(cp, rounddown(i, sectorsize), read_len, NULL);
                /* read ok? */
                if (buf == NULL)
                        break;

                /* Wildcard, replace '.' with byte from data */
                bcopy(key, key_mask, key_len);
                for (c = 0; c < key_len; c++)
                        if (key_mask[c] == '.')
                                key_mask[c] = ((char *)(buf + (i % 
sectorsize)))[c];

                if (bcmp( (buf + (i % sectorsize)), key_mask, key_len) == 0)
                        ret = i;
                g_free(buf);
        }
        g_topology_lock();
        
        if (bootverbose) {
                if (ret)
                        printf("found at 0x%jx\n", ret);
                else
                        printf("NOT found!\n");
        }

        return(ret);
}


/* load maps from hints */
static u_int
g_map_load_hints(struct g_consumer *cp, u_int idx)
{
        struct g_geom *gp;
        struct g_provider *pp;
        struct g_slicer *gsp;
        struct g_map_softc *sc;
        const char *map_name, *tmpstr, *search_key;
        off_t map_start, map_end, map_size, map_offset, search_start, 
search_step;
        u_int i, sectorsize, map_readonly, map_start_searched;
        int ret;

        gp = cp->geom;
        pp = cp->provider;
        gsp = gp->softc;
        sc = gsp->softc;

        sectorsize = cp->provider->sectorsize;

        for (i = 0; i < MAP_MAXSLICE; i++) {
                map_start = map_end = map_size = map_offset = map_readonly = 
map_start_searched = 0;

                ret = resource_string_value("map", i, "at", &tmpstr);
                /* Check if my provider */
                if (ret || strcmp(pp->name, tmpstr))
                        continue;

                ret = resource_string_value("map", i, "name", &map_name);
                /* No name or error read name */
                if (ret)
                        continue;

                ret = resource_string_value("map", i, "start", &tmpstr);
                /* No start or error read */
                if (ret)
                        continue;
                if (strncmp(tmpstr, "search", 6) == 0) {
                        ret = resource_string_value("map", i, "searchkey", 
&search_key);
                        if (ret)
                                continue;

                        search_start = 0;
                        search_step = MAP_SEARCH_STEP_DEF;
                        resource_quad_t_value("map", i, "searchstart", 
&search_start);
                        resource_quad_t_value("map", i, "searchstep", 
&search_step);
                        map_start_searched = 1;

                        map_start = g_map_search_key(cp, sectorsize, 
search_start, search_step, search_key, strlen(search_key));
                        /* is search failed? */
                        if (search_start > map_start)
                                ret = 1;
                } else
                        ret = resource_quad_t_value("map", i, "start", 
&map_start);
                if (ret)
                        continue;


                ret = resource_string_value("map", i, "end", &tmpstr);
                /* No start or error read */
                if (ret)
                        continue;
                if (strncmp(tmpstr, "search", 6) == 0) {
                        ret = resource_string_value("map", i, "searchkey", 
&search_key);
                        if (ret)
                                continue;

                        search_step = MAP_SEARCH_STEP_DEF;
                        if (map_start_searched) {
                                /* we found key for start, end will see in next 
"step" offset */
                                search_start = (map_start + search_step);
                        }else{
                                search_start = 0;
                                resource_quad_t_value("map", i, "searchstart", 
&search_start);
                        }
                        resource_quad_t_value("map", i, "searchstep", 
&search_step);

                        map_end = g_map_search_key(cp, sectorsize, 
search_start, search_step, search_key, strlen(search_key));
                        /* is search failed? */
                        if (search_start > map_start)
                                ret = 1;
                } else
                        ret = resource_quad_t_value("map", i, "end", &map_end);

                map_size = (map_end - map_start);

                /* end is 0 or size is 0, No MAP - so next */
                if (ret || map_end == 0 || map_size == 0)
                        continue;
                if (map_offset > map_size) {
                        printf("GEOM_MAP: /dev/%s: offset(%jx) > size(%jx) for 
\"%s\"\n", pp->name, map_offset, map_size, map_name);
                        continue;
                }

                resource_quad_t_value("map", i, "offset", &map_offset);
                resource_int_value("map", i, "readonly", &map_readonly);

                /* strip dev name: pp->name = "flash/spi0" -> tmpstr = "spi0" */
                for (tmpstr = (pp->name + strlen(pp->name)); tmpstr > pp->name 
&& tmpstr[0] != '/'; tmpstr --);
                if (tmpstr[0] == '/')
                        tmpstr ++;

                ret = g_slice_config(gp, idx, G_SLICE_CONFIG_SET, (map_start + 
map_offset), (map_size - map_offset), sectorsize, "map/%s%s", tmpstr, map_name);
                if (ret) {
                        printf("GEOM_MAP: /dev/%s: g_slice_config returns %d 
for \"%s\"\n", pp->name, ret, map_name);
                }else{
                        sc->entry[idx] = map_offset;
                        sc->dsize[idx] = (map_size - map_offset);
                        sc->readonly[idx] = map_readonly;
                        idx ++;

                        printf("GEOM_MAP: /dev/%s: 0x%08jx-0x%08jx, 
offset=0x%jx, %s, size=%ju bytes at: \"/dev/map/%s%s\"\n",
                                pp->name, map_start, map_end, map_offset, 
(map_readonly? "R/O":"R/W"), map_size, tmpstr, map_name);
                }
        }/* for (i = 0; i < MAP_MAXSLICE; i++) */

        return(idx);
}



static struct g_geom *
g_map_taste(struct g_class *mp, struct g_provider *pp, int insist)
{
        struct g_geom *gp;
        struct g_consumer *cp;
        struct g_map_softc *sc;
        u_int idx = 0;


        g_trace(G_T_TOPOLOGY, "map_taste(%s,%s)", mp->name, pp->name);
        g_topology_assert();
        if (!strcmp(pp->geom->class->name, MAP_CLASS_NAME))
                return (NULL);

        gp = g_slice_new(mp, MAP_MAXSLICE, pp, &cp, &sc, sizeof(*sc), 
g_map_start);
        if (gp == NULL)
                return (NULL);

        /* interpose our access method */
        sc->parent_access = gp->access;
        gp->access = g_map_access;

        idx += g_map_load_hints(cp, idx);

#if !defined(GEOM_MAP_NO_REDBOOT)
        idx += g_map_load_fis(cp, idx);
#endif

        if (idx && bootverbose)
                printf("GEOM_MAP: /dev/%s: mediasize=%ju, secsize=%d, 
blksize=%d\n",
                    pp->name, pp->mediasize, pp->sectorsize, pp->stripesize);


        g_access(cp, -1, 0, 0);
        if (LIST_EMPTY(&gp->provider)) {
                g_slice_spoiled(cp);
                return (NULL);
        }
        return (gp);
}

static void
g_map_config(struct gctl_req *req, struct g_class *mp, const char *verb)
{
        struct g_geom  *gp;

        g_topology_assert();
        gp = gctl_get_geom(req, mp, "geom");
        if (gp == NULL)
                return;
        gctl_error(req, "Unknown verb");
}

static struct g_class g_map_class = {
        .name           = MAP_CLASS_NAME,
        .version        = G_VERSION,
        .taste          = g_map_taste,
        .dumpconf       = g_map_dumpconf,
        .ctlreq = g_map_config,
        .ioctl          = g_map_ioctl,
};
DECLARE_GEOM_CLASS(g_map_class, g_map);
--- /usr/src/sys/conf/options_orig      2011-04-04 02:38:46.000000000 +0900
+++ /usr/src/sys/conf/options   2011-04-03 06:18:26.000000000 +0900
@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/options,v 1.687.2.11 2011/03/27 00:42:28 kib Exp $
+# $FreeBSD: src/sys/conf/options,v 1.687.2.10 2010/07/09 08:48:51 ae Exp $
 #
 #        On the handling of kernel options
 #
@@ -99,6 +99,8 @@
 GEOM_PART_MBR  opt_geom.h
 GEOM_PART_PC98 opt_geom.h
 GEOM_PART_VTOC8        opt_geom.h
+GEOM_MAP       opt_geom.h
+GEOM_MAP_NO_REDBOOT opt_geom.h
 GEOM_PC98      opt_geom.h
 GEOM_RAID3     opt_geom.h
 GEOM_SHSEC     opt_geom.h

_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-geom
To unsubscribe, send any mail to "[email protected]"

Reply via email to