aboutsummaryrefslogtreecommitdiff
path: root/hw/usb/hcd-xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb/hcd-xhci.c')
-rw-r--r--hw/usb/hcd-xhci.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index b6411f0..292c378 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -644,6 +644,11 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
dma_addr_t erdp;
unsigned int dp_idx;
+ if (xhci->numintrs == 1 ||
+ (xhci->intr_mapping_supported && !xhci->intr_mapping_supported(xhci))) {
+ v = 0;
+ }
+
if (v >= xhci->numintrs) {
DPRINTF("intr nr out of range (%d >= %d)\n", v, xhci->numintrs);
return;
@@ -1182,6 +1187,12 @@ static void xhci_ep_free_xfer(XHCITransfer *xfer)
g_free(xfer);
}
+static void xhci_xfer_unmap(XHCITransfer *xfer)
+{
+ usb_packet_unmap(&xfer->packet, &xfer->sgl);
+ qemu_sglist_destroy(&xfer->sgl);
+}
+
static int xhci_ep_nuke_one_xfer(XHCITransfer *t, TRBCCode report)
{
int killed = 0;
@@ -1193,6 +1204,7 @@ static int xhci_ep_nuke_one_xfer(XHCITransfer *t, TRBCCode report)
if (t->running_async) {
usb_cancel_packet(&t->packet);
+ xhci_xfer_unmap(t);
t->running_async = 0;
killed = 1;
}
@@ -1475,12 +1487,6 @@ err:
return -1;
}
-static void xhci_xfer_unmap(XHCITransfer *xfer)
-{
- usb_packet_unmap(&xfer->packet, &xfer->sgl);
- qemu_sglist_destroy(&xfer->sgl);
-}
-
static void xhci_xfer_report(XHCITransfer *xfer)
{
uint32_t edtla = 0;
@@ -2810,9 +2816,15 @@ static uint64_t xhci_port_read(void *ptr, hwaddr reg, unsigned size)
case 0x08: /* PORTLI */
ret = 0;
break;
- case 0x0c: /* reserved */
+ case 0x0c: /* PORTHLPMC */
+ ret = 0;
+ qemu_log_mask(LOG_UNIMP, "%s: read from port register PORTHLPMC",
+ __func__);
+ break;
default:
- trace_usb_xhci_unimplemented("port read", reg);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: read from port offset 0x%" HWADDR_PRIx,
+ __func__, reg);
ret = 0;
}
@@ -2881,9 +2893,22 @@ static void xhci_port_write(void *ptr, hwaddr reg,
}
break;
case 0x04: /* PORTPMSC */
+ case 0x0c: /* PORTHLPMC */
+ qemu_log_mask(LOG_UNIMP,
+ "%s: write 0x%" PRIx64
+ " (%u bytes) to port register at offset 0x%" HWADDR_PRIx,
+ __func__, val, size, reg);
+ break;
case 0x08: /* PORTLI */
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Write to read-only PORTLI register",
+ __func__);
+ break;
default:
- trace_usb_xhci_unimplemented("port write", reg);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: write 0x%" PRIx64 " (%u bytes) to unknown port "
+ "register at offset 0x%" HWADDR_PRIx,
+ __func__, val, size, reg);
+ break;
}
}
@@ -3605,23 +3630,22 @@ const VMStateDescription vmstate_xhci = {
}
};
-static Property xhci_properties[] = {
+static const Property xhci_properties[] = {
DEFINE_PROP_BIT("streams", XHCIState, flags,
XHCI_FLAG_ENABLE_STREAMS, true),
DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4),
DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4),
DEFINE_PROP_LINK("host", XHCIState, hostOpaque, TYPE_DEVICE,
DeviceState *),
- DEFINE_PROP_END_OF_LIST(),
};
-static void xhci_class_init(ObjectClass *klass, void *data)
+static void xhci_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = usb_xhci_realize;
dc->unrealize = usb_xhci_unrealize;
- dc->reset = xhci_reset;
+ device_class_set_legacy_reset(dc, xhci_reset);
device_class_set_props(dc, xhci_properties);
dc->user_creatable = false;
}