Module Name:    src
Committed By:   manu
Date:           Sun Aug 18 02:18:25 UTC 2019

Modified Files:
        src/sys/arch/i386/stand/boot: boot2.c devopen.c devopen.h
        src/sys/arch/i386/stand/efiboot: boot.c devopen.c devopen.h efidisk.c
        src/sys/arch/i386/stand/lib: Makefile biosdisk.c biosdisk.h

Log Message:
Add GPT and RAIDframe support to bootloaders

Classic BIOS (/boot) and EFI bootloaders can now name devices
using the NAME=gpt_label syntax, or using raid partitions. Here
are examples:
boot NAME=root:/netbsd
boot raid0e:/netbsd


To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/sys/arch/i386/stand/boot/boot2.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/i386/stand/boot/devopen.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/i386/stand/boot/devopen.h
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/i386/stand/efiboot/boot.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/i386/stand/efiboot/devopen.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/i386/stand/efiboot/devopen.h
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/i386/stand/efiboot/efidisk.c
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/i386/stand/lib/Makefile
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/i386/stand/lib/biosdisk.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/i386/stand/lib/biosdisk.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/i386/stand/boot/boot2.c
diff -u src/sys/arch/i386/stand/boot/boot2.c:1.70 src/sys/arch/i386/stand/boot/boot2.c:1.71
--- src/sys/arch/i386/stand/boot/boot2.c:1.70	Tue Nov 14 09:55:41 2017
+++ src/sys/arch/i386/stand/boot/boot2.c	Sun Aug 18 02:18:24 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot2.c,v 1.70 2017/11/14 09:55:41 maxv Exp $	*/
+/*	$NetBSD: boot2.c,v 1.71 2019/08/18 02:18:24 manu Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -79,6 +79,7 @@
 #include <libi386.h>
 #include <bootmod.h>
 #include <bootmenu.h>
+#include <biosdisk.h>
 #include <vbe.h>
 #include "devopen.h"
 
@@ -104,11 +105,16 @@ static const char * const names[][2] = {
 #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;
+static const char *default_part_name;
 
 char *sprint_bootsel(const char *);
 static void bootit(const char *, int);
@@ -160,9 +166,15 @@ parsebootfile(const char *fname, char **
 	      int *unit, int *partition, const char **file)
 {
 	const char *col;
+	static char savedevname[MAXDEVNAME+1];
 
 	*fsname = "ufs";
-	*devname = default_devname;
+	if (default_part_name == NULL) {
+		*devname = default_devname;
+	} else {
+		snprintf(savedevname, MAXDEVNAME, "NAME=%s", default_part_name);
+		*devname = savedevname;
+	}
 	*unit = default_unit;
 	*partition = default_partition;
 	*file = default_filename;
@@ -171,7 +183,6 @@ parsebootfile(const char *fname, char **
 		return 0;
 
 	if ((col = strchr(fname, ':')) != NULL) {	/* device given */
-		static char savedevname[MAXDEVNAME+1];
 		int devlen;
 		int u = 0, p = 0;
 		int i = 0;
@@ -180,6 +191,17 @@ parsebootfile(const char *fname, char **
 		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;
@@ -215,6 +237,7 @@ parsebootfile(const char *fname, char **
 		fname = col + 1;
 	}
 
+out:
 	if (*fname)
 		*file = fname;
 
@@ -231,8 +254,11 @@ sprint_bootsel(const char *filename)
 
 	if (parsebootfile(filename, &fsname, &devname, &unit,
 			  &partition, &file) == 0) {
-		snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
-		    'a' + partition, file);
+		if (strstr(devname, "NAME=") == devname)
+			snprintf(buf, sizeof(buf), "%s:%s", devname, file);
+		else
+			snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
+			    'a' + partition, file);
 		return buf;
 	}
 	return "(invalid)";
@@ -319,7 +345,7 @@ boot2(int biosdev, uint64_t biossector)
 
 	/* try to set default device to what BIOS tells us */
 	bios2dev(biosdev, biossector, &default_devname, &default_unit,
-		 &default_partition);
+		 &default_partition, &default_part_name);
 
 	/* if the user types "boot" without filename */
 	default_filename = DEFFILENAME;
