Merge remote-tracking branch 'kraxel/usb.81' into staging
# By Gerd Hoffmann (3) and Hans de Goede (1) # Via Gerd Hoffmann * kraxel/usb.81: usb-host: raise libusbx minimum version to 1.0.13 usb: better speed mismatch error reporting ehci_free_packet: Discard finished packets when the queue is halted xhci: remove XHCIRing->base (unused) Message-id: 1366705929-11251-1-git-send-email-kraxel@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
2cfd5cc06a
2
configure
vendored
2
configure
vendored
@ -3060,7 +3060,7 @@ fi
|
|||||||
|
|
||||||
# check for libusb
|
# check for libusb
|
||||||
if test "$libusb" != "no" ; then
|
if test "$libusb" != "no" ; then
|
||||||
if $pkg_config libusb-1.0 >/dev/null 2>&1 ; then
|
if $pkg_config --atleast-version=1.0.13 libusb-1.0 >/dev/null 2>&1 ; then
|
||||||
libusb="yes"
|
libusb="yes"
|
||||||
usb="libusb"
|
usb="libusb"
|
||||||
libusb_cflags=$($pkg_config --cflags libusb-1.0 2>/dev/null)
|
libusb_cflags=$($pkg_config --cflags libusb-1.0 2>/dev/null)
|
||||||
|
36
hw/usb/bus.c
36
hw/usb/bus.c
@ -417,19 +417,47 @@ void usb_release_port(USBDevice *dev)
|
|||||||
bus->nfree++;
|
bus->nfree++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void usb_mask_to_str(char *dest, size_t size,
|
||||||
|
unsigned int speedmask)
|
||||||
|
{
|
||||||
|
static const struct {
|
||||||
|
unsigned int mask;
|
||||||
|
const char *name;
|
||||||
|
} speeds[] = {
|
||||||
|
{ .mask = USB_SPEED_MASK_FULL, .name = "full" },
|
||||||
|
{ .mask = USB_SPEED_MASK_HIGH, .name = "high" },
|
||||||
|
{ .mask = USB_SPEED_MASK_SUPER, .name = "super" },
|
||||||
|
};
|
||||||
|
int i, pos = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(speeds); i++) {
|
||||||
|
if (speeds[i].mask & speedmask) {
|
||||||
|
pos += snprintf(dest + pos, size - pos, "%s%s",
|
||||||
|
pos ? "+" : "",
|
||||||
|
speeds[i].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int usb_device_attach(USBDevice *dev)
|
int usb_device_attach(USBDevice *dev)
|
||||||
{
|
{
|
||||||
USBBus *bus = usb_bus_from_device(dev);
|
USBBus *bus = usb_bus_from_device(dev);
|
||||||
USBPort *port = dev->port;
|
USBPort *port = dev->port;
|
||||||
|
char devspeed[32], portspeed[32];
|
||||||
|
|
||||||
assert(port != NULL);
|
assert(port != NULL);
|
||||||
assert(!dev->attached);
|
assert(!dev->attached);
|
||||||
trace_usb_port_attach(bus->busnr, port->path);
|
usb_mask_to_str(devspeed, sizeof(devspeed), dev->speedmask);
|
||||||
|
usb_mask_to_str(portspeed, sizeof(portspeed), port->speedmask);
|
||||||
|
trace_usb_port_attach(bus->busnr, port->path,
|
||||||
|
devspeed, portspeed);
|
||||||
|
|
||||||
if (!(port->speedmask & dev->speedmask)) {
|
if (!(port->speedmask & dev->speedmask)) {
|
||||||
error_report("Warning: speed mismatch trying to attach "
|
error_report("Warning: speed mismatch trying to attach"
|
||||||
"usb device %s to bus %s",
|
" usb device \"%s\" (%s speed)"
|
||||||
dev->product_desc, bus->qbus.name);
|
" to bus \"%s\", port \"%s\" (%s speed)",
|
||||||
|
dev->product_desc, devspeed,
|
||||||
|
bus->qbus.name, port->path, portspeed);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,8 +522,6 @@ void usb_desc_attach(USBDevice *dev)
|
|||||||
} else if (desc->full && (dev->port->speedmask & USB_SPEED_MASK_FULL)) {
|
} else if (desc->full && (dev->port->speedmask & USB_SPEED_MASK_FULL)) {
|
||||||
dev->speed = USB_SPEED_FULL;
|
dev->speed = USB_SPEED_FULL;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n",
|
|
||||||
usb_device_get_product_desc(dev));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
usb_desc_setdefaults(dev);
|
usb_desc_setdefaults(dev);
|
||||||
|
@ -586,17 +586,23 @@ static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
|
|||||||
|
|
||||||
static void ehci_free_packet(EHCIPacket *p)
|
static void ehci_free_packet(EHCIPacket *p)
|
||||||
{
|
{
|
||||||
if (p->async == EHCI_ASYNC_FINISHED) {
|
if (p->async == EHCI_ASYNC_FINISHED &&
|
||||||
|
!(p->queue->qh.token & QTD_TOKEN_HALT)) {
|
||||||
ehci_writeback_async_complete_packet(p);
|
ehci_writeback_async_complete_packet(p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
trace_usb_ehci_packet_action(p->queue, p, "free");
|
trace_usb_ehci_packet_action(p->queue, p, "free");
|
||||||
if (p->async == EHCI_ASYNC_INITIALIZED) {
|
|
||||||
usb_packet_unmap(&p->packet, &p->sgl);
|
|
||||||
qemu_sglist_destroy(&p->sgl);
|
|
||||||
}
|
|
||||||
if (p->async == EHCI_ASYNC_INFLIGHT) {
|
if (p->async == EHCI_ASYNC_INFLIGHT) {
|
||||||
usb_cancel_packet(&p->packet);
|
usb_cancel_packet(&p->packet);
|
||||||
|
}
|
||||||
|
if (p->async == EHCI_ASYNC_FINISHED &&
|
||||||
|
p->packet.status == USB_RET_SUCCESS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"EHCI: Dropping completed packet from halted %s ep %02X\n",
|
||||||
|
(p->pid == USB_TOKEN_IN) ? "in" : "out",
|
||||||
|
get_field(p->queue->qh.epchar, QH_EPCHAR_EP));
|
||||||
|
}
|
||||||
|
if (p->async != EHCI_ASYNC_NONE) {
|
||||||
usb_packet_unmap(&p->packet, &p->sgl);
|
usb_packet_unmap(&p->packet, &p->sgl);
|
||||||
qemu_sglist_destroy(&p->sgl);
|
qemu_sglist_destroy(&p->sgl);
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,6 @@ typedef enum EPType {
|
|||||||
} EPType;
|
} EPType;
|
||||||
|
|
||||||
typedef struct XHCIRing {
|
typedef struct XHCIRing {
|
||||||
dma_addr_t base;
|
|
||||||
dma_addr_t dequeue;
|
dma_addr_t dequeue;
|
||||||
bool ccs;
|
bool ccs;
|
||||||
} XHCIRing;
|
} XHCIRing;
|
||||||
@ -943,7 +942,6 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
|
|||||||
static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
|
static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
|
||||||
dma_addr_t base)
|
dma_addr_t base)
|
||||||
{
|
{
|
||||||
ring->base = base;
|
|
||||||
ring->dequeue = base;
|
ring->dequeue = base;
|
||||||
ring->ccs = 1;
|
ring->ccs = 1;
|
||||||
}
|
}
|
||||||
@ -1948,7 +1946,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
|
|||||||
streamid = 0;
|
streamid = 0;
|
||||||
xhci_set_ep_state(xhci, epctx, NULL, EP_RUNNING);
|
xhci_set_ep_state(xhci, epctx, NULL, EP_RUNNING);
|
||||||
}
|
}
|
||||||
assert(ring->base != 0);
|
assert(ring->dequeue != 0);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];
|
XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];
|
||||||
|
@ -236,8 +236,6 @@ static int usb_host_init(void)
|
|||||||
|
|
||||||
static int usb_host_get_port(libusb_device *dev, char *port, size_t len)
|
static int usb_host_get_port(libusb_device *dev, char *port, size_t len)
|
||||||
{
|
{
|
||||||
#if defined(LIBUSBX_API_VERSION) && (LIBUSBX_API_VERSION >= 0x010000ff)
|
|
||||||
/* have libusb_get_port_path() */
|
|
||||||
uint8_t path[7];
|
uint8_t path[7];
|
||||||
size_t off;
|
size_t off;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
@ -251,9 +249,6 @@ static int usb_host_get_port(libusb_device *dev, char *port, size_t len)
|
|||||||
off += snprintf(port+off, len-off, ".%d", path[i]);
|
off += snprintf(port+off, len-off, ".%d", path[i]);
|
||||||
}
|
}
|
||||||
return off;
|
return off;
|
||||||
#else
|
|
||||||
return snprintf(port, len, "FIXME");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_host_libusb_error(const char *func, int rc)
|
static void usb_host_libusb_error(const char *func, int rc)
|
||||||
|
@ -277,7 +277,7 @@ usb_packet_state_fault(int bus, const char *port, int ep, void *p, const char *o
|
|||||||
|
|
||||||
# hw/usb/bus.c
|
# hw/usb/bus.c
|
||||||
usb_port_claim(int bus, const char *port) "bus %d, port %s"
|
usb_port_claim(int bus, const char *port) "bus %d, port %s"
|
||||||
usb_port_attach(int bus, const char *port) "bus %d, port %s"
|
usb_port_attach(int bus, const char *port, const char *devspeed, const char *portspeed) "bus %d, port %s, devspeed %s, portspeed %s"
|
||||||
usb_port_detach(int bus, const char *port) "bus %d, port %s"
|
usb_port_detach(int bus, const char *port) "bus %d, port %s"
|
||||||
usb_port_release(int bus, const char *port) "bus %d, port %s"
|
usb_port_release(int bus, const char *port) "bus %d, port %s"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user