Page MenuHomeFreeBSD

D49355.id.diff
No OneTemporary

D49355.id.diff

diff --git a/stand/efi/include/efi.h b/stand/efi/include/efi.h
--- a/stand/efi/include/efi.h
+++ b/stand/efi/include/efi.h
@@ -74,14 +74,16 @@
#include "efidef.h"
#include "efidevp.h"
#include "efipciio.h"
-#include "efiprot.h"
#include "eficon.h"
+#include "efiapi.h"
+#include "efipart.h"
+#include "efigpt.h"
+#include "efiprot.h"
#include "eficonsctl.h"
#include "efiser.h"
#include "efi_nii.h"
#include "efipxebc.h"
#include "efinet.h"
-#include "efiapi.h"
#include "efifs.h"
#include "efierr.h"
#include "efigop.h"
@@ -90,6 +92,7 @@
#include "efitcp.h"
#include "efipoint.h"
#include "efiuga.h"
+#include "efichar.h"
#include <sys/types.h>
/*
diff --git a/stand/efi/include/efilib.h b/stand/efi/include/efilib.h
--- a/stand/efi/include/efilib.h
+++ b/stand/efi/include/efilib.h
@@ -40,6 +40,7 @@
extern struct devsw efipart_fddev;
extern struct devsw efipart_cddev;
extern struct devsw efipart_hddev;
+extern struct devsw efipart_label;
extern struct devsw efihttp_dev;
extern struct devsw efinet_dev;
extern struct netif_driver efinetif;
@@ -58,6 +59,7 @@
uint32_t pd_unit; /* unit number */
uint32_t pd_open; /* reference counter */
void *pd_bcache; /* buffer cache data */
+ char pd_volname[36*2];
struct pdinfo *pd_parent; /* Linked items (eg partitions) */
struct devsw *pd_devsw; /* Back pointer to devsw */
} pdinfo_t;
diff --git a/stand/efi/include/efiprot.h b/stand/efi/include/efiprot.h
--- a/stand/efi/include/efiprot.h
+++ b/stand/efi/include/efiprot.h
@@ -659,4 +659,41 @@
EFI_GET_BOOT_HARTID GetBootHartId;
} RISCV_EFI_BOOT_PROTOCOL;
+//
+// Partition Info Protocol
+//
+
+#define PARTITION_INFO_PROTOCOL \
+ { 0x8cf2f62c, 0xbc9b, 0x4821, {0x80, 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0} }
+
+INTERFACE_DECL(_EFI_PARTITION_INFO);
+
+#define EFI_PARTITION_INFO_INTERFACE_REVISION 0x0001000
+#define PARTITION_TYPE_OTHER 0x00
+#define PARTITION_TYPE_MBR 0x01
+#define PARTITION_TYPE_GPT 0x02
+
+#pragma pack(1)
+
+typedef struct _EFI_PARTITION_INFO {
+
+ UINT32 Revision;
+ UINT32 Type;
+ UINT8 System;
+ UINT8 Reserved[7];
+ union {
+ ///
+ /// MBR data
+ ///
+ MBR_PARTITION_RECORD Mbr;
+
+ ///
+ /// GPT data
+ ///
+ EFI_PARTITION_ENTRY Gpt;
+ } Info;
+} EFI_PARTITION_INFO;
+
+#pragma pack()
+
#endif
diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c
--- a/stand/efi/libefi/efipart.c
+++ b/stand/efi/libefi/efipart.c
@@ -35,11 +35,10 @@
#include <efi.h>
#include <efilib.h>
-#include <efiprot.h>
-#include <efichar.h>
#include <disk.h>
static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
+static EFI_GUID partinfo_guid = PARTITION_INFO_PROTOCOL;
typedef bool (*pd_test_cb_t)(pdinfo_t *, pdinfo_t *);
static int efipart_initfd(void);
@@ -58,6 +57,12 @@
static int efipart_printcd(int);
static int efipart_printhd(int);
+static int efipart_get_volname(EFI_HANDLE h, char *dest, int size);
+static int label_parsedev(struct devdesc **idev, const char *devspec, const char **path);
+
+static char *nullfmt(struct devdesc *vdev);
+static int nullinit(void);
+
/* EISA PNP ID's for floppy controllers */
#define PNP0604 0x604
#define PNP0700 0x700
@@ -104,6 +109,20 @@
.dv_parsedev = disk_parsedev,
};
+struct devsw efipart_label = {
+ .dv_name = "label",
+ .dv_type = DEVT_LABEL,
+ .dv_init = nullinit,
+ .dv_strategy = efipart_strategy,
+ .dv_open = efipart_open,
+ .dv_close = efipart_close,
+ .dv_ioctl = efipart_ioctl,
+ .dv_print = efipart_printhd,
+ .dv_cleanup = nullsys,
+ .dv_fmtdev = nullfmt,
+ .dv_parsedev = label_parsedev,
+};
+
static pdinfo_list_t fdinfo = STAILQ_HEAD_INITIALIZER(fdinfo);
static pdinfo_list_t cdinfo = STAILQ_HEAD_INITIALIZER(cdinfo);
static pdinfo_list_t hdinfo = STAILQ_HEAD_INITIALIZER(hdinfo);
@@ -406,6 +425,8 @@
pd->pd_handle = hin[i];
pd->pd_devpath = devpath;
pd->pd_blkio = blkio;
+ /* Do not fail here */
+ efipart_get_volname(hin[i], pd->pd_volname, sizeof(pd->pd_volname));
STAILQ_INSERT_TAIL(&pdinfo, pd, pd_link);
}
@@ -419,6 +440,20 @@
return (0);
}
+static int
+efipart_get_volname(EFI_HANDLE h, char *dest, int size)
+{
+ EFI_PARTITION_INFO *partinfo;
+ int status;
+
+ status = OpenProtocolByHandle(h, &partinfo_guid, (void **)&partinfo);
+ if (EFI_ERROR(status)) {
+ return (efi_status_to_errno(status));
+ }
+ cpy16to8(partinfo->Info.Gpt.PartitionName, dest, size);
+ return (0);
+}
+
/*
* Get node identified by pd_test() from plist.
*/
@@ -1249,3 +1284,99 @@
free(blkbuf);
return (rc);
}
+
+static pdinfo_t *
+label_lookup_part(const char *label, struct devsw **dev)
+{
+ pdinfo_t *dp, *pp;
+
+ /*
+ * Check hard disks, then cd, then floppy
+ */
+ STAILQ_FOREACH(dp, &hdinfo, pd_link) {
+ if (!strcmp(label, dp->pd_volname)) {
+ *dev = &efipart_hddev;
+ return (dp);
+ }
+ STAILQ_FOREACH(pp, &dp->pd_part, pd_link) {
+ if (!strcmp(label, pp->pd_volname)) {
+ *dev = &efipart_hddev;
+ return (pp);
+ }
+ }
+ }
+ STAILQ_FOREACH(dp, &cdinfo, pd_link) {
+ if (!strcmp(label, dp->pd_volname)) {
+ *dev = &efipart_cddev;
+ return (dp);
+ }
+ STAILQ_FOREACH(pp, &dp->pd_part, pd_link) {
+ if (!strcmp(label, pp->pd_volname)) {
+ *dev = &efipart_cddev;
+ return (pp);
+ }
+ }
+ }
+ STAILQ_FOREACH(dp, &fdinfo, pd_link) {
+ if (!strcmp(label, dp->pd_volname)) {
+ *dev = &efipart_fddev;
+ return (dp);
+ }
+ }
+ return (NULL);
+}
+
+static int
+label_parsedev(struct devdesc **idev, const char *devspec, const char **path)
+{
+ pdinfo_t *part;
+ const char *devspeci, *devspecp;
+ char *label;
+ struct disk_devdesc *dev;
+
+ if (strncmp(devspec, "label:", strlen("label:"))) {
+ return (EINVAL);
+ }
+ devspeci = devspec + strlen("label:");
+ devspecp = strchr(devspeci, ':');
+ if (devspecp == NULL) {
+ return (EINVAL);
+ }
+ label = malloc(devspecp - devspeci + 1);
+ if (label == NULL) {
+ return (ENOMEM);
+ }
+ memcpy(label, devspeci, devspecp - devspeci);
+ label[devspecp - devspeci] = 0;
+
+ dev = calloc(sizeof(*dev), 1);
+ if (dev == NULL)
+ return (ENOMEM);
+
+ part = label_lookup_part(label, &dev->dd.d_dev);
+ if (part == NULL) {
+ return (ENOENT);
+ }
+
+ dev->dd.d_unit = part->pd_parent->pd_unit;
+ dev->d_slice = part->pd_unit;
+ dev->d_partition = D_PARTISGPT;
+ *idev = &dev->dd;
+ if (path != NULL) {
+ *path = devspecp + 1;
+ }
+
+ return (0);
+}
+
+static char *
+nullfmt(struct devdesc *vdev)
+{
+ return ("");
+}
+
+static int
+nullinit(void)
+{
+ return (0);
+}
diff --git a/stand/efi/loader/conf.c b/stand/efi/loader/conf.c
--- a/stand/efi/loader/conf.c
+++ b/stand/efi/loader/conf.c
@@ -40,6 +40,7 @@
&efipart_fddev,
&efipart_cddev,
&efipart_hddev,
+ &efipart_label,
&efihttp_dev, /* ordering with efinet_dev matters */
#if defined(LOADER_NET_SUPPORT)
&efinet_dev,
diff --git a/stand/libsa/dev.c b/stand/libsa/dev.c
--- a/stand/libsa/dev.c
+++ b/stand/libsa/dev.c
@@ -139,7 +139,8 @@
if (err != 0)
return (err);
- idev->d_dev = dv;
+ if (idev->d_dev == NULL)
+ idev->d_dev = dv;
if (dev != NULL)
*dev = idev;
else
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -153,6 +153,7 @@
#define DEVT_CD 3
#define DEVT_ZFS 4
#define DEVT_FD 5
+#define DEVT_LABEL 6
int (*dv_init)(void); /* early probe call */
int (*dv_strategy)(void *devdata, int rw, daddr_t blk,
size_t size, char *buf, size_t *rsize);

File Metadata

Mime Type
text/plain
Expires
Thu, Jun 25, 9:13 AM (3 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34220723
Default Alt Text
D49355.id.diff (7 KB)

Event Timeline