iPXE
Functions | Variables
efi_snp_hii.c File Reference

EFI SNP HII protocol. More...

#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 <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/efi_null.h>
#include <config/branding.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 EFI_REQUEST_PROTOCOL (EFI_HII_DATABASE_PROTOCOL, &efihii)
 
static struct settingsefi_snp_hii_settings (struct efi_snp_device *snpdev)
 Identify settings to be exposed via HII. More...
 
static int efi_snp_hii_setting_applies (struct efi_snp_device *snpdev, struct setting *setting)
 Check whether or not setting is applicable. More...
 
static void efi_snp_hii_random_guid (EFI_GUID *guid)
 Generate a random GUID. More...
 
static void efi_snp_hii_questions (struct efi_snp_device *snpdev, struct efi_ifr_builder *ifr, unsigned int varstore_id)
 Generate EFI SNP questions. More...
 
static EFI_HII_PACKAGE_LIST_HEADERefi_snp_hii_package_list (struct efi_snp_device *snpdev)
 Build HII package list for SNP device. More...
 
static int efi_snp_hii_append (struct efi_snp_device *snpdev __unused, const char *key, const char *value, wchar_t **results)
 Append response to result string. More...
 
static int efi_snp_hii_fetch (struct efi_snp_device *snpdev, const char *key, const char *value, wchar_t **results, int *have_setting)
 Fetch HII setting. More...
 
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)
 Fetch HII setting. More...
 
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))
 Process portion of HII configuration string. More...
 
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)
 Fetch configuration. More...
 
static EFI_STATUS EFIAPI efi_snp_hii_route_config (const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii, EFI_STRING config, EFI_STRING *progress)
 Store configuration. More...
 
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)
 Handle form actions. More...
 
int efi_snp_hii_install (struct efi_snp_device *snpdev)
 Install HII protocol and packages for SNP device. More...
 
int efi_snp_hii_uninstall (struct efi_snp_device *snpdev)
 Uninstall HII protocol and package for SNP device. More...
 

Variables

static EFI_GUID efi_hii_platform_setup_formset_guid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID
 EFI platform setup formset GUID. More...
 
static EFI_GUID efi_hii_ibm_ucm_compliant_formset_guid = EFI_HII_IBM_UCM_COMPLIANT_FORMSET_GUID
 EFI IBM UCM compliant formset GUID. More...
 
static EFI_HII_DATABASE_PROTOCOLefihii
 EFI HII database protocol. More...
 
static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
 HII configuration access protocol. More...
 

Detailed Description

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.

Definition in file efi_snp_hii.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ EFI_REQUEST_PROTOCOL()

EFI_REQUEST_PROTOCOL ( EFI_HII_DATABASE_PROTOCOL  ,
efihii 
)

◆ efi_snp_hii_settings()

static struct settings* efi_snp_hii_settings ( struct efi_snp_device snpdev)
static

Identify settings to be exposed via HII.

Parameters
snpdevSNP device
Return values
settingsSettings, or NULL

Definition at line 89 of file efi_snp_hii.c.

89  {
90 
91  return find_child_settings ( netdev_settings ( snpdev->netdev ),
93 }
static struct settings * netdev_settings(struct net_device *netdev)
Get per-netdevice configuration settings block.
Definition: netdevice.h:583
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define NVO_SETTINGS_NAME
Name of non-volatile options settings block.
Definition: nvo.h:46
struct settings * find_child_settings(struct settings *parent, const char *name)
Find child settings block.
Definition: settings.c:279

References find_child_settings(), efi_snp_device::netdev, netdev_settings(), and NVO_SETTINGS_NAME.

Referenced by efi_snp_hii_fetch(), efi_snp_hii_setting_applies(), and efi_snp_hii_store().

◆ efi_snp_hii_setting_applies()

static int efi_snp_hii_setting_applies ( struct efi_snp_device snpdev,
struct setting setting 
)
static

Check whether or not setting is applicable.

Parameters
snpdevSNP device
settingSetting
Return values
appliesSetting applies

Definition at line 102 of file efi_snp_hii.c.

103  {
104 
105  return nvo_applies ( efi_snp_hii_settings ( snpdev ), setting );
106 }
int nvo_applies(struct settings *settings __unused, const struct setting *setting)
Check applicability of NVO setting.
Definition: nvo.c:199
static struct settings * efi_snp_hii_settings(struct efi_snp_device *snpdev)
Identify settings to be exposed via HII.
Definition: efi_snp_hii.c:89
A setting.
Definition: settings.h:23

References efi_snp_hii_settings(), and nvo_applies().

Referenced by efi_snp_hii_extract_config(), and efi_snp_hii_questions().

◆ efi_snp_hii_random_guid()

static void efi_snp_hii_random_guid ( EFI_GUID guid)
static

Generate a random GUID.

Parameters
guidGUID to fill in

Definition at line 113 of file efi_snp_hii.c.

113  {
114  uint8_t *byte = ( ( uint8_t * ) guid );
115  unsigned int i;
116 
117  for ( i = 0 ; i < sizeof ( *guid ) ; i++ )
118  *(byte++) = random();
119 }
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
unsigned char uint8_t
Definition: stdint.h:10
uint64_t guid
GUID.
Definition: edd.h:30

References guid, and random().

Referenced by efi_snp_hii_install(), and efi_snp_hii_package_list().

◆ efi_snp_hii_questions()

static void efi_snp_hii_questions ( struct efi_snp_device snpdev,
struct efi_ifr_builder ifr,
unsigned int  varstore_id 
)
static

Generate EFI SNP questions.

Parameters
snpdevSNP device
ifrIFR builder
varstore_idVariable store identifier

Definition at line 128 of file efi_snp_hii.c.

130  {
131  struct setting *setting;
132  struct setting *previous = NULL;
133  unsigned int name_id;
134  unsigned int prompt_id;
135  unsigned int help_id;
136  unsigned int question_id;
137 
138  /* Add all applicable settings */
140  if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
141  continue;
142  if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
143  continue;
144  previous = setting;
145  name_id = efi_ifr_string ( ifr, "%s", setting->name );
146  prompt_id = efi_ifr_string ( ifr, "%s", setting->description );
147  help_id = efi_ifr_string ( ifr, PRODUCT_SETTING_URI,
148  setting->name );
149  question_id = setting->tag;
150  efi_ifr_string_op ( ifr, prompt_id, help_id,
151  question_id, varstore_id, name_id,
152  0, 0x00, 0xff, 0 );
153  }
154 }
const char * description
Description.
Definition: settings.h:30
const char * name
Name.
Definition: settings.h:28
#define SETTINGS
Configuration setting table.
Definition: settings.h:53
void efi_ifr_string_op(struct efi_ifr_builder *ifr, unsigned int prompt_id, unsigned int help_id, unsigned int question_id, unsigned int varstore_id, unsigned int varstore_info, unsigned int vflags, unsigned int min_size, unsigned int max_size, unsigned int flags)
Add string opcode to IFR builder.
Definition: efi_hii.c:386
uint64_t tag
Setting tag, if applicable.
Definition: settings.h:43
#define PRODUCT_SETTING_URI
Definition: branding.h:170
static int efi_snp_hii_setting_applies(struct efi_snp_device *snpdev, struct setting *setting)
Check whether or not setting is applicable.
Definition: efi_snp_hii.c:102
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
A setting.
Definition: settings.h:23
unsigned int efi_ifr_string(struct efi_ifr_builder *ifr, const char *fmt,...)
Add string to IFR builder.
Definition: efi_hii.c:45
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1120
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References setting::description, efi_ifr_string(), efi_ifr_string_op(), efi_snp_hii_setting_applies(), for_each_table_entry, setting::name, NULL, PRODUCT_SETTING_URI, setting_cmp(), SETTINGS, and setting::tag.

