summaryrefslogtreecommitdiff
path: root/usbredirhost/usbredirhost.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-01-23 23:25:05 +0100
committerHans de Goede <hdegoede@redhat.com>2012-01-23 23:25:05 +0100
commit7b7e8a814408a1a1ec95110447109a616e39eb19 (patch)
treed2ebd1611fd1fc677842b443284e0fdc9eb0beef /usbredirhost/usbredirhost.c
parent806ba66ad52e3ff18ec096fcc915b557a494e2b6 (diff)
usbredirhost: Don't attach drivers when releasing interfaces for set_config
When changing the active configuration we must first release all interfaces, this is done by the usbredirhost_release() helper function, but before this patch that function also re-attached the in kernel driver, making the interfaces busy again and causing the set_config call to fail. This patch fixes this by not doing the kernel driver re-attach when releasing the interfaces for a set_config call. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'usbredirhost/usbredirhost.c')
-rw-r--r--usbredirhost/usbredirhost.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/usbredirhost/usbredirhost.c b/usbredirhost/usbredirhost.c
index 88c3462..39c115f 100644
--- a/usbredirhost/usbredirhost.c
+++ b/usbredirhost/usbredirhost.c
@@ -330,7 +330,7 @@ static void usbredirhost_parse_config(struct usbredirhost *host)
}
/* Called from open/close and parser read callbacks */
-static int usbredirhost_claim(struct usbredirhost *host)
+static int usbredirhost_claim(struct usbredirhost *host, int detach_drivers)
{
int i, n, r, ret = usb_redir_success;
@@ -358,15 +358,17 @@ static int usbredirhost_claim(struct usbredirhost *host)
for (i = 0; i < host->config->bNumInterfaces; i++) {
n = host->config->interface[i].altsetting[0].bInterfaceNumber;
- r = libusb_detach_kernel_driver(host->handle, n);
- if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND) {
- ERROR("could not detach driver from interface %d (configuration %d): %d",
- n, host->active_config, r);
- ret = libusb_status_or_error_to_redir_status(host, r);
- goto error;
+ if (detach_drivers) {
+ r = libusb_detach_kernel_driver(host->handle, n);
+ if (r < 0 && r != LIBUSB_ERROR_NOT_FOUND) {
+ ERROR("could not detach driver from interface %d (configuration %d): %d",
+ n, host->active_config, r);
+ ret = libusb_status_or_error_to_redir_status(host, r);
+ goto error;
+ }
+ /* Note indexed by i not n !! (too ensure we don't go out of bound) */
+ host->driver_detached[i] = (r != LIBUSB_ERROR_NOT_FOUND);
}
- /* Note indexed by i not n !! (too ensure we don't go out of bound) */
- host->driver_detached[i] = (r != LIBUSB_ERROR_NOT_FOUND);
r = libusb_claim_interface(host->handle, n);
if (r < 0) {
@@ -388,7 +390,7 @@ error:
/* This is a nop on non claimed interfaces */
libusb_release_interface(host->handle, n);
- if (host->driver_detached[i]) {
+ if (detach_drivers && host->driver_detached[i]) {
r = libusb_attach_kernel_driver(host->handle, n);
if (r == 0) {
host->driver_detached[i] = 0;
@@ -399,7 +401,7 @@ error:
}
/* Called from open/close and parser read callbacks */
-static int usbredirhost_release(struct usbredirhost *host)
+static int usbredirhost_release(struct usbredirhost *host, int attach_drivers)
{
int i, n, r, ret = usb_redir_success;
@@ -419,6 +421,10 @@ static int usbredirhost_release(struct usbredirhost *host)
}
}
+ if (!attach_drivers) {
+ goto exit;
+ }
+
for (i = 0; i < host->config->bNumInterfaces; i++) {
n = host->config->interface[i].altsetting[0].bInterfaceNumber;
@@ -437,6 +443,7 @@ static int usbredirhost_release(struct usbredirhost *host)
}
}
+exit:
host->claimed = 0;
return ret;
}
@@ -554,7 +561,7 @@ struct usbredirhost *usbredirhost_open_full(
return NULL;
}
- if (usbredirhost_claim(host) != usb_redir_success) {
+ if (usbredirhost_claim(host, 1) != usb_redir_success) {
usbredirhost_close(host);
return NULL;
}
@@ -603,7 +610,7 @@ void usbredirhost_close(struct usbredirhost *host)
}
if (host->claimed && !host->disconnected) {
- usbredirhost_release(host);
+ usbredirhost_release(host, 1);
}
if (host->config) {
libusb_free_config_descriptor(host->config);
@@ -1342,7 +1349,7 @@ static void usbredirhost_set_configuration(void *priv, uint32_t id,
}
usbredirhost_cancel_pending_urbs(host);
- status.status = usbredirhost_release(host);
+ status.status = usbredirhost_release(host, 0);
if (status.status != usb_redir_success) {
goto exit;
}
@@ -1356,7 +1363,7 @@ static void usbredirhost_set_configuration(void *priv, uint32_t id,
}
host->active_config = set_config->configuration;
- status.status = usbredirhost_claim(host);
+ status.status = usbredirhost_claim(host, 0);
exit:
status.configuration = host->active_config;