diff options
Diffstat (limited to 'src/drivers/usb/usbio.c')
| -rw-r--r-- | src/drivers/usb/usbio.c | 148 |
1 files changed, 48 insertions, 100 deletions
diff --git a/src/drivers/usb/usbio.c b/src/drivers/usb/usbio.c index 278b43cd3..97860a281 100644 --- a/src/drivers/usb/usbio.c +++ b/src/drivers/usb/usbio.c @@ -187,10 +187,6 @@ static int usbio_open ( struct usbio_device *usbio, unsigned int interface ) { EFI_DEVICE_PATH_PROTOCOL *path; EFI_DEVICE_PATH_PROTOCOL *end; USB_DEVICE_PATH *usbpath; - union { - void *interface; - EFI_USB_IO_PROTOCOL *io; - } u; EFI_STATUS efirc; int rc; @@ -229,13 +225,9 @@ static int usbio_open ( struct usbio_device *usbio, unsigned int interface ) { } /* Open USB I/O protocol on this handle */ - if ( ( efirc = bs->OpenProtocol ( intf->handle, - &efi_usb_io_protocol_guid, - &u.interface, efi_image_handle, - intf->handle, - ( EFI_OPEN_PROTOCOL_BY_DRIVER | - EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){ - rc = -EEFI ( efirc ); + if ( ( rc = efi_open_by_driver ( intf->handle, + &efi_usb_io_protocol_guid, + &intf->io ) ) != 0 ) { DBGC ( usbio, "USBIO %s cannot open ", efi_handle_name ( handle ) ); DBGC ( usbio, "%s: %s\n", @@ -244,7 +236,6 @@ static int usbio_open ( struct usbio_device *usbio, unsigned int interface ) { &efi_usb_io_protocol_guid ); return rc; } - intf->io = u.io; /* Increment usage count */ intf->count++; @@ -259,7 +250,6 @@ static int usbio_open ( struct usbio_device *usbio, unsigned int interface ) { * @v interface Interface number */ static void usbio_close ( struct usbio_device *usbio, unsigned int interface ) { - EFI_BOOT_SERVICES *bs = efi_systab->BootServices; struct usbio_interface *intf = &usbio->interface[interface]; /* Sanity checks */ @@ -274,8 +264,7 @@ static void usbio_close ( struct usbio_device *usbio, unsigned int interface ) { return; /* Close USB I/O protocol */ - bs->CloseProtocol ( intf->handle, &efi_usb_io_protocol_guid, - efi_image_handle, intf->handle ); + efi_close_by_driver ( intf->handle, &efi_usb_io_protocol_guid ); } /****************************************************************************** @@ -1297,49 +1286,40 @@ static struct usb_host_operations usbio_operations = { * @ret rc Return status code */ static int usbio_supported ( EFI_HANDLE handle ) { - EFI_BOOT_SERVICES *bs = efi_systab->BootServices; EFI_USB_DEVICE_DESCRIPTOR device; EFI_USB_INTERFACE_DESCRIPTOR interface; struct usb_function_descriptor desc; struct usb_driver *driver; struct usb_device_id *id; - union { - void *interface; - EFI_USB_IO_PROTOCOL *io; - } usb; + EFI_USB_IO_PROTOCOL *io; EFI_STATUS efirc; int rc; /* Get protocol */ - if ( ( efirc = bs->OpenProtocol ( handle, &efi_usb_io_protocol_guid, - &usb.interface, efi_image_handle, - handle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){ - rc = -EEFI ( efirc ); + if ( ( rc = efi_open ( handle, &efi_usb_io_protocol_guid, + &io ) ) != 0 ) { DBGCP ( handle, "USB %s is not a USB device\n", efi_handle_name ( handle ) ); - goto err_open_protocol; + return rc; } /* Get device descriptor */ - if ( ( efirc = usb.io->UsbGetDeviceDescriptor ( usb.io, - &device ) ) != 0 ) { + if ( ( efirc = io->UsbGetDeviceDescriptor ( io, &device ) ) != 0 ) { rc = -EEFI ( efirc ); DBGC ( handle, "USB %s could not get device descriptor: " "%s\n", efi_handle_name ( handle ), strerror ( rc ) ); - goto err_get_device_descriptor; + return rc; } memset ( &desc, 0, sizeof ( desc ) ); desc.vendor = device.IdVendor; desc.product = device.IdProduct; /* Get interface descriptor */ - if ( ( efirc = usb.io->UsbGetInterfaceDescriptor ( usb.io, - &interface ) ) !=0){ + if ( ( efirc = io->UsbGetInterfaceDescriptor ( io, &interface ) ) != 0){ rc = -EEFI ( efirc ); DBGC ( handle, "USB %s could not get interface descriptor: " "%s\n", efi_handle_name ( handle ), strerror ( rc ) ); - goto err_get_interface_descriptor; + return rc; } desc.class.class.class = interface.InterfaceClass; desc.class.class.subclass = interface.InterfaceSubClass; @@ -1347,21 +1327,10 @@ static int usbio_supported ( EFI_HANDLE handle ) { /* Look for a driver for this interface */ driver = usb_find_driver ( &desc, &id ); - if ( ! driver ) { - rc = -ENOTSUP; - goto err_unsupported; - } - - /* Success */ - rc = 0; + if ( ! driver ) + return -ENOTSUP; - err_unsupported: - err_get_interface_descriptor: - err_get_device_descriptor: - bs->CloseProtocol ( handle, &efi_usb_io_protocol_guid, - efi_image_handle, handle ); - err_open_protocol: - return rc; + return 0; } /** @@ -1477,39 +1446,27 @@ static int usbio_config ( struct usbio_device *usbio ) { * @ret rc Return status code */ static int usbio_path ( struct usbio_device *usbio ) { - EFI_BOOT_SERVICES *bs = efi_systab->BootServices; EFI_HANDLE handle = usbio->handle; EFI_DEVICE_PATH_PROTOCOL *path; EFI_DEVICE_PATH_PROTOCOL *end; USB_DEVICE_PATH *usbpath; - union { - void *interface; - EFI_DEVICE_PATH_PROTOCOL *path; - } u; size_t len; - EFI_STATUS efirc; int rc; /* Open device path protocol */ - if ( ( efirc = bs->OpenProtocol ( handle, - &efi_device_path_protocol_guid, - &u.interface, efi_image_handle, - handle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){ - rc = -EEFI ( efirc ); + if ( ( rc = efi_open ( handle, &efi_device_path_protocol_guid, + &path ) ) != 0 ) { DBGC ( usbio, "USBIO %s cannot open device path protocol: " "%s\n", efi_handle_name ( handle ), strerror ( rc ) ); - goto err_open_protocol; + return rc; } - path = u.interface; /* Locate end of device path and sanity check */ len = efi_path_len ( path ); if ( len < sizeof ( *usbpath ) ) { DBGC ( usbio, "USBIO %s underlength device path\n", efi_handle_name ( handle ) ); - rc = -EINVAL; - goto err_underlength; + return -EINVAL; } usbpath = ( ( ( void * ) path ) + len - sizeof ( *usbpath ) ); if ( ! ( ( usbpath->Header.Type == MESSAGING_DEVICE_PATH ) && @@ -1517,34 +1474,18 @@ static int usbio_path ( struct usbio_device *usbio ) { DBGC ( usbio, "USBIO %s not a USB device path: ", efi_handle_name ( handle ) ); DBGC ( usbio, "%s\n", efi_devpath_text ( path ) ); - rc = -EINVAL; - goto err_non_usb; + return -EINVAL; } /* Allocate copy of device path */ usbio->path = malloc ( len + sizeof ( *end ) ); - if ( ! usbio->path ) { - rc = -ENOMEM; - goto err_alloc; - } + if ( ! usbio->path ) + return -ENOMEM; memcpy ( usbio->path, path, ( len + sizeof ( *end ) ) ); usbio->usbpath = ( ( ( void * ) usbio->path ) + len - sizeof ( *usbpath ) ); - /* Close protocol */ - bs->CloseProtocol ( handle, &efi_device_path_protocol_guid, - efi_image_handle, handle ); - return 0; - - free ( usbio->path ); - err_alloc: - err_non_usb: - err_underlength: - bs->CloseProtocol ( handle, &efi_device_path_protocol_guid, - efi_image_handle, handle ); - err_open_protocol: - return rc; } /** @@ -1602,21 +1543,35 @@ static int usbio_interfaces ( struct usbio_device *usbio ) { } /** + * Exclude existing drivers + * + * @v device EFI device handle + * @ret rc Return status code + */ +static int usbio_exclude ( EFI_HANDLE device ) { + EFI_GUID *protocol = &efi_usb_io_protocol_guid; + int rc; + + /* Exclude existing USB I/O protocol drivers */ + if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) { + DBGC ( device, "USBIO %s could not exclude drivers: %s\n", + efi_handle_name ( device ), strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** * Attach driver to device * * @v efidev EFI device * @ret rc Return status code */ static int usbio_start ( struct efi_device *efidev ) { - EFI_BOOT_SERVICES *bs = efi_systab->BootServices; EFI_HANDLE handle = efidev->device; struct usbio_device *usbio; struct usb_port *port; - union { - void *interface; - EFI_USB_IO_PROTOCOL *io; - } u; - EFI_STATUS efirc; int rc; /* Allocate and initialise structure */ @@ -1630,18 +1585,13 @@ static int usbio_start ( struct efi_device *efidev ) { INIT_LIST_HEAD ( &usbio->endpoints ); /* Open USB I/O protocol */ - if ( ( efirc = bs->OpenProtocol ( handle, &efi_usb_io_protocol_guid, - &u.interface, efi_image_handle, - handle, - ( EFI_OPEN_PROTOCOL_BY_DRIVER | - EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){ - rc = -EEFI ( efirc ); + if ( ( rc = efi_open_by_driver ( handle, &efi_usb_io_protocol_guid, + &usbio->io ) ) != 0 ) { DBGC ( usbio, "USBIO %s cannot open USB I/O protocol: %s\n", efi_handle_name ( handle ), strerror ( rc ) ); DBGC_EFI_OPENERS ( usbio, handle, &efi_usb_io_protocol_guid ); goto err_open_usbio; } - usbio->io = u.io; /* Describe generic device */ efi_device_info ( handle, "USB", &usbio->dev ); @@ -1692,8 +1642,7 @@ static int usbio_start ( struct efi_device *efidev ) { free ( usbio->config ); err_config: list_del ( &usbio->dev.siblings ); - bs->CloseProtocol ( handle, &efi_usb_io_protocol_guid, - efi_image_handle, handle ); + efi_close_by_driver ( handle, &efi_usb_io_protocol_guid ); err_open_usbio: free ( usbio ); err_alloc: @@ -1706,7 +1655,6 @@ static int usbio_start ( struct efi_device *efidev ) { * @v efidev EFI device */ static void usbio_stop ( struct efi_device *efidev ) { - EFI_BOOT_SERVICES *bs = efi_systab->BootServices; EFI_HANDLE handle = efidev->device; struct usbio_device *usbio = efidev_get_drvdata ( efidev ); @@ -1716,15 +1664,15 @@ static void usbio_stop ( struct efi_device *efidev ) { free ( usbio->path ); free ( usbio->config ); list_del ( &usbio->dev.siblings ); - bs->CloseProtocol ( handle, &efi_usb_io_protocol_guid, - efi_image_handle, handle ); + efi_close_by_driver ( handle, &efi_usb_io_protocol_guid ); free ( usbio ); } /** EFI USB I/O driver */ -struct efi_driver usbio_driver __efi_driver ( EFI_DRIVER_NORMAL ) = { +struct efi_driver usbio_driver __efi_driver ( EFI_DRIVER_HARDWARE ) = { .name = "USBIO", .supported = usbio_supported, + .exclude = usbio_exclude, .start = usbio_start, .stop = usbio_stop, }; |