@@ -401,13 +427,21 @@ command_help(char *arg)
 {
 
 	printf("commands are:\n"
-	       "boot [xdNx:][filename] [-12acdqsvxz]\n"
+	       "boot [dev:][filename] [-12acdqsvxz]\n"
+#ifndef NO_RAIDFRAME
+	       "     dev syntax is (hd|fd|cd|raid)[N[x]]\n"
+#else
+	       "     dev syntax is (hd|fd|cd)[N[x]]n"
+#endif
+#ifndef NO_GPT
+	       "                or NAME=gpt_label\n"
+#endif
 	       "     (ex. \"hd0a:netbsd.old -s\")\n"
-	       "pkboot [xdNx:][filename] [-12acdqsvxz]\n"
+	       "pkboot [dev:][filename] [-12acdqsvxz]\n"
 #if LIBSA_ENABLE_LS_OP
-	       "ls [path]\n"
+	       "ls [dev:][path]\n"
 #endif
-	       "dev xd[N[x]]:\n"
+	       "dev [dev:]\n"
 	       "consdev {pc|com[0123]|com[0123]kbd|auto}\n"
 	       "vesa {modenum|on|off|enabled|disabled|list}\n"
 #ifndef SMALL
@@ -415,7 +449,7 @@ command_help(char *arg)
 #endif
 	       "modules {on|off|enabled|disabled}\n"
 	       "load {path_to_module}\n"
-	       "multiboot [xdNx:][filename] [<args>]\n"
+	       "multiboot [dev:][filename] [<args>]\n"
 	       "splash {path_to_image_file}\n"
 	       "userconf {command}\n"
 	       "rndseed {path_to_rndseed_file}\n"
@@ -490,8 +524,16 @@ command_dev(char *arg)
 
 	if (*arg == '\0') {
 		biosdisk_probe();
-		printf("default %s%d%c\n", default_devname, default_unit,
-		       'a' + default_partition);
+
+#ifndef NO_GPT
+		if (default_part_name)
+			printf("default NAME=%s on %s%d\n", default_part_name,
+			       default_devname, default_unit);
+		else
+#endif
+			printf("default %s%d%c\n",
+			       default_devname, default_unit,
+			       'a' + default_partition);
 		return;
 	}
 
@@ -505,6 +547,10 @@ command_dev(char *arg)
 	/* put to own static storage */
 	strncpy(savedevname, devname, MAXDEVNAME + 1);
 	default_devname = savedevname;
+
+	/* +5 to skip leading NAME= */
+	if (strstr(devname, "NAME=") == devname)
+		default_part_name = default_devname + 5;
 }
 
 static const struct cons_devs {

Index: src/sys/arch/i386/stand/boot/devopen.c
diff -u src/sys/arch/i386/stand/boot/devopen.c:1.8 src/sys/arch/i386/stand/boot/devopen.c:1.9
--- src/sys/arch/i386/stand/boot/devopen.c:1.8	Fri Dec 24 20:40:42 2010
+++ src/sys/arch/i386/stand/boot/devopen.c	Sun Aug 18 02:18:24 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: devopen.c,v 1.8 2010/12/24 20:40:42 jakllsch Exp $	 */
+/*	$NetBSD: devopen.c,v 1.9 2019/08/18 02:18:24 manu Exp $	 */
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -89,7 +89,8 @@ dev2bios(char *devname, int unit, int *b
 }
 
 void
-bios2dev(int biosdev, daddr_t sector, char **devname, int *unit, int *partition)
+bios2dev(int biosdev, daddr_t sector, char **devname, int *unit,
+	 int *partition, const char **part_name)
 {
 
 	/* set default */
@@ -109,7 +110,7 @@ bios2dev(int biosdev, daddr_t sector, ch
 	} else
 		*devname = "fd";
 
-	*partition = biosdisk_findpartition(biosdev, sector);
+	(void)biosdisk_findpartition(biosdev, sector, partition, part_name);
 }
 
 #ifdef _STANDALONE
@@ -128,9 +129,9 @@ devopen(struct open_file *f, const char 
 	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 */
@@ -142,5 +143,26 @@ devopen(struct open_file *f, const char 
 	}
 #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, devname);
+	}
+#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, devname);
+	}
+#endif
+
+	error = dev2bios(devname, unit, &biosdev);
+	if (error)
+		return error;
+
 	return biosdisk_open(f, biosdev, partition);
 }

