usb-linux: catch ENODEV in more places.

Factor out disconnect code (called when a device disappears) to a
separate function.  Add a check for ENODEV errno to a few more places
to make sure we notice disconnects.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Gerd Hoffmann 2011-05-24 16:12:31 +02:00
parent 0b862cedf3
commit 41c01ee715

View file

@ -267,6 +267,14 @@ static void async_free(AsyncURB *aurb)
qemu_free(aurb);
}
static void do_disconnect(USBHostDevice *s)
{
printf("husb: device %d.%d disconnected\n",
s->bus_num, s->addr);
usb_host_close(s);
usb_host_auto_check(NULL);
}
static void async_complete(void *opaque)
{
USBHostDevice *s = opaque;
@ -281,10 +289,7 @@ static void async_complete(void *opaque)
return;
}
if (errno == ENODEV && !s->closing) {
printf("husb: device %d.%d disconnected\n",
s->bus_num, s->addr);
usb_host_close(s);
usb_host_auto_check(NULL);
do_disconnect(s);
return;
}
@ -358,6 +363,7 @@ static void usb_host_async_cancel(USBDevice *dev, USBPacket *p)
static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
{
const char *op = NULL;
int dev_descr_len, config_descr_len;
int interface, nb_interfaces;
int ret, i;
@ -410,9 +416,9 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
ctrl.ioctl_code = USBDEVFS_DISCONNECT;
ctrl.ifno = interface;
ctrl.data = 0;
op = "USBDEVFS_DISCONNECT";
ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
if (ret < 0 && errno != ENODATA) {
perror("USBDEVFS_DISCONNECT");
goto fail;
}
}
@ -421,6 +427,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
/* XXX: only grab if all interfaces are free */
for (interface = 0; interface < nb_interfaces; interface++) {
op = "USBDEVFS_CLAIMINTERFACE";
ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
if (ret < 0) {
if (errno == EBUSY) {
@ -428,8 +435,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
} else {
perror("husb: failed to claim interface");
}
fail:
return 0;
goto fail;
}
}
@ -439,6 +445,13 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
dev->ninterfaces = nb_interfaces;
dev->configuration = configuration;
return 1;
fail:
if (errno == ENODEV) {
do_disconnect(dev);
}
perror(op);
return 0;
}
static int usb_host_release_interfaces(USBHostDevice *s)