iPXE
efi_block.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * EFI block device protocols
30  *
31  */
32 
33 #include <stddef.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <errno.h>
39 #include <ipxe/refcnt.h>
40 #include <ipxe/list.h>
41 #include <ipxe/uri.h>
42 #include <ipxe/interface.h>
43 #include <ipxe/blockdev.h>
44 #include <ipxe/xfer.h>
45 #include <ipxe/open.h>
46 #include <ipxe/retry.h>
47 #include <ipxe/timer.h>
48 #include <ipxe/process.h>
49 #include <ipxe/sanboot.h>
50 #include <ipxe/iso9660.h>
51 #include <ipxe/acpi.h>
52 #include <ipxe/efi/efi.h>
57 #include <ipxe/efi/efi_driver.h>
58 #include <ipxe/efi/efi_strings.h>
59 #include <ipxe/efi/efi_snp.h>
60 #include <ipxe/efi/efi_path.h>
61 #include <ipxe/efi/efi_null.h>
62 #include <ipxe/efi/efi_block.h>
63 
64 /** ACPI table protocol protocol */
67 
68 /** Boot filename */
69 static wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME;
70 
71 /** EFI SAN device private data */
73  /** SAN device */
74  struct san_device *sandev;
75  /** EFI handle */
77  /** Media descriptor */
79  /** Block I/O protocol */
81  /** Device path protocol */
83 };
84 
85 /**
86  * Read from or write to EFI block device
87  *
88  * @v sandev SAN device
89  * @v lba Starting LBA
90  * @v data Data buffer
91  * @v len Size of buffer
92  * @v sandev_rw SAN device read/write method
93  * @ret rc Return status code
94  */
95 static int efi_block_rw ( struct san_device *sandev, uint64_t lba,
96  void *data, size_t len,
97  int ( * sandev_rw ) ( struct san_device *sandev,
98  uint64_t lba, unsigned int count,
99  userptr_t buffer ) ) {
100  struct efi_block_data *block = sandev->priv;
101  unsigned int count;
102  int rc;
103 
104  /* Sanity check */
105  count = ( len / block->media.BlockSize );
106  if ( ( count * block->media.BlockSize ) != len ) {
107  DBGC ( sandev->drive, "EFIBLK %#02x impossible length %#zx\n",
108  sandev->drive, len );
109  return -EINVAL;
110  }
111 
112  /* Read from / write to block device */
113  if ( ( rc = sandev_rw ( sandev, lba, count,
114  virt_to_user ( data ) ) ) != 0 ) {
115  DBGC ( sandev->drive, "EFIBLK %#02x I/O failed: %s\n",
116  sandev->drive, strerror ( rc ) );
117  return rc;
118  }
119 
120  return 0;
121 }
122 
123 /**
124  * Reset EFI block device
125  *
126  * @v block_io Block I/O protocol
127  * @v verify Perform extended verification
128  * @ret efirc EFI status code
129  */
131  BOOLEAN verify __unused ) {
132  struct efi_block_data *block =
134  struct san_device *sandev = block->sandev;
135  int rc;
136 
137  DBGC2 ( sandev->drive, "EFIBLK %#02x reset\n", sandev->drive );
138  efi_snp_claim();
139  rc = sandev_reset ( sandev );
140  efi_snp_release();
141  return EFIRC ( rc );
142 }
143 
144 /**
145  * Read from EFI block device
146  *
147  * @v block_io Block I/O protocol
148  * @v media Media identifier
149  * @v lba Starting LBA
150  * @v len Size of buffer
151  * @v data Data buffer
152  * @ret efirc EFI status code
153  */
154 static EFI_STATUS EFIAPI
156  EFI_LBA lba, UINTN len, VOID *data ) {
157  struct efi_block_data *block =
159  struct san_device *sandev = block->sandev;
160  int rc;
161 
162  DBGC2 ( sandev->drive, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
163  sandev->drive, lba, data, ( ( size_t ) len ) );
164  efi_snp_claim();
165  rc = efi_block_rw ( sandev, lba, data, len, sandev_read );
166  efi_snp_release();
167  return EFIRC ( rc );
168 }
169 
170 /**
171  * Write to EFI block device
172  *
173  * @v block_io Block I/O protocol
174  * @v media Media identifier
175  * @v lba Starting LBA
176  * @v len Size of buffer
177  * @v data Data buffer
178  * @ret efirc EFI status code
179  */
180 static EFI_STATUS EFIAPI
182  EFI_LBA lba, UINTN len, VOID *data ) {
183  struct efi_block_data *block =
185  struct san_device *sandev = block->sandev;
186  int rc;
187 
188  DBGC2 ( sandev->drive, "EFIBLK %#02x write LBA %#08llx from "
189  "%p+%#08zx\n", sandev->drive, lba, data, ( ( size_t ) len ) );
190  efi_snp_claim();
191  rc = efi_block_rw ( sandev, lba, data, len, sandev_write );
192  efi_snp_release();
193  return EFIRC ( rc );
194 }
195 
196 /**
197  * Flush data to EFI block device
198  *
199  * @v block_io Block I/O protocol
200  * @ret efirc EFI status code
201  */
202 static EFI_STATUS EFIAPI
204  struct efi_block_data *block =
206  struct san_device *sandev = block->sandev;
207 
208  DBGC2 ( sandev->drive, "EFIBLK %#02x flush\n", sandev->drive );
209 
210  /* Nothing to do */
211  return 0;
212 }
213 
214 /**
215  * Connect all possible drivers to EFI block device
216  *
217  * @v drive Drive number
218  * @v handle Block device handle
219  */
220 static void efi_block_connect ( unsigned int drive, EFI_HANDLE handle ) {
222  EFI_STATUS efirc;
223  int rc;
224 
225  /* Try to connect all possible drivers to this block device */
226  if ( ( efirc = bs->ConnectController ( handle, NULL, NULL,
227  TRUE ) ) != 0 ) {
228  rc = -EEFI ( efirc );
229  DBGC ( drive, "EFIBLK %#02x could not connect drivers: %s\n",
230  drive, strerror ( rc ) );
231  /* May not be an error; may already be connected */
232  }
233  DBGC2 ( drive, "EFIBLK %#02x supports protocols:\n", drive );
235 }
236 
237 /**
238  * Hook EFI block device
239  *
240  * @v drive Drive number
241  * @v uris List of URIs
242  * @v count Number of URIs
243  * @v flags Flags
244  * @ret drive Drive number, or negative error
245  */
246 static int efi_block_hook ( unsigned int drive, struct uri **uris,
247  unsigned int count, unsigned int flags ) {
249  struct san_device *sandev;
250  struct efi_block_data *block;
251  int leak = 0;
252  EFI_STATUS efirc;
253  int rc;
254 
255  /* Sanity check */
256  if ( ! count ) {
257  DBGC ( drive, "EFIBLK %#02x has no URIs\n", drive );
258  rc = -ENOTTY;
259  goto err_no_uris;
260  }
261 
262  /* Allocate and initialise structure */
263  sandev = alloc_sandev ( uris, count, sizeof ( *block ) );
264  if ( ! sandev ) {
265  rc = -ENOMEM;
266  goto err_alloc;
267  }
268  block = sandev->priv;
269  block->sandev = sandev;
270  block->media.MediaPresent = 1;
271  block->media.LogicalBlocksPerPhysicalBlock = 1;
272  block->block_io.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
273  block->block_io.Media = &block->media;
274  block->block_io.Reset = efi_block_io_reset;
275  block->block_io.ReadBlocks = efi_block_io_read;
276  block->block_io.WriteBlocks = efi_block_io_write;
277  block->block_io.FlushBlocks = efi_block_io_flush;
278 
279  /* Register SAN device */
280  if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
281  DBGC ( drive, "EFIBLK %#02x could not register: %s\n",
282  drive, strerror ( rc ) );
283  goto err_register;
284  }
285 
286  /* Update media descriptor */
287  block->media.BlockSize =
289  block->media.LastBlock =
290  ( ( sandev->capacity.blocks >> sandev->blksize_shift ) - 1 );
291 
292  /* Construct device path */
293  if ( ! sandev->active ) {
294  rc = -ENODEV;
295  DBGC ( drive, "EFIBLK %#02x not active after registration\n",
296  drive );
297  goto err_active;
298  }
299  block->path = efi_describe ( &sandev->active->block );
300  if ( ! block->path ) {
301  rc = -ENODEV;
302  DBGC ( drive, "EFIBLK %#02x has no device path\n", drive );
303  goto err_describe;
304  }
305  DBGC2 ( drive, "EFIBLK %#02x has device path %s\n",
306  drive, efi_devpath_text ( block->path ) );
307 
308  /* Install protocols */
309  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
310  &block->handle,
311  &efi_block_io_protocol_guid, &block->block_io,
313  NULL ) ) != 0 ) {
314  rc = -EEFI ( efirc );
315  DBGC ( drive, "EFIBLK %#02x could not install protocols: %s\n",
316  drive, strerror ( rc ) );
317  goto err_install;
318  }
319  DBGC ( drive, "EFIBLK %#02x installed as SAN drive %s\n",
320  drive, efi_handle_name ( block->handle ) );
321 
322  /* Connect all possible protocols */
323  efi_block_connect ( drive, block->handle );
324 
325  return drive;
326 
327  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
328  block->handle,
329  &efi_block_io_protocol_guid, &block->block_io,
331  NULL ) ) != 0 ) {
332  DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
333  "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
334  leak = 1;
335  }
336  efi_nullify_block ( &block->block_io );
337  err_install:
338  if ( ! leak ) {
339  free ( block->path );
340  block->path = NULL;
341  }
342  err_describe:
343  err_active:
345  err_register:
346  if ( ! leak )
347  sandev_put ( sandev );
348  err_alloc:
349  err_no_uris:
350  if ( leak )
351  DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
352  return rc;
353 }
354 
355 /**
356  * Unhook EFI block device
357  *
358  * @v drive Drive number
359  */
360 static void efi_block_unhook ( unsigned int drive ) {
362  struct san_device *sandev;
363  struct efi_block_data *block;
364  int leak = efi_shutdown_in_progress;
365  EFI_STATUS efirc;
366 
367  /* Find SAN device */
368  sandev = sandev_find ( drive );
369  if ( ! sandev ) {
370  DBGC ( drive, "EFIBLK %#02x is not a SAN drive\n", drive );
371  return;
372  }
373  block = sandev->priv;
374 
375  /* Uninstall protocols */
376  if ( ( ! efi_shutdown_in_progress ) &&
377  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
378  block->handle,
379  &efi_block_io_protocol_guid, &block->block_io,
381  NULL ) ) != 0 ) ) {
382  DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
383  "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
384  leak = 1;
385  }
386  efi_nullify_block ( &block->block_io );
387 
388  /* Free device path */
389  if ( ! leak ) {
390  free ( block->path );
391  block->path = NULL;
392  }
393 
394  /* Unregister SAN device */
396 
397  /* Drop reference to drive */
398  if ( ! leak )
399  sandev_put ( sandev );
400 
401  /* Report leakage, if applicable */
402  if ( leak && ( ! efi_shutdown_in_progress ) )
403  DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
404 }
405 
406 /** An installed ACPI table */
408  /** List of installed tables */
409  struct list_head list;
410  /** Table key */
412 };
413 
414 /** List of installed ACPI tables */
415 static LIST_HEAD ( efi_acpi_tables );
416 
417 /**
418  * Install ACPI table
419  *
420  * @v hdr ACPI description header
421  * @ret rc Return status code
422  */
423 static int efi_block_install ( struct acpi_header *hdr ) {
424  size_t len = le32_to_cpu ( hdr->length );
425  struct efi_acpi_table *installed;
426  EFI_STATUS efirc;
427  int rc;
428 
429  /* Allocate installed table record */
430  installed = zalloc ( sizeof ( *installed ) );
431  if ( ! installed ) {
432  rc = -ENOMEM;
433  goto err_alloc;
434  }
435 
436  /* Fill in common parameters */
437  strncpy ( hdr->oem_id, "FENSYS", sizeof ( hdr->oem_id ) );
438  strncpy ( hdr->oem_table_id, "iPXE", sizeof ( hdr->oem_table_id ) );
439 
440  /* Fix up ACPI checksum */
442 
443  /* Install table */
444  if ( ( efirc = acpi->InstallAcpiTable ( acpi, hdr, len,
445  &installed->key ) ) != 0 ){
446  rc = -EEFI ( efirc );
447  DBGC ( acpi, "EFIBLK could not install %s: %s\n",
448  acpi_name ( hdr->signature ), strerror ( rc ) );
449  DBGC2_HDA ( acpi, 0, hdr, len );
450  goto err_install;
451  }
452 
453  /* Add to list of installed tables */
454  list_add_tail ( &installed->list, &efi_acpi_tables );
455 
456  DBGC ( acpi, "EFIBLK installed %s as ACPI table %#lx\n",
457  acpi_name ( hdr->signature ),
458  ( ( unsigned long ) installed->key ) );
459  DBGC2_HDA ( acpi, 0, hdr, len );
460  return 0;
461 
462  list_del ( &installed->list );
463  err_install:
464  free ( installed );
465  err_alloc:
466  return rc;
467 }
468 
469 /**
470  * Describe EFI block devices
471  *
472  * @ret rc Return status code
473  */
474 static int efi_block_describe ( void ) {
475  struct efi_acpi_table *installed;
476  struct efi_acpi_table *tmp;
477  UINTN key;
478  EFI_STATUS efirc;
479  int rc;
480 
481  /* Sanity check */
482  if ( ! acpi ) {
483  DBG ( "EFIBLK has no ACPI table protocol\n" );
484  return -ENOTSUP;
485  }
486 
487  /* Uninstall any existing ACPI tables */
488  list_for_each_entry_safe ( installed, tmp, &efi_acpi_tables, list ) {
489  key = installed->key;
490  if ( ( efirc = acpi->UninstallAcpiTable ( acpi, key ) ) != 0 ) {
491  rc = -EEFI ( efirc );
492  DBGC ( acpi, "EFIBLK could not uninstall ACPI table "
493  "%#lx: %s\n", ( ( unsigned long ) key ),
494  strerror ( rc ) );
495  /* Continue anyway */
496  }
497  list_del ( &installed->list );
498  free ( installed );
499  }
500 
501  /* Install ACPI tables */
502  if ( ( rc = acpi_install ( efi_block_install ) ) != 0 ) {
503  DBGC ( acpi, "EFIBLK could not install ACPI tables: %s\n",
504  strerror ( rc ) );
505  return rc;
506  }
507 
508  return 0;
509 }
510 
511 /**
512  * Open root directory within a filesystem
513  *
514  * @v drive Drive number
515  * @v handle Filesystem handle
516  * @v root Root directory file to fill in
517  * @ret rc Return status code
518  */
519 static int efi_block_root ( unsigned int drive, EFI_HANDLE handle,
520  EFI_FILE_PROTOCOL **root ) {
523  union {
525  void *interface;
526  } u;
527  EFI_STATUS efirc;
528  int rc;
529 
530  /* Open filesystem protocol */
531  if ( ( efirc = bs->OpenProtocol ( handle, protocol, &u.interface,
534  rc = -EEFI ( efirc );
535  DBGC ( drive, "EFIBLK %#02x could not open %s filesystem: %s\n",
536  drive, efi_handle_name ( handle ), strerror ( rc ) );
537  goto err_open;
538  }
539 
540  /* Open root volume */
541  if ( ( efirc = u.fs->OpenVolume ( u.fs, root ) ) != 0 ) {
542  rc = -EEFI ( efirc );
543  DBGC ( drive, "EFIBLK %#02x could not open %s root: %s\n",
544  drive, efi_handle_name ( handle ), strerror ( rc ) );
545  goto err_volume;
546  }
547 
548  /* Success */
549  rc = 0;
550 
551  err_volume:
553  err_open:
554  return rc;
555 }
556 
557 /**
558  * Check for existence of a file within a filesystem
559  *
560  * @v drive Drive number
561  * @v handle Filesystem handle
562  * @v root Root directory
563  * @v filename Filename (or NULL to use default)
564  * @ret rc Return status code
565  */
566 static int efi_block_filename ( unsigned int drive, EFI_HANDLE handle,
568  const char *filename ) {
569  CHAR16 tmp[ filename ? ( strlen ( filename ) + 1 /* wNUL */ ) : 0 ];
570  CHAR16 *wname;
571  EFI_FILE_PROTOCOL *file;
572  EFI_STATUS efirc;
573  int rc;
574 
575  /* Construct filename */
576  if ( filename ) {
577  efi_snprintf ( tmp, sizeof ( tmp ), "%s", filename );
578  wname = tmp;
579  } else {
580  wname = efi_block_boot_filename;
581  }
582 
583  /* Try opening file */
584  if ( ( efirc = root->Open ( root, &file, wname,
585  EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
586  rc = -EEFI ( efirc );
587  DBGC ( drive, "EFIBLK %#02x could not open %s/%ls: %s\n",
588  drive, efi_handle_name ( handle ), wname,
589  strerror ( rc ) );
590  goto err_file;
591  }
592 
593  /* Success */
594  rc = 0;
595 
596  file->Close ( file );
597  err_file:
598  return rc;
599 }
600 
601 /**
602  * Check for EFI block device filesystem label
603  *
604  * @v drive Drive number
605  * @v root Root directory
606  * @v label Volume label
607  * @ret rc Return status code
608  */
609 static int efi_block_label ( unsigned int drive, EFI_FILE_PROTOCOL *root,
610  const char *label ) {
612  UINTN size;
613  char *actual;
614  EFI_STATUS efirc;
615  int rc;
616 
617  /* Get length of file system information */
618  size = 0;
619  root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
620 
621  /* Allocate file system information */
622  info = malloc ( size );
623  if ( ! info ) {
624  rc = -ENOMEM;
625  goto err_alloc_info;
626  }
627 
628  /* Get file system information */
629  if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
630  info ) ) != 0 ) {
631  rc = -EEFI ( efirc );
632  DBGC ( drive, "EFIBLK %#02x could not get filesystem info: "
633  "%s\n", drive, strerror ( rc ) );
634  goto err_get_info;
635  }
636 
637  /* Construct volume label for comparison */
638  if ( asprintf ( &actual, "%ls", info->VolumeLabel ) < 0 ) {
639  rc = -ENOMEM;
640  goto err_alloc_label;
641  }
642 
643  /* Compare volume label */
644  if ( strcasecmp ( label, actual ) != 0 ) {
645  DBGC ( drive, "EFIBLK %#02x has wrong label \"%s\"\n",
646  drive, actual );
647  rc = -ENOENT;
648  goto err_compare;
649  }
650 
651  /* Success */
652  rc = 0;
653 
654  err_compare:
655  free ( actual );
656  err_alloc_label:
657  err_get_info:
658  free ( info );
659  err_alloc_info:
660  return rc;
661 }
662 
663 /**
664  * Check EFI block device filesystem match
665  *
666  * @v drive Drive number
667  * @v handle Filesystem handle
668  * @v path Block device path
669  * @v config Boot configuration parameters
670  * @v fspath Filesystem device path to fill in
671  * @ret rc Return status code
672  */
673 static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
675  struct san_boot_config *config,
676  EFI_DEVICE_PATH_PROTOCOL **fspath ) {
679  union {
681  void *interface;
682  } u;
683  EFI_FILE *root;
684  union uuid guid;
685  EFI_STATUS efirc;
686  int rc;
687 
688  /* Identify device path */
689  if ( ( efirc = bs->OpenProtocol ( handle, protocol, &u.interface,
692  rc = -EEFI ( efirc );
693  DBGC ( drive, "EFIBLK %#02x could not open %s device path: "
694  "%s\n", drive, efi_handle_name ( handle ),
695  strerror ( rc ) );
696  goto err_open;
697  }
698  *fspath = u.path;
699 
700  /* Check if filesystem is a child of this block device */
701  if ( memcmp ( u.path, path, efi_path_len ( path ) ) != 0 ) {
702  /* Not a child device */
703  rc = -ENOTTY;
704  DBGC2 ( drive, "EFIBLK %#02x is not parent of %s\n",
706  goto err_not_child;
707  }
708  DBGC ( drive, "EFIBLK %#02x contains filesystem %s\n",
709  drive, efi_devpath_text ( u.path ) );
710 
711  /* Check if filesystem matches GUID, if applicable */
712  if ( config->uuid ) {
713  if ( ( rc = efi_path_guid ( u.path, &guid ) ) != 0 ) {
714  DBGC ( drive, "EFIBLK %#02x could not determine GUID: "
715  "%s\n", drive, strerror ( rc ) );
716  goto err_no_guid;
717  }
718  if ( memcmp ( config->uuid, &guid, sizeof ( guid ) ) != 0 ) {
719  DBGC ( drive, "EFIBLK %#02x has wrong GUID %s\n",
720  drive, uuid_ntoa ( &guid ) );
721  rc = -ENOENT;
722  goto err_wrong_guid;
723  }
724  }
725 
726  /* Open root directory */
727  if ( ( rc = efi_block_root ( drive, handle, &root ) ) != 0 )
728  goto err_root;
729 
730  /* Check if filesystem contains boot filename */
731  if ( ( rc = efi_block_filename ( drive, handle, root,
732  config->filename ) ) != 0 ) {
733  goto err_filename;
734  }
735 
736  /* Check if filesystem contains additional filename, if applicable */
737  if ( config->extra &&
739  config->extra ) ) != 0 ) ) {
740  goto err_extra;
741  }
742 
743  /* Check volume label, if applicable */
744  if ( config->label &&
745  ( ( rc = efi_block_label ( drive, root,
746  config->label ) ) != 0 ) ) {
747  goto err_label;
748  }
749 
750  /* Success */
751  rc = 0;
752 
753  err_label:
754  err_extra:
755  err_filename:
756  root->Close ( root );
757  err_root:
758  err_wrong_guid:
759  err_no_guid:
760  err_not_child:
762  err_open:
763  return rc;
764 }
765 
766 /**
767  * Scan EFI block device for a matching filesystem
768  *
769  * @v drive Drive number
770  * @v handle Block device handle
771  * @v config Boot configuration parameters
772  * @v fspath Filesystem device path to fill in
773  * @ret rc Return status code
774  */
775 static int efi_block_scan ( unsigned int drive, EFI_HANDLE handle,
776  struct san_boot_config *config,
777  EFI_DEVICE_PATH_PROTOCOL **fspath ) {
780  union {
782  void *interface;
783  } u;
784  EFI_HANDLE *handles;
785  UINTN count;
786  unsigned int i;
787  EFI_STATUS efirc;
788  int rc;
789 
790  /* Connect up possible file system drivers */
792 
793  /* Identify device path */
794  if ( ( efirc = bs->OpenProtocol ( handle, protocol, &u.interface,
797  rc = -EEFI ( efirc );
798  DBGC ( drive, "EFIBLK %#02x could not open device path: %s\n",
799  drive, strerror ( rc ) );
800  goto err_open;
801  }
802 
803  /* Locate all Simple File System protocol handles */
804  if ( ( efirc = bs->LocateHandleBuffer (
806  NULL, &count, &handles ) ) != 0 ) {
807  rc = -EEFI ( efirc );
808  DBGC ( drive, "EFIBLK %#02x cannot locate file systems: %s\n",
809  drive, strerror ( rc ) );
810  goto err_locate;
811  }
812 
813  /* Scan for a matching filesystem */
814  rc = -ENOENT;
815  for ( i = 0 ; i < count ; i++ ) {
816 
817  /* Check for a matching filesystem */
818  if ( ( rc = efi_block_match ( drive, handles[i], u.path,
819  config, fspath ) ) != 0 )
820  continue;
821 
822  break;
823  }
824 
825  bs->FreePool ( handles );
826  err_locate:
828  err_open:
829  return rc;
830 }
831 
832 /**
833  * Boot from EFI block device filesystem boot image
834  *
835  * @v drive Drive number
836  * @v fspath Filesystem device path
837  * @v filename Filename (or NULL to use default)
838  * @ret rc Return status code
839  */
840 static int efi_block_exec ( unsigned int drive,
841  EFI_DEVICE_PATH_PROTOCOL *fspath,
842  const char *filename ) {
845  FILEPATH_DEVICE_PATH *filepath;
848  size_t fspath_len;
849  size_t filepath_len;
850  size_t path_len;
851  EFI_STATUS efirc;
852  int rc;
853 
854  /* Construct device path for boot image */
855  end = efi_path_end ( fspath );
856  fspath_len = ( ( ( void * ) end ) - ( ( void * ) fspath ) );
857  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
858  ( filename ?
859  ( ( strlen ( filename ) + 1 /* NUL */ ) *
860  sizeof ( filepath->PathName[0] ) ) :
861  sizeof ( efi_block_boot_filename ) ) );
862  path_len = ( fspath_len + filepath_len + sizeof ( *end ) );
863  path = zalloc ( path_len );
864  if ( ! path ) {
865  rc = -ENOMEM;
866  goto err_alloc;
867  }
868  memcpy ( path, fspath, fspath_len );
869  filepath = ( ( ( void * ) path ) + fspath_len );
870  filepath->Header.Type = MEDIA_DEVICE_PATH;
871  filepath->Header.SubType = MEDIA_FILEPATH_DP;
872  filepath->Header.Length[0] = ( filepath_len & 0xff );
873  filepath->Header.Length[1] = ( filepath_len >> 8 );
874  if ( filename ) {
875  efi_sprintf ( filepath->PathName, "%s", filename );
876  } else {
878  sizeof ( efi_block_boot_filename ) );
879  }
880  end = ( ( ( void * ) filepath ) + filepath_len );
882  DBGC ( drive, "EFIBLK %#02x trying to load %s\n",
883  drive, efi_devpath_text ( path ) );
884 
885  /* Load image */
886  image = NULL;
887  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path, NULL, 0,
888  &image ) ) != 0 ) {
889  rc = -EEFI ( efirc );
890  DBGC ( drive, "EFIBLK %#02x could not load: %s\n",
891  drive, strerror ( rc ) );
892  if ( efirc == EFI_SECURITY_VIOLATION ) {
893  goto err_load_security_violation;
894  } else {
895  goto err_load;
896  }
897  }
898 
899  /* Start image */
900  efirc = bs->StartImage ( image, NULL, NULL );
901  rc = ( efirc ? -EEFI ( efirc ) : 0 );
902  DBGC ( drive, "EFIBLK %#02x boot image returned: %s\n",
903  drive, strerror ( rc ) );
904 
905  err_load_security_violation:
906  bs->UnloadImage ( image );
907  err_load:
908  free ( path );
909  err_alloc:
910  return rc;
911 }
912 
913 /**
914  * Check that EFI block device is eligible for a local virtual drive number
915  *
916  * @v handle Block device handle
917  * @ret rc Return status code
918  *
919  * We assign virtual drive numbers for local (non-SAN) EFI block
920  * devices that represent complete disks, to provide roughly
921  * equivalent functionality to BIOS drive numbers.
922  */
926  struct san_device *sandev;
927  struct efi_block_data *block;
928  union {
929  EFI_BLOCK_IO_PROTOCOL *blockio;
930  void *interface;
931  } u;
932  EFI_STATUS efirc;
933  int rc;
934 
935  /* Check if handle belongs to a SAN device */
936  for_each_sandev ( sandev ) {
937  block = sandev->priv;
938  if ( handle == block->handle ) {
939  rc = -ENOTTY;
940  goto err_sandev;
941  }
942  }
943 
944  /* Open block I/O protocol */
945  if ( ( efirc = bs->OpenProtocol ( handle, protocol, &u.interface,
948  rc = -EEFI ( efirc );
949  DBGC ( handle, "EFIBLK %s could not open block I/O: %s\n",
950  efi_handle_name ( handle ), strerror ( rc ) );
951  goto err_open;
952  }
953 
954  /* Do not assign drive numbers for partitions */
955  if ( u.blockio->Media->LogicalPartition ) {
956  rc = -ENOTTY;
957  DBGC2 ( handle, "EFLBLK %s is a partition\n",
958  efi_handle_name ( handle ) );
959  goto err_partition;
960  }
961 
962  /* Success */
963  rc = 0;
964 
965  err_partition:
967  err_open:
968  err_sandev:
969  return rc;
970 }
971 
972 /**
973  * Boot from EFI block device
974  *
975  * @v drive Drive number
976  * @v config Boot configuration parameters
977  * @ret rc Return status code
978  */
979 static int efi_block_boot ( unsigned int drive,
980  struct san_boot_config *config ) {
982  EFI_DEVICE_PATH_PROTOCOL *fspath = NULL;
983  EFI_HANDLE *handles;
985  UINTN count;
986  struct san_device *sandev;
987  struct efi_block_data *block;
988  unsigned int vdrive;
989  unsigned int index;
990  EFI_STATUS efirc;
991  int rc;
992 
993  /* Release SNP devices */
994  efi_snp_release();
995 
996  /* Locate all block I/O protocol handles */
997  if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol,
999  NULL, &count,
1000  &handles ) ) != 0 ) {
1001  rc = -EEFI ( efirc );
1002  DBGC ( drive, "EFIBLK %#02x cannot locate block I/O: %s\n",
1003  drive, strerror ( rc ) );
1004  goto err_locate_block_io;
1005  }
1006 
1007  /* Try booting from the first matching block device, if any */
1008  rc = -ENOENT;
1009  for ( vdrive = 0, index = 0 ; ; vdrive++ ) {
1010 
1011  /* Identify next drive number and block I/O handle */
1012  if ( ( sandev = sandev_next ( vdrive ) ) &&
1013  ( ( sandev->drive == vdrive ) ||
1014  ( sandev->drive <= SAN_DEFAULT_DRIVE ) ||
1015  ( index >= count ) ) ) {
1016 
1017  /* There is a SAN drive that either:
1018  *
1019  * a) has the current virtual drive number, or
1020  * b) has a drive number below SAN_DEFAULT_DRIVE, or
1021  * c) has a drive number higher than any local drive
1022  *
1023  * Use this SAN drive, since the explicit SAN
1024  * drive numbering takes precedence over the
1025  * implicit local drive numbering.
1026  */
1027  block = sandev->priv;
1028  handle = block->handle;
1029 
1030  /* Use SAN drive's explicit drive number */
1031  vdrive = sandev->drive;
1032  DBGC ( vdrive, "EFIBLK %#02x is SAN drive %s\n",
1033  vdrive, efi_handle_name ( handle ) );
1034 
1035  } else if ( index < count ) {
1036 
1037  /* There is no SAN drive meeting any of the
1038  * above criteria. Try the next block I/O
1039  * handle.
1040  */
1041  handle = handles[index++];
1042 
1043  /* Check if this handle is eligible to be
1044  * given a local virtual drive number.
1045  *
1046  * Do not record this as the overall error
1047  * status, since it is not an interesting
1048  * error.
1049  */
1050  if ( efi_block_local ( handle ) != 0 ) {
1051  /* Do not consume virtual drive number */
1052  vdrive--;
1053  continue;
1054  }
1055 
1056  /* Use the current virtual drive number, with
1057  * a minimum of SAN_DEFAULT_DRIVE to match
1058  * typical BIOS drive numbering.
1059  */
1060  if ( vdrive < SAN_DEFAULT_DRIVE )
1061  vdrive = SAN_DEFAULT_DRIVE;
1062  DBGC ( vdrive, "EFIBLK %#02x is local drive %s\n",
1063  vdrive, efi_handle_name ( handle ) );
1064 
1065  } else {
1066 
1067  /* No more SAN or local drives */
1068  break;
1069  }
1070 
1071  /* Skip non-matching drives */
1072  if ( drive && ( drive != vdrive ) )
1073  continue;
1074  DBGC ( vdrive, "EFIBLK %#02x attempting to boot\n", vdrive );
1075 
1076  /* Scan for a matching filesystem within this drive */
1077  if ( ( rc = efi_block_scan ( vdrive, handle, config,
1078  &fspath ) ) != 0 ) {
1079  continue;
1080  }
1081 
1082  /* Attempt to boot from the matched filesystem */
1083  rc = efi_block_exec ( vdrive, fspath, config->filename );
1084  break;
1085  }
1086 
1087  bs->FreePool ( handles );
1088  err_locate_block_io:
1089  efi_snp_claim();
1090  return rc;
1091 }
1092 
static int efi_block_describe(void)
Describe EFI block devices.
Definition: efi_block.c:474
EFI_FILE_CLOSE Close
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
#define EINVAL
Invalid argument.
Definition: errno.h:428
The EFI_ACPI_TABLE_PROTOCOL provides the ability for a component to install and uninstall ACPI tables...
Definition: AcpiTable.h:116
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition: sanboot.c:574
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void efi_block_connect(unsigned int drive, EFI_HANDLE handle)
Connect all possible drivers to EFI block device.
Definition: efi_block.c:220
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE InstallAcpiTable
Definition: AcpiTable.h:117
u32 info
Definition: ar9003_mac.h:67
EFI driver interface.
UINTN key
Table key.
Definition: efi_block.c:411
int san_describe(void)
Describe SAN devices for SAN-booted operating system.
uint32_t lba
Start address.
Definition: scsi.h:23
int san_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook SAN device.
#define le32_to_cpu(value)
Definition: byteswap.h:113
struct stp_switch root
Root switch.
Definition: stp.h:26
struct san_device * sandev
SAN device.
Definition: efi_block.c:74
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:393
128 bit buffer containing a unique identifier value.
Definition: Base.h:215
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:596
Error codes.
A universally unique ID.
Definition: uuid.h:15
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
static int efi_block_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook EFI block device.
Definition: efi_block.c:246
EFI strings.
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1964
unsigned char BOOLEAN
Retry timers.
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:939
int san_boot(unsigned int drive, struct san_boot_config *config)
Attempt to boot from a SAN device.
#define DBGC(...)
Definition: compiler.h:505
This protocol provides control over block devices.
Definition: BlockIo.h:216
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
#define ENOENT
No such file or directory.
Definition: errno.h:514
unsigned int UINT32
Definition: ProcessorBind.h:98
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1996
unsigned long long uint64_t
Definition: stdint.h:13
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:144
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:225
unsigned short CHAR16
static EFI_STATUS EFIAPI efi_block_io_write(EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
Write to EFI block device.
Definition: efi_block.c:181
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:80
iPXE timers
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1967
An executable image.
Definition: image.h:24
static int efi_block_local(EFI_HANDLE handle)
Check that EFI block device is eligible for a local virtual drive number.
Definition: efi_block.c:923
uint8_t drive
Drive number.
Definition: int13.h:16
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1086
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1082
Uniform Resource Identifiers.
static int efi_block_rw(struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Read from or write to EFI block device.
Definition: efi_block.c:95
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
EFI SAN device private data.
Definition: efi_block.c:72
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A doubly-linked list entry (or list head)
Definition: list.h:18
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:30
Data transfer interfaces.
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
Definition: efi_block.c:82
unsigned long tmp
Definition: linux_pci.h:53
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition: string.c:347
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define EFI_BLOCK_IO_PROTOCOL_REVISION3
Definition: BlockIo.h:206
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_ACPI_TABLE_UNINSTALL_ACPI_TABLE UninstallAcpiTable
Definition: AcpiTable.h:118
static int efi_block_match(unsigned int drive, EFI_HANDLE handle, EFI_DEVICE_PATH_PROTOCOL *path, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
Check EFI block device filesystem match.
Definition: efi_block.c:673
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:124
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:303
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:47
Object interfaces.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:65
unsigned int drive
Drive number.
Definition: sanboot.h:65
SAN boot configuration parameters.
Definition: sanboot.h:110
union uuid * uuid
UUID (or NULL to ignore UUID)
Definition: sanboot.h:118
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition: sanboot.c:877
static int efi_block_install(struct acpi_header *hdr)
Install ACPI table.
Definition: efi_block.c:423
static int efi_block_exec(unsigned int drive, EFI_DEVICE_PATH_PROTOCOL *fspath, const char *filename)
Boot from EFI block device filesystem boot image.
Definition: efi_block.c:840
static void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
Definition: efi_block.c:360
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:106
const char * filename
Boot filename (or NULL to use default)
Definition: sanboot.h:112
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:84
static int efi_block_boot(unsigned int drive, struct san_boot_config *config)
Boot from EFI block device.
Definition: efi_block.c:979
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition: acpi.c:85
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1089
EFI_REQUEST_PROTOCOL(EFI_ACPI_TABLE_PROTOCOL, &acpi)
uint64_t blocks
Total number of blocks.
Definition: blockdev.h:20
ISO9660 CD-ROM specification.
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:461
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1344
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
EFI null interfaces.
Linked lists.
#define DBGC2_HDA(...)
Definition: compiler.h:523
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition: acpi.c:336
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
static EFI_STATUS EFIAPI efi_block_io_reset(EFI_BLOCK_IO_PROTOCOL *block_io, BOOLEAN verify __unused)
Reset EFI block device.
Definition: efi_block.c:130
uint32_t fs
Definition: librm.h:252
Block devices.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
ACPI data structures.
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define EFIAPI
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1917
#define efi_sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.h:45
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: asprintf.c:41
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:645
static LIST_HEAD(efi_acpi_tables)
List of installed ACPI tables.
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
EFI_CONNECT_CONTROLLER ConnectController
Definition: UefiSpec.h:1980
#define ENODEV
No such device.
Definition: errno.h:509
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:99
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
A SAN device.
Definition: sanboot.h:58
const char * label
Filesystem label (or NULL to ignore volume label)
Definition: sanboot.h:116
Processes.
static int efi_block_filename(unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL *root, const char *filename)
Check for existence of a file within a filesystem.
Definition: efi_block.c:566
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition: efi_block.c:69
Data transfer interface opening.
EFI device paths.
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1965
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:991
UINT64 UINTN
Unsigned value of native width.
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:196
struct san_device * sandev_next(unsigned int drive)
Find next SAN device by drive number.
Definition: sanboot.c:106
An ACPI description header.
Definition: acpi.h:163
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
#define VOID
Undeclared type.
Definition: Base.h:271
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition: uuid.c:45
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1936
#define TRUE
Definition: tlan.h:46
static int efi_block_scan(unsigned int drive, EFI_HANDLE handle, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
Scan EFI block device for a matching filesystem.
Definition: efi_block.c:775
EFI_HANDLE handle
EFI handle.
Definition: efi_block.c:76
EFI API.
uint64_t guid
GUID.
Definition: edd.h:30
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:130
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
struct list_head list
List of installed tables.
Definition: efi_block.c:409
void san_unhook(unsigned int drive)
Unhook SAN device.
static EFI_STATUS EFIAPI efi_block_io_read(EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
Read from EFI block device.
Definition: efi_block.c:155
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:680
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
uint32_t len
Length.
Definition: ena.h:14
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:90
#define DBGC2(...)
Definition: compiler.h:522
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:119
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
static EFI_STATUS EFIAPI efi_block_io_flush(EFI_BLOCK_IO_PROTOCOL *block_io)
Flush data to EFI block device.
Definition: efi_block.c:203
const char * extra
Required extra filename (or NULL to ignore)
Definition: sanboot.h:114
#define EFI_FILE_MODE_READ
void efi_nullify_block(EFI_BLOCK_IO_PROTOCOL *block)
Nullify block I/O protocol.
Definition: efi_null.c:396
void * priv
Driver private data.
Definition: sanboot.h:89
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
uint16_t count
Number of entries.
Definition: ena.h:22
static int efi_block_label(unsigned int drive, EFI_FILE_PROTOCOL *root, const char *label)
Check for EFI block device filesystem label.
Definition: efi_block.c:609
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:190
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define DBGC2_EFI_PROTOCOLS(...)
Definition: efi.h:334
Block IO protocol as defined in the UEFI 2.0 specification.
union @17 u
Reference counting.
EFI_BLOCK_IO_MEDIA media
Media descriptor.
Definition: efi_block.c:78
uint32_t end
Ending offset.
Definition: netvsc.h:18
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
static char media[]
Definition: sundance.c:85
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define FALSE
Definition: tlan.h:45
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:46
Retrieve the set of handles from the handle database that support a specified protocol.
Definition: UefiSpec.h:1520
A Uniform Resource Identifier.
Definition: uri.h:64
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1986
uint16_t protocol
Protocol ID.
Definition: stp.h:18
iPXE EFI SNP interface
struct san_path * active
Current active path.
Definition: sanboot.h:94
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition: sanboot.h:33
The file provides the protocol to install or remove an ACPI table from a platform.
static int efi_block_root(unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL **root)
Open root directory within a filesystem.
Definition: efi_block.c:519
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
iPXE sanboot API
uint16_t handle
Handle.
Definition: smbios.h:16
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
Definition: sanboot.c:665
String functions.
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.GetInfo() or EFI_FILE_PR...
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_path.c:133
PROVIDE_SANBOOT(efi, san_hook, efi_block_hook)
An installed ACPI table.
Definition: efi_block.c:407
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
Definition: efi_path.c:204
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
union @382 key
Sense key.
Definition: crypto.h:284
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
Definition: efi.h:59
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct san_device * alloc_sandev(struct uri **uris, unsigned int count, size_t priv_size)
Allocate SAN device.
Definition: sanboot.c:834
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition: UefiSpec.h:1994
size_t blksize
Block size.
Definition: blockdev.h:22
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
String functions.
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1080
uint8_t flags
Flags.
Definition: ena.h:18