Referenced by efi_snp_hii_package_list().

◆ efi_snp_hii_package_list()

static EFI_HII_PACKAGE_LIST_HEADER* efi_snp_hii_package_list ( struct efi_snp_device snpdev)
static

Build HII package list for SNP device.

Parameters
snpdevSNP device
Return values
packagePackage list, or NULL on error

Definition at line 163 of file efi_snp_hii.c.

163  {
164  struct net_device *netdev = snpdev->netdev;
165  struct device *dev = netdev->dev;
166  struct efi_ifr_builder ifr;
168  const char *name;
169  EFI_GUID package_guid;
170  EFI_GUID formset_guid;
171  EFI_GUID varstore_guid;
172  unsigned int title_id;
173  unsigned int varstore_id;
174 
175  /* Initialise IFR builder */
176  efi_ifr_init ( &ifr );
177 
178  /* Determine product name */
180 
181  /* Generate GUIDs */
182  efi_snp_hii_random_guid ( &package_guid );
183  efi_snp_hii_random_guid ( &formset_guid );
184  efi_snp_hii_random_guid ( &varstore_guid );
185 
186  /* Generate title string (used more than once) */
187  title_id = efi_ifr_string ( &ifr, "%s (%s)", name,
188  netdev_addr ( netdev ) );
189 
190  /* Generate opcodes */
191  efi_ifr_form_set_op ( &ifr, &formset_guid, title_id,
192  efi_ifr_string ( &ifr, "Configure %s",
197  efi_ifr_guid_subclass_op ( &ifr, 0x03 );
198  varstore_id = efi_ifr_varstore_name_value_op ( &ifr, &varstore_guid );
199  efi_ifr_form_op ( &ifr, title_id );
200  efi_ifr_text_op ( &ifr,
201  efi_ifr_string ( &ifr, "Name" ),
202  efi_ifr_string ( &ifr, "Firmware product name" ),
203  efi_ifr_string ( &ifr, "%s", name ) );
204  efi_ifr_text_op ( &ifr,
205  efi_ifr_string ( &ifr, "Version" ),
206  efi_ifr_string ( &ifr, "Firmware version" ),
207  efi_ifr_string ( &ifr, "%s", product_version ) );
208  efi_ifr_text_op ( &ifr,
209  efi_ifr_string ( &ifr, "Driver" ),
210  efi_ifr_string ( &ifr, "Firmware driver" ),
211  efi_ifr_string ( &ifr, "%s", dev->driver_name ) );
212  efi_ifr_text_op ( &ifr,
213  efi_ifr_string ( &ifr, "Device" ),
214  efi_ifr_string ( &ifr, "Hardware device" ),
215  efi_ifr_string ( &ifr, "%s", dev->name ) );
216  efi_snp_hii_questions ( snpdev, &ifr, varstore_id );
217  efi_ifr_end_op ( &ifr );
218  efi_ifr_end_op ( &ifr );
219 
220  /* Build package */
221  package = efi_ifr_package ( &ifr, &package_guid, "en-us",
222  efi_ifr_string ( &ifr, "English" ) );
223  if ( ! package ) {
224  DBGC ( snpdev, "SNPDEV %p could not build IFR package\n",
225  snpdev );
226  efi_ifr_free ( &ifr );
227  return NULL;
228  }
229 
230  /* Free temporary storage */
231  efi_ifr_free ( &ifr );
232  return package;
233 }
const char product_short_name[]
Product short name string.
Definition: version.c:76
const char * name
Definition: ath9k_hw.c:1984
void efi_ifr_form_set_op(struct efi_ifr_builder *ifr, const EFI_GUID *guid, unsigned int title_id, unsigned int help_id,...)
Add formset opcode to IFR builder.
Definition: efi_hii.c:194
static void efi_ifr_init(struct efi_ifr_builder *ifr)
Initialise IFR builder.
Definition: efi_hii.h:48
void efi_ifr_end_op(struct efi_ifr_builder *ifr)
Add end opcode to IFR builder.
Definition: efi_hii.c:132
static void efi_snp_hii_random_guid(EFI_GUID *guid)
Generate a random GUID.
Definition: efi_snp_hii.c:113
unsigned int efi_ifr_varstore_name_value_op(struct efi_ifr_builder *ifr, const EFI_GUID *guid)
Add name/value store opcode to IFR builder.
Definition: efi_hii.c:481
static EFI_GUID efi_hii_ibm_ucm_compliant_formset_guid
EFI IBM UCM compliant formset GUID.
Definition: efi_snp_hii.c:77
128 bit buffer containing a unique identifier value.
Definition: Base.h:215
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:75
static const char * netdev_addr(struct net_device *netdev)
Get printable network device link-layer address.
Definition: netdevice.h:538
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
A hardware device.
Definition: device.h:73
static void efi_snp_hii_questions(struct efi_snp_device *snpdev, struct efi_ifr_builder *ifr, unsigned int varstore_id)
Generate EFI SNP questions.
Definition: efi_snp_hii.c:128
void efi_ifr_guid_subclass_op(struct efi_ifr_builder *ifr, unsigned int subclass)
Add GUID subclass opcode to IFR builder.
Definition: efi_hii.c:288
static struct net_device * netdev
Definition: gdbudp.c:52
void efi_ifr_text_op(struct efi_ifr_builder *ifr, unsigned int prompt_id, unsigned int help_id, unsigned int text_id)
Add text opcode to IFR builder.
Definition: efi_hii.c:440
unsigned int efi_ifr_form_op(struct efi_ifr_builder *ifr, unsigned int title_id)
Add form opcode to IFR builder.
Definition: efi_hii.c:166
const char * driver_name
Driver name.
Definition: device.h:77
static EFI_GUID efi_hii_platform_setup_formset_guid
EFI platform setup formset GUID.
Definition: efi_snp_hii.c:73
unsigned int varstore_id
Current variable store identifier.
Definition: efi_hii.h:33
A network device.
Definition: netdevice.h:352
const char product_version[]
Product version string.
Definition: version.c:70
void efi_ifr_free(struct efi_ifr_builder *ifr)
Free memory used by IFR builder.
Definition: efi_hii.c:505
void efi_ifr_guid_class_op(struct efi_ifr_builder *ifr, unsigned int class)
Add GUID class opcode to IFR builder.
Definition: efi_hii.c:265
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
unsigned int efi_ifr_string(struct efi_ifr_builder *ifr, const char *fmt,...)
Add string to IFR builder.
Definition: efi_hii.c:45
#define EFI_NETWORK_DEVICE_CLASS
Definition: MdeModuleHii.h:101
An EFI IFR builder.
Definition: efi_hii.h:21
const char product_name[]
Product name string.
Definition: version.c:73
The header found at the start of each package list.
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References DBGC, net_device::dev, device::driver_name, efi_hii_ibm_ucm_compliant_formset_guid, efi_hii_platform_setup_formset_guid, efi_ifr_end_op(), efi_ifr_form_op(), efi_ifr_form_set_op(), efi_ifr_free(), efi_ifr_guid_class_op(), efi_ifr_guid_subclass_op(), efi_ifr_init(), efi_ifr_string(), efi_ifr_text_op(), efi_ifr_varstore_name_value_op(), EFI_NETWORK_DEVICE_CLASS, efi_snp_hii_questions(), efi_snp_hii_random_guid(), device::name, name, efi_snp_device::netdev, netdev, netdev_addr(), NULL, product_name, product_short_name, product_version, and efi_ifr_builder::varstore_id.

Referenced by efi_snp_hii_install().

◆ efi_snp_hii_append()

static int efi_snp_hii_append ( struct efi_snp_device *snpdev  __unused,
const char *  key,
const char *  value,
wchar_t **  results 
)
static

Append response to result string.

Parameters
snpdevSNP device
keyKey
valueValue
resultsResult string
Return values
rcReturn status code

The result string is allocated dynamically using BootServices::AllocatePool(), and the caller is responsible for eventually calling BootServices::FreePool().

Definition at line 248 of file efi_snp_hii.c.

250  {
252  EFI_STATUS efirc;
253  size_t len;
254  void *new;
255 
256  /* Allocate new string */
257  len = ( ( *results ? ( wcslen ( *results ) + 1 /* "&" */ ) : 0 ) +
258  strlen ( key ) + 1 /* "=" */ + strlen ( value ) + 1 /* NUL */ );
259  if ( ( efirc = bs->AllocatePool ( EfiBootServicesData,
260  ( len * sizeof ( wchar_t ) ),
261  &new ) ) != 0 )
262  return -EEFI ( efirc );
263 
264  /* Populate string */
265  efi_snprintf ( new, len, "%ls%s%s=%s", ( *results ? *results : L"" ),
266  ( *results ? L"&" : L"" ), key, value );
267  bs->FreePool ( *results );
268  *results = new;
269 
270  return 0;
271 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
size_t wcslen(const wchar_t *string)
Calculate length of wide-character string.
Definition: wchar.c:41
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:106
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
EFI Boot Services Table.
Definition: UefiSpec.h:1917
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1936
uint32_t len
Length.
Definition: ena.h:14
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
EFI_SYSTEM_TABLE * efi_systab
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
union @382 key
Sense key.
Definition: crypto.h:284
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1935

References EFI_BOOT_SERVICES::AllocatePool, EFI_SYSTEM_TABLE::BootServices, EEFI, efi_snprintf(), efi_systab, EfiBootServicesData, EFI_BOOT_SERVICES::FreePool, key, len, strlen(), value, and wcslen().

Referenced by efi_snp_hii_fetch().

◆ efi_snp_hii_fetch()

static int efi_snp_hii_fetch ( struct efi_snp_device snpdev,
const char *  key,
const char *  value,
wchar_t **  results,
int *  have_setting 
)
static

Fetch HII setting.

Parameters
snpdevSNP device
keyKey
valueValue
resultsResult string
have_settingFlag indicating detection of a setting
Return values
rcReturn status code

Definition at line 283 of file efi_snp_hii.c.

285  {
286  struct settings *settings = efi_snp_hii_settings ( snpdev );
287  struct settings *origin;
288  struct setting *setting;
289  struct setting fetched;
290  int len;
291  char *buf;
292  char *encoded;
293  int i;
294  int rc;
295 
296  /* Handle ConfigHdr components */
297  if ( ( strcasecmp ( key, "GUID" ) == 0 ) ||
298  ( strcasecmp ( key, "NAME" ) == 0 ) ||
299  ( strcasecmp ( key, "PATH" ) == 0 ) ) {
300  return efi_snp_hii_append ( snpdev, key, value, results );
301  }
302  if ( have_setting )
303  *have_setting = 1;
304 
305  /* Do nothing more unless we have a settings block */
306  if ( ! settings ) {
307  rc = -ENOTSUP;
308  goto err_no_settings;
309  }
310 
311  /* Identify setting */
312  setting = find_setting ( key );
313  if ( ! setting ) {
314  DBGC ( snpdev, "SNPDEV %p no such setting \"%s\"\n",
315  snpdev, key );
316  rc = -ENODEV;
317  goto err_find_setting;
318  }
319 
320  /* Encode value */
321  if ( setting_exists ( settings, setting ) ) {
322 
323  /* Calculate formatted length */
324  len = fetchf_setting ( settings, setting, &origin, &fetched,
325  NULL, 0 );
326  if ( len < 0 ) {
327  rc = len;
328  DBGC ( snpdev, "SNPDEV %p could not fetch %s: %s\n",
329  snpdev, setting->name, strerror ( rc ) );
330  goto err_fetchf_len;
331  }
332 
333  /* Allocate buffer for formatted value and HII-encoded value */
334  buf = zalloc ( len + 1 /* NUL */ + ( len * 4 ) + 1 /* NUL */ );
335  if ( ! buf ) {
336  rc = -ENOMEM;
337  goto err_alloc;
338  }
339  encoded = ( buf + len + 1 /* NUL */ );
340 
341  /* Format value */
342  fetchf_setting ( origin, &fetched, NULL, NULL, buf,
343  ( len + 1 /* NUL */ ) );
344  for ( i = 0 ; i < len ; i++ ) {
345  sprintf ( ( encoded + ( 4 * i ) ), "%04x",
346  *( ( uint8_t * ) buf + i ) );
347  }
348 
349  } else {
350 
351  /* Non-existent or inapplicable setting */
352  buf = NULL;
353  encoded = "";
354  }
355 
356  /* Append results */
357  if ( ( rc = efi_snp_hii_append ( snpdev, key, encoded,
358  results ) ) != 0 ) {
359  goto err_append;
360  }
361 
362  /* Success */
363  rc = 0;
364 
365  err_append:
366  free ( buf );
367  err_alloc:
368  err_fetchf_len:
369  err_find_setting:
370  err_no_settings:
371  return rc;
372 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t origin
Origin.
Definition: hyperv.h:20
int fetchf_setting(struct settings *settings, const struct setting *setting, struct settings **origin, struct setting *fetched, char *buf, size_t len)
Fetch formatted value of setting.
Definition: settings.c:1229
static struct settings * efi_snp_hii_settings(struct efi_snp_device *snpdev)
Identify settings to be exposed via HII.
Definition: efi_snp_hii.c:89
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:36
static int efi_snp_hii_append(struct efi_snp_device *snpdev __unused, const char *key, const char *value, wchar_t **results)
Append response to result string.
Definition: efi_snp_hii.c:248
#define DBGC(...)
Definition: compiler.h:505
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
const char * name
Name.
Definition: settings.h:28
#define ENOMEM
Not enough space.
Definition: errno.h:534
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define ENODEV
No such device.
Definition: errno.h:509
A settings block.
Definition: settings.h:132
unsigned char uint8_t
Definition: stdint.h:10
A setting.
Definition: settings.h:23
static int setting_exists(struct settings *settings, const struct setting *setting)
Check existence of predefined setting.
Definition: settings.h:543
uint32_t len
Length.
Definition: ena.h:14
struct setting * find_setting(const char *name)
Find predefined setting.
Definition: settings.c:1466
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @382 key
Sense key.
Definition: crypto.h:284

References DBGC, efi_snp_hii_append(), efi_snp_hii_settings(), ENODEV, ENOMEM, ENOTSUP, fetchf_setting(), find_setting(), free, key, len, setting::name, NULL, origin, rc, setting_exists(), sprintf, strcasecmp(), strerror(), value, and zalloc().

Referenced by efi_snp_hii_extract_config().

◆ efi_snp_hii_store()

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 
)
static

Fetch HII setting.

Parameters
snpdevSNP device
keyKey
valueValue
resultsResult string (unused)
have_settingFlag indicating detection of a setting (unused)
Return values
rcReturn status code

Definition at line 384 of file efi_snp_hii.c.

387  {
388  struct settings *settings = efi_snp_hii_settings ( snpdev );
389  struct setting *setting;
390  char *buf;
391  char tmp[5];
392  char *endp;
393  int len;
394  int i;
395  int rc;
396 
397  /* Handle ConfigHdr components */
398  if ( ( strcasecmp ( key, "GUID" ) == 0 ) ||
399  ( strcasecmp ( key, "NAME" ) == 0 ) ||
400  ( strcasecmp ( key, "PATH" ) == 0 ) ) {
401  /* Nothing to do */
402  return 0;
403  }
404 
405  /* Do nothing more unless we have a settings block */
406  if ( ! settings ) {
407  rc = -ENOTSUP;
408  goto err_no_settings;
409  }
410 
411  /* Identify setting */
412  setting = find_setting ( key );
413  if ( ! setting ) {
414  DBGC ( snpdev, "SNPDEV %p no such setting \"%s\"\n",
415  snpdev, key );
416  rc = -ENODEV;
417  goto err_find_setting;
418  }
419 
420  /* Allocate buffer */
421  len = ( strlen ( value ) / 4 );
422  buf = zalloc ( len + 1 /* NUL */ );
423  if ( ! buf ) {
424  rc = -ENOMEM;
425  goto err_alloc;
426  }
427 
428  /* Decode value */
429  tmp[4] = '\0';
430  for ( i = 0 ; i < len ; i++ ) {
431  memcpy ( tmp, ( value + ( i * 4 ) ), 4 );
432  buf[i] = strtoul ( tmp, &endp, 16 );
433  if ( endp != &tmp[4] ) {
434  DBGC ( snpdev, "SNPDEV %p invalid character %s\n",
435  snpdev, tmp );
436  rc = -EINVAL;
437  goto err_inval;
438  }
439  }
440 
441  /* Store value */
442  if ( ( rc = storef_setting ( settings, setting, buf ) ) != 0 ) {
443  DBGC ( snpdev, "SNPDEV %p could not store \"%s\" into %s: %s\n",
444  snpdev, buf, setting->name, strerror ( rc ) );
445  goto err_storef;
446  }
447 
448  /* Success */
449  rc = 0;
450 
451  err_storef:
452  err_inval:
453  free ( buf );
454  err_alloc:
455  err_find_setting:
456  err_no_settings:
457  return rc;
458 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:471
static struct settings * efi_snp_hii_settings(struct efi_snp_device *snpdev)
Identify settings to be exposed via HII.
Definition: efi_snp_hii.c:89
#define DBGC(...)
Definition: compiler.h:505
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
const char * name
Name.
Definition: settings.h:28
unsigned long tmp
Definition: linux_pci.h:53
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int storef_setting(struct settings *settings, const struct setting *setting, const char *value)
Store formatted value of setting.
Definition: settings.c:1319
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define ENODEV
No such device.
Definition: errno.h:509
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
A settings block.
Definition: settings.h:132
A setting.
Definition: settings.h:23
uint32_t len
Length.
Definition: ena.h:14
struct setting * find_setting(const char *name)
Find predefined setting.
Definition: settings.c:1466
union @382 key
Sense key.
Definition: crypto.h:284

References DBGC, efi_snp_hii_settings(), EINVAL, ENODEV, ENOMEM, ENOTSUP, find_setting(), free, key, len, memcpy(), setting::name, rc, storef_setting(), strcasecmp(), strerror(), strlen(), strtoul(), tmp, value, and zalloc().

Referenced by efi_snp_hii_route_config().

◆ efi_snp_hii_process()

static int efi_snp_hii_process ( struct efi_snp_device snpdev,
wchar_t string,
wchar_t **  progress,
wchar_t **  results,
int *  have_setting,
int(*)(struct efi_snp_device *, const char *key, const char *value, wchar_t **results, int *have_setting)  process 
)
static

Process portion of HII configuration string.

Parameters
snpdevSNP device
stringHII configuration string
progressProgress through HII configuration string
resultsResults string
have_settingFlag indicating detection of a setting (unused)
processFunction used to process key=value pairs
Return values
rcReturn status code

Definition at line 471 of file efi_snp_hii.c.

478  {
479  wchar_t *wkey = string;
480  wchar_t *wend = string;
481  wchar_t *wvalue = NULL;
482  size_t key_len;
483  size_t value_len;
484  void *temp;
485  char *key;
486  char *value;
487  int rc;
488 
489  /* Locate key, value (if any), and end */
490  while ( *wend ) {
491  if ( *wend == L'&' )
492  break;
493  if ( *(wend++) == L'=' )
494  wvalue = wend;
495  }
496 
497  /* Allocate memory for key and value */
498  key_len = ( ( wvalue ? ( wvalue - 1 ) : wend ) - wkey );
499  value_len = ( wvalue ? ( wend - wvalue ) : 0 );
500  temp = zalloc ( key_len + 1 /* NUL */ + value_len + 1 /* NUL */ );
501  if ( ! temp )
502  return -ENOMEM;
503  key = temp;
504  value = ( temp + key_len + 1 /* NUL */ );
505 
506  /* Copy key and value */
507  while ( key_len-- )
508  key[key_len] = wkey[key_len];
509  while ( value_len-- )
510  value[value_len] = wvalue[value_len];
511 
512  /* Process key and value */
513  if ( ( rc = process ( snpdev, key, value, results,
514  have_setting ) ) != 0 ) {
515  goto err;
516  }
517 
518  /* Update progress marker */
519  *progress = wend;
520 
521  err:
522  /* Free temporary storage */
523  free ( temp );
524 
525  return rc;
526 }
A process.
Definition: process.h:17
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t string
Definition: multiboot.h:14
static void const void size_t key_len
Definition: crypto.h:285
#define ENOMEM
Not enough space.
Definition: errno.h:534
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @382 key
Sense key.
Definition: crypto.h:284

References ENOMEM, free, key, key_len, NULL, rc, string, value, and zalloc().

Referenced by efi_snp_hii_extract_config(), and efi_snp_hii_route_config().

◆ efi_snp_hii_extract_config()

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 
)
static

Fetch configuration.

Parameters
hiiHII configuration access protocol
requestConfiguration to fetch
Return values
progressProgress made through configuration to fetch
resultsQuery results
efircEFI status code

Definition at line 538 of file efi_snp_hii.c.

540  {
541  struct efi_snp_device *snpdev =
542  container_of ( hii, struct efi_snp_device, hii );
543  int have_setting = 0;
544  wchar_t *pos;
545  int rc;
546 
547  DBGC ( snpdev, "SNPDEV %p ExtractConfig request \"%ls\"\n",
548  snpdev, request );
549 
550  /* Initialise results */
551  *results = NULL;
552 
553  /* Work around apparently broken UEFI specification */
554  if ( ! ( request && request[0] ) ) {
555  DBGC ( snpdev, "SNPDEV %p ExtractConfig ignoring malformed "
556  "request\n", snpdev );
557  return EFI_INVALID_PARAMETER;
558  }
559 
560  /* Process all request fragments */
561  for ( pos = *progress = request ; *progress && **progress ;
562  pos = *progress + 1 ) {
563  if ( ( rc = efi_snp_hii_process ( snpdev, pos, progress,
564  results, &have_setting,
565  efi_snp_hii_fetch ) ) != 0 ) {
566  return EFIRC ( rc );
567  }
568  }
569 
570  /* If we have no explicit request, return all settings */
571  if ( ! have_setting ) {
572  struct setting *setting;
573 
575  if ( ! efi_snp_hii_setting_applies ( snpdev, setting ) )
576  continue;
577  if ( ( rc = efi_snp_hii_fetch ( snpdev, setting->name,
578  NULL, results,
579  NULL ) ) != 0 ) {
580  return EFIRC ( rc );
581  }
582  }
583  }
584 
585  DBGC ( snpdev, "SNPDEV %p ExtractConfig results \"%ls\"\n",
586  snpdev, *results );
587  return 0;
588 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
const char * name
Name.
Definition: settings.h:28
#define SETTINGS
Configuration setting table.
Definition: settings.h:53
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))
Process portion of HII configuration string.
Definition: efi_snp_hii.c:471
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static int efi_snp_hii_fetch(struct efi_snp_device *snpdev, const char *key, const char *value, wchar_t **results, int *have_setting)
Fetch HII setting.
Definition: efi_snp_hii.c:283
static int efi_snp_hii_setting_applies(struct efi_snp_device *snpdev, struct setting *setting)
Check whether or not setting is applicable.
Definition: efi_snp_hii.c:102
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:385
An SNP device.
Definition: efi_snp.h:28
#define EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:116
A setting.
Definition: settings.h:23
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

References container_of, DBGC, EFI_INVALID_PARAMETER, efi_snp_hii_fetch(), efi_snp_hii_process(), efi_snp_hii_setting_applies(), EFIRC, for_each_table_entry, efi_snp_device::hii, setting::name, NULL, rc, request, and SETTINGS.

◆ efi_snp_hii_route_config()

static EFI_STATUS EFIAPI efi_snp_hii_route_config ( const EFI_HII_CONFIG_ACCESS_PROTOCOL hii,
EFI_STRING  config,
EFI_STRING progress 
)
static

Store configuration.

Parameters
hiiHII configuration access protocol
configConfiguration to store
Return values
progressProgress made through configuration to store
efircEFI status code

Definition at line 599 of file efi_snp_hii.c.

600  {
601  struct efi_snp_device *snpdev =
602  container_of ( hii, struct efi_snp_device, hii );
603  wchar_t *pos;
604  int rc;
605 
606  DBGC ( snpdev, "SNPDEV %p RouteConfig \"%ls\"\n", snpdev, config );
607 
608  /* Process all request fragments */
609  for ( pos = *progress = config ; *progress && **progress ;
610  pos = *progress + 1 ) {
611  if ( ( rc = efi_snp_hii_process ( snpdev, pos, progress,
612  NULL, NULL,
613  efi_snp_hii_store ) ) != 0 ) {
614  return EFIRC ( rc );
615  }
616  }
617 
618  return 0;
619 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
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))
Process portion of HII configuration string.
Definition: efi_snp_hii.c:471
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
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)
Fetch HII setting.
Definition: efi_snp_hii.c:384
An SNP device.
Definition: efi_snp.h:28
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

References container_of, DBGC, efi_snp_hii_process(), efi_snp_hii_store(), EFIRC, efi_snp_device::hii, NULL, and rc.

◆ efi_snp_hii_callback()

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 
)
static

Handle form actions.

Parameters
hiiHII configuration access protocol
actionForm browser action
question_idQuestion ID
typeType of value
valueValue
Return values
action_requestAction requested by driver
efircEFI status code

Definition at line 633 of file efi_snp_hii.c.

637  {
638  struct efi_snp_device *snpdev =
639  container_of ( hii, struct efi_snp_device, hii );
640 
641  DBGC ( snpdev, "SNPDEV %p Callback\n", snpdev );
642  return EFI_UNSUPPORTED;
643 }
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
#define DBGC(...)
Definition: compiler.h:505
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An SNP device.
Definition: efi_snp.h:28

References container_of, DBGC, EFI_UNSUPPORTED, and efi_snp_device::hii.

◆ efi_snp_hii_install()

int efi_snp_hii_install ( struct efi_snp_device snpdev)

Install HII protocol and packages for SNP device.

Parameters
snpdevSNP device
Return values
rcReturn status code

Definition at line 658 of file efi_snp_hii.c.

658  {
660  VENDOR_DEVICE_PATH *vendor_path;
661  EFI_DEVICE_PATH_PROTOCOL *path_end;
662  size_t path_prefix_len;
663  int leak = 0;
664  EFI_STATUS efirc;
665  int rc;
666 
667  /* Do nothing if HII database protocol is not supported */
668  if ( ! efihii ) {
669  rc = -ENOTSUP;
670  goto err_no_hii;
671  }
672 
673  /* Initialise HII protocol */
674  memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
675 
676  /* Create HII package list */
677  snpdev->package_list = efi_snp_hii_package_list ( snpdev );
678  if ( ! snpdev->package_list ) {
679  DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
680  snpdev );
681  rc = -ENOMEM;
682  goto err_build_package_list;
683  }
684 
685  /* Allocate the new device path */
686  path_prefix_len = efi_path_len ( snpdev->path );
687  snpdev->hii_child_path = zalloc ( path_prefix_len +
688  sizeof ( *vendor_path ) +
689  sizeof ( *path_end ) );
690  if ( ! snpdev->hii_child_path ) {
691  DBGC ( snpdev,
692  "SNPDEV %p could not allocate HII child device path\n",
693  snpdev );
694  rc = -ENOMEM;
695  goto err_alloc_child_path;
696  }
697 
698  /* Populate the device path */
699  memcpy ( snpdev->hii_child_path, snpdev->path, path_prefix_len );
700  vendor_path = ( ( ( void * ) snpdev->hii_child_path ) +
701  path_prefix_len );
702  vendor_path->Header.Type = HARDWARE_DEVICE_PATH;
703  vendor_path->Header.SubType = HW_VENDOR_DP;
704  vendor_path->Header.Length[0] = sizeof ( *vendor_path );
705  efi_snp_hii_random_guid ( &vendor_path->Guid );
706  path_end = ( ( void * ) ( vendor_path + 1 ) );
707  efi_path_terminate ( path_end );
708 
709  /* Create device path and child handle for HII association */
710  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
711  &snpdev->hii_child_handle,
713  NULL ) ) != 0 ) {
714  rc = -EEFI ( efirc );
715  DBGC ( snpdev, "SNPDEV %p could not create HII child handle: "
716  "%s\n", snpdev, strerror ( rc ) );
717  goto err_hii_child_handle;
718  }
719 
720  /* Add HII packages */
721  if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
722  snpdev->hii_child_handle,
723  &snpdev->hii_handle ) ) != 0 ) {
724  rc = -EEFI ( efirc );
725  DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
726  snpdev, strerror ( rc ) );
727  goto err_new_package_list;
728  }
729 
730  /* Install HII protocol */
731  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
732  &snpdev->hii_child_handle,
734  NULL ) ) != 0 ) {
735  rc = -EEFI ( efirc );
736  DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
737  snpdev, strerror ( rc ) );
738  goto err_install_protocol;
739  }
740 
741  /* Add as child of handle with SNP instance */
742  if ( ( rc = efi_child_add ( snpdev->handle,
743  snpdev->hii_child_handle ) ) != 0 ) {
744  DBGC ( snpdev,
745  "SNPDEV %p could not adopt HII child handle: %s\n",
746  snpdev, strerror ( rc ) );
747  goto err_efi_child_add;
748  }
749 
750  return 0;
751 
752  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
753  err_efi_child_add:
754  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
755  snpdev->hii_child_handle,
757  NULL ) ) != 0 ) {
758  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
759  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
760  leak = 1;
761  }
762  efi_nullify_hii ( &snpdev->hii );
763  err_install_protocol:
764  if ( ! leak )
766  err_new_package_list:
767  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
768  snpdev->hii_child_handle,
770  NULL ) ) != 0 ) {
771  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
772  snpdev, strerror ( -EEFI ( efirc ) ) );
773  leak = 1;
774  }
775  err_hii_child_handle:
776  if ( ! leak ) {
777  free ( snpdev->hii_child_path );
778  snpdev->hii_child_path = NULL;
779  }
780  err_alloc_child_path:
781  if ( ! leak ) {
782  free ( snpdev->package_list );
783  snpdev->package_list = NULL;
784  }
785  err_build_package_list:
786  err_no_hii:
787  return rc;
788 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
static void efi_snp_hii_random_guid(EFI_GUID *guid)
Generate a random GUID.
Definition: efi_snp_hii.c:113
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:506
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition: DevicePath.h:70
#define DBGC(...)
Definition: compiler.h:505
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1996
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:144
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition: efi_utils.c:122
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:66
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:191
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:30
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:156
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:70
EFI_GUID Guid
Vendor-assigned GUID that defines the data that follows.
Definition: DevicePath.h:147
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:143
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:64
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition: DevicePath.h:135
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:142
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1917
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:343
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
static EFI_HII_PACKAGE_LIST_HEADER * efi_snp_hii_package_list(struct efi_snp_device *snpdev)
Build HII package list for SNP device.
Definition: efi_snp_hii.c:163
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:68
static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
HII configuration access protocol.
Definition: efi_snp_hii.c:646
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition: DevicePath.h:53
EFI_HII_DATABASE_NEW_PACK NewPackageList
Definition: HiiDatabase.h:505
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:46
EFI_SYSTEM_TABLE * efi_systab
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:78
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:80

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_add(), efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_path_len(), efi_path_terminate(), efi_snp_device_hii, efi_snp_hii_package_list(), efi_snp_hii_random_guid(), efi_systab, efihii, ENOMEM, ENOTSUP, free, VENDOR_DEVICE_PATH::Guid, efi_snp_device::handle, HARDWARE_DEVICE_PATH, VENDOR_DEVICE_PATH::Header, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, HW_VENDOR_DP, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, EFI_DEVICE_PATH_PROTOCOL::Length, memcpy(), _EFI_HII_DATABASE_PROTOCOL::NewPackageList, NULL, efi_snp_device::package_list, efi_snp_device::path, rc, _EFI_HII_DATABASE_PROTOCOL::RemovePackageList, strerror(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and zalloc().

Referenced by efi_snp_probe().

◆ efi_snp_hii_uninstall()

int efi_snp_hii_uninstall ( struct efi_snp_device snpdev)

Uninstall HII protocol and package for SNP device.

Parameters
snpdevSNP device
Return values
leakUninstallation failed: leak memory

Definition at line 796 of file efi_snp_hii.c.

796  {
798  int leak = efi_shutdown_in_progress;
799  EFI_STATUS efirc;
800 
801  /* Do nothing if HII database protocol is not supported */
802  if ( ! efihii )
803  return 0;
804 
805  /* Uninstall protocols and remove package list */
806  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
807  if ( ( ! efi_shutdown_in_progress ) &&
808  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
809  snpdev->hii_child_handle,
811  NULL ) ) != 0 ) ) {
812  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
813  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
814  leak = 1;
815  }
816  efi_nullify_hii ( &snpdev->hii );
817  if ( ! leak )
819  if ( ( ! efi_shutdown_in_progress ) &&
820  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
821  snpdev->hii_child_handle,
823  NULL ) ) != 0 ) ) {
824  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
825  snpdev, strerror ( -EEFI ( efirc ) ) );
826  leak = 1;
827  }
828  if ( ! leak ) {
829  free ( snpdev->hii_child_path );
830  snpdev->hii_child_path = NULL;
831  free ( snpdev->package_list );
832  snpdev->package_list = NULL;
833  }
834 
835  /* Report leakage, if applicable */
836  if ( leak && ( ! efi_shutdown_in_progress ) )
837  DBGC ( snpdev, "SNPDEV %p HII nullified and leaked\n", snpdev );
838  return leak;
839 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:506
#define DBGC(...)
Definition: compiler.h:505
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:66
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:191
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:156
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:70
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:64
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI Boot Services Table.
Definition: UefiSpec.h:1917
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:343
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:68
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
EFI_SYSTEM_TABLE * efi_systab
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:80

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_shutdown_in_progress, efi_systab, efihii, free, efi_snp_device::handle, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, NULL, efi_snp_device::package_list, _EFI_HII_DATABASE_PROTOCOL::RemovePackageList, strerror(), and EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces.

