X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=usb-redir.c;h=fb91c926a9e53d475b9b54edb19bcca0da19b57d;hb=refs%2Fheads%2Fstable-1.0;hp=9e5fce21eafbf6bb3bf1233727eeabc472eed1d5;hpb=b9c6cbff76061537b722d55f0e321dde2a612a23;p=qemu.git diff --git a/usb-redir.c b/usb-redir.c index 9e5fce21e..fb91c926a 100644 --- a/usb-redir.c +++ b/usb-redir.c @@ -225,7 +225,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count) { USBRedirDevice *dev = priv; - return qemu_chr_write(dev->cs, data, count); + if (!dev->cs->opened) { + return 0; + } + + return qemu_chr_fe_write(dev->cs, data, count); } /* @@ -234,7 +238,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count) static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p) { - AsyncURB *aurb = (AsyncURB *) qemu_mallocz(sizeof(AsyncURB)); + AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB)); aurb->dev = dev; aurb->packet = p; aurb->packet_id = dev->packet_id; @@ -247,7 +251,7 @@ static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p) static void async_free(USBRedirDevice *dev, AsyncURB *aurb) { QTAILQ_REMOVE(&dev->asyncq, aurb, next); - qemu_free(aurb); + g_free(aurb); } static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id) @@ -286,7 +290,7 @@ static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) static struct buf_packet *bufp_alloc(USBRedirDevice *dev, uint8_t *data, int len, int status, uint8_t ep) { - struct buf_packet *bufp = qemu_malloc(sizeof(struct buf_packet)); + struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet)); bufp->data = data; bufp->len = len; bufp->status = status; @@ -299,7 +303,7 @@ static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp, { QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next); free(bufp->data); - qemu_free(bufp); + g_free(bufp); } static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep) @@ -814,6 +818,8 @@ static int usbredir_initfn(USBDevice *udev) /* We'll do the attach once we receive the speed from the usb-host */ udev->auto_attach = 0; + /* Let the backend know we are ready */ + qemu_chr_fe_open(dev->cs); qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, usbredir_chardev_read, usbredir_chardev_event, dev); @@ -837,7 +843,8 @@ static void usbredir_handle_destroy(USBDevice *udev) { USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); - qemu_chr_close(dev->cs); + qemu_chr_fe_close(dev->cs); + qemu_chr_delete(dev->cs); /* Note must be done after qemu_chr_close, as that causes a close event */ qemu_bh_delete(dev->open_close_bh); @@ -878,6 +885,11 @@ static void usbredir_device_connect(void *priv, { USBRedirDevice *dev = priv; + if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) { + ERROR("Received device connect while already connected\n"); + return; + } + switch (device_connect->speed) { case usb_redir_speed_low: DPRINTF("attaching low speed device\n"); @@ -906,19 +918,26 @@ static void usbredir_device_connect(void *priv, static void usbredir_device_disconnect(void *priv) { USBRedirDevice *dev = priv; + int i; /* Stop any pending attaches */ qemu_del_timer(dev->attach_timer); if (dev->dev.attached) { usb_device_detach(&dev->dev); - usbredir_cleanup_device_queues(dev); /* * Delay next usb device attach to give the guest a chance to see * see the detach / attach in case of quick close / open succession */ dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200; } + + /* Reset state so that the next dev connected starts with a clean slate */ + usbredir_cleanup_device_queues(dev); + memset(dev->endpoint, 0, sizeof(dev->endpoint)); + for (i = 0; i < MAX_ENDPOINTS; i++) { + QTAILQ_INIT(&dev->endpoint[i].bufpq); + } } static void usbredir_interface_info(void *priv, @@ -1010,6 +1029,10 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id, DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status, ep, id); + if (!dev->dev.attached) { + return; + } + dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status; if (iso_stream_status->status == usb_redir_stall) { DPRINTF("iso stream stopped by peer ep %02X\n", ep); @@ -1027,6 +1050,10 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, DPRINTF("interrupt recv status %d ep %02X id %u\n", interrupt_receiving_status->status, ep, id); + if (!dev->dev.attached) { + return; + } + dev->endpoint[EP2I(ep)].interrupt_error = interrupt_receiving_status->status; if (interrupt_receiving_status->status == usb_redir_stall) {