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:
parent
0b862cedf3
commit
41c01ee715
27
usb-linux.c
27
usb-linux.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user