diff --git a/arch/x86/configs/efi_defconfig b/arch/x86/configs/efi_defconfig index 3e83fd9..fdf092e 100644 --- a/arch/x86/configs/efi_defconfig +++ b/arch/x86/configs/efi_defconfig @@ -55,6 +55,7 @@ CONFIG_CMD_MM=y CONFIG_CMD_DETECT=y CONFIG_CMD_FLASH=y +CONFIG_CMD_POWEROFF=y CONFIG_CMD_2048=y CONFIG_CMD_BAREBOX_UPDATE=y CONFIG_CMD_OF_NODE=y diff --git a/common/efi-guid.c b/common/efi-guid.c index 71aa21d..1e45ccf 100644 --- a/common/efi-guid.c +++ b/common/efi-guid.c @@ -35,6 +35,7 @@ EFI_GUID_STRING(EFI_UGA_PROTOCOL_GUID, "UGA Draw Protocol", "EFI 1.1 UGA Draw Protocol"); EFI_GUID_STRING(EFI_UGA_IO_PROTOCOL_GUID, "UGA Protocol", "EFI 1.1 UGA Protocol"); EFI_GUID_STRING(EFI_PCI_IO_PROTOCOL_GUID, "PCI IO Protocol", "EFI 1.1 PCI IO Protocol"); + EFI_GUID_STRING(EFI_USB_IO_PROTOCOL_GUID, "USB IO Protocol", "EFI 1.0 USB IO Protocol"); EFI_GUID_STRING(EFI_FILE_INFO_GUID, "File Info", "EFI File Infom"); EFI_GUID_STRING(EFI_SIMPLE_FILE_SYSTEM_GUID, "Filesystem", "EFI 1.0 Simple FileSystem"); EFI_GUID_STRING(EFI_DEVICE_TREE_GUID, "Device Tree", "EFI Device Tree GUID"); diff --git a/common/efi/efi.c b/common/efi/efi.c index 4b42f5d..561ce4c 100644 --- a/common/efi/efi.c +++ b/common/efi/efi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -283,9 +284,18 @@ hang(); } +static void __noreturn efi_poweroff_system(struct poweroff_handler *handler) +{ + shutdown_barebox(); + RT->reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); + + hang(); +} + static int restart_register_feature(void) { restart_handler_register_fn(efi_restart_system); + poweroff_handler_register_fn(efi_poweroff_system); return 0; } diff --git a/drivers/block/efi-block-io.c b/drivers/block/efi-block-io.c index a4d9d3a..2bbeb99 100644 --- a/drivers/block/efi-block-io.c +++ b/drivers/block/efi-block-io.c @@ -130,6 +130,18 @@ media->optimal_transfer_length_granularity); } +static int is_bio_usbdev(struct efi_device *efidev) +{ + int i; + + for (i = 0; i < efidev->num_guids; i++) { + if (!efi_guidcmp(efidev->guids[i], EFI_USB_IO_PROTOCOL_GUID)) + return 1; + } + + return 0; +} + int efi_bio_probe(struct efi_device *efidev) { int ret; @@ -147,7 +159,10 @@ efi_bio_print_info(priv); priv->dev = &efidev->dev; - priv->blk.cdev.name = xasprintf("disk%d", cdev_find_free_index("disk")); + if (is_bio_usbdev(efidev)) + priv->blk.cdev.name = xasprintf("usbdisk%d", cdev_find_free_index("usbdisk")); + else + priv->blk.cdev.name = xasprintf("disk%d", cdev_find_free_index("disk")); priv->blk.blockbits = ffs(media->block_size) - 1; priv->blk.num_blocks = media->last_block + 1; priv->blk.ops = &efi_bio_ops; diff --git a/drivers/efi/Kconfig b/drivers/efi/Kconfig index cca1a2e..d6beeb0 100644 --- a/drivers/efi/Kconfig +++ b/drivers/efi/Kconfig @@ -1,4 +1,5 @@ config EFI_BOOTUP bool + select HAS_POWEROFF select BLOCK select PARTITION_DISK diff --git a/include/efi.h b/include/efi.h index e1fc134..7cc5fe0 100644 --- a/include/efi.h +++ b/include/efi.h @@ -358,6 +358,9 @@ #define EFI_PCI_IO_PROTOCOL_GUID \ EFI_GUID( 0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a ) +#define EFI_USB_IO_PROTOCOL_GUID \ + EFI_GUID(0x2B2F68D6, 0x0CD2, 0x44cf, 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75) + #define EFI_FILE_INFO_GUID \ EFI_GUID( 0x9576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )