Index: sys/arch/i386/stand/boot/boot2.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/boot2.c,v
retrieving revision 1.70
diff -U4 -r1.70 boot2.c
--- sys/arch/i386/stand/boot/boot2.c    14 Nov 2017 09:55:41 -0000      1.70
+++ sys/arch/i386/stand/boot/boot2.c    10 Aug 2019 01:47:34 -0000
@@ -103,9 +103,13 @@

#define NUMNAMES (sizeof(names)/sizeof(names[0]))
#define DEFFILENAME names[0][0]

+#ifndef NO_GPT
+#define MAXDEVNAME 39 /* "NAME=" + 34 char part_name */
+#else
#define MAXDEVNAME 16
+#endif

static char *default_devname;
static int default_unit, default_partition;
static const char *default_filename;
@@ -179,8 +183,19 @@
               devlen = col - fname;
               if (devlen > MAXDEVNAME)
                       return EINVAL;

+#ifndef NO_GPT
+               if (strstr(fname, "NAME=") == fname) {
+                       strlcpy(savedevname, fname, devlen + 1);
+                       *devname = savedevname;
+                       *unit = -1;
+                       *partition = -1;
+                       fname = col + 1;
+                       goto out;
+               }
+#endif
+
#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
               if (!isvalidname(fname[i]))
                       return EINVAL;
               do {
@@ -214,8 +229,9 @@
               *partition = p;
               fname = col + 1;
       }

+out:
       if (*fname)
               *file = fname;

       return 0;
Index: sys/arch/i386/stand/boot/devopen.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/devopen.c,v
retrieving revision 1.8
diff -U4 -r1.8 devopen.c
--- sys/arch/i386/stand/boot/devopen.c  24 Dec 2010 20:40:42 -0000      1.8
+++ sys/arch/i386/stand/boot/devopen.c  10 Aug 2019 01:47:34 -0000
@@ -127,11 +127,11 @@
       int unit, partition;
       int biosdev;
       int error;

-       if ((error = parsebootfile(fname, &fsname, &devname,
-                                  &unit, &partition, (const char **) file))
-           || (error = dev2bios(devname, unit, &biosdev)))
+       error = parsebootfile(fname, &fsname, &devname,
+                             &unit, &partition, (const char **) file);
+       if (error)
               return error;

       f->f_dev = &devsw[0];           /* must be biosdisk */

@@ -141,6 +141,27 @@
               BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
       }
#endif

+#ifndef NO_GPT
+       /* Search by GPT label name */
+       if (strstr(devname, "NAME=") == devname) {
+               f->f_dev = &devsw[0];           /* must be biosdisk */
+
+               return biosdisk_open_name(f, fname);
+       }
+#endif
+#ifndef NO_RAIDFRAME
+       /* Search by raidframe name */
+       if (strstr(devname, "raid") == devname) {
+               f->f_dev = &devsw[0];           /* must be biosdisk */
+
+               return biosdisk_open_name(f, fname);
+       }
+#endif
+
+       error = dev2bios(devname, unit, &biosdev);
+       if (error)
+               return error;
+
       return biosdisk_open(f, biosdev, partition);
}
Index: sys/arch/i386/stand/efiboot/boot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/boot.c,v
retrieving revision 1.11
diff -U4 -r1.11 boot.c
--- sys/arch/i386/stand/efiboot/boot.c  20 Jun 2019 17:33:31 -0000      1.11
+++ sys/arch/i386/stand/efiboot/boot.c  10 Aug 2019 01:47:34 -0000
@@ -141,8 +141,17 @@
               devlen = col - fname;
               if (devlen > MAXDEVNAME)
                       return EINVAL;

+               if (strstr(fname, "NAME=") == fname) {
+                       strlcpy(savedevname, fname, devlen + 1);
+                       *devname = savedevname;
+                       *unit = -1;
+                       *partition = -1;
+                       fname = col + 1;
+                       goto out;
+               }
+
#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
               if (!isvalidname(fname[i]))
                       return EINVAL;
               do {
@@ -176,8 +185,9 @@
               *partition = p;
               fname = col + 1;
       }

+out:
       if (*fname)
               *file = fname;

       return 0;
Index: sys/arch/i386/stand/efiboot/devopen.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/devopen.c,v
retrieving revision 1.5
diff -U4 -r1.5 devopen.c
--- sys/arch/i386/stand/efiboot/devopen.c       11 Apr 2018 10:32:09 -0000      1.5
+++ sys/arch/i386/stand/efiboot/devopen.c       10 Aug 2019 01:47:34 -0000
@@ -129,8 +129,22 @@
           (const char **) file);
       if (error)
               return error;

+       /* Search by GPT label or raidframe name */
+       if ((strstr(devname, "NAME=") == devname) ||
+           (strstr(devname, "raid") == devname)) {
+               f->f_dev = &devsw[0];           /* must be biosdisk */
+
+               if (!kernel_loaded) {
+                       strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
+                       BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
+               }
+
+               error = biosdisk_open_name(f, fname);
+               return error;
+       }
+
       memcpy(file_system, file_system_disk, sizeof(*file_system) * nfsys);
       nfsys = nfsys_disk;

#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
Index: sys/arch/i386/stand/efiboot/devopen.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/devopen.h,v
retrieving revision 1.3
diff -U4 -r1.3 devopen.h
--- sys/arch/i386/stand/efiboot/devopen.h       11 Apr 2018 10:32:09 -0000      1.3
+++ sys/arch/i386/stand/efiboot/devopen.h       10 Aug 2019 01:47:34 -0000
@@ -33,9 +33,9 @@
extern struct fs_ops file_system_nfs;
extern struct fs_ops file_system_tftp;
extern struct fs_ops file_system_null;

-#define        MAXDEVNAME      16
+#define        MAXDEVNAME      39 /* mxmimum is "NAME=" + 34 char part_name */

void bios2dev(int, daddr_t, char **, int *, int *);

