|
@@ -44,6 +44,9 @@ static EFI_DRIVER_BINDING_PROTOCOL efi_driver_binding;
|
44
|
44
|
/** List of controlled EFI devices */
|
45
|
45
|
static LIST_HEAD ( efi_devices );
|
46
|
46
|
|
|
47
|
+/** We are currently disconnecting drivers */
|
|
48
|
+static int efi_driver_disconnecting;
|
|
49
|
+
|
47
|
50
|
/**
|
48
|
51
|
* Find EFI device
|
49
|
52
|
*
|
|
@@ -159,6 +162,14 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
159
|
162
|
goto err_already_started;
|
160
|
163
|
}
|
161
|
164
|
|
|
165
|
+ /* Do nothing if we are currently disconnecting drivers */
|
|
166
|
+ if ( efi_driver_disconnecting ) {
|
|
167
|
+ DBGC ( device, "EFIDRV %s refusing to start during "
|
|
168
|
+ "disconnection\n", efi_handle_name ( device ) );
|
|
169
|
+ efirc = EFI_NOT_READY;
|
|
170
|
+ goto err_disconnecting;
|
|
171
|
+ }
|
|
172
|
+
|
162
|
173
|
/* Open device path */
|
163
|
174
|
if ( ( efirc = bs->OpenProtocol ( device,
|
164
|
175
|
&efi_device_path_protocol_guid,
|
|
@@ -220,6 +231,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
220
|
231
|
efi_image_handle, device );
|
221
|
232
|
}
|
222
|
233
|
err_open_path:
|
|
234
|
+ err_disconnecting:
|
223
|
235
|
err_already_started:
|
224
|
236
|
return efirc;
|
225
|
237
|
}
|
|
@@ -411,6 +423,7 @@ static int efi_driver_connect ( EFI_HANDLE device ) {
|
411
|
423
|
DBGC2_EFI_PROTOCOLS ( device, device );
|
412
|
424
|
DBGC ( device, "EFIDRV %s disconnecting existing drivers\n",
|
413
|
425
|
efi_handle_name ( device ) );
|
|
426
|
+ efi_driver_disconnecting = 1;
|
414
|
427
|
if ( ( efirc = bs->DisconnectController ( device, NULL,
|
415
|
428
|
NULL ) ) != 0 ) {
|
416
|
429
|
rc = -EEFI ( efirc );
|
|
@@ -419,6 +432,7 @@ static int efi_driver_connect ( EFI_HANDLE device ) {
|
419
|
432
|
strerror ( rc ) );
|
420
|
433
|
/* Ignore the error and attempt to connect our drivers */
|
421
|
434
|
}
|
|
435
|
+ efi_driver_disconnecting = 0;
|
422
|
436
|
DBGC2 ( device, "EFIDRV %s after disconnecting:\n",
|
423
|
437
|
efi_handle_name ( device ) );
|
424
|
438
|
DBGC2_EFI_PROTOCOLS ( device, device );
|
|
@@ -450,9 +464,11 @@ static int efi_driver_disconnect ( EFI_HANDLE device ) {
|
450
|
464
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
451
|
465
|
|
452
|
466
|
/* Disconnect our driver */
|
|
467
|
+ efi_driver_disconnecting = 1;
|
453
|
468
|
bs->DisconnectController ( device,
|
454
|
469
|
efi_driver_binding.DriverBindingHandle,
|
455
|
470
|
NULL );
|
|
471
|
+ efi_driver_disconnecting = 0;
|
456
|
472
|
return 0;
|
457
|
473
|
}
|
458
|
474
|
|