Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[efi] Raise TPL within EFI_USB_IO_PROTOCOL entry points
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Feb 20, 2018
1 parent a272b7c commit f672a27
Showing 1 changed file with 41 additions and 6 deletions.
47 changes: 41 additions & 6 deletions src/interface/efi/efi_usb.c
Expand Up @@ -505,13 +505,15 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
EFI_USB_DATA_DIRECTION direction,
UINT32 timeout, VOID *data, UINTN len,
UINT32 *status ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
unsigned int request = ( packet->RequestType |
USB_REQUEST_TYPE ( packet->Request ) );
unsigned int value = le16_to_cpu ( packet->Value );
unsigned int index = le16_to_cpu ( packet->Index );
EFI_TPL saved_tpl;
int rc;

DBGC2 ( usbdev, "USBDEV %s control %04x:%04x:%04x:%04x %s %dms "
Expand All @@ -520,6 +522,9 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
efi_usb_direction_name ( direction ), timeout, data,
( ( size_t ) len ) );

/* Raise TPL */
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );

/* Clear status */
*status = 0;

Expand Down Expand Up @@ -563,6 +568,7 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,

err_control:
err_change_config:
bs->RestoreTPL ( saved_tpl );
return EFIRC ( rc );
}

Expand All @@ -580,16 +586,21 @@ efi_usb_control_transfer ( EFI_USB_IO_PROTOCOL *usbio,
static EFI_STATUS EFIAPI
efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
UINTN *len, UINTN timeout, UINT32 *status ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
size_t actual = *len;
EFI_TPL saved_tpl;
int rc;

DBGC2 ( usbdev, "USBDEV %s bulk %s %p+%zx %dms\n", usbintf->name,
( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
( ( size_t ) *len ), ( ( unsigned int ) timeout ) );

/* Raise TPL */
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );

/* Clear status */
*status = 0;

Expand All @@ -599,10 +610,12 @@ efi_usb_bulk_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint, VOID *data,
data, &actual ) ) != 0 ) {
/* Assume that any error represents a timeout */
*status = EFI_USB_ERR_TIMEOUT;
return rc;
goto err_transfer;
}

return 0;
err_transfer:
bs->RestoreTPL ( saved_tpl );
return EFIRC ( rc );
}

/**
Expand All @@ -620,16 +633,21 @@ static EFI_STATUS EFIAPI
efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
VOID *data, UINTN *len, UINTN timeout,
UINT32 *status ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
size_t actual = *len;
EFI_TPL saved_tpl;
int rc;

DBGC2 ( usbdev, "USBDEV %s sync intr %s %p+%zx %dms\n", usbintf->name,
( ( endpoint & USB_ENDPOINT_IN ) ? "IN" : "OUT" ), data,
( ( size_t ) *len ), ( ( unsigned int ) timeout ) );

/* Raise TPL */
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );

/* Clear status */
*status = 0;

Expand All @@ -639,10 +657,12 @@ efi_usb_sync_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
timeout, data, &actual ) ) != 0 ) {
/* Assume that any error represents a timeout */
*status = EFI_USB_ERR_TIMEOUT;
return rc;
goto err_transfer;
}

return 0;
err_transfer:
bs->RestoreTPL ( saved_tpl );
return EFIRC ( rc );
}

/**
Expand All @@ -662,9 +682,11 @@ efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
BOOLEAN start, UINTN interval, UINTN len,
EFI_ASYNC_USB_TRANSFER_CALLBACK callback,
VOID *context ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_usb_interface *usbintf =
container_of ( usbio, struct efi_usb_interface, usbio );
struct efi_usb_device *usbdev = usbintf->usbdev;
EFI_TPL saved_tpl;
int rc;

DBGC2 ( usbdev, "USBDEV %s async intr %s len %#zx int %d %p/%p\n",
Expand All @@ -673,6 +695,9 @@ efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
( ( size_t ) len ), ( ( unsigned int ) interval ),
callback, context );

/* Raise TPL */
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );

/* Start/stop transfer as applicable */
if ( start ) {

Expand All @@ -687,11 +712,13 @@ efi_usb_async_interrupt_transfer ( EFI_USB_IO_PROTOCOL *usbio, UINT8 endpoint,
/* Stop transfer */
efi_usb_async_stop ( usbintf, endpoint );

}
/* Success */
rc = 0;

return 0;
}

err_start:
bs->RestoreTPL ( saved_tpl );
return EFIRC ( rc );
}

Expand Down Expand Up @@ -889,12 +916,16 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
struct usb_descriptor_header header;
VOID *buffer;
size_t len;
EFI_TPL saved_tpl;
EFI_STATUS efirc;
int rc;

DBGC2 ( usbdev, "USBDEV %s get string %d:%d descriptor\n",
usbintf->name, language, index );

/* Raise TPL */
saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );

/* Read descriptor header */
if ( ( rc = usb_get_descriptor ( usbdev->usb, 0, USB_STRING_DESCRIPTOR,
index, language, &header,
Expand Down Expand Up @@ -928,6 +959,9 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
( len - sizeof ( header ) ) );
memset ( ( buffer + len - sizeof ( header ) ), 0, sizeof ( **string ) );

/* Restore TPL */
bs->RestoreTPL ( saved_tpl );

/* Return allocated string */
*string = buffer;
return 0;
Expand All @@ -936,6 +970,7 @@ efi_usb_get_string_descriptor ( EFI_USB_IO_PROTOCOL *usbio, UINT16 language,
bs->FreePool ( buffer );
err_alloc:
err_get_header:
bs->RestoreTPL ( saved_tpl );
return EFIRC ( rc );
}

Expand Down

0 comments on commit f672a27

Please sign in to comment.