struct devdesc {
Index: sys/arch/i386/stand/efiboot/efidisk.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/efidisk.c,v
retrieving revision 1.7
diff -U4 -r1.7 efidisk.c
--- sys/arch/i386/stand/efiboot/efidisk.c       17 Apr 2019 06:50:34 -0000      1.7
+++ sys/arch/i386/stand/efiboot/efidisk.c       10 Aug 2019 01:47:34 -0000
@@ -29,9 +29,11 @@
#define FSTYPENAMES    /* for sys/disklabel.h */

#include "efiboot.h"

+#include <sys/param.h> /* for howmany, required by <dev/raidframe/raidframevar.h> */
#include <sys/disklabel.h>
+#include <sys/disklabel_gpt.h>

#include "biosdisk.h"
#include "biosdisk_ll.h"
#include "devopen.h"
@@ -39,8 +41,42 @@

static struct efidiskinfo_lh efi_disklist;
static int nefidisks;

+#define MAXDEVNAME 39 /* "NAME=" + 34 char part_name */
+
+#include <dev/raidframe/raidframevar.h>
+#define RF_COMPONENT_INFO_OFFSET   16384   /* from sys/dev/raidframe/rf_netbsdkintf.c */
+#define RF_COMPONENT_LABEL_VERSION     2   /* from <dev/raidframe/rf_raid.h> */
+
+#define RAIDFRAME_NDEV 16 /* abitrary limit to 15 raidframe devices */
+struct efi_raidframe {
+       int last_unit;
+       int serial;
+       const struct efidiskinfo *edi;
+       int parent_part;
+       char parent_name[MAXDEVNAME + 1];
+       daddr_t offset;
+       daddr_t size;
+};
+
+static void
+dealloc_biosdisk_part(struct biosdisk_partition *part, int nparts)
+{
+       int i;
+
+       for (i = 0; i < nparts; i++) {
+               if (part[i].part_name != NULL) {
+                       dealloc(part[i].part_name, BIOSDISK_PART_NAME_LEN);
+                       part[i].part_name = NULL;
+               }
+       }
+
+       dealloc(part, sizeof(*part) * nparts);
+
+       return;
+}
+
void
efi_disk_probe(void)
{
       EFI_STATUS status;
@@ -123,16 +159,53 @@
                       boot_biosdev = edi->dev;
       }
}

+static void
+efi_raidframe_probe(struct efi_raidframe *raidframe, int *raidframe_count,
+                   const struct efidiskinfo *edi,
+                   struct biosdisk_partition *part, int parent_part)
+
+{
+       int i = *raidframe_count;
+       struct RF_ComponentLabel_s label;
+
+       if (i + 1 > RAIDFRAME_NDEV)
+               return;
+
+       if (biosdisk_read_raidframe(edi->dev, part->offset, &label) != 0)
+               return;
+
+       if (label.version != RF_COMPONENT_LABEL_VERSION)
+               return;
+
+       raidframe[i].last_unit = label.last_unit;
+       raidframe[i].serial = label.serial_number;
+       raidframe[i].edi = edi;
+       raidframe[i].parent_part = parent_part;
+       if (part->part_name)
+               strlcpy(raidframe[i].parent_name, part->part_name, MAXDEVNAME);
+       else
+               raidframe[i].parent_name[0] = '\0';
+       raidframe[i].offset = part->offset;
+       raidframe[i].size = label.__numBlocks;
+
+       (*raidframe_count)++;
+
+       return;
+}
+
+
void
efi_disk_show(void)
{
       const struct efidiskinfo *edi;
+       struct efi_raidframe raidframe[RAIDFRAME_NDEV];
+       int raidframe_count = 0;
       EFI_BLOCK_IO_MEDIA *media;
       struct biosdisk_partition *part;
       uint64_t size;
-       int i, nparts;
+       int i, j, nparts;
       bool first;

       TAILQ_FOREACH(edi, &efi_disklist, list) {
               media = edi->bio->Media;
@@ -163,21 +236,28 @@
               }
               if (edi->type != BIOSDISK_TYPE_HD)
                       continue;

-               if (biosdisk_readpartition(edi->dev, &part, &nparts))
+               if (biosdisk_readpartition(edi->dev, 0, 0, &part, &nparts))
                       continue;

               for (i = 0; i < nparts; i++) {
                       if (part[i].size == 0)
                               continue;
                       if (part[i].fstype == FS_UNUSED)
                               continue;
+                       if (part[i].fstype == FS_RAID) {
+                               efi_raidframe_probe(raidframe, &raidframe_count,
+                                                   edi, &part[i], i);
+                       }
                       if (first) {
                               printf(" ");
                               first = false;
                       }
-                       printf(" hd%d%c(", edi->dev & 0x7f, i + 'a');
+                       if (part[i].part_name != NULL)
+                               printf(" NAME=%s(", part[i].part_name);
+                       else
+                               printf(" hd%d%c(", edi->dev & 0x7f, i + 'a');
                       if (part[i].guid != NULL)
                               printf("%s", part[i].guid->name);
                       else if (part[i].fstype < FSMAXTYPES)
                               printf("%s", fstypenames[part[i].fstype]);
@@ -186,9 +266,68 @@
                       printf(")");
               }
               if (!first)
                       printf("\n");
-               dealloc(part, sizeof(*part) * nparts);
+               dealloc_biosdisk_part(part, nparts);
+       }
+
+       for (i = 0; i < raidframe_count; i++) {
+               size_t secsize = raidframe[i].edi->bio->Media->BlockSize;
+               printf("raidframe raid%d serial %d in ",
+                      raidframe[i].last_unit, raidframe[i].serial);
+               if (raidframe[i].parent_name[0])
+                       printf("NAME=%s size ", raidframe[i].parent_name);
+               else
+                       printf("hd%d%c size ",
+                              raidframe[i].edi->dev & 0x7f,
+                              raidframe[i].parent_part + 'a');
+               if (raidframe[i].size >= (10ULL * 1024 * 1024 * 1024 / secsize))
+                       printf("%"PRIu64" GB",
+                           raidframe[i].size / (1024 * 1024 * 1024 / secsize));
+               else
+                       printf("%"PRIu64" MB",
+                           raidframe[i].size / (1024 * 1024 / secsize));
+               printf("\n");
+
+               if (biosdisk_readpartition(raidframe[i].edi->dev,
+                   raidframe[i].offset + RF_PROTECTED_SECTORS,
+                   raidframe[i].size,
+                   &part, &nparts))
+                       continue;
+
+               first = 1;
+               for (j = 0; j < nparts; j++) {
+                       bool bootme = part[j].attr & GPT_ENT_ATTR_BOOTME;
+
+                       if (part[j].size == 0)
+                               continue;
+                       if (part[j].fstype == FS_UNUSED)
+                               continue;
+                       if (part[j].fstype == FS_RAID) /* raid in raid? */
+                               continue;
+                       if (first) {
+                               printf(" ");
+                               first = 0;
+                       }
+                       if (part[j].part_name != NULL)
+                               printf(" NAME=%s(", part[j].part_name);
+                       else
+                               printf(" raid%d%c(",
+                                      raidframe[i].last_unit, j + 'a');
+                       if (part[j].guid != NULL)
+                               printf("%s", part[j].guid->name);
+                       else if (part[j].fstype < FSMAXTYPES)
+                               printf("%s",
+                                 fstypenames[part[j].fstype]);
+                       else
+                               printf("%d", part[j].fstype);
+                       printf("%s)", bootme ? ", bootme" : "");
+               }
+
+               if (first == 0)
+                       printf("\n");
+
+               dealloc_biosdisk_part(part, nparts);
       }
}

