mirror of https://github.com/xemu-project/xemu.git
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);
|
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)
|
static void async_complete(void *opaque)
|
||||||
{
|
{
|
||||||
USBHostDevice *s = opaque;
|
USBHostDevice *s = opaque;
|
||||||
|
@ -281,10 +289,7 @@ static void async_complete(void *opaque)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (errno == ENODEV && !s->closing) {
|
if (errno == ENODEV && !s->closing) {
|
||||||
printf("husb: device %d.%d disconnected\n",
|
do_disconnect(s);
|
||||||
s->bus_num, s->addr);
|
|
||||||
usb_host_close(s);
|
|
||||||
usb_host_auto_check(NULL);
|
|
||||||
return;
|
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)
|
static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
{
|
{
|
||||||
|
const char *op = NULL;
|
||||||
int dev_descr_len, config_descr_len;
|
int dev_descr_len, config_descr_len;
|
||||||
int interface, nb_interfaces;
|
int interface, nb_interfaces;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
@ -410,9 +416,9 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
ctrl.ioctl_code = USBDEVFS_DISCONNECT;
|
ctrl.ioctl_code = USBDEVFS_DISCONNECT;
|
||||||
ctrl.ifno = interface;
|
ctrl.ifno = interface;
|
||||||
ctrl.data = 0;
|
ctrl.data = 0;
|
||||||
|
op = "USBDEVFS_DISCONNECT";
|
||||||
ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
|
ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
|
||||||
if (ret < 0 && errno != ENODATA) {
|
if (ret < 0 && errno != ENODATA) {
|
||||||
perror("USBDEVFS_DISCONNECT");
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,6 +427,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
|
|
||||||
/* XXX: only grab if all interfaces are free */
|
/* XXX: only grab if all interfaces are free */
|
||||||
for (interface = 0; interface < nb_interfaces; interface++) {
|
for (interface = 0; interface < nb_interfaces; interface++) {
|
||||||
|
op = "USBDEVFS_CLAIMINTERFACE";
|
||||||
ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
|
ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno == EBUSY) {
|
if (errno == EBUSY) {
|
||||||
|
@ -428,8 +435,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
} else {
|
} else {
|
||||||
perror("husb: failed to claim interface");
|
perror("husb: failed to claim interface");
|
||||||
}
|
}
|
||||||
fail:
|
goto fail;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,6 +445,13 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
|
||||||
dev->ninterfaces = nb_interfaces;
|
dev->ninterfaces = nb_interfaces;
|
||||||
dev->configuration = configuration;
|
dev->configuration = configuration;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (errno == ENODEV) {
|
||||||
|
do_disconnect(dev);
|
||||||
|
}
|
||||||
|
perror(op);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_host_release_interfaces(USBHostDevice *s)
|
static int usb_host_release_interfaces(USBHostDevice *s)
|
||||||
|
|
Loading…
Reference in New Issue