Index: src/sys/arch/i386/stand/boot/devopen.h
diff -u src/sys/arch/i386/stand/boot/devopen.h:1.4 src/sys/arch/i386/stand/boot/devopen.h:1.5
--- src/sys/arch/i386/stand/boot/devopen.h:1.4	Fri Dec 24 20:40:42 2010
+++ src/sys/arch/i386/stand/boot/devopen.h	Sun Aug 18 02:18:24 2019
@@ -1,5 +1,5 @@
-/*	$NetBSD: devopen.h,v 1.4 2010/12/24 20:40:42 jakllsch Exp $	*/
+/*	$NetBSD: devopen.h,v 1.5 2019/08/18 02:18:24 manu Exp $	*/
 
 extern int boot_biosdev;
 
-void bios2dev(int, daddr_t, char **, int *, int *);
+void bios2dev(int, daddr_t, char **, int *, int *, const char **);

Index: src/sys/arch/i386/stand/efiboot/boot.c
diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.13 src/sys/arch/i386/stand/efiboot/boot.c:1.14
--- src/sys/arch/i386/stand/efiboot/boot.c:1.13	Mon Jul 29 11:28:51 2019
+++ src/sys/arch/i386/stand/efiboot/boot.c	Sun Aug 18 02:18:24 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.13 2019/07/29 11:28:51 nonaka Exp $	*/
+/*	$NetBSD: boot.c,v 1.14 2019/08/18 02:18:24 manu Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -35,6 +35,7 @@
 #include "bootcfg.h"
 #include "bootmod.h"
 #include "bootmenu.h"
+#include "biosdisk.h"
 #include "devopen.h"
 
 int errno;
@@ -113,6 +114,7 @@ const struct bootblk_command commands[] 
 static char *default_devname;
 static int default_unit, default_partition;
 static const char *default_filename;
+static const char *default_part_name;
 
 static char *sprint_bootsel(const char *);
 static void bootit(const char *, int);
@@ -122,9 +124,15 @@ parsebootfile(const char *fname, char **
     int *partition, const char **file)
 {
 	const char *col;
+	static char savedevname[MAXDEVNAME+1];
 
 	*fsname = "ufs";
-	*devname = default_devname;
+	if (default_part_name == NULL) {
+		*devname = default_devname;
+	} else {
+		snprintf(savedevname, MAXDEVNAME, "NAME=%s", default_part_name);
+		*devname = savedevname;
+	}
 	*unit = default_unit;
 	*partition = default_partition;
 	*file = default_filename;
@@ -133,7 +141,6 @@ parsebootfile(const char *fname, char **
 		return 0;
 
 	if ((col = strchr(fname, ':')) != NULL) {	/* device given */
-		static char savedevname[MAXDEVNAME+1];
 		int devlen;
 		int u = 0, p = 0;
 		int i = 0;
@@ -142,6 +149,15 @@ parsebootfile(const char *fname, char **
 		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;
@@ -177,6 +193,7 @@ parsebootfile(const char *fname, char **
 		fname = col + 1;
 	}
 
+out:
 	if (*fname)
 		*file = fname;
 
@@ -193,8 +210,11 @@ snprint_bootdev(char *buf, size_t bufsiz
 	for (i = 0; i < __arraycount(no_partition_devs); i++)
 		if (strcmp(devname, no_partition_devs[i]) == 0)
 			break;
-	snprintf(buf, bufsize, "%s%d%c", devname, unit,
-	    i < __arraycount(no_partition_devs) ? '\0' : 'a' + partition);
+	if (strstr(devname, "NAME=") == devname)
+		strlcpy(buf, devname, bufsize);
+	else
+		snprintf(buf, bufsize, "%s%d%c", devname, unit,
+		  i < __arraycount(no_partition_devs) ? '\0' : 'a' + partition);
 	return buf;
 }
 
@@ -262,7 +282,7 @@ boot(void)
 
 	/* try to set default device to what BIOS tells us */
 	bios2dev(boot_biosdev, boot_biossector, &default_devname, &default_unit,
-	    &default_partition);
+	    &default_partition, &default_part_name);
 
 	/* if the user types "boot" without filename */
 	default_filename = DEFFILENAME;