const struct efidiskinfo *
@@ -226,9 +365,9 @@

       if (edi->type != BIOSDISK_TYPE_HD)
               return ENOTSUP;

-       if (biosdisk_readpartition(edi->dev, &part, &nparts))
+       if (biosdisk_readpartition(edi->dev, 0, 0, &part, &nparts))
               return EIO;

       for (i = 0; i < nparts; i++) {
               if (part[i].size == 0)
@@ -237,9 +376,9 @@
                       continue;
               if (guid_is_equal(part[i].guid->guid, &GET_efi))
                       break;
       }
-       dealloc(part, sizeof(*part) * nparts);
+       dealloc_biosdisk_part(part, nparts);
       if (i == nparts)
               return ENOENT;

       *partition = i;
Index: sys/arch/i386/stand/lib/biosdisk.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk.c,v
retrieving revision 1.49
diff -U4 -r1.49 biosdisk.c
--- sys/arch/i386/stand/lib/biosdisk.c  2 Apr 2018 09:44:18 -0000       1.49
+++ sys/arch/i386/stand/lib/biosdisk.c  10 Aug 2019 01:47:34 -0000
@@ -77,8 +77,9 @@
#include <sys/disklabel_gpt.h>
#include <sys/uuid.h>

#include <fs/cd9660/iso.h>
+#include <fs/unicode.h>

#include <lib/libsa/saerrno.h>
#include <machine/cpu.h>

@@ -88,8 +89,14 @@
#ifdef _STANDALONE
#include "bootinfo.h"
#endif

+#ifndef NO_GPT
+#define MAXDEVNAME 39 /* "NAME=" + 34 char part_name */
+#else
+#define MAXDEVNAME 16
+#endif
+
#ifndef BIOSDISK_BUFSIZE
#define BIOSDISK_BUFSIZE       2048    /* must be large enough for a CD sector */
#endif

@@ -103,16 +110,34 @@
       struct biosdisk_partition part[BIOSDISKNPART];
#endif
};

+#include <dev/raidframe/raidframevar.h>
+#define RF_COMPONENT_INFO_OFFSET   16384   /* from sys/dev/raidframe/rf_netbsdkintf.c */
+#define RF_COMPONENT_LABEL_VERSION     2   /* from <dev/raidframe/rf_raid.h> */
+
+#define RAIDFRAME_NDEV 16 /* abitrary limit to 15 raidframe devices */
+struct raidframe {
+       int     last_unit;
+       int     serial;
+       int     biosdev;
+       int     parent_part;
+#ifndef NO_GPT
+       char    parent_name[MAXDEVNAME + 1];
+#endif
+       daddr_t offset;
+       daddr_t size;
+};
+
+
#ifndef NO_GPT
const struct uuid GET_nbsd_raid = GPT_ENT_TYPE_NETBSD_RAIDFRAME;
const struct uuid GET_nbsd_ffs = GPT_ENT_TYPE_NETBSD_FFS;
const struct uuid GET_nbsd_lfs = GPT_ENT_TYPE_NETBSD_LFS;
const struct uuid GET_nbsd_swap = GPT_ENT_TYPE_NETBSD_SWAP;
const struct uuid GET_nbsd_ccd = GPT_ENT_TYPE_NETBSD_CCD;
const struct uuid GET_nbsd_cgd = GPT_ENT_TYPE_NETBSD_CGD;
-#ifdef EFIBOOT
+
const struct uuid GET_efi = GPT_ENT_TYPE_EFI;
const struct uuid GET_mbr = GPT_ENT_TYPE_MBR;
const struct uuid GET_fbsd = GPT_ENT_TYPE_FREEBSD;
const struct uuid GET_fbsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP;
@@ -156,9 +181,8 @@
       { &GET_apple_hfs,       "Apple HFS" },
       { &GET_apple_ufs,       "Apple UFS" },
       { &GET_bios,            "BIOS Boot (GRUB)" },
};
-#endif
#endif /* NO_GPT */

#ifdef _STANDALONE
static struct btinfo_bootdisk bi_disk;
@@ -166,14 +190,56 @@
#endif

#define MBR_PARTS(buf) ((char *)(buf) + offsetof(struct mbr_sector, mbr_parts))

-#define        RF_PROTECTED_SECTORS    64      /* XXX refer to <.../rf_optnames.h> */
-
#ifndef        devb2cdb
#define        devb2cdb(bno)   (((bno) * DEV_BSIZE) / ISO_DEFAULT_BLOCK_SIZE)
#endif

+static void
+dealloc_biosdisk(struct biosdisk *d)
+{
+#ifndef NO_GPT
+       int i;
+
+       for (i = 0; i < __arraycount(d->part); i++) {
+               if (d->part[i].part_name != NULL)
+                       dealloc(d->part[i].part_name, BIOSDISK_PART_NAME_LEN);
+       }
+#endif
+
+       dealloc(d, sizeof(*d));
+
+       return;
+}
+
+static struct biosdisk_partition *
+copy_biosdisk_part(struct biosdisk *d)
+{
+       struct biosdisk_partition *part;
+
+       part = alloc(sizeof(d->part));
+       if (part == NULL)
+               goto out;
+
+       memcpy(part, d->part, sizeof(d->part));
+
+#ifndef NO_GPT
+       int i;
+
+       for (i = 0; i < __arraycount(d->part); i++) {
+               if (d->part[i].part_name != NULL) {
+                       part[i].part_name = alloc(BIOSDISK_PART_NAME_LEN);
+                       memcpy(part[i].part_name, d->part[i].part_name,
+                              BIOSDISK_PART_NAME_LEN);
+               }
+       }
+#endif
+
+out:
+       return part;
+}
+
int
biosdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
                 void *buf, size_t *rsize)
{
@@ -227,9 +293,9 @@
       if (set_geometry(&d->ll, NULL)) {
#ifdef DISK_DEBUG
               printf("no geometry information\n");
#endif
-               dealloc(d, sizeof(*d));
+               dealloc_biosdisk(d);
               return NULL;
       }
       return d;
}
@@ -261,10 +327,35 @@
{
       return (memcmp(a, b, sizeof(*a)) == 0 ? true : false);
}

