diff --git a/.gitignore b/.gitignore index 9b14986..fa85789 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ qemu-kvm-0.13.0-25fdf4a.tar.gz /qemu-kvm-0.14.0-3593e6b.tar.gz /qemu-kvm-0.14.0-7aa8c46.tar.gz /qemu-kvm-0.15.0-525e3df.tar.gz +/qemu-kvm-0.15.0-fda1906.tar.gz +/qemu-kvm-0.15.0-59fadcc.tar.gz diff --git a/0025-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch b/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch similarity index 84% rename from 0025-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch rename to 0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch index 2632655..e92a81a 100644 --- a/0025-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch +++ b/0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch @@ -1,7 +1,7 @@ -From d24514c807c4cddfe5f919bd01cb1a9cd3f21b10 Mon Sep 17 00:00:00 2001 +From 47d0d4d2d16bdbb3e80b6c9a29b9db3f81f1d6fd Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 21:57:47 +0100 -Subject: [PATCH 25/35] char: Split out tcp socket close code in a separate +Subject: [PATCH 01/13] char: Split out tcp socket close code in a separate function Signed-off-by: Amit Shah @@ -10,10 +10,10 @@ Signed-off-by: Amit Shah 1 files changed, 16 insertions(+), 9 deletions(-) diff --git a/qemu-char.c b/qemu-char.c -index fb13b28..75efa60 100644 +index dcf7065..1701bdf 100644 --- a/qemu-char.c +++ b/qemu-char.c -@@ -1917,6 +1917,21 @@ typedef struct { +@@ -1945,6 +1945,21 @@ typedef struct { static void tcp_chr_accept(void *opaque); @@ -35,7 +35,7 @@ index fb13b28..75efa60 100644 static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { TCPCharDriver *s = chr->opaque; -@@ -2067,15 +2082,7 @@ static void tcp_chr_read(void *opaque) +@@ -2095,15 +2110,7 @@ static void tcp_chr_read(void *opaque) len = s->max_size; size = tcp_chr_recv(chr, (void *)buf, len); if (size == 0) { diff --git a/0001-hw-usb-musb.c-Don-t-misuse-usb_packet_complete.patch b/0001-hw-usb-musb.c-Don-t-misuse-usb_packet_complete.patch deleted file mode 100644 index 135f851..0000000 --- a/0001-hw-usb-musb.c-Don-t-misuse-usb_packet_complete.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 5b1a8791870cbb83cce780be54da6029be4126a4 Mon Sep 17 00:00:00 2001 -From: Peter Maydell -Date: Tue, 14 Jun 2011 12:24:04 +0100 -Subject: [PATCH 01/35] hw/usb-musb.c: Don't misuse usb_packet_complete() - -In musb_packet() handle final processing of non-asynchronous -USB packets by directly calling musb_schedule_cb() rather than -going through usb_packet_complete(). The latter will trigger -an assertion because the packet doesn't belong to a device. - -Signed-off-by: Peter Maydell -Signed-off-by: Gerd Hoffmann ---- - hw/usb-musb.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/usb-musb.c b/hw/usb-musb.c -index 21f35afa..d15971f 100644 ---- a/hw/usb-musb.c -+++ b/hw/usb-musb.c -@@ -616,7 +616,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep, - } - - ep->status[dir] = ret; -- usb_packet_complete(s->port.dev, &ep->packey[dir].p); -+ musb_schedule_cb(s->port.dev, &ep->packey[dir].p); - } - - static void musb_tx_packet_complete(USBPacket *packey, void *opaque) --- -1.7.5.1 - diff --git a/0026-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch b/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch similarity index 95% rename from 0026-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch rename to 0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch index 7433073..1fd460c 100644 --- a/0026-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch +++ b/0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch @@ -1,7 +1,7 @@ -From 7a78607683a3c3a25ab715d6a5e137be9cf29e66 Mon Sep 17 00:00:00 2001 +From ffef9f85d32395989a3c5845dfe34d2110ccb82b Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 20:31:45 +0100 -Subject: [PATCH 26/35] char: Add a QemuChrHandlers struct to initialise +Subject: [PATCH 02/13] char: Add a QemuChrHandlers struct to initialise chardev handlers Instead of passing each handler in the qemu_add_handlers() function, @@ -306,7 +306,7 @@ index 09090e9..5438660 100644 return 0; diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c -index db57096..9928c11 100644 +index 905e116..bb5740c 100644 --- a/hw/mcf_uart.c +++ b/hw/mcf_uart.c @@ -268,6 +268,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size) @@ -359,7 +359,7 @@ index 56c90da..4412b1b 100644 return 0; diff --git a/hw/pl011.c b/hw/pl011.c -index 3b94b14..7b4f3ae 100644 +index 997ce84..37ba7f6 100644 --- a/hw/pl011.c +++ b/hw/pl011.c @@ -260,6 +260,12 @@ static const VMStateDescription vmstate_pl011 = { @@ -386,7 +386,7 @@ index 3b94b14..7b4f3ae 100644 vmstate_register(&dev->qdev, -1, &vmstate_pl011, s); return 0; diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c -index ac5d95d..779081c 100644 +index cf93110..18bbe48 100644 --- a/hw/pxa2xx.c +++ b/hw/pxa2xx.c @@ -2019,6 +2019,12 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id) @@ -554,7 +554,7 @@ index 2ef7175..ac68022 100644 if (s->fifo_size <= 0) { fprintf(stderr, "syborg_serial: fifo too small\n"); diff --git a/hw/usb-serial.c b/hw/usb-serial.c -index 59cb0fb..bebd900 100644 +index c69c437..45d48ee 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -476,6 +476,12 @@ static void usb_serial_event(void *opaque, int event) @@ -581,10 +581,10 @@ index 59cb0fb..bebd900 100644 return 0; } diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index b076331..147a467 100644 +index fe5e188..cfc3087 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c -@@ -74,6 +74,12 @@ static void chr_event(void *opaque, int event) +@@ -95,6 +95,12 @@ static void chr_event(void *opaque, int event) } } @@ -597,7 +597,7 @@ index b076331..147a467 100644 static int virtconsole_initfn(VirtIOSerialPort *port) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); -@@ -86,8 +92,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port) +@@ -107,8 +113,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port) } if (vcon->chr) { @@ -607,7 +607,7 @@ index b076331..147a467 100644 info->have_data = flush_buf; info->guest_open = guest_open; info->guest_close = guest_close; -@@ -105,7 +110,7 @@ static int virtconsole_exitfn(VirtIOSerialPort *port) +@@ -126,7 +131,7 @@ static int virtconsole_exitfn(VirtIOSerialPort *port) * Instead of closing the chardev, free it so it can be used * for other purposes. */ @@ -617,11 +617,11 @@ index b076331..147a467 100644 return 0; diff --git a/hw/xen_console.c b/hw/xen_console.c -index c6c8163..4c39310 100644 +index 8ef104c..85e8a22 100644 --- a/hw/xen_console.c +++ b/hw/xen_console.c -@@ -201,6 +201,11 @@ static int con_init(struct XenDevice *xendev) - return 0; +@@ -212,6 +212,11 @@ out: + return ret; } +static const QemuChrHandlers xencons_handlers = { @@ -632,7 +632,7 @@ index c6c8163..4c39310 100644 static int con_connect(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); -@@ -221,9 +226,9 @@ static int con_connect(struct XenDevice *xendev) +@@ -232,9 +237,9 @@ static int con_connect(struct XenDevice *xendev) return -1; xen_be_bind_evtchn(&con->xendev); @@ -645,7 +645,7 @@ index c6c8163..4c39310 100644 xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", con->ring_ref, -@@ -237,8 +242,9 @@ static void con_disconnect(struct XenDevice *xendev) +@@ -248,8 +253,9 @@ static void con_disconnect(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); @@ -687,10 +687,10 @@ index 9b94e98..1845577 100644 } diff --git a/monitor.c b/monitor.c -index a6388a9..5e7ce62 100644 +index 718935b..5b79dde 100644 --- a/monitor.c +++ b/monitor.c -@@ -5238,6 +5238,18 @@ static void monitor_event(void *opaque, int event) +@@ -5249,6 +5249,18 @@ static void monitor_event(void *opaque, int event) * End: */ @@ -709,7 +709,7 @@ index a6388a9..5e7ce62 100644 void monitor_init(CharDriverState *chr, int flags) { static int is_first_init = 1; -@@ -5260,12 +5272,10 @@ void monitor_init(CharDriverState *chr, int flags) +@@ -5271,12 +5283,10 @@ void monitor_init(CharDriverState *chr, int flags) if (monitor_ctrl_mode(mon)) { mon->mc = qemu_mallocz(sizeof(MonitorControl)); /* Control mode requires special handlers */ @@ -725,10 +725,10 @@ index a6388a9..5e7ce62 100644 QLIST_INSERT_HEAD(&mon_list, mon, entry); diff --git a/net/slirp.c b/net/slirp.c -index e057a14..6eb0c51 100644 +index 157b80a..8eeec7e 100644 --- a/net/slirp.c +++ b/net/slirp.c -@@ -576,6 +576,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) +@@ -577,6 +577,11 @@ static void guestfwd_read(void *opaque, const uint8_t *buf, int size) slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size); } @@ -740,7 +740,7 @@ index e057a14..6eb0c51 100644 static int slirp_guestfwd(SlirpState *s, const char *config_str, int legacy_format) { -@@ -632,8 +637,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, +@@ -633,8 +638,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str, fwd->port = port; fwd->slirp = s->slirp; @@ -751,10 +751,10 @@ index e057a14..6eb0c51 100644 fail_syntax: diff --git a/qemu-char.c b/qemu-char.c -index 75efa60..ee763d5 100644 +index 1701bdf..1c33828 100644 --- a/qemu-char.c +++ b/qemu-char.c -@@ -190,19 +190,26 @@ void qemu_chr_send_event(CharDriverState *s, int event) +@@ -195,19 +195,26 @@ void qemu_chr_send_event(CharDriverState *s, int event) s->chr_send_event(s, event); } @@ -789,7 +789,7 @@ index 75efa60..ee763d5 100644 s->handler_opaque = opaque; if (s->chr_update_read_handler) s->chr_update_read_handler(s); -@@ -440,6 +447,12 @@ static void mux_chr_event(void *opaque, int event) +@@ -447,6 +454,12 @@ static void mux_chr_event(void *opaque, int event) mux_chr_send_event(d, i, event); } @@ -802,7 +802,7 @@ index 75efa60..ee763d5 100644 static void mux_chr_update_read_handler(CharDriverState *chr) { MuxDriver *d = chr->opaque; -@@ -454,8 +467,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr) +@@ -461,8 +474,7 @@ static void mux_chr_update_read_handler(CharDriverState *chr) d->chr_event[d->mux_cnt] = chr->chr_event; /* Fix up the real driver with mux routines */ if (d->mux_cnt == 0) { @@ -813,7 +813,7 @@ index 75efa60..ee763d5 100644 if (d->focus != -1) { mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT); diff --git a/qemu-char.h b/qemu-char.h -index 892c6da..c8e3f2b 100644 +index f361c6d..b8372ea 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -1,6 +1,7 @@ @@ -824,7 +824,7 @@ index 892c6da..c8e3f2b 100644 #include "qemu-common.h" #include "qemu-queue.h" #include "qemu-option.h" -@@ -76,6 +77,13 @@ struct CharDriverState { +@@ -77,6 +78,13 @@ struct CharDriverState { QTAILQ_ENTRY(CharDriverState) next; }; @@ -838,7 +838,7 @@ index 892c6da..c8e3f2b 100644 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); CharDriverState *qemu_chr_open_opts(QemuOpts *opts, void (*init)(struct CharDriverState *s)); -@@ -88,10 +96,7 @@ void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) +@@ -89,10 +97,7 @@ void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); void qemu_chr_send_event(CharDriverState *s, int event); diff --git a/0002-usb-Add-a-usb_fill_port-helper-function.patch b/0002-usb-Add-a-usb_fill_port-helper-function.patch deleted file mode 100644 index 43ea3cf..0000000 --- a/0002-usb-Add-a-usb_fill_port-helper-function.patch +++ /dev/null @@ -1,42 +0,0 @@ -From dc1a2be79b202d353d320393445ccd9db6263371 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 30 Jun 2011 11:57:57 +0200 -Subject: [PATCH 02/35] usb: Add a usb_fill_port helper function - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-bus.c | 10 ++++++++-- - 1 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/hw/usb-bus.c b/hw/usb-bus.c -index 2abce12..776974e 100644 ---- a/hw/usb-bus.c -+++ b/hw/usb-bus.c -@@ -140,8 +140,8 @@ USBDevice *usb_create_simple(USBBus *bus, const char *name) - return dev; - } - --void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, -- USBPortOps *ops, int speedmask) -+static void usb_fill_port(USBPort *port, void *opaque, int index, -+ USBPortOps *ops, int speedmask) - { - port->opaque = opaque; - port->index = index; -@@ -149,6 +149,12 @@ void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, - port->index = index; - port->ops = ops; - port->speedmask = speedmask; -+} -+ -+void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, -+ USBPortOps *ops, int speedmask) -+{ -+ usb_fill_port(port, opaque, index, ops, speedmask); - QTAILQ_INSERT_TAIL(&bus->free, port, next); - bus->nfree++; - } --- -1.7.5.1 - diff --git a/0027-iohandlers-Add-enable-disable_write_fd_handler-funct.patch b/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch similarity index 88% rename from 0027-iohandlers-Add-enable-disable_write_fd_handler-funct.patch rename to 0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch index 9c6620a..cb2c9a2 100644 --- a/0027-iohandlers-Add-enable-disable_write_fd_handler-funct.patch +++ b/0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch @@ -1,7 +1,7 @@ -From 328ddb228ed9e5509b8418b1f34de6d6aff83d62 Mon Sep 17 00:00:00 2001 +From cb93720645e20825259dbb4d2f833b05a98e3062 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 20:32:58 +0100 -Subject: [PATCH 27/35] iohandlers: Add enable/disable_write_fd_handler() +Subject: [PATCH 03/13] iohandlers: Add enable/disable_write_fd_handler() functions These will be used to provide a cleaner API for the nonblocking case. @@ -59,10 +59,10 @@ index 2b82421..8e6628b 100644 /* XXX: fd_read_poll should be suppressed, but an API change is necessary in the character devices to suppress fd_can_read(). */ diff --git a/qemu-char.h b/qemu-char.h -index c8e3f2b..7d5dc6c 100644 +index b8372ea..9fe1b82 100644 --- a/qemu-char.h +++ b/qemu-char.h -@@ -121,6 +121,9 @@ size_t qemu_chr_mem_osize(const CharDriverState *chr); +@@ -123,6 +123,9 @@ size_t qemu_chr_mem_osize(const CharDriverState *chr); /* async I/O support */ diff --git a/0003-usb-Move-initial-call-of-usb_port_location-to-usb_fi.patch b/0003-usb-Move-initial-call-of-usb_port_location-to-usb_fi.patch deleted file mode 100644 index cba122d..0000000 --- a/0003-usb-Move-initial-call-of-usb_port_location-to-usb_fi.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 397fed3bc9bf6dd0e8e18c5be077897299e5c4e2 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 30 Jun 2011 12:05:19 +0200 -Subject: [PATCH 03/35] usb: Move (initial) call of usb_port_location to - usb_fill_port - -Cleanup / preparation patch for companion controller support. Note that -as a "side-effect" this patch also fixes the milkymist-softusb controller -not having a port_location set for its ports. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-bus.c | 1 + - hw/usb-ehci.c | 1 - - hw/usb-musb.c | 1 - - hw/usb-ohci.c | 1 - - hw/usb-uhci.c | 1 - - 5 files changed, 1 insertions(+), 4 deletions(-) - -diff --git a/hw/usb-bus.c b/hw/usb-bus.c -index 776974e..e37e8a2 100644 ---- a/hw/usb-bus.c -+++ b/hw/usb-bus.c -@@ -149,6 +149,7 @@ static void usb_fill_port(USBPort *port, void *opaque, int index, - port->index = index; - port->ops = ops; - port->speedmask = speedmask; -+ usb_port_location(port, NULL, index + 1); - } - - void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 91fb7de..88cb2c2 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -2206,7 +2206,6 @@ static int usb_ehci_initfn(PCIDevice *dev) - for(i = 0; i < NB_PORTS; i++) { - usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops, - USB_SPEED_MASK_HIGH); -- usb_port_location(&s->ports[i], NULL, i+1); - s->ports[i].dev = 0; - } - -diff --git a/hw/usb-musb.c b/hw/usb-musb.c -index d15971f..84e6017 100644 ---- a/hw/usb-musb.c -+++ b/hw/usb-musb.c -@@ -369,7 +369,6 @@ struct MUSBState *musb_init(qemu_irq *irqs) - usb_bus_new(&s->bus, &musb_bus_ops, NULL /* FIXME */); - usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -- usb_port_location(&s->port, NULL, 1); - - return s; - } -diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c -index 1c29b9f..95e4623 100644 ---- a/hw/usb-ohci.c -+++ b/hw/usb-ohci.c -@@ -1742,7 +1742,6 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, - for (i = 0; i < num_ports; i++) { - usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -- usb_port_location(&ohci->rhport[i].port, NULL, i+1); - } - - ohci->async_td = 0; -diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c -index 405fa7b..fd25d2a 100644 ---- a/hw/usb-uhci.c -+++ b/hw/usb-uhci.c -@@ -1129,7 +1129,6 @@ static int usb_uhci_common_initfn(PCIDevice *dev) - for(i = 0; i < NB_PORTS; i++) { - usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -- usb_port_location(&s->ports[i].port, NULL, i+1); - } - s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s); - s->num_ports_vmstate = NB_PORTS; --- -1.7.5.1 - diff --git a/0028-char-Add-framework-for-a-write-unblocked-callback.patch b/0004-char-Add-framework-for-a-write-unblocked-callback.patch similarity index 84% rename from 0028-char-Add-framework-for-a-write-unblocked-callback.patch rename to 0004-char-Add-framework-for-a-write-unblocked-callback.patch index dc32f9b..36ec50d 100644 --- a/0028-char-Add-framework-for-a-write-unblocked-callback.patch +++ b/0004-char-Add-framework-for-a-write-unblocked-callback.patch @@ -1,7 +1,7 @@ -From 59ff8a6457e82aadad7529602da68406de374a33 Mon Sep 17 00:00:00 2001 +From 66945912c4bd1bc70f3221288a4e7acc5717b336 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 21:41:42 +0100 -Subject: [PATCH 28/35] char: Add framework for a 'write unblocked' callback +Subject: [PATCH 04/13] char: Add framework for a 'write unblocked' callback The char layer can let users know that the driver will block on further input. For users interested in not blocking, they can assign a function @@ -16,10 +16,10 @@ Signed-off-by: Amit Shah 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/qemu-char.c b/qemu-char.c -index ee763d5..830f0c3 100644 +index 1c33828..ec4eb68 100644 --- a/qemu-char.c +++ b/qemu-char.c -@@ -209,11 +209,14 @@ void qemu_chr_add_handlers(CharDriverState *s, +@@ -214,11 +214,14 @@ void qemu_chr_add_handlers(CharDriverState *s, } s->chr_can_read = handlers->fd_can_read; s->chr_read = handlers->fd_read; @@ -35,10 +35,10 @@ index ee763d5..830f0c3 100644 also get the open event */ if (s->opened) { diff --git a/qemu-char.h b/qemu-char.h -index 7d5dc6c..e942bdf 100644 +index 9fe1b82..68e7b5b 100644 --- a/qemu-char.h +++ b/qemu-char.h -@@ -61,6 +61,9 @@ struct CharDriverState { +@@ -62,6 +62,9 @@ struct CharDriverState { IOEventHandler *chr_event; IOCanReadHandler *chr_can_read; IOReadHandler *chr_read; @@ -48,7 +48,7 @@ index 7d5dc6c..e942bdf 100644 void *handler_opaque; void (*chr_send_event)(struct CharDriverState *chr, int event); void (*chr_close)(struct CharDriverState *chr); -@@ -74,6 +77,7 @@ struct CharDriverState { +@@ -75,6 +78,7 @@ struct CharDriverState { char *filename; int opened; int avail_connections; diff --git a/0004-usb-Add-a-register_companion-USB-bus-op.patch b/0004-usb-Add-a-register_companion-USB-bus-op.patch deleted file mode 100644 index 3cdd193..0000000 --- a/0004-usb-Add-a-register_companion-USB-bus-op.patch +++ /dev/null @@ -1,82 +0,0 @@ -From fc63639374684dae600d200c133adad75044e587 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 11:29:56 +0200 -Subject: [PATCH 04/35] usb: Add a register_companion USB bus op. - -This is a preparation patch for adding support for USB companion controllers. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-bus.c | 31 +++++++++++++++++++++++++++++++ - hw/usb.h | 5 +++++ - 2 files changed, 36 insertions(+), 0 deletions(-) - -diff --git a/hw/usb-bus.c b/hw/usb-bus.c -index e37e8a2..b511bac 100644 ---- a/hw/usb-bus.c -+++ b/hw/usb-bus.c -@@ -160,6 +160,37 @@ void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, - bus->nfree++; - } - -+int usb_register_companion(const char *masterbus, USBPort *ports[], -+ uint32_t portcount, uint32_t firstport, -+ void *opaque, USBPortOps *ops, int speedmask) -+{ -+ USBBus *bus; -+ int i; -+ -+ QTAILQ_FOREACH(bus, &busses, next) { -+ if (strcmp(bus->qbus.name, masterbus) == 0) { -+ break; -+ } -+ } -+ -+ if (!bus || !bus->ops->register_companion) { -+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus", -+ "an USB masterbus"); -+ if (bus) { -+ error_printf_unless_qmp( -+ "USB bus '%s' does not allow companion controllers\n", -+ masterbus); -+ } -+ return -1; -+ } -+ -+ for (i = 0; i < portcount; i++) { -+ usb_fill_port(ports[i], opaque, i, ops, speedmask); -+ } -+ -+ return bus->ops->register_companion(bus, ports, portcount, firstport); -+} -+ - void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr) - { - if (upstream) { -diff --git a/hw/usb.h b/hw/usb.h -index 076e2ff..a5f2efa 100644 ---- a/hw/usb.h -+++ b/hw/usb.h -@@ -344,6 +344,8 @@ struct USBBus { - }; - - struct USBBusOps { -+ int (*register_companion)(USBBus *bus, USBPort *ports[], -+ uint32_t portcount, uint32_t firstport); - void (*device_destroy)(USBBus *bus, USBDevice *dev); - }; - -@@ -356,6 +358,9 @@ USBDevice *usb_create_simple(USBBus *bus, const char *name); - USBDevice *usbdevice_create(const char *cmdline); - void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, - USBPortOps *ops, int speedmask); -+int usb_register_companion(const char *masterbus, USBPort *ports[], -+ uint32_t portcount, uint32_t firstport, -+ void *opaque, USBPortOps *ops, int speedmask); - void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr); - void usb_unregister_port(USBBus *bus, USBPort *port); - int usb_device_attach(USBDevice *dev); --- -1.7.5.1 - diff --git a/0029-char-Update-send_all-to-handle-nonblocking-chardev-w.patch b/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch similarity index 90% rename from 0029-char-Update-send_all-to-handle-nonblocking-chardev-w.patch rename to 0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch index db4edba..ead1e8b 100644 --- a/0029-char-Update-send_all-to-handle-nonblocking-chardev-w.patch +++ b/0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch @@ -1,7 +1,7 @@ -From 4178a8240badad028ffd13482352510ad6a050e4 Mon Sep 17 00:00:00 2001 +From 8aab343e17b05abb051105cdb367edb4deef0c60 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 22:00:27 +0100 -Subject: [PATCH 29/35] char: Update send_all() to handle nonblocking chardev +Subject: [PATCH 05/13] char: Update send_all() to handle nonblocking chardev write requests The send_all function is modified to return to the caller in case the @@ -37,10 +37,10 @@ index bc1bf58..a40687a 100644 static ssize_t net_socket_receive_dgram(VLANClientState *nc, const uint8_t *buf, size_t size) diff --git a/qemu-char.c b/qemu-char.c -index 830f0c3..88b22c3 100644 +index ec4eb68..8789627 100644 --- a/qemu-char.c +++ b/qemu-char.c -@@ -506,7 +506,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) +@@ -513,7 +513,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) #ifdef _WIN32 @@ -49,7 +49,7 @@ index 830f0c3..88b22c3 100644 { int ret, len; -@@ -514,9 +514,14 @@ int send_all(int fd, const void *buf, int len1) +@@ -521,9 +521,14 @@ int send_all(int fd, const void *buf, int len1) while (len > 0) { ret = send(fd, buf, len, 0); if (ret < 0) { @@ -64,7 +64,7 @@ index 830f0c3..88b22c3 100644 } } else if (ret == 0) { break; -@@ -530,7 +535,7 @@ int send_all(int fd, const void *buf, int len1) +@@ -537,7 +542,7 @@ int send_all(int fd, const void *buf, int len1) #else @@ -73,7 +73,7 @@ index 830f0c3..88b22c3 100644 { int ret, len; const uint8_t *buf = _buf; -@@ -539,8 +544,15 @@ int send_all(int fd, const void *_buf, int len1) +@@ -546,8 +551,15 @@ int send_all(int fd, const void *_buf, int len1) while (len > 0) { ret = write(fd, buf, len); if (ret < 0) { @@ -90,7 +90,7 @@ index 830f0c3..88b22c3 100644 } else if (ret == 0) { break; } else { -@@ -552,6 +564,55 @@ int send_all(int fd, const void *_buf, int len1) +@@ -559,6 +571,55 @@ int send_all(int fd, const void *_buf, int len1) } #endif /* !_WIN32 */ @@ -146,7 +146,7 @@ index 830f0c3..88b22c3 100644 #ifndef _WIN32 typedef struct { -@@ -565,7 +626,7 @@ static int stdio_nb_clients = 0; +@@ -572,7 +633,7 @@ static int stdio_nb_clients = 0; static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { FDCharDriver *s = chr->opaque; @@ -155,7 +155,7 @@ index 830f0c3..88b22c3 100644 } static int fd_chr_read_poll(void *opaque) -@@ -881,7 +942,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +@@ -897,7 +958,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len) pty_chr_update_read_handler(chr); return 0; } @@ -164,7 +164,7 @@ index 830f0c3..88b22c3 100644 } static int pty_chr_read_poll(void *opaque) -@@ -1950,8 +2011,15 @@ static void tcp_closed(void *opaque) +@@ -1978,8 +2039,15 @@ static void tcp_closed(void *opaque) static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { TCPCharDriver *s = chr->opaque; diff --git a/0005-usb-Make-port-wakeup-and-complete-ops-take-a-USBPort.patch b/0005-usb-Make-port-wakeup-and-complete-ops-take-a-USBPort.patch deleted file mode 100644 index 9a30d18..0000000 --- a/0005-usb-Make-port-wakeup-and-complete-ops-take-a-USBPort.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 99a493bf96aa03427633b24653112b43fa7b7131 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 21 Jun 2011 11:52:28 +0200 -Subject: [PATCH 05/35] usb: Make port wakeup and complete ops take a USBPort - instead of a Device - -This makes them consistent with the attach and detach ops, and in general -it makes sense to make portops take a port as argument. This also makes -adding support for a companion controller easier / cleaner. - -[ kraxel: fix usb-musb.c build ] - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 2 +- - hw/usb-hub.c | 10 +++++----- - hw/usb-musb.c | 6 +++--- - hw/usb-ohci.c | 12 +++++------- - hw/usb-uhci.c | 11 +++++------ - hw/usb.c | 4 ++-- - hw/usb.h | 9 +++++++-- - 7 files changed, 28 insertions(+), 26 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 88cb2c2..428c90b 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -1111,7 +1111,7 @@ static int ehci_buffer_rw(EHCIQueue *q, int bytes, int rw) - return 0; - } - --static void ehci_async_complete_packet(USBDevice *dev, USBPacket *packet) -+static void ehci_async_complete_packet(USBPort *port, USBPacket *packet) - { - EHCIQueue *q = container_of(packet, EHCIQueue, packet); - -diff --git a/hw/usb-hub.c b/hw/usb-hub.c -index 6e2a358..d324bba 100644 ---- a/hw/usb-hub.c -+++ b/hw/usb-hub.c -@@ -246,10 +246,10 @@ static void usb_hub_detach(USBPort *port1) - } - } - --static void usb_hub_wakeup(USBDevice *dev) -+static void usb_hub_wakeup(USBPort *port1) - { -- USBHubState *s = dev->port->opaque; -- USBHubPort *port = &s->ports[dev->port->index]; -+ USBHubState *s = port1->opaque; -+ USBHubPort *port = &s->ports[port1->index]; - - if (port->wPortStatus & PORT_STAT_SUSPEND) { - port->wPortChange |= PORT_STAT_C_SUSPEND; -@@ -257,9 +257,9 @@ static void usb_hub_wakeup(USBDevice *dev) - } - } - --static void usb_hub_complete(USBDevice *dev, USBPacket *packet) -+static void usb_hub_complete(USBPort *port, USBPacket *packet) - { -- USBHubState *s = dev->port->opaque; -+ USBHubState *s = port->opaque; - - /* - * Just pass it along upstream for now. -diff --git a/hw/usb-musb.c b/hw/usb-musb.c -index 84e6017..580bdc8 100644 ---- a/hw/usb-musb.c -+++ b/hw/usb-musb.c -@@ -261,7 +261,7 @@ - - static void musb_attach(USBPort *port); - static void musb_detach(USBPort *port); --static void musb_schedule_cb(USBDevice *dev, USBPacket *p); -+static void musb_schedule_cb(USBPort *port, USBPacket *p); - static void musb_device_destroy(USBBus *bus, USBDevice *dev); - - static USBPortOps musb_port_ops = { -@@ -517,7 +517,7 @@ static void musb_cb_tick1(void *opaque) - - #define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0) - --static void musb_schedule_cb(USBDevice *dev, USBPacket *packey) -+static void musb_schedule_cb(USBPort *port, USBPacket *packey) - { - MUSBPacket *p = container_of(packey, MUSBPacket, p); - MUSBEndPoint *ep = p->ep; -@@ -615,7 +615,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep, - } - - ep->status[dir] = ret; -- musb_schedule_cb(s->port.dev, &ep->packey[dir].p); -+ musb_schedule_cb(&s->port, &ep->packey[dir].p); - } - - static void musb_tx_packet_complete(USBPacket *packey, void *opaque) -diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c -index 95e4623..bd92c31 100644 ---- a/hw/usb-ohci.c -+++ b/hw/usb-ohci.c -@@ -367,15 +367,13 @@ static void ohci_detach(USBPort *port1) - ohci_set_interrupt(s, OHCI_INTR_RHSC); - } - --static void ohci_wakeup(USBDevice *dev) -+static void ohci_wakeup(USBPort *port1) - { -- USBBus *bus = usb_bus_from_device(dev); -- OHCIState *s = container_of(bus, OHCIState, bus); -- int portnum = dev->port->index; -- OHCIPort *port = &s->rhport[portnum]; -+ OHCIState *s = port1->opaque; -+ OHCIPort *port = &s->rhport[port1->index]; - uint32_t intr = 0; - if (port->ctrl & OHCI_PORT_PSS) { -- DPRINTF("usb-ohci: port %d: wakeup\n", portnum); -+ DPRINTF("usb-ohci: port %d: wakeup\n", port1->index); - port->ctrl |= OHCI_PORT_PSSC; - port->ctrl &= ~OHCI_PORT_PSS; - intr = OHCI_INTR_RHSC; -@@ -602,7 +600,7 @@ static void ohci_copy_iso_td(OHCIState *ohci, - - static void ohci_process_lists(OHCIState *ohci, int completion); - --static void ohci_async_complete_packet(USBDevice *dev, USBPacket *packet) -+static void ohci_async_complete_packet(USBPort *port, USBPacket *packet) - { - OHCIState *ohci = container_of(packet, OHCIState, usb_packet); - #ifdef DEBUG_PACKET -diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c -index fd25d2a..ab635f6 100644 ---- a/hw/usb-uhci.c -+++ b/hw/usb-uhci.c -@@ -620,11 +620,10 @@ static void uhci_detach(USBPort *port1) - uhci_resume(s); - } - --static void uhci_wakeup(USBDevice *dev) -+static void uhci_wakeup(USBPort *port1) - { -- USBBus *bus = usb_bus_from_device(dev); -- UHCIState *s = container_of(bus, UHCIState, bus); -- UHCIPort *port = s->ports + dev->port->index; -+ UHCIState *s = port1->opaque; -+ UHCIPort *port = &s->ports[port1->index]; - - if (port->ctrl & UHCI_PORT_SUSPEND && !(port->ctrl & UHCI_PORT_RD)) { - port->ctrl |= UHCI_PORT_RD; -@@ -657,7 +656,7 @@ static int uhci_broadcast_packet(UHCIState *s, USBPacket *p) - return ret; - } - --static void uhci_async_complete(USBDevice *dev, USBPacket *packet); -+static void uhci_async_complete(USBPort *port, USBPacket *packet); - static void uhci_process_frame(UHCIState *s); - - /* return -1 if fatal error (frame must be stopped) -@@ -849,7 +848,7 @@ done: - return len; - } - --static void uhci_async_complete(USBDevice *dev, USBPacket *packet) -+static void uhci_async_complete(USBPort *port, USBPacket *packet) - { - UHCIAsync *async = container_of(packet, UHCIAsync, packet); - UHCIState *s = async->uhci; -diff --git a/hw/usb.c b/hw/usb.c -index 4a39cbc..735ffd1 100644 ---- a/hw/usb.c -+++ b/hw/usb.c -@@ -52,7 +52,7 @@ void usb_attach(USBPort *port, USBDevice *dev) - void usb_wakeup(USBDevice *dev) - { - if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) { -- dev->port->ops->wakeup(dev); -+ dev->port->ops->wakeup(dev->port); - } - } - -@@ -335,7 +335,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p) - { - /* Note: p->owner != dev is possible in case dev is a hub */ - assert(p->owner != NULL); -- dev->port->ops->complete(dev, p); -+ dev->port->ops->complete(dev->port, p); - p->owner = NULL; - } - -diff --git a/hw/usb.h b/hw/usb.h -index a5f2efa..65f45a0 100644 ---- a/hw/usb.h -+++ b/hw/usb.h -@@ -252,8 +252,13 @@ struct USBDeviceInfo { - typedef struct USBPortOps { - void (*attach)(USBPort *port); - void (*detach)(USBPort *port); -- void (*wakeup)(USBDevice *dev); -- void (*complete)(USBDevice *dev, USBPacket *p); -+ void (*wakeup)(USBPort *port); -+ /* -+ * Note that port->dev will be different then the device from which -+ * the packet originated when a hub is involved, if you want the orginating -+ * device use p->owner -+ */ -+ void (*complete)(USBPort *port, USBPacket *p); - } USBPortOps; - - /* USB port on which a device can be connected */ --- -1.7.5.1 - diff --git a/0030-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch b/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch similarity index 83% rename from 0030-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch rename to 0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch index 0594e32..d8fcefc 100644 --- a/0030-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch +++ b/0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch @@ -1,7 +1,7 @@ -From 56cbfb533c04cde3a55c1345ea0f9097b1ab13fa Mon Sep 17 00:00:00 2001 +From 9a773de6f770bf2f05acca786e14abd79a9f930c Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 22:02:47 +0100 -Subject: [PATCH 30/35] char: Equip the unix/tcp backend to handle nonblocking +Subject: [PATCH 06/13] char: Equip the unix/tcp backend to handle nonblocking writes# Now that the infrastructure is in place to return -EAGAIN to callers, @@ -18,7 +18,7 @@ Signed-off-by: Amit Shah 1 files changed, 34 insertions(+), 0 deletions(-) diff --git a/qemu-char.c b/qemu-char.c -index 88b22c3..e9d7f0a 100644 +index 8789627..d811f2a 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -106,6 +106,19 @@ @@ -41,7 +41,7 @@ index 88b22c3..e9d7f0a 100644 static void qemu_chr_event(CharDriverState *s, int event) { /* Keep track if the char device is open */ -@@ -2268,6 +2281,25 @@ static void tcp_chr_close(CharDriverState *chr) +@@ -2308,6 +2321,25 @@ static void tcp_chr_close(CharDriverState *chr) qemu_chr_event(chr, CHR_EVENT_CLOSED); } @@ -64,13 +64,13 @@ index 88b22c3..e9d7f0a 100644 + disable_write_fd_handler(s->fd); +} + - static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) + static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr = NULL; -@@ -2320,6 +2352,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) - chr->chr_write = tcp_chr_write; +@@ -2364,6 +2396,8 @@ static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr) chr->chr_close = tcp_chr_close; chr->get_msgfd = tcp_get_msgfd; + chr->chr_add_client = tcp_chr_add_client; + chr->chr_enable_write_fd_handler = tcp_enable_write_fd_handler; + chr->chr_disable_write_fd_handler = tcp_disable_write_fd_handler; diff --git a/0006-usb-Replace-device_destroy-bus-op-with-a-child_detac.patch b/0006-usb-Replace-device_destroy-bus-op-with-a-child_detac.patch deleted file mode 100644 index 5811b96..0000000 --- a/0006-usb-Replace-device_destroy-bus-op-with-a-child_detac.patch +++ /dev/null @@ -1,358 +0,0 @@ -From a0f20940be744556be844ac857fa6dd679dc7af0 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 12:31:11 +0200 -Subject: [PATCH 06/35] usb: Replace device_destroy bus op with a child_detach - port op - -Note this fixes 2 things in one go, first of all the device_destroy bus -op should be a device_detach bus op, as pending async packets from the -device should be cancelled on detach not on destroy. - -Secondly having this as a bus op won't work with companion controllers, since -then there will be 1 bus driven by the ehci controller and thus 1 set of bus -ops, but the device being detached may be downstream of a handed over port. -Making the detach of a downstream device a port op allows the ehci controller -to forward this to the companion controller port for handed over ports. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/milkymist-softusb.c | 9 +++++++-- - hw/usb-bus.c | 2 -- - hw/usb-ehci.c | 18 ++++++++++-------- - hw/usb-hub.c | 12 ++++++++++++ - hw/usb-musb.c | 17 +++++++++++++---- - hw/usb-ohci.c | 16 ++++++++++++---- - hw/usb-uhci.c | 18 ++++++++++-------- - hw/usb.h | 6 +++++- - 8 files changed, 69 insertions(+), 29 deletions(-) - -diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c -index 5ab35c3..ce2bfc6 100644 ---- a/hw/milkymist-softusb.c -+++ b/hw/milkymist-softusb.c -@@ -247,16 +247,21 @@ static void softusb_attach(USBPort *port) - { - } - --static void softusb_device_destroy(USBBus *bus, USBDevice *dev) -+static void softusb_detach(USBPort *port) -+{ -+} -+ -+static void softusb_child_detach(USBPort *port, USBDevice *child) - { - } - - static USBPortOps softusb_ops = { - .attach = softusb_attach, -+ .detach = softusb_detach, -+ .child_detach = softusb_child_detach, - }; - - static USBBusOps softusb_bus_ops = { -- .device_destroy = softusb_device_destroy, - }; - - static void milkymist_softusb_reset(DeviceState *d) -diff --git a/hw/usb-bus.c b/hw/usb-bus.c -index b511bac..c8347e9 100644 ---- a/hw/usb-bus.c -+++ b/hw/usb-bus.c -@@ -82,12 +82,10 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) - static int usb_qdev_exit(DeviceState *qdev) - { - USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev); -- USBBus *bus = usb_bus_from_device(dev); - - if (dev->attached) { - usb_device_detach(dev); - } -- bus->ops->device_destroy(bus, dev); - if (dev->info->handle_destroy) { - dev->info->handle_destroy(dev); - } -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 428c90b..96451f3 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -751,6 +751,8 @@ static void ehci_detach(USBPort *port) - - trace_usb_ehci_port_detach(port->index); - -+ ehci_queues_rip_device(s, port->dev); -+ - *portsc &= ~PORTSC_CONNECT; - *portsc |= PORTSC_CSC; - -@@ -764,6 +766,13 @@ static void ehci_detach(USBPort *port) - } - } - -+static void ehci_child_detach(USBPort *port, USBDevice *child) -+{ -+ EHCIState *s = port->opaque; -+ -+ ehci_queues_rip_device(s, child); -+} -+ - /* 4.1 host controller initialization */ - static void ehci_reset(void *opaque) - { -@@ -2117,23 +2126,16 @@ static void ehci_map(PCIDevice *pci_dev, int region_num, - cpu_register_physical_memory(addr, size, s->mem); - } - --static void ehci_device_destroy(USBBus *bus, USBDevice *dev) --{ -- EHCIState *s = container_of(bus, EHCIState, bus); -- -- ehci_queues_rip_device(s, dev); --} -- - static int usb_ehci_initfn(PCIDevice *dev); - - static USBPortOps ehci_port_ops = { - .attach = ehci_attach, - .detach = ehci_detach, -+ .child_detach = ehci_child_detach, - .complete = ehci_async_complete_packet, - }; - - static USBBusOps ehci_bus_ops = { -- .device_destroy = ehci_device_destroy, - }; - - static PCIDeviceInfo ehci_info = { -diff --git a/hw/usb-hub.c b/hw/usb-hub.c -index d324bba..b7557ce 100644 ---- a/hw/usb-hub.c -+++ b/hw/usb-hub.c -@@ -238,6 +238,9 @@ static void usb_hub_detach(USBPort *port1) - USBHubState *s = port1->opaque; - USBHubPort *port = &s->ports[port1->index]; - -+ /* Let upstream know the device on this port is gone */ -+ s->dev.port->ops->child_detach(s->dev.port, port1->dev); -+ - port->wPortStatus &= ~PORT_STAT_CONNECTION; - port->wPortChange |= PORT_STAT_C_CONNECTION; - if (port->wPortStatus & PORT_STAT_ENABLE) { -@@ -246,6 +249,14 @@ static void usb_hub_detach(USBPort *port1) - } - } - -+static void usb_hub_child_detach(USBPort *port1, USBDevice *child) -+{ -+ USBHubState *s = port1->opaque; -+ -+ /* Pass along upstream */ -+ s->dev.port->ops->child_detach(s->dev.port, child); -+} -+ - static void usb_hub_wakeup(USBPort *port1) - { - USBHubState *s = port1->opaque; -@@ -537,6 +548,7 @@ static void usb_hub_handle_destroy(USBDevice *dev) - static USBPortOps usb_hub_port_ops = { - .attach = usb_hub_attach, - .detach = usb_hub_detach, -+ .child_detach = usb_hub_child_detach, - .wakeup = usb_hub_wakeup, - .complete = usb_hub_complete, - }; -diff --git a/hw/usb-musb.c b/hw/usb-musb.c -index 580bdc8..035dda8 100644 ---- a/hw/usb-musb.c -+++ b/hw/usb-musb.c -@@ -261,17 +261,18 @@ - - static void musb_attach(USBPort *port); - static void musb_detach(USBPort *port); -+static void musb_child_detach(USBPort *port, USBDevice *child); - static void musb_schedule_cb(USBPort *port, USBPacket *p); --static void musb_device_destroy(USBBus *bus, USBDevice *dev); -+static void musb_async_cancel_device(MUSBState *s, USBDevice *dev); - - static USBPortOps musb_port_ops = { - .attach = musb_attach, - .detach = musb_detach, -+ .child_detach = musb_child_detach, - .complete = musb_schedule_cb, - }; - - static USBBusOps musb_bus_ops = { -- .device_destroy = musb_device_destroy, - }; - - typedef struct MUSBPacket MUSBPacket; -@@ -497,10 +498,19 @@ static void musb_detach(USBPort *port) - { - MUSBState *s = (MUSBState *) port->opaque; - -+ musb_async_cancel_device(s, port->dev); -+ - musb_intr_set(s, musb_irq_disconnect, 1); - musb_session_update(s, 1, s->session); - } - -+static void musb_child_detach(USBPort *port, USBDevice *child) -+{ -+ MUSBState *s = (MUSBState *) port->opaque; -+ -+ musb_async_cancel_device(s, child); -+} -+ - static void musb_cb_tick0(void *opaque) - { - MUSBEndPoint *ep = (MUSBEndPoint *) opaque; -@@ -782,9 +792,8 @@ static void musb_rx_packet_complete(USBPacket *packey, void *opaque) - musb_rx_intr_set(s, epnum, 1); - } - --static void musb_device_destroy(USBBus *bus, USBDevice *dev) -+static void musb_async_cancel_device(MUSBState *s, USBDevice *dev) - { -- MUSBState *s = container_of(bus, MUSBState, bus); - int ep, dir; - - for (ep = 0; ep < 16; ep++) { -diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c -index bd92c31..46f0bcb 100644 ---- a/hw/usb-ohci.c -+++ b/hw/usb-ohci.c -@@ -124,6 +124,7 @@ struct ohci_hcca { - }; - - static void ohci_bus_stop(OHCIState *ohci); -+static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev); - - /* Bitfields for the first word of an Endpoint Desciptor. */ - #define OHCI_ED_FA_SHIFT 0 -@@ -351,6 +352,8 @@ static void ohci_detach(USBPort *port1) - OHCIPort *port = &s->rhport[port1->index]; - uint32_t old_state = port->ctrl; - -+ ohci_async_cancel_device(s, port1->dev); -+ - /* set connect status */ - if (port->ctrl & OHCI_PORT_CCS) { - port->ctrl &= ~OHCI_PORT_CCS; -@@ -392,6 +395,13 @@ static void ohci_wakeup(USBPort *port1) - ohci_set_interrupt(s, intr); - } - -+static void ohci_child_detach(USBPort *port1, USBDevice *child) -+{ -+ OHCIState *s = port1->opaque; -+ -+ ohci_async_cancel_device(s, child); -+} -+ - /* Reset the controller */ - static void ohci_reset(void *opaque) - { -@@ -1673,10 +1683,8 @@ static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) - } - } - --static void ohci_device_destroy(USBBus *bus, USBDevice *dev) -+static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) - { -- OHCIState *ohci = container_of(bus, OHCIState, bus); -- - if (ohci->async_td && ohci->usb_packet.owner == dev) { - usb_cancel_packet(&ohci->usb_packet); - ohci->async_td = 0; -@@ -1700,12 +1708,12 @@ static CPUWriteMemoryFunc * const ohci_writefn[3]={ - static USBPortOps ohci_port_ops = { - .attach = ohci_attach, - .detach = ohci_detach, -+ .child_detach = ohci_child_detach, - .wakeup = ohci_wakeup, - .complete = ohci_async_complete_packet, - }; - - static USBBusOps ohci_bus_ops = { -- .device_destroy = ohci_device_destroy, - }; - - static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, -diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c -index ab635f6..a46d61a 100644 ---- a/hw/usb-uhci.c -+++ b/hw/usb-uhci.c -@@ -606,6 +606,8 @@ static void uhci_detach(USBPort *port1) - UHCIState *s = port1->opaque; - UHCIPort *port = &s->ports[port1->index]; - -+ uhci_async_cancel_device(s, port1->dev); -+ - /* set connect status */ - if (port->ctrl & UHCI_PORT_CCS) { - port->ctrl &= ~UHCI_PORT_CCS; -@@ -620,6 +622,13 @@ static void uhci_detach(USBPort *port1) - uhci_resume(s); - } - -+static void uhci_child_detach(USBPort *port1, USBDevice *child) -+{ -+ UHCIState *s = port1->opaque; -+ -+ uhci_async_cancel_device(s, child); -+} -+ - static void uhci_wakeup(USBPort *port1) - { - UHCIState *s = port1->opaque; -@@ -1095,22 +1104,15 @@ static void uhci_map(PCIDevice *pci_dev, int region_num, - register_ioport_read(addr, 32, 1, uhci_ioport_readb, s); - } - --static void uhci_device_destroy(USBBus *bus, USBDevice *dev) --{ -- UHCIState *s = container_of(bus, UHCIState, bus); -- -- uhci_async_cancel_device(s, dev); --} -- - static USBPortOps uhci_port_ops = { - .attach = uhci_attach, - .detach = uhci_detach, -+ .child_detach = uhci_child_detach, - .wakeup = uhci_wakeup, - .complete = uhci_async_complete, - }; - - static USBBusOps uhci_bus_ops = { -- .device_destroy = uhci_device_destroy, - }; - - static int usb_uhci_common_initfn(PCIDevice *dev) -diff --git a/hw/usb.h b/hw/usb.h -index 65f45a0..ded2de2 100644 ---- a/hw/usb.h -+++ b/hw/usb.h -@@ -252,6 +252,11 @@ struct USBDeviceInfo { - typedef struct USBPortOps { - void (*attach)(USBPort *port); - void (*detach)(USBPort *port); -+ /* -+ * This gets called when a device downstream from the device attached to -+ * the port (iow attached through a hub) gets detached. -+ */ -+ void (*child_detach)(USBPort *port, USBDevice *child); - void (*wakeup)(USBPort *port); - /* - * Note that port->dev will be different then the device from which -@@ -351,7 +356,6 @@ struct USBBus { - struct USBBusOps { - int (*register_companion)(USBBus *bus, USBPort *ports[], - uint32_t portcount, uint32_t firstport); -- void (*device_destroy)(USBBus *bus, USBDevice *dev); - }; - - void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host); --- -1.7.5.1 - diff --git a/0031-char-Throttle-when-host-connection-is-down.patch b/0007-char-Throttle-when-host-connection-is-down.patch similarity index 88% rename from 0031-char-Throttle-when-host-connection-is-down.patch rename to 0007-char-Throttle-when-host-connection-is-down.patch index a60c0e7..edfd98e 100644 --- a/0031-char-Throttle-when-host-connection-is-down.patch +++ b/0007-char-Throttle-when-host-connection-is-down.patch @@ -1,7 +1,7 @@ -From 00cf9482be18cdacda0ae9b207b84a7e86ca1d11 Mon Sep 17 00:00:00 2001 +From 7e19009aa497ae5bc2da8dfedb956f8a705698f1 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 22:05:10 +0100 -Subject: [PATCH 31/35] char: Throttle when host connection is down# +Subject: [PATCH 07/13] char: Throttle when host connection is down# When the host-side connection goes down, throttle the virtio-serial bus and later unthrottle when a connection gets established. This helps @@ -20,7 +20,7 @@ Signed-off-by: Amit Shah 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/qemu-char.c b/qemu-char.c -index e9d7f0a..77ab1ed 100644 +index d811f2a..111fdc8 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -140,6 +140,9 @@ static void qemu_chr_generic_open_bh(void *opaque) @@ -33,7 +33,7 @@ index e9d7f0a..77ab1ed 100644 qemu_bh_delete(s->bh); s->bh = NULL; } -@@ -2031,6 +2034,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +@@ -2059,6 +2062,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) ret = send_all(chr, s->fd, buf, len); if (ret == -1 && errno == EPIPE) { tcp_closed(chr); diff --git a/0007-usb-ehci-drop-unused-num-ports-state-member.patch b/0007-usb-ehci-drop-unused-num-ports-state-member.patch deleted file mode 100644 index 7ea28e7..0000000 --- a/0007-usb-ehci-drop-unused-num-ports-state-member.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 788de57b67ba5e14d965edb542eb58ed4603faf8 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 17 Jun 2011 15:26:29 +0200 -Subject: [PATCH 07/35] usb-ehci: drop unused num-ports state member - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 96451f3..87e1de3 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -373,7 +373,6 @@ struct EHCIState { - qemu_irq irq; - target_phys_addr_t mem_base; - int mem; -- int num_ports; - - /* properties */ - uint32_t freq; --- -1.7.5.1 - diff --git a/0008-usb-ehci-Connect-Status-bit-is-read-only-don-t-allow.patch b/0008-usb-ehci-Connect-Status-bit-is-read-only-don-t-allow.patch deleted file mode 100644 index 7ebbdaf..0000000 --- a/0008-usb-ehci-Connect-Status-bit-is-read-only-don-t-allow.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f7e7c102ed1c3ff7790c84f8bb9d379ad6405d6b Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 21 Jun 2011 12:12:35 +0200 -Subject: [PATCH 08/35] usb-ehci: Connect Status bit is read only, don't allow - changing it by the guest - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 87e1de3..ce1a432 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -103,10 +103,10 @@ - #define PORTSC_BEGIN PORTSC - #define PORTSC_END (PORTSC + 4 * NB_PORTS) - /* -- * Bits that are reserverd or are read-only are masked out of values -+ * Bits that are reserved or are read-only are masked out of values - * written to us by software - */ --#define PORTSC_RO_MASK 0x007021c5 -+#define PORTSC_RO_MASK 0x007021c4 - #define PORTSC_RWC_MASK 0x0000002a - #define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable - #define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable --- -1.7.5.1 - diff --git a/0032-virtio-console-Enable-port-throttling-when-chardev-i.patch b/0008-virtio-console-Enable-port-throttling-when-chardev-i.patch similarity index 83% rename from 0032-virtio-console-Enable-port-throttling-when-chardev-i.patch rename to 0008-virtio-console-Enable-port-throttling-when-chardev-i.patch index 4d130a8..a3c07df 100644 --- a/0032-virtio-console-Enable-port-throttling-when-chardev-i.patch +++ b/0008-virtio-console-Enable-port-throttling-when-chardev-i.patch @@ -1,7 +1,7 @@ -From ba203585e61d1fbe6ba45683d958d261678641ad Mon Sep 17 00:00:00 2001 +From badc85629db4d774f3b5b41070474bd5479d5be3 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 21 Mar 2011 22:06:41 +0100 -Subject: [PATCH 32/35] virtio-console: Enable port throttling when chardev is +Subject: [PATCH 08/13] virtio-console: Enable port throttling when chardev is slow to consume data When a chardev indicates it can't accept more data, we tell the @@ -16,10 +16,10 @@ Signed-off-by: Amit Shah 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c -index 147a467..9286f6e 100644 +index cfc3087..b91f46e 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c -@@ -19,6 +19,16 @@ typedef struct VirtConsole { +@@ -20,6 +20,16 @@ typedef struct VirtConsole { CharDriverState *chr; } VirtConsole; @@ -36,7 +36,7 @@ index 147a467..9286f6e 100644 /* Callback function that's called when the guest sends us data */ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) -@@ -78,6 +88,7 @@ static const QemuChrHandlers chr_handlers = { +@@ -99,6 +109,7 @@ static const QemuChrHandlers chr_handlers = { .fd_can_read = chr_can_read, .fd_read = chr_read, .fd_event = chr_event, diff --git a/0033-spice-qemu-char.c-add-throttling.patch b/0009-spice-qemu-char.c-add-throttling.patch similarity index 95% rename from 0033-spice-qemu-char.c-add-throttling.patch rename to 0009-spice-qemu-char.c-add-throttling.patch index 0696f81..7c2b68b 100644 --- a/0033-spice-qemu-char.c-add-throttling.patch +++ b/0009-spice-qemu-char.c-add-throttling.patch @@ -1,7 +1,7 @@ -From 7322ad318ecde8669e68ef1314e97b4553a327fa Mon Sep 17 00:00:00 2001 +From 433a034b4ee87fe228be4e7f7e4399101d1e33c8 Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Tue, 22 Mar 2011 12:27:59 +0200 -Subject: [PATCH 33/35] spice-qemu-char.c: add throttling +Subject: [PATCH 09/13] spice-qemu-char.c: add throttling BZ: 672191 @@ -39,7 +39,7 @@ is reworked to use glib. 1 files changed, 35 insertions(+), 4 deletions(-) diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index 605c241..9348f65 100644 +index 95bf6b6..0f72e91 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -1,4 +1,6 @@ @@ -120,7 +120,7 @@ index 605c241..9348f65 100644 } static void spice_chr_close(struct CharDriverState *chr) -@@ -196,6 +226,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) +@@ -196,6 +226,7 @@ int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr) chr->chr_close = spice_chr_close; chr->chr_guest_open = spice_chr_guest_open; chr->chr_guest_close = spice_chr_guest_close; diff --git a/0009-usb-ehci-cleanup-port-reset-handling.patch b/0009-usb-ehci-cleanup-port-reset-handling.patch deleted file mode 100644 index 2651396..0000000 --- a/0009-usb-ehci-cleanup-port-reset-handling.patch +++ /dev/null @@ -1,38 +0,0 @@ -From afada27ad05658aae93aa8beab34b1b6885f63b9 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 21 Jun 2011 12:23:40 +0200 -Subject: [PATCH 09/35] usb-ehci: cleanup port reset handling - -Doing a usb_attach when dev is NULL will just result in the -port detach op getting called even though nothing was connected in -the first place. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 7 +------ - 1 files changed, 1 insertions(+), 6 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index ce1a432..d85e0a9 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -863,14 +863,9 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val) - - if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) { - trace_usb_ehci_port_reset(port, 0); -- usb_attach(&s->ports[port], dev); -- -- // TODO how to handle reset of ports with no device - if (dev) { -+ usb_attach(&s->ports[port], dev); - usb_send_msg(dev, USB_MSG_RESET); -- } -- -- if (s->ports[port].dev) { - *portsc &= ~PORTSC_CSC; - } - --- -1.7.5.1 - diff --git a/0034-spice-qemu-char.c-remove-intermediate-buffer.patch b/0010-spice-qemu-char.c-remove-intermediate-buffer.patch similarity index 94% rename from 0034-spice-qemu-char.c-remove-intermediate-buffer.patch rename to 0010-spice-qemu-char.c-remove-intermediate-buffer.patch index c2a5c69..3999246 100644 --- a/0034-spice-qemu-char.c-remove-intermediate-buffer.patch +++ b/0010-spice-qemu-char.c-remove-intermediate-buffer.patch @@ -1,7 +1,7 @@ -From 8b7c5738faa2c7851ecc92182467a564bf7c9109 Mon Sep 17 00:00:00 2001 +From 7735740bd0c9f2d9585c64cc5f975dd03f2a7c11 Mon Sep 17 00:00:00 2001 From: Alon Levy Date: Tue, 22 Mar 2011 12:28:00 +0200 -Subject: [PATCH 34/35] spice-qemu-char.c: remove intermediate buffer +Subject: [PATCH 10/13] spice-qemu-char.c: remove intermediate buffer BZ: 672191 upstream: not submitted (explained below) @@ -20,7 +20,7 @@ can't go upstream right now as explained in that patch. 1 files changed, 6 insertions(+), 12 deletions(-) diff --git a/spice-qemu-char.c b/spice-qemu-char.c -index 9348f65..ce75e91 100644 +index 0f72e91..2b8aec4 100644 --- a/spice-qemu-char.c +++ b/spice-qemu-char.c @@ -23,9 +23,8 @@ typedef struct SpiceCharDriver { diff --git a/0010-usb-assert-on-calling-usb_attach-port-NULL-on-a-port.patch b/0010-usb-assert-on-calling-usb_attach-port-NULL-on-a-port.patch deleted file mode 100644 index 8b86aed..0000000 --- a/0010-usb-assert-on-calling-usb_attach-port-NULL-on-a-port.patch +++ /dev/null @@ -1,44 +0,0 @@ -From a7466b2ff8e1cbdf3abf08a935c3b6c19303ffc2 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 14:26:18 +0200 -Subject: [PATCH 10/35] usb: assert on calling usb_attach(port, NULL) on a - port without a dev - -with the "usb-ehci: cleanup port reset handling" patch in place no callers -are calling usb_attach(port, NULL) for a port where port->dev is NULL. - -Doing that makes no sense as that causes the port detach op to get called -for a port with nothing attached. Add an assert that port->dev != NULL when -dev == NULL, and remove the check for not having a port->dev in the dev == NULL -case. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb.c | 9 ++++----- - 1 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/hw/usb.c b/hw/usb.c -index 735ffd1..27a983c 100644 ---- a/hw/usb.c -+++ b/hw/usb.c -@@ -40,12 +40,11 @@ void usb_attach(USBPort *port, USBDevice *dev) - } else { - /* detach */ - dev = port->dev; -+ assert(dev); - port->ops->detach(port); -- if (dev) { -- usb_send_msg(dev, USB_MSG_DETACH); -- dev->port = NULL; -- port->dev = NULL; -- } -+ usb_send_msg(dev, USB_MSG_DETACH); -+ dev->port = NULL; -+ port->dev = NULL; - } - } - --- -1.7.5.1 - diff --git a/0011-usb-ehci-Fix-handling-of-PED-and-PEDC-port-status-bi.patch b/0011-usb-ehci-Fix-handling-of-PED-and-PEDC-port-status-bi.patch deleted file mode 100644 index 6978540..0000000 --- a/0011-usb-ehci-Fix-handling-of-PED-and-PEDC-port-status-bi.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 555ef05ebba2bf68abace047e39b12de75b71181 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 14:36:13 +0200 -Subject: [PATCH 11/35] usb-ehci: Fix handling of PED and PEDC port status - bits - -The PED bit should only be set for highspeed devices and the PEDC bit -should not be set on "normal" PED bit changes, only on io errors. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 24 +++++++++++------------- - 1 files changed, 11 insertions(+), 13 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index d85e0a9..973c342 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -106,7 +106,7 @@ - * Bits that are reserved or are read-only are masked out of values - * written to us by software - */ --#define PORTSC_RO_MASK 0x007021c4 -+#define PORTSC_RO_MASK 0x007021c0 - #define PORTSC_RWC_MASK 0x0000002a - #define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable - #define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable -@@ -752,7 +752,7 @@ static void ehci_detach(USBPort *port) - - ehci_queues_rip_device(s, port->dev); - -- *portsc &= ~PORTSC_CONNECT; -+ *portsc &= ~(PORTSC_CONNECT|PORTSC_PED); - *portsc |= PORTSC_CSC; - - /* -@@ -847,16 +847,14 @@ static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val) - static void handle_port_status_write(EHCIState *s, int port, uint32_t val) - { - uint32_t *portsc = &s->portsc[port]; -- int rwc; - USBDevice *dev = s->ports[port].dev; - -- rwc = val & PORTSC_RWC_MASK; -+ /* Clear rwc bits */ -+ *portsc &= ~(val & PORTSC_RWC_MASK); -+ /* The guest may clear, but not set the PED bit */ -+ *portsc &= val | ~PORTSC_PED; - val &= PORTSC_RO_MASK; - -- // handle_read_write_clear(&val, portsc, PORTSC_PEDC | PORTSC_CSC); -- -- *portsc &= ~rwc; -- - if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) { - trace_usb_ehci_port_reset(port, 1); - } -@@ -869,13 +867,13 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val) - *portsc &= ~PORTSC_CSC; - } - -- /* Table 2.16 Set the enable bit(and enable bit change) to indicate -+ /* -+ * Table 2.16 Set the enable bit(and enable bit change) to indicate - * to SW that this port has a high speed device attached -- * -- * TODO - when to disable? - */ -- val |= PORTSC_PED; -- val |= PORTSC_PEDC; -+ if (dev && (dev->speedmask & USB_SPEED_MASK_HIGH)) { -+ val |= PORTSC_PED; -+ } - } - - *portsc &= ~PORTSC_RO_MASK; --- -1.7.5.1 - diff --git a/0035-usb-redir-Add-flow-control-support.patch b/0011-usb-redir-Add-flow-control-support.patch similarity index 92% rename from 0035-usb-redir-Add-flow-control-support.patch rename to 0011-usb-redir-Add-flow-control-support.patch index c03c813..f23ad36 100644 --- a/0035-usb-redir-Add-flow-control-support.patch +++ b/0011-usb-redir-Add-flow-control-support.patch @@ -1,7 +1,7 @@ -From f7f2f55e2a8beb68fc81c1def7a0a4436664ed97 Mon Sep 17 00:00:00 2001 +From 2b797647b4a85a765bfdd8f4539d1fa10daad4fa Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 19 Jul 2011 10:56:19 +0200 -Subject: [PATCH 35/35] usb-redir: Add flow control support +Subject: [PATCH 11/13] usb-redir: Add flow control support Signed-off-by: Hans de Goede --- diff --git a/0012-usb-ehci-Add-support-for-registering-companion-contr.patch b/0012-usb-ehci-Add-support-for-registering-companion-contr.patch deleted file mode 100644 index 527a1bc..0000000 --- a/0012-usb-ehci-Add-support-for-registering-companion-contr.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 692f238a2abea35607bc8c9e76d26ae5b15518da Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 16:18:13 +0200 -Subject: [PATCH 12/35] usb-ehci: Add support for registering companion - controllers - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++---------- - 1 files changed, 144 insertions(+), 30 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 973c342..ec68c29 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -20,9 +20,6 @@ - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . -- * -- * TODO: -- * o Downstream port handoff - */ - - #include "hw.h" -@@ -106,7 +103,7 @@ - * Bits that are reserved or are read-only are masked out of values - * written to us by software - */ --#define PORTSC_RO_MASK 0x007021c0 -+#define PORTSC_RO_MASK 0x007001c0 - #define PORTSC_RWC_MASK 0x0000002a - #define PORTSC_WKOC_E (1 << 22) // Wake on Over Current Enable - #define PORTSC_WKDS_E (1 << 21) // Wake on Disconnect Enable -@@ -373,6 +370,7 @@ struct EHCIState { - qemu_irq irq; - target_phys_addr_t mem_base; - int mem; -+ int companion_count; - - /* properties */ - uint32_t freq; -@@ -408,6 +406,7 @@ struct EHCIState { - int astate; // Current state in asynchronous schedule - int pstate; // Current state in periodic schedule - USBPort ports[NB_PORTS]; -+ USBPort *companion_ports[NB_PORTS]; - uint32_t usbsts_pending; - QTAILQ_HEAD(, EHCIQueue) queues; - -@@ -730,17 +729,17 @@ static void ehci_attach(USBPort *port) - - trace_usb_ehci_port_attach(port->index, port->dev->product_desc); - -+ if (*portsc & PORTSC_POWNER) { -+ USBPort *companion = s->companion_ports[port->index]; -+ companion->dev = port->dev; -+ companion->ops->attach(companion); -+ return; -+ } -+ - *portsc |= PORTSC_CONNECT; - *portsc |= PORTSC_CSC; - -- /* -- * If a high speed device is attached then we own this port(indicated -- * by zero in the PORTSC_POWNER bit field) so set the status bit -- * and set an interrupt if enabled. -- */ -- if ( !(*portsc & PORTSC_POWNER)) { -- ehci_set_interrupt(s, USBSTS_PCD); -- } -+ ehci_set_interrupt(s, USBSTS_PCD); - } - - static void ehci_detach(USBPort *port) -@@ -750,36 +749,110 @@ static void ehci_detach(USBPort *port) - - trace_usb_ehci_port_detach(port->index); - -+ if (*portsc & PORTSC_POWNER) { -+ USBPort *companion = s->companion_ports[port->index]; -+ companion->ops->detach(companion); -+ companion->dev = NULL; -+ return; -+ } -+ - ehci_queues_rip_device(s, port->dev); - - *portsc &= ~(PORTSC_CONNECT|PORTSC_PED); - *portsc |= PORTSC_CSC; - -- /* -- * If a high speed device is attached then we own this port(indicated -- * by zero in the PORTSC_POWNER bit field) so set the status bit -- * and set an interrupt if enabled. -- */ -- if ( !(*portsc & PORTSC_POWNER)) { -- ehci_set_interrupt(s, USBSTS_PCD); -- } -+ ehci_set_interrupt(s, USBSTS_PCD); - } - - static void ehci_child_detach(USBPort *port, USBDevice *child) - { - EHCIState *s = port->opaque; -+ uint32_t portsc = s->portsc[port->index]; -+ -+ if (portsc & PORTSC_POWNER) { -+ USBPort *companion = s->companion_ports[port->index]; -+ companion->ops->child_detach(companion, child); -+ companion->dev = NULL; -+ return; -+ } - - ehci_queues_rip_device(s, child); - } - -+static void ehci_wakeup(USBPort *port) -+{ -+ EHCIState *s = port->opaque; -+ uint32_t portsc = s->portsc[port->index]; -+ -+ if (portsc & PORTSC_POWNER) { -+ USBPort *companion = s->companion_ports[port->index]; -+ if (companion->ops->wakeup) { -+ companion->ops->wakeup(companion); -+ } -+ } -+} -+ -+static int ehci_register_companion(USBBus *bus, USBPort *ports[], -+ uint32_t portcount, uint32_t firstport) -+{ -+ EHCIState *s = container_of(bus, EHCIState, bus); -+ uint32_t i; -+ -+ if (firstport + portcount > NB_PORTS) { -+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "firstport", -+ "firstport on masterbus"); -+ error_printf_unless_qmp( -+ "firstport value of %u makes companion take ports %u - %u, which " -+ "is outside of the valid range of 0 - %u\n", firstport, firstport, -+ firstport + portcount - 1, NB_PORTS - 1); -+ return -1; -+ } -+ -+ for (i = 0; i < portcount; i++) { -+ if (s->companion_ports[firstport + i]) { -+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "masterbus", -+ "an USB masterbus"); -+ error_printf_unless_qmp( -+ "port %u on masterbus %s already has a companion assigned\n", -+ firstport + i, bus->qbus.name); -+ return -1; -+ } -+ } -+ -+ for (i = 0; i < portcount; i++) { -+ s->companion_ports[firstport + i] = ports[i]; -+ s->ports[firstport + i].speedmask |= -+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL; -+ /* Ensure devs attached before the initial reset go to the companion */ -+ s->portsc[firstport + i] = PORTSC_POWNER; -+ } -+ -+ s->companion_count++; -+ s->mmio[0x05] = (s->companion_count << 4) | portcount; -+ -+ return 0; -+} -+ - /* 4.1 host controller initialization */ - static void ehci_reset(void *opaque) - { - EHCIState *s = opaque; - int i; -+ USBDevice *devs[NB_PORTS]; - - trace_usb_ehci_reset(); - -+ /* -+ * Do the detach before touching portsc, so that it correctly gets send to -+ * us or to our companion based on PORTSC_POWNER before the reset. -+ */ -+ for(i = 0; i < NB_PORTS; i++) { -+ devs[i] = s->ports[i].dev; -+ if (devs[i]) { -+ usb_attach(&s->ports[i], NULL); -+ } -+ } -+ - memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE); - - s->usbcmd = NB_MAXINTRATE << USBCMD_ITC_SH; -@@ -791,10 +864,13 @@ static void ehci_reset(void *opaque) - s->attach_poll_counter = 0; - - for(i = 0; i < NB_PORTS; i++) { -- s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER; -- -- if (s->ports[i].dev) { -- usb_attach(&s->ports[i], s->ports[i].dev); -+ if (s->companion_ports[i]) { -+ s->portsc[i] = PORTSC_POWNER | PORTSC_PPOWER; -+ } else { -+ s->portsc[i] = PORTSC_PPOWER; -+ } -+ if (devs[i]) { -+ usb_attach(&s->ports[i], devs[i]); - } - } - ehci_queues_rip_all(s); -@@ -844,6 +920,34 @@ static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val) - exit(1); - } - -+static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner) -+{ -+ USBDevice *dev = s->ports[port].dev; -+ uint32_t *portsc = &s->portsc[port]; -+ uint32_t orig; -+ -+ if (s->companion_ports[port] == NULL) -+ return; -+ -+ owner = owner & PORTSC_POWNER; -+ orig = *portsc & PORTSC_POWNER; -+ -+ if (!(owner ^ orig)) { -+ return; -+ } -+ -+ if (dev) { -+ usb_attach(&s->ports[port], NULL); -+ } -+ -+ *portsc &= ~PORTSC_POWNER; -+ *portsc |= owner; -+ -+ if (dev) { -+ usb_attach(&s->ports[port], dev); -+ } -+} -+ - static void handle_port_status_write(EHCIState *s, int port, uint32_t val) - { - uint32_t *portsc = &s->portsc[port]; -@@ -853,6 +957,9 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val) - *portsc &= ~(val & PORTSC_RWC_MASK); - /* The guest may clear, but not set the PED bit */ - *portsc &= val | ~PORTSC_PED; -+ /* POWNER is masked out by RO_MASK as it is RO when we've no companion */ -+ handle_port_owner_write(s, port, val); -+ /* And finally apply RO_MASK */ - val &= PORTSC_RO_MASK; - - if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) { -@@ -956,7 +1063,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) - val &= 0x1; - if (val) { - for(i = 0; i < NB_PORTS; i++) -- s->portsc[i] &= ~PORTSC_POWNER; -+ handle_port_owner_write(s, i, 0); - } - break; - -@@ -1114,8 +1221,17 @@ static int ehci_buffer_rw(EHCIQueue *q, int bytes, int rw) - - static void ehci_async_complete_packet(USBPort *port, USBPacket *packet) - { -- EHCIQueue *q = container_of(packet, EHCIQueue, packet); -+ EHCIQueue *q; -+ EHCIState *s = port->opaque; -+ uint32_t portsc = s->portsc[port->index]; -+ -+ if (portsc & PORTSC_POWNER) { -+ USBPort *companion = s->companion_ports[port->index]; -+ companion->ops->complete(companion, packet); -+ return; -+ } - -+ q = container_of(packet, EHCIQueue, packet); - trace_usb_ehci_queue_action(q, "wakeup"); - assert(q->async == EHCI_ASYNC_INFLIGHT); - q->async = EHCI_ASYNC_FINISHED; -@@ -1245,8 +1361,6 @@ static int ehci_execute(EHCIQueue *q) - port = &q->ehci->ports[i]; - dev = port->dev; - -- // TODO sometime we will also need to check if we are the port owner -- - if (!(q->ehci->portsc[i] &(PORTSC_CONNECT))) { - DPRINTF("Port %d, no exec, not connected(%08X)\n", - i, q->ehci->portsc[i]); -@@ -1339,8 +1453,6 @@ static int ehci_process_itd(EHCIState *ehci, - port = &ehci->ports[j]; - dev = port->dev; - -- // TODO sometime we will also need to check if we are the port owner -- - if (!(ehci->portsc[j] &(PORTSC_CONNECT))) { - continue; - } -@@ -2124,10 +2236,12 @@ static USBPortOps ehci_port_ops = { - .attach = ehci_attach, - .detach = ehci_detach, - .child_detach = ehci_child_detach, -+ .wakeup = ehci_wakeup, - .complete = ehci_async_complete_packet, - }; - - static USBBusOps ehci_bus_ops = { -+ .register_companion = ehci_register_companion, - }; - - static PCIDeviceInfo ehci_info = { --- -1.7.5.1 - diff --git a/0012-usb-redir-Call-qemu_chr_guest_open-close.patch b/0012-usb-redir-Call-qemu_chr_guest_open-close.patch new file mode 100644 index 0000000..bcf6f9c --- /dev/null +++ b/0012-usb-redir-Call-qemu_chr_guest_open-close.patch @@ -0,0 +1,37 @@ +From 824ab3383370291885f1a18978018a41cfac7ee8 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 21 Jul 2011 16:28:06 +0200 +Subject: [PATCH 12/13] usb-redir: Call qemu_chr_guest_open/close + +To let the chardev now we're ready start receiving data. This is necessary +with the spicevmc chardev to get it registered with the spice-server. + +Signed-off-by: Hans de Goede +--- + usb-redir.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/usb-redir.c b/usb-redir.c +index 6932beb..d1aafda 100644 +--- a/usb-redir.c ++++ b/usb-redir.c +@@ -840,6 +840,8 @@ static int usbredir_initfn(USBDevice *udev) + udev->auto_attach = 0; + + qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev); ++ /* Let the other side know we are ready */ ++ qemu_chr_guest_open(dev->cs); + + return 0; + } +@@ -861,6 +863,7 @@ static void usbredir_handle_destroy(USBDevice *udev) + { + USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); + ++ qemu_chr_guest_close(dev->cs); + qemu_chr_close(dev->cs); + /* Note must be done after qemu_chr_close, as that causes a close event */ + qemu_bh_delete(dev->open_close_bh); +-- +1.7.5.1 + diff --git a/0013-spice-qemu-char-Generate-chardev-open-close-events.patch b/0013-spice-qemu-char-Generate-chardev-open-close-events.patch new file mode 100644 index 0000000..2ba39ad --- /dev/null +++ b/0013-spice-qemu-char-Generate-chardev-open-close-events.patch @@ -0,0 +1,90 @@ +From 5149f056bd4fbeeb0ce3b850febe213a305a348b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 21 Jul 2011 15:36:40 +0200 +Subject: [PATCH 13/13] spice-qemu-char: Generate chardev open/close events + +Define a state callback and make that generate chardev open/close events when +called by the spice-server. + +Note that for all but the newest spice-server versions (which have a fix for +this) the code ignores these events for a spicevmc with a subtype of vdagent, +this subtype specific knowledge is undesirable, but unavoidable for now, see: +http://lists.freedesktop.org/archives/spice-devel/2011-July/004837.html + +Signed-off-by: Hans de Goede +--- + spice-qemu-char.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 45 insertions(+), 1 deletions(-) + +diff --git a/spice-qemu-char.c b/spice-qemu-char.c +index 2b8aec4..1f4f1ec 100644 +--- a/spice-qemu-char.c ++++ b/spice-qemu-char.c +@@ -89,11 +89,50 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) + return bytes; + } + ++static void vmc_state(SpiceCharDeviceInstance *sin, int connected) ++{ ++ SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); ++ int event; ++ ++#if SPICE_SERVER_VERSION < 0x000901 ++ /* ++ * spice-server calls the state callback for the agent channel when the ++ * spice client connects / disconnects. Given that not the client but ++ * the server is doing the parsing of the messages this is wrong as the ++ * server is still listening. Worse, this causes the parser in the server ++ * to go out of sync, so we ignore state calls for subtype vdagent ++ * spicevmc chardevs. For the full story see: ++ * http://lists.freedesktop.org/archives/spice-devel/2011-July/004837.html ++ */ ++ if (strcmp(sin->subtype, "vdagent") == 0) { ++ return; ++ } ++#endif ++ ++ if ((scd->chr->opened && connected) || ++ (!scd->chr->opened && !connected)) { ++ return; ++ } ++ ++ if (connected) { ++ scd->chr->opened = 1; ++ event = CHR_EVENT_OPENED; ++ } else { ++ scd->chr->opened = 0; ++ event = CHR_EVENT_CLOSED; ++ } ++ ++ if (scd->chr->chr_event) { ++ scd->chr->chr_event(scd->chr->handler_opaque, event); ++ } ++} ++ + static SpiceCharDeviceInterface vmc_interface = { + .base.type = SPICE_INTERFACE_CHAR_DEVICE, + .base.description = "spice virtual channel char device", + .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR, + .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR, ++ .state = vmc_state, + .write = vmc_write, + .read = vmc_read, + }; +@@ -222,7 +261,12 @@ int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr) + chr->chr_guest_close = spice_chr_guest_close; + s->unblock_timer = qemu_new_timer_ms(vm_clock, spice_chr_unblock, s); + +- qemu_chr_generic_open(chr); ++#if SPICE_SERVER_VERSION < 0x000901 ++ /* See comment in vmc_state() */ ++ if (strcmp(subtype, "vdagent") == 0) { ++ qemu_chr_generic_open(chr); ++ } ++#endif + + *_chr = chr; + return 0; +-- +1.7.5.1 + diff --git a/0013-usb-uhci-Add-support-for-being-a-companion-controlle.patch b/0013-usb-uhci-Add-support-for-being-a-companion-controlle.patch deleted file mode 100644 index bb28f62..0000000 --- a/0013-usb-uhci-Add-support-for-being-a-companion-controlle.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 850d218026df41324430af62063f68afe652a7ac Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 17:44:53 +0200 -Subject: [PATCH 13/35] usb-uhci: Add support for being a companion controller - -To use as a companion controller set the masterbus property. - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-uhci.c | 41 ++++++++++++++++++++++++++++++++++++----- - 1 files changed, 36 insertions(+), 5 deletions(-) - -diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c -index a46d61a..925c03b 100644 ---- a/hw/usb-uhci.c -+++ b/hw/usb-uhci.c -@@ -132,7 +132,7 @@ typedef struct UHCIPort { - - struct UHCIState { - PCIDevice dev; -- USBBus bus; -+ USBBus bus; /* Note unused when we're a companion controller */ - uint16_t cmd; /* cmd register */ - uint16_t status; - uint16_t intr; /* interrupt enable register */ -@@ -150,6 +150,10 @@ struct UHCIState { - /* Active packets */ - QTAILQ_HEAD(,UHCIAsync) async_pending; - uint8_t num_ports_vmstate; -+ -+ /* Properties */ -+ char *masterbus; -+ uint32_t firstport; - }; - - typedef struct UHCI_TD { -@@ -1126,10 +1130,22 @@ static int usb_uhci_common_initfn(PCIDevice *dev) - pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3 - pci_conf[USB_SBRN] = USB_RELEASE_1; // release number - -- usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev); -- for(i = 0; i < NB_PORTS; i++) { -- usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, -- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -+ if (s->masterbus) { -+ USBPort *ports[NB_PORTS]; -+ for(i = 0; i < NB_PORTS; i++) { -+ ports[i] = &s->ports[i].port; -+ } -+ if (usb_register_companion(s->masterbus, ports, NB_PORTS, -+ s->firstport, s, &uhci_port_ops, -+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { -+ return -1; -+ } -+ } else { -+ usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev); -+ for (i = 0; i < NB_PORTS; i++) { -+ usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops, -+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -+ } - } - s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s); - s->num_ports_vmstate = NB_PORTS; -@@ -1170,6 +1186,11 @@ static PCIDeviceInfo uhci_info[] = { - .device_id = PCI_DEVICE_ID_INTEL_82371SB_2, - .revision = 0x01, - .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -+ DEFINE_PROP_END_OF_LIST(), -+ }, - },{ - .qdev.name = "piix4-usb-uhci", - .qdev.size = sizeof(UHCIState), -@@ -1179,6 +1200,11 @@ static PCIDeviceInfo uhci_info[] = { - .device_id = PCI_DEVICE_ID_INTEL_82371AB_2, - .revision = 0x01, - .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -+ DEFINE_PROP_END_OF_LIST(), -+ }, - },{ - .qdev.name = "vt82c686b-usb-uhci", - .qdev.size = sizeof(UHCIState), -@@ -1188,6 +1214,11 @@ static PCIDeviceInfo uhci_info[] = { - .device_id = PCI_DEVICE_ID_VIA_UHCI, - .revision = 0x01, - .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -+ DEFINE_PROP_END_OF_LIST(), -+ }, - },{ - /* end of list */ - } --- -1.7.5.1 - diff --git a/0014-usb-ohci-Add-support-for-being-a-companion-controlle.patch b/0014-usb-ohci-Add-support-for-being-a-companion-controlle.patch deleted file mode 100644 index e0688bf..0000000 --- a/0014-usb-ohci-Add-support-for-being-a-companion-controlle.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 90ac519e89c71ac9f9731b21cef510b5cbaee38b Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 24 Jun 2011 20:29:05 +0200 -Subject: [PATCH 14/35] usb-ohci: Add support for being a companion controller - -To use as a companion controller, use pci-ohci as device and set the -masterbus and num-ports properties, ie: - --device usb-ehci,addr=0b.1,multifunction=on,id=ehci0 --device pci-ohci,addr=0b.0,multifunction=on,masterbus=ehci0.0,num-ports=4 - -Signed-off-by: Hans de Goede -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ohci.c | 52 ++++++++++++++++++++++++++++++++++++++++------------ - 1 files changed, 40 insertions(+), 12 deletions(-) - -diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c -index 46f0bcb..c77a20e 100644 ---- a/hw/usb-ohci.c -+++ b/hw/usb-ohci.c -@@ -1716,8 +1716,9 @@ static USBPortOps ohci_port_ops = { - static USBBusOps ohci_bus_ops = { - }; - --static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, -- int num_ports, uint32_t localmem_base) -+static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, -+ int num_ports, uint32_t localmem_base, -+ char *masterbus, uint32_t firstport) - { - int i; - -@@ -1737,38 +1738,58 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, - usb_frame_time, usb_bit_time); - } - -+ ohci->num_ports = num_ports; -+ if (masterbus) { -+ USBPort *ports[OHCI_MAX_PORTS]; -+ for(i = 0; i < num_ports; i++) { -+ ports[i] = &ohci->rhport[i].port; -+ } -+ if (usb_register_companion(masterbus, ports, num_ports, -+ firstport, ohci, &ohci_port_ops, -+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { -+ return -1; -+ } -+ } else { -+ usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); -+ for (i = 0; i < num_ports; i++) { -+ usb_register_port(&ohci->bus, &ohci->rhport[i].port, -+ ohci, i, &ohci_port_ops, -+ USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -+ } -+ } -+ - ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci, - DEVICE_LITTLE_ENDIAN); - ohci->localmem_base = localmem_base; - - ohci->name = dev->info->name; - -- usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); -- ohci->num_ports = num_ports; -- for (i = 0; i < num_ports; i++) { -- usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops, -- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); -- } -- - ohci->async_td = 0; - qemu_register_reset(ohci_reset, ohci); -+ -+ return 0; - } - - typedef struct { - PCIDevice pci_dev; - OHCIState state; -+ char *masterbus; -+ uint32_t num_ports; -+ uint32_t firstport; - } OHCIPCIState; - - static int usb_ohci_initfn_pci(struct PCIDevice *dev) - { - OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev); -- int num_ports = 3; - - ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */ - /* TODO: RST# value should be 0. */ - ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */ - -- usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0); -+ if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0, -+ ohci->masterbus, ohci->firstport) != 0) { -+ return -1; -+ } - ohci->state.irq = ohci->pci_dev.irq[0]; - - /* TODO: avoid cast below by using dev */ -@@ -1792,7 +1813,8 @@ static int ohci_init_pxa(SysBusDevice *dev) - { - OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev); - -- usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset); -+ /* Cannot fail as we pass NULL for masterbus */ -+ usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0); - sysbus_init_irq(dev, &s->ohci.irq); - sysbus_init_mmio(dev, 0x1000, s->ohci.mem); - -@@ -1807,6 +1829,12 @@ static PCIDeviceInfo ohci_pci_info = { - .vendor_id = PCI_VENDOR_ID_APPLE, - .device_id = PCI_DEVICE_ID_APPLE_IPID_USB, - .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus), -+ DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3), -+ DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0), -+ DEFINE_PROP_END_OF_LIST(), -+ }, - }; - - static SysBusDeviceInfo ohci_sysbus_info = { --- -1.7.5.1 - diff --git a/0015-pci-add-ich9-usb-controller-ids.patch b/0015-pci-add-ich9-usb-controller-ids.patch deleted file mode 100644 index 64c6f37..0000000 --- a/0015-pci-add-ich9-usb-controller-ids.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 79a91f584ad187b6f159209b3aff3d3d310e78c2 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 1 Jul 2011 11:45:02 +0200 -Subject: [PATCH 15/35] pci: add ich9 usb controller ids - -Signed-off-by: Gerd Hoffmann ---- - hw/pci_ids.h | 8 ++++++++ - 1 files changed, 8 insertions(+), 0 deletions(-) - -diff --git a/hw/pci_ids.h b/hw/pci_ids.h -index d94578c..927f2b0 100644 ---- a/hw/pci_ids.h -+++ b/hw/pci_ids.h -@@ -109,5 +109,13 @@ - #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 - #define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 - #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 -+#define PCI_DEVICE_ID_INTEL_82801I_UHCI1 0x2934 -+#define PCI_DEVICE_ID_INTEL_82801I_UHCI2 0x2935 -+#define PCI_DEVICE_ID_INTEL_82801I_UHCI3 0x2936 -+#define PCI_DEVICE_ID_INTEL_82801I_UHCI4 0x2937 -+#define PCI_DEVICE_ID_INTEL_82801I_UHCI5 0x2938 -+#define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939 -+#define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a -+#define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c - - #define PCI_VENDOR_ID_XENSOURCE 0x5853 --- -1.7.5.1 - diff --git a/0016-uhci-add-ich9-controllers.patch b/0016-uhci-add-ich9-controllers.patch deleted file mode 100644 index c5b6897..0000000 --- a/0016-uhci-add-ich9-controllers.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 18f499ba7cac5d66f42255f6ddf384e01bead569 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 1 Jul 2011 09:48:49 +0200 -Subject: [PATCH 16/35] uhci: add ich9 controllers - -Add ich9 controllers, Factor out properties to a separate -struct and reference it to reduce duplication. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb-uhci.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- - 1 files changed, 39 insertions(+), 15 deletions(-) - -diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c -index 925c03b..2ef4c5b 100644 ---- a/hw/usb-uhci.c -+++ b/hw/usb-uhci.c -@@ -1176,6 +1176,12 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev) - return usb_uhci_common_initfn(dev); - } - -+static Property uhci_properties[] = { -+ DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -+ DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ - static PCIDeviceInfo uhci_info[] = { - { - .qdev.name = "piix3-usb-uhci", -@@ -1186,11 +1192,7 @@ static PCIDeviceInfo uhci_info[] = { - .device_id = PCI_DEVICE_ID_INTEL_82371SB_2, - .revision = 0x01, - .class_id = PCI_CLASS_SERIAL_USB, -- .qdev.props = (Property[]) { -- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -- DEFINE_PROP_END_OF_LIST(), -- }, -+ .qdev.props = uhci_properties, - },{ - .qdev.name = "piix4-usb-uhci", - .qdev.size = sizeof(UHCIState), -@@ -1200,11 +1202,7 @@ static PCIDeviceInfo uhci_info[] = { - .device_id = PCI_DEVICE_ID_INTEL_82371AB_2, - .revision = 0x01, - .class_id = PCI_CLASS_SERIAL_USB, -- .qdev.props = (Property[]) { -- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -- DEFINE_PROP_END_OF_LIST(), -- }, -+ .qdev.props = uhci_properties, - },{ - .qdev.name = "vt82c686b-usb-uhci", - .qdev.size = sizeof(UHCIState), -@@ -1214,11 +1212,37 @@ static PCIDeviceInfo uhci_info[] = { - .device_id = PCI_DEVICE_ID_VIA_UHCI, - .revision = 0x01, - .class_id = PCI_CLASS_SERIAL_USB, -- .qdev.props = (Property[]) { -- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus), -- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0), -- DEFINE_PROP_END_OF_LIST(), -- }, -+ .qdev.props = uhci_properties, -+ },{ -+ .qdev.name = "ich9-usb-uhci1", -+ .qdev.size = sizeof(UHCIState), -+ .qdev.vmsd = &vmstate_uhci, -+ .init = usb_uhci_common_initfn, -+ .vendor_id = PCI_VENDOR_ID_INTEL, -+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1, -+ .revision = 0x03, -+ .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = uhci_properties, -+ },{ -+ .qdev.name = "ich9-usb-uhci2", -+ .qdev.size = sizeof(UHCIState), -+ .qdev.vmsd = &vmstate_uhci, -+ .init = usb_uhci_common_initfn, -+ .vendor_id = PCI_VENDOR_ID_INTEL, -+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2, -+ .revision = 0x03, -+ .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = uhci_properties, -+ },{ -+ .qdev.name = "ich9-usb-uhci3", -+ .qdev.size = sizeof(UHCIState), -+ .qdev.vmsd = &vmstate_uhci, -+ .init = usb_uhci_common_initfn, -+ .vendor_id = PCI_VENDOR_ID_INTEL, -+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3, -+ .revision = 0x03, -+ .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = uhci_properties, - },{ - /* end of list */ - } --- -1.7.5.1 - diff --git a/0017-ehci-fix-port-count.patch b/0017-ehci-fix-port-count.patch deleted file mode 100644 index 13253f7..0000000 --- a/0017-ehci-fix-port-count.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 62ffcd73894343e42b28eb1c4746ef706bd237b3 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 1 Jul 2011 09:56:43 +0200 -Subject: [PATCH 17/35] ehci: fix port count. - -The ICH4 EHCI controller which we emulate has six ports not four. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index ec68c29..0b959ca 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -130,7 +130,7 @@ - #define FRAME_TIMER_NS (1000000000 / FRAME_TIMER_FREQ) - - #define NB_MAXINTRATE 8 // Max rate at which controller issues ints --#define NB_PORTS 4 // Number of downstream ports -+#define NB_PORTS 6 // Number of downstream ports - #define BUFF_SIZE 5*4096 // Max bytes to transfer per transaction - #define MAX_ITERATIONS 20 // Max number of QH before we break the loop - #define MAX_QH 100 // Max allowable queue heads in a chain --- -1.7.5.1 - diff --git a/0018-ehci-add-ich9-controller.patch b/0018-ehci-add-ich9-controller.patch deleted file mode 100644 index dcf3a56..0000000 --- a/0018-ehci-add-ich9-controller.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 8fe1c377cf894b7071e36e64a206f3b52ea0ab68 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 1 Jul 2011 11:51:02 +0200 -Subject: [PATCH 18/35] ehci: add ich9 controller. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ehci.c | 43 +++++++++++++++++++++++++++++-------------- - 1 files changed, 29 insertions(+), 14 deletions(-) - -diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c -index 0b959ca..a4758f9 100644 ---- a/hw/usb-ehci.c -+++ b/hw/usb-ehci.c -@@ -2244,19 +2244,34 @@ static USBBusOps ehci_bus_ops = { - .register_companion = ehci_register_companion, - }; - --static PCIDeviceInfo ehci_info = { -- .qdev.name = "usb-ehci", -- .qdev.size = sizeof(EHCIState), -- .init = usb_ehci_initfn, -- .vendor_id = PCI_VENDOR_ID_INTEL, -- .device_id = PCI_DEVICE_ID_INTEL_82801D, -- .revision = 0x10, -- .class_id = PCI_CLASS_SERIAL_USB, -- .qdev.props = (Property[]) { -- DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ), -- DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128), -- DEFINE_PROP_END_OF_LIST(), -- }, -+static Property ehci_properties[] = { -+ DEFINE_PROP_UINT32("freq", EHCIState, freq, FRAME_TIMER_FREQ), -+ DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ -+static PCIDeviceInfo ehci_info[] = { -+ { -+ .qdev.name = "usb-ehci", -+ .qdev.size = sizeof(EHCIState), -+ .init = usb_ehci_initfn, -+ .vendor_id = PCI_VENDOR_ID_INTEL, -+ .device_id = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */ -+ .revision = 0x10, -+ .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = ehci_properties, -+ },{ -+ .qdev.name = "ich9-usb-ehci1", -+ .qdev.size = sizeof(EHCIState), -+ .init = usb_ehci_initfn, -+ .vendor_id = PCI_VENDOR_ID_INTEL, -+ .device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1, -+ .revision = 0x03, -+ .class_id = PCI_CLASS_SERIAL_USB, -+ .qdev.props = ehci_properties, -+ },{ -+ /* end of list */ -+ } - }; - - static int usb_ehci_initfn(PCIDevice *dev) -@@ -2335,7 +2350,7 @@ static int usb_ehci_initfn(PCIDevice *dev) - - static void ehci_register(void) - { -- pci_qdev_register(&ehci_info); -+ pci_qdev_register_many(ehci_info); - } - device_init(ehci_register); - --- -1.7.5.1 - diff --git a/0019-usb-update-documentation.patch b/0019-usb-update-documentation.patch deleted file mode 100644 index af65a25..0000000 --- a/0019-usb-update-documentation.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 097e10ae52ea3c4fd2ac9b019a1de9a4649e8f2e Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Tue, 5 Jul 2011 16:58:41 +0200 -Subject: [PATCH 19/35] usb: update documentation - -Add a paragraph on companion controller mode and a -configuration file which sets it all up for you. - -Signed-off-by: Gerd Hoffmann ---- - docs/ich9-ehci-uhci.cfg | 37 +++++++++++++++++++++++++++++++++++++ - docs/usb2.txt | 33 ++++++++++++++++++++++++++++----- - 2 files changed, 65 insertions(+), 5 deletions(-) - create mode 100644 docs/ich9-ehci-uhci.cfg - -diff --git a/docs/ich9-ehci-uhci.cfg b/docs/ich9-ehci-uhci.cfg -new file mode 100644 -index 0000000..a0e9b96 ---- /dev/null -+++ b/docs/ich9-ehci-uhci.cfg -@@ -0,0 +1,37 @@ -+########################################################################### -+# -+# You can pass this file directly to qemu using the -readconfig -+# command line switch. -+# -+# This config file creates a EHCI adapter with companion UHCI -+# controllers as multifunction device in PCI slot "1d". -+# -+# Specify "bus=ehci.0" when creating usb devices to hook them up -+# there. -+# -+ -+[device "ehci"] -+ driver = "ich9-usb-ehci1" -+ addr = "1d.7" -+ multifunction = "on" -+ -+[device "uhci-1"] -+ driver = "ich9-usb-uhci1" -+ addr = "1d.0" -+ multifunction = "on" -+ masterbus = "ehci.0" -+ firstport = "0" -+ -+[device "uhci-2"] -+ driver = "ich9-usb-uhci2" -+ addr = "1d.1" -+ multifunction = "on" -+ masterbus = "ehci.0" -+ firstport = "2" -+ -+[device "uhci-3"] -+ driver = "ich9-usb-uhci3" -+ addr = "1d.2" -+ multifunction = "on" -+ masterbus = "ehci.0" -+ firstport = "4" -diff --git a/docs/usb2.txt b/docs/usb2.txt -index 5950c71..228aa33 100644 ---- a/docs/usb2.txt -+++ b/docs/usb2.txt -@@ -2,11 +2,13 @@ - USB 2.0 Quick Start - =================== - --The QEMU EHCI Adapter does *not* support companion controllers. That --implies there are two completely separate USB busses: One USB 1.1 bus --driven by the UHCI controller and one USB 2.0 bus driven by the EHCI --controller. Devices must be attached to the correct controller --manually. -+The QEMU EHCI Adapter can be used with and without companion -+controllers. See below for the companion controller mode. -+ -+When not running in companion controller mode there are two completely -+separate USB busses: One USB 1.1 bus driven by the UHCI controller and -+one USB 2.0 bus driven by the EHCI controller. Devices must be -+attached to the correct controller manually. - - The '-usb' switch will make qemu create the UHCI controller as part of - the PIIX3 chipset. The USB 1.1 bus will carry the name "usb.0". -@@ -32,6 +34,27 @@ This attaches a usb tablet to the UHCI adapter and a usb mass storage - device to the EHCI adapter. - - -+Companion controller support -+---------------------------- -+ -+Companion controller support has been added recently. The operational -+model described above with two completely separate busses still works -+fine. Additionally the UHCI and OHCI controllers got the ability to -+attach to a usb bus created by EHCI as companion controllers. This is -+done by specifying the masterbus and firstport properties. masterbus -+specifies the bus name the controller should attach to. firstport -+specifies the first port the controller should attach to, which is -+needed as usually one ehci controller with six ports has three uhci -+companion controllers with two ports each. -+ -+There is a config file in docs which will do all this for you, just -+try ... -+ -+ qemu -readconfig docs/ich9-ehci-uhci.cfg -+ -+... then use "bus=ehci.0" to assign your usb devices to that bus. -+ -+ - More USB tips & tricks - ====================== - --- -1.7.5.1 - diff --git a/0020-usb_register_port-do-not-set-port-opaque-and-port-in.patch b/0020-usb_register_port-do-not-set-port-opaque-and-port-in.patch deleted file mode 100644 index ff3d32e..0000000 --- a/0020-usb_register_port-do-not-set-port-opaque-and-port-in.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 88a8f55b17e9e6c78ce620ac91012bfd822f8f04 Mon Sep 17 00:00:00 2001 -From: Jes Sorensen -Date: Mon, 4 Jul 2011 17:33:05 +0200 -Subject: [PATCH 20/35] usb_register_port(): do not set port->opaque and - port->index twice - -Signed-off-by: Jes Sorensen -Signed-off-by: Gerd Hoffmann ---- - hw/usb-bus.c | 2 -- - 1 files changed, 0 insertions(+), 2 deletions(-) - -diff --git a/hw/usb-bus.c b/hw/usb-bus.c -index c8347e9..f1dd55e 100644 ---- a/hw/usb-bus.c -+++ b/hw/usb-bus.c -@@ -143,8 +143,6 @@ static void usb_fill_port(USBPort *port, void *opaque, int index, - { - port->opaque = opaque; - port->index = index; -- port->opaque = opaque; -- port->index = index; - port->ops = ops; - port->speedmask = speedmask; - usb_port_location(port, NULL, index + 1); --- -1.7.5.1 - diff --git a/0021-usb-fixup-bluetooth-descriptors.patch b/0021-usb-fixup-bluetooth-descriptors.patch deleted file mode 100644 index d81d1b2..0000000 --- a/0021-usb-fixup-bluetooth-descriptors.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 1d729b8511fd72f66d7cc10e801a546daa40bb79 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Wed, 6 Jul 2011 12:40:28 +0200 -Subject: [PATCH 21/35] usb: fixup bluetooth descriptors - -Commit 4696425cd05c7baa0a4b469d43ba4b8488bcfc0f changes some -endpoints from isocrounous to interrupt by mistake. Fix it. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb-bt.c | 24 ++++++++++++------------ - 1 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/hw/usb-bt.c b/hw/usb-bt.c -index baae487..e364513 100644 ---- a/hw/usb-bt.c -+++ b/hw/usb-bt.c -@@ -99,13 +99,13 @@ static const USBDescIface desc_iface_bluetooth[] = { - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0, - .bInterval = 0x01, - }, - { - .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0, - .bInterval = 0x01, - }, -@@ -120,13 +120,13 @@ static const USBDescIface desc_iface_bluetooth[] = { - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x09, - .bInterval = 0x01, - }, - { - .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x09, - .bInterval = 0x01, - }, -@@ -141,13 +141,13 @@ static const USBDescIface desc_iface_bluetooth[] = { - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x11, - .bInterval = 0x01, - }, - { - .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x11, - .bInterval = 0x01, - }, -@@ -162,13 +162,13 @@ static const USBDescIface desc_iface_bluetooth[] = { - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x19, - .bInterval = 0x01, - }, - { - .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x19, - .bInterval = 0x01, - }, -@@ -183,13 +183,13 @@ static const USBDescIface desc_iface_bluetooth[] = { - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x21, - .bInterval = 0x01, - }, - { - .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x21, - .bInterval = 0x01, - }, -@@ -204,13 +204,13 @@ static const USBDescIface desc_iface_bluetooth[] = { - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_OUT | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x31, - .bInterval = 0x01, - }, - { - .bEndpointAddress = USB_DIR_IN | USB_SCO_EP, -- .bmAttributes = USB_ENDPOINT_XFER_INT, -+ .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = 0x31, - .bInterval = 0x01, - }, --- -1.7.5.1 - diff --git a/0022-usb-hub-remove-unused-descriptor-arrays.patch b/0022-usb-hub-remove-unused-descriptor-arrays.patch deleted file mode 100644 index 3f5aa9a..0000000 --- a/0022-usb-hub-remove-unused-descriptor-arrays.patch +++ /dev/null @@ -1,95 +0,0 @@ -From d9c7f506bea5ed587ecf2178276e4bf82e370a67 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 7 Jul 2011 15:02:58 +0200 -Subject: [PATCH 22/35] usb-hub: remove unused descriptor arrays - -Somehow they where left over when converting the hub -to the new usb descriptor infrastructure ... - -Signed-off-by: Gerd Hoffmann ---- - hw/usb-hub.c | 68 ---------------------------------------------------------- - 1 files changed, 0 insertions(+), 68 deletions(-) - -diff --git a/hw/usb-hub.c b/hw/usb-hub.c -index b7557ce..b49a2fe 100644 ---- a/hw/usb-hub.c -+++ b/hw/usb-hub.c -@@ -138,74 +138,6 @@ static const USBDesc desc_hub = { - .str = desc_strings, - }; - --static const uint8_t qemu_hub_dev_descriptor[] = { -- 0x12, /* u8 bLength; */ -- 0x01, /* u8 bDescriptorType; Device */ -- 0x10, 0x01, /* u16 bcdUSB; v1.1 */ -- -- 0x09, /* u8 bDeviceClass; HUB_CLASSCODE */ -- 0x00, /* u8 bDeviceSubClass; */ -- 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */ -- 0x08, /* u8 bMaxPacketSize0; 8 Bytes */ -- -- 0x00, 0x00, /* u16 idVendor; */ -- 0x00, 0x00, /* u16 idProduct; */ -- 0x01, 0x01, /* u16 bcdDevice */ -- -- 0x03, /* u8 iManufacturer; */ -- 0x02, /* u8 iProduct; */ -- 0x01, /* u8 iSerialNumber; */ -- 0x01 /* u8 bNumConfigurations; */ --}; -- --/* XXX: patch interrupt size */ --static const uint8_t qemu_hub_config_descriptor[] = { -- -- /* one configuration */ -- 0x09, /* u8 bLength; */ -- 0x02, /* u8 bDescriptorType; Configuration */ -- 0x19, 0x00, /* u16 wTotalLength; */ -- 0x01, /* u8 bNumInterfaces; (1) */ -- 0x01, /* u8 bConfigurationValue; */ -- 0x00, /* u8 iConfiguration; */ -- 0xe0, /* u8 bmAttributes; -- Bit 7: must be set, -- 6: Self-powered, -- 5: Remote wakeup, -- 4..0: resvd */ -- 0x00, /* u8 MaxPower; */ -- -- /* USB 1.1: -- * USB 2.0, single TT organization (mandatory): -- * one interface, protocol 0 -- * -- * USB 2.0, multiple TT organization (optional): -- * two interfaces, protocols 1 (like single TT) -- * and 2 (multiple TT mode) ... config is -- * sometimes settable -- * NOT IMPLEMENTED -- */ -- -- /* one interface */ -- 0x09, /* u8 if_bLength; */ -- 0x04, /* u8 if_bDescriptorType; Interface */ -- 0x00, /* u8 if_bInterfaceNumber; */ -- 0x00, /* u8 if_bAlternateSetting; */ -- 0x01, /* u8 if_bNumEndpoints; */ -- 0x09, /* u8 if_bInterfaceClass; HUB_CLASSCODE */ -- 0x00, /* u8 if_bInterfaceSubClass; */ -- 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ -- 0x00, /* u8 if_iInterface; */ -- -- /* one endpoint (status change endpoint) */ -- 0x07, /* u8 ep_bLength; */ -- 0x05, /* u8 ep_bDescriptorType; Endpoint */ -- 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ -- 0x03, /* u8 ep_bmAttributes; Interrupt */ -- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ -- 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ --}; -- - static const uint8_t qemu_hub_hub_descriptor[] = - { - 0x00, /* u8 bLength; patched in later */ --- -1.7.5.1 - diff --git a/0023-usb-ohci-raise-interrupt-on-attach.patch b/0023-usb-ohci-raise-interrupt-on-attach.patch deleted file mode 100644 index 63dd15d..0000000 --- a/0023-usb-ohci-raise-interrupt-on-attach.patch +++ /dev/null @@ -1,50 +0,0 @@ -From a0559e6445bf2cceba279bf3bcdc062497872db1 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Thu, 7 Jul 2011 15:18:50 +0200 -Subject: [PATCH 23/35] usb-ohci: raise interrupt on attach - -Got lost in commit 618c169b577db64ac6589ad48825d2e11760d1a6, -add it back in. Also fix codestyle while we are at it. - -Signed-off-by: Gerd Hoffmann ---- - hw/usb-ohci.c | 8 +++++++- - 1 files changed, 7 insertions(+), 1 deletions(-) - -diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c -index c77a20e..8491d59 100644 ---- a/hw/usb-ohci.c -+++ b/hw/usb-ohci.c -@@ -327,6 +327,7 @@ static void ohci_attach(USBPort *port1) - { - OHCIState *s = port1->opaque; - OHCIPort *port = &s->rhport[port1->index]; -+ uint32_t old_state = port->ctrl; - - /* set connect status */ - port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC; -@@ -344,6 +345,10 @@ static void ohci_attach(USBPort *port1) - } - - DPRINTF("usb-ohci: Attached port %d\n", port1->index); -+ -+ if (old_state != port->ctrl) { -+ ohci_set_interrupt(s, OHCI_INTR_RHSC); -+ } - } - - static void ohci_detach(USBPort *port1) -@@ -366,8 +371,9 @@ static void ohci_detach(USBPort *port1) - } - DPRINTF("usb-ohci: Detached port %d\n", port1->index); - -- if (old_state != port->ctrl) -+ if (old_state != port->ctrl) { - ohci_set_interrupt(s, OHCI_INTR_RHSC); -+ } - } - - static void ohci_wakeup(USBPort *port1) --- -1.7.5.1 - diff --git a/0024-USB-add-usb-network-redirection-support.patch b/0024-USB-add-usb-network-redirection-support.patch deleted file mode 100644 index 88ebda4..0000000 --- a/0024-USB-add-usb-network-redirection-support.patch +++ /dev/null @@ -1,1346 +0,0 @@ -From 961391dad70649ac54a3011b5f9ba54f44d476e6 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 31 May 2011 14:59:41 +0200 -Subject: [PATCH 24/35] USB: add usb network redirection support - -This patch adds support for a usb-redir device, which takes a chardev -as a communication channel to an actual usbdevice using the usbredir protocol. - -Compiling the usb-redir device requires usbredir-0.3 to be installed for -the usbredir protocol parser, usbredir-0.3 also contains a server for -redirecting usb traffic from an actual usb device. You can get the 0.3 -release of usbredir here: -http://people.fedoraproject.org/~jwrdegoede/usbredir-0.3.tar.bz2 -(getting a more formal site for it is a WIP) - -Example usage: -1) Start usbredirserver for a usb device: -sudo usbredirserver 045e:0772 -2) Start qemu with usb2 support + a chardev talking to usbredirserver + - a usb-redir device using this chardev: -qemu ... \ - -readconfig docs/ich9-ehci-uhci.cfg \ - -chardev socket,id=usbredirchardev,host=localhost,port=4000 \ - -device usb-redir,chardev=usbredirchardev,id=usbredirdev - -Signed-off-by: Hans de Goede ---- - Makefile.objs | 1 + - configure | 28 ++ - usb-redir.c | 1218 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 1247 insertions(+), 0 deletions(-) - create mode 100644 usb-redir.c - -diff --git a/Makefile.objs b/Makefile.objs -index dbde6b1..ed8cfa2 100644 ---- a/Makefile.objs -+++ b/Makefile.objs -@@ -208,6 +208,7 @@ hw-obj-$(CONFIG_HPET) += hpet.o - hw-obj-$(CONFIG_APPLESMC) += applesmc.o - hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o - hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o -+hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o - - # PPC devices - hw-obj-$(CONFIG_OPENPIC) += openpic.o -diff --git a/configure b/configure -index a896f11..4576f21 100755 ---- a/configure -+++ b/configure -@@ -190,6 +190,7 @@ spice="" - rbd="" - smartcard="" - smartcard_nss="" -+usb_redir="" - opengl="" - - # parse CC options first -@@ -773,6 +774,10 @@ for opt do - ;; - --enable-smartcard-nss) smartcard_nss="yes" - ;; -+ --disable-usb-redir) usb_redir="no" -+ ;; -+ --enable-usb-redir) usb_redir="yes" -+ ;; - *) echo "ERROR: unknown option $opt"; show_help="yes" - ;; - esac -@@ -1053,6 +1058,8 @@ echo " --disable-smartcard disable smartcard support" - echo " --enable-smartcard enable smartcard support" - echo " --disable-smartcard-nss disable smartcard nss support" - echo " --enable-smartcard-nss enable smartcard nss support" -+echo " --disable-usb-redir disable usb network redirection support" -+echo " --enable-usb-redir enable usb network redirection support" - echo "" - echo "NOTE: The object files are built at the place where configure is launched" - exit 1 -@@ -2427,6 +2434,22 @@ if test "$smartcard" = "no" ; then - smartcard_nss="no" - fi - -+# check for usbredirparser for usb network redirection support -+if test "$usb_redir" != "no" ; then -+ if $pkg_config libusbredirparser >/dev/null 2>&1 ; then -+ usb_redir="yes" -+ usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null) -+ usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null) -+ QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags" -+ LIBS="$LIBS $usb_redir_libs" -+ else -+ if test "$usb_redir" = "yes"; then -+ feature_not_found "usb-redir" -+ fi -+ usb_redir="no" -+ fi -+fi -+ - ########################################## - - ########################################## -@@ -2676,6 +2699,7 @@ echo "spice support $spice" - echo "rbd support $rbd" - echo "xfsctl support $xfs" - echo "nss used $smartcard_nss" -+echo "usb net redir $usb_redir" - echo "OpenGL support $opengl" - - if test $sdl_too_old = "yes"; then -@@ -2974,6 +2998,10 @@ if test "$smartcard_nss" = "yes" ; then - echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak - fi - -+if test "$usb_redir" = "yes" ; then -+ echo "CONFIG_USB_REDIR=y" >> $config_host_mak -+fi -+ - if test "$opengl" = "yes" ; then - echo "CONFIG_OPENGL=y" >> $config_host_mak - fi -diff --git a/usb-redir.c b/usb-redir.c -new file mode 100644 -index 0000000..e212993 ---- /dev/null -+++ b/usb-redir.c -@@ -0,0 +1,1218 @@ -+/* -+ * USB redirector usb-guest -+ * -+ * Copyright (c) 2011 Red Hat, Inc. -+ * -+ * Red Hat Authors: -+ * Hans de Goede -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+ -+#include "qemu-common.h" -+#include "qemu-timer.h" -+#include "monitor.h" -+#include "sysemu.h" -+ -+#include -+#include -+#include -+#include -+ -+#include "hw/usb.h" -+ -+#define MAX_ENDPOINTS 32 -+#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f)) -+#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f)) -+ -+typedef struct AsyncURB AsyncURB; -+typedef struct USBRedirDevice USBRedirDevice; -+ -+/* Struct to hold buffered packets (iso or int input packets) */ -+struct buf_packet { -+ uint8_t *data; -+ int len; -+ int status; -+ QTAILQ_ENTRY(buf_packet)next; -+}; -+ -+struct endp_data { -+ uint8_t type; -+ uint8_t interval; -+ uint8_t interface; /* bInterfaceNumber this ep belongs to */ -+ uint8_t iso_started; -+ uint8_t iso_error; /* For reporting iso errors to the HC */ -+ uint8_t interrupt_started; -+ uint8_t interrupt_error; -+ QTAILQ_HEAD(, buf_packet) bufpq; -+}; -+ -+struct USBRedirDevice { -+ USBDevice dev; -+ /* Properties */ -+ CharDriverState *cs; -+ uint8_t debug; -+ /* Data passed from chardev the fd_read cb to the usbredirparser read cb */ -+ const uint8_t *read_buf; -+ int read_buf_size; -+ /* For async handling of open/close */ -+ QEMUBH *open_close_bh; -+ /* To delay the usb attach in case of quick chardev close + open */ -+ QEMUTimer *attach_timer; -+ int64_t next_attach_time; -+ struct usbredirparser *parser; -+ struct endp_data endpoint[MAX_ENDPOINTS]; -+ uint32_t packet_id; -+ QTAILQ_HEAD(, AsyncURB) asyncq; -+}; -+ -+struct AsyncURB { -+ USBRedirDevice *dev; -+ USBPacket *packet; -+ uint32_t packet_id; -+ int get; -+ union { -+ struct usb_redir_control_packet_header control_packet; -+ struct usb_redir_bulk_packet_header bulk_packet; -+ struct usb_redir_interrupt_packet_header interrupt_packet; -+ }; -+ QTAILQ_ENTRY(AsyncURB)next; -+}; -+ -+static void usbredir_device_connect(void *priv, -+ struct usb_redir_device_connect_header *device_connect); -+static void usbredir_device_disconnect(void *priv); -+static void usbredir_interface_info(void *priv, -+ struct usb_redir_interface_info_header *interface_info); -+static void usbredir_ep_info(void *priv, -+ struct usb_redir_ep_info_header *ep_info); -+static void usbredir_configuration_status(void *priv, uint32_t id, -+ struct usb_redir_configuration_status_header *configuration_status); -+static void usbredir_alt_setting_status(void *priv, uint32_t id, -+ struct usb_redir_alt_setting_status_header *alt_setting_status); -+static void usbredir_iso_stream_status(void *priv, uint32_t id, -+ struct usb_redir_iso_stream_status_header *iso_stream_status); -+static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, -+ struct usb_redir_interrupt_receiving_status_header -+ *interrupt_receiving_status); -+static void usbredir_bulk_streams_status(void *priv, uint32_t id, -+ struct usb_redir_bulk_streams_status_header *bulk_streams_status); -+static void usbredir_control_packet(void *priv, uint32_t id, -+ struct usb_redir_control_packet_header *control_packet, -+ uint8_t *data, int data_len); -+static void usbredir_bulk_packet(void *priv, uint32_t id, -+ struct usb_redir_bulk_packet_header *bulk_packet, -+ uint8_t *data, int data_len); -+static void usbredir_iso_packet(void *priv, uint32_t id, -+ struct usb_redir_iso_packet_header *iso_packet, -+ uint8_t *data, int data_len); -+static void usbredir_interrupt_packet(void *priv, uint32_t id, -+ struct usb_redir_interrupt_packet_header *interrupt_header, -+ uint8_t *data, int data_len); -+ -+static int usbredir_handle_status(USBRedirDevice *dev, -+ int status, int actual_len); -+ -+#define VERSION "qemu usb-redir guest " QEMU_VERSION -+ -+/* -+ * Logging stuff -+ */ -+ -+#define ERROR(...) \ -+ do { \ -+ if (dev->debug >= usbredirparser_error) { \ -+ error_report("usb-redir error: " __VA_ARGS__); \ -+ } \ -+ } while (0) -+#define WARNING(...) \ -+ do { \ -+ if (dev->debug >= usbredirparser_warning) { \ -+ error_report("usb-redir warning: " __VA_ARGS__); \ -+ } \ -+ } while (0) -+#define INFO(...) \ -+ do { \ -+ if (dev->debug >= usbredirparser_info) { \ -+ error_report("usb-redir: " __VA_ARGS__); \ -+ } \ -+ } while (0) -+#define DPRINTF(...) \ -+ do { \ -+ if (dev->debug >= usbredirparser_debug) { \ -+ error_report("usb-redir: " __VA_ARGS__); \ -+ } \ -+ } while (0) -+#define DPRINTF2(...) \ -+ do { \ -+ if (dev->debug >= usbredirparser_debug_data) { \ -+ error_report("usb-redir: " __VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+static void usbredir_log(void *priv, int level, const char *msg) -+{ -+ USBRedirDevice *dev = priv; -+ -+ if (dev->debug < level) { -+ return; -+ } -+ -+ error_report("%s\n", msg); -+} -+ -+static void usbredir_log_data(USBRedirDevice *dev, const char *desc, -+ const uint8_t *data, int len) -+{ -+ int i, j, n; -+ -+ if (dev->debug < usbredirparser_debug_data) { -+ return; -+ } -+ -+ for (i = 0; i < len; i += j) { -+ char buf[128]; -+ -+ n = sprintf(buf, "%s", desc); -+ for (j = 0; j < 8 && i + j < len; j++) { -+ n += sprintf(buf + n, " %02X", data[i + j]); -+ } -+ error_report("%s\n", buf); -+ } -+} -+ -+/* -+ * usbredirparser io functions -+ */ -+ -+static int usbredir_read(void *priv, uint8_t *data, int count) -+{ -+ USBRedirDevice *dev = priv; -+ -+ if (dev->read_buf_size < count) { -+ count = dev->read_buf_size; -+ } -+ -+ memcpy(data, dev->read_buf, count); -+ -+ dev->read_buf_size -= count; -+ if (dev->read_buf_size) { -+ dev->read_buf += count; -+ } else { -+ dev->read_buf = NULL; -+ } -+ -+ return count; -+} -+ -+static int usbredir_write(void *priv, uint8_t *data, int count) -+{ -+ USBRedirDevice *dev = priv; -+ -+ return qemu_chr_write(dev->cs, data, count); -+} -+ -+/* -+ * Async and buffered packets helpers -+ */ -+ -+static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p) -+{ -+ AsyncURB *aurb = (AsyncURB *) qemu_mallocz(sizeof(AsyncURB)); -+ aurb->dev = dev; -+ aurb->packet = p; -+ aurb->packet_id = dev->packet_id; -+ QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next); -+ dev->packet_id++; -+ -+ return aurb; -+} -+ -+static void async_free(USBRedirDevice *dev, AsyncURB *aurb) -+{ -+ QTAILQ_REMOVE(&dev->asyncq, aurb, next); -+ qemu_free(aurb); -+} -+ -+static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id) -+{ -+ AsyncURB *aurb; -+ -+ QTAILQ_FOREACH(aurb, &dev->asyncq, next) { -+ if (aurb->packet_id == packet_id) { -+ return aurb; -+ } -+ } -+ ERROR("could not find async urb for packet_id %u\n", packet_id); -+ return NULL; -+} -+ -+static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ AsyncURB *aurb; -+ -+ QTAILQ_FOREACH(aurb, &dev->asyncq, next) { -+ if (p != aurb->packet) { -+ continue; -+ } -+ -+ DPRINTF("async cancel id %u\n", aurb->packet_id); -+ usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id); -+ usbredirparser_do_write(dev->parser); -+ -+ /* Mark it as dead */ -+ aurb->packet = NULL; -+ break; -+ } -+} -+ -+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)); -+ bufp->data = data; -+ bufp->len = len; -+ bufp->status = status; -+ QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next); -+ return bufp; -+} -+ -+static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp, -+ uint8_t ep) -+{ -+ QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next); -+ free(bufp->data); -+ qemu_free(bufp); -+} -+ -+static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep) -+{ -+ struct buf_packet *buf, *buf_next; -+ -+ QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) { -+ bufp_free(dev, buf, ep); -+ } -+} -+ -+/* -+ * USBDevice callbacks -+ */ -+ -+static void usbredir_handle_reset(USBDevice *udev) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ -+ DPRINTF("reset device\n"); -+ usbredirparser_send_reset(dev->parser); -+ usbredirparser_do_write(dev->parser); -+} -+ -+static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p, -+ uint8_t ep) -+{ -+ int status, len; -+ -+ if (!dev->endpoint[EP2I(ep)].iso_started && -+ !dev->endpoint[EP2I(ep)].iso_error) { -+ struct usb_redir_start_iso_stream_header start_iso = { -+ .endpoint = ep, -+ /* TODO maybe do something with these depending on ep interval? */ -+ .pkts_per_urb = 32, -+ .no_urbs = 3, -+ }; -+ /* No id, we look at the ep when receiving a status back */ -+ usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso); -+ usbredirparser_do_write(dev->parser); -+ DPRINTF("iso stream started ep %02X\n", ep); -+ dev->endpoint[EP2I(ep)].iso_started = 1; -+ } -+ -+ if (ep & USB_DIR_IN) { -+ struct buf_packet *isop; -+ -+ isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); -+ if (isop == NULL) { -+ DPRINTF2("iso-token-in ep %02X, no isop\n", ep); -+ /* Check iso_error for stream errors, otherwise its an underrun */ -+ status = dev->endpoint[EP2I(ep)].iso_error; -+ dev->endpoint[EP2I(ep)].iso_error = 0; -+ return usbredir_handle_status(dev, status, 0); -+ } -+ DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status, -+ isop->len); -+ -+ status = isop->status; -+ if (status != usb_redir_success) { -+ bufp_free(dev, isop, ep); -+ return usbredir_handle_status(dev, status, 0); -+ } -+ -+ len = isop->len; -+ if (len > p->len) { -+ ERROR("received iso data is larger then packet ep %02X\n", ep); -+ bufp_free(dev, isop, ep); -+ return USB_RET_NAK; -+ } -+ memcpy(p->data, isop->data, len); -+ bufp_free(dev, isop, ep); -+ return len; -+ } else { -+ /* If the stream was not started because of a pending error don't -+ send the packet to the usb-host */ -+ if (dev->endpoint[EP2I(ep)].iso_started) { -+ struct usb_redir_iso_packet_header iso_packet = { -+ .endpoint = ep, -+ .length = p->len -+ }; -+ /* No id, we look at the ep when receiving a status back */ -+ usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet, -+ p->data, p->len); -+ usbredirparser_do_write(dev->parser); -+ } -+ status = dev->endpoint[EP2I(ep)].iso_error; -+ dev->endpoint[EP2I(ep)].iso_error = 0; -+ DPRINTF2("iso-token-out ep %02X status %d len %d\n", ep, status, -+ p->len); -+ return usbredir_handle_status(dev, status, p->len); -+ } -+} -+ -+static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep) -+{ -+ struct usb_redir_stop_iso_stream_header stop_iso_stream = { -+ .endpoint = ep -+ }; -+ if (dev->endpoint[EP2I(ep)].iso_started) { -+ usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream); -+ DPRINTF("iso stream stopped ep %02X\n", ep); -+ dev->endpoint[EP2I(ep)].iso_started = 0; -+ } -+ usbredir_free_bufpq(dev, ep); -+} -+ -+static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p, -+ uint8_t ep) -+{ -+ AsyncURB *aurb = async_alloc(dev, p); -+ struct usb_redir_bulk_packet_header bulk_packet; -+ -+ DPRINTF("bulk-out ep %02X len %d id %u\n", ep, p->len, aurb->packet_id); -+ -+ bulk_packet.endpoint = ep; -+ bulk_packet.length = p->len; -+ bulk_packet.stream_id = 0; -+ aurb->bulk_packet = bulk_packet; -+ -+ if (ep & USB_DIR_IN) { -+ usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id, -+ &bulk_packet, NULL, 0); -+ } else { -+ usbredir_log_data(dev, "bulk data out:", p->data, p->len); -+ usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id, -+ &bulk_packet, p->data, p->len); -+ } -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+} -+ -+static int usbredir_handle_interrupt_data(USBRedirDevice *dev, -+ USBPacket *p, uint8_t ep) -+{ -+ if (ep & USB_DIR_IN) { -+ /* Input interrupt endpoint, buffered packet input */ -+ struct buf_packet *intp; -+ int status, len; -+ -+ if (!dev->endpoint[EP2I(ep)].interrupt_started && -+ !dev->endpoint[EP2I(ep)].interrupt_error) { -+ struct usb_redir_start_interrupt_receiving_header start_int = { -+ .endpoint = ep, -+ }; -+ /* No id, we look at the ep when receiving a status back */ -+ usbredirparser_send_start_interrupt_receiving(dev->parser, 0, -+ &start_int); -+ usbredirparser_do_write(dev->parser); -+ DPRINTF("interrupt recv started ep %02X\n", ep); -+ dev->endpoint[EP2I(ep)].interrupt_started = 1; -+ } -+ -+ intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); -+ if (intp == NULL) { -+ DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep); -+ /* Check interrupt_error for stream errors */ -+ status = dev->endpoint[EP2I(ep)].interrupt_error; -+ dev->endpoint[EP2I(ep)].interrupt_error = 0; -+ return usbredir_handle_status(dev, status, 0); -+ } -+ DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep, -+ intp->status, intp->len); -+ -+ status = intp->status; -+ if (status != usb_redir_success) { -+ bufp_free(dev, intp, ep); -+ return usbredir_handle_status(dev, status, 0); -+ } -+ -+ len = intp->len; -+ if (len > p->len) { -+ ERROR("received int data is larger then packet ep %02X\n", ep); -+ bufp_free(dev, intp, ep); -+ return USB_RET_NAK; -+ } -+ memcpy(p->data, intp->data, len); -+ bufp_free(dev, intp, ep); -+ return len; -+ } else { -+ /* Output interrupt endpoint, normal async operation */ -+ AsyncURB *aurb = async_alloc(dev, p); -+ struct usb_redir_interrupt_packet_header interrupt_packet; -+ -+ DPRINTF("interrupt-out ep %02X len %d id %u\n", ep, p->len, -+ aurb->packet_id); -+ -+ interrupt_packet.endpoint = ep; -+ interrupt_packet.length = p->len; -+ aurb->interrupt_packet = interrupt_packet; -+ -+ usbredir_log_data(dev, "interrupt data out:", p->data, p->len); -+ usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id, -+ &interrupt_packet, p->data, p->len); -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+ } -+} -+ -+static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev, -+ uint8_t ep) -+{ -+ struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = { -+ .endpoint = ep -+ }; -+ if (dev->endpoint[EP2I(ep)].interrupt_started) { -+ usbredirparser_send_stop_interrupt_receiving(dev->parser, 0, -+ &stop_interrupt_recv); -+ DPRINTF("interrupt recv stopped ep %02X\n", ep); -+ dev->endpoint[EP2I(ep)].interrupt_started = 0; -+ } -+ usbredir_free_bufpq(dev, ep); -+} -+ -+static int usbredir_handle_data(USBDevice *udev, USBPacket *p) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ uint8_t ep; -+ -+ ep = p->devep; -+ if (p->pid == USB_TOKEN_IN) { -+ ep |= USB_DIR_IN; -+ } -+ -+ switch (dev->endpoint[EP2I(ep)].type) { -+ case USB_ENDPOINT_XFER_CONTROL: -+ ERROR("handle_data called for control transfer on ep %02X\n", ep); -+ return USB_RET_NAK; -+ case USB_ENDPOINT_XFER_ISOC: -+ return usbredir_handle_iso_data(dev, p, ep); -+ case USB_ENDPOINT_XFER_BULK: -+ return usbredir_handle_bulk_data(dev, p, ep);; -+ case USB_ENDPOINT_XFER_INT: -+ return usbredir_handle_interrupt_data(dev, p, ep);; -+ default: -+ ERROR("handle_data ep %02X has unknown type %d\n", ep, -+ dev->endpoint[EP2I(ep)].type); -+ return USB_RET_NAK; -+ } -+} -+ -+static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p, -+ int config) -+{ -+ struct usb_redir_set_configuration_header set_config; -+ AsyncURB *aurb = async_alloc(dev, p); -+ int i; -+ -+ DPRINTF("set config %d id %u\n", config, aurb->packet_id); -+ -+ for (i = 0; i < MAX_ENDPOINTS; i++) { -+ switch (dev->endpoint[i].type) { -+ case USB_ENDPOINT_XFER_ISOC: -+ usbredir_stop_iso_stream(dev, I2EP(i)); -+ break; -+ case USB_ENDPOINT_XFER_INT: -+ if (i & 0x10) { -+ usbredir_stop_interrupt_receiving(dev, I2EP(i)); -+ } -+ break; -+ } -+ usbredir_free_bufpq(dev, I2EP(i)); -+ } -+ -+ set_config.configuration = config; -+ usbredirparser_send_set_configuration(dev->parser, aurb->packet_id, -+ &set_config); -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+} -+ -+static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p) -+{ -+ AsyncURB *aurb = async_alloc(dev, p); -+ -+ DPRINTF("get config id %u\n", aurb->packet_id); -+ -+ aurb->get = 1; -+ usbredirparser_send_get_configuration(dev->parser, aurb->packet_id); -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+} -+ -+static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p, -+ int interface, int alt) -+{ -+ struct usb_redir_set_alt_setting_header set_alt; -+ AsyncURB *aurb = async_alloc(dev, p); -+ int i; -+ -+ DPRINTF("set interface %d alt %d id %u\n", interface, alt, -+ aurb->packet_id); -+ -+ for (i = 0; i < MAX_ENDPOINTS; i++) { -+ if (dev->endpoint[i].interface == interface) { -+ switch (dev->endpoint[i].type) { -+ case USB_ENDPOINT_XFER_ISOC: -+ usbredir_stop_iso_stream(dev, I2EP(i)); -+ break; -+ case USB_ENDPOINT_XFER_INT: -+ if (i & 0x10) { -+ usbredir_stop_interrupt_receiving(dev, I2EP(i)); -+ } -+ break; -+ } -+ usbredir_free_bufpq(dev, I2EP(i)); -+ } -+ } -+ -+ set_alt.interface = interface; -+ set_alt.alt = alt; -+ usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id, -+ &set_alt); -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+} -+ -+static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p, -+ int interface) -+{ -+ struct usb_redir_get_alt_setting_header get_alt; -+ AsyncURB *aurb = async_alloc(dev, p); -+ -+ DPRINTF("get interface %d id %u\n", interface, aurb->packet_id); -+ -+ get_alt.interface = interface; -+ aurb->get = 1; -+ usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id, -+ &get_alt); -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+} -+ -+static int usbredir_handle_control(USBDevice *udev, USBPacket *p, -+ int request, int value, int index, int length, uint8_t *data) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ struct usb_redir_control_packet_header control_packet; -+ AsyncURB *aurb; -+ -+ /* Special cases for certain standard device requests */ -+ switch (request) { -+ case DeviceOutRequest | USB_REQ_SET_ADDRESS: -+ DPRINTF("set address %d\n", value); -+ dev->dev.addr = value; -+ return 0; -+ case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: -+ return usbredir_set_config(dev, p, value & 0xff); -+ case DeviceRequest | USB_REQ_GET_CONFIGURATION: -+ return usbredir_get_config(dev, p); -+ case InterfaceOutRequest | USB_REQ_SET_INTERFACE: -+ return usbredir_set_interface(dev, p, index, value); -+ case InterfaceRequest | USB_REQ_GET_INTERFACE: -+ return usbredir_get_interface(dev, p, index); -+ } -+ -+ /* "Normal" ctrl requests */ -+ aurb = async_alloc(dev, p); -+ -+ /* Note request is (bRequestType << 8) | bRequest */ -+ DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n", -+ request >> 8, request & 0xff, value, index, length, -+ aurb->packet_id); -+ -+ control_packet.request = request & 0xFF; -+ control_packet.requesttype = request >> 8; -+ control_packet.endpoint = control_packet.requesttype & USB_DIR_IN; -+ control_packet.value = value; -+ control_packet.index = index; -+ control_packet.length = length; -+ aurb->control_packet = control_packet; -+ -+ if (control_packet.requesttype & USB_DIR_IN) { -+ usbredirparser_send_control_packet(dev->parser, aurb->packet_id, -+ &control_packet, NULL, 0); -+ } else { -+ usbredir_log_data(dev, "ctrl data out:", data, length); -+ usbredirparser_send_control_packet(dev->parser, aurb->packet_id, -+ &control_packet, data, length); -+ } -+ usbredirparser_do_write(dev->parser); -+ return USB_RET_ASYNC; -+} -+ -+/* -+ * Close events can be triggered by usbredirparser_do_write which gets called -+ * from within the USBDevice data / control packet callbacks and doing a -+ * usb_detach from within these callbacks is not a good idea. -+ * -+ * So we use a bh handler to take care of close events. We also handle -+ * open events from this callback to make sure that a close directly followed -+ * by an open gets handled in the right order. -+ */ -+static void usbredir_open_close_bh(void *opaque) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ usbredir_device_disconnect(dev); -+ -+ if (dev->parser) { -+ usbredirparser_destroy(dev->parser); -+ dev->parser = NULL; -+ } -+ -+ if (dev->cs->opened) { -+ dev->parser = qemu_oom_check(usbredirparser_create()); -+ dev->parser->priv = dev; -+ dev->parser->log_func = usbredir_log; -+ dev->parser->read_func = usbredir_read; -+ dev->parser->write_func = usbredir_write; -+ dev->parser->device_connect_func = usbredir_device_connect; -+ dev->parser->device_disconnect_func = usbredir_device_disconnect; -+ dev->parser->interface_info_func = usbredir_interface_info; -+ dev->parser->ep_info_func = usbredir_ep_info; -+ dev->parser->configuration_status_func = usbredir_configuration_status; -+ dev->parser->alt_setting_status_func = usbredir_alt_setting_status; -+ dev->parser->iso_stream_status_func = usbredir_iso_stream_status; -+ dev->parser->interrupt_receiving_status_func = -+ usbredir_interrupt_receiving_status; -+ dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status; -+ dev->parser->control_packet_func = usbredir_control_packet; -+ dev->parser->bulk_packet_func = usbredir_bulk_packet; -+ dev->parser->iso_packet_func = usbredir_iso_packet; -+ dev->parser->interrupt_packet_func = usbredir_interrupt_packet; -+ dev->read_buf = NULL; -+ dev->read_buf_size = 0; -+ usbredirparser_init(dev->parser, VERSION, NULL, 0, 0); -+ usbredirparser_do_write(dev->parser); -+ } -+} -+ -+static void usbredir_do_attach(void *opaque) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ usb_device_attach(&dev->dev); -+} -+ -+/* -+ * chardev callbacks -+ */ -+ -+static int usbredir_chardev_can_read(void *opaque) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ if (dev->parser) { -+ /* usbredir_parser_do_read will consume *all* data we give it */ -+ return 1024 * 1024; -+ } else { -+ /* usbredir_open_close_bh hasn't handled the open event yet */ -+ return 0; -+ } -+} -+ -+static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ /* No recursion allowed! */ -+ assert(dev->read_buf == NULL); -+ -+ dev->read_buf = buf; -+ dev->read_buf_size = size; -+ -+ usbredirparser_do_read(dev->parser); -+ /* Send any acks, etc. which may be queued now */ -+ usbredirparser_do_write(dev->parser); -+} -+ -+static void usbredir_chardev_event(void *opaque, int event) -+{ -+ USBRedirDevice *dev = opaque; -+ -+ switch (event) { -+ case CHR_EVENT_OPENED: -+ case CHR_EVENT_CLOSED: -+ qemu_bh_schedule(dev->open_close_bh); -+ break; -+ } -+} -+ -+/* -+ * init + destroy -+ */ -+ -+static int usbredir_initfn(USBDevice *udev) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ int i; -+ -+ if (dev->cs == NULL) { -+ qerror_report(QERR_MISSING_PARAMETER, "chardev"); -+ return -1; -+ } -+ -+ dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev); -+ dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev); -+ -+ QTAILQ_INIT(&dev->asyncq); -+ for (i = 0; i < MAX_ENDPOINTS; i++) { -+ QTAILQ_INIT(&dev->endpoint[i].bufpq); -+ } -+ -+ /* We'll do the attach once we receive the speed from the usb-host */ -+ udev->auto_attach = 0; -+ -+ qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read, -+ usbredir_chardev_read, usbredir_chardev_event, dev); -+ -+ return 0; -+} -+ -+static void usbredir_cleanup_device_queues(USBRedirDevice *dev) -+{ -+ AsyncURB *aurb, *next_aurb; -+ int i; -+ -+ QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) { -+ async_free(dev, aurb); -+ } -+ for (i = 0; i < MAX_ENDPOINTS; i++) { -+ usbredir_free_bufpq(dev, I2EP(i)); -+ } -+} -+ -+static void usbredir_handle_destroy(USBDevice *udev) -+{ -+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); -+ -+ qemu_chr_close(dev->cs); -+ /* Note must be done after qemu_chr_close, as that causes a close event */ -+ qemu_bh_delete(dev->open_close_bh); -+ -+ qemu_del_timer(dev->attach_timer); -+ qemu_free_timer(dev->attach_timer); -+ -+ usbredir_cleanup_device_queues(dev); -+ -+ if (dev->parser) { -+ usbredirparser_destroy(dev->parser); -+ } -+} -+ -+/* -+ * usbredirparser packet complete callbacks -+ */ -+ -+static int usbredir_handle_status(USBRedirDevice *dev, -+ int status, int actual_len) -+{ -+ switch (status) { -+ case usb_redir_success: -+ return actual_len; -+ case usb_redir_stall: -+ return USB_RET_STALL; -+ case usb_redir_cancelled: -+ WARNING("returning cancelled packet to HC?\n"); -+ case usb_redir_inval: -+ case usb_redir_ioerror: -+ case usb_redir_timeout: -+ default: -+ return USB_RET_NAK; -+ } -+} -+ -+static void usbredir_device_connect(void *priv, -+ struct usb_redir_device_connect_header *device_connect) -+{ -+ USBRedirDevice *dev = priv; -+ -+ switch (device_connect->speed) { -+ case usb_redir_speed_low: -+ DPRINTF("attaching low speed device\n"); -+ dev->dev.speed = USB_SPEED_LOW; -+ break; -+ case usb_redir_speed_full: -+ DPRINTF("attaching full speed device\n"); -+ dev->dev.speed = USB_SPEED_FULL; -+ break; -+ case usb_redir_speed_high: -+ DPRINTF("attaching high speed device\n"); -+ dev->dev.speed = USB_SPEED_HIGH; -+ break; -+ case usb_redir_speed_super: -+ DPRINTF("attaching super speed device\n"); -+ dev->dev.speed = USB_SPEED_SUPER; -+ break; -+ default: -+ DPRINTF("attaching unknown speed device, assuming full speed\n"); -+ dev->dev.speed = USB_SPEED_FULL; -+ } -+ dev->dev.speedmask = (1 << dev->dev.speed); -+ qemu_mod_timer(dev->attach_timer, dev->next_attach_time); -+} -+ -+static void usbredir_device_disconnect(void *priv) -+{ -+ USBRedirDevice *dev = priv; -+ -+ /* 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; -+ } -+} -+ -+static void usbredir_interface_info(void *priv, -+ struct usb_redir_interface_info_header *interface_info) -+{ -+ /* The intention is to allow specifying acceptable interface classes -+ for redirection on the cmdline and in the future verify this here, -+ and disconnect (or never connect) the device if a not accepted -+ interface class is detected */ -+} -+ -+static void usbredir_ep_info(void *priv, -+ struct usb_redir_ep_info_header *ep_info) -+{ -+ USBRedirDevice *dev = priv; -+ int i; -+ -+ for (i = 0; i < MAX_ENDPOINTS; i++) { -+ dev->endpoint[i].type = ep_info->type[i]; -+ dev->endpoint[i].interval = ep_info->interval[i]; -+ dev->endpoint[i].interface = ep_info->interface[i]; -+ if (dev->endpoint[i].type != usb_redir_type_invalid) { -+ DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i), -+ dev->endpoint[i].type, dev->endpoint[i].interface); -+ } -+ } -+} -+ -+static void usbredir_configuration_status(void *priv, uint32_t id, -+ struct usb_redir_configuration_status_header *config_status) -+{ -+ USBRedirDevice *dev = priv; -+ AsyncURB *aurb; -+ int len = 0; -+ -+ DPRINTF("set config status %d config %d id %u\n", config_status->status, -+ config_status->configuration, id); -+ -+ aurb = async_find(dev, id); -+ if (!aurb) { -+ return; -+ } -+ if (aurb->packet) { -+ if (aurb->get) { -+ dev->dev.data_buf[0] = config_status->configuration; -+ len = 1; -+ } -+ aurb->packet->len = -+ usbredir_handle_status(dev, config_status->status, len); -+ usb_generic_async_ctrl_complete(&dev->dev, aurb->packet); -+ } -+ async_free(dev, aurb); -+} -+ -+static void usbredir_alt_setting_status(void *priv, uint32_t id, -+ struct usb_redir_alt_setting_status_header *alt_setting_status) -+{ -+ USBRedirDevice *dev = priv; -+ AsyncURB *aurb; -+ int len = 0; -+ -+ DPRINTF("alt status %d intf %d alt %d id: %u\n", -+ alt_setting_status->status, -+ alt_setting_status->interface, -+ alt_setting_status->alt, id); -+ -+ aurb = async_find(dev, id); -+ if (!aurb) { -+ return; -+ } -+ if (aurb->packet) { -+ if (aurb->get) { -+ dev->dev.data_buf[0] = alt_setting_status->alt; -+ len = 1; -+ } -+ aurb->packet->len = -+ usbredir_handle_status(dev, alt_setting_status->status, len); -+ usb_generic_async_ctrl_complete(&dev->dev, aurb->packet); -+ } -+ async_free(dev, aurb); -+} -+ -+static void usbredir_iso_stream_status(void *priv, uint32_t id, -+ struct usb_redir_iso_stream_status_header *iso_stream_status) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t ep = iso_stream_status->endpoint; -+ -+ DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status, -+ ep, id); -+ -+ 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); -+ dev->endpoint[EP2I(ep)].iso_started = 0; -+ } -+} -+ -+static void usbredir_interrupt_receiving_status(void *priv, uint32_t id, -+ struct usb_redir_interrupt_receiving_status_header -+ *interrupt_receiving_status) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t ep = interrupt_receiving_status->endpoint; -+ -+ DPRINTF("interrupt recv status %d ep %02X id %u\n", -+ interrupt_receiving_status->status, ep, id); -+ -+ dev->endpoint[EP2I(ep)].interrupt_error = -+ interrupt_receiving_status->status; -+ if (interrupt_receiving_status->status == usb_redir_stall) { -+ DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep); -+ dev->endpoint[EP2I(ep)].interrupt_started = 0; -+ } -+} -+ -+static void usbredir_bulk_streams_status(void *priv, uint32_t id, -+ struct usb_redir_bulk_streams_status_header *bulk_streams_status) -+{ -+} -+ -+static void usbredir_control_packet(void *priv, uint32_t id, -+ struct usb_redir_control_packet_header *control_packet, -+ uint8_t *data, int data_len) -+{ -+ USBRedirDevice *dev = priv; -+ int len = control_packet->length; -+ AsyncURB *aurb; -+ -+ DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status, -+ len, id); -+ -+ aurb = async_find(dev, id); -+ if (!aurb) { -+ free(data); -+ return; -+ } -+ -+ aurb->control_packet.status = control_packet->status; -+ aurb->control_packet.length = control_packet->length; -+ if (memcmp(&aurb->control_packet, control_packet, -+ sizeof(*control_packet))) { -+ ERROR("return control packet mismatch, please report this!\n"); -+ len = USB_RET_NAK; -+ } -+ -+ if (aurb->packet) { -+ len = usbredir_handle_status(dev, control_packet->status, len); -+ if (len > 0) { -+ usbredir_log_data(dev, "ctrl data in:", data, data_len); -+ if (data_len <= sizeof(dev->dev.data_buf)) { -+ memcpy(dev->dev.data_buf, data, data_len); -+ } else { -+ ERROR("ctrl buffer too small (%d > %zu)\n", -+ data_len, sizeof(dev->dev.data_buf)); -+ len = USB_RET_STALL; -+ } -+ } -+ aurb->packet->len = len; -+ usb_generic_async_ctrl_complete(&dev->dev, aurb->packet); -+ } -+ async_free(dev, aurb); -+ free(data); -+} -+ -+static void usbredir_bulk_packet(void *priv, uint32_t id, -+ struct usb_redir_bulk_packet_header *bulk_packet, -+ uint8_t *data, int data_len) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t ep = bulk_packet->endpoint; -+ int len = bulk_packet->length; -+ AsyncURB *aurb; -+ -+ DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status, -+ ep, len, id); -+ -+ aurb = async_find(dev, id); -+ if (!aurb) { -+ free(data); -+ return; -+ } -+ -+ if (aurb->bulk_packet.endpoint != bulk_packet->endpoint || -+ aurb->bulk_packet.stream_id != bulk_packet->stream_id) { -+ ERROR("return bulk packet mismatch, please report this!\n"); -+ len = USB_RET_NAK; -+ } -+ -+ if (aurb->packet) { -+ len = usbredir_handle_status(dev, bulk_packet->status, len); -+ if (len > 0) { -+ usbredir_log_data(dev, "bulk data in:", data, data_len); -+ if (data_len <= aurb->packet->len) { -+ memcpy(aurb->packet->data, data, data_len); -+ } else { -+ ERROR("bulk buffer too small (%d > %d)\n", data_len, -+ aurb->packet->len); -+ len = USB_RET_STALL; -+ } -+ } -+ aurb->packet->len = len; -+ usb_packet_complete(&dev->dev, aurb->packet); -+ } -+ async_free(dev, aurb); -+ free(data); -+} -+ -+static void usbredir_iso_packet(void *priv, uint32_t id, -+ struct usb_redir_iso_packet_header *iso_packet, -+ uint8_t *data, int data_len) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t ep = iso_packet->endpoint; -+ -+ DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep, -+ data_len, id); -+ -+ if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) { -+ ERROR("received iso packet for non iso endpoint %02X\n", ep); -+ free(data); -+ return; -+ } -+ -+ if (dev->endpoint[EP2I(ep)].iso_started == 0) { -+ DPRINTF("received iso packet for non started stream ep %02X\n", ep); -+ free(data); -+ return; -+ } -+ -+ /* bufp_alloc also adds the packet to the ep queue */ -+ bufp_alloc(dev, data, data_len, iso_packet->status, ep); -+} -+ -+static void usbredir_interrupt_packet(void *priv, uint32_t id, -+ struct usb_redir_interrupt_packet_header *interrupt_packet, -+ uint8_t *data, int data_len) -+{ -+ USBRedirDevice *dev = priv; -+ uint8_t ep = interrupt_packet->endpoint; -+ -+ DPRINTF("interrupt-in status %d ep %02X len %d id %u\n", -+ interrupt_packet->status, ep, data_len, id); -+ -+ if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) { -+ ERROR("received int packet for non interrupt endpoint %02X\n", ep); -+ free(data); -+ return; -+ } -+ -+ if (ep & USB_DIR_IN) { -+ if (dev->endpoint[EP2I(ep)].interrupt_started == 0) { -+ DPRINTF("received int packet while not started ep %02X\n", ep); -+ free(data); -+ return; -+ } -+ -+ /* bufp_alloc also adds the packet to the ep queue */ -+ bufp_alloc(dev, data, data_len, interrupt_packet->status, ep); -+ } else { -+ int len = interrupt_packet->length; -+ -+ AsyncURB *aurb = async_find(dev, id); -+ if (!aurb) { -+ return; -+ } -+ -+ if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) { -+ ERROR("return int packet mismatch, please report this!\n"); -+ len = USB_RET_NAK; -+ } -+ -+ if (aurb->packet) { -+ aurb->packet->len = usbredir_handle_status(dev, -+ interrupt_packet->status, len); -+ usb_packet_complete(&dev->dev, aurb->packet); -+ } -+ async_free(dev, aurb); -+ } -+} -+ -+static struct USBDeviceInfo usbredir_dev_info = { -+ .product_desc = "USB Redirection Device", -+ .qdev.name = "usb-redir", -+ .qdev.size = sizeof(USBRedirDevice), -+ .init = usbredir_initfn, -+ .handle_destroy = usbredir_handle_destroy, -+ .handle_packet = usb_generic_handle_packet, -+ .cancel_packet = usbredir_cancel_packet, -+ .handle_reset = usbredir_handle_reset, -+ .handle_data = usbredir_handle_data, -+ .handle_control = usbredir_handle_control, -+ .qdev.props = (Property[]) { -+ DEFINE_PROP_CHR("chardev", USBRedirDevice, cs), -+ DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0), -+ DEFINE_PROP_END_OF_LIST(), -+ }, -+}; -+ -+static void usbredir_register_devices(void) -+{ -+ usb_qdev_register(&usbredir_dev_info); -+} -+device_init(usbredir_register_devices); --- -1.7.5.1 - diff --git a/qemu.spec b/qemu.spec index f423c2b..0d88168 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,9 +1,9 @@ -%define githead 525e3df +%define githead 59fadcc Summary: QEMU is a FAST! processor emulator Name: qemu Version: 0.15.0 -Release: 0.2.20110718%githead%{?dist} +Release: 0.2.20110728%githead%{?dist} # Epoch because we pushed a qemu-1.0 package Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD @@ -22,7 +22,7 @@ URL: http://www.qemu.org/ # Source0: http://downloads.sourceforge.net/sourceforge/kvm/qemu-kvm-%{version}.tar.gz # The source for this package was pulled from upstream's git. Use the # following commands to generate the tarball: -# git archive --format=tar --prefix=qemu-kvm-0.15/ 525e3df | gzip > qemu-kvm-0.15.0-525e3df.tar.gz +# git archive --format=tar --prefix=qemu-kvm-0.15.0/ 59fadcc | gzip > qemu-kvm-0.15.0-59fadcc.tar.gz Source0: qemu-kvm-%{version}-%{githead}.tar.gz Source1: qemu.init @@ -40,45 +40,20 @@ Source6: ksmtuned.init Source7: ksmtuned Source8: ksmtuned.conf -# Sync with: http://www.kraxel.org/cgit/qemu/log/?h=usb.19 -# USB patches waiting to be pulled by upstream -Patch1: 0001-hw-usb-musb.c-Don-t-misuse-usb_packet_complete.patch -Patch2: 0002-usb-Add-a-usb_fill_port-helper-function.patch -Patch3: 0003-usb-Move-initial-call-of-usb_port_location-to-usb_fi.patch -Patch4: 0004-usb-Add-a-register_companion-USB-bus-op.patch -Patch5: 0005-usb-Make-port-wakeup-and-complete-ops-take-a-USBPort.patch -Patch6: 0006-usb-Replace-device_destroy-bus-op-with-a-child_detac.patch -Patch7: 0007-usb-ehci-drop-unused-num-ports-state-member.patch -Patch8: 0008-usb-ehci-Connect-Status-bit-is-read-only-don-t-allow.patch -Patch9: 0009-usb-ehci-cleanup-port-reset-handling.patch -Patch10: 0010-usb-assert-on-calling-usb_attach-port-NULL-on-a-port.patch -Patch11: 0011-usb-ehci-Fix-handling-of-PED-and-PEDC-port-status-bi.patch -Patch12: 0012-usb-ehci-Add-support-for-registering-companion-contr.patch -Patch13: 0013-usb-uhci-Add-support-for-being-a-companion-controlle.patch -Patch14: 0014-usb-ohci-Add-support-for-being-a-companion-controlle.patch -Patch15: 0015-pci-add-ich9-usb-controller-ids.patch -Patch16: 0016-uhci-add-ich9-controllers.patch -Patch17: 0017-ehci-fix-port-count.patch -Patch18: 0018-ehci-add-ich9-controller.patch -Patch19: 0019-usb-update-documentation.patch -Patch20: 0020-usb_register_port-do-not-set-port-opaque-and-port-in.patch -Patch21: 0021-usb-fixup-bluetooth-descriptors.patch -Patch22: 0022-usb-hub-remove-unused-descriptor-arrays.patch -Patch23: 0023-usb-ohci-raise-interrupt-on-attach.patch -# Add usb-redir device, under review upstream -Patch24: 0024-USB-add-usb-network-redirection-support.patch # Amit's flow control patches, waiting to glib conversion before going upstream -Patch25: 0025-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch -Patch26: 0026-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch -Patch27: 0027-iohandlers-Add-enable-disable_write_fd_handler-funct.patch -Patch28: 0028-char-Add-framework-for-a-write-unblocked-callback.patch -Patch29: 0029-char-Update-send_all-to-handle-nonblocking-chardev-w.patch -Patch30: 0030-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch -Patch31: 0031-char-Throttle-when-host-connection-is-down.patch -Patch32: 0032-virtio-console-Enable-port-throttling-when-chardev-i.patch -Patch33: 0033-spice-qemu-char.c-add-throttling.patch -Patch34: 0034-spice-qemu-char.c-remove-intermediate-buffer.patch -Patch35: 0035-usb-redir-Add-flow-control-support.patch +Patch01: 0001-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch +Patch02: 0002-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch +Patch03: 0003-iohandlers-Add-enable-disable_write_fd_handler-funct.patch +Patch04: 0004-char-Add-framework-for-a-write-unblocked-callback.patch +Patch05: 0005-char-Update-send_all-to-handle-nonblocking-chardev-w.patch +Patch06: 0006-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch +Patch07: 0007-char-Throttle-when-host-connection-is-down.patch +Patch08: 0008-virtio-console-Enable-port-throttling-when-chardev-i.patch +Patch09: 0009-spice-qemu-char.c-add-throttling.patch +Patch10: 0010-spice-qemu-char.c-remove-intermediate-buffer.patch +Patch11: 0011-usb-redir-Add-flow-control-support.patch +Patch12: 0012-usb-redir-Call-qemu_chr_guest_open-close.patch +Patch13: 0013-spice-qemu-char-Generate-chardev-open-close-events.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel @@ -252,41 +227,19 @@ such as kvm_stat. %prep %setup -q -n qemu-kvm-%{version} -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 +%patch01 -p1 +%patch02 -p1 +%patch03 -p1 +%patch04 -p1 +%patch05 -p1 +%patch06 -p1 +%patch07 -p1 +%patch08 -p1 +%patch09 -p1 %patch10 -p1 %patch11 -p1 %patch12 -p1 %patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 -%patch35 -p1 %build # By default we build everything, but allow x86 to build a minimal version @@ -515,6 +468,7 @@ fi %{_initddir}/qemu %{_bindir}/qemu-i386 %{_bindir}/qemu-x86_64 +%{_bindir}/qemu-ga %if !%{with_x86only} %{_bindir}/qemu-alpha %{_bindir}/qemu-arm @@ -596,6 +550,9 @@ fi %{_mandir}/man1/qemu-img.1* %changelog +* Thu Jul 28 2011 Justin M. Forbes - 2:0.15.0-0.1.2011072859fadcc +- Update to 0.15.0-rc0 as we prepare for 0.15.0 release + * Tue Jul 19 2011 Hans de Goede - 2:0.15.0-0.2.20110718525e3df - Add support usb redirection over the network, see: http://fedoraproject.org/wiki/Features/UsbNetworkRedirection diff --git a/sources b/sources index 2826ce6..ff5bb55 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -cbd0d49d1490ca90208609cd158eb080 qemu-kvm-0.15.0-525e3df.tar.gz +b0d29c5405ec451421d98d335762ff7c qemu-kvm-0.15.0-59fadcc.tar.gz