@@ -339,24 +359,32 @@ command_help(char *arg)
 {
 
 	printf("commands are:\n"
-	       "boot [xdNx:][filename] [-12acdqsvxz]\n"
+	       "boot [dev:][filename] [-12acdqsvxz]\n"
+#ifndef NO_RAIDFRAME
+	       "     dev syntax is (hd|fd|cd|raid)[N[x]]\n"
+#else
+	       "     dev syntax is (hd|fd|cd)[N[x]]\n"
+#endif
+#ifndef NO_GPT
+	       "                or NAME=gpt_label\n"
+#endif
 	       "     (ex. \"hd0a:netbsd.old -s\")\n"
-	       "pkboot [xdNx:][filename] [-12acdqsvxz]\n"
-	       "dev [xd[N[x]]:]\n"
+	       "pkboot [dev:][filename] [-12acdqsvxz]\n"
+	       "dev [dev:]\n"
 	       "consdev {pc|com[0123][,{speed}]|com,{ioport}[,{speed}]}\n"
 	       "devpath\n"
 	       "efivar\n"
 	       "gop [{modenum|list}]\n"
 	       "load {path_to_module}\n"
 #if LIBSA_ENABLE_LS_OP
-	       "ls [path]\n"
+	       "ls [dev:][path]\n"
 #endif
 	       "memmap [{sorted|unsorted|compact}]\n"
 #ifndef SMALL
 	       "menu (reenters boot menu, if defined in boot.cfg)\n"
 #endif
 	       "modules {on|off|enabled|disabled}\n"
-	       "multiboot [xdNx:][filename] [<args>]\n"
+	       "multiboot [dev:][filename] [<args>]\n"
 	       "rndseed {path_to_rndseed_file}\n"
 	       "splash {path_to_image_file}\n"
 	       "text [{modenum|list}]\n"
@@ -433,8 +461,14 @@ command_dev(char *arg)
 	if (*arg == '\0') {
 		efi_disk_show();
 		efi_net_show();
-		printf("default %s\n", snprint_bootdev(buf, sizeof(buf),
-		    default_devname, default_unit, default_partition));
+	
+		if (default_part_name != NULL)
+			printf("default NAME=%s\n", default_part_name);
+		else
+			printf("default %s\n",
+			       snprint_bootdev(buf, sizeof(buf),
+					       default_devname, default_unit,
+					       default_partition));
 		return;
 	}
 
@@ -448,6 +482,10 @@ command_dev(char *arg)
 	/* put to own static storage */
 	strncpy(savedevname, devname, MAXDEVNAME + 1);
 	default_devname = savedevname;
+
+	/* +5 to skip leading NAME= */
+	if (strstr(devname, "NAME=") == devname)
+		default_part_name = default_devname + 5;
 }
 
 static const struct cons_devs {

Index: src/sys/arch/i386/stand/efiboot/devopen.c
diff -u src/sys/arch/i386/stand/efiboot/devopen.c:1.5 src/sys/arch/i386/stand/efiboot/devopen.c:1.6
--- src/sys/arch/i386/stand/efiboot/devopen.c:1.5	Wed Apr 11 10:32:09 2018
+++ src/sys/arch/i386/stand/efiboot/devopen.c	Sun Aug 18 02:18:24 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: devopen.c,v 1.5 2018/04/11 10:32:09 nonaka Exp $	 */
+/*	$NetBSD: devopen.c,v 1.6 2019/08/18 02:18:24 manu Exp $	 */
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -78,8 +78,10 @@ dev2bios(char *devname, int unit, int *b
 }
 
 void
-bios2dev(int biosdev, daddr_t sector, char **devname, int *unit, int *partition)
+bios2dev(int biosdev, daddr_t sector, char **devname, int *unit,
+	 int *partition, const char **part_name)
 {
+	static char savedevname[MAXDEVNAME+1];
 
 	*unit = biosdev & 0x7f;
 
@@ -96,7 +98,11 @@ bios2dev(int biosdev, daddr_t sector, ch
 	} else
 		*devname = "hd";
 
-	*partition = biosdisk_findpartition(biosdev, sector);
+	(void)biosdisk_findpartition(biosdev, sector, partition, part_name);
+	if (*part_name != NULL) {
+		snprintf(savedevname, MAXDEVNAME, "NAME=%s", *part_name);
+			*devname = savedevname;
+	}
 }
 
 struct btinfo_bootpath bibp;
@@ -130,6 +136,20 @@ devopen(struct open_file *f, const char 
 	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, devname);
+		return error;
+	}
+
 	memcpy(file_system, file_system_disk, sizeof(*file_system) * nfsys);
 	nfsys = nfsys_disk;
 
@@ -194,7 +214,7 @@ devopen(struct open_file *f, const char 
 	 */
 	if (strcmp(devname, "esp") == 0) {
 		bios2dev(boot_biosdev, boot_biossector, &devname, &unit,
-		    &partition);
+		    &partition, NULL);
 		if (efidisk_get_efi_system_partition(boot_biosdev, &partition))
 			return ENXIO;
 	}

Index: src/sys/arch/i386/stand/efiboot/devopen.h
diff -u src/sys/arch/i386/stand/efiboot/devopen.h:1.3 src/sys/arch/i386/stand/efiboot/devopen.h:1.4
--- src/sys/arch/i386/stand/efiboot/devopen.h:1.3	Wed Apr 11 10:32:09 2018
+++ src/sys/arch/i386/stand/efiboot/devopen.h	Sun Aug 18 02:18:24 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: devopen.h,v 1.3 2018/04/11 10:32:09 nonaka Exp $	*/
+/*	$NetBSD: devopen.h,v 1.4 2019/08/18 02:18:24 manu Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -34,9 +34,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 *);
+void bios2dev(int, daddr_t, char **, int *, int *, const char **);
 
 struct devdesc {
 	char	d_name[MAXDEVNAME];

Index: src/sys/arch/i386/stand/efiboot/efidisk.c
diff -u src/sys/arch/i386/stand/efiboot/efidisk.c:1.7 src/sys/arch/i386/stand/efiboot/efidisk.c:1.8
--- src/sys/arch/i386/stand/efiboot/efidisk.c:1.7	Wed Apr 17 06:50:34 2019
+++ src/sys/arch/i386/stand/efiboot/efidisk.c	Sun Aug 18 02:18:24 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: efidisk.c,v 1.7 2019/04/17 06:50:34 nonaka Exp $	*/
+/*	$NetBSD: efidisk.c,v 1.8 2019/08/18 02:18:24 manu Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -30,7 +30,9 @@
 
 #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"
@@ -40,6 +42,40 @@
 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)
 {
@@ -124,14 +160,51 @@ next:
 	}
 }
 
+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) {
@@ -164,7 +237,7 @@ efi_disk_show(void)
 		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++) {
@@ -172,11 +245,18 @@ efi_disk_show(void)
 				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)
@@ -187,7 +267,66 @@ efi_disk_show(void)
 		}
 		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);
 	}
 }
 
@@ -227,7 +366,7 @@ efidisk_get_efi_system_partition(int dev
 	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++) {
@@ -238,7 +377,7 @@ efidisk_get_efi_system_partition(int dev
 		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;
 

Index: src/sys/arch/i386/stand/lib/Makefile
diff -u src/sys/arch/i386/stand/lib/Makefile:1.45 src/sys/arch/i386/stand/lib/Makefile:1.46
--- src/sys/arch/i386/stand/lib/Makefile:1.45	Fri Feb  2 01:02:41 2018
+++ src/sys/arch/i386/stand/lib/Makefile	Sun Aug 18 02:18:25 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.45 2018/02/02 01:02:41 mrg Exp $
+#	$NetBSD: Makefile,v 1.46 2019/08/18 02:18:25 manu Exp $
 
 S?=	${.CURDIR}/../../../..
 
@@ -17,6 +17,7 @@ CPPFLAGS= -I$S/lib/libsa ${I386CPPFLAGS}
 #CPPFLAGS+= -DDISK_DEBUG
 #CPPFLAGS+= -DNO_DISKLABEL
 #CPPFLAGS+= -DNO_GPT
+#CPPFLAGS+= -DNO_RAIDFRAME
 #CPPFLAGS+= -DSAVE_MEMORY
 
 SRCS= pcio.c conio.S comio.S comio_direct.c biosvideomode.S

Index: src/sys/arch/i386/stand/lib/biosdisk.c
diff -u src/sys/arch/i386/stand/lib/biosdisk.c:1.49 src/sys/arch/i386/stand/lib/biosdisk.c:1.50
--- src/sys/arch/i386/stand/lib/biosdisk.c:1.49	Mon Apr  2 09:44:18 2018
+++ src/sys/arch/i386/stand/lib/biosdisk.c	Sun Aug 18 02:18:25 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: biosdisk.c,v 1.49 2018/04/02 09:44:18 nonaka Exp $	*/
+/*	$NetBSD: biosdisk.c,v 1.50 2019/08/18 02:18:25 manu Exp $	*/
 
 /*
  * Copyright (c) 1996, 1998
@@ -78,6 +78,7 @@
 #include <sys/uuid.h>
 
 #include <fs/cd9660/iso.h>
+#include <fs/unicode.h>
 
 #include <lib/libsa/saerrno.h>
 #include <machine/cpu.h>
@@ -89,6 +90,12 @@
 #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
@@ -104,6 +111,24 @@ struct biosdisk {
 #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;
@@ -111,7 +136,7 @@ const struct uuid GET_nbsd_lfs = GPT_ENT
 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;
@@ -157,7 +182,6 @@ const struct gpt_part gpt_parts[] = {
 	{ &GET_apple_ufs,	"Apple UFS" },
 	{ &GET_bios,		"BIOS Boot (GRUB)" },
 };
-#endif
 #endif /* NO_GPT */
 
 #ifdef _STANDALONE
@@ -167,12 +191,54 @@ static struct btinfo_bootwedge bi_wedge;
 
 #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)
@@ -228,7 +294,7 @@ alloc_biosdisk(int biosdev)
 #ifdef DISK_DEBUG
 		printf("no geometry information\n");
 #endif
-		dealloc(d, sizeof(*d));
+		dealloc_biosdisk(d);
 		return NULL;
 	}
 	return d;
