Mercurial > unleashed > prev-conversion
changeset 18810:4c0b161579af
libefi: Move EFI fmtdev functionality to libefi
illumos issue #9072
author | Toomas Soome <tsoome@me.com> |
---|---|
date | Tue, 12 Dec 2017 15:05:32 +0200 |
parents | 4d483ddfc2b1 |
children | 4c609abb3bf5 |
files | usr/src/boot/sys/boot/efi/include/efilib.h usr/src/boot/sys/boot/efi/libefi/Makefile usr/src/boot/sys/boot/efi/libefi/devicename.c usr/src/boot/sys/boot/efi/loader/Makefile usr/src/boot/sys/boot/efi/loader/devicename.c usr/src/boot/sys/boot/efi/loader/loader_efi.h |
diffstat | 6 files changed, 225 insertions(+), 227 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/boot/sys/boot/efi/include/efilib.h Tue Dec 12 15:23:09 2017 +0200 +++ b/usr/src/boot/sys/boot/efi/include/efilib.h Tue Dec 12 15:05:32 2017 +0200 @@ -63,6 +63,10 @@ void *efi_get_table(EFI_GUID *tbl); +int efi_getdev(void **, const char *, const char **); +char *efi_fmtdev(void *); +int efi_setcurrdev(struct env_var *, int, const void *); + int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int); EFI_HANDLE efi_find_handle(struct devsw *, int); int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *);
--- a/usr/src/boot/sys/boot/efi/libefi/Makefile Tue Dec 12 15:23:09 2017 +0200 +++ b/usr/src/boot/sys/boot/efi/libefi/Makefile Tue Dec 12 15:05:32 2017 +0200 @@ -24,9 +24,9 @@ install: -SRCS= delay.c devpath.c efi_console.c efi_driver_utils.c efichar.c \ - efinet.c efipart.c efizfs.c env.c errno.c handles.c libefi.c \ - time.c wchar.c +SRCS= delay.c devicename.c devpath.c efi_console.c efi_driver_utils.c \ + efichar.c efinet.c efipart.c efizfs.c env.c errno.c handles.c \ + libefi.c time.c wchar.c #.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" #SRCS += time.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/boot/sys/boot/efi/libefi/devicename.c Tue Dec 12 15:05:32 2017 +0200 @@ -0,0 +1,216 @@ +/* + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2006 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#include <stand.h> +#include <string.h> +#include <sys/disklabel.h> +#include <sys/param.h> +#include <bootstrap.h> +#include <disk.h> +#include <libzfs.h> + +#include <efi.h> +#include <efilib.h> + +static int efi_parsedev(struct devdesc **, const char *, const char **); + +/* + * Point (dev) at an allocated device specifier for the device matching the + * path in (devspec). If it contains an explicit device specification, + * use that. If not, use the default device. + */ +int +efi_getdev(void **vdev, const char *devspec, const char **path) +{ + struct devdesc **dev = (struct devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no device, then + * use the current device instead. + */ + if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) { + rv = efi_parsedev(dev, getenv("currdev"), NULL); + if (rv == 0 && path != NULL) + *path = devspec; + return (rv); + } + + /* Parse the device name off the beginning of the devspec. */ + return (efi_parsedev(dev, devspec, path)); +} + +/* + * Point (dev) at an allocated device specifier matching the string version + * at the beginning of (devspec). Return a pointer to the remaining + * text in (path). + * + * In all cases, the beginning of (devspec) is compared to the names + * of known devices in the device switch, and then any following text + * is parsed according to the rules applied to the device type. + * + * For disk-type devices, the syntax is: + * + * fs<unit>: + */ +static int +efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) +{ + struct devdesc *idev; + struct devsw *dv; + int i, unit, err; + char *cp; + const char *np; + + /* minimum length check */ + if (strlen(devspec) < 2) + return (EINVAL); + + /* look for a device that matches */ + for (i = 0; devsw[i] != NULL; i++) { + dv = devsw[i]; + if (strncmp(devspec, dv->dv_name, strlen(dv->dv_name)) == 0) + break; + } + if (devsw[i] == NULL) + return (ENOENT); + + np = devspec + strlen(dv->dv_name); + idev = NULL; + err = 0; + + switch (dv->dv_type) { + case DEVT_NONE: + break; + + case DEVT_DISK: + idev = malloc(sizeof (struct disk_devdesc)); + if (idev == NULL) + return (ENOMEM); + + err = disk_parsedev((struct disk_devdesc *)idev, np, path); + if (err != 0) + goto fail; + break; + + case DEVT_ZFS: + idev = malloc(sizeof (struct zfs_devdesc)); + if (idev == NULL) + return (ENOMEM); + + err = zfs_parsedev((struct zfs_devdesc *)idev, np, path); + if (err != 0) + goto fail; + break; + + default: + idev = malloc(sizeof (struct devdesc)); + if (idev == NULL) + return (ENOMEM); + + unit = 0; + cp = (char *)np; + + if (*np != '\0' && *np != ':') { + /* get unit number if present */ + errno = 0; + unit = strtol(np, &cp, 0); + if (errno != 0 || cp == np) { + err = EUNIT; + goto fail; + } + } + if (*cp != '\0' && *cp != ':') { + err = EINVAL; + goto fail; + } + + idev->d_unit = unit; + if (path != NULL) + *path = (*cp == '\0') ? cp : cp + 1; + break; + } + + idev->d_dev = dv; + idev->d_type = dv->dv_type; + + if (dev != NULL) + *dev = idev; + else + free(idev); + return (0); + +fail: + free(idev); + return (err); +} + +char * +efi_fmtdev(void *vdev) +{ + struct devdesc *dev = (struct devdesc *)vdev; + static char buf[SPECNAMELEN + 1]; + + switch (dev->d_type) { + case DEVT_NONE: + strlcpy(buf, "(no device)", sizeof (buf)); + break; + + case DEVT_DISK: + return (disk_fmtdev(vdev)); + + case DEVT_ZFS: + return (zfs_fmtdev(dev)); + + default: + snprintf(buf, sizeof (buf), "%s%d:", dev->d_dev->dv_name, + dev->d_unit); + break; + } + + return (buf); +} + +/* + * Set currdev to suit the value being supplied in (value) + */ +int +efi_setcurrdev(struct env_var *ev, int flags, const void *value) +{ + struct devdesc *ncurr; + int rv; + + rv = efi_parsedev(&ncurr, value, NULL); + if (rv != 0) + return (rv); + + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return (0); +}
--- a/usr/src/boot/sys/boot/efi/loader/Makefile Tue Dec 12 15:23:09 2017 +0200 +++ b/usr/src/boot/sys/boot/efi/loader/Makefile Tue Dec 12 15:05:32 2017 +0200 @@ -26,9 +26,9 @@ MACHINE= $(MACH64) # architecture-specific loader code -SRCS= autoload.c bootinfo.c conf.c copy.c devicename.c efi_main.c main.c \ +SRCS= autoload.c bootinfo.c conf.c copy.c efi_main.c main.c \ self_reloc.c smbios.c acpi.c vers.c memmap.c multiboot2.c -OBJS= autoload.o bootinfo.o conf.o copy.o devicename.o efi_main.o main.o \ +OBJS= autoload.o bootinfo.o conf.o copy.o efi_main.o main.o \ self_reloc.o smbios.o acpi.o vers.o memmap.o multiboot2.o ASFLAGS=-m64 -fPIC
--- a/usr/src/boot/sys/boot/efi/loader/devicename.c Tue Dec 12 15:23:09 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -/* - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * Copyright (c) 2006 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> - -#include <stand.h> -#include <string.h> -#include <sys/disklabel.h> -#include <sys/param.h> -#include <bootstrap.h> -#include <disk.h> -#include <libzfs.h> - -#include <efi.h> -#include <efilib.h> - -#include "loader_efi.h" - -static int efi_parsedev(struct devdesc **, const char *, const char **); - -/* - * Point (dev) at an allocated device specifier for the device matching the - * path in (devspec). If it contains an explicit device specification, - * use that. If not, use the default device. - */ -int -efi_getdev(void **vdev, const char *devspec, const char **path) -{ - struct devdesc **dev = (struct devdesc **)vdev; - int rv; - - /* - * If it looks like this is just a path and no device, then - * use the current device instead. - */ - if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) { - rv = efi_parsedev(dev, getenv("currdev"), NULL); - if (rv == 0 && path != NULL) - *path = devspec; - return (rv); - } - - /* Parse the device name off the beginning of the devspec. */ - return (efi_parsedev(dev, devspec, path)); -} - -/* - * Point (dev) at an allocated device specifier matching the string version - * at the beginning of (devspec). Return a pointer to the remaining - * text in (path). - * - * In all cases, the beginning of (devspec) is compared to the names - * of known devices in the device switch, and then any following text - * is parsed according to the rules applied to the device type. - * - * For disk-type devices, the syntax is: - * - * fs<unit>: - */ -static int -efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) -{ - struct devdesc *idev; - struct devsw *dv; - int i, unit, err; - char *cp; - const char *np; - - /* minimum length check */ - if (strlen(devspec) < 2) - return (EINVAL); - - /* look for a device that matches */ - for (i = 0; devsw[i] != NULL; i++) { - dv = devsw[i]; - if (strncmp(devspec, dv->dv_name, strlen(dv->dv_name)) == 0) - break; - } - if (devsw[i] == NULL) - return (ENOENT); - - np = devspec + strlen(dv->dv_name); - idev = NULL; - err = 0; - - switch (dv->dv_type) { - case DEVT_NONE: - break; - - case DEVT_DISK: - idev = malloc(sizeof (struct disk_devdesc)); - if (idev == NULL) - return (ENOMEM); - - err = disk_parsedev((struct disk_devdesc *)idev, np, path); - if (err != 0) - goto fail; - break; - - case DEVT_ZFS: - idev = malloc(sizeof (struct zfs_devdesc)); - if (idev == NULL) - return (ENOMEM); - - err = zfs_parsedev((struct zfs_devdesc *)idev, np, path); - if (err != 0) - goto fail; - break; - - default: - idev = malloc(sizeof (struct devdesc)); - if (idev == NULL) - return (ENOMEM); - - unit = 0; - cp = (char *)np; - - if (*np != '\0' && *np != ':') { - /* get unit number if present */ - errno = 0; - unit = strtol(np, &cp, 0); - if (errno != 0 || cp == np) { - err = EUNIT; - goto fail; - } - } - if (*cp != '\0' && *cp != ':') { - err = EINVAL; - goto fail; - } - - idev->d_unit = unit; - if (path != NULL) - *path = (*cp == '\0') ? cp : cp + 1; - break; - } - - idev->d_dev = dv; - idev->d_type = dv->dv_type; - - if (dev != NULL) - *dev = idev; - else - free(idev); - return (0); - -fail: - free(idev); - return (err); -} - -char * -efi_fmtdev(void *vdev) -{ - struct devdesc *dev = (struct devdesc *)vdev; - static char buf[SPECNAMELEN + 1]; - - switch (dev->d_type) { - case DEVT_NONE: - strlcpy(buf, "(no device)", sizeof (buf)); - break; - - case DEVT_DISK: - return (disk_fmtdev(vdev)); - - case DEVT_ZFS: - return (zfs_fmtdev(dev)); - - default: - snprintf(buf, sizeof (buf), "%s%d:", dev->d_dev->dv_name, - dev->d_unit); - break; - } - - return (buf); -} - -/* - * Set currdev to suit the value being supplied in (value) - */ -int -efi_setcurrdev(struct env_var *ev, int flags, const void *value) -{ - struct devdesc *ncurr; - int rv; - - rv = efi_parsedev(&ncurr, value, NULL); - if (rv != 0) - return (rv); - - free(ncurr); - env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); - return (0); -}
--- a/usr/src/boot/sys/boot/efi/loader/loader_efi.h Tue Dec 12 15:23:09 2017 +0200 +++ b/usr/src/boot/sys/boot/efi/loader/loader_efi.h Tue Dec 12 15:05:32 2017 +0200 @@ -55,10 +55,6 @@ int efi_autoload(void); -int efi_getdev(void **, const char *, const char **); -char *efi_fmtdev(void *); -int efi_setcurrdev(struct env_var *, int, const void *); - ssize_t efi_copyin(const void *, vm_offset_t, const size_t); ssize_t efi_copyout(const vm_offset_t, void *, const size_t); ssize_t efi_readin(const int, vm_offset_t, const size_t);