summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c')
-rw-r--r--qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c727
1 files changed, 0 insertions, 727 deletions
diff --git a/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c b/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c
deleted file mode 100644
index 720402bdb..000000000
--- a/qemu/roms/ipxe/src/interface/efi/efi_snp_hii.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/**
- * @file
- *
- * EFI SNP HII protocol
- *
- * The HII protocols are some of the less-well designed parts of the
- * entire EFI specification. This is a significant accomplishment.
- *
- * The face-slappingly ludicrous query string syntax seems to be
- * motivated by the desire to allow a caller to query multiple drivers
- * simultaneously via the single-instance HII_CONFIG_ROUTING_PROTOCOL,
- * which is supposed to pass relevant subsets of the query string to
- * the relevant drivers.
- *
- * Nobody uses the HII_CONFIG_ROUTING_PROTOCOL. Not even the EFI
- * setup browser uses the HII_CONFIG_ROUTING_PROTOCOL. To the best of
- * my knowledge, there has only ever been one implementation of the
- * HII_CONFIG_ROUTING_PROTOCOL (as part of EDK2), and it just doesn't
- * work. It's so badly broken that I can't even figure out what the
- * code is _trying_ to do.
- *
- * Fundamentally, the problem seems to be that Javascript programmers
- * should not be allowed to design APIs for C code.
- */
-
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <errno.h>
-#include <ipxe/settings.h>
-#include <ipxe/nvo.h>
-#include <ipxe/device.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/version.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_hii.h>
-#include <ipxe/efi/efi_snp.h>
-#include <ipxe/efi/efi_strings.h>
-#include <config/branding.h>
-
-/** EFI platform setup formset GUID */
-static EFI_GUID efi_hii_platform_setup_formset_guid
- = EFI_HII_PLATFORM_SETUP_FORMSET_GUID;
-
-/** EFI IBM UCM compliant formset GUID */
-static EFI_GUID efi_hii_ibm_ucm_compliant_formset_guid
- = EFI_HII_IBM_UCM_COMPLIANT_FORMSET_GUID;
-
-/** EFI HII database protocol */
-static EFI_HII_DATABASE_PROTOCOL *efihii;
-EFI_REQUEST_PROTOCOL ( EFI_HII_DATABASE_PROTOCOL, &efihii );
-
-/**
- * Identify settings to be exposed via HII
- *
- * @v snpdev SNP device
- * @ret settings Settings, or NULL
- */
-static struct settings * efi_snp_hii_settings ( struct efi_snp_device *snpdev ){
-
- return find_child_settings ( netdev_settings ( snpdev->netdev ),
- NVO_SETTINGS_NAME );
-}
-
-/**
- * Check whether or not setting is applicable
- *
- * @v snpdev SNP device
- * @v setting Setting
- * @ret applies Setting applies
- */
-static int efi_snp_hii_setting_applies ( struct efi_snp_device *snpdev,
- struct setting *setting ) {
-
- return nvo_applies ( efi_snp_hii_settings ( snpdev ), setting );
-}
-
-/**
- * Generate a random GUID
- *
- * @v guid GUID to fill in
- */
-static void efi_snp_hii_random_guid ( EFI_GUID *guid ) {
- uint8_t *byte = ( ( uint8_t * ) guid );
- unsigned int i;
-
- for ( i = 0 ; i < sizeof ( *guid ) ; i++ )
- *(byte++) = random();
-}
-
-/**
- * Generate EFI SNP questions
- *
- * @v snpdev SNP device
- * @v ifr IFR builder
- * @v varstore_id Variable store identifier
- */
-static void efi_snp_hii_questions ( struct efi_snp_device *snpdev,
- struct efi_ifr_builder *ifr,
- unsigned int varstore_id ) {
- struct setting *setting;
- struct setting *previous = NULL;
- unsigned int name_id;
- unsigned int prompt_id;
- unsigned int help_id;
- unsigned int question_id;
-
- /* Add all applicable settings */
- for_each_table_entry ( setting, SETTINGS ) {
- if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
- continue;
- if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
- continue;
- previous = setting;
- name_id = efi_ifr_string ( ifr, "%s", setting->name );
- prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
- help_id = efi_ifr_string ( ifr, PRODUCT_SETTING_URI,
- setting->name );
- question_id = setting->tag;
- efi_ifr_string_op ( ifr, prompt_id, help_id,
- question_id, varstore_id, name_id,
- 0, 0x00, 0xff, 0 );
- }
-}
-
-/**
- * Build HII package list for SNP device
- *
- * @v snpdev SNP device
- * @ret package Package list, or NULL on error
- */
-static EFI_HII_PACKAGE_LIST_HEADER *
-efi_snp_hii_package_list ( struct efi_snp_device *snpdev ) {
- struct net_device *netdev = snpdev->netdev;
- struct device *dev = netdev->dev;
- struct efi_ifr_builder ifr;
- EFI_HII_PACKAGE_LIST_HEADER *package;
- const char *name;
- EFI_GUID package_guid;
- EFI_GUID formset_guid;
- EFI_GUID varstore_guid;
- unsigned int title_id;
- unsigned int varstore_id;
-
- /* Initialise IFR builder */
- efi_ifr_init ( &ifr );
-
- /* Determine product name */
- name = ( product_name[0] ? product_name : product_short_name );
-
- /* Generate GUIDs */
- efi_snp_hii_random_guid ( &package_guid );
- efi_snp_hii_random_guid ( &formset_guid );
- efi_snp_hii_random_guid ( &varstore_guid );
-
- /* Generate title string (used more than once) */
- title_id = efi_ifr_string ( &ifr, "%s (%s)", name,
- netdev_addr ( netdev ) );
-
- /* Generate opcodes */
- efi_ifr_form_set_op ( &ifr, &formset_guid, title_id,
- efi_ifr_string ( &ifr, "Configure %s",
- product_short_name ),
- &efi_hii_platform_setup_formset_guid,
- &efi_hii_ibm_ucm_compliant_formset_guid, NULL );
- efi_ifr_guid_class_op ( &ifr, EFI_NETWORK_DEVICE_CLASS );
- efi_ifr_guid_subclass_op ( &ifr, 0x03 );
- varstore_id = efi_ifr_varstore_name_value_op ( &ifr, &varstore_guid );
- efi_ifr_form_op ( &ifr, title_id );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Name" ),
- efi_ifr_string ( &ifr, "Firmware product name" ),
- efi_ifr_string ( &ifr, "%s", name ) );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Version" ),
- efi_ifr_string ( &ifr, "Firmware version" ),
- efi_ifr_string ( &ifr, "%s", product_version ) );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Driver" ),
- efi_ifr_string ( &ifr, "Firmware driver" ),
- efi_ifr_string ( &ifr, "%s", dev->driver_name ) );
- efi_ifr_text_op ( &ifr,
- efi_ifr_string ( &ifr, "Device" ),
- efi_ifr_string ( &ifr, "Hardware device" ),
- efi_ifr_string ( &ifr, "%s", dev->name ) );
- efi_snp_hii_questions ( snpdev, &ifr, varstore_id );
- efi_ifr_end_op ( &ifr );
- efi_ifr_end_op ( &ifr );
-
- /* Build package */
- package = efi_ifr_package ( &ifr, &package_guid, "en-us",
- efi_ifr_string ( &ifr, "English" ) );
- if ( ! package ) {
- DBGC ( snpdev, "SNPDEV %p could not build IFR package\n",
- snpdev );
- efi_ifr_free ( &ifr );
- return NULL;
- }
-
- /* Free temporary storage */
- efi_ifr_free ( &ifr );
- return package;
-}
-
-/**
- * Append response to result string
- *
- * @v snpdev SNP device
- * @v key Key
- * @v value Value
- * @v results Result string
- * @ret rc Return status code
- *
- * The result string is allocated dynamically using
- * BootServices::AllocatePool(), and the caller is responsible for
- * eventually calling BootServices::FreePool().
- */
-static int efi_snp_hii_append ( struct efi_snp_device *snpdev __unused,
- const char *key, const char *value,
- wchar_t **results ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- size_t len;
- void *new;
-
- /* Allocate new string */
- len = ( ( *results ? ( wcslen ( *results ) + 1 /* "&" */ ) : 0 ) +
- strlen ( key ) + 1 /* "=" */ + strlen ( value ) + 1 /* NUL */ );
- bs->AllocatePool ( EfiBootServicesData, ( len * sizeof ( wchar_t ) ),
- &new );
- if ( ! new )
- return -ENOMEM;
-
- /* Populate string */
- efi_snprintf ( new, len, "%ls%s%s=%s", ( *results ? *results : L"" ),
- ( *results ? L"&" : L"" ), key, value );
- bs->FreePool ( *results );
- *results = new;
-
- return 0;
-}
-
-/**
- * Fetch HII setting
- *
- * @v snpdev SNP device
- * @v key Key
- * @v value Value
- * @v results Result string
- * @v have_setting Flag indicating detection of a setting
- * @ret rc Return status code
- */
-static int efi_snp_hii_fetch ( struct efi_snp_device *snpdev,
- const char *key, const char *value,
- wchar_t **results, int *have_setting ) {
- struct settings *settings = efi_snp_hii_settings ( snpdev );
- struct settings *origin;
- struct setting *setting;
- struct setting fetched;
- int len;
- char *buf;
- char *encoded;
- int i;
- int rc;
-
- /* Handle ConfigHdr components */
- if ( ( strcasecmp ( key, "GUID" ) == 0 ) ||
- ( strcasecmp ( key, "NAME" ) == 0 ) ||
- ( strcasecmp ( key, "PATH" ) == 0 ) ) {
- return efi_snp_hii_append ( snpdev, key, value, results );
- }
- if ( have_setting )
- *have_setting = 1;
-
- /* Do nothing more unless we have a settings block */
- if ( ! settings ) {
- rc = -ENOTSUP;
- goto err_no_settings;
- }
-
- /* Identify setting */
- setting = find_setting ( key );
- if ( ! setting ) {
- DBGC ( snpdev, "SNPDEV %p no such setting \"%s\"\n",
- snpdev, key );
- rc = -ENODEV;
- goto err_find_setting;
- }
-
- /* Encode value */
- if ( setting_exists ( settings, setting ) ) {
-
- /* Calculate formatted length */
- len = fetchf_setting ( settings, setting, &origin, &fetched,
- NULL, 0 );
- if ( len < 0 ) {
- rc = len;
- DBGC ( snpdev, "SNPDEV %p could not fetch %s: %s\n",
- snpdev, setting->name, strerror ( rc ) );
- goto err_fetchf_len;
- }
-
- /* Allocate buffer for formatted value and HII-encoded value */
- buf = zalloc ( len + 1 /* NUL */ + ( len * 4 ) + 1 /* NUL */ );
- if ( ! buf ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- encoded = ( buf + len + 1 /* NUL */ );
-
- /* Format value */
- fetchf_setting ( origin, &fetched, NULL, NULL, buf,
- ( len + 1 /* NUL */ ) );
- for ( i = 0 ; i < len ; i++ ) {
- sprintf ( ( encoded + ( 4 * i ) ), "%04x",
- *( ( uint8_t * ) buf + i ) );
- }
-
- } else {
-
- /* Non-existent or inapplicable setting */
- buf = NULL;
- encoded = "";
- }
-
- /* Append results */
- if ( ( rc = efi_snp_hii_append ( snpdev, key, encoded,
- results ) ) != 0 ) {
- goto err_append;
- }
-
- /* Success */
- rc = 0;
-
- err_append:
- free ( buf );
- err_alloc:
- err_fetchf_len:
- err_find_setting:
- err_no_settings:
- return rc;
-}
-
-/**
- * Fetch HII setting
- *
- * @v snpdev SNP device
- * @v key Key
- * @v value Value
- * @v results Result string (unused)
- * @v have_setting Flag indicating detection of a setting (unused)
- * @ret rc Return status code
- */
-static int efi_snp_hii_store ( struct efi_snp_device *snpdev,
- const char *key, const char *value,
- wchar_t **results __unused,
- int *have_setting __unused ) {
- struct settings *settings = efi_snp_hii_settings ( snpdev );
- struct setting *setting;
- char *buf;
- char tmp[5];
- char *endp;
- int len;
- int i;
- int rc;
-
- /* Handle ConfigHdr components */
- if ( ( strcasecmp ( key, "GUID" ) == 0 ) ||
- ( strcasecmp ( key, "NAME" ) == 0 ) ||
- ( strcasecmp ( key, "PATH" ) == 0 ) ) {
- /* Nothing to do */
- return 0;
- }
-
- /* Do nothing more unless we have a settings block */
- if ( ! settings ) {
- rc = -ENOTSUP;
- goto err_no_settings;
- }
-
- /* Identify setting */
- setting = find_setting ( key );
- if ( ! setting ) {
- DBGC ( snpdev, "SNPDEV %p no such setting \"%s\"\n",
- snpdev, key );
- rc = -ENODEV;
- goto err_find_setting;
- }
-
- /* Allocate buffer */
- len = ( strlen ( value ) / 4 );
- buf = zalloc ( len + 1 /* NUL */ );
- if ( ! buf ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
-
- /* Decode value */
- tmp[4] = '\0';
- for ( i = 0 ; i < len ; i++ ) {
- memcpy ( tmp, ( value + ( i * 4 ) ), 4 );
- buf[i] = strtoul ( tmp, &endp, 16 );
- if ( endp != &tmp[4] ) {
- DBGC ( snpdev, "SNPDEV %p invalid character %s\n",
- snpdev, tmp );
- rc = -EINVAL;
- goto err_inval;
- }
- }
-
- /* Store value */
- if ( ( rc = storef_setting ( settings, setting, buf ) ) != 0 ) {
- DBGC ( snpdev, "SNPDEV %p could not store \"%s\" into %s: %s\n",
- snpdev, buf, setting->name, strerror ( rc ) );
- goto err_storef;
- }
-
- /* Success */
- rc = 0;
-
- err_storef:
- err_inval:
- free ( buf );
- err_alloc:
- err_find_setting:
- err_no_settings:
- return rc;
-}
-
-/**
- * Process portion of HII configuration string
- *
- * @v snpdev SNP device
- * @v string HII configuration string
- * @v progress Progress through HII configuration string
- * @v results Results string
- * @v have_setting Flag indicating detection of a setting (unused)
- * @v process Function used to process key=value pairs
- * @ret rc Return status code
- */
-static int efi_snp_hii_process ( struct efi_snp_device *snpdev,
- wchar_t *string, wchar_t **progress,
- wchar_t **results, int *have_setting,
- int ( * process ) ( struct efi_snp_device *,
- const char *key,
- const char *value,
- wchar_t **results,
- int *have_setting ) ) {
- wchar_t *wkey = string;
- wchar_t *wend = string;
- wchar_t *wvalue = NULL;
- size_t key_len;
- size_t value_len;
- void *temp;
- char *key;
- char *value;
- int rc;
-
- /* Locate key, value (if any), and end */
- while ( *wend ) {
- if ( *wend == L'&' )
- break;
- if ( *(wend++) == L'=' )
- wvalue = wend;
- }
-
- /* Allocate memory for key and value */
- key_len = ( ( wvalue ? ( wvalue - 1 ) : wend ) - wkey );
- value_len = ( wvalue ? ( wend - wvalue ) : 0 );
- temp = zalloc ( key_len + 1 /* NUL */ + value_len + 1 /* NUL */ );
- if ( ! temp )
- return -ENOMEM;
- key = temp;
- value = ( temp + key_len + 1 /* NUL */ );
-
- /* Copy key and value */
- while ( key_len-- )
- key[key_len] = wkey[key_len];
- while ( value_len-- )
- value[value_len] = wvalue[value_len];
-
- /* Process key and value */
- if ( ( rc = process ( snpdev, key, value, results,
- have_setting ) ) != 0 ) {
- goto err;
- }
-
- /* Update progress marker */
- *progress = wend;
-
- err:
- /* Free temporary storage */
- free ( temp );
-
- return rc;
-}
-
-/**
- * Fetch configuration
- *
- * @v hii HII configuration access protocol
- * @v request Configuration to fetch
- * @ret progress Progress made through configuration to fetch
- * @ret results Query results
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_hii_extract_config ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
- EFI_STRING request, EFI_STRING *progress,
- EFI_STRING *results ) {
- struct efi_snp_device *snpdev =
- container_of ( hii, struct efi_snp_device, hii );
- int have_setting = 0;
- wchar_t *pos;
- int rc;
-
- DBGC ( snpdev, "SNPDEV %p ExtractConfig request \"%ls\"\n",
- snpdev, request );
-
- /* Initialise results */
- *results = NULL;
-
- /* Process all request fragments */
- for ( pos = *progress = request ; *progress && **progress ;
- pos = *progress + 1 ) {
- if ( ( rc = efi_snp_hii_process ( snpdev, pos, progress,
- results, &have_setting,
- efi_snp_hii_fetch ) ) != 0 ) {
- return EFIRC ( rc );
- }
- }
-
- /* If we have no explicit request, return all settings */
- if ( ! have_setting ) {
- struct setting *setting;
-
- for_each_table_entry ( setting, SETTINGS ) {
- if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
- continue;
- if ( ( rc = efi_snp_hii_fetch ( snpdev, setting->name,
- NULL, results,
- NULL ) ) != 0 ) {
- return EFIRC ( rc );
- }
- }
- }
-
- DBGC ( snpdev, "SNPDEV %p ExtractConfig results \"%ls\"\n",
- snpdev, *results );
- return 0;
-}
-
-/**
- * Store configuration
- *
- * @v hii HII configuration access protocol
- * @v config Configuration to store
- * @ret progress Progress made through configuration to store
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_hii_route_config ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
- EFI_STRING config, EFI_STRING *progress ) {
- struct efi_snp_device *snpdev =
- container_of ( hii, struct efi_snp_device, hii );
- wchar_t *pos;
- int rc;
-
- DBGC ( snpdev, "SNPDEV %p RouteConfig \"%ls\"\n", snpdev, config );
-
- /* Process all request fragments */
- for ( pos = *progress = config ; *progress && **progress ;
- pos = *progress + 1 ) {
- if ( ( rc = efi_snp_hii_process ( snpdev, pos, progress,
- NULL, NULL,
- efi_snp_hii_store ) ) != 0 ) {
- return EFIRC ( rc );
- }
- }
-
- return 0;
-}
-
-/**
- * Handle form actions
- *
- * @v hii HII configuration access protocol
- * @v action Form browser action
- * @v question_id Question ID
- * @v type Type of value
- * @v value Value
- * @ret action_request Action requested by driver
- * @ret efirc EFI status code
- */
-static EFI_STATUS EFIAPI
-efi_snp_hii_callback ( const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii,
- EFI_BROWSER_ACTION action __unused,
- EFI_QUESTION_ID question_id __unused,
- UINT8 type __unused, EFI_IFR_TYPE_VALUE *value __unused,
- EFI_BROWSER_ACTION_REQUEST *action_request __unused ) {
- struct efi_snp_device *snpdev =
- container_of ( hii, struct efi_snp_device, hii );
-
- DBGC ( snpdev, "SNPDEV %p Callback\n", snpdev );
- return EFI_UNSUPPORTED;
-}
-
-/** HII configuration access protocol */
-static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii = {
- .ExtractConfig = efi_snp_hii_extract_config,
- .RouteConfig = efi_snp_hii_route_config,
- .Callback = efi_snp_hii_callback,
-};
-
-/**
- * Install HII protocol and packages for SNP device
- *
- * @v snpdev SNP device
- * @ret rc Return status code
- */
-int efi_snp_hii_install ( struct efi_snp_device *snpdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- int efirc;
- int rc;
-
- /* Do nothing if HII database protocol is not supported */
- if ( ! efihii ) {
- rc = -ENOTSUP;
- goto err_no_hii;
- }
-
- /* Initialise HII protocol */
- memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
-
- /* Create HII package list */
- snpdev->package_list = efi_snp_hii_package_list ( snpdev );
- if ( ! snpdev->package_list ) {
- DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
- snpdev );
- rc = -ENOMEM;
- goto err_build_package_list;
- }
-
- /* Add HII packages */
- if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
- snpdev->handle,
- &snpdev->hii_handle ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
- snpdev, strerror ( rc ) );
- goto err_new_package_list;
- }
-
- /* Install HII protocol */
- if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
- &snpdev->handle,
- &efi_hii_config_access_protocol_guid, &snpdev->hii,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
- snpdev, strerror ( rc ) );
- goto err_install_protocol;
- }
-
- return 0;
-
- bs->UninstallMultipleProtocolInterfaces (
- snpdev->handle,
- &efi_hii_config_access_protocol_guid, &snpdev->hii,
- NULL );
- err_install_protocol:
- efihii->RemovePackageList ( efihii, snpdev->hii_handle );
- err_new_package_list:
- free ( snpdev->package_list );
- snpdev->package_list = NULL;
- err_build_package_list:
- err_no_hii:
- return rc;
-}
-
-/**
- * Uninstall HII protocol and package for SNP device
- *
- * @v snpdev SNP device
- */
-void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- /* Do nothing if HII database protocol is not supported */
- if ( ! efihii )
- return;
-
- /* Uninstall protocols and remove package list */
- bs->UninstallMultipleProtocolInterfaces (
- snpdev->handle,
- &efi_hii_config_access_protocol_guid, &snpdev->hii,
- NULL );
- efihii->RemovePackageList ( efihii, snpdev->hii_handle );
- free ( snpdev->package_list );
- snpdev->package_list = NULL;
-}