Merge "Change requested in launchpad bug #1288352" into 5.0
[packages/centos6/qemu.git] / 0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
1 From b89a0cc1ec9dbe30cbe002f12d487a52950da166 Mon Sep 17 00:00:00 2001
2 From: Hans de Goede <hdegoede@redhat.com>
3 Date: Thu, 23 Aug 2012 16:37:19 +0200
4 Subject: [PATCH] usb-redir: Don't delay handling of open events to a bottom
5  half
6
7 There is no need for this, and doing so means that a backend trying to
8 write immediately after an open event will see qemu_chr_be_can_write
9 returning 0, which not all backends handle well as there is no wakeup
10 mechanism to detect when the frontend does become writable.
11
12 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
13 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
14 (cherry picked from commit ed9873bfbf145c084d039baab08c63b9d67e7bd3)
15
16 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
17 ---
18  hw/usb/redirect.c | 100 +++++++++++++++++++++++++++++-------------------------
19  1 file changed, 53 insertions(+), 47 deletions(-)
20
21 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
22 index 7f3719b..5cc3334 100644
23 --- a/hw/usb/redirect.c
24 +++ b/hw/usb/redirect.c
25 @@ -79,8 +79,8 @@ struct USBRedirDevice {
26      /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
27      const uint8_t *read_buf;
28      int read_buf_size;
29 -    /* For async handling of open/close */
30 -    QEMUBH *open_close_bh;
31 +    /* For async handling of close */
32 +    QEMUBH *chardev_close_bh;
33      /* To delay the usb attach in case of quick chardev close + open */
34      QEMUTimer *attach_timer;
35      int64_t next_attach_time;
36 @@ -784,18 +784,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
37   * from within the USBDevice data / control packet callbacks and doing a
38   * usb_detach from within these callbacks is not a good idea.
39   *
40 - * So we use a bh handler to take care of close events. We also handle
41 - * open events from this callback to make sure that a close directly followed
42 - * by an open gets handled in the right order.
43 + * So we use a bh handler to take care of close events.
44   */
45 -static void usbredir_open_close_bh(void *opaque)
46 +static void usbredir_chardev_close_bh(void *opaque)
47  {
48      USBRedirDevice *dev = opaque;
49 -    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
50 -    char version[32];
51 -
52 -    strcpy(version, "qemu usb-redir guest ");
53 -    pstrcat(version, sizeof(version), qemu_get_version());
54  
55      usbredir_device_disconnect(dev);
56  
57 @@ -803,36 +796,47 @@ static void usbredir_open_close_bh(void *opaque)
58          usbredirparser_destroy(dev->parser);
59          dev->parser = NULL;
60      }
61 +}
62  
63 -    if (dev->cs->opened) {
64 -        dev->parser = qemu_oom_check(usbredirparser_create());
65 -        dev->parser->priv = dev;
66 -        dev->parser->log_func = usbredir_log;
67 -        dev->parser->read_func = usbredir_read;
68 -        dev->parser->write_func = usbredir_write;
69 -        dev->parser->hello_func = usbredir_hello;
70 -        dev->parser->device_connect_func = usbredir_device_connect;
71 -        dev->parser->device_disconnect_func = usbredir_device_disconnect;
72 -        dev->parser->interface_info_func = usbredir_interface_info;
73 -        dev->parser->ep_info_func = usbredir_ep_info;
74 -        dev->parser->configuration_status_func = usbredir_configuration_status;
75 -        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
76 -        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
77 -        dev->parser->interrupt_receiving_status_func =
78 -            usbredir_interrupt_receiving_status;
79 -        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
80 -        dev->parser->control_packet_func = usbredir_control_packet;
81 -        dev->parser->bulk_packet_func = usbredir_bulk_packet;
82 -        dev->parser->iso_packet_func = usbredir_iso_packet;
83 -        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
84 -        dev->read_buf = NULL;
85 -        dev->read_buf_size = 0;
86 +static void usbredir_chardev_open(USBRedirDevice *dev)
87 +{
88 +    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
89 +    char version[32];
90  
91 -        usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
92 -        usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
93 -        usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
94 -        usbredirparser_do_write(dev->parser);
95 -    }
96 +    /* Make sure any pending closes are handled (no-op if none pending) */
97 +    usbredir_chardev_close_bh(dev);
98 +    qemu_bh_cancel(dev->chardev_close_bh);
99 +
100 +    strcpy(version, "qemu usb-redir guest ");
101 +    pstrcat(version, sizeof(version), qemu_get_version());
102 +
103 +    dev->parser = qemu_oom_check(usbredirparser_create());
104 +    dev->parser->priv = dev;
105 +    dev->parser->log_func = usbredir_log;
106 +    dev->parser->read_func = usbredir_read;
107 +    dev->parser->write_func = usbredir_write;
108 +    dev->parser->hello_func = usbredir_hello;
109 +    dev->parser->device_connect_func = usbredir_device_connect;
110 +    dev->parser->device_disconnect_func = usbredir_device_disconnect;
111 +    dev->parser->interface_info_func = usbredir_interface_info;
112 +    dev->parser->ep_info_func = usbredir_ep_info;
113 +    dev->parser->configuration_status_func = usbredir_configuration_status;
114 +    dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
115 +    dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
116 +    dev->parser->interrupt_receiving_status_func =
117 +        usbredir_interrupt_receiving_status;
118 +    dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
119 +    dev->parser->control_packet_func = usbredir_control_packet;
120 +    dev->parser->bulk_packet_func = usbredir_bulk_packet;
121 +    dev->parser->iso_packet_func = usbredir_iso_packet;
122 +    dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
123 +    dev->read_buf = NULL;
124 +    dev->read_buf_size = 0;
125 +
126 +    usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
127 +    usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
128 +    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
129 +    usbredirparser_do_write(dev->parser);
130  }
131  
132  static void usbredir_do_attach(void *opaque)
133 @@ -856,13 +860,13 @@ static int usbredir_chardev_can_read(void *opaque)
134  {
135      USBRedirDevice *dev = opaque;
136  
137 -    if (dev->parser) {
138 -        /* usbredir_parser_do_read will consume *all* data we give it */
139 -        return 1024 * 1024;
140 -    } else {
141 -        /* usbredir_open_close_bh hasn't handled the open event yet */
142 +    if (!dev->parser) {
143 +        WARNING("chardev_can_read called on non open chardev!\n");
144          return 0;
145      }
146 +
147 +    /* usbredir_parser_do_read will consume *all* data we give it */
148 +    return 1024 * 1024;
149  }
150  
151  static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
152 @@ -886,8 +890,10 @@ static void usbredir_chardev_event(void *opaque, int event)
153  
154      switch (event) {
155      case CHR_EVENT_OPENED:
156 +        usbredir_chardev_open(dev);
157 +        break;
158      case CHR_EVENT_CLOSED:
159 -        qemu_bh_schedule(dev->open_close_bh);
160 +        qemu_bh_schedule(dev->chardev_close_bh);
161          break;
162      }
163  }
164 @@ -917,7 +923,7 @@ static int usbredir_initfn(USBDevice *udev)
165          }
166      }
167  
168 -    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
169 +    dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
170      dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
171  
172      QTAILQ_INIT(&dev->asyncq);
173 @@ -957,7 +963,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
174      qemu_chr_fe_close(dev->cs);
175      qemu_chr_delete(dev->cs);
176      /* Note must be done after qemu_chr_close, as that causes a close event */
177 -    qemu_bh_delete(dev->open_close_bh);
178 +    qemu_bh_delete(dev->chardev_close_bh);
179  
180      qemu_del_timer(dev->attach_timer);
181      qemu_free_timer(dev->attach_timer);
182 -- 
183 1.7.12.1
184