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