|
|
5e6fc3 |
From 6b62aa40cfa1feb924609a065098da98c99e925c Mon Sep 17 00:00:00 2001
|
|
|
5e6fc3 |
From: Peter Jones <pjones@redhat.com>
|
|
|
5e6fc3 |
Date: Wed, 20 Jun 2018 14:45:14 -0400
|
|
|
5e6fc3 |
Subject: [PATCH 13/39] Make a platform ACPI root parser separate from PCI
|
|
|
5e6fc3 |
roots.
|
|
|
5e6fc3 |
|
|
|
5e6fc3 |
Because apparently PNP0A03 and PNP0A0C weren't good enough.
|
|
|
5e6fc3 |
|
|
|
5e6fc3 |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
5e6fc3 |
---
|
|
|
5e6fc3 |
src/linux-acpi-root.c | 199 ++++++++++++++++++++++++++++++++++++++++++
|
|
|
5e6fc3 |
src/linux-pci-root.c | 136 +++++++++++++++++++++++++++++
|
|
|
5e6fc3 |
src/linux-pci.c | 1 -
|
|
|
5e6fc3 |
src/linux.c | 4 +-
|
|
|
5e6fc3 |
src/linux.h | 4 +-
|
|
|
5e6fc3 |
5 files changed, 341 insertions(+), 3 deletions(-)
|
|
|
5e6fc3 |
create mode 100644 src/linux-acpi-root.c
|
|
|
5e6fc3 |
create mode 100644 src/linux-pci-root.c
|
|
|
5e6fc3 |
|
|
|
5e6fc3 |
diff --git a/src/linux-acpi-root.c b/src/linux-acpi-root.c
|
|
|
5e6fc3 |
new file mode 100644
|
|
|
5e6fc3 |
index 00000000000..c7d8276a642
|
|
|
5e6fc3 |
--- /dev/null
|
|
|
5e6fc3 |
+++ b/src/linux-acpi-root.c
|
|
|
5e6fc3 |
@@ -0,0 +1,199 @@
|
|
|
5e6fc3 |
+/*
|
|
|
5e6fc3 |
+ * libefiboot - library for the manipulation of EFI boot variables
|
|
|
5e6fc3 |
+ * Copyright 2012-2018 Red Hat, Inc.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * This library is free software; you can redistribute it and/or
|
|
|
5e6fc3 |
+ * modify it under the terms of the GNU Lesser General Public License as
|
|
|
5e6fc3 |
+ * published by the Free Software Foundation; either version 2.1 of the
|
|
|
5e6fc3 |
+ * License, or (at your option) any later version.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
5e6fc3 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
5e6fc3 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
5e6fc3 |
+ * Lesser General Public License for more details.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
5e6fc3 |
+ * License along with this library; if not, see
|
|
|
5e6fc3 |
+ * <http://www.gnu.org/licenses/>.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+#include "fix_coverity.h"
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+#include <errno.h>
|
|
|
5e6fc3 |
+#include <fcntl.h>
|
|
|
5e6fc3 |
+#include <inttypes.h>
|
|
|
5e6fc3 |
+#include <stdint.h>
|
|
|
5e6fc3 |
+#include <unistd.h>
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+#include "efiboot.h"
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+/*
|
|
|
5e6fc3 |
+ * support for ACPI-like platform root hub and devices
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * various devices /sys/dev/block/$major:$minor start with:
|
|
|
5e6fc3 |
+ * maj:min -> ../../devices/ACPI0000:00/$PCI_DEVICES/$BLOCKDEV_STUFF/block/$DISK/$PART
|
|
|
5e6fc3 |
+ * i.e.: APMC0D0D:00/ata1/host0/target0:0:0/0:0:0:0/block/sda
|
|
|
5e6fc3 |
+ * ^ root hub ^blockdev stuff
|
|
|
5e6fc3 |
+ * or:
|
|
|
5e6fc3 |
+ * maj:min -> ../../devices/ACPI0000:00/$PCI_DEVICES/$BLOCKDEV_STUFF/block/$DISK/$PART
|
|
|
5e6fc3 |
+ * i.e.: APMC0D0D:00/0000:00:1d.0/0000:05:00.0/ata1/host0/target0:0:0/0:0:0:0/block/sda
|
|
|
5e6fc3 |
+ * ^ root hub ^pci dev ^pci dev ^ blockdev stuff
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+static ssize_t
|
|
|
5e6fc3 |
+parse_acpi_root(struct device *dev, const char *current, const char *root UNUSED)
|
|
|
5e6fc3 |
+{
|
|
|
5e6fc3 |
+ int rc;
|
|
|
5e6fc3 |
+ int pos;
|
|
|
5e6fc3 |
+ uint16_t pad0;
|
|
|
5e6fc3 |
+ uint8_t pad1;
|
|
|
5e6fc3 |
+ char *acpi_header = NULL;
|
|
|
5e6fc3 |
+ char *colon;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ const char *devpart = current;
|
|
|
5e6fc3 |
+ char *spaces;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ pos = strlen(current);
|
|
|
5e6fc3 |
+ spaces = alloca(pos+1);
|
|
|
5e6fc3 |
+ memset(spaces, ' ', pos+1);
|
|
|
5e6fc3 |
+ spaces[pos] = '\0';
|
|
|
5e6fc3 |
+ pos = 0;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ debug(DEBUG, "entry");
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ /*
|
|
|
5e6fc3 |
+ * find the ACPI root dunno0 and dunno1; they basically look like:
|
|
|
5e6fc3 |
+ * ABCD0000:00/
|
|
|
5e6fc3 |
+ * ^d0 ^d1
|
|
|
5e6fc3 |
+ * This is annoying because "/%04ms%h:%hhx/" won't bind from the right
|
|
|
5e6fc3 |
+ * side in sscanf.
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+ rc = sscanf(devpart, "../../devices/platform/%n", &pos;;
|
|
|
5e6fc3 |
+ debug(DEBUG, "devpart:\"%s\" rc:%d pos:%d", devpart, rc, pos);
|
|
|
5e6fc3 |
+ if (rc != 0 || pos < 1)
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+ devpart += pos;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ /*
|
|
|
5e6fc3 |
+ * If it's too short to be A0000:00, it's not an ACPI string
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+ if (strlen(devpart) < 8)
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ colon = strchr(devpart, ':');
|
|
|
5e6fc3 |
+ if (!colon)
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+ pos = colon - devpart;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ /*
|
|
|
5e6fc3 |
+ * If colon doesn't point at something between one of these:
|
|
|
5e6fc3 |
+ * A0000:00 ACPI0000:00
|
|
|
5e6fc3 |
+ * ^ 5 ^ 8
|
|
|
5e6fc3 |
+ * Then it's not an ACPI string.
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+ if (pos < 5 || pos > 8)
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid_str = strndup(devpart, pos + 1);
|
|
|
5e6fc3 |
+ if (!dev->acpi_root.acpi_hid_str) {
|
|
|
5e6fc3 |
+ efi_error("Could not allocate memory");
|
|
|
5e6fc3 |
+ return -1;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid_str[pos] = 0;
|
|
|
5e6fc3 |
+ debug(DEBUG, "acpi_hid_str:\"%s\"", dev->acpi_root.acpi_hid_str);
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ pos -= 4;
|
|
|
5e6fc3 |
+ debug(DEBUG, "devpart:\"%s\" rc:%d pos:%d", devpart, rc, pos);
|
|
|
5e6fc3 |
+ acpi_header = strndupa(devpart, pos);
|
|
|
5e6fc3 |
+ if (!acpi_header)
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+ acpi_header[pos] = 0;
|
|
|
5e6fc3 |
+ debug(DEBUG, "devpart:\"%s\" acpi_header:\"%s\"", devpart, acpi_header);
|
|
|
5e6fc3 |
+ devpart += pos;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ /*
|
|
|
5e6fc3 |
+ * If we can't find these numbers, it's not an ACPI string
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+ rc = sscanf(devpart, "%hx:%hhx/%n", &pad0, &pad1, &pos;;
|
|
|
5e6fc3 |
+ if (rc != 2) {
|
|
|
5e6fc3 |
+ efi_error("Could not parse ACPI path \"%s\"", devpart);
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ debug(DEBUG, "devpart:\"%s\" parsed:%04hx:%02hhx pos:%d rc:%d",
|
|
|
5e6fc3 |
+ devpart, pad0, pad1, pos, rc);
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ devpart += pos;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ rc = parse_acpi_hid_uid(dev, "devices/platform/%s%04hX:%02hhX",
|
|
|
5e6fc3 |
+ acpi_header, pad0, pad1);
|
|
|
5e6fc3 |
+ debug(DEBUG, "rc:%d acpi_header:%s pad0:%04hX pad1:%02hhX",
|
|
|
5e6fc3 |
+ rc, acpi_header, pad0, pad1);
|
|
|
5e6fc3 |
+ if (rc < 0 && errno == ENOENT) {
|
|
|
5e6fc3 |
+ rc = parse_acpi_hid_uid(dev, "devices/platform/%s%04hx:%02hhx",
|
|
|
5e6fc3 |
+ acpi_header, pad0, pad1);
|
|
|
5e6fc3 |
+ debug(DEBUG, "rc:%d acpi_header:%s pad0:%04hx pad1:%02hhx",
|
|
|
5e6fc3 |
+ rc, acpi_header, pad0, pad1);
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ if (rc < 0) {
|
|
|
5e6fc3 |
+ efi_error("Could not parse hid/uid");
|
|
|
5e6fc3 |
+ return rc;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ debug(DEBUG, "Parsed HID:0x%08x UID:0x%"PRIx64" uidstr:\"%s\" path:\"%s\"",
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid, dev->acpi_root.acpi_uid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid_str,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_cid_str);
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ return devpart - current;
|
|
|
5e6fc3 |
+}
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+static ssize_t
|
|
|
5e6fc3 |
+dp_create_acpi_root(struct device *dev,
|
|
|
5e6fc3 |
+ uint8_t *buf, ssize_t size, ssize_t off)
|
|
|
5e6fc3 |
+{
|
|
|
5e6fc3 |
+ ssize_t sz = 0, new = 0;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ debug(DEBUG, "entry buf:%p size:%zd off:%zd", buf, size, off);
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ if (dev->acpi_root.acpi_uid_str || dev->acpi_root.acpi_cid_str) {
|
|
|
5e6fc3 |
+ debug(DEBUG, "creating acpi_hid_ex dp hid:0x%08x uid:0x%"PRIx64" uidstr:\"%s\" cidstr:\"%s\"",
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid, dev->acpi_root.acpi_uid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid_str, dev->acpi_root.acpi_cid_str);
|
|
|
5e6fc3 |
+ new = efidp_make_acpi_hid_ex(buf + off, size ? size - off : 0,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_cid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid_str,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid_str,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_cid_str);
|
|
|
5e6fc3 |
+ if (new < 0) {
|
|
|
5e6fc3 |
+ efi_error("efidp_make_acpi_hid_ex() failed");
|
|
|
5e6fc3 |
+ return new;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ } else {
|
|
|
5e6fc3 |
+ debug(DEBUG, "creating acpi_hid dp hid:0x%08x uid:0x%0"PRIx64,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid);
|
|
|
5e6fc3 |
+ new = efidp_make_acpi_hid(buf + off, size ? size - off : 0,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid);
|
|
|
5e6fc3 |
+ if (new < 0) {
|
|
|
5e6fc3 |
+ efi_error("efidp_make_acpi_hid() failed");
|
|
|
5e6fc3 |
+ return new;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ off += new;
|
|
|
5e6fc3 |
+ sz += new;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ debug(DEBUG, "returning %zd", sz);
|
|
|
5e6fc3 |
+ return sz;
|
|
|
5e6fc3 |
+}
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+enum interface_type acpi_root_iftypes[] = { acpi_root, unknown };
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+struct dev_probe HIDDEN acpi_root_parser = {
|
|
|
5e6fc3 |
+ .name = "acpi_root",
|
|
|
5e6fc3 |
+ .iftypes = acpi_root_iftypes,
|
|
|
5e6fc3 |
+ .flags = DEV_PROVIDES_ROOT,
|
|
|
5e6fc3 |
+ .parse = parse_acpi_root,
|
|
|
5e6fc3 |
+ .create = dp_create_acpi_root,
|
|
|
5e6fc3 |
+};
|
|
|
5e6fc3 |
diff --git a/src/linux-pci-root.c b/src/linux-pci-root.c
|
|
|
5e6fc3 |
new file mode 100644
|
|
|
5e6fc3 |
index 00000000000..8f556a066f3
|
|
|
5e6fc3 |
--- /dev/null
|
|
|
5e6fc3 |
+++ b/src/linux-pci-root.c
|
|
|
5e6fc3 |
@@ -0,0 +1,136 @@
|
|
|
5e6fc3 |
+/*
|
|
|
5e6fc3 |
+ * libefiboot - library for the manipulation of EFI boot variables
|
|
|
5e6fc3 |
+ * Copyright 2012-2018 Red Hat, Inc.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * This library is free software; you can redistribute it and/or
|
|
|
5e6fc3 |
+ * modify it under the terms of the GNU Lesser General Public License as
|
|
|
5e6fc3 |
+ * published by the Free Software Foundation; either version 2.1 of the
|
|
|
5e6fc3 |
+ * License, or (at your option) any later version.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
5e6fc3 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
5e6fc3 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
5e6fc3 |
+ * Lesser General Public License for more details.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
5e6fc3 |
+ * License along with this library; if not, see
|
|
|
5e6fc3 |
+ * <http://www.gnu.org/licenses/>.
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+#include "fix_coverity.h"
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+#include <errno.h>
|
|
|
5e6fc3 |
+#include <fcntl.h>
|
|
|
5e6fc3 |
+#include <inttypes.h>
|
|
|
5e6fc3 |
+#include <stdint.h>
|
|
|
5e6fc3 |
+#include <unistd.h>
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+#include "efiboot.h"
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+/*
|
|
|
5e6fc3 |
+ * support for PCI root hub and devices
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * various devices /sys/dev/block/$major:$minor start with:
|
|
|
5e6fc3 |
+ * maj:min -> ../../devices/pci$PCIROOT/$PCI_DEVICES/$BLOCKDEV_STUFF/block/$DISK/$PART
|
|
|
5e6fc3 |
+ * i.e.: pci0000:00/0000:00:1d.0/0000:05:00.0/
|
|
|
5e6fc3 |
+ * ^ root hub ^device ^device
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ * for network devices, we also get:
|
|
|
5e6fc3 |
+ * /sys/class/net/$IFACE -> ../../devices/$PCI_STUFF/net/$IFACE
|
|
|
5e6fc3 |
+ *
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+static ssize_t
|
|
|
5e6fc3 |
+parse_pci_root(struct device *dev, const char *current, const char *root UNUSED)
|
|
|
5e6fc3 |
+{
|
|
|
5e6fc3 |
+ int rc;
|
|
|
5e6fc3 |
+ int pos;
|
|
|
5e6fc3 |
+ uint16_t root_domain;
|
|
|
5e6fc3 |
+ uint8_t root_bus;
|
|
|
5e6fc3 |
+ const char *devpart = current;
|
|
|
5e6fc3 |
+ char *spaces;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ pos = strlen(current);
|
|
|
5e6fc3 |
+ spaces = alloca(pos+1);
|
|
|
5e6fc3 |
+ memset(spaces, ' ', pos+1);
|
|
|
5e6fc3 |
+ spaces[pos] = '\0';
|
|
|
5e6fc3 |
+ pos = 0;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ debug(DEBUG, "entry");
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ /*
|
|
|
5e6fc3 |
+ * find the pci root domain and port; they basically look like:
|
|
|
5e6fc3 |
+ * pci0000:00/
|
|
|
5e6fc3 |
+ * ^d ^p
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+ rc = sscanf(devpart, "../../devices/pci%hx:%hhx/%n", &root_domain, &root_bus, &pos;;
|
|
|
5e6fc3 |
+ /*
|
|
|
5e6fc3 |
+ * If we can't find that, it's not a PCI device.
|
|
|
5e6fc3 |
+ */
|
|
|
5e6fc3 |
+ if (rc != 2)
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+ devpart += pos;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ dev->pci_root.pci_domain = root_domain;
|
|
|
5e6fc3 |
+ dev->pci_root.pci_bus = root_bus;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ rc = parse_acpi_hid_uid(dev, "devices/pci%04hx:%02hhx",
|
|
|
5e6fc3 |
+ root_domain, root_bus);
|
|
|
5e6fc3 |
+ if (rc < 0)
|
|
|
5e6fc3 |
+ return -1;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ errno = 0;
|
|
|
5e6fc3 |
+ return devpart - current;
|
|
|
5e6fc3 |
+}
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+static ssize_t
|
|
|
5e6fc3 |
+dp_create_pci_root(struct device *dev UNUSED,
|
|
|
5e6fc3 |
+ uint8_t *buf, ssize_t size, ssize_t off)
|
|
|
5e6fc3 |
+{
|
|
|
5e6fc3 |
+ debug(DEBUG, "entry buf:%p size:%zd off:%zd", buf, size, off);
|
|
|
5e6fc3 |
+ debug(DEBUG, "returning 0");
|
|
|
5e6fc3 |
+#if 0
|
|
|
5e6fc3 |
+ if (dev->acpi_root.acpi_uid_str) {
|
|
|
5e6fc3 |
+ debug(DEBUG, "creating acpi_hid_ex dp hid:0x%08x uid:\"%s\"",
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid_str);
|
|
|
5e6fc3 |
+ new = efidp_make_acpi_hid_ex(buf + off, size ? size - off : 0,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ 0, 0, "",
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid_str,
|
|
|
5e6fc3 |
+ "");
|
|
|
5e6fc3 |
+ if (new < 0) {
|
|
|
5e6fc3 |
+ efi_error("efidp_make_acpi_hid_ex() failed");
|
|
|
5e6fc3 |
+ return new;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ } else {
|
|
|
5e6fc3 |
+ debug(DEBUG, "creating acpi_hid dp hid:0x%08x uid:0x%0"PRIx64,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid);
|
|
|
5e6fc3 |
+ new = efidp_make_acpi_hid(buf + off, size ? size - off : 0,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_hid,
|
|
|
5e6fc3 |
+ dev->acpi_root.acpi_uid);
|
|
|
5e6fc3 |
+ if (new < 0) {
|
|
|
5e6fc3 |
+ efi_error("efidp_make_acpi_hid() failed");
|
|
|
5e6fc3 |
+ return new;
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ }
|
|
|
5e6fc3 |
+ off += new;
|
|
|
5e6fc3 |
+ sz += new;
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+ debug(DEBUG, "returning %zd", sz);
|
|
|
5e6fc3 |
+ return sz;
|
|
|
5e6fc3 |
+#else
|
|
|
5e6fc3 |
+ return 0;
|
|
|
5e6fc3 |
+#endif
|
|
|
5e6fc3 |
+}
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+enum interface_type pci_root_iftypes[] = { pci_root, unknown };
|
|
|
5e6fc3 |
+
|
|
|
5e6fc3 |
+struct dev_probe HIDDEN pci_root_parser = {
|
|
|
5e6fc3 |
+ .name = "pci_root",
|
|
|
5e6fc3 |
+ .iftypes = pci_root_iftypes,
|
|
|
5e6fc3 |
+ .flags = DEV_PROVIDES_ROOT,
|
|
|
5e6fc3 |
+ .parse = parse_pci_root,
|
|
|
5e6fc3 |
+ .create = dp_create_pci_root,
|
|
|
5e6fc3 |
+};
|
|
|
5e6fc3 |
diff --git a/src/linux-pci.c b/src/linux-pci.c
|
|
|
5e6fc3 |
index aa3e40c0f7c..0f59d3e840d 100644
|
|
|
5e6fc3 |
--- a/src/linux-pci.c
|
|
|
5e6fc3 |
+++ b/src/linux-pci.c
|
|
|
5e6fc3 |
@@ -147,7 +147,6 @@ enum interface_type pci_iftypes[] = { pci, unknown };
|
|
|
5e6fc3 |
struct dev_probe HIDDEN pci_parser = {
|
|
|
5e6fc3 |
.name = "pci",
|
|
|
5e6fc3 |
.iftypes = pci_iftypes,
|
|
|
5e6fc3 |
- .flags = DEV_PROVIDES_ROOT,
|
|
|
5e6fc3 |
.parse = parse_pci,
|
|
|
5e6fc3 |
.create = dp_create_pci,
|
|
|
5e6fc3 |
};
|
|
|
5e6fc3 |
diff --git a/src/linux.c b/src/linux.c
|
|
|
5e6fc3 |
index 9f3a22f7025..436fb882a98 100644
|
|
|
5e6fc3 |
--- a/src/linux.c
|
|
|
5e6fc3 |
+++ b/src/linux.c
|
|
|
5e6fc3 |
@@ -235,6 +235,8 @@ static struct dev_probe *dev_probes[] = {
|
|
|
5e6fc3 |
* be found first.
|
|
|
5e6fc3 |
*/
|
|
|
5e6fc3 |
&pmem_parser,
|
|
|
5e6fc3 |
+ &acpi_root_parser,
|
|
|
5e6fc3 |
+ &pci_root_parser,
|
|
|
5e6fc3 |
&pci_parser,
|
|
|
5e6fc3 |
&virtblk_parser,
|
|
|
5e6fc3 |
&sas_parser,
|
|
|
5e6fc3 |
@@ -447,7 +449,7 @@ struct device HIDDEN
|
|
|
5e6fc3 |
}
|
|
|
5e6fc3 |
debug(DEBUG, "%s matched %s", probe->name, current);
|
|
|
5e6fc3 |
|
|
|
5e6fc3 |
- if (probe->flags & DEV_PROVIDES_HD)
|
|
|
5e6fc3 |
+ if (probe->flags & DEV_PROVIDES_HD || probe->flags & DEV_PROVIDES_ROOT)
|
|
|
5e6fc3 |
needs_root = false;
|
|
|
5e6fc3 |
dev->probes[n++] = dev_probes[i];
|
|
|
5e6fc3 |
current += pos;
|
|
|
5e6fc3 |
diff --git a/src/linux.h b/src/linux.h
|
|
|
5e6fc3 |
index aa9e3d14a83..7b18bda31c6 100644
|
|
|
5e6fc3 |
--- a/src/linux.h
|
|
|
5e6fc3 |
+++ b/src/linux.h
|
|
|
5e6fc3 |
@@ -95,7 +95,7 @@ struct nvdimm_info {
|
|
|
5e6fc3 |
|
|
|
5e6fc3 |
enum interface_type {
|
|
|
5e6fc3 |
unknown,
|
|
|
5e6fc3 |
- isa, pci, network,
|
|
|
5e6fc3 |
+ isa, acpi_root, pci_root, pci, network,
|
|
|
5e6fc3 |
ata, atapi, scsi, sata, sas,
|
|
|
5e6fc3 |
usb, i1394, fibre, i2o,
|
|
|
5e6fc3 |
md, virtblk,
|
|
|
5e6fc3 |
@@ -264,6 +264,8 @@ extern ssize_t parse_scsi_link(const char *current, uint32_t *host,
|
|
|
5e6fc3 |
|
|
|
5e6fc3 |
/* device support implementations */
|
|
|
5e6fc3 |
extern struct dev_probe pmem_parser;
|
|
|
5e6fc3 |
+extern struct dev_probe pci_root_parser;
|
|
|
5e6fc3 |
+extern struct dev_probe acpi_root_parser;
|
|
|
5e6fc3 |
extern struct dev_probe pci_parser;
|
|
|
5e6fc3 |
extern struct dev_probe sas_parser;
|
|
|
5e6fc3 |
extern struct dev_probe sata_parser;
|
|
|
5e6fc3 |
--
|
|
|
5e6fc3 |
2.17.1
|
|
|
5e6fc3 |
|