--- /dev/null
+From 670eba790c368e9c37b0c964d94e0ff7f0d0c443 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 30 Aug 2012 17:15:12 +0200
+Subject: [PATCH] xhci: prepare xhci_runtime_{read,write} for multiple
+ interrupters
+
+Prepare xhci runtime register access function for multiple interrupters.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-xhci.c | 100 +++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 57 insertions(+), 43 deletions(-)
+
+diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
+index 8a14ee8..6b3ff16 100644
+--- a/hw/usb/hcd-xhci.c
++++ b/hw/usb/hcd-xhci.c
+@@ -2586,37 +2586,43 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+
+ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+ {
+- XHCIInterrupter *intr = &xhci->intr[0];
+- uint32_t ret;
++ uint32_t ret = 0;
+
+- switch (reg) {
+- case 0x00: /* MFINDEX */
+- ret = xhci_mfindex_get(xhci) & 0x3fff;
+- break;
+- case 0x20: /* IMAN */
+- ret = intr->iman;
+- break;
+- case 0x24: /* IMOD */
+- ret = intr->imod;
+- break;
+- case 0x28: /* ERSTSZ */
+- ret = intr->erstsz;
+- break;
+- case 0x30: /* ERSTBA low */
+- ret = intr->erstba_low;
+- break;
+- case 0x34: /* ERSTBA high */
+- ret = intr->erstba_high;
+- break;
+- case 0x38: /* ERDP low */
+- ret = intr->erdp_low;
+- break;
+- case 0x3c: /* ERDP high */
+- ret = intr->erdp_high;
+- break;
+- default:
+- fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
+- ret = 0;
++ if (reg < 0x20) {
++ switch (reg) {
++ case 0x00: /* MFINDEX */
++ ret = xhci_mfindex_get(xhci) & 0x3fff;
++ break;
++ default:
++ fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
++ break;
++ }
++ } else {
++ int v = (reg - 0x20) / 0x20;
++ XHCIInterrupter *intr = &xhci->intr[v];
++ switch (reg & 0x1f) {
++ case 0x00: /* IMAN */
++ ret = intr->iman;
++ break;
++ case 0x04: /* IMOD */
++ ret = intr->imod;
++ break;
++ case 0x08: /* ERSTSZ */
++ ret = intr->erstsz;
++ break;
++ case 0x10: /* ERSTBA low */
++ ret = intr->erstba_low;
++ break;
++ case 0x14: /* ERSTBA high */
++ ret = intr->erstba_high;
++ break;
++ case 0x18: /* ERDP low */
++ ret = intr->erdp_low;
++ break;
++ case 0x1c: /* ERDP high */
++ ret = intr->erdp_high;
++ break;
++ }
+ }
+
+ trace_usb_xhci_runtime_read(reg, ret);
+@@ -2625,43 +2631,51 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+
+ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+ {
+- XHCIInterrupter *intr = &xhci->intr[0];
++ int v = (reg - 0x20) / 0x20;
++ XHCIInterrupter *intr = &xhci->intr[v];
+ trace_usb_xhci_runtime_write(reg, val);
+
+- switch (reg) {
+- case 0x20: /* IMAN */
++ if (reg < 0x20) {
++ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
++ return;
++ }
++
++ switch (reg & 0x1f) {
++ case 0x00: /* IMAN */
+ if (val & IMAN_IP) {
+ intr->iman &= ~IMAN_IP;
+ }
+ intr->iman &= ~IMAN_IE;
+ intr->iman |= val & IMAN_IE;
+- xhci_intx_update(xhci);
+- xhci_msix_update(xhci, 0);
++ if (v == 0) {
++ xhci_intx_update(xhci);
++ }
++ xhci_msix_update(xhci, v);
+ break;
+- case 0x24: /* IMOD */
++ case 0x04: /* IMOD */
+ intr->imod = val;
+ break;
+- case 0x28: /* ERSTSZ */
++ case 0x08: /* ERSTSZ */
+ intr->erstsz = val & 0xffff;
+ break;
+- case 0x30: /* ERSTBA low */
++ case 0x10: /* ERSTBA low */
+ /* XXX NEC driver bug: it doesn't align this to 64 bytes
+ intr->erstba_low = val & 0xffffffc0; */
+ intr->erstba_low = val & 0xfffffff0;
+ break;
+- case 0x34: /* ERSTBA high */
++ case 0x14: /* ERSTBA high */
+ intr->erstba_high = val;
+- xhci_er_reset(xhci, 0);
++ xhci_er_reset(xhci, v);
+ break;
+- case 0x38: /* ERDP low */
++ case 0x18: /* ERDP low */
+ if (val & ERDP_EHB) {
+ intr->erdp_low &= ~ERDP_EHB;
+ }
+ intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB);
+ break;
+- case 0x3c: /* ERDP high */
++ case 0x1c: /* ERDP high */
+ intr->erdp_high = val;
+- xhci_events_update(xhci, 0);
++ xhci_events_update(xhci, v);
+ break;
+ default:
+ fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
+--
+1.7.12.1
+