mirror of https://github.com/ipxe/ipxe.git
[efi] Raise TPL within EFI_DRIVER_BINDING_PROTOCOL entry points
Debugged-by: Rob Taglang <rob@privatemachines.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/69/merge
parent
d8c500b794
commit
10d083ffa9
|
@ -95,7 +95,9 @@ struct efi_device * efidev_parent ( struct device *dev ) {
|
||||||
static EFI_STATUS EFIAPI
|
static EFI_STATUS EFIAPI
|
||||||
efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
|
EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_driver *efidrv;
|
struct efi_driver *efidrv;
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
DBGCP ( device, "EFIDRV %s DRIVER_SUPPORTED",
|
DBGCP ( device, "EFIDRV %s DRIVER_SUPPORTED",
|
||||||
|
@ -111,17 +113,22 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
return EFI_ALREADY_STARTED;
|
return EFI_ALREADY_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Look for a driver claiming to support this device */
|
/* Look for a driver claiming to support this device */
|
||||||
for_each_table_entry ( efidrv, EFI_DRIVERS ) {
|
for_each_table_entry ( efidrv, EFI_DRIVERS ) {
|
||||||
if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
|
if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
|
||||||
DBGC ( device, "EFIDRV %s has driver \"%s\"\n",
|
DBGC ( device, "EFIDRV %s has driver \"%s\"\n",
|
||||||
efi_handle_name ( device ), efidrv->name );
|
efi_handle_name ( device ), efidrv->name );
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBGCP ( device, "EFIDRV %s has no driver\n",
|
DBGCP ( device, "EFIDRV %s has no driver\n",
|
||||||
efi_handle_name ( device ) );
|
efi_handle_name ( device ) );
|
||||||
|
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +152,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
} path;
|
} path;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
||||||
size_t path_len;
|
size_t path_len;
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -162,6 +170,9 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
goto err_already_started;
|
goto err_already_started;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Do nothing if we are currently disconnecting drivers */
|
/* Do nothing if we are currently disconnecting drivers */
|
||||||
if ( efi_driver_disconnecting ) {
|
if ( efi_driver_disconnecting ) {
|
||||||
DBGC ( device, "EFIDRV %s refusing to start during "
|
DBGC ( device, "EFIDRV %s refusing to start during "
|
||||||
|
@ -215,6 +226,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
DBGC ( device, "EFIDRV %s using driver \"%s\"\n",
|
DBGC ( device, "EFIDRV %s using driver \"%s\"\n",
|
||||||
efi_handle_name ( device ),
|
efi_handle_name ( device ),
|
||||||
efidev->driver->name );
|
efidev->driver->name );
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
|
DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
|
||||||
|
@ -232,6 +244,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
}
|
}
|
||||||
err_open_path:
|
err_open_path:
|
||||||
err_disconnecting:
|
err_disconnecting:
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
err_already_started:
|
err_already_started:
|
||||||
return efirc;
|
return efirc;
|
||||||
}
|
}
|
||||||
|
@ -250,8 +263,10 @@ static EFI_STATUS EFIAPI
|
||||||
efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
EFI_HANDLE device, UINTN num_children,
|
EFI_HANDLE device, UINTN num_children,
|
||||||
EFI_HANDLE *children ) {
|
EFI_HANDLE *children ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_driver *efidrv;
|
struct efi_driver *efidrv;
|
||||||
struct efi_device *efidev;
|
struct efi_device *efidev;
|
||||||
|
EFI_TPL saved_tpl;
|
||||||
UINTN i;
|
UINTN i;
|
||||||
|
|
||||||
DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
|
DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
|
||||||
|
@ -269,6 +284,9 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Raise TPL */
|
||||||
|
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
|
||||||
|
|
||||||
/* Stop this device */
|
/* Stop this device */
|
||||||
efidrv = efidev->driver;
|
efidrv = efidev->driver;
|
||||||
assert ( efidrv != NULL );
|
assert ( efidrv != NULL );
|
||||||
|
@ -276,6 +294,7 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
list_del ( &efidev->dev.siblings );
|
list_del ( &efidev->dev.siblings );
|
||||||
free ( efidev );
|
free ( efidev );
|
||||||
|
|
||||||
|
bs->RestoreTPL ( saved_tpl );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue