[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/6] usb-host: handle USBDEVFS_SETCONFIGURATION retu
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 5/6] usb-host: handle USBDEVFS_SETCONFIGURATION returning EBUSY |
Date: |
Thu, 15 Sep 2011 13:18:01 +0200 |
In case the host uses the usb device usbfs will refuse to set the
configuration due to the device being busy. Handle this case by
disconnection the interfaces, then trying again.
Signed-off-by: Gerd Hoffmann <address@hidden>
---
usb-linux.c | 36 +++++++++++++++++++++++++++++++++++-
1 files changed, 35 insertions(+), 1 deletions(-)
diff --git a/usb-linux.c b/usb-linux.c
index ff1a29c..7d4d1d7 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -485,6 +485,26 @@ static int usb_host_disconnect_ifaces(USBHostDevice *dev,
int nb_interfaces)
return 0;
}
+static int usb_linux_get_num_interfaces(USBHostDevice *s)
+{
+ char device_name[64], line[1024];
+ int num_interfaces = 0;
+
+ if (usb_fs_type != USB_FS_SYS) {
+ return -1;
+ }
+
+ sprintf(device_name, "%d-%s", s->bus_num, s->port);
+ if (!usb_host_read_file(line, sizeof(line), "bNumInterfaces",
+ device_name)) {
+ return -1;
+ }
+ if (sscanf(line, "%d", &num_interfaces) != 1) {
+ return -1;
+ }
+ return num_interfaces;
+}
+
static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
{
const char *op = NULL;
@@ -901,14 +921,28 @@ static int usb_host_set_address(USBHostDevice *s, int
addr)
static int usb_host_set_config(USBHostDevice *s, int config)
{
+ int ret, first = 1;
+
trace_usb_host_set_config(s->bus_num, s->addr, config);
usb_host_release_interfaces(s);
- int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
+again:
+ ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
+ if (ret < 0 && errno == EBUSY && first) {
+ /* happens if usb device is in use by host drivers */
+ int count = usb_linux_get_num_interfaces(s);
+ if (count > 0) {
+ DPRINTF("husb: busy -> disconnecting %d interfaces\n", count);
+ usb_host_disconnect_ifaces(s, count);
+ first = 0;
+ goto again;
+ }
+ }
+
if (ret < 0) {
return ctrl_error();
}
--
1.7.1
- [Qemu-devel] [PATCH 0/6] usb patch queue, Gerd Hoffmann, 2011/09/15
- [Qemu-devel] [PATCH 1/6] usb-storage: fix NULL pointer dereference., Gerd Hoffmann, 2011/09/15
- [Qemu-devel] [PATCH 3/6] usb: fix port reset, Gerd Hoffmann, 2011/09/15
- [Qemu-devel] [PATCH 2/6] usb-hub: need to check dev->attached, Gerd Hoffmann, 2011/09/15
- [Qemu-devel] [PATCH 6/6] hw/usb-ohci: Fix OHCI_TD_T1 bit position definition, Gerd Hoffmann, 2011/09/15
- [Qemu-devel] [PATCH 5/6] usb-host: handle USBDEVFS_SETCONFIGURATION returning EBUSY,
Gerd Hoffmann <=
- [Qemu-devel] [PATCH 4/6] usb-host: factor out code, Gerd Hoffmann, 2011/09/15