qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] usbredir: Do not detach usb if backend chardev disconnect


From: minglei.liu
Subject: [PATCH] usbredir: Do not detach usb if backend chardev disconnect
Date: Wed, 9 Nov 2022 19:56:19 +0800

If the network between qemu and usbredirserver is temporarily disconnected,
the USB device in the VM will be unplugged. If the reconnect parameter is
configured for the backend chardev, the device will be reconnected later.
But from the inside of the VM, this USB device has experienced unplug and
re-plug, if the USB storage device has been mounted in the VM before,
the drive letter will change after the device is re-plugged.

So in this case, we no longer unplug the device, and operations to the USB
is returned immediately at this point.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1305
Signed-off-by: minglei.liu <minglei.liu@smartx.com>
---
 hw/usb/redirect.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 1bd30efc3e..73731bcab5 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -379,6 +379,11 @@ static void usbredir_cancel_packet(USBDevice *udev, 
USBPacket *p)
     USBRedirDevice *dev = USB_REDIRECT(udev);
     int i = USBEP2I(p->ep);
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return;
+    }
+
     if (p->combined) {
         usb_combined_packet_cancel(udev, p);
         return;
@@ -519,6 +524,11 @@ static void usbredir_handle_reset(USBDevice *udev)
 {
     USBRedirDevice *dev = USB_REDIRECT(udev);
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return;
+    }
+
     DPRINTF("reset device\n");
     usbredirparser_send_reset(dev->parser);
     usbredirparser_do_write(dev->parser);
@@ -959,6 +969,11 @@ static void usbredir_handle_data(USBDevice *udev, 
USBPacket *p)
     USBRedirDevice *dev = USB_REDIRECT(udev);
     uint8_t ep;
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return;
+    }
+
     ep = p->ep->nr;
     if (p->pid == USB_TOKEN_IN) {
         ep |= USB_DIR_IN;
@@ -1027,6 +1042,11 @@ static void usbredir_ep_stopped(USBDevice *udev, 
USBEndpoint *uep)
 {
     USBRedirDevice *dev = USB_REDIRECT(udev);
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return;
+    }
+
     usbredir_stop_ep(dev, USBEP2I(uep));
     usbredirparser_do_write(dev->parser);
 }
@@ -1098,6 +1118,11 @@ static void usbredir_handle_control(USBDevice *udev, 
USBPacket *p,
     USBRedirDevice *dev = USB_REDIRECT(udev);
     struct usb_redir_control_packet_header control_packet;
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return;
+    }
+
     if (usbredir_already_in_flight(dev, p->id)) {
         p->status = USB_RET_ASYNC;
         return;
@@ -1155,6 +1180,11 @@ static int usbredir_alloc_streams(USBDevice *udev, 
USBEndpoint **eps,
     struct usb_redir_alloc_bulk_streams_header alloc_streams;
     int i;
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return -1;
+    }
+
     if (!usbredirparser_peer_has_cap(dev->parser,
                                      usb_redir_cap_bulk_streams)) {
         ERROR("peer does not support streams\n");
@@ -1193,6 +1223,11 @@ static void usbredir_free_streams(USBDevice *udev, 
USBEndpoint **eps,
     struct usb_redir_free_bulk_streams_header free_streams;
     int i;
 
+    if(!dev->parser) {
+        ERROR("usbredir parser is not available, need reconnect.\n");
+        return;
+    }
+
     if (!usbredirparser_peer_has_cap(dev->parser,
                                      usb_redir_cap_bulk_streams)) {
         return;
@@ -1219,8 +1254,6 @@ static void usbredir_chardev_close_bh(void *opaque)
     USBRedirDevice *dev = opaque;
 
     qemu_bh_cancel(dev->device_reject_bh);
-    usbredir_device_disconnect(dev);
-
     if (dev->parser) {
         DPRINTF("destroying usbredirparser\n");
         usbredirparser_destroy(dev->parser);
-- 
2.27.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]