+#ifndef NO_GPT
+static void
+part_name_utf8(const uint16_t *utf16_src, size_t utf16_srclen,
+              char *utf8_dst, size_t utf8_dstlen)
+{
+       char *c = utf8_dst;
+       size_t r = utf8_dstlen - 1;
+       size_t n;
+       int j;
+
+       if (utf8_dst == NULL)
+               return;
+
+       for (j = 0; j < utf16_srclen && utf16_src[j] != 0x0000; j++) {
+               n = wput_utf8(c, r, le16toh(utf16_src[j]));
+               if (n == 0)
+                       break;
+               c += n; r -= n;
+       }
+       *c = '\0';
+
+       return;
+}
+#endif
+
static int
-check_gpt(struct biosdisk *d, daddr_t sector)
+check_gpt(struct biosdisk *d, daddr_t rf_offset, daddr_t sector)
{
       struct gpt_hdr gpth;
       const struct gpt_ent *ep;
       const struct uuid *u;
@@ -295,9 +386,9 @@
       if (gpth.hdr_crc_self != crc) {
               return -1;
       }

-       if (gpth.hdr_lba_self != sector)
+       if (gpth.hdr_lba_self + rf_offset != sector)
               return -1;

#ifdef _STANDALONE
       bi_wedge.matchblk = sector;
@@ -307,9 +398,9 @@
#endif

       sectors = sizeof(d->buf)/d->ll.secsize; /* sectors per buffer */
       entries = sizeof(d->buf)/gpth.hdr_entsz; /* entries per buffer */
-       entblk = gpth.hdr_lba_table;
+       entblk = gpth.hdr_lba_table + rf_offset;
       crc = crc32(0, NULL, 0);

       j = 0;
       ep = (const struct gpt_ent *)d->buf;
@@ -343,16 +434,23 @@
                               else if (guid_is_equal(u, &GET_nbsd_cgd))
                                       d->part[j].fstype = FS_CGD;
                               else
                                       d->part[j].fstype = FS_OTHER;
-#ifdef EFIBOOT
+#ifndef NO_GPT
                               for (int k = 0;
                                    k < __arraycount(gpt_parts);
                                    k++) {
                                       if (guid_is_equal(u, gpt_parts[k].guid))
                                               d->part[j].guid = &gpt_parts[k];
                               }
                               d->part[j].attr = ep[i].ent_attr;
+
+                               d->part[j].part_name =
+                                   alloc(BIOSDISK_PART_NAME_LEN);
+                               part_name_utf8(ep[i].ent_name,
+                                              sizeof(ep[i].ent_name),
+                                              d->part[j].part_name,
+                                              BIOSDISK_PART_NAME_LEN);
#endif
                               j++;
                       }
               }
@@ -369,9 +467,9 @@
       return 0;
}

