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 *);
