/*-1* Copyright (c) 2008-2010 Rui Paulo2* Copyright (c) 2006 Marcel Moolenaar3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR16* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES17* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.18* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,19* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT20* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,21* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY22* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT23* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF24* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.25*/2627#include <sys/param.h>28#include <stand.h>2930#ifdef EFI_ZFS_BOOT31#include <libzfs.h>32#endif3334#include <efi.h>35#include <efilib.h>3637#include "efizfs.h"3839#ifdef EFI_ZFS_BOOT40static zfsinfo_list_t zfsinfo;4142uint64_t pool_guid;4344zfsinfo_list_t *45efizfs_get_zfsinfo_list(void)46{47return (&zfsinfo);48}4950EFI_HANDLE51efizfs_get_handle_by_guid(uint64_t guid)52{53zfsinfo_t *zi;5455STAILQ_FOREACH(zi, &zfsinfo, zi_link) {56if (zi->zi_pool_guid == guid) {57return (zi->zi_handle);58}59}60return (NULL);61}6263bool64efizfs_get_guid_by_handle(EFI_HANDLE handle, uint64_t *guid)65{66zfsinfo_t *zi;6768if (guid == NULL)69return (false);70STAILQ_FOREACH(zi, &zfsinfo, zi_link) {71if (zi->zi_handle == handle) {72*guid = zi->zi_pool_guid;73return (true);74}75}76return (false);77}7879static void80insert_zfs(EFI_HANDLE handle, uint64_t guid)81{82zfsinfo_t *zi;8384zi = malloc(sizeof(zfsinfo_t));85if (zi != NULL) {86zi->zi_handle = handle;87zi->zi_pool_guid = guid;88STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);89}90}9192void93efi_zfs_probe(void)94{95pdinfo_list_t *hdi;96pdinfo_t *hd, *pd = NULL;97char devname[SPECNAMELEN + 1];98uint64_t guid;99100hdi = efiblk_get_pdinfo_list(&efipart_hddev);101STAILQ_INIT(&zfsinfo);102103/*104* Find the handle for the boot device. The boot1 did find the105* device with loader binary, now we need to search for the106* same device and if it is part of the zfs pool, we record the107* pool GUID for currdev setup.108*/109STAILQ_FOREACH(hd, hdi, pd_link) {110STAILQ_FOREACH(pd, &hd->pd_part, pd_link) {111snprintf(devname, sizeof(devname), "%s%dp%d:",112efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit);113guid = 0;114if (zfs_probe_dev(devname, &guid, false) == 0) {115insert_zfs(pd->pd_handle, guid);116if (pd->pd_handle == boot_img->DeviceHandle)117pool_guid = guid;118}119120}121}122}123#endif124125126