aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2012-10-26 13:09:56 +0200
committerGerd Hoffmann <kraxel@redhat.com>2012-11-01 13:10:09 +0100
commit0bc85da69e01f25c27f575ef0d57d29be4154d71 (patch)
treea0bd2e9896acaa017012beb9016b21ab82f87790
parent4f47f0f82eccbda44bac929df94fa244bf3452bd (diff)
xhci: allow address slot being called multiple times
win8 guests do that for some reason ... Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/usb/hcd-xhci.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 325963882d..900abf5566 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -483,6 +483,8 @@ enum xhci_flags {
static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
unsigned int epid);
+static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid,
+ unsigned int epid);
static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v);
static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v);
@@ -1075,8 +1077,7 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
slot = &xhci->slots[slotid-1];
if (slot->eps[epid-1]) {
- fprintf(stderr, "xhci: slot %d ep %d already enabled!\n", slotid, epid);
- return CC_TRB_ERROR;
+ xhci_disable_ep(xhci, slotid, epid);
}
epctx = g_malloc(sizeof(XHCIEPContext));
@@ -1919,6 +1920,9 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
}
for (i = 0; i < xhci->numslots; i++) {
+ if (i == slotid-1) {
+ continue;
+ }
if (xhci->slots[i].uport == uport) {
fprintf(stderr, "xhci: port %s already assigned to slot %d\n",
uport->path, i+1);
@@ -1936,6 +1940,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
slot->devaddr = xhci->devaddr++;
slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr;
DPRINTF("xhci: device address is %d\n", slot->devaddr);
+ usb_device_reset(dev);
usb_device_handle_control(dev, NULL,
DeviceOutRequest | USB_REQ_SET_ADDRESS,
slot->devaddr, 0, 0, NULL);