Referenced by efi_snp_probe(), and efi_snp_remove().

Variable Documentation

◆ efi_hii_platform_setup_formset_guid

EFI_GUID efi_hii_platform_setup_formset_guid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID
static

EFI platform setup formset GUID.

Definition at line 73 of file efi_snp_hii.c.

Referenced by efi_snp_hii_package_list().

◆ efi_hii_ibm_ucm_compliant_formset_guid

EFI_GUID efi_hii_ibm_ucm_compliant_formset_guid = EFI_HII_IBM_UCM_COMPLIANT_FORMSET_GUID
static

EFI IBM UCM compliant formset GUID.

Definition at line 77 of file efi_snp_hii.c.

Referenced by efi_snp_hii_package_list().

◆ efihii

EFI_HII_DATABASE_PROTOCOL* efihii
static

EFI HII database protocol.

Definition at line 80 of file efi_snp_hii.c.

Referenced by efi_snp_hii_install(), and efi_snp_hii_uninstall().

◆ efi_snp_device_hii

EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
static
Initial value:
= {
.ExtractConfig = efi_snp_hii_extract_config,
.RouteConfig = efi_snp_hii_route_config,
.Callback = efi_snp_hii_callback,
}
static EFI_STATUS EFIAPI efi_snp_hii_route_config(const EFI_HII_CONFIG_ACCESS_PROTOCOL *hii, EFI_STRING config, EFI_STRING *progress)
Store configuration.
Definition: efi_snp_hii.c:599
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)
Fetch configuration.
Definition: efi_snp_hii.c:538
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)
Handle form actions.
Definition: efi_snp_hii.c:633

HII configuration access protocol.

Definition at line 646 of file efi_snp_hii.c.

Referenced by efi_snp_hii_install().