@@ -262,8 +328,33 @@ guid_is_equal(const struct uuid *a, cons
 	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;
@@ -296,7 +387,7 @@ check_gpt(struct biosdisk *d, daddr_t se
 		return -1;
 	}
 
-	if (gpth.hdr_lba_self != sector)
+	if (gpth.hdr_lba_self + rf_offset != sector)
 		return -1;
 
 #ifdef _STANDALONE
@@ -308,7 +399,7 @@ check_gpt(struct biosdisk *d, daddr_t se
 
 	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;
@@ -344,7 +435,7 @@ check_gpt(struct biosdisk *d, daddr_t se
 					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++) {
@@ -352,6 +443,13 @@ check_gpt(struct biosdisk *d, daddr_t se
 						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++;
 			}
@@ -370,7 +468,7 @@ check_gpt(struct biosdisk *d, daddr_t se
 }
 
 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];
@@ -380,23 +478,30 @@ read_gpt(struct biosdisk *d)
 		/* 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;
 	}
@@ -546,7 +651,7 @@ check_cd9660(struct biosdisk *d)
 #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];
@@ -573,11 +678,11 @@ read_label(struct biosdisk *d)
 	 * 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);
@@ -607,14 +712,14 @@ read_label(struct biosdisk *d)
 					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++];
@@ -624,15 +729,15 @@ read_label(struct biosdisk *d)
 			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");
@@ -671,31 +776,74 @@ read_label(struct biosdisk *d)
 
 #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;
@@ -705,26 +853,31 @@ biosdisk_probe(void)
 
 	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))
@@ -738,38 +891,132 @@ biosdisk_probe(void)
 			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
+				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)
+
+			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
@@ -777,68 +1024,97 @@ biosdisk_probe(void)
  */
 
 int
-biosdisk_findpartition(int biosdev, daddr_t sector)
+biosdisk_findpartition(int biosdev, daddr_t sector,
+		       int *partition, const char **part_name)
 {
 #if defined(NO_DISKLABEL) && defined(NO_GPT)
+	*partition = 0;
+	*part_name = NULL;
 	return 0;
 #else
+	int i;
 	struct biosdisk *d;
-	int partition = 0;
-#ifdef EFIBOOT
-	int candidate = 0;
+	int biosboot_sector_part = -1;
+	int bootable_fs_part = -1;
+	int boot_part = 0;
+#ifndef NO_GPT
+	int gpt_bootme_part = -1;
+	static char namebuf[MAXDEVNAME + 1];
 #endif
 
 #ifdef DISK_DEBUG
 	printf("looking for partition device %x, sector %"PRId64"\n", biosdev, sector);
 #endif
 
+	/* default ot first partition */
+	*partition = 0;
+	*part_name = NULL;
+
 	/* Look for netbsd partition that is the dos boot one */
 	d = alloc_biosdisk(biosdev);
 	if (d == NULL)
-		return 0;
+		return -1;
 
-	if (read_partitions(d) == 0) {
-		for (partition = (BIOSDISKNPART-1); --partition;) {
-			if (d->part[partition].fstype == FS_UNUSED)
+	if (read_partitions(d, 0, 0) == 0) {
+		for (i = 0; i < BIOSDISKNPART; i++) {
+			if (d->part[i].fstype == FS_UNUSED)
 				continue;
-#ifdef EFIBOOT
-			switch (d->part[partition].fstype) {
+
+			if (d->part[i].offset == sector &&
+			    biosboot_sector_part == -1)
+				biosboot_sector_part = i;
+
+#ifndef NO_GPT
+			if (d->part[i].attr & GPT_ENT_ATTR_BOOTME &&
+			    gpt_bootme_part == -1)
+				gpt_bootme_part = i;
+#endif
+			switch (d->part[i].fstype) {
 			case FS_BSDFFS:
 			case FS_BSDLFS:
 			case FS_RAID:
 			case FS_CCD:
 			case FS_CGD:
 			case FS_ISO9660:
-				if (d->part[partition].attr & GPT_ENT_ATTR_BOOTME)
-					goto found;
-				candidate = partition;
+				if (bootable_fs_part == -1)
+					bootable_fs_part = i;
 				break;
 
 			default:
-				if (d->part[partition].attr & GPT_ENT_ATTR_BOOTME)
-					candidate = partition;
 				break;
 			}
-#else
-			if (d->part[partition].offset == sector)
-				break;
+		}
+
+#ifndef NO_GPT
+		if (gpt_bootme_part != -1)
+			boot_part = gpt_bootme_part;
+		else
 #endif
+		if (biosboot_sector_part != -1)
+			boot_part = biosboot_sector_part;
+		else if (bootable_fs_part != -1)
+			boot_part = bootable_fs_part;
+		else
+			boot_part = 0;
+
+		*partition = boot_part;
+#ifndef NO_GPT
+		if (part_name && d->part[boot_part].part_name) {
+			strlcpy(namebuf, d->part[boot_part].part_name,
+				BIOSDISK_PART_NAME_LEN);
+			*part_name = namebuf;
 		}
-#ifdef EFIBOOT
-found:
-		if (partition == 0 && candidate != 0)
-			partition = candidate;
 #endif
 	}
 
-	dealloc(d, sizeof(*d));
-	return partition;
+	dealloc_biosdisk(d);
+	return 0;
 #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;
@@ -852,27 +1128,70 @@ biosdisk_readpartition(int biosdev, stru
 	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)
@@ -886,6 +1205,39 @@ add_biosdisk_bootinfo(void)
 }
 #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 */
@@ -915,7 +1267,7 @@ biosdisk_open(struct open_file *f, ...)
 #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;
@@ -935,7 +1287,11 @@ biosdisk_open(struct open_file *f, ...)
 	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;
@@ -956,10 +1312,327 @@ nolabel:
 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("%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;
+
+	/*
+	 * If we did not get wedge match info from check_gpt()
+	 * compute it now.
+	 */
+	if (bi_wedge.matchblk == -1) {
+		if (readsects(&d->ll, offset, 1, d->buf, 1)) {
+#ifdef DISK_DEBUG
+       			printf("Error reading sector at %"PRId64"\n", offset);
+#endif
+			error =  EIO;
+			goto out;
+		}
+
+		bi_wedge.matchblk = offset;
+		bi_wedge.matchnblks = 1;
+
+		md5(bi_wedge.matchhash, d->buf, d->ll.secsize);
+	}
+#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)
@@ -970,7 +1643,7 @@ biosdisk_close(struct open_file *f)
 	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;
 }

Index: src/sys/arch/i386/stand/lib/biosdisk.h
diff -u src/sys/arch/i386/stand/lib/biosdisk.h:1.10 src/sys/arch/i386/stand/lib/biosdisk.h:1.11
--- src/sys/arch/i386/stand/lib/biosdisk.h:1.10	Mon Apr  2 09:44:18 2018
+++ src/sys/arch/i386/stand/lib/biosdisk.h	Sun Aug 18 02:18:25 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: biosdisk.h,v 1.10 2018/04/02 09:44:18 nonaka Exp $	*/
+/*	$NetBSD: biosdisk.h,v 1.11 2019/08/18 02:18:25 manu Exp $	*/
 
 /*
  * Copyright (c) 1996
@@ -25,25 +25,33 @@
  * 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_findpartition(int, daddr_t, int *, const char **);
+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;

Reply via email to