|
|
36520b |
From d6a526a0c819c439a894af625f45b657576f8744 Mon Sep 17 00:00:00 2001
|
|
|
36520b |
From: Alek Du <alek.du@intel.com>
|
|
|
36520b |
Date: Fri, 27 Jul 2018 21:31:01 +0800
|
|
|
36520b |
Subject: [PATCH 27/39] emmc_parser: add emmc_parser
|
|
|
36520b |
|
|
|
36520b |
Signed-off-by: Alek Du <alek.du@intel.com>
|
|
|
36520b |
---
|
|
|
36520b |
src/dp-message.c | 18 +++++
|
|
|
36520b |
src/linux-emmc.c | 129 +++++++++++++++++++++++++++++++++
|
|
|
36520b |
src/linux.c | 1 +
|
|
|
36520b |
src/include/efivar/efivar-dp.h | 2 +
|
|
|
36520b |
src/linux.h | 7 ++
|
|
|
36520b |
src/libefivar.map.in | 1 +
|
|
|
36520b |
6 files changed, 158 insertions(+)
|
|
|
36520b |
create mode 100644 src/linux-emmc.c
|
|
|
36520b |
|
|
|
36520b |
diff --git a/src/dp-message.c b/src/dp-message.c
|
|
|
36520b |
index 5af66438bfc..3724e5f57bd 100644
|
|
|
36520b |
--- a/src/dp-message.c
|
|
|
36520b |
+++ b/src/dp-message.c
|
|
|
36520b |
@@ -826,3 +826,21 @@ efidp_make_nvdimm(uint8_t *buf, ssize_t size, efi_guid_t *uuid)
|
|
|
36520b |
|
|
|
36520b |
return sz;
|
|
|
36520b |
}
|
|
|
36520b |
+
|
|
|
36520b |
+ssize_t PUBLIC
|
|
|
36520b |
+efidp_make_emmc(uint8_t *buf, ssize_t size, uint32_t slot_id)
|
|
|
36520b |
+{
|
|
|
36520b |
+ efidp_emmc *emmc = (efidp_emmc *)buf;
|
|
|
36520b |
+ ssize_t req = sizeof (*emmc);
|
|
|
36520b |
+ ssize_t sz;
|
|
|
36520b |
+
|
|
|
36520b |
+ sz = efidp_make_generic(buf, size, EFIDP_MESSAGE_TYPE,
|
|
|
36520b |
+ EFIDP_MSG_NVME, sizeof (*emmc));
|
|
|
36520b |
+ if (size && sz == req)
|
|
|
36520b |
+ emmc->slot = slot_id;
|
|
|
36520b |
+
|
|
|
36520b |
+ if (sz < 0)
|
|
|
36520b |
+ efi_error("efidp_make_generic failed");
|
|
|
36520b |
+
|
|
|
36520b |
+ return sz;
|
|
|
36520b |
+}
|
|
|
36520b |
diff --git a/src/linux-emmc.c b/src/linux-emmc.c
|
|
|
36520b |
new file mode 100644
|
|
|
36520b |
index 00000000000..f0c9e635cb6
|
|
|
36520b |
--- /dev/null
|
|
|
36520b |
+++ b/src/linux-emmc.c
|
|
|
36520b |
@@ -0,0 +1,129 @@
|
|
|
36520b |
+/*
|
|
|
36520b |
+ * libefiboot - library for the manipulation of EFI boot variables
|
|
|
36520b |
+ * Copyright 2012-2018 Red Hat, Inc.
|
|
|
36520b |
+ *
|
|
|
36520b |
+ * This library is free software; you can redistribute it and/or
|
|
|
36520b |
+ * modify it under the terms of the GNU Lesser General Public License as
|
|
|
36520b |
+ * published by the Free Software Foundation; either version 2.1 of the
|
|
|
36520b |
+ * License, or (at your option) any later version.
|
|
|
36520b |
+ *
|
|
|
36520b |
+ * This library is distributed in the hope that it will be useful,
|
|
|
36520b |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
36520b |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
36520b |
+ * Lesser General Public License for more details.
|
|
|
36520b |
+ *
|
|
|
36520b |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
36520b |
+ * License along with this library; if not, see
|
|
|
36520b |
+ * <http://www.gnu.org/licenses/>.
|
|
|
36520b |
+ *
|
|
|
36520b |
+ */
|
|
|
36520b |
+
|
|
|
36520b |
+#include "fix_coverity.h"
|
|
|
36520b |
+
|
|
|
36520b |
+#include <errno.h>
|
|
|
36520b |
+#include <fcntl.h>
|
|
|
36520b |
+#include <inttypes.h>
|
|
|
36520b |
+#include <stdint.h>
|
|
|
36520b |
+#include <unistd.h>
|
|
|
36520b |
+
|
|
|
36520b |
+#include "efiboot.h"
|
|
|
36520b |
+
|
|
|
36520b |
+/*
|
|
|
36520b |
+ * support for emmc devices
|
|
|
36520b |
+ *
|
|
|
36520b |
+ * /sys/dev/block/$major:$minor looks like:
|
|
|
36520b |
+ * 179:0 -> ../../devices/pci0000:00/0000:00:1c.0/mmc_host/mmc0/mmc0:0001/block/mmcblk0
|
|
|
36520b |
+ * 179:1 -> ../../devices/pci0000:00/0000:00:1c.0/mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1
|
|
|
36520b |
+ *
|
|
|
36520b |
+ * /sys/dev/block/179:0/device looks like:
|
|
|
36520b |
+ * device -> ../../../mmc0:0001
|
|
|
36520b |
+ *
|
|
|
36520b |
+ * /sys/dev/block/179:1/partition looks like:
|
|
|
36520b |
+ * $ cat partition
|
|
|
36520b |
+ * 1
|
|
|
36520b |
+ *
|
|
|
36520b |
+ */
|
|
|
36520b |
+
|
|
|
36520b |
+static ssize_t
|
|
|
36520b |
+parse_emmc(struct device *dev, const char *current, const char *root UNUSED)
|
|
|
36520b |
+{
|
|
|
36520b |
+ int rc;
|
|
|
36520b |
+ int32_t tosser0, tosser1, tosser2, tosser3, slot_id, partition;
|
|
|
36520b |
+ int pos0 = 0, pos1 = 0;
|
|
|
36520b |
+ char *spaces;
|
|
|
36520b |
+
|
|
|
36520b |
+ pos0 = strlen(current);
|
|
|
36520b |
+ spaces = alloca(pos0+1);
|
|
|
36520b |
+ memset(spaces, ' ', pos0+1);
|
|
|
36520b |
+ spaces[pos0] = '\0';
|
|
|
36520b |
+ pos0 = 0;
|
|
|
36520b |
+
|
|
|
36520b |
+ debug(DEBUG, "entry");
|
|
|
36520b |
+
|
|
|
36520b |
+ debug(DEBUG, "searching for mmc_host/mmc0/mmc0:0001/block/mmcblk0 or mmc_host/mmc0/mmc0:0001/block/mmcblk0/mmcblk0p1");
|
|
|
36520b |
+ rc = sscanf(current, "mmc_host/mmc%d/mmc%d:%d/block/mmcblk%d%n/mmcblk%dp%d%n",
|
|
|
36520b |
+ &tosser0, &tosser1, &tosser2, &slot_id,
|
|
|
36520b |
+ &pos0, &tosser3, &partition, &pos1);
|
|
|
36520b |
+ debug(DEBUG, "current:\"%s\" rc:%d pos0:%d pos1:%d\n", current, rc, pos0, pos1);
|
|
|
36520b |
+ arrow(DEBUG, spaces, 9, pos0, rc, 4);
|
|
|
36520b |
+ arrow(DEBUG, spaces, 9, pos1, rc, 6);
|
|
|
36520b |
+ /*
|
|
|
36520b |
+ * If it isn't of that form, it's not one of our emmc devices.
|
|
|
36520b |
+ */
|
|
|
36520b |
+ if (rc != 4 && rc != 6)
|
|
|
36520b |
+ return 0;
|
|
|
36520b |
+
|
|
|
36520b |
+ dev->emmc_info.slot_id = slot_id;
|
|
|
36520b |
+ dev->interface_type = emmc;
|
|
|
36520b |
+
|
|
|
36520b |
+ if (rc == 6) {
|
|
|
36520b |
+ if (dev->part == -1)
|
|
|
36520b |
+ dev->part = partition;
|
|
|
36520b |
+
|
|
|
36520b |
+ pos0 = pos1;
|
|
|
36520b |
+ }
|
|
|
36520b |
+
|
|
|
36520b |
+ return pos0;
|
|
|
36520b |
+}
|
|
|
36520b |
+
|
|
|
36520b |
+static ssize_t
|
|
|
36520b |
+dp_create_emmc(struct device *dev,
|
|
|
36520b |
+ uint8_t *buf, ssize_t size, ssize_t off)
|
|
|
36520b |
+{
|
|
|
36520b |
+ ssize_t sz;
|
|
|
36520b |
+
|
|
|
36520b |
+ debug(DEBUG, "entry");
|
|
|
36520b |
+
|
|
|
36520b |
+ sz = efidp_make_emmc(buf + off, size ? size - off : 0,
|
|
|
36520b |
+ dev->emmc_info.slot_id);
|
|
|
36520b |
+ return sz;
|
|
|
36520b |
+}
|
|
|
36520b |
+
|
|
|
36520b |
+static char *
|
|
|
36520b |
+make_part_name(struct device *dev)
|
|
|
36520b |
+{
|
|
|
36520b |
+ char *ret = NULL;
|
|
|
36520b |
+ ssize_t rc;
|
|
|
36520b |
+
|
|
|
36520b |
+ if (dev->part < 1)
|
|
|
36520b |
+ return NULL;
|
|
|
36520b |
+
|
|
|
36520b |
+ rc = asprintf(&ret, "%sp%d", dev->disk_name, dev->part);
|
|
|
36520b |
+ if (rc < 0) {
|
|
|
36520b |
+ efi_error("could not allocate memory");
|
|
|
36520b |
+ return NULL;
|
|
|
36520b |
+ }
|
|
|
36520b |
+
|
|
|
36520b |
+ return ret;
|
|
|
36520b |
+}
|
|
|
36520b |
+
|
|
|
36520b |
+static enum interface_type emmc_iftypes[] = { emmc, unknown };
|
|
|
36520b |
+
|
|
|
36520b |
+struct dev_probe HIDDEN emmc_parser = {
|
|
|
36520b |
+ .name = "emmc",
|
|
|
36520b |
+ .iftypes = emmc_iftypes,
|
|
|
36520b |
+ .flags = DEV_PROVIDES_HD,
|
|
|
36520b |
+ .parse = parse_emmc,
|
|
|
36520b |
+ .create = dp_create_emmc,
|
|
|
36520b |
+ .make_part_name = make_part_name,
|
|
|
36520b |
+};
|
|
|
36520b |
diff --git a/src/linux.c b/src/linux.c
|
|
|
36520b |
index 7fac339c50e..ff8db812ad3 100644
|
|
|
36520b |
--- a/src/linux.c
|
|
|
36520b |
+++ b/src/linux.c
|
|
|
36520b |
@@ -246,6 +246,7 @@ static struct dev_probe *dev_probes[] = {
|
|
|
36520b |
&ata_parser,
|
|
|
36520b |
&scsi_parser,
|
|
|
36520b |
&i2o_parser,
|
|
|
36520b |
+ &emmc_parser,
|
|
|
36520b |
NULL
|
|
|
36520b |
};
|
|
|
36520b |
|
|
|
36520b |
diff --git a/src/include/efivar/efivar-dp.h b/src/include/efivar/efivar-dp.h
|
|
|
36520b |
index 1b05775ae7e..f9ebb059d06 100644
|
|
|
36520b |
--- a/src/include/efivar/efivar-dp.h
|
|
|
36520b |
+++ b/src/include/efivar/efivar-dp.h
|
|
|
36520b |
@@ -689,6 +689,8 @@ typedef struct {
|
|
|
36520b |
uint8_t slot;
|
|
|
36520b |
} EFIVAR_PACKED efidp_emmc;
|
|
|
36520b |
|
|
|
36520b |
+extern ssize_t efidp_make_emmc(uint8_t *buf, ssize_t size, uint32_t slot_id);
|
|
|
36520b |
+
|
|
|
36520b |
#define EFIDP_MSG_BTLE 0x1e
|
|
|
36520b |
typedef struct {
|
|
|
36520b |
efidp_header header;
|
|
|
36520b |
diff --git a/src/linux.h b/src/linux.h
|
|
|
36520b |
index 99d61013e02..7c7ea91e771 100644
|
|
|
36520b |
--- a/src/linux.h
|
|
|
36520b |
+++ b/src/linux.h
|
|
|
36520b |
@@ -93,6 +93,10 @@ struct nvdimm_info {
|
|
|
36520b |
efi_guid_t nvdimm_label;
|
|
|
36520b |
};
|
|
|
36520b |
|
|
|
36520b |
+struct emmc_info {
|
|
|
36520b |
+ int32_t slot_id;
|
|
|
36520b |
+};
|
|
|
36520b |
+
|
|
|
36520b |
enum interface_type {
|
|
|
36520b |
unknown,
|
|
|
36520b |
isa, acpi_root, pci_root, soc_root, pci, network,
|
|
|
36520b |
@@ -100,6 +104,7 @@ enum interface_type {
|
|
|
36520b |
usb, i1394, fibre, i2o,
|
|
|
36520b |
md, virtblk,
|
|
|
36520b |
nvme, nd_pmem,
|
|
|
36520b |
+ emmc,
|
|
|
36520b |
};
|
|
|
36520b |
|
|
|
36520b |
struct dev_probe;
|
|
|
36520b |
@@ -139,6 +144,7 @@ struct device {
|
|
|
36520b |
struct sata_info sata_info;
|
|
|
36520b |
struct ata_info ata_info;
|
|
|
36520b |
struct nvme_info nvme_info;
|
|
|
36520b |
+ struct emmc_info emmc_info;
|
|
|
36520b |
struct nvdimm_info nvdimm_info;
|
|
|
36520b |
};
|
|
|
36520b |
};
|
|
|
36520b |
@@ -277,5 +283,6 @@ extern struct dev_probe virtblk_parser;
|
|
|
36520b |
extern struct dev_probe i2o_parser;
|
|
|
36520b |
extern struct dev_probe scsi_parser;
|
|
|
36520b |
extern struct dev_probe ata_parser;
|
|
|
36520b |
+extern struct dev_probe emmc_parser;
|
|
|
36520b |
|
|
|
36520b |
#endif /* _EFIBOOT_LINUX_H */
|
|
|
36520b |
diff --git a/src/libefivar.map.in b/src/libefivar.map.in
|
|
|
36520b |
index 31f696d3cb5..b5ee1ce334a 100644
|
|
|
36520b |
--- a/src/libefivar.map.in
|
|
|
36520b |
+++ b/src/libefivar.map.in
|
|
|
36520b |
@@ -51,6 +51,7 @@ libefivar.so.0 {
|
|
|
36520b |
efidp_make_sata;
|
|
|
36520b |
efidp_make_scsi;
|
|
|
36520b |
efidp_make_vendor;
|
|
|
36520b |
+ efidp_make_emmc;
|
|
|
36520b |
efidp_parse_device_node;
|
|
|
36520b |
efidp_parse_device_path;
|
|
|
36520b |
efidp_set_node_data;
|
|
|
36520b |
--
|
|
|
36520b |
2.17.1
|
|
|
36520b |
|