This patch adds IDs to usb packets. Those IDs are (a) supposed to be
unique for the lifecycle of a packet (from packet setup until the packet
is either completed or canceled) and (b) stable across migration.
uhci, ohci, ehci and xhci use the guest physical address of the transfer
descriptor for this.
musb needs a different approach because there is no transfer descriptor.
But musb also doesn't support pipelining, so we have never more than one
packet per endpoint in flight. So we go create an ID based on endpoint
and device address.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
For controllers which queue up more then 1 packet at a time, we must halt the
ep queue, and inside the controller code cancel all pending packets on an
error.
There are multiple reasons for this:
1) Guests expect the controllers to halt ep queues on error, so that they
get the opportunity to cancel transfers which the scheduled after the failing
one, before processing continues
2) Not cancelling queued up packets after a failed transfer also messes up
the controller state machine, in the case of EHCI causing the following
assert to trigger: "assert(p->qtdaddr == q->qtdaddr)" at hcd-ehci.c:2075
3) For bulk endpoints with pipelining enabled (redirection to a real USB
device), we must cancel all the transfers after this a failed one so that:
a) If they've completed already, they are not processed further causing more
stalls to be reported, originating from the same failed transfer
b) If still in flight, they are cancelled before the guest does
a clear stall, otherwise the guest and device can loose sync!
Note this patch only touches the ehci and uhci controller changes, since AFAIK
no other controllers actually queue up multiple transfer. If I'm wrong on this
other controllers need to be updated too!
Also note that this patch was heavily tested with the ehci code, where I had
a reproducer for a device causing a transfer to fail. The uhci code is not
tested with actually failing transfers and could do with a thorough review!
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
$subject says all: when loading old (v1) vmstate which doesn't contain
expire_time initialize it with a reasonable default (current time).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Not a single driver has any possibility of failure on their
exit function, let's keep it that way.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
The USB UHCI and EHCI drivers were converted some time ago to use the
pci_dma_*() helper functions. However, this conversion was not complete
because in some places both these drivers do DMA via the usb_packet_map()
function in usb-libhw.c. That function directly used
cpu_physical_memory_map().
Now that the sglist code uses DMA wrappers properly, we can convert the
functions in usb-libhw.c, thus conpleting the conversion of UHCI and EHCI
to use the DMA wrappers.
Note that usb_packet_map() invokes dma_memory_map() with a NULL invalidate
callback function. When IOMMU support is added, this will mean that
usb_packet_map() and the corresponding usb_packet_unmap() must be called in
close proximity without dropping the qemu device lock - otherwise the guest
might invalidate IOMMU mappings while they are still in use by the device
code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
We update the QTAILQ in the loop, thus we must use the SAFE version
to make sure we don't touch the queue struct after freeing it.
https://bugzilla.novell.com/show_bug.cgi?id=766310
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
The multifunction ich9 ehci controller with uhci companions uses a
different interrupt pin for each function. The three uhci devices
get pins A, B and C, whereas ehci uses pin D. This way the guest
can assign different IRQ lines to each controller.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Cancel transactions before saving vmstate is pretty pointless and just
causes disruptions. We need to cancel them before *loading* vmstate,
but in that case uhci_reset() handles it already and no special action
is needed.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Add a property for the uhci bandwidth. Can be used to make uhci
emulation run faster than real hardware.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Schedule bottom half on completion of async packets instead of calling
uhci_process_frame directly. This way we run uhci_process_frame only
once in case multiple packets finish in a row. Also check whenever
there is bandwidth left before scheduling uhci_process_frame.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
uhci_process_frame() can be invoked multiple times per frame, so
accounting usb bandwith in a local variable doesn't fly, use a variable
in UHCIState instead. Also check the limit more frequently.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
uhci_reset() clears irq mask and irq status registers, but doesn't
update the irq line. Which may result in suspious IRQs after uhci
reset. Fix it.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
When we queue up usb packets we may happen to find a already queued
packet, which also might be finished at that point already. We don't
want continue processing the packet at this point though, so lets
just signal back we've found a in-flight packet when in queuing mode.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Not only QHs can form rings, but TDs too. With the new
queuing/pipelining support we are following TD chains and
can actually walk in circles. An assert() prevents us from
entering an endless loop then.
Fix is easy: Just stop queuing when we figure the TD we are
about to queue up is in flight already.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Step #2 (separate for better bisectability): renumber so the silly '-1'
goes away. Pick a range which doesn't overlap the old values.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Remove the uhci and ohci init wrappers, which all wrapped a
pci_create_simple() one-liner. Switch callsites to call
pci_create_simple directly. Remove the header files where
the wrappers where declared.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reorganize usb source files. Create a new hw/usb/ directory and move
all usb source code to that place. Also make filenames a bit more
descriptive. Host adapters are prefixed with "hch-" now, usb device
emulations are prefixed with "dev-". Fixup paths Makefile and include
paths to make it compile. No code changes.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>