/** List of controlled EFI devices */
static LIST_HEAD ( efi_devices );
+/** We are currently disconnecting drivers */
+static int efi_driver_disconnecting;
+
/**
* Find EFI device
*
goto err_already_started;
}
+ /* Do nothing if we are currently disconnecting drivers */
+ if ( efi_driver_disconnecting ) {
+ DBGC ( device, "EFIDRV %s refusing to start during "
+ "disconnection\n", efi_handle_name ( device ) );
+ efirc = EFI_NOT_READY;
+ goto err_disconnecting;
+ }
+
/* Open device path */
if ( ( efirc = bs->OpenProtocol ( device,
&efi_device_path_protocol_guid,
efi_image_handle, device );
}
err_open_path:
+ err_disconnecting:
err_already_started:
return efirc;
}
DBGC2_EFI_PROTOCOLS ( device, device );
DBGC ( device, "EFIDRV %s disconnecting existing drivers\n",
efi_handle_name ( device ) );
+ efi_driver_disconnecting = 1;
if ( ( efirc = bs->DisconnectController ( device, NULL,
NULL ) ) != 0 ) {
rc = -EEFI ( efirc );
strerror ( rc ) );
/* Ignore the error and attempt to connect our drivers */
}
+ efi_driver_disconnecting = 0;
DBGC2 ( device, "EFIDRV %s after disconnecting:\n",
efi_handle_name ( device ) );
DBGC2_EFI_PROTOCOLS ( device, device );
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
/* Disconnect our driver */
+ efi_driver_disconnecting = 1;
bs->DisconnectController ( device,
efi_driver_binding.DriverBindingHandle,
NULL );
+ efi_driver_disconnecting = 0;
return 0;
}