aboutsummaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-06-22 15:09:48 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-06-22 15:09:48 +0100
commite18a639164e162b3a4f078ab60606cd2f163d934 (patch)
tree07fdd8337a34402b78c4c6368daca1d3534215e8 /hw/usb
parent469819a3e8e3ce4c8ec352fe23ad2509d0653d5c (diff)
parent896b6757f9c4d176ce4439238efea223a2952411 (diff)
downloadqemu-e18a639164e162b3a4f078ab60606cd2f163d934.zip
qemu-e18a639164e162b3a4f078ab60606cd2f163d934.tar.gz
qemu-e18a639164e162b3a4f078ab60606cd2f163d934.tar.bz2
Merge remote-tracking branch 'remotes/kraxel/tags/usb-20170621-pull-request' into staging
# gpg: Signature made Wed 21 Jun 2017 16:43:14 BST # gpg: using RSA key 0x4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/usb-20170621-pull-request: usb-host: support devices with sparse/non-sequential USB interfaces Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/host-libusb.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index f9c8eaf..1b0be07 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1107,7 +1107,7 @@ static void usb_host_detach_kernel(USBHostDevice *s)
if (rc != 0) {
return;
}
- for (i = 0; i < conf->bNumInterfaces; i++) {
+ for (i = 0; i < USB_MAX_INTERFACES; i++) {
rc = libusb_kernel_driver_active(s->dh, i);
usb_host_libusb_error("libusb_kernel_driver_active", rc);
if (rc != 1) {
@@ -1130,7 +1130,7 @@ static void usb_host_attach_kernel(USBHostDevice *s)
if (rc != 0) {
return;
}
- for (i = 0; i < conf->bNumInterfaces; i++) {
+ for (i = 0; i < USB_MAX_INTERFACES; i++) {
if (!s->ifs[i].detached) {
continue;
}
@@ -1145,7 +1145,7 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
{
USBDevice *udev = USB_DEVICE(s);
struct libusb_config_descriptor *conf;
- int rc, i;
+ int rc, i, claimed;
for (i = 0; i < USB_MAX_INTERFACES; i++) {
udev->altsetting[i] = 0;
@@ -1164,14 +1164,19 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
return USB_RET_STALL;
}
- for (i = 0; i < conf->bNumInterfaces; i++) {
+ claimed = 0;
+ for (i = 0; i < USB_MAX_INTERFACES; i++) {
trace_usb_host_claim_interface(s->bus_num, s->addr, configuration, i);
rc = libusb_claim_interface(s->dh, i);
- usb_host_libusb_error("libusb_claim_interface", rc);
- if (rc != 0) {
- return USB_RET_STALL;
+ if (rc == 0) {
+ s->ifs[i].claimed = true;
+ if (++claimed == conf->bNumInterfaces) {
+ break;
+ }
}
- s->ifs[i].claimed = true;
+ }
+ if (claimed != conf->bNumInterfaces) {
+ return USB_RET_STALL;
}
udev->ninterfaces = conf->bNumInterfaces;
@@ -1183,10 +1188,9 @@ static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)
static void usb_host_release_interfaces(USBHostDevice *s)
{
- USBDevice *udev = USB_DEVICE(s);
int i, rc;
- for (i = 0; i < udev->ninterfaces; i++) {
+ for (i = 0; i < USB_MAX_INTERFACES; i++) {
if (!s->ifs[i].claimed) {
continue;
}