static int
-read_gpt(struct biosdisk *d)
+read_gpt(struct biosdisk *d, daddr_t rf_offset, daddr_t rf_size)
{
       struct biosdisk_extinfo ed;
       daddr_t gptsector[2];
       int i, error;
@@ -379,25 +477,32 @@
       if (d->ll.type != BIOSDISK_TYPE_HD)
               /* No GPT on floppy and CD */
               return -1;

-       gptsector[0] = GPT_HDR_BLKNO;
-       if (set_geometry(&d->ll, &ed) == 0 && d->ll.flags & BIOSDISK_INT13EXT) {
-               gptsector[1] = ed.totsec - 1;
-               /* Sanity check values returned from BIOS */
-               if (ed.sbytes >= 512 && (ed.sbytes & (ed.sbytes - 1)) == 0)
-                       d->ll.secsize = ed.sbytes;
+       if (rf_offset && rf_size) {
+               gptsector[0] = rf_offset + GPT_HDR_BLKNO;
+               gptsector[1] = rf_offset + rf_size - 1;
       } else {
+               gptsector[0] = GPT_HDR_BLKNO;
+               if (set_geometry(&d->ll, &ed) == 0 &&
+                   d->ll.flags & BIOSDISK_INT13EXT) {
+                       gptsector[1] = ed.totsec - 1;
+                       /* Sanity check values returned from BIOS */
+                       if (ed.sbytes >= 512 &&
+                           (ed.sbytes & (ed.sbytes - 1)) == 0)
+                               d->ll.secsize = ed.sbytes;
+               } else {
#ifdef DISK_DEBUG
-               printf("Unable to determine extended disk geometry - "
-                       "using CHS\n");
+                       printf("Unable to determine extended disk geometry - "
+                               "using CHS\n");
#endif
-               /* at least try some other reasonable values then */
-               gptsector[1] = d->ll.chs_sectors - 1;
+                       /* at least try some other reasonable values then */
+                       gptsector[1] = d->ll.chs_sectors - 1;
+               }
       }

       for (i = 0; i < __arraycount(gptsector); i++) {
-               error = check_gpt(d, gptsector[i]);
+               error = check_gpt(d, rf_offset, gptsector[i]);
               if (error == 0)
                       break;
       }

@@ -545,9 +650,9 @@
}
#endif

static int
-read_label(struct biosdisk *d)
+read_label(struct biosdisk *d, daddr_t offset)
{
       struct disklabel dflt_lbl;
       struct mbr_partition mbr[MBR_PART_COUNT];
       struct partition *p;
@@ -572,13 +677,13 @@
       /*
        * find NetBSD Partition in DOS partition table
        * XXX check magic???
        */
-       ext_base = 0;
-       next_ext = 0;
+       ext_base = offset;
+       next_ext = offset;
       for (;;) {
               this_ext = ext_base + next_ext;
-               next_ext = 0;
+               next_ext = offset;
               if (readsects(&d->ll, this_ext, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
                       printf("error reading MBR sector %u\n", this_ext);
#endif
@@ -606,16 +711,16 @@
                               if (error >= 0)
                                       return error;
                       }
                       if (MBR_IS_EXTENDED(typ)) {
-                               next_ext = mbr[i].mbrp_start;
+                               next_ext = mbr[i].mbrp_start + offset;
                               continue;
                       }
#ifdef COMPAT_386BSD_MBRPART
-                       if (this_ext == 0 && typ == MBR_PTYPE_386BSD)
+                       if (this_ext == offset && typ == MBR_PTYPE_386BSD)
                               sector_386bsd = sector;
#endif
-                       if (this_ext != 0) {
+                       if (this_ext != offset) {
                               if (dflt_lbl.d_npartitions >= MAXPARTITIONS)
                                       continue;
                               p = &dflt_lbl.d_partitions[dflt_lbl.d_npartitions++];
                       } else
@@ -623,17 +728,17 @@
                       p->p_offset = sector;
                       p->p_size = mbr[i].mbrp_size;
                       p->p_fstype = xlat_mbr_fstype(typ);
               }
-               if (next_ext == 0)
+               if (next_ext == offset)
                       break;
-               if (ext_base == 0) {
+               if (ext_base == offset) {
                       ext_base = next_ext;
-                       next_ext = 0;
+                       next_ext = offset;
               }
       }

-       sector = 0;
+       sector = offset;
#ifdef COMPAT_386BSD_MBRPART
       if (sector_386bsd != -1) {
               printf("old BSD partition ID!\n");
               sector = sector_386bsd;
@@ -670,33 +775,76 @@
#endif /* NO_DISKLABEL */

#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
static int
-read_partitions(struct biosdisk *d)
+read_partitions(struct biosdisk *d, daddr_t offset, daddr_t size)
{
       int error;

       error = -1;

#ifndef NO_GPT
-       error = read_gpt(d);
+       error = read_gpt(d, offset, size);
       if (error == 0)
               return 0;

#endif
#ifndef NO_DISKLABEL
-       error = read_label(d);
+       error = read_label(d, offset);

#endif
       return error;
}
#endif

+#ifndef NO_RAIDFRAME
+static void
+raidframe_probe(struct raidframe *raidframe, int *raidframe_count,
+               struct biosdisk *d, int part)
+{
+       int i = *raidframe_count;
+       struct RF_ComponentLabel_s label;
+       daddr_t offset;
+
+       if (i + 1 > RAIDFRAME_NDEV)
+               return;
+
+       offset = d->part[part].offset;
+       if ((biosdisk_read_raidframe(d->ll.dev, offset, &label)) != 0)
+               return;
+
+       if (label.version != RF_COMPONENT_LABEL_VERSION)
+               printf("Unexpected raidframe label version\n");
+
+       raidframe[i].last_unit = label.last_unit;
+       raidframe[i].serial = label.serial_number;
+       raidframe[i].biosdev = d->ll.dev;
+       raidframe[i].parent_part = part;
+#ifndef NO_GPT
+       if (d->part[part].part_name)
+               strlcpy(raidframe[i].parent_name,
+                       d->part[part].part_name, MAXDEVNAME);
+       else
+               raidframe[i].parent_name[0] = '\0';
+#endif
+       raidframe[i].offset = offset;
+       raidframe[i].size = label.__numBlocks;
+
+       (*raidframe_count)++;
+
+       return;
+}
+#endif
+
void
biosdisk_probe(void)
{
-       struct biosdisk d;
+       struct biosdisk *d;
       struct biosdisk_extinfo ed;
+#ifndef NO_RAIDFRAME
+       struct raidframe raidframe[RAIDFRAME_NDEV];
+       int raidframe_count = 0;
+#endif
       uint64_t size;
       int first;
       int i;
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
@@ -704,28 +852,33 @@
#endif

       for (i = 0; i < MAX_BIOSDISKS + 2; i++) {
               first = 1;
-               memset(&d, 0, sizeof(d));
+               d = alloc(sizeof(*d));
+               if (d == NULL) {
+                       printf("Out of memory\n");
+                       return;
+               }
+               memset(d, 0, sizeof(d));
               memset(&ed, 0, sizeof(ed));
               if (i >= MAX_BIOSDISKS)
-                       d.ll.dev = 0x00 + i - MAX_BIOSDISKS;    /* fd */
+                       d->ll.dev = 0x00 + i - MAX_BIOSDISKS;   /* fd */
               else
-                       d.ll.dev = 0x80 + i;                    /* hd/cd */
-               if (set_geometry(&d.ll, &ed))
-                       continue;
+                       d->ll.dev = 0x80 + i;                   /* hd/cd */
+               if (set_geometry(&d->ll, &ed))
+                       goto next_disk;
               printf("disk ");
-               switch (d.ll.type) {
+               switch (d->ll.type) {
               case BIOSDISK_TYPE_CD:
                       printf("cd0\n  cd0a\n");
                       break;
               case BIOSDISK_TYPE_FD:
-                       printf("fd%d\n", d.ll.dev & 0x7f);
-                       printf("  fd%da\n", d.ll.dev & 0x7f);
+                       printf("fd%d\n", d->ll.dev & 0x7f);
+                       printf("  fd%da\n", d->ll.dev & 0x7f);
                       break;
               case BIOSDISK_TYPE_HD:
-                       printf("hd%d", d.ll.dev & 0x7f);
-                       if (d.ll.flags & BIOSDISK_INT13EXT) {
+                       printf("hd%d", d->ll.dev & 0x7f);
+                       if (d->ll.flags & BIOSDISK_INT13EXT) {
                               printf(" size ");
                               size = ed.totsec * ed.sbytes;
                               if (size >= (10ULL * 1024 * 1024 * 1024))
                                       printf("%"PRIu64" GB",
@@ -737,40 +890,134 @@
                       printf("\n");
                       break;
               }
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
-               if (d.ll.type != BIOSDISK_TYPE_HD)
-                       continue;
+               if (d->ll.type != BIOSDISK_TYPE_HD)
+                       goto next_disk;

-               if (read_partitions(&d) != 0)
-                       continue;
+               if (read_partitions(d, 0, 0) != 0)
+                       goto next_disk;

               for (part = 0; part < BIOSDISKNPART; part++) {
-                       if (d.part[part].size == 0)
+                       if (d->part[part].size == 0)
                               continue;
-                       if (d.part[part].fstype == FS_UNUSED)
+                       if (d->part[part].fstype == FS_UNUSED)
                               continue;
+#ifndef NO_RAIDFRAME
+                       if (d->part[part].fstype == FS_RAID)
+                               raidframe_probe(raidframe,
+                                               &raidframe_count, d, part);
+#endif
                       if (first) {
                               printf(" ");
                               first = 0;
                       }
-                       printf(" hd%d%c(", d.ll.dev & 0x7f, part + 'a');
-#ifdef EFIBOOT
-                       if (d.part[part].guid != NULL)
-                               printf("%s", d.part[part].guid->name);
+#ifndef NO_GPT
+                       if (d->part[part].part_name != NULL)
+                               printf(" NAME=%s(", d->part[part].part_name);
                       else
#endif
-                       if (d.part[part].fstype < FSMAXTYPES)
+                               printf(" hd%d%c(", d->ll.dev & 0x7f, part + 'a');
+
+#ifndef NO_GPT
+                       if (d->part[part].guid != NULL)
+                               printf("%s", d->part[part].guid->name);
+                       else
+#endif
+
+                       if (d->part[part].fstype < FSMAXTYPES)
                               printf("%s",
-                                 fstypenames[d.part[part].fstype]);
+                                 fstypenames[d->part[part].fstype]);
                       else
-                               printf("%d", d.part[part].fstype);
+                               printf("%d", d->part[part].fstype);
                       printf(")");
               }
#endif
               if (first == 0)
                       printf("\n");
+
+next_disk:
+               dealloc_biosdisk(d);
       }
+
+#ifndef NO_RAIDFRAME
+       for (i = 0; i < raidframe_count; i++) {
+               size_t secsize;
+
+               if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) {
+                       printf("Out of memory\n");
+                       return;
+               }
+
+               secsize = d->ll.secsize;
+
+               printf("raidframe raid%d serial %d in ",
+                      raidframe[i].last_unit, raidframe[i].serial);
+#ifndef NO_GPT
+               if (raidframe[i].parent_name[0])
+                       printf("NAME=%s size ", raidframe[i].parent_name);
+               else
+#endif
+               printf("hd%d%c size ", d->ll.dev & 0x7f,
+                      raidframe[i].parent_part + 'a');
+               if (raidframe[i].size >= (10ULL * 1024 * 1024 * 1024 / secsize))
+                       printf("%"PRIu64" GB",
+                           raidframe[i].size / (1024 * 1024 * 1024 / secsize));
+               else
+                       printf("%"PRIu64" MB",
+                           raidframe[i].size / (1024 * 1024 / secsize));
+               printf("\n");
+
+               if (read_partitions(d,
+                   raidframe[i].offset + RF_PROTECTED_SECTORS,
+                   raidframe[i].size) != 0)
+                       goto next_raidrame;
+
+               first = 1;
+               for (part = 0; part < BIOSDISKNPART; part++) {
+#ifndef NO_GPT
+                       bool bootme = d->part[part].attr & GPT_ENT_ATTR_BOOTME;
+#else
+                       bool bootme = 0;
+#endif
+
+                       if (d->part[part].size == 0)
+                               continue;
+                       if (d->part[part].fstype == FS_UNUSED)
+                               continue;
+                       if (d->part[part].fstype == FS_RAID)
+                               continue;
+                       if (first) {
+                               printf(" ");
+                               first = 0;
+                       }
+#ifndef NO_GPT
+                       if (d->part[part].part_name != NULL)
+                               printf(" NAME=%s(", d->part[part].part_name);
+                       else
+#endif
+                               printf(" raid%d%c(", raidframe[i].last_unit,
+                                      part + 'a');
+#ifndef NO_GPT
+                       if (d->part[part].guid != NULL)
+                               printf("%s", d->part[part].guid->name);
+                       else
+#endif
+                       if (d->part[part].fstype < FSMAXTYPES)
+                               printf("%s",
+                                 fstypenames[d->part[part].fstype]);
+                       else
+                               printf("%d", d->part[part].fstype);
+                       printf("%s)", bootme ? ", bootme" : "");
+               }
+
+next_raidrame:
+               if (first == 0)
+                       printf("\n");
+
+               dealloc_biosdisk(d);
+       }
+#endif
}

/* Determine likely partition for possible sector number of dos
 * partition.
@@ -783,9 +1030,9 @@
       return 0;
#else
       struct biosdisk *d;
       int partition = 0;
-#ifdef EFIBOOT
+#ifndef NO_GPT
       int candidate = 0;
#endif

#ifdef DISK_DEBUG
@@ -796,13 +1043,13 @@
       d = alloc_biosdisk(biosdev);
       if (d == NULL)
               return 0;

-       if (read_partitions(d) == 0) {
+       if (read_partitions(d, 0, 0) == 0) {
               for (partition = (BIOSDISKNPART-1); --partition;) {
                       if (d->part[partition].fstype == FS_UNUSED)
                               continue;
-#ifdef EFIBOOT
+#ifndef NO_GPT
                       switch (d->part[partition].fstype) {
                       case FS_BSDFFS:
                       case FS_BSDLFS:
                       case FS_RAID:
@@ -823,23 +1070,23 @@
                       if (d->part[partition].offset == sector)
                               break;
#endif
               }
-#ifdef EFIBOOT
+#ifndef NO_GPT
found:
               if (partition == 0 && candidate != 0)
                       partition = candidate;
#endif
       }

-       dealloc(d, sizeof(*d));
+       dealloc_biosdisk(d);
       return partition;
#endif /* NO_DISKLABEL && NO_GPT */
}

int
-biosdisk_readpartition(int biosdev, struct biosdisk_partition **partpp,
-    int *rnum)
+biosdisk_readpartition(int biosdev, daddr_t offset, daddr_t size,
+    struct biosdisk_partition **partpp, int *rnum)
{
#if defined(NO_DISKLABEL) && defined(NO_GPT)
       return ENOTSUP;
#else
@@ -851,28 +1098,71 @@
       d = alloc_biosdisk(biosdev);
       if (d == NULL)
               return ENOMEM;

-       if (read_partitions(d)) {
+       if (read_partitions(d, offset, size)) {
               rv = EINVAL;
               goto out;
       }

-       part = alloc(sizeof(d->part));
+       part = copy_biosdisk_part(d);
       if (part == NULL) {
               rv = ENOMEM;
               goto out;
       }

-       memcpy(part, d->part, sizeof(d->part));
       *partpp = part;
       *rnum = (int)__arraycount(d->part);
       rv = 0;
out:
-       dealloc(d, sizeof(*d));
+       dealloc_biosdisk(d);
+       return rv;
+#endif /* NO_DISKLABEL && NO_GPT */
+}
+
+#ifndef NO_RAIDFRAME
+int
+biosdisk_read_raidframe(int biosdev, daddr_t offset,
+                       struct RF_ComponentLabel_s *label)
+{
+#if defined(NO_DISKLABEL) && defined(NO_GPT)
+       return ENOTSUP;
+#else
+       struct biosdisk *d;
+       struct biosdisk_extinfo ed;
+       daddr_t size;
+       int rv = -1;
+
+       /* Look for netbsd partition that is the dos boot one */
+       d = alloc_biosdisk(biosdev);
+       if (d == NULL)
+               goto out;
+
+       if (d->ll.type != BIOSDISK_TYPE_HD)
+               /* No raidframe on floppy and CD */
+               goto out;
+
+       if (set_geometry(&d->ll, &ed) != 0)
+               goto out;
+
+       /* Sanity check values returned from BIOS */
+       if (ed.sbytes >= 512 &&
+           (ed.sbytes & (ed.sbytes - 1)) == 0)
+               d->ll.secsize = ed.sbytes;
+
+       offset += (RF_COMPONENT_INFO_OFFSET / d->ll.secsize);
+       size = roundup(sizeof(*label), d->ll.secsize) / d->ll.secsize;
+       if (readsects(&d->ll, offset, size, d->buf, 0))
+               goto out;
+       memcpy(label, d->buf, sizeof(*label));
+       rv = 0;
+out:
+       if (d != NULL)
+               dealloc_biosdisk(d);
       return rv;
#endif /* NO_DISKLABEL && NO_GPT */
}
+#endif /* NO_RAIDFRAME */

#ifdef _STANDALONE
static void
add_biosdisk_bootinfo(void)
@@ -885,8 +1175,41 @@
       return;
}
#endif

+#ifndef NO_GPT
+static daddr_t
+raidframe_part_offset(struct biosdisk *d, int part)
+{
+       struct biosdisk raidframe;
+       daddr_t rf_offset;
+       daddr_t rf_size;
+       int i, candidate;
+
+       memset(&raidframe, 0, sizeof(raidframe));
+       raidframe.ll = d->ll;
+
+       rf_offset = d->part[part].offset + RF_PROTECTED_SECTORS;
+       rf_size = d->part[part].size;
+       if (read_gpt(&raidframe, rf_offset, rf_size) != 0)
+               return RF_PROTECTED_SECTORS;
+
+       candidate = 0;
+       for (i = 0; i < BIOSDISKNPART; i++) {
+               if (raidframe.part[i].size == 0)
+                       continue;
+               if (raidframe.part[i].fstype == FS_UNUSED)
+                       continue;
+#ifndef NO_GPT
+               if (raidframe.part[i].attr & GPT_ENT_ATTR_BOOTME)
+                       candidate = i;
+#endif
+       }
+
+       return RF_PROTECTED_SECTORS + raidframe.part[candidate].offset;
+}
+#endif
+
int
biosdisk_open(struct open_file *f, ...)
/* struct open_file *f, int biosdev, int partition */
{
@@ -914,9 +1237,9 @@
       bi_wedge.matchblk = -1;
#endif

#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
-       error = read_partitions(d);
+       error = read_partitions(d, 0, 0);
       if (error == -1) {
               error = 0;
               goto nolabel;
       }
@@ -934,9 +1257,13 @@

       d->boff = d->part[partition].offset;

       if (d->part[partition].fstype == FS_RAID)
+#ifndef NO_GPT
+               d->boff += raidframe_part_offset(d, partition);
+#else
               d->boff += RF_PROTECTED_SECTORS;
+#endif

#ifdef _STANDALONE
       bi_wedge.startblk = d->part[partition].offset;
       bi_wedge.nblks = d->part[partition].size;
@@ -955,12 +1282,312 @@
       f->f_devdata = d;
out:
        va_end(ap);
       if (error)
-               dealloc(d, sizeof(*d));
+               dealloc_biosdisk(d);
+       return error;
+}
+
+#ifndef NO_GPT
+static int
+biosdisk_find_name(const char *fname, int *biosdev,
+                  daddr_t *offset, daddr_t *size)
+{
+       struct biosdisk *d;
+       char name[MAXDEVNAME + 1];
+       char *sep;
+#ifndef NO_RAIDFRAME
+       struct raidframe raidframe[RAIDFRAME_NDEV];
+       int raidframe_count = 0;
+#endif
+       int i;
+       int part;
+       int ret = -1;
+
+       /* Strip leadinf NAME= and cut after the coloon included */
+       strlcpy(name, fname + 5, MAXDEVNAME);
+       sep = strchr(name, ':');
+       if (sep)
+               *sep = '\0';
+
+       for (i = 0; i < MAX_BIOSDISKS; i++) {
+               d = alloc(sizeof(*d));
+               if (d == NULL) {
+                       printf("Out of memory\n");
+                       goto out;
+               }
+
+               memset(d, 0, sizeof(*d));
+               d->ll.dev = 0x80 + i;                   /* hd/cd */
+               if (set_geometry(&d->ll, NULL))
+                       goto next_disk;
+
+               if (d->ll.type != BIOSDISK_TYPE_HD)
+                       goto next_disk;
+
+               if (read_partitions(d, 0, 0) != 0)
+                       goto next_disk;
+
+               for (part = 0; part < BIOSDISKNPART; part++) {
+                       if (d->part[part].size == 0)
+                               continue;
+                       if (d->part[part].fstype == FS_UNUSED)
+                               continue;
+#ifndef NO_RAIDFRAME
+                       if (d->part[part].fstype == FS_RAID) {
+                               raidframe_probe(raidframe,
+                                               &raidframe_count, d, part);
+                               /*
+                                * Do not match RAID partition for a name,
+                                * we want to report an inner partition.
+                                */
+                               continue;
+                       }
+#endif
+                       if (d->part[part].part_name != NULL &&
+                           strcmp(d->part[part].part_name, name) == 0) {
+                               *biosdev = d->ll.dev;
+                               *offset = d->part[part].offset;
+                               *size = d->part[part].size;
+                               ret = 0;
+                               goto out;
+                       }
+
+               }
+next_disk:
+               dealloc_biosdisk(d);
+               d = NULL;
+       }
+
+#ifndef NO_RAIDFRAME
+       for (i = 0; i < raidframe_count; i++) {
+               int candidate = -1;
+
+               if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) {
+                       printf("Out of memory\n");
+                       goto out;
+               }
+
+               if (read_partitions(d,
+                   raidframe[i].offset + RF_PROTECTED_SECTORS,
+                   raidframe[i].size) != 0)
+                       goto next_raidframe;
+
+               for (part = 0; part < BIOSDISKNPART; part++) {
+                       bool bootme = d->part[part].attr & GPT_ENT_ATTR_BOOTME;
+                       if (d->part[part].size == 0)
+                               continue;
+                       if (d->part[part].fstype == FS_UNUSED)
+                               continue;
+                       if (d->part[part].part_name == NULL)
+                               continue;
+                       if (strcmp(d->part[part].part_name, name) == 0) {
+                               *biosdev = raidframe[i].biosdev;
+                               *offset = raidframe[i].offset
+                                       + RF_PROTECTED_SECTORS
+                                       + d->part[part].offset;
+                               *size = d->part[part].size;
+                               ret = 0;
+                               goto out;
+                       }
+                       if (strcmp(raidframe[i].parent_name, name) == 0) {
+                               if (candidate == -1 || bootme)
+                                       candidate = part;
+                               continue;
+                       }
+               }
+
+               if (candidate != -1) {
+                       *biosdev = raidframe[i].biosdev;
+                       *offset = raidframe[i].offset
+                               + RF_PROTECTED_SECTORS
+                               + d->part[candidate].offset;
+                       *size = d->part[candidate].size;
+                       ret = 0;
+                       goto out;
+               }
+
+next_raidframe:
+               dealloc_biosdisk(d);
+               d = NULL;
+       }
+#endif
+
+out:
+       if (d != NULL)
+               dealloc_biosdisk(d);
+
+       return ret;
+}
+#endif
+
+#ifndef NO_RAIDFRAME
+static int
+biosdisk_find_raid(const char *name, int *biosdev,
+                  daddr_t *offset, daddr_t *size)
+{
+       struct biosdisk *d = NULL;
+       struct raidframe raidframe[RAIDFRAME_NDEV];
+       int raidframe_count = 0;
+       int i;
+       int target_unit = 0;
+       int target_part;
+       int part;
+       int ret = -1;
+
+       if (strstr(name, "raid") != name)
+               goto out;
+
+#define isnum(c) ((c) >= '0' && (c) <= '9')
+       i = 4; /* skip leading "raid" */
+       if (!isnum(name[i]))
+               goto out;
+       do {
+               target_unit *= 10;
+               target_unit += name[i++] - '0';
+       } while (isnum(name[i]));
+
+#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
+
+       if (!isvalidpart(name[i]))
+               goto out;
+       target_part = name[i] - 'a';
+
+       for (i = 0; i < MAX_BIOSDISKS; i++) {
+               d = alloc(sizeof(*d));
+               if (d == NULL) {
+                       printf("Out of memory\n");
+                       goto out;
+               }
+
+               memset(d, 0, sizeof(*d));
+               d->ll.dev = 0x80 + i;                   /* hd/cd */
+               if (set_geometry(&d->ll, NULL))
+                       goto next_disk;
+
+               if (d->ll.type != BIOSDISK_TYPE_HD)
+                       goto next_disk;
+
+               if (read_partitions(d, 0, 0) != 0)
+                       goto next_disk;
+
+               for (part = 0; part < BIOSDISKNPART; part++) {
+                       if (d->part[part].size == 0)
+                               continue;
+                       if (d->part[part].fstype != FS_RAID)
+                               continue;
+                       raidframe_probe(raidframe,
+                                       &raidframe_count, d, part);
+
+               }
+next_disk:
+               dealloc_biosdisk(d);
+               d = NULL;
+       }
+
+       for (i = 0; i < raidframe_count; i++) {
+               if (raidframe[i].last_unit != target_unit)
+                       continue;
+
+               if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) {
+                       printf("Out of memory\n");
+                       goto out;
+               }
+
+               if (read_partitions(d,
+                   raidframe[i].offset + RF_PROTECTED_SECTORS,
+                   raidframe[i].size) != 0)
+                       goto next_raidframe;
+
+               for (part = 0; part < BIOSDISKNPART; part++) {
+                       if (d->part[part].size == 0)
+                               continue;
+                       if (d->part[part].fstype == FS_UNUSED)
+                               continue;
+                       if (part == target_part) {
+                               *biosdev = raidframe[i].biosdev;
+                               *offset = raidframe[i].offset
+                                       + RF_PROTECTED_SECTORS
+                                       + d->part[part].offset;
+                               *size = d->part[part].size;
+                               ret = 0;
+                               goto out;
+                       }
+               }
+next_raidframe:
+               dealloc_biosdisk(d);
+               d = NULL;
+       }
+out:
+       if (d != NULL)
+               dealloc_biosdisk(d);
+
+       return ret;
+}
+#endif
+
+int
+biosdisk_open_name(struct open_file *f, const char *name)
+{
+#if defined(NO_GPT) && defined(NO_RAIDFRAME)
+       return ENXIO;
+#else
+       struct biosdisk *d = NULL;
+       int biosdev;
+       daddr_t offset;
+       daddr_t size;
+       int error = -1;
+
+#ifndef NO_GPT
+       if (strstr(name, "NAME=") == name)
+               error = biosdisk_find_name(name, &biosdev, &offset, &size);
+#endif
+#ifndef NO_RAIDFRAME
+       if (strstr(name, "raid") == name)
+               error = biosdisk_find_raid(name, &biosdev, &offset, &size);
+#endif
+
+       if (error != 0) {
+               printf("partition %s not found\n", name);
+               error = ENXIO;
+               goto out;
+       }
+
+       d = alloc_biosdisk(biosdev);
+       if (d == NULL) {
+               error = ENXIO;
+               goto out;
+       }
+
+#ifdef _STANDALONE
+       bi_disk.biosdev = d->ll.dev;
+       bi_disk.partition = 0;
+       bi_disk.labelsector = -1;
+
+       bi_wedge.biosdev = d->ll.dev;
+       bi_wedge.matchblk = offset;
+       bi_wedge.matchnblks = 1;
+#endif
+
+       d->boff = offset;
+
+#ifdef _STANDALONE
+       bi_wedge.startblk = offset;
+       bi_wedge.nblks = size;
+
+       add_biosdisk_bootinfo();
+#endif
+
+       f->f_devdata = d;
+out:
+       if (error && d != NULL)
+               dealloc_biosdisk(d);
       return error;
+#endif
}

+
+
#ifndef LIBSA_NO_FS_CLOSE
int
biosdisk_close(struct open_file *f)
{
@@ -969,9 +1596,9 @@
       /* let the floppy drive go off */
       if (d->ll.type == BIOSDISK_TYPE_FD)
               wait_sec(3);    /* 2s is enough on all PCs I found */

-       dealloc(d, sizeof(*d));
+       dealloc_biosdisk(d);
       f->f_devdata = NULL;
       return 0;
}
#endif
Index: sys/arch/i386/stand/lib/biosdisk.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk.h,v
retrieving revision 1.10
diff -U4 -r1.10 biosdisk.h
--- sys/arch/i386/stand/lib/biosdisk.h  2 Apr 2018 09:44:18 -0000       1.10
+++ sys/arch/i386/stand/lib/biosdisk.h  10 Aug 2019 01:47:34 -0000
@@ -24,27 +24,35 @@
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

+#define BIOSDISK_PART_NAME_LEN 36
+
struct biosdisk_partition {
       daddr_t offset;
       daddr_t size;
       int     fstype;
-#ifdef EFIBOOT
+#ifndef NO_GPT
       const struct gpt_part {
               const struct uuid *guid;
               const char *name;
       } *guid;
       uint64_t attr;
+       char *part_name; /* maximum BIOSDISK_PART_NAME_LEN */
#endif
};

int biosdisk_strategy(void *, int, daddr_t, size_t, void *, size_t *);
int biosdisk_open(struct open_file *, ...);
+int biosdisk_open_name(struct open_file *, const char *);
int biosdisk_close(struct open_file *);
int biosdisk_ioctl(struct open_file *, u_long, void *);
int biosdisk_findpartition(int, daddr_t);
-int biosdisk_readpartition(int, struct biosdisk_partition **, int *);
+int biosdisk_readpartition(int, daddr_t, daddr_t,
+     struct biosdisk_partition **, int *);
+
+struct RF_ComponentLabel_s;
+int biosdisk_read_raidframe(int, daddr_t, struct RF_ComponentLabel_s *);

#if !defined(NO_GPT)
struct uuid;
bool guid_is_nil(